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
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>
16 #define LM3532_NAME "lm3532-led"
17 #define LM3532_BL_MODE_MANUAL 0x00
18 #define LM3532_BL_MODE_ALS 0x01
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
48 #define LM3532_CTRL_A_ENABLE BIT(0)
49 #define LM3532_CTRL_B_ENABLE BIT(1)
50 #define LM3532_CTRL_C_ENABLE BIT(2)
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)
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)
71 #define LM3532_ENABLE_ALS BIT(3)
72 #define LM3532_ALS_SEL_SHIFT 6
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
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
85 #define LM3532_OUTPUT_CFG_MASK 0x3
86 #define LM3532_BRT_VAL_ADJUST 8
87 #define LM3532_RAMP_DOWN_SHIFT 3
89 #define LM3532_NUM_RAMP_VALS 8
90 #define LM3532_NUM_AVG_VALS 8
91 #define LM3532_NUM_IMP_VALS 32
93 #define LM3532_FS_CURR_MIN 5000
94 #define LM3532_FS_CURR_MAX 29800
95 #define LM3532_FS_CURR_STEP 800
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
109 struct lm3532_als_data {
117 u8 zones_lo[LM3532_ALS_ZB_MAX];
118 u8 zones_hi[LM3532_ALS_ZB_MAX];
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
134 struct led_classdev led_dev;
135 struct lm3532_data *priv;
139 int ctrl_brt_pointer;
141 int full_scale_current;
142 unsigned int enabled:1;
143 u32 led_strings[LM3532_MAX_CONTROL_BANKS];
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
160 struct gpio_desc *enable_gpio;
161 struct regulator *regulator;
162 struct i2c_client *client;
163 struct regmap *regmap;
167 struct lm3532_als_data *als_data;
170 u32 runtime_ramp_down;
172 struct lm3532_led leds[];
175 static 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},
200 static const struct regmap_config lm3532_regmap_config = {
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,
210 static 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};
218 static int lm3532_get_als_imp_index(int als_imped)
222 if (als_imped > als_imp_table[1])
225 if (als_imped < als_imp_table[LM3532_NUM_IMP_VALS - 1])
226 return LM3532_NUM_IMP_VALS - 1;
228 for (i = 1; i < LM3532_NUM_IMP_VALS; i++) {
229 if (als_imped == als_imp_table[i])
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)
246 static int lm3532_get_index(const int table[], int size, int value)
250 for (i = 1; i < size; i++) {
251 if (value == table[i])
254 /* Find an approximate index by looking up the table */
255 if (value > table[i - 1] &&
257 if (value - table[i - 1] < table[i] - value)
267 static const int als_avrg_table[LM3532_NUM_AVG_VALS] = {17920, 35840, 71680,
268 1433360, 286720, 573440,
270 static int lm3532_get_als_avg_index(int avg_time)
272 if (avg_time <= als_avrg_table[0])
275 if (avg_time > als_avrg_table[LM3532_NUM_AVG_VALS - 1])
276 return LM3532_NUM_AVG_VALS - 1;
278 return lm3532_get_index(&als_avrg_table[0], LM3532_NUM_AVG_VALS,
282 static const int ramp_table[LM3532_NUM_RAMP_VALS] = { 8, 1024, 2048, 4096, 8192,
283 16384, 32768, 65536};
284 static int lm3532_get_ramp_index(int ramp_time)
286 if (ramp_time <= ramp_table[0])
289 if (ramp_time > ramp_table[LM3532_NUM_RAMP_VALS - 1])
290 return LM3532_NUM_RAMP_VALS - 1;
292 return lm3532_get_index(&ramp_table[0], LM3532_NUM_RAMP_VALS,
296 /* Caller must take care of locking */
297 static int lm3532_led_enable(struct lm3532_led *led_data)
299 int ctrl_en_val = BIT(led_data->control_bank);
302 if (led_data->enabled)
305 ret = regmap_update_bits(led_data->priv->regmap, LM3532_REG_ENABLE,
306 ctrl_en_val, ctrl_en_val);
308 dev_err(led_data->priv->dev, "Failed to set ctrl:%d\n", ret);
312 ret = regulator_enable(led_data->priv->regulator);
316 led_data->enabled = 1;
321 /* Caller must take care of locking */
322 static int lm3532_led_disable(struct lm3532_led *led_data)
324 int ctrl_en_val = BIT(led_data->control_bank);
327 if (!led_data->enabled)
330 ret = regmap_update_bits(led_data->priv->regmap, LM3532_REG_ENABLE,
333 dev_err(led_data->priv->dev, "Failed to set ctrl:%d\n", ret);
337 ret = regulator_disable(led_data->priv->regulator);
341 led_data->enabled = 0;
346 static int lm3532_brightness_set(struct led_classdev *led_cdev,
347 enum led_brightness brt_val)
349 struct lm3532_led *led =
350 container_of(led_cdev, struct lm3532_led, led_dev);
354 mutex_lock(&led->priv->lock);
356 if (led->mode == LM3532_ALS_CTRL) {
357 if (brt_val > LED_OFF)
358 ret = lm3532_led_enable(led);
360 ret = lm3532_led_disable(led);
365 if (brt_val == LED_OFF) {
366 ret = lm3532_led_disable(led);
370 ret = lm3532_led_enable(led);
374 brightness_reg = LM3532_REG_ZONE_TRGT_A + led->control_bank * 5 +
375 (led->ctrl_brt_pointer >> 2);
377 ret = regmap_write(led->priv->regmap, brightness_reg, brt_val);
380 mutex_unlock(&led->priv->lock);
384 static int lm3532_init_registers(struct lm3532_led *led)
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;
397 if (drvdata->enable_gpio)
398 gpiod_direction_output(drvdata->enable_gpio, 1);
400 brightness_config_reg = LM3532_REG_ZONE_CFG_A + led->control_bank * 2;
402 * This could be hard coded to the default value but the control
403 * brightness register may have changed during boot.
405 ret = regmap_read(drvdata->regmap, brightness_config_reg,
406 &led->ctrl_brt_pointer);
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);
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) /
422 ret = regmap_write(drvdata->regmap, fs_current_reg,
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;
434 ret = regmap_update_bits(drvdata->regmap, LM3532_REG_OUTPUT_CFG,
435 output_cfg_mask, output_cfg_val);
439 runtime_ramp_val = drvdata->runtime_ramp_up |
440 (drvdata->runtime_ramp_down << LM3532_RAMP_DOWN_SHIFT);
442 return regmap_write(drvdata->regmap, LM3532_REG_RT_RAMP,
446 static int lm3532_als_configure(struct lm3532_data *priv,
447 struct lm3532_led *led)
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;
455 als_vmin = als->als_vmin;
456 als_vmax = als->als_vmax;
458 als_vstep = (als_vmax - als_vmin) / ((LM3532_ALS_ZB_MAX + 1) * 2);
460 for (i = 0; i < LM3532_ALS_ZB_MAX; i++) {
461 als->zones_lo[i] = ((als_vmin + als_vstep + (i * als_vstep)) *
463 als->zones_hi[i] = ((als_vmin + LM3532_ALS_OFFSET_mV +
464 als_vstep + (i * als_vstep)) * LED_FULL) / 1000;
466 zone_reg = LM3532_REG_ZN_0_HI + i * 2;
467 ret = regmap_write(priv->regmap, zone_reg, als->zones_lo[i]);
472 ret = regmap_write(priv->regmap, zone_reg, als->zones_hi[i]);
477 als->config = (als->als_avrg_time | (LM3532_ENABLE_ALS) |
478 (als->als_input_mode << LM3532_ALS_SEL_SHIFT));
480 return regmap_write(priv->regmap, LM3532_ALS_CONFIG, als->config);
483 static int lm3532_parse_als(struct lm3532_data *priv)
485 struct lm3532_als_data *als;
490 als = devm_kzalloc(priv->dev, sizeof(*als), GFP_KERNEL);
494 ret = device_property_read_u32(&priv->client->dev, "ti,als-vmin",
499 ret = device_property_read_u32(&priv->client->dev, "ti,als-vmax",
502 als->als_vmax = LM3532_ALS_WINDOW_mV;
504 if (als->als_vmax > LM3532_ALS_WINDOW_mV) {
509 ret = device_property_read_u32(&priv->client->dev, "ti,als1-imp-sel",
512 als->als1_imp_sel = 0;
514 als->als1_imp_sel = lm3532_get_als_imp_index(als_impedance);
516 ret = device_property_read_u32(&priv->client->dev, "ti,als2-imp-sel",
519 als->als2_imp_sel = 0;
521 als->als2_imp_sel = lm3532_get_als_imp_index(als_impedance);
523 ret = device_property_read_u32(&priv->client->dev, "ti,als-avrg-time-us",
526 als->als_avrg_time = 0;
528 als->als_avrg_time = lm3532_get_als_avg_index(als_avg_time);
530 ret = device_property_read_u8(&priv->client->dev, "ti,als-input-mode",
531 &als->als_input_mode);
533 als->als_input_mode = 0;
535 if (als->als_input_mode > LM3532_BL_MODE_ALS) {
540 priv->als_data = als;
545 static int lm3532_parse_node(struct lm3532_data *priv)
547 struct fwnode_handle *child = NULL;
548 struct lm3532_led *led;
554 priv->enable_gpio = devm_gpiod_get_optional(&priv->client->dev,
555 "enable", GPIOD_OUT_LOW);
556 if (IS_ERR(priv->enable_gpio))
557 priv->enable_gpio = NULL;
559 priv->regulator = devm_regulator_get(&priv->client->dev, "vin");
560 if (IS_ERR(priv->regulator))
561 priv->regulator = NULL;
563 ret = device_property_read_u32(&priv->client->dev, "ramp-up-us",
566 dev_info(&priv->client->dev, "ramp-up-ms property missing\n");
568 priv->runtime_ramp_up = lm3532_get_ramp_index(ramp_time);
570 ret = device_property_read_u32(&priv->client->dev, "ramp-down-us",
573 dev_info(&priv->client->dev, "ramp-down-ms property missing\n");
575 priv->runtime_ramp_down = lm3532_get_ramp_index(ramp_time);
577 device_for_each_child_node(priv->dev, child) {
578 struct led_init_data idata = {
580 .default_label = ":",
581 .devicename = priv->client->name,
584 led = &priv->leds[i];
586 ret = fwnode_property_read_u32(child, "reg", &control_bank);
588 dev_err(&priv->client->dev, "reg property missing\n");
592 if (control_bank > LM3532_CONTROL_C) {
593 dev_err(&priv->client->dev, "Control bank invalid\n");
597 led->control_bank = control_bank;
599 ret = fwnode_property_read_u32(child, "ti,led-mode",
602 dev_err(&priv->client->dev, "ti,led-mode property missing\n");
606 if (fwnode_property_present(child, "led-max-microamp") &&
607 fwnode_property_read_u32(child, "led-max-microamp",
608 &led->full_scale_current))
609 dev_err(&priv->client->dev,
610 "Failed getting led-max-microamp\n");
612 led->full_scale_current = min(led->full_scale_current,
615 if (led->mode == LM3532_BL_MODE_ALS) {
616 led->mode = LM3532_ALS_CTRL;
617 ret = lm3532_parse_als(priv);
619 dev_err(&priv->client->dev, "Failed to parse als\n");
621 lm3532_als_configure(priv, led);
623 led->mode = LM3532_I2C_CTRL;
626 led->num_leds = fwnode_property_count_u32(child, "led-sources");
627 if (led->num_leds > LM3532_MAX_LED_STRINGS) {
628 dev_err(&priv->client->dev, "Too many LED string defined\n");
632 ret = fwnode_property_read_u32_array(child, "led-sources",
636 dev_err(&priv->client->dev, "led-sources property missing\n");
641 led->led_dev.brightness_set_blocking = lm3532_brightness_set;
643 ret = devm_led_classdev_register_ext(priv->dev, &led->led_dev, &idata);
645 dev_err(&priv->client->dev, "led register err: %d\n",
650 ret = lm3532_init_registers(led);
652 dev_err(&priv->client->dev, "register init err: %d\n",
662 fwnode_handle_put(child);
666 static int lm3532_probe(struct i2c_client *client,
667 const struct i2c_device_id *id)
669 struct lm3532_data *drvdata;
673 count = device_get_child_node_count(&client->dev);
675 dev_err(&client->dev, "LEDs are not defined in device tree!");
679 drvdata = devm_kzalloc(&client->dev, struct_size(drvdata, leds, count),
684 drvdata->client = client;
685 drvdata->dev = &client->dev;
687 drvdata->regmap = devm_regmap_init_i2c(client, &lm3532_regmap_config);
688 if (IS_ERR(drvdata->regmap)) {
689 ret = PTR_ERR(drvdata->regmap);
690 dev_err(&client->dev, "Failed to allocate register map: %d\n",
695 mutex_init(&drvdata->lock);
696 i2c_set_clientdata(client, drvdata);
698 ret = lm3532_parse_node(drvdata);
700 dev_err(&client->dev, "Failed to parse node\n");
707 static int lm3532_remove(struct i2c_client *client)
709 struct lm3532_data *drvdata = i2c_get_clientdata(client);
711 mutex_destroy(&drvdata->lock);
713 if (drvdata->enable_gpio)
714 gpiod_direction_output(drvdata->enable_gpio, 0);
719 static const struct of_device_id of_lm3532_leds_match[] = {
720 { .compatible = "ti,lm3532", },
723 MODULE_DEVICE_TABLE(of, of_lm3532_leds_match);
725 static const struct i2c_device_id lm3532_id[] = {
729 MODULE_DEVICE_TABLE(i2c, lm3532_id);
731 static struct i2c_driver lm3532_i2c_driver = {
732 .probe = lm3532_probe,
733 .remove = lm3532_remove,
734 .id_table = lm3532_id,
737 .of_match_table = of_lm3532_leds_match,
740 module_i2c_driver(lm3532_i2c_driver);
742 MODULE_DESCRIPTION("Back Light driver for LM3532");
743 MODULE_LICENSE("GPL v2");
744 MODULE_AUTHOR("Dan Murphy <dmurphy@ti.com>");