xref: /linux/drivers/leds/leds-lm3532.c (revision 95298d63c67673c654c08952672d016212b26054)
1 // SPDX-License-Identifier: GPL-2.0
2 // TI LM3532 LED driver
3 // Copyright (C) 2019 Texas Instruments Incorporated - http://www.ti.com/
4 // http://www.ti.com/lit/ds/symlink/lm3532.pdf
5 
6 #include <linux/i2c.h>
7 #include <linux/leds.h>
8 #include <linux/slab.h>
9 #include <linux/regmap.h>
10 #include <linux/types.h>
11 #include <linux/regulator/consumer.h>
12 #include <linux/module.h>
13 #include <uapi/linux/uleds.h>
14 #include <linux/gpio/consumer.h>
15 
16 #define LM3532_NAME "lm3532-led"
17 #define LM3532_BL_MODE_MANUAL	0x00
18 #define LM3532_BL_MODE_ALS	0x01
19 
20 #define LM3532_REG_OUTPUT_CFG	0x10
21 #define LM3532_REG_STARTSHUT_RAMP	0x11
22 #define LM3532_REG_RT_RAMP	0x12
23 #define LM3532_REG_PWM_A_CFG	0x13
24 #define LM3532_REG_PWM_B_CFG	0x14
25 #define LM3532_REG_PWM_C_CFG	0x15
26 #define LM3532_REG_ZONE_CFG_A	0x16
27 #define LM3532_REG_CTRL_A_FS_CURR	0x17
28 #define LM3532_REG_ZONE_CFG_B	0x18
29 #define LM3532_REG_CTRL_B_FS_CURR	0x19
30 #define LM3532_REG_ZONE_CFG_C	0x1a
31 #define LM3532_REG_CTRL_C_FS_CURR	0x1b
32 #define LM3532_REG_ENABLE	0x1d
33 #define LM3532_ALS_CONFIG	0x23
34 #define LM3532_REG_ZN_0_HI	0x60
35 #define LM3532_REG_ZN_0_LO	0x61
36 #define LM3532_REG_ZN_1_HI	0x62
37 #define LM3532_REG_ZN_1_LO	0x63
38 #define LM3532_REG_ZN_2_HI	0x64
39 #define LM3532_REG_ZN_2_LO	0x65
40 #define LM3532_REG_ZN_3_HI	0x66
41 #define LM3532_REG_ZN_3_LO	0x67
42 #define LM3532_REG_ZONE_TRGT_A	0x70
43 #define LM3532_REG_ZONE_TRGT_B	0x75
44 #define LM3532_REG_ZONE_TRGT_C	0x7a
45 #define LM3532_REG_MAX		0x7e
46 
47 /* Control Enable */
48 #define LM3532_CTRL_A_ENABLE	BIT(0)
49 #define LM3532_CTRL_B_ENABLE	BIT(1)
50 #define LM3532_CTRL_C_ENABLE	BIT(2)
51 
52 /* PWM Zone Control */
53 #define LM3532_PWM_ZONE_MASK	0x7c
54 #define LM3532_PWM_ZONE_0_EN	BIT(2)
55 #define LM3532_PWM_ZONE_1_EN	BIT(3)
56 #define LM3532_PWM_ZONE_2_EN	BIT(4)
57 #define LM3532_PWM_ZONE_3_EN	BIT(5)
58 #define LM3532_PWM_ZONE_4_EN	BIT(6)
59 
60 /* Brightness Configuration */
61 #define LM3532_I2C_CTRL		BIT(0)
62 #define LM3532_ALS_CTRL		0
63 #define LM3532_LINEAR_MAP	BIT(1)
64 #define LM3532_ZONE_MASK	(BIT(2) | BIT(3) | BIT(4))
65 #define LM3532_ZONE_0		0
66 #define LM3532_ZONE_1		BIT(2)
67 #define LM3532_ZONE_2		BIT(3)
68 #define LM3532_ZONE_3		(BIT(2) | BIT(3))
69 #define LM3532_ZONE_4		BIT(4)
70 
71 #define LM3532_ENABLE_ALS	BIT(3)
72 #define LM3532_ALS_SEL_SHIFT	6
73 
74 /* Zone Boundary Register */
75 #define LM3532_ALS_WINDOW_mV	2000
76 #define LM3532_ALS_ZB_MAX	4
77 #define LM3532_ALS_OFFSET_mV	2
78 
79 #define LM3532_CONTROL_A	0
80 #define LM3532_CONTROL_B	1
81 #define LM3532_CONTROL_C	2
82 #define LM3532_MAX_CONTROL_BANKS 3
83 #define LM3532_MAX_LED_STRINGS	3
84 
85 #define LM3532_OUTPUT_CFG_MASK	0x3
86 #define LM3532_BRT_VAL_ADJUST	8
87 #define LM3532_RAMP_DOWN_SHIFT	3
88 
89 #define LM3532_NUM_RAMP_VALS	8
90 #define LM3532_NUM_AVG_VALS	8
91 #define LM3532_NUM_IMP_VALS	32
92 
93 #define LM3532_FS_CURR_MIN	5000
94 #define LM3532_FS_CURR_MAX	29800
95 #define LM3532_FS_CURR_STEP	800
96 
97 /*
98  * struct lm3532_als_data
99  * @config - value of ALS configuration register
100  * @als1_imp_sel - value of ALS1 resistor select register
101  * @als2_imp_sel - value of ALS2 resistor select register
102  * @als_avrg_time - ALS averaging time
103  * @als_input_mode - ALS input mode for brightness control
104  * @als_vmin - Minimum ALS voltage
105  * @als_vmax - Maximum ALS voltage
106  * @zone_lo - values of ALS lo ZB(Zone Boundary) registers
107  * @zone_hi - values of ALS hi ZB(Zone Boundary) registers
108  */
109 struct lm3532_als_data {
110 	u8 config;
111 	u8 als1_imp_sel;
112 	u8 als2_imp_sel;
113 	u8 als_avrg_time;
114 	u8 als_input_mode;
115 	u32 als_vmin;
116 	u32 als_vmax;
117 	u8 zones_lo[LM3532_ALS_ZB_MAX];
118 	u8 zones_hi[LM3532_ALS_ZB_MAX];
119 };
120 
121 /**
122  * struct lm3532_led
123  * @led_dev: led class device
124  * @priv - Pointer the device data structure
125  * @control_bank - Control bank the LED is associated to
126  * @mode - Mode of the LED string
127  * @ctrl_brt_pointer - Zone target register that controls the sink
128  * @num_leds - Number of LED strings are supported in this array
129  * @full_scale_current - The full-scale current setting for the current sink.
130  * @led_strings - The LED strings supported in this array
131  * @enabled - Enabled status
132  * @label - LED label
133  */
134 struct lm3532_led {
135 	struct led_classdev led_dev;
136 	struct lm3532_data *priv;
137 
138 	int control_bank;
139 	int mode;
140 	int ctrl_brt_pointer;
141 	int num_leds;
142 	int full_scale_current;
143 	unsigned int enabled:1;
144 	u32 led_strings[LM3532_MAX_CONTROL_BANKS];
145 	char label[LED_MAX_NAME_SIZE];
146 };
147 
148 /**
149  * struct lm3532_data
150  * @enable_gpio - Hardware enable gpio
151  * @regulator: regulator
152  * @client: i2c client
153  * @regmap - Devices register map
154  * @dev - Pointer to the devices device struct
155  * @lock - Lock for reading/writing the device
156  * @als_data - Pointer to the als data struct
157  * @runtime_ramp_up - Runtime ramp up setting
158  * @runtime_ramp_down - Runtime ramp down setting
159  * @leds - Array of LED strings
160  */
161 struct lm3532_data {
162 	struct gpio_desc *enable_gpio;
163 	struct regulator *regulator;
164 	struct i2c_client *client;
165 	struct regmap *regmap;
166 	struct device *dev;
167 	struct mutex lock;
168 
169 	struct lm3532_als_data *als_data;
170 
171 	u32 runtime_ramp_up;
172 	u32 runtime_ramp_down;
173 
174 	struct lm3532_led leds[];
175 };
176 
177 static const struct reg_default lm3532_reg_defs[] = {
178 	{LM3532_REG_OUTPUT_CFG, 0xe4},
179 	{LM3532_REG_STARTSHUT_RAMP, 0xc0},
180 	{LM3532_REG_RT_RAMP, 0xc0},
181 	{LM3532_REG_PWM_A_CFG, 0x82},
182 	{LM3532_REG_PWM_B_CFG, 0x82},
183 	{LM3532_REG_PWM_C_CFG, 0x82},
184 	{LM3532_REG_ZONE_CFG_A, 0xf1},
185 	{LM3532_REG_CTRL_A_FS_CURR, 0xf3},
186 	{LM3532_REG_ZONE_CFG_B, 0xf1},
187 	{LM3532_REG_CTRL_B_FS_CURR, 0xf3},
188 	{LM3532_REG_ZONE_CFG_C, 0xf1},
189 	{LM3532_REG_CTRL_C_FS_CURR, 0xf3},
190 	{LM3532_REG_ENABLE, 0xf8},
191 	{LM3532_ALS_CONFIG, 0x44},
192 	{LM3532_REG_ZN_0_HI, 0x35},
193 	{LM3532_REG_ZN_0_LO, 0x33},
194 	{LM3532_REG_ZN_1_HI, 0x6a},
195 	{LM3532_REG_ZN_1_LO, 0x66},
196 	{LM3532_REG_ZN_2_HI, 0xa1},
197 	{LM3532_REG_ZN_2_LO, 0x99},
198 	{LM3532_REG_ZN_3_HI, 0xdc},
199 	{LM3532_REG_ZN_3_LO, 0xcc},
200 };
201 
202 static const struct regmap_config lm3532_regmap_config = {
203 	.reg_bits = 8,
204 	.val_bits = 8,
205 
206 	.max_register = LM3532_REG_MAX,
207 	.reg_defaults = lm3532_reg_defs,
208 	.num_reg_defaults = ARRAY_SIZE(lm3532_reg_defs),
209 	.cache_type = REGCACHE_FLAT,
210 };
211 
212 static const int als_imp_table[LM3532_NUM_IMP_VALS] = {37000, 18500, 12330,
213 						       92500, 7400, 6170, 5290,
214 						       4630, 4110, 3700, 3360,
215 						       3080, 2850, 2640, 2440,
216 						       2310, 2180, 2060, 1950,
217 						       1850, 1760, 1680, 1610,
218 						       1540, 1480, 1420, 1370,
219 						       1320, 1280, 1230, 1190};
220 static int lm3532_get_als_imp_index(int als_imped)
221 {
222 	int i;
223 
224 	if (als_imped > als_imp_table[1])
225 		return 0;
226 
227 	if (als_imped < als_imp_table[LM3532_NUM_IMP_VALS - 1])
228 		return LM3532_NUM_IMP_VALS - 1;
229 
230 	for (i = 1; i < LM3532_NUM_IMP_VALS; i++) {
231 		if (als_imped == als_imp_table[i])
232 			return i;
233 
234 		/* Find an approximate index by looking up the table */
235 		if (als_imped < als_imp_table[i - 1] &&
236 		    als_imped > als_imp_table[i]) {
237 			if (als_imped - als_imp_table[i - 1] <
238 			    als_imp_table[i] - als_imped)
239 				return i + 1;
240 			else
241 				return i;
242 		}
243 	}
244 
245 	return -EINVAL;
246 }
247 
248 static int lm3532_get_index(const int table[], int size, int value)
249 {
250 	int i;
251 
252 	for (i = 1; i < size; i++) {
253 		if (value == table[i])
254 			return i;
255 
256 		/* Find an approximate index by looking up the table */
257 		if (value > table[i - 1] &&
258 		    value < table[i]) {
259 			if (value - table[i - 1] < table[i] - value)
260 				return i - 1;
261 			else
262 				return i;
263 		}
264 	}
265 
266 	return -EINVAL;
267 }
268 
269 static const int als_avrg_table[LM3532_NUM_AVG_VALS] = {17920, 35840, 71680,
270 							1433360, 286720, 573440,
271 							1146880, 2293760};
272 static int lm3532_get_als_avg_index(int avg_time)
273 {
274 	if (avg_time <= als_avrg_table[0])
275 		return 0;
276 
277 	if (avg_time > als_avrg_table[LM3532_NUM_AVG_VALS - 1])
278 		return LM3532_NUM_AVG_VALS - 1;
279 
280 	return lm3532_get_index(&als_avrg_table[0], LM3532_NUM_AVG_VALS,
281 				avg_time);
282 }
283 
284 static const int ramp_table[LM3532_NUM_RAMP_VALS] = { 8, 1024, 2048, 4096, 8192,
285 						     16384, 32768, 65536};
286 static int lm3532_get_ramp_index(int ramp_time)
287 {
288 	if (ramp_time <= ramp_table[0])
289 		return 0;
290 
291 	if (ramp_time > ramp_table[LM3532_NUM_RAMP_VALS - 1])
292 		return LM3532_NUM_RAMP_VALS - 1;
293 
294 	return lm3532_get_index(&ramp_table[0], LM3532_NUM_RAMP_VALS,
295 				ramp_time);
296 }
297 
298 /* Caller must take care of locking */
299 static int lm3532_led_enable(struct lm3532_led *led_data)
300 {
301 	int ctrl_en_val = BIT(led_data->control_bank);
302 	int ret;
303 
304 	if (led_data->enabled)
305 		return 0;
306 
307 	ret = regmap_update_bits(led_data->priv->regmap, LM3532_REG_ENABLE,
308 					 ctrl_en_val, ctrl_en_val);
309 	if (ret) {
310 		dev_err(led_data->priv->dev, "Failed to set ctrl:%d\n", ret);
311 		return ret;
312 	}
313 
314 	ret = regulator_enable(led_data->priv->regulator);
315 	if (ret < 0)
316 		return ret;
317 
318 	led_data->enabled = 1;
319 
320 	return 0;
321 }
322 
323 /* Caller must take care of locking */
324 static int lm3532_led_disable(struct lm3532_led *led_data)
325 {
326 	int ctrl_en_val = BIT(led_data->control_bank);
327 	int ret;
328 
329 	if (!led_data->enabled)
330 		return 0;
331 
332 	ret = regmap_update_bits(led_data->priv->regmap, LM3532_REG_ENABLE,
333 					 ctrl_en_val, 0);
334 	if (ret) {
335 		dev_err(led_data->priv->dev, "Failed to set ctrl:%d\n", ret);
336 		return ret;
337 	}
338 
339 	ret = regulator_disable(led_data->priv->regulator);
340 	if (ret < 0)
341 		return ret;
342 
343 	led_data->enabled = 0;
344 
345 	return 0;
346 }
347 
348 static int lm3532_brightness_set(struct led_classdev *led_cdev,
349 				 enum led_brightness brt_val)
350 {
351 	struct lm3532_led *led =
352 			container_of(led_cdev, struct lm3532_led, led_dev);
353 	u8 brightness_reg;
354 	int ret;
355 
356 	mutex_lock(&led->priv->lock);
357 
358 	if (led->mode == LM3532_ALS_CTRL) {
359 		if (brt_val > LED_OFF)
360 			ret = lm3532_led_enable(led);
361 		else
362 			ret = lm3532_led_disable(led);
363 
364 		goto unlock;
365 	}
366 
367 	if (brt_val == LED_OFF) {
368 		ret = lm3532_led_disable(led);
369 		goto unlock;
370 	}
371 
372 	ret = lm3532_led_enable(led);
373 	if (ret)
374 		goto unlock;
375 
376 	brightness_reg = LM3532_REG_ZONE_TRGT_A + led->control_bank * 5 +
377 			 (led->ctrl_brt_pointer >> 2);
378 
379 	ret = regmap_write(led->priv->regmap, brightness_reg, brt_val);
380 
381 unlock:
382 	mutex_unlock(&led->priv->lock);
383 	return ret;
384 }
385 
386 static int lm3532_init_registers(struct lm3532_led *led)
387 {
388 	struct lm3532_data *drvdata = led->priv;
389 	unsigned int runtime_ramp_val;
390 	unsigned int output_cfg_val = 0;
391 	unsigned int output_cfg_shift = 0;
392 	unsigned int output_cfg_mask = 0;
393 	unsigned int brightness_config_reg;
394 	unsigned int brightness_config_val;
395 	int fs_current_reg;
396 	int fs_current_val;
397 	int ret, i;
398 
399 	if (drvdata->enable_gpio)
400 		gpiod_direction_output(drvdata->enable_gpio, 1);
401 
402 	brightness_config_reg = LM3532_REG_ZONE_CFG_A + led->control_bank * 2;
403 	/*
404 	 * This could be hard coded to the default value but the control
405 	 * brightness register may have changed during boot.
406 	 */
407 	ret = regmap_read(drvdata->regmap, brightness_config_reg,
408 			  &led->ctrl_brt_pointer);
409 	if (ret)
410 		return ret;
411 
412 	led->ctrl_brt_pointer &= LM3532_ZONE_MASK;
413 	brightness_config_val = led->ctrl_brt_pointer | led->mode;
414 	ret = regmap_write(drvdata->regmap, brightness_config_reg,
415 			   brightness_config_val);
416 	if (ret)
417 		return ret;
418 
419 	if (led->full_scale_current) {
420 		fs_current_reg = LM3532_REG_CTRL_A_FS_CURR + led->control_bank * 2;
421 		fs_current_val = (led->full_scale_current - LM3532_FS_CURR_MIN) /
422 				 LM3532_FS_CURR_STEP;
423 
424 		ret = regmap_write(drvdata->regmap, fs_current_reg,
425 				   fs_current_val);
426 		if (ret)
427 			return ret;
428 	}
429 
430 	for (i = 0; i < led->num_leds; i++) {
431 		output_cfg_shift = led->led_strings[i] * 2;
432 		output_cfg_val |= (led->control_bank << output_cfg_shift);
433 		output_cfg_mask |= LM3532_OUTPUT_CFG_MASK << output_cfg_shift;
434 	}
435 
436 	ret = regmap_update_bits(drvdata->regmap, LM3532_REG_OUTPUT_CFG,
437 				 output_cfg_mask, output_cfg_val);
438 	if (ret)
439 		return ret;
440 
441 	runtime_ramp_val = drvdata->runtime_ramp_up |
442 			 (drvdata->runtime_ramp_down << LM3532_RAMP_DOWN_SHIFT);
443 
444 	return regmap_write(drvdata->regmap, LM3532_REG_RT_RAMP,
445 			    runtime_ramp_val);
446 }
447 
448 static int lm3532_als_configure(struct lm3532_data *priv,
449 				struct lm3532_led *led)
450 {
451 	struct lm3532_als_data *als = priv->als_data;
452 	u32 als_vmin, als_vmax, als_vstep;
453 	int zone_reg = LM3532_REG_ZN_0_HI;
454 	int ret;
455 	int i;
456 
457 	als_vmin = als->als_vmin;
458 	als_vmax = als->als_vmax;
459 
460 	als_vstep = (als_vmax - als_vmin) / ((LM3532_ALS_ZB_MAX + 1) * 2);
461 
462 	for (i = 0; i < LM3532_ALS_ZB_MAX; i++) {
463 		als->zones_lo[i] = ((als_vmin + als_vstep + (i * als_vstep)) *
464 				LED_FULL) / 1000;
465 		als->zones_hi[i] = ((als_vmin + LM3532_ALS_OFFSET_mV +
466 				als_vstep + (i * als_vstep)) * LED_FULL) / 1000;
467 
468 		zone_reg = LM3532_REG_ZN_0_HI + i * 2;
469 		ret = regmap_write(priv->regmap, zone_reg, als->zones_lo[i]);
470 		if (ret)
471 			return ret;
472 
473 		zone_reg += 1;
474 		ret = regmap_write(priv->regmap, zone_reg, als->zones_hi[i]);
475 		if (ret)
476 			return ret;
477 	}
478 
479 	als->config = (als->als_avrg_time | (LM3532_ENABLE_ALS) |
480 		(als->als_input_mode << LM3532_ALS_SEL_SHIFT));
481 
482 	return regmap_write(priv->regmap, LM3532_ALS_CONFIG, als->config);
483 }
484 
485 static int lm3532_parse_als(struct lm3532_data *priv)
486 {
487 	struct lm3532_als_data *als;
488 	int als_avg_time;
489 	int als_impedance;
490 	int ret;
491 
492 	als = devm_kzalloc(priv->dev, sizeof(*als), GFP_KERNEL);
493 	if (als == NULL)
494 		return -ENOMEM;
495 
496 	ret = device_property_read_u32(&priv->client->dev, "ti,als-vmin",
497 				       &als->als_vmin);
498 	if (ret)
499 		als->als_vmin = 0;
500 
501 	ret = device_property_read_u32(&priv->client->dev, "ti,als-vmax",
502 				       &als->als_vmax);
503 	if (ret)
504 		als->als_vmax = LM3532_ALS_WINDOW_mV;
505 
506 	if (als->als_vmax > LM3532_ALS_WINDOW_mV) {
507 		ret = -EINVAL;
508 		return ret;
509 	}
510 
511 	ret = device_property_read_u32(&priv->client->dev, "ti,als1-imp-sel",
512 				      &als_impedance);
513 	if (ret)
514 		als->als1_imp_sel = 0;
515 	else
516 		als->als1_imp_sel = lm3532_get_als_imp_index(als_impedance);
517 
518 	ret = device_property_read_u32(&priv->client->dev, "ti,als2-imp-sel",
519 				      &als_impedance);
520 	if (ret)
521 		als->als2_imp_sel = 0;
522 	else
523 		als->als2_imp_sel = lm3532_get_als_imp_index(als_impedance);
524 
525 	ret = device_property_read_u32(&priv->client->dev, "ti,als-avrg-time-us",
526 				      &als_avg_time);
527 	if (ret)
528 		als->als_avrg_time = 0;
529 	else
530 		als->als_avrg_time = lm3532_get_als_avg_index(als_avg_time);
531 
532 	ret = device_property_read_u8(&priv->client->dev, "ti,als-input-mode",
533 				      &als->als_input_mode);
534 	if (ret)
535 		als->als_input_mode = 0;
536 
537 	if (als->als_input_mode > LM3532_BL_MODE_ALS) {
538 		ret = -EINVAL;
539 		return ret;
540 	}
541 
542 	priv->als_data = als;
543 
544 	return ret;
545 }
546 
547 static int lm3532_parse_node(struct lm3532_data *priv)
548 {
549 	struct fwnode_handle *child = NULL;
550 	struct lm3532_led *led;
551 	const char *name;
552 	int control_bank;
553 	u32 ramp_time;
554 	size_t i = 0;
555 	int ret;
556 
557 	priv->enable_gpio = devm_gpiod_get_optional(&priv->client->dev,
558 						   "enable", GPIOD_OUT_LOW);
559 	if (IS_ERR(priv->enable_gpio))
560 		priv->enable_gpio = NULL;
561 
562 	priv->regulator = devm_regulator_get(&priv->client->dev, "vin");
563 	if (IS_ERR(priv->regulator))
564 		priv->regulator = NULL;
565 
566 	ret = device_property_read_u32(&priv->client->dev, "ramp-up-us",
567 				       &ramp_time);
568 	if (ret)
569 		dev_info(&priv->client->dev, "ramp-up-ms property missing\n");
570 	else
571 		priv->runtime_ramp_up = lm3532_get_ramp_index(ramp_time);
572 
573 	ret = device_property_read_u32(&priv->client->dev, "ramp-down-us",
574 				       &ramp_time);
575 	if (ret)
576 		dev_info(&priv->client->dev, "ramp-down-ms property missing\n");
577 	else
578 		priv->runtime_ramp_down = lm3532_get_ramp_index(ramp_time);
579 
580 	device_for_each_child_node(priv->dev, child) {
581 		struct led_init_data idata = {
582 			.fwnode = child,
583 			.default_label = ":",
584 			.devicename = priv->client->name,
585 		};
586 
587 		led = &priv->leds[i];
588 
589 		ret = fwnode_property_read_u32(child, "reg", &control_bank);
590 		if (ret) {
591 			dev_err(&priv->client->dev, "reg property missing\n");
592 			fwnode_handle_put(child);
593 			goto child_out;
594 		}
595 
596 		if (control_bank > LM3532_CONTROL_C) {
597 			dev_err(&priv->client->dev, "Control bank invalid\n");
598 			continue;
599 		}
600 
601 		led->control_bank = control_bank;
602 
603 		ret = fwnode_property_read_u32(child, "ti,led-mode",
604 					       &led->mode);
605 		if (ret) {
606 			dev_err(&priv->client->dev, "ti,led-mode property missing\n");
607 			fwnode_handle_put(child);
608 			goto child_out;
609 		}
610 
611 		if (fwnode_property_present(child, "led-max-microamp") &&
612 		    fwnode_property_read_u32(child, "led-max-microamp",
613 					     &led->full_scale_current))
614 			dev_err(&priv->client->dev,
615 				"Failed getting led-max-microamp\n");
616 		else
617 			led->full_scale_current = min(led->full_scale_current,
618 						      LM3532_FS_CURR_MAX);
619 
620 		if (led->mode == LM3532_BL_MODE_ALS) {
621 			led->mode = LM3532_ALS_CTRL;
622 			ret = lm3532_parse_als(priv);
623 			if (ret)
624 				dev_err(&priv->client->dev, "Failed to parse als\n");
625 			else
626 				lm3532_als_configure(priv, led);
627 		} else {
628 			led->mode = LM3532_I2C_CTRL;
629 		}
630 
631 		led->num_leds = fwnode_property_count_u32(child, "led-sources");
632 		if (led->num_leds > LM3532_MAX_LED_STRINGS) {
633 			dev_err(&priv->client->dev, "Too many LED string defined\n");
634 			continue;
635 		}
636 
637 		ret = fwnode_property_read_u32_array(child, "led-sources",
638 						    led->led_strings,
639 						    led->num_leds);
640 		if (ret) {
641 			dev_err(&priv->client->dev, "led-sources property missing\n");
642 			fwnode_handle_put(child);
643 			goto child_out;
644 		}
645 
646 		fwnode_property_read_string(child, "linux,default-trigger",
647 					    &led->led_dev.default_trigger);
648 
649 		ret = fwnode_property_read_string(child, "label", &name);
650 		if (ret)
651 			snprintf(led->label, sizeof(led->label),
652 				"%s::", priv->client->name);
653 		else
654 			snprintf(led->label, sizeof(led->label),
655 				 "%s:%s", priv->client->name, name);
656 
657 		led->priv = priv;
658 		led->led_dev.name = led->label;
659 		led->led_dev.brightness_set_blocking = lm3532_brightness_set;
660 
661 		ret = devm_led_classdev_register_ext(priv->dev, &led->led_dev, &idata);
662 		if (ret) {
663 			dev_err(&priv->client->dev, "led register err: %d\n",
664 				ret);
665 			fwnode_handle_put(child);
666 			goto child_out;
667 		}
668 
669 		ret = lm3532_init_registers(led);
670 		if (ret) {
671 			dev_err(&priv->client->dev, "register init err: %d\n",
672 				ret);
673 			fwnode_handle_put(child);
674 			goto child_out;
675 		}
676 
677 		i++;
678 	}
679 
680 child_out:
681 	return ret;
682 }
683 
684 static int lm3532_probe(struct i2c_client *client,
685 			   const struct i2c_device_id *id)
686 {
687 	struct lm3532_data *drvdata;
688 	int ret = 0;
689 	int count;
690 
691 	count = device_get_child_node_count(&client->dev);
692 	if (!count) {
693 		dev_err(&client->dev, "LEDs are not defined in device tree!");
694 		return -ENODEV;
695 	}
696 
697 	drvdata = devm_kzalloc(&client->dev, struct_size(drvdata, leds, count),
698 			   GFP_KERNEL);
699 	if (drvdata == NULL)
700 		return -ENOMEM;
701 
702 	drvdata->client = client;
703 	drvdata->dev = &client->dev;
704 
705 	drvdata->regmap = devm_regmap_init_i2c(client, &lm3532_regmap_config);
706 	if (IS_ERR(drvdata->regmap)) {
707 		ret = PTR_ERR(drvdata->regmap);
708 		dev_err(&client->dev, "Failed to allocate register map: %d\n",
709 			ret);
710 		return ret;
711 	}
712 
713 	mutex_init(&drvdata->lock);
714 	i2c_set_clientdata(client, drvdata);
715 
716 	ret = lm3532_parse_node(drvdata);
717 	if (ret) {
718 		dev_err(&client->dev, "Failed to parse node\n");
719 		return ret;
720 	}
721 
722 	return ret;
723 }
724 
725 static int lm3532_remove(struct i2c_client *client)
726 {
727 	struct lm3532_data *drvdata = i2c_get_clientdata(client);
728 
729 	mutex_destroy(&drvdata->lock);
730 
731 	if (drvdata->enable_gpio)
732 		gpiod_direction_output(drvdata->enable_gpio, 0);
733 
734 	return 0;
735 }
736 
737 static const struct of_device_id of_lm3532_leds_match[] = {
738 	{ .compatible = "ti,lm3532", },
739 	{},
740 };
741 MODULE_DEVICE_TABLE(of, of_lm3532_leds_match);
742 
743 static const struct i2c_device_id lm3532_id[] = {
744 	{LM3532_NAME, 0},
745 	{}
746 };
747 MODULE_DEVICE_TABLE(i2c, lm3532_id);
748 
749 static struct i2c_driver lm3532_i2c_driver = {
750 	.probe = lm3532_probe,
751 	.remove = lm3532_remove,
752 	.id_table = lm3532_id,
753 	.driver = {
754 		.name = LM3532_NAME,
755 		.of_match_table = of_lm3532_leds_match,
756 	},
757 };
758 module_i2c_driver(lm3532_i2c_driver);
759 
760 MODULE_DESCRIPTION("Back Light driver for LM3532");
761 MODULE_LICENSE("GPL v2");
762 MODULE_AUTHOR("Dan Murphy <dmurphy@ti.com>");
763