Linux Audio

Check our new training course

Linux BSP development engineering services

Need help to port Linux and bootloaders to your hardware?
Loading...
v6.13.7
  1// SPDX-License-Identifier: GPL-2.0
  2// TI LM3532 LED driver
  3// Copyright (C) 2019 Texas Instruments Incorporated - https://www.ti.com/
  4// https://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 */
109struct 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 */
133struct lm3532_led {
134	struct led_classdev led_dev;
135	struct lm3532_data *priv;
136
137	int control_bank;
138	int mode;
139	int ctrl_brt_pointer;
140	int num_leds;
141	int full_scale_current;
142	unsigned int enabled:1;
143	u32 led_strings[LM3532_MAX_CONTROL_BANKS];
 
144};
145
146/**
147 * struct lm3532_data
148 * @enable_gpio: Hardware enable gpio
149 * @regulator: regulator
150 * @client: i2c client
151 * @regmap: Devices register map
152 * @dev: Pointer to the devices device struct
153 * @lock: Lock for reading/writing the device
154 * @als_data: Pointer to the als data struct
155 * @runtime_ramp_up: Runtime ramp up setting
156 * @runtime_ramp_down: Runtime ramp down setting
157 * @leds: Array of LED strings
158 */
159struct lm3532_data {
160	struct gpio_desc *enable_gpio;
161	struct regulator *regulator;
162	struct i2c_client *client;
163	struct regmap *regmap;
164	struct device *dev;
165	struct mutex lock;
166
167	struct lm3532_als_data *als_data;
168
169	u32 runtime_ramp_up;
170	u32 runtime_ramp_down;
171
172	struct lm3532_led leds[];
173};
174
175static const struct reg_default lm3532_reg_defs[] = {
176	{LM3532_REG_OUTPUT_CFG, 0xe4},
177	{LM3532_REG_STARTSHUT_RAMP, 0xc0},
178	{LM3532_REG_RT_RAMP, 0xc0},
179	{LM3532_REG_PWM_A_CFG, 0x82},
180	{LM3532_REG_PWM_B_CFG, 0x82},
181	{LM3532_REG_PWM_C_CFG, 0x82},
182	{LM3532_REG_ZONE_CFG_A, 0xf1},
183	{LM3532_REG_CTRL_A_FS_CURR, 0xf3},
184	{LM3532_REG_ZONE_CFG_B, 0xf1},
185	{LM3532_REG_CTRL_B_FS_CURR, 0xf3},
186	{LM3532_REG_ZONE_CFG_C, 0xf1},
187	{LM3532_REG_CTRL_C_FS_CURR, 0xf3},
188	{LM3532_REG_ENABLE, 0xf8},
189	{LM3532_ALS_CONFIG, 0x44},
190	{LM3532_REG_ZN_0_HI, 0x35},
191	{LM3532_REG_ZN_0_LO, 0x33},
192	{LM3532_REG_ZN_1_HI, 0x6a},
193	{LM3532_REG_ZN_1_LO, 0x66},
194	{LM3532_REG_ZN_2_HI, 0xa1},
195	{LM3532_REG_ZN_2_LO, 0x99},
196	{LM3532_REG_ZN_3_HI, 0xdc},
197	{LM3532_REG_ZN_3_LO, 0xcc},
198};
199
200static const struct regmap_config lm3532_regmap_config = {
201	.reg_bits = 8,
202	.val_bits = 8,
203
204	.max_register = LM3532_REG_MAX,
205	.reg_defaults = lm3532_reg_defs,
206	.num_reg_defaults = ARRAY_SIZE(lm3532_reg_defs),
207	.cache_type = REGCACHE_FLAT,
208};
209
210static const int als_imp_table[LM3532_NUM_IMP_VALS] = {37000, 18500, 12330,
211						       92500, 7400, 6170, 5290,
212						       4630, 4110, 3700, 3360,
213						       3080, 2850, 2640, 2440,
214						       2310, 2180, 2060, 1950,
215						       1850, 1760, 1680, 1610,
216						       1540, 1480, 1420, 1370,
217						       1320, 1280, 1230, 1190};
218static int lm3532_get_als_imp_index(int als_imped)
219{
220	int i;
221
222	if (als_imped > als_imp_table[1])
223		return 0;
224
225	if (als_imped < als_imp_table[LM3532_NUM_IMP_VALS - 1])
226		return LM3532_NUM_IMP_VALS - 1;
227
228	for (i = 1; i < LM3532_NUM_IMP_VALS; i++) {
229		if (als_imped == als_imp_table[i])
230			return i;
231
232		/* Find an approximate index by looking up the table */
233		if (als_imped < als_imp_table[i - 1] &&
234		    als_imped > als_imp_table[i]) {
235			if (als_imped - als_imp_table[i - 1] <
236			    als_imp_table[i] - als_imped)
237				return i + 1;
238			else
239				return i;
240		}
241	}
242
243	return -EINVAL;
244}
245
246static int lm3532_get_index(const int table[], int size, int value)
247{
248	int i;
249
250	for (i = 1; i < size; i++) {
251		if (value == table[i])
252			return i;
253
254		/* Find an approximate index by looking up the table */
255		if (value > table[i - 1] &&
256		    value < table[i]) {
257			if (value - table[i - 1] < table[i] - value)
258				return i - 1;
259			else
260				return i;
261		}
262	}
263
264	return -EINVAL;
265}
266
267static const int als_avrg_table[LM3532_NUM_AVG_VALS] = {17920, 35840, 71680,
268							1433360, 286720, 573440,
269							1146880, 2293760};
270static int lm3532_get_als_avg_index(int avg_time)
271{
272	if (avg_time <= als_avrg_table[0])
273		return 0;
274
275	if (avg_time > als_avrg_table[LM3532_NUM_AVG_VALS - 1])
276		return LM3532_NUM_AVG_VALS - 1;
277
278	return lm3532_get_index(&als_avrg_table[0], LM3532_NUM_AVG_VALS,
279				avg_time);
280}
281
282static const int ramp_table[LM3532_NUM_RAMP_VALS] = { 8, 1024, 2048, 4096, 8192,
283						     16384, 32768, 65536};
284static int lm3532_get_ramp_index(int ramp_time)
285{
286	if (ramp_time <= ramp_table[0])
287		return 0;
288
289	if (ramp_time > ramp_table[LM3532_NUM_RAMP_VALS - 1])
290		return LM3532_NUM_RAMP_VALS - 1;
291
292	return lm3532_get_index(&ramp_table[0], LM3532_NUM_RAMP_VALS,
293				ramp_time);
294}
295
296/* Caller must take care of locking */
297static int lm3532_led_enable(struct lm3532_led *led_data)
298{
299	int ctrl_en_val = BIT(led_data->control_bank);
300	int ret;
301
302	if (led_data->enabled)
303		return 0;
304
305	ret = regmap_update_bits(led_data->priv->regmap, LM3532_REG_ENABLE,
306					 ctrl_en_val, ctrl_en_val);
307	if (ret) {
308		dev_err(led_data->priv->dev, "Failed to set ctrl:%d\n", ret);
309		return ret;
310	}
311
312	ret = regulator_enable(led_data->priv->regulator);
313	if (ret < 0)
314		return ret;
315
316	led_data->enabled = 1;
317
318	return 0;
319}
320
321/* Caller must take care of locking */
322static int lm3532_led_disable(struct lm3532_led *led_data)
323{
324	int ctrl_en_val = BIT(led_data->control_bank);
325	int ret;
326
327	if (!led_data->enabled)
328		return 0;
329
330	ret = regmap_update_bits(led_data->priv->regmap, LM3532_REG_ENABLE,
331					 ctrl_en_val, 0);
332	if (ret) {
333		dev_err(led_data->priv->dev, "Failed to set ctrl:%d\n", ret);
334		return ret;
335	}
336
337	ret = regulator_disable(led_data->priv->regulator);
338	if (ret < 0)
339		return ret;
340
341	led_data->enabled = 0;
342
343	return 0;
344}
345
346static int lm3532_brightness_set(struct led_classdev *led_cdev,
347				 enum led_brightness brt_val)
348{
349	struct lm3532_led *led =
350			container_of(led_cdev, struct lm3532_led, led_dev);
351	u8 brightness_reg;
352	int ret;
353
354	mutex_lock(&led->priv->lock);
355
356	if (led->mode == LM3532_ALS_CTRL) {
357		if (brt_val > LED_OFF)
358			ret = lm3532_led_enable(led);
359		else
360			ret = lm3532_led_disable(led);
361
362		goto unlock;
363	}
364
365	if (brt_val == LED_OFF) {
366		ret = lm3532_led_disable(led);
367		goto unlock;
368	}
369
370	ret = lm3532_led_enable(led);
371	if (ret)
372		goto unlock;
373
374	brightness_reg = LM3532_REG_ZONE_TRGT_A + led->control_bank * 5 +
375			 (led->ctrl_brt_pointer >> 2);
376
377	ret = regmap_write(led->priv->regmap, brightness_reg, brt_val);
378
379unlock:
380	mutex_unlock(&led->priv->lock);
381	return ret;
382}
383
384static int lm3532_init_registers(struct lm3532_led *led)
385{
386	struct lm3532_data *drvdata = led->priv;
387	unsigned int runtime_ramp_val;
388	unsigned int output_cfg_val = 0;
389	unsigned int output_cfg_shift = 0;
390	unsigned int output_cfg_mask = 0;
391	unsigned int brightness_config_reg;
392	unsigned int brightness_config_val;
393	int fs_current_reg;
394	int fs_current_val;
395	int ret, i;
396
397	if (drvdata->enable_gpio)
398		gpiod_direction_output(drvdata->enable_gpio, 1);
399
400	brightness_config_reg = LM3532_REG_ZONE_CFG_A + led->control_bank * 2;
401	/*
402	 * This could be hard coded to the default value but the control
403	 * brightness register may have changed during boot.
404	 */
405	ret = regmap_read(drvdata->regmap, brightness_config_reg,
406			  &led->ctrl_brt_pointer);
407	if (ret)
408		return ret;
409
410	led->ctrl_brt_pointer &= LM3532_ZONE_MASK;
411	brightness_config_val = led->ctrl_brt_pointer | led->mode;
412	ret = regmap_write(drvdata->regmap, brightness_config_reg,
413			   brightness_config_val);
414	if (ret)
415		return ret;
416
417	if (led->full_scale_current) {
418		fs_current_reg = LM3532_REG_CTRL_A_FS_CURR + led->control_bank * 2;
419		fs_current_val = (led->full_scale_current - LM3532_FS_CURR_MIN) /
420				 LM3532_FS_CURR_STEP;
421
422		ret = regmap_write(drvdata->regmap, fs_current_reg,
423				   fs_current_val);
424		if (ret)
425			return ret;
426	}
427
428	for (i = 0; i < led->num_leds; i++) {
429		output_cfg_shift = led->led_strings[i] * 2;
430		output_cfg_val |= (led->control_bank << output_cfg_shift);
431		output_cfg_mask |= LM3532_OUTPUT_CFG_MASK << output_cfg_shift;
432	}
433
434	ret = regmap_update_bits(drvdata->regmap, LM3532_REG_OUTPUT_CFG,
435				 output_cfg_mask, output_cfg_val);
436	if (ret)
437		return ret;
438
439	runtime_ramp_val = drvdata->runtime_ramp_up |
440			 (drvdata->runtime_ramp_down << LM3532_RAMP_DOWN_SHIFT);
441
442	return regmap_write(drvdata->regmap, LM3532_REG_RT_RAMP,
443			    runtime_ramp_val);
444}
445
446static int lm3532_als_configure(struct lm3532_data *priv,
447				struct lm3532_led *led)
448{
449	struct lm3532_als_data *als = priv->als_data;
450	u32 als_vmin, als_vmax, als_vstep;
451	int zone_reg = LM3532_REG_ZN_0_HI;
452	int ret;
453	int i;
454
455	als_vmin = als->als_vmin;
456	als_vmax = als->als_vmax;
457
458	als_vstep = (als_vmax - als_vmin) / ((LM3532_ALS_ZB_MAX + 1) * 2);
459
460	for (i = 0; i < LM3532_ALS_ZB_MAX; i++) {
461		als->zones_lo[i] = ((als_vmin + als_vstep + (i * als_vstep)) *
462				LED_FULL) / 1000;
463		als->zones_hi[i] = ((als_vmin + LM3532_ALS_OFFSET_mV +
464				als_vstep + (i * als_vstep)) * LED_FULL) / 1000;
465
466		zone_reg = LM3532_REG_ZN_0_HI + i * 2;
467		ret = regmap_write(priv->regmap, zone_reg, als->zones_lo[i]);
468		if (ret)
469			return ret;
470
471		zone_reg += 1;
472		ret = regmap_write(priv->regmap, zone_reg, als->zones_hi[i]);
473		if (ret)
474			return ret;
475	}
476
477	als->config = (als->als_avrg_time | (LM3532_ENABLE_ALS) |
478		(als->als_input_mode << LM3532_ALS_SEL_SHIFT));
479
480	return regmap_write(priv->regmap, LM3532_ALS_CONFIG, als->config);
481}
482
483static int lm3532_parse_als(struct lm3532_data *priv)
484{
485	struct lm3532_als_data *als;
486	int als_avg_time;
487	int als_impedance;
488	int ret;
489
490	als = devm_kzalloc(priv->dev, sizeof(*als), GFP_KERNEL);
491	if (als == NULL)
492		return -ENOMEM;
493
494	ret = device_property_read_u32(&priv->client->dev, "ti,als-vmin",
495				       &als->als_vmin);
496	if (ret)
497		als->als_vmin = 0;
498
499	ret = device_property_read_u32(&priv->client->dev, "ti,als-vmax",
500				       &als->als_vmax);
501	if (ret)
502		als->als_vmax = LM3532_ALS_WINDOW_mV;
503
504	if (als->als_vmax > LM3532_ALS_WINDOW_mV) {
505		ret = -EINVAL;
506		return ret;
507	}
508
509	ret = device_property_read_u32(&priv->client->dev, "ti,als1-imp-sel",
510				      &als_impedance);
511	if (ret)
512		als->als1_imp_sel = 0;
513	else
514		als->als1_imp_sel = lm3532_get_als_imp_index(als_impedance);
515
516	ret = device_property_read_u32(&priv->client->dev, "ti,als2-imp-sel",
517				      &als_impedance);
518	if (ret)
519		als->als2_imp_sel = 0;
520	else
521		als->als2_imp_sel = lm3532_get_als_imp_index(als_impedance);
522
523	ret = device_property_read_u32(&priv->client->dev, "ti,als-avrg-time-us",
524				      &als_avg_time);
525	if (ret)
526		als->als_avrg_time = 0;
527	else
528		als->als_avrg_time = lm3532_get_als_avg_index(als_avg_time);
529
530	ret = device_property_read_u8(&priv->client->dev, "ti,als-input-mode",
531				      &als->als_input_mode);
532	if (ret)
533		als->als_input_mode = 0;
534
535	if (als->als_input_mode > LM3532_BL_MODE_ALS) {
536		ret = -EINVAL;
537		return ret;
538	}
539
540	priv->als_data = als;
541
542	return ret;
543}
544
545static void gpio_set_low_action(void *data)
546{
547	struct lm3532_data *priv = data;
548
549	gpiod_direction_output(priv->enable_gpio, 0);
550}
551
552static int lm3532_parse_node(struct lm3532_data *priv)
553{
 
554	struct lm3532_led *led;
 
555	int control_bank;
556	u32 ramp_time;
557	size_t i = 0;
558	int ret;
559
560	priv->enable_gpio = devm_gpiod_get_optional(&priv->client->dev,
561						   "enable", GPIOD_OUT_LOW);
562	if (IS_ERR(priv->enable_gpio))
563		priv->enable_gpio = NULL;
564
565	if (priv->enable_gpio) {
566		ret = devm_add_action(&priv->client->dev, gpio_set_low_action, priv);
567		if (ret)
568			return ret;
569	}
570
571	priv->regulator = devm_regulator_get(&priv->client->dev, "vin");
572	if (IS_ERR(priv->regulator))
573		priv->regulator = NULL;
574
575	ret = device_property_read_u32(&priv->client->dev, "ramp-up-us",
576				       &ramp_time);
577	if (ret)
578		dev_info(&priv->client->dev, "ramp-up-ms property missing\n");
579	else
580		priv->runtime_ramp_up = lm3532_get_ramp_index(ramp_time);
581
582	ret = device_property_read_u32(&priv->client->dev, "ramp-down-us",
583				       &ramp_time);
584	if (ret)
585		dev_info(&priv->client->dev, "ramp-down-ms property missing\n");
586	else
587		priv->runtime_ramp_down = lm3532_get_ramp_index(ramp_time);
588
589	device_for_each_child_node_scoped(priv->dev, child) {
590		struct led_init_data idata = {
591			.fwnode = child,
592			.default_label = ":",
593			.devicename = priv->client->name,
594		};
595
596		led = &priv->leds[i];
597
598		ret = fwnode_property_read_u32(child, "reg", &control_bank);
599		if (ret) {
600			dev_err(&priv->client->dev, "reg property missing\n");
601			return ret;
 
602		}
603
604		if (control_bank > LM3532_CONTROL_C) {
605			dev_err(&priv->client->dev, "Control bank invalid\n");
606			continue;
607		}
608
609		led->control_bank = control_bank;
610
611		ret = fwnode_property_read_u32(child, "ti,led-mode",
612					       &led->mode);
613		if (ret) {
614			dev_err(&priv->client->dev, "ti,led-mode property missing\n");
615			return ret;
 
616		}
617
618		if (fwnode_property_present(child, "led-max-microamp") &&
619		    fwnode_property_read_u32(child, "led-max-microamp",
620					     &led->full_scale_current))
621			dev_err(&priv->client->dev,
622				"Failed getting led-max-microamp\n");
623		else
624			led->full_scale_current = min(led->full_scale_current,
625						      LM3532_FS_CURR_MAX);
626
627		if (led->mode == LM3532_BL_MODE_ALS) {
628			led->mode = LM3532_ALS_CTRL;
629			ret = lm3532_parse_als(priv);
630			if (ret)
631				dev_err(&priv->client->dev, "Failed to parse als\n");
632			else
633				lm3532_als_configure(priv, led);
634		} else {
635			led->mode = LM3532_I2C_CTRL;
636		}
637
638		led->num_leds = fwnode_property_count_u32(child, "led-sources");
639		if (led->num_leds > LM3532_MAX_LED_STRINGS) {
640			dev_err(&priv->client->dev, "Too many LED string defined\n");
641			continue;
642		}
643
644		ret = fwnode_property_read_u32_array(child, "led-sources",
645						    led->led_strings,
646						    led->num_leds);
647		if (ret) {
648			dev_err(&priv->client->dev, "led-sources property missing\n");
649			return ret;
 
650		}
651
 
 
 
 
 
 
 
 
 
 
 
652		led->priv = priv;
 
653		led->led_dev.brightness_set_blocking = lm3532_brightness_set;
654
655		ret = devm_led_classdev_register_ext(priv->dev, &led->led_dev, &idata);
656		if (ret) {
657			dev_err(&priv->client->dev, "led register err: %d\n",
658				ret);
659			return ret;
 
660		}
661
662		ret = lm3532_init_registers(led);
663		if (ret) {
664			dev_err(&priv->client->dev, "register init err: %d\n",
665				ret);
666			return ret;
 
667		}
668
669		i++;
670	}
671
672	return 0;
 
673}
674
675static int lm3532_probe(struct i2c_client *client)
 
676{
677	struct lm3532_data *drvdata;
678	int ret = 0;
679	int count;
680
681	count = device_get_child_node_count(&client->dev);
682	if (!count) {
683		dev_err(&client->dev, "LEDs are not defined in device tree!");
684		return -ENODEV;
685	}
686
687	drvdata = devm_kzalloc(&client->dev, struct_size(drvdata, leds, count),
688			   GFP_KERNEL);
689	if (drvdata == NULL)
690		return -ENOMEM;
691
692	drvdata->client = client;
693	drvdata->dev = &client->dev;
694
695	drvdata->regmap = devm_regmap_init_i2c(client, &lm3532_regmap_config);
696	if (IS_ERR(drvdata->regmap)) {
697		ret = PTR_ERR(drvdata->regmap);
698		dev_err(&client->dev, "Failed to allocate register map: %d\n",
699			ret);
700		return ret;
701	}
702
703	ret = devm_mutex_init(&client->dev, &drvdata->lock);
704	if (ret)
705		return ret;
706
707	i2c_set_clientdata(client, drvdata);
708
709	ret = lm3532_parse_node(drvdata);
710	if (ret) {
711		dev_err(&client->dev, "Failed to parse node\n");
712		return ret;
713	}
714
715	return ret;
716}
717
 
 
 
 
 
 
 
 
 
 
 
 
718static const struct of_device_id of_lm3532_leds_match[] = {
719	{ .compatible = "ti,lm3532", },
720	{},
721};
722MODULE_DEVICE_TABLE(of, of_lm3532_leds_match);
723
724static const struct i2c_device_id lm3532_id[] = {
725	{ LM3532_NAME },
726	{}
727};
728MODULE_DEVICE_TABLE(i2c, lm3532_id);
729
730static struct i2c_driver lm3532_i2c_driver = {
731	.probe = lm3532_probe,
 
732	.id_table = lm3532_id,
733	.driver = {
734		.name = LM3532_NAME,
735		.of_match_table = of_lm3532_leds_match,
736	},
737};
738module_i2c_driver(lm3532_i2c_driver);
739
740MODULE_DESCRIPTION("Back Light driver for LM3532");
741MODULE_LICENSE("GPL v2");
742MODULE_AUTHOR("Dan Murphy <dmurphy@ti.com>");
v5.9
  1// SPDX-License-Identifier: GPL-2.0
  2// TI LM3532 LED driver
  3// Copyright (C) 2019 Texas Instruments Incorporated - https://www.ti.com/
  4// https://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 */
109struct 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 */
134struct 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 */
161struct 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
177static 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
202static 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
212static 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};
220static 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
248static 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
269static const int als_avrg_table[LM3532_NUM_AVG_VALS] = {17920, 35840, 71680,
270							1433360, 286720, 573440,
271							1146880, 2293760};
272static 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
284static const int ramp_table[LM3532_NUM_RAMP_VALS] = { 8, 1024, 2048, 4096, 8192,
285						     16384, 32768, 65536};
286static 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 */
299static 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 */
324static 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
348static 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
381unlock:
382	mutex_unlock(&led->priv->lock);
383	return ret;
384}
385
386static 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
448static 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
485static 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
 
 
 
 
 
 
 
547static 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
680child_out:
681	return ret;
682}
683
684static 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
725static 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
737static const struct of_device_id of_lm3532_leds_match[] = {
738	{ .compatible = "ti,lm3532", },
739	{},
740};
741MODULE_DEVICE_TABLE(of, of_lm3532_leds_match);
742
743static const struct i2c_device_id lm3532_id[] = {
744	{LM3532_NAME, 0},
745	{}
746};
747MODULE_DEVICE_TABLE(i2c, lm3532_id);
748
749static 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};
758module_i2c_driver(lm3532_i2c_driver);
759
760MODULE_DESCRIPTION("Back Light driver for LM3532");
761MODULE_LICENSE("GPL v2");
762MODULE_AUTHOR("Dan Murphy <dmurphy@ti.com>");