1919#define PCA995X_MODE1 0x00
2020#define PCA995X_MODE2 0x01
2121#define PCA995X_LEDOUT0 0x02
22- #define PCA9955B_PWM0 0x08
23- #define PCA9952_PWM0 0x0A
24- #define PCA9952_IREFALL 0x43
25- #define PCA9955B_IREFALL 0x45
2622
2723/* Auto-increment disabled. Normal mode */
2824#define PCA995X_MODE1_CFG 0x00
3430#define PCA995X_LDRX_MASK 0x3
3531#define PCA995X_LDRX_BITS 2
3632
37- #define PCA995X_MAX_OUTPUTS 16
33+ #define PCA995X_MAX_OUTPUTS 24
3834#define PCA995X_OUTPUTS_PER_REG 4
3935
4036#define PCA995X_IREFALL_FULL_CFG 0xFF
4137#define PCA995X_IREFALL_HALF_CFG (PCA995X_IREFALL_FULL_CFG / 2)
4238
43- #define PCA995X_TYPE_NON_B 0
44- #define PCA995X_TYPE_B 1
45-
4639#define ldev_to_led (c ) container_of(c, struct pca995x_led, ldev)
4740
41+ struct pca995x_chipdef {
42+ unsigned int num_leds ;
43+ u8 pwm_base ;
44+ u8 irefall ;
45+ };
46+
47+ static const struct pca995x_chipdef pca9952_chipdef = {
48+ .num_leds = 16 ,
49+ .pwm_base = 0x0a ,
50+ .irefall = 0x43 ,
51+ };
52+
53+ static const struct pca995x_chipdef pca9955b_chipdef = {
54+ .num_leds = 16 ,
55+ .pwm_base = 0x08 ,
56+ .irefall = 0x45 ,
57+ };
58+
59+ static const struct pca995x_chipdef pca9956b_chipdef = {
60+ .num_leds = 24 ,
61+ .pwm_base = 0x0a ,
62+ .irefall = 0x40 ,
63+ };
64+
4865struct pca995x_led {
4966 unsigned int led_no ;
5067 struct led_classdev ldev ;
@@ -54,18 +71,19 @@ struct pca995x_led {
5471struct pca995x_chip {
5572 struct regmap * regmap ;
5673 struct pca995x_led leds [PCA995X_MAX_OUTPUTS ];
57- int btype ;
74+ const struct pca995x_chipdef * chipdef ;
5875};
5976
6077static int pca995x_brightness_set (struct led_classdev * led_cdev ,
6178 enum led_brightness brightness )
6279{
6380 struct pca995x_led * led = ldev_to_led (led_cdev );
6481 struct pca995x_chip * chip = led -> chip ;
82+ const struct pca995x_chipdef * chipdef = chip -> chipdef ;
6583 u8 ledout_addr , pwmout_addr ;
6684 int shift , ret ;
6785
68- pwmout_addr = ( chip -> btype ? PCA9955B_PWM0 : PCA9952_PWM0 ) + led -> led_no ;
86+ pwmout_addr = chipdef -> pwm_base + led -> led_no ;
6987 ledout_addr = PCA995X_LEDOUT0 + (led -> led_no / PCA995X_OUTPUTS_PER_REG );
7088 shift = PCA995X_LDRX_BITS * (led -> led_no % PCA995X_OUTPUTS_PER_REG );
7189
@@ -104,11 +122,12 @@ static int pca995x_probe(struct i2c_client *client)
104122 struct fwnode_handle * led_fwnodes [PCA995X_MAX_OUTPUTS ] = { 0 };
105123 struct fwnode_handle * np , * child ;
106124 struct device * dev = & client -> dev ;
125+ const struct pca995x_chipdef * chipdef ;
107126 struct pca995x_chip * chip ;
108127 struct pca995x_led * led ;
109- int i , btype , reg , ret ;
128+ int i , reg , ret ;
110129
111- btype = ( unsigned long ) device_get_match_data (& client -> dev );
130+ chipdef = device_get_match_data (& client -> dev );
112131
113132 np = dev_fwnode (dev );
114133 if (!np )
@@ -118,7 +137,7 @@ static int pca995x_probe(struct i2c_client *client)
118137 if (!chip )
119138 return - ENOMEM ;
120139
121- chip -> btype = btype ;
140+ chip -> chipdef = chipdef ;
122141 chip -> regmap = devm_regmap_init_i2c (client , & pca995x_regmap );
123142 if (IS_ERR (chip -> regmap ))
124143 return PTR_ERR (chip -> regmap );
@@ -170,21 +189,21 @@ static int pca995x_probe(struct i2c_client *client)
170189 return ret ;
171190
172191 /* IREF Output current value for all LEDn outputs */
173- return regmap_write (chip -> regmap ,
174- btype ? PCA9955B_IREFALL : PCA9952_IREFALL ,
175- PCA995X_IREFALL_HALF_CFG );
192+ return regmap_write (chip -> regmap , chipdef -> irefall , PCA995X_IREFALL_HALF_CFG );
176193}
177194
178195static const struct i2c_device_id pca995x_id [] = {
179- { "pca9952" , .driver_data = (kernel_ulong_t )PCA995X_TYPE_NON_B },
180- { "pca9955b" , .driver_data = (kernel_ulong_t )PCA995X_TYPE_B },
196+ { "pca9952" , .driver_data = (kernel_ulong_t )& pca9952_chipdef },
197+ { "pca9955b" , .driver_data = (kernel_ulong_t )& pca9955b_chipdef },
198+ { "pca9956b" , .driver_data = (kernel_ulong_t )& pca9956b_chipdef },
181199 {}
182200};
183201MODULE_DEVICE_TABLE (i2c , pca995x_id );
184202
185203static const struct of_device_id pca995x_of_match [] = {
186- { .compatible = "nxp,pca9952" , .data = (void * )PCA995X_TYPE_NON_B },
187- { .compatible = "nxp,pca9955b" , .data = (void * )PCA995X_TYPE_B },
204+ { .compatible = "nxp,pca9952" , .data = & pca9952_chipdef },
205+ { .compatible = "nxp,pca9955b" , . data = & pca9955b_chipdef },
206+ { .compatible = "nxp,pca9956b" , .data = & pca9956b_chipdef },
188207 {},
189208};
190209MODULE_DEVICE_TABLE (of , pca995x_of_match );
0 commit comments