1 // SPDX-License-Identifier: GPL-2.0
2 // TI LM3532 LED driver
3 // Copyright (C) 2019 Texas Instruments Incorporated - http://www.ti.com/
6 #include <linux/leds.h>
7 #include <linux/slab.h>
8 #include <linux/regmap.h>
9 #include <linux/types.h>
10 #include <linux/regulator/consumer.h>
11 #include <linux/module.h>
12 #include <uapi/linux/uleds.h>
13 #include <linux/gpio/consumer.h>
15 #define LM3532_NAME "lm3532-led"
16 #define LM3532_BL_MODE_MANUAL 0x00
17 #define LM3532_BL_MODE_ALS 0x01
19 #define LM3532_REG_OUTPUT_CFG 0x10
20 #define LM3532_REG_STARTSHUT_RAMP 0x11
21 #define LM3532_REG_RT_RAMP 0x12
22 #define LM3532_REG_PWM_A_CFG 0x13
23 #define LM3532_REG_PWM_B_CFG 0x14
24 #define LM3532_REG_PWM_C_CFG 0x15
25 #define LM3532_REG_ZONE_CFG_A 0x16
26 #define LM3532_REG_CTRL_A_FS_CURR 0x17
27 #define LM3532_REG_ZONE_CFG_B 0x18
28 #define LM3532_REG_CTRL_B_FS_CURR 0x19
29 #define LM3532_REG_ZONE_CFG_C 0x1a
30 #define LM3532_REG_CTRL_C_FS_CURR 0x1b
31 #define LM3532_REG_ENABLE 0x1d
32 #define LM3532_ALS_CONFIG 0x23
33 #define LM3532_REG_ZN_0_HI 0x60
34 #define LM3532_REG_ZN_0_LO 0x61
35 #define LM3532_REG_ZN_1_HI 0x62
36 #define LM3532_REG_ZN_1_LO 0x63
37 #define LM3532_REG_ZN_2_HI 0x64
38 #define LM3532_REG_ZN_2_LO 0x65
39 #define LM3532_REG_ZN_3_HI 0x66
40 #define LM3532_REG_ZN_3_LO 0x67
41 #define LM3532_REG_ZONE_TRGT_A 0x70
42 #define LM3532_REG_ZONE_TRGT_B 0x75
43 #define LM3532_REG_ZONE_TRGT_C 0x7a
44 #define LM3532_REG_MAX 0x7e
47 #define LM3532_CTRL_A_ENABLE BIT(0)
48 #define LM3532_CTRL_B_ENABLE BIT(1)
49 #define LM3532_CTRL_C_ENABLE BIT(2)
51 /* PWM Zone Control */
52 #define LM3532_PWM_ZONE_MASK 0x7c
53 #define LM3532_PWM_ZONE_0_EN BIT(2)
54 #define LM3532_PWM_ZONE_1_EN BIT(3)
55 #define LM3532_PWM_ZONE_2_EN BIT(4)
56 #define LM3532_PWM_ZONE_3_EN BIT(5)
57 #define LM3532_PWM_ZONE_4_EN BIT(6)
59 /* Brightness Configuration */
60 #define LM3532_I2C_CTRL BIT(0)
61 #define LM3532_ALS_CTRL 0
62 #define LM3532_LINEAR_MAP BIT(1)
63 #define LM3532_ZONE_MASK (BIT(2) | BIT(3) | BIT(4))
64 #define LM3532_ZONE_0 0
65 #define LM3532_ZONE_1 BIT(2)
66 #define LM3532_ZONE_2 BIT(3)
67 #define LM3532_ZONE_3 (BIT(2) | BIT(3))
68 #define LM3532_ZONE_4 BIT(4)
70 #define LM3532_ENABLE_ALS BIT(3)
71 #define LM3532_ALS_SEL_SHIFT 6
73 /* Zone Boundary Register */
74 #define LM3532_ALS_WINDOW_mV 2000
75 #define LM3532_ALS_ZB_MAX 4
76 #define LM3532_ALS_OFFSET_mV 2
78 #define LM3532_CONTROL_A 0
79 #define LM3532_CONTROL_B 1
80 #define LM3532_CONTROL_C 2
81 #define LM3532_MAX_CONTROL_BANKS 3
82 #define LM3532_MAX_LED_STRINGS 3
84 #define LM3532_OUTPUT_CFG_MASK 0x3
85 #define LM3532_BRT_VAL_ADJUST 8
86 #define LM3532_RAMP_DOWN_SHIFT 3
88 #define LM3532_NUM_RAMP_VALS 8
89 #define LM3532_NUM_AVG_VALS 8
90 #define LM3532_NUM_IMP_VALS 32
92 #define LM3532_FS_CURR_MIN 5000
93 #define LM3532_FS_CURR_MAX 29800
94 #define LM3532_FS_CURR_STEP 800
97 * struct lm3532_als_data
98 * @config - value of ALS configuration register
99 * @als1_imp_sel - value of ALS1 resistor select register
100 * @als2_imp_sel - value of ALS2 resistor select register
101 * @als_avrg_time - ALS averaging time
102 * @als_input_mode - ALS input mode for brightness control
103 * @als_vmin - Minimum ALS voltage
104 * @als_vmax - Maximum ALS voltage
105 * @zone_lo - values of ALS lo ZB(Zone Boundary) registers
106 * @zone_hi - values of ALS hi ZB(Zone Boundary) registers
108 struct lm3532_als_data
{
116 u8 zones_lo
[LM3532_ALS_ZB_MAX
];
117 u8 zones_hi
[LM3532_ALS_ZB_MAX
];
122 * @led_dev: led class device
123 * @priv - Pointer the device data structure
124 * @control_bank - Control bank the LED is associated to
125 * @mode - Mode of the LED string
126 * @ctrl_brt_pointer - Zone target register that controls the sink
127 * @num_leds - Number of LED strings are supported in this array
128 * @full_scale_current - The full-scale current setting for the current sink.
129 * @led_strings - The LED strings supported in this array
130 * @enabled - Enabled status
134 struct led_classdev led_dev
;
135 struct lm3532_data
*priv
;
139 int ctrl_brt_pointer
;
141 int full_scale_current
;
143 u32 led_strings
[LM3532_MAX_CONTROL_BANKS
];
144 char label
[LED_MAX_NAME_SIZE
];
149 * @enable_gpio - Hardware enable gpio
150 * @regulator: regulator
151 * @client: i2c client
152 * @regmap - Devices register map
153 * @dev - Pointer to the devices device struct
154 * @lock - Lock for reading/writing the device
155 * @als_data - Pointer to the als data struct
156 * @runtime_ramp_up - Runtime ramp up setting
157 * @runtime_ramp_down - Runtime ramp down setting
158 * @leds - Array of LED strings
161 struct gpio_desc
*enable_gpio
;
162 struct regulator
*regulator
;
163 struct i2c_client
*client
;
164 struct regmap
*regmap
;
168 struct lm3532_als_data
*als_data
;
171 u32 runtime_ramp_down
;
173 struct lm3532_led leds
[];
176 static const struct reg_default lm3532_reg_defs
[] = {
177 {LM3532_REG_OUTPUT_CFG
, 0xe4},
178 {LM3532_REG_STARTSHUT_RAMP
, 0xc0},
179 {LM3532_REG_RT_RAMP
, 0xc0},
180 {LM3532_REG_PWM_A_CFG
, 0x82},
181 {LM3532_REG_PWM_B_CFG
, 0x82},
182 {LM3532_REG_PWM_C_CFG
, 0x82},
183 {LM3532_REG_ZONE_CFG_A
, 0xf1},
184 {LM3532_REG_CTRL_A_FS_CURR
, 0xf3},
185 {LM3532_REG_ZONE_CFG_B
, 0xf1},
186 {LM3532_REG_CTRL_B_FS_CURR
, 0xf3},
187 {LM3532_REG_ZONE_CFG_C
, 0xf1},
188 {LM3532_REG_CTRL_C_FS_CURR
, 0xf3},
189 {LM3532_REG_ENABLE
, 0xf8},
190 {LM3532_ALS_CONFIG
, 0x44},
191 {LM3532_REG_ZN_0_HI
, 0x35},
192 {LM3532_REG_ZN_0_LO
, 0x33},
193 {LM3532_REG_ZN_1_HI
, 0x6a},
194 {LM3532_REG_ZN_1_LO
, 0x66},
195 {LM3532_REG_ZN_2_HI
, 0xa1},
196 {LM3532_REG_ZN_2_LO
, 0x99},
197 {LM3532_REG_ZN_3_HI
, 0xdc},
198 {LM3532_REG_ZN_3_LO
, 0xcc},
201 static const struct regmap_config lm3532_regmap_config
= {
205 .max_register
= LM3532_REG_MAX
,
206 .reg_defaults
= lm3532_reg_defs
,
207 .num_reg_defaults
= ARRAY_SIZE(lm3532_reg_defs
),
208 .cache_type
= REGCACHE_FLAT
,
211 static const int als_imp_table
[LM3532_NUM_IMP_VALS
] = {37000, 18500, 12330,
212 92500, 7400, 6170, 5290,
213 4630, 4110, 3700, 3360,
214 3080, 2850, 2640, 2440,
215 2310, 2180, 2060, 1950,
216 1850, 1760, 1680, 1610,
217 1540, 1480, 1420, 1370,
218 1320, 1280, 1230, 1190};
219 static int lm3532_get_als_imp_index(int als_imped
)
223 if (als_imped
> als_imp_table
[1])
226 if (als_imped
< als_imp_table
[LM3532_NUM_IMP_VALS
- 1])
227 return LM3532_NUM_IMP_VALS
- 1;
229 for (i
= 1; i
< LM3532_NUM_IMP_VALS
; i
++) {
230 if (als_imped
== als_imp_table
[i
])
233 /* Find an approximate index by looking up the table */
234 if (als_imped
< als_imp_table
[i
- 1] &&
235 als_imped
> als_imp_table
[i
]) {
236 if (als_imped
- als_imp_table
[i
- 1] <
237 als_imp_table
[i
] - als_imped
)
247 static int lm3532_get_index(const int table
[], int size
, int value
)
251 for (i
= 1; i
< size
; i
++) {
252 if (value
== table
[i
])
255 /* Find an approximate index by looking up the table */
256 if (value
> table
[i
- 1] &&
258 if (value
- table
[i
- 1] < table
[i
] - value
)
268 static const int als_avrg_table
[LM3532_NUM_AVG_VALS
] = {17920, 35840, 71680,
269 1433360, 286720, 573440,
271 static int lm3532_get_als_avg_index(int avg_time
)
273 if (avg_time
<= als_avrg_table
[0])
276 if (avg_time
> als_avrg_table
[LM3532_NUM_AVG_VALS
- 1])
277 return LM3532_NUM_AVG_VALS
- 1;
279 return lm3532_get_index(&als_avrg_table
[0], LM3532_NUM_AVG_VALS
,
283 static const int ramp_table
[LM3532_NUM_RAMP_VALS
] = { 8, 1024, 2048, 4096, 8192,
284 16384, 32768, 65536};
285 static int lm3532_get_ramp_index(int ramp_time
)
287 if (ramp_time
<= ramp_table
[0])
290 if (ramp_time
> ramp_table
[LM3532_NUM_RAMP_VALS
- 1])
291 return LM3532_NUM_RAMP_VALS
- 1;
293 return lm3532_get_index(&ramp_table
[0], LM3532_NUM_RAMP_VALS
,
297 /* Caller must take care of locking */
298 static int lm3532_led_enable(struct lm3532_led
*led_data
)
300 int ctrl_en_val
= BIT(led_data
->control_bank
);
303 if (led_data
->enabled
)
306 ret
= regmap_update_bits(led_data
->priv
->regmap
, LM3532_REG_ENABLE
,
307 ctrl_en_val
, ctrl_en_val
);
309 dev_err(led_data
->priv
->dev
, "Failed to set ctrl:%d\n", ret
);
313 ret
= regulator_enable(led_data
->priv
->regulator
);
317 led_data
->enabled
= 1;
322 /* Caller must take care of locking */
323 static int lm3532_led_disable(struct lm3532_led
*led_data
)
325 int ctrl_en_val
= BIT(led_data
->control_bank
);
328 if (!led_data
->enabled
)
331 ret
= regmap_update_bits(led_data
->priv
->regmap
, LM3532_REG_ENABLE
,
334 dev_err(led_data
->priv
->dev
, "Failed to set ctrl:%d\n", ret
);
338 ret
= regulator_disable(led_data
->priv
->regulator
);
342 led_data
->enabled
= 0;
347 static int lm3532_brightness_set(struct led_classdev
*led_cdev
,
348 enum led_brightness brt_val
)
350 struct lm3532_led
*led
=
351 container_of(led_cdev
, struct lm3532_led
, led_dev
);
355 mutex_lock(&led
->priv
->lock
);
357 if (led
->mode
== LM3532_ALS_CTRL
) {
358 if (brt_val
> LED_OFF
)
359 ret
= lm3532_led_enable(led
);
361 ret
= lm3532_led_disable(led
);
366 if (brt_val
== LED_OFF
) {
367 ret
= lm3532_led_disable(led
);
371 ret
= lm3532_led_enable(led
);
375 brightness_reg
= LM3532_REG_ZONE_TRGT_A
+ led
->control_bank
* 5 +
376 (led
->ctrl_brt_pointer
>> 2);
378 ret
= regmap_write(led
->priv
->regmap
, brightness_reg
, brt_val
);
381 mutex_unlock(&led
->priv
->lock
);
385 static int lm3532_init_registers(struct lm3532_led
*led
)
387 struct lm3532_data
*drvdata
= led
->priv
;
388 unsigned int runtime_ramp_val
;
389 unsigned int output_cfg_val
= 0;
390 unsigned int output_cfg_shift
= 0;
391 unsigned int output_cfg_mask
= 0;
392 unsigned int brightness_config_reg
;
393 unsigned int brightness_config_val
;
398 if (drvdata
->enable_gpio
)
399 gpiod_direction_output(drvdata
->enable_gpio
, 1);
401 brightness_config_reg
= LM3532_REG_ZONE_CFG_A
+ led
->control_bank
* 2;
403 * This could be hard coded to the default value but the control
404 * brightness register may have changed during boot.
406 ret
= regmap_read(drvdata
->regmap
, brightness_config_reg
,
407 &led
->ctrl_brt_pointer
);
411 led
->ctrl_brt_pointer
&= LM3532_ZONE_MASK
;
412 brightness_config_val
= led
->ctrl_brt_pointer
| led
->mode
;
413 ret
= regmap_write(drvdata
->regmap
, brightness_config_reg
,
414 brightness_config_val
);
418 if (led
->full_scale_current
) {
419 fs_current_reg
= LM3532_REG_CTRL_A_FS_CURR
+ led
->control_bank
* 2;
420 fs_current_val
= (led
->full_scale_current
- LM3532_FS_CURR_MIN
) /
423 ret
= regmap_write(drvdata
->regmap
, fs_current_reg
,
429 for (i
= 0; i
< led
->num_leds
; i
++) {
430 output_cfg_shift
= led
->led_strings
[i
] * 2;
431 output_cfg_val
|= (led
->control_bank
<< output_cfg_shift
);
432 output_cfg_mask
|= LM3532_OUTPUT_CFG_MASK
<< output_cfg_shift
;
435 ret
= regmap_update_bits(drvdata
->regmap
, LM3532_REG_OUTPUT_CFG
,
436 output_cfg_mask
, output_cfg_val
);
440 runtime_ramp_val
= drvdata
->runtime_ramp_up
|
441 (drvdata
->runtime_ramp_down
<< LM3532_RAMP_DOWN_SHIFT
);
443 return regmap_write(drvdata
->regmap
, LM3532_REG_RT_RAMP
,
447 static int lm3532_als_configure(struct lm3532_data
*priv
,
448 struct lm3532_led
*led
)
450 struct lm3532_als_data
*als
= priv
->als_data
;
451 u32 als_vmin
, als_vmax
, als_vstep
;
452 int zone_reg
= LM3532_REG_ZN_0_HI
;
456 als_vmin
= als
->als_vmin
;
457 als_vmax
= als
->als_vmax
;
459 als_vstep
= (als_vmax
- als_vmin
) / ((LM3532_ALS_ZB_MAX
+ 1) * 2);
461 for (i
= 0; i
< LM3532_ALS_ZB_MAX
; i
++) {
462 als
->zones_lo
[i
] = ((als_vmin
+ als_vstep
+ (i
* als_vstep
)) *
464 als
->zones_hi
[i
] = ((als_vmin
+ LM3532_ALS_OFFSET_mV
+
465 als_vstep
+ (i
* als_vstep
)) * LED_FULL
) / 1000;
467 zone_reg
= LM3532_REG_ZN_0_HI
+ i
* 2;
468 ret
= regmap_write(priv
->regmap
, zone_reg
, als
->zones_lo
[i
]);
473 ret
= regmap_write(priv
->regmap
, zone_reg
, als
->zones_hi
[i
]);
478 als
->config
= (als
->als_avrg_time
| (LM3532_ENABLE_ALS
) |
479 (als
->als_input_mode
<< LM3532_ALS_SEL_SHIFT
));
481 return regmap_write(priv
->regmap
, LM3532_ALS_CONFIG
, als
->config
);
484 static int lm3532_parse_als(struct lm3532_data
*priv
)
486 struct lm3532_als_data
*als
;
491 als
= devm_kzalloc(priv
->dev
, sizeof(*als
), GFP_KERNEL
);
495 ret
= device_property_read_u32(&priv
->client
->dev
, "ti,als-vmin",
500 ret
= device_property_read_u32(&priv
->client
->dev
, "ti,als-vmax",
503 als
->als_vmax
= LM3532_ALS_WINDOW_mV
;
505 if (als
->als_vmax
> LM3532_ALS_WINDOW_mV
) {
510 ret
= device_property_read_u32(&priv
->client
->dev
, "ti,als1-imp-sel",
513 als
->als1_imp_sel
= 0;
515 als
->als1_imp_sel
= lm3532_get_als_imp_index(als_impedance
);
517 ret
= device_property_read_u32(&priv
->client
->dev
, "ti,als2-imp-sel",
520 als
->als2_imp_sel
= 0;
522 als
->als2_imp_sel
= lm3532_get_als_imp_index(als_impedance
);
524 ret
= device_property_read_u32(&priv
->client
->dev
, "ti,als-avrg-time-us",
527 als
->als_avrg_time
= 0;
529 als
->als_avrg_time
= lm3532_get_als_avg_index(als_avg_time
);
531 ret
= device_property_read_u8(&priv
->client
->dev
, "ti,als-input-mode",
532 &als
->als_input_mode
);
534 als
->als_input_mode
= 0;
536 if (als
->als_input_mode
> LM3532_BL_MODE_ALS
) {
541 priv
->als_data
= als
;
546 static int lm3532_parse_node(struct lm3532_data
*priv
)
548 struct fwnode_handle
*child
= NULL
;
549 struct lm3532_led
*led
;
556 priv
->enable_gpio
= devm_gpiod_get_optional(&priv
->client
->dev
,
557 "enable", GPIOD_OUT_LOW
);
558 if (IS_ERR(priv
->enable_gpio
))
559 priv
->enable_gpio
= NULL
;
561 priv
->regulator
= devm_regulator_get(&priv
->client
->dev
, "vin");
562 if (IS_ERR(priv
->regulator
))
563 priv
->regulator
= NULL
;
565 ret
= device_property_read_u32(&priv
->client
->dev
, "ramp-up-us",
568 dev_info(&priv
->client
->dev
, "ramp-up-ms property missing\n");
570 priv
->runtime_ramp_up
= lm3532_get_ramp_index(ramp_time
);
572 ret
= device_property_read_u32(&priv
->client
->dev
, "ramp-down-us",
575 dev_info(&priv
->client
->dev
, "ramp-down-ms property missing\n");
577 priv
->runtime_ramp_down
= lm3532_get_ramp_index(ramp_time
);
579 device_for_each_child_node(priv
->dev
, child
) {
580 led
= &priv
->leds
[i
];
582 ret
= fwnode_property_read_u32(child
, "reg", &control_bank
);
584 dev_err(&priv
->client
->dev
, "reg property missing\n");
585 fwnode_handle_put(child
);
589 if (control_bank
> LM3532_CONTROL_C
) {
590 dev_err(&priv
->client
->dev
, "Control bank invalid\n");
594 led
->control_bank
= control_bank
;
596 ret
= fwnode_property_read_u32(child
, "ti,led-mode",
599 dev_err(&priv
->client
->dev
, "ti,led-mode property missing\n");
600 fwnode_handle_put(child
);
604 if (fwnode_property_present(child
, "led-max-microamp") &&
605 fwnode_property_read_u32(child
, "led-max-microamp",
606 &led
->full_scale_current
))
607 dev_err(&priv
->client
->dev
,
608 "Failed getting led-max-microamp\n");
610 led
->full_scale_current
= min(led
->full_scale_current
,
613 if (led
->mode
== LM3532_BL_MODE_ALS
) {
614 led
->mode
= LM3532_ALS_CTRL
;
615 ret
= lm3532_parse_als(priv
);
617 dev_err(&priv
->client
->dev
, "Failed to parse als\n");
619 lm3532_als_configure(priv
, led
);
621 led
->mode
= LM3532_I2C_CTRL
;
624 led
->num_leds
= fwnode_property_count_u32(child
, "led-sources");
625 if (led
->num_leds
> LM3532_MAX_LED_STRINGS
) {
626 dev_err(&priv
->client
->dev
, "To many LED string defined\n");
630 ret
= fwnode_property_read_u32_array(child
, "led-sources",
634 dev_err(&priv
->client
->dev
, "led-sources property missing\n");
635 fwnode_handle_put(child
);
639 fwnode_property_read_string(child
, "linux,default-trigger",
640 &led
->led_dev
.default_trigger
);
642 ret
= fwnode_property_read_string(child
, "label", &name
);
644 snprintf(led
->label
, sizeof(led
->label
),
645 "%s::", priv
->client
->name
);
647 snprintf(led
->label
, sizeof(led
->label
),
648 "%s:%s", priv
->client
->name
, name
);
651 led
->led_dev
.name
= led
->label
;
652 led
->led_dev
.brightness_set_blocking
= lm3532_brightness_set
;
654 ret
= devm_led_classdev_register(priv
->dev
, &led
->led_dev
);
656 dev_err(&priv
->client
->dev
, "led register err: %d\n",
658 fwnode_handle_put(child
);
662 ret
= lm3532_init_registers(led
);
664 dev_err(&priv
->client
->dev
, "register init err: %d\n",
666 fwnode_handle_put(child
);
677 static int lm3532_probe(struct i2c_client
*client
,
678 const struct i2c_device_id
*id
)
680 struct lm3532_data
*drvdata
;
684 count
= device_get_child_node_count(&client
->dev
);
686 dev_err(&client
->dev
, "LEDs are not defined in device tree!");
690 drvdata
= devm_kzalloc(&client
->dev
, struct_size(drvdata
, leds
, count
),
695 drvdata
->client
= client
;
696 drvdata
->dev
= &client
->dev
;
698 drvdata
->regmap
= devm_regmap_init_i2c(client
, &lm3532_regmap_config
);
699 if (IS_ERR(drvdata
->regmap
)) {
700 ret
= PTR_ERR(drvdata
->regmap
);
701 dev_err(&client
->dev
, "Failed to allocate register map: %d\n",
706 mutex_init(&drvdata
->lock
);
707 i2c_set_clientdata(client
, drvdata
);
709 ret
= lm3532_parse_node(drvdata
);
711 dev_err(&client
->dev
, "Failed to parse node\n");
718 static int lm3532_remove(struct i2c_client
*client
)
720 struct lm3532_data
*drvdata
= i2c_get_clientdata(client
);
722 mutex_destroy(&drvdata
->lock
);
724 if (drvdata
->enable_gpio
)
725 gpiod_direction_output(drvdata
->enable_gpio
, 0);
730 static const struct of_device_id of_lm3532_leds_match
[] = {
731 { .compatible
= "ti,lm3532", },
734 MODULE_DEVICE_TABLE(of
, of_lm3532_leds_match
);
736 static const struct i2c_device_id lm3532_id
[] = {
740 MODULE_DEVICE_TABLE(i2c
, lm3532_id
);
742 static struct i2c_driver lm3532_i2c_driver
= {
743 .probe
= lm3532_probe
,
744 .remove
= lm3532_remove
,
745 .id_table
= lm3532_id
,
748 .of_match_table
= of_lm3532_leds_match
,
751 module_i2c_driver(lm3532_i2c_driver
);
753 MODULE_DESCRIPTION("Back Light driver for LM3532");
754 MODULE_LICENSE("GPL v2");
755 MODULE_AUTHOR("Dan Murphy <dmurphy@ti.com>");