Skip to content

Commit 4225466

Browse files
daniel-nicolai-hanstennashif
authored andcommitted
drivers: led: pca9633: add support for multiple devices
PCA9633 driver does not cunnetly support multiple devices. Updated the driver to use DT_INST_FOREACH_STATUS_OKAY to configure all devices defined in the device tree. Convert driver to use `i2c_dt_spec` helpers. Fixes #40076 Signed-off-by: Daniel N. Hansten <[email protected]>
1 parent 07680b2 commit 4225466

File tree

1 file changed

+35
-23
lines changed

1 file changed

+35
-23
lines changed

drivers/led/pca9633.c

Lines changed: 35 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ LOG_MODULE_REGISTER(pca9633);
3131
/* PCA9633 control register */
3232
#define PCA9633_MODE1 0x00
3333
#define PCA9633_MODE2 0x01
34-
#define PCA9633_PWM_BASE 0x02
34+
#define PCA9633_PWM_BASE 0x02 /* Reg 0x02-0x05 for brightness control LED01-04 */
3535
#define PCA9633_GRPPWM 0x06
3636
#define PCA9633_GRPFREQ 0x07
3737
#define PCA9633_LEDOUT 0x08
@@ -43,15 +43,19 @@ LOG_MODULE_REGISTER(pca9633);
4343

4444
#define PCA9633_MASK 0x03
4545

46+
struct pca9633_config {
47+
struct i2c_dt_spec i2c;
48+
};
49+
4650
struct pca9633_data {
47-
const struct device *i2c;
4851
struct led_data dev_data;
4952
};
5053

5154
static int pca9633_led_blink(const struct device *dev, uint32_t led,
5255
uint32_t delay_on, uint32_t delay_off)
5356
{
5457
struct pca9633_data *data = dev->data;
58+
const struct pca9633_config *config = dev->config;
5559
struct led_data *dev_data = &data->dev_data;
5660
uint8_t gdc, gfrq;
5761
uint32_t period;
@@ -69,7 +73,7 @@ static int pca9633_led_blink(const struct device *dev, uint32_t led,
6973
* GDC = ((time_on * 256) / period)
7074
*/
7175
gdc = delay_on * 256U / period;
72-
if (i2c_reg_write_byte(data->i2c, DT_INST_REG_ADDR(0),
76+
if (i2c_reg_write_byte_dt(&config->i2c,
7377
PCA9633_GRPPWM,
7478
gdc)) {
7579
LOG_ERR("LED reg write failed");
@@ -83,15 +87,15 @@ static int pca9633_led_blink(const struct device *dev, uint32_t led,
8387
* GFRQ = ((period * 24 / 1000) - 1)
8488
*/
8589
gfrq = (period * 24U / 1000) - 1;
86-
if (i2c_reg_write_byte(data->i2c, DT_INST_REG_ADDR(0),
90+
if (i2c_reg_write_byte_dt(&config->i2c,
8791
PCA9633_GRPFREQ,
8892
gfrq)) {
8993
LOG_ERR("LED reg write failed");
9094
return -EIO;
9195
}
9296

9397
/* Enable blinking mode */
94-
if (i2c_reg_update_byte(data->i2c, DT_INST_REG_ADDR(0),
98+
if (i2c_reg_update_byte_dt(&config->i2c,
9599
PCA9633_MODE2,
96100
PCA9633_MODE2_DMBLNK,
97101
PCA9633_MODE2_DMBLNK)) {
@@ -100,7 +104,7 @@ static int pca9633_led_blink(const struct device *dev, uint32_t led,
100104
}
101105

102106
/* Select the GRPPWM source to drive the LED outpout */
103-
if (i2c_reg_update_byte(data->i2c, DT_INST_REG_ADDR(0),
107+
if (i2c_reg_update_byte_dt(&config->i2c,
104108
PCA9633_LEDOUT,
105109
PCA9633_MASK << (led << 1),
106110
PCA9633_LED_GRP_PWM << (led << 1))) {
@@ -114,6 +118,7 @@ static int pca9633_led_blink(const struct device *dev, uint32_t led,
114118
static int pca9633_led_set_brightness(const struct device *dev, uint32_t led,
115119
uint8_t value)
116120
{
121+
const struct pca9633_config *config = dev->config;
117122
struct pca9633_data *data = dev->data;
118123
struct led_data *dev_data = &data->dev_data;
119124
uint8_t val;
@@ -125,15 +130,15 @@ static int pca9633_led_set_brightness(const struct device *dev, uint32_t led,
125130

126131
/* Set the LED brightness value */
127132
val = (value * 255U) / dev_data->max_brightness;
128-
if (i2c_reg_write_byte(data->i2c, DT_INST_REG_ADDR(0),
133+
if (i2c_reg_write_byte_dt(&config->i2c,
129134
PCA9633_PWM_BASE + led,
130135
val)) {
131136
LOG_ERR("LED reg write failed");
132137
return -EIO;
133138
}
134139

135140
/* Set the LED driver to be controlled through its PWMx register. */
136-
if (i2c_reg_update_byte(data->i2c, DT_INST_REG_ADDR(0),
141+
if (i2c_reg_update_byte_dt(&config->i2c,
137142
PCA9633_LEDOUT,
138143
PCA9633_MASK << (led << 1),
139144
PCA9633_LED_PWM << (led << 1))) {
@@ -146,10 +151,10 @@ static int pca9633_led_set_brightness(const struct device *dev, uint32_t led,
146151

147152
static inline int pca9633_led_on(const struct device *dev, uint32_t led)
148153
{
149-
struct pca9633_data *data = dev->data;
154+
const struct pca9633_config *config = dev->config;
150155

151156
/* Set LED state to ON */
152-
if (i2c_reg_update_byte(data->i2c, DT_INST_REG_ADDR(0),
157+
if (i2c_reg_update_byte_dt(&config->i2c,
153158
PCA9633_LEDOUT,
154159
PCA9633_MASK << (led << 1),
155160
PCA9633_LED_ON << (led << 1))) {
@@ -162,10 +167,10 @@ static inline int pca9633_led_on(const struct device *dev, uint32_t led)
162167

163168
static inline int pca9633_led_off(const struct device *dev, uint32_t led)
164169
{
165-
struct pca9633_data *data = dev->data;
170+
const struct pca9633_config *config = dev->config;
166171

167172
/* Set LED state to OFF */
168-
if (i2c_reg_update_byte(data->i2c, DT_INST_REG_ADDR(0),
173+
if (i2c_reg_update_byte_dt(&config->i2c,
169174
PCA9633_LEDOUT,
170175
PCA9633_MASK << (led << 1),
171176
PCA9633_LED_OFF)) {
@@ -178,17 +183,17 @@ static inline int pca9633_led_off(const struct device *dev, uint32_t led)
178183

179184
static int pca9633_led_init(const struct device *dev)
180185
{
186+
const struct pca9633_config *config = dev->config;
181187
struct pca9633_data *data = dev->data;
182188
struct led_data *dev_data = &data->dev_data;
183189

184-
data->i2c = device_get_binding(DT_INST_BUS_LABEL(0));
185-
if (data->i2c == NULL) {
186-
LOG_DBG("Failed to get I2C device");
187-
return -EINVAL;
190+
if (!device_is_ready(config->i2c.bus)) {
191+
LOG_ERR("I2C bus is not ready");
192+
return -ENODEV;
188193
}
189194

190195
/* Take the LED driver out from Sleep mode. */
191-
if (i2c_reg_update_byte(data->i2c, DT_INST_REG_ADDR(0),
196+
if (i2c_reg_update_byte_dt(&config->i2c,
192197
PCA9633_MODE1,
193198
PCA9633_MODE1_SLEEP,
194199
~PCA9633_MODE1_SLEEP)) {
@@ -204,16 +209,23 @@ static int pca9633_led_init(const struct device *dev)
204209
return 0;
205210
}
206211

207-
static struct pca9633_data pca9633_led_data;
208-
209212
static const struct led_driver_api pca9633_led_api = {
210213
.blink = pca9633_led_blink,
211214
.set_brightness = pca9633_led_set_brightness,
212215
.on = pca9633_led_on,
213216
.off = pca9633_led_off,
214217
};
215218

216-
DEVICE_DT_INST_DEFINE(0, &pca9633_led_init, NULL,
217-
&pca9633_led_data,
218-
NULL, POST_KERNEL, CONFIG_LED_INIT_PRIORITY,
219-
&pca9633_led_api);
219+
#define PCA9633_DEVICE(id) \
220+
static const struct pca9633_config pca9633_##id##_cfg = { \
221+
.i2c = I2C_DT_SPEC_INST_GET(id) \
222+
}; \
223+
static struct pca9633_data pca9633_##id##_data; \
224+
\
225+
DEVICE_DT_INST_DEFINE(id, &pca9633_led_init, NULL, \
226+
&pca9633_##id##_data, \
227+
&pca9633_##id##_cfg, POST_KERNEL, \
228+
CONFIG_LED_INIT_PRIORITY, \
229+
&pca9633_led_api);
230+
231+
DT_INST_FOREACH_STATUS_OKAY(PCA9633_DEVICE)

0 commit comments

Comments
 (0)