spi: sprd: adi: Add a reset reason for watchdog mode
[linux/fpc-iii.git] / drivers / leds / leds-lm3532.c
blob180895b83b888c635f0810fbbb7595217982d0bf
1 // SPDX-License-Identifier: GPL-2.0
2 // TI LM3532 LED driver
3 // Copyright (C) 2019 Texas Instruments Incorporated - http://www.ti.com/
5 #include <linux/i2c.h>
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_BRT 0x17
27 #define LM3532_REG_ZONE_CFG_B 0x18
28 #define LM3532_REG_CTRL_B_BRT 0x19
29 #define LM3532_REG_ZONE_CFG_C 0x1a
30 #define LM3532_REG_CTRL_C_BRT 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_MAX 0x7e
43 /* Contorl Enable */
44 #define LM3532_CTRL_A_ENABLE BIT(0)
45 #define LM3532_CTRL_B_ENABLE BIT(1)
46 #define LM3532_CTRL_C_ENABLE BIT(2)
48 /* PWM Zone Control */
49 #define LM3532_PWM_ZONE_MASK 0x7c
50 #define LM3532_PWM_ZONE_0_EN BIT(2)
51 #define LM3532_PWM_ZONE_1_EN BIT(3)
52 #define LM3532_PWM_ZONE_2_EN BIT(4)
53 #define LM3532_PWM_ZONE_3_EN BIT(5)
54 #define LM3532_PWM_ZONE_4_EN BIT(6)
56 /* Brightness Configuration */
57 #define LM3532_I2C_CTRL BIT(0)
58 #define LM3532_ALS_CTRL 0
59 #define LM3532_LINEAR_MAP BIT(1)
60 #define LM3532_ZONE_MASK (BIT(2) | BIT(3) | BIT(4))
61 #define LM3532_ZONE_0 0
62 #define LM3532_ZONE_1 BIT(2)
63 #define LM3532_ZONE_2 BIT(3)
64 #define LM3532_ZONE_3 (BIT(2) | BIT(3))
65 #define LM3532_ZONE_4 BIT(4)
67 #define LM3532_ENABLE_ALS BIT(3)
68 #define LM3532_ALS_SEL_SHIFT 6
70 /* Zone Boundary Register */
71 #define LM3532_ALS_WINDOW_mV 2000
72 #define LM3532_ALS_ZB_MAX 4
73 #define LM3532_ALS_OFFSET_mV 2
75 #define LM3532_CONTROL_A 0
76 #define LM3532_CONTROL_B 1
77 #define LM3532_CONTROL_C 2
78 #define LM3532_MAX_CONTROL_BANKS 3
79 #define LM3532_MAX_LED_STRINGS 3
81 #define LM3532_OUTPUT_CFG_MASK 0x3
82 #define LM3532_BRT_VAL_ADJUST 8
83 #define LM3532_RAMP_DOWN_SHIFT 3
85 #define LM3532_NUM_RAMP_VALS 8
86 #define LM3532_NUM_AVG_VALS 8
87 #define LM3532_NUM_IMP_VALS 32
90 * struct lm3532_als_data
91 * @config - value of ALS configuration register
92 * @als1_imp_sel - value of ALS1 resistor select register
93 * @als2_imp_sel - value of ALS2 resistor select register
94 * @als_avrg_time - ALS averaging time
95 * @als_input_mode - ALS input mode for brightness control
96 * @als_vmin - Minimum ALS voltage
97 * @als_vmax - Maximum ALS voltage
98 * @zone_lo - values of ALS lo ZB(Zone Boundary) registers
99 * @zone_hi - values of ALS hi ZB(Zone Boundary) registers
101 struct lm3532_als_data {
102 u8 config;
103 u8 als1_imp_sel;
104 u8 als2_imp_sel;
105 u8 als_avrg_time;
106 u8 als_input_mode;
107 u32 als_vmin;
108 u32 als_vmax;
109 u8 zones_lo[LM3532_ALS_ZB_MAX];
110 u8 zones_hi[LM3532_ALS_ZB_MAX];
114 * struct lm3532_led
115 * @led_dev: led class device
116 * @priv - Pointer the device data structure
117 * @control_bank - Control bank the LED is associated to
118 * @mode - Mode of the LED string
119 * @num_leds - Number of LED strings are supported in this array
120 * @led_strings - The LED strings supported in this array
121 * @label - LED label
123 struct lm3532_led {
124 struct led_classdev led_dev;
125 struct lm3532_data *priv;
127 int control_bank;
128 int mode;
129 int num_leds;
130 u32 led_strings[LM3532_MAX_CONTROL_BANKS];
131 char label[LED_MAX_NAME_SIZE];
135 * struct lm3532_data
136 * @enable_gpio - Hardware enable gpio
137 * @regulator: regulator
138 * @client: i2c client
139 * @regmap - Devices register map
140 * @dev - Pointer to the devices device struct
141 * @lock - Lock for reading/writing the device
142 * @als_data - Pointer to the als data struct
143 * @runtime_ramp_up - Runtime ramp up setting
144 * @runtime_ramp_down - Runtime ramp down setting
145 * @leds - Array of LED strings
147 struct lm3532_data {
148 struct gpio_desc *enable_gpio;
149 struct regulator *regulator;
150 struct i2c_client *client;
151 struct regmap *regmap;
152 struct device *dev;
153 struct mutex lock;
155 struct lm3532_als_data *als_data;
157 u32 runtime_ramp_up;
158 u32 runtime_ramp_down;
160 struct lm3532_led leds[];
163 static const struct reg_default lm3532_reg_defs[] = {
164 {LM3532_REG_OUTPUT_CFG, 0xe4},
165 {LM3532_REG_STARTSHUT_RAMP, 0xc0},
166 {LM3532_REG_RT_RAMP, 0xc0},
167 {LM3532_REG_PWM_A_CFG, 0x82},
168 {LM3532_REG_PWM_B_CFG, 0x82},
169 {LM3532_REG_PWM_C_CFG, 0x82},
170 {LM3532_REG_ZONE_CFG_A, 0xf1},
171 {LM3532_REG_CTRL_A_BRT, 0xf3},
172 {LM3532_REG_ZONE_CFG_B, 0xf1},
173 {LM3532_REG_CTRL_B_BRT, 0xf3},
174 {LM3532_REG_ZONE_CFG_C, 0xf1},
175 {LM3532_REG_CTRL_C_BRT, 0xf3},
176 {LM3532_REG_ENABLE, 0xf8},
177 {LM3532_ALS_CONFIG, 0x44},
178 {LM3532_REG_ZN_0_HI, 0x35},
179 {LM3532_REG_ZN_0_LO, 0x33},
180 {LM3532_REG_ZN_1_HI, 0x6a},
181 {LM3532_REG_ZN_1_LO, 0x66},
182 {LM3532_REG_ZN_2_HI, 0xa1},
183 {LM3532_REG_ZN_2_LO, 0x99},
184 {LM3532_REG_ZN_3_HI, 0xdc},
185 {LM3532_REG_ZN_3_LO, 0xcc},
188 static const struct regmap_config lm3532_regmap_config = {
189 .reg_bits = 8,
190 .val_bits = 8,
192 .max_register = LM3532_REG_MAX,
193 .reg_defaults = lm3532_reg_defs,
194 .num_reg_defaults = ARRAY_SIZE(lm3532_reg_defs),
195 .cache_type = REGCACHE_FLAT,
198 const static int als_imp_table[LM3532_NUM_IMP_VALS] = {37000, 18500, 12330,
199 92500, 7400, 6170, 5290,
200 4630, 4110, 3700, 3360,
201 3080, 2850, 2640, 2440,
202 2310, 2180, 2060, 1950,
203 1850, 1760, 1680, 1610,
204 1540, 1480, 1420, 1370,
205 1320, 1280, 1230, 1190};
206 static int lm3532_get_als_imp_index(int als_imped)
208 int i;
210 if (als_imped > als_imp_table[1])
211 return 0;
213 if (als_imped < als_imp_table[LM3532_NUM_IMP_VALS - 1])
214 return LM3532_NUM_IMP_VALS - 1;
216 for (i = 1; i < LM3532_NUM_IMP_VALS; i++) {
217 if (als_imped == als_imp_table[i])
218 return i;
220 /* Find an approximate index by looking up the table */
221 if (als_imped < als_imp_table[i - 1] &&
222 als_imped > als_imp_table[i]) {
223 if (als_imped - als_imp_table[i - 1] <
224 als_imp_table[i] - als_imped)
225 return i + 1;
226 else
227 return i;
231 return -EINVAL;
234 static int lm3532_get_index(const int table[], int size, int value)
236 int i;
238 for (i = 1; i < size; i++) {
239 if (value == table[i])
240 return i;
242 /* Find an approximate index by looking up the table */
243 if (value > table[i - 1] &&
244 value < table[i]) {
245 if (value - table[i - 1] < table[i] - value)
246 return i - 1;
247 else
248 return i;
252 return -EINVAL;
255 const static int als_avrg_table[LM3532_NUM_AVG_VALS] = {17920, 35840, 71680,
256 1433360, 286720, 573440,
257 1146880, 2293760};
258 static int lm3532_get_als_avg_index(int avg_time)
260 if (avg_time <= als_avrg_table[0])
261 return 0;
263 if (avg_time > als_avrg_table[LM3532_NUM_AVG_VALS - 1])
264 return LM3532_NUM_AVG_VALS - 1;
266 return lm3532_get_index(&als_avrg_table[0], LM3532_NUM_AVG_VALS,
267 avg_time);
270 const static int ramp_table[LM3532_NUM_RAMP_VALS] = { 8, 1024, 2048, 4096, 8192,
271 16384, 32768, 65536};
272 static int lm3532_get_ramp_index(int ramp_time)
274 if (ramp_time <= ramp_table[0])
275 return 0;
277 if (ramp_time > ramp_table[LM3532_NUM_RAMP_VALS - 1])
278 return LM3532_NUM_RAMP_VALS - 1;
280 return lm3532_get_index(&ramp_table[0], LM3532_NUM_RAMP_VALS,
281 ramp_time);
284 static int lm3532_led_enable(struct lm3532_led *led_data)
286 int ctrl_en_val = BIT(led_data->control_bank);
287 int ret;
289 ret = regmap_update_bits(led_data->priv->regmap, LM3532_REG_ENABLE,
290 ctrl_en_val, ctrl_en_val);
291 if (ret) {
292 dev_err(led_data->priv->dev, "Failed to set ctrl:%d\n", ret);
293 return ret;
296 return regulator_enable(led_data->priv->regulator);
299 static int lm3532_led_disable(struct lm3532_led *led_data)
301 int ctrl_en_val = BIT(led_data->control_bank);
302 int ret;
304 ret = regmap_update_bits(led_data->priv->regmap, LM3532_REG_ENABLE,
305 ctrl_en_val, ~ctrl_en_val);
306 if (ret) {
307 dev_err(led_data->priv->dev, "Failed to set ctrl:%d\n", ret);
308 return ret;
311 return regulator_disable(led_data->priv->regulator);
314 static int lm3532_brightness_set(struct led_classdev *led_cdev,
315 enum led_brightness brt_val)
317 struct lm3532_led *led =
318 container_of(led_cdev, struct lm3532_led, led_dev);
319 u8 brightness_reg;
320 int ret;
322 mutex_lock(&led->priv->lock);
324 if (led->mode == LM3532_BL_MODE_ALS) {
325 if (brt_val > LED_OFF)
326 ret = lm3532_led_enable(led);
327 else
328 ret = lm3532_led_disable(led);
330 goto unlock;
333 if (brt_val == LED_OFF) {
334 ret = lm3532_led_disable(led);
335 goto unlock;
338 ret = lm3532_led_enable(led);
339 if (ret)
340 goto unlock;
342 brightness_reg = LM3532_REG_CTRL_A_BRT + led->control_bank * 2;
343 brt_val = brt_val / LM3532_BRT_VAL_ADJUST;
345 ret = regmap_write(led->priv->regmap, brightness_reg, brt_val);
347 unlock:
348 mutex_unlock(&led->priv->lock);
349 return ret;
352 static int lm3532_init_registers(struct lm3532_led *led)
354 struct lm3532_data *drvdata = led->priv;
355 unsigned int runtime_ramp_val;
356 unsigned int output_cfg_val = 0;
357 unsigned int output_cfg_shift = 0;
358 unsigned int output_cfg_mask = 0;
359 int ret, i;
361 for (i = 0; i < led->num_leds; i++) {
362 output_cfg_shift = led->led_strings[i] * 2;
363 output_cfg_val |= (led->control_bank << output_cfg_shift);
364 output_cfg_mask |= LM3532_OUTPUT_CFG_MASK << output_cfg_shift;
367 ret = regmap_update_bits(drvdata->regmap, LM3532_REG_OUTPUT_CFG,
368 output_cfg_mask, output_cfg_val);
369 if (ret)
370 return ret;
372 runtime_ramp_val = drvdata->runtime_ramp_up |
373 (drvdata->runtime_ramp_down << LM3532_RAMP_DOWN_SHIFT);
375 return regmap_write(drvdata->regmap, LM3532_REG_RT_RAMP,
376 runtime_ramp_val);
379 static int lm3532_als_configure(struct lm3532_data *priv,
380 struct lm3532_led *led)
382 struct lm3532_als_data *als = priv->als_data;
383 u32 als_vmin, als_vmax, als_vstep;
384 int zone_reg = LM3532_REG_ZN_0_HI;
385 int brightnes_config_reg;
386 int ret;
387 int i;
389 als_vmin = als->als_vmin;
390 als_vmax = als->als_vmax;
392 als_vstep = (als_vmax - als_vmin) / ((LM3532_ALS_ZB_MAX + 1) * 2);
394 for (i = 0; i < LM3532_ALS_ZB_MAX; i++) {
395 als->zones_lo[i] = ((als_vmin + als_vstep + (i * als_vstep)) *
396 LED_FULL) / 1000;
397 als->zones_hi[i] = ((als_vmin + LM3532_ALS_OFFSET_mV +
398 als_vstep + (i * als_vstep)) * LED_FULL) / 1000;
400 zone_reg = LM3532_REG_ZN_0_HI + i * 2;
401 ret = regmap_write(priv->regmap, zone_reg, als->zones_lo[i]);
402 if (ret)
403 return ret;
405 zone_reg += 1;
406 ret = regmap_write(priv->regmap, zone_reg, als->zones_hi[i]);
407 if (ret)
408 return ret;
411 als->config = (als->als_avrg_time | (LM3532_ENABLE_ALS) |
412 (als->als_input_mode << LM3532_ALS_SEL_SHIFT));
414 ret = regmap_write(priv->regmap, LM3532_ALS_CONFIG, als->config);
415 if (ret)
416 return ret;
418 brightnes_config_reg = LM3532_REG_ZONE_CFG_A + led->control_bank * 2;
420 return regmap_update_bits(priv->regmap, brightnes_config_reg,
421 LM3532_I2C_CTRL, LM3532_ALS_CTRL);
424 static int lm3532_parse_als(struct lm3532_data *priv)
426 struct lm3532_als_data *als;
427 int als_avg_time;
428 int als_impedance;
429 int ret;
431 als = devm_kzalloc(priv->dev, sizeof(*als), GFP_KERNEL);
432 if (als == NULL)
433 return -ENOMEM;
435 ret = device_property_read_u32(&priv->client->dev, "ti,als-vmin",
436 &als->als_vmin);
437 if (ret)
438 als->als_vmin = 0;
440 ret = device_property_read_u32(&priv->client->dev, "ti,als-vmax",
441 &als->als_vmax);
442 if (ret)
443 als->als_vmax = LM3532_ALS_WINDOW_mV;
445 if (als->als_vmax > LM3532_ALS_WINDOW_mV) {
446 ret = -EINVAL;
447 return ret;
450 ret = device_property_read_u32(&priv->client->dev, "ti,als1-imp-sel",
451 &als_impedance);
452 if (ret)
453 als->als1_imp_sel = 0;
454 else
455 als->als1_imp_sel = lm3532_get_als_imp_index(als_impedance);
457 ret = device_property_read_u32(&priv->client->dev, "ti,als2-imp-sel",
458 &als_impedance);
459 if (ret)
460 als->als2_imp_sel = 0;
461 else
462 als->als2_imp_sel = lm3532_get_als_imp_index(als_impedance);
464 ret = device_property_read_u32(&priv->client->dev, "ti,als-avrg-time-us",
465 &als_avg_time);
466 if (ret)
467 als->als_avrg_time = 0;
468 else
469 als->als_avrg_time = lm3532_get_als_avg_index(als_avg_time);
471 ret = device_property_read_u8(&priv->client->dev, "ti,als-input-mode",
472 &als->als_input_mode);
473 if (ret)
474 als->als_input_mode = 0;
476 if (als->als_input_mode > LM3532_BL_MODE_ALS) {
477 ret = -EINVAL;
478 return ret;
481 priv->als_data = als;
483 return ret;
486 static int lm3532_parse_node(struct lm3532_data *priv)
488 struct fwnode_handle *child = NULL;
489 struct lm3532_led *led;
490 const char *name;
491 int control_bank;
492 u32 ramp_time;
493 size_t i = 0;
494 int ret;
496 priv->enable_gpio = devm_gpiod_get_optional(&priv->client->dev,
497 "enable", GPIOD_OUT_LOW);
498 if (IS_ERR(priv->enable_gpio))
499 priv->enable_gpio = NULL;
501 priv->regulator = devm_regulator_get(&priv->client->dev, "vin");
502 if (IS_ERR(priv->regulator))
503 priv->regulator = NULL;
505 ret = device_property_read_u32(&priv->client->dev, "ramp-up-us",
506 &ramp_time);
507 if (ret)
508 dev_info(&priv->client->dev, "ramp-up-ms property missing\n");
509 else
510 priv->runtime_ramp_up = lm3532_get_ramp_index(ramp_time);
512 ret = device_property_read_u32(&priv->client->dev, "ramp-down-us",
513 &ramp_time);
514 if (ret)
515 dev_info(&priv->client->dev, "ramp-down-ms property missing\n");
516 else
517 priv->runtime_ramp_down = lm3532_get_ramp_index(ramp_time);
519 device_for_each_child_node(priv->dev, child) {
520 led = &priv->leds[i];
522 ret = fwnode_property_read_u32(child, "reg", &control_bank);
523 if (ret) {
524 dev_err(&priv->client->dev, "reg property missing\n");
525 fwnode_handle_put(child);
526 goto child_out;
529 if (control_bank > LM3532_CONTROL_C) {
530 dev_err(&priv->client->dev, "Control bank invalid\n");
531 continue;
534 led->control_bank = control_bank;
536 ret = fwnode_property_read_u32(child, "ti,led-mode",
537 &led->mode);
538 if (ret) {
539 dev_err(&priv->client->dev, "ti,led-mode property missing\n");
540 fwnode_handle_put(child);
541 goto child_out;
544 if (led->mode == LM3532_BL_MODE_ALS) {
545 ret = lm3532_parse_als(priv);
546 if (ret)
547 dev_err(&priv->client->dev, "Failed to parse als\n");
548 else
549 lm3532_als_configure(priv, led);
552 led->num_leds = fwnode_property_read_u32_array(child,
553 "led-sources",
554 NULL, 0);
556 if (led->num_leds > LM3532_MAX_LED_STRINGS) {
557 dev_err(&priv->client->dev, "To many LED string defined\n");
558 continue;
561 ret = fwnode_property_read_u32_array(child, "led-sources",
562 led->led_strings,
563 led->num_leds);
564 if (ret) {
565 dev_err(&priv->client->dev, "led-sources property missing\n");
566 fwnode_handle_put(child);
567 goto child_out;
570 fwnode_property_read_string(child, "linux,default-trigger",
571 &led->led_dev.default_trigger);
573 ret = fwnode_property_read_string(child, "label", &name);
574 if (ret)
575 snprintf(led->label, sizeof(led->label),
576 "%s::", priv->client->name);
577 else
578 snprintf(led->label, sizeof(led->label),
579 "%s:%s", priv->client->name, name);
581 led->priv = priv;
582 led->led_dev.name = led->label;
583 led->led_dev.brightness_set_blocking = lm3532_brightness_set;
585 ret = devm_led_classdev_register(priv->dev, &led->led_dev);
586 if (ret) {
587 dev_err(&priv->client->dev, "led register err: %d\n",
588 ret);
589 fwnode_handle_put(child);
590 goto child_out;
593 lm3532_init_registers(led);
595 i++;
598 child_out:
599 return ret;
602 static int lm3532_probe(struct i2c_client *client,
603 const struct i2c_device_id *id)
605 struct lm3532_data *drvdata;
606 int ret = 0;
607 int count;
609 count = device_get_child_node_count(&client->dev);
610 if (!count) {
611 dev_err(&client->dev, "LEDs are not defined in device tree!");
612 return -ENODEV;
615 drvdata = devm_kzalloc(&client->dev, struct_size(drvdata, leds, count),
616 GFP_KERNEL);
617 if (drvdata == NULL)
618 return -ENOMEM;
620 drvdata->client = client;
621 drvdata->dev = &client->dev;
623 drvdata->regmap = devm_regmap_init_i2c(client, &lm3532_regmap_config);
624 if (IS_ERR(drvdata->regmap)) {
625 ret = PTR_ERR(drvdata->regmap);
626 dev_err(&client->dev, "Failed to allocate register map: %d\n",
627 ret);
628 return ret;
631 mutex_init(&drvdata->lock);
632 i2c_set_clientdata(client, drvdata);
634 ret = lm3532_parse_node(drvdata);
635 if (ret) {
636 dev_err(&client->dev, "Failed to parse node\n");
637 return ret;
640 if (drvdata->enable_gpio)
641 gpiod_direction_output(drvdata->enable_gpio, 1);
643 return ret;
646 static int lm3532_remove(struct i2c_client *client)
648 struct lm3532_data *drvdata = i2c_get_clientdata(client);
650 mutex_destroy(&drvdata->lock);
652 if (drvdata->enable_gpio)
653 gpiod_direction_output(drvdata->enable_gpio, 0);
655 return 0;
658 static const struct of_device_id of_lm3532_leds_match[] = {
659 { .compatible = "ti,lm3532", },
662 MODULE_DEVICE_TABLE(of, of_lm3532_leds_match);
664 static const struct i2c_device_id lm3532_id[] = {
665 {LM3532_NAME, 0},
668 MODULE_DEVICE_TABLE(i2c, lm3532_id);
670 static struct i2c_driver lm3532_i2c_driver = {
671 .probe = lm3532_probe,
672 .remove = lm3532_remove,
673 .id_table = lm3532_id,
674 .driver = {
675 .name = LM3532_NAME,
676 .of_match_table = of_lm3532_leds_match,
679 module_i2c_driver(lm3532_i2c_driver);
681 MODULE_DESCRIPTION("Back Light driver for LM3532");
682 MODULE_LICENSE("GPL v2");
683 MODULE_AUTHOR("Dan Murphy <dmurphy@ti.com>");