forked from ~ljy/RK356X_SDK_RELEASE

hc
2024-05-11 297b60346df8beafee954a0fd7c2d64f33f3b9bc
kernel/drivers/leds/leds-lm3692x.c
....@@ -1,11 +1,12 @@
11 // SPDX-License-Identifier: GPL-2.0
22 // TI LM3692x LED chip family driver
3
-// Copyright (C) 2017-18 Texas Instruments Incorporated - http://www.ti.com/
3
+// Copyright (C) 2017-18 Texas Instruments Incorporated - https://www.ti.com/
44
55 #include <linux/gpio/consumer.h>
66 #include <linux/i2c.h>
77 #include <linux/init.h>
88 #include <linux/leds.h>
9
+#include <linux/log2.h>
910 #include <linux/module.h>
1011 #include <linux/mutex.h>
1112 #include <linux/of.h>
....@@ -13,7 +14,6 @@
1314 #include <linux/regmap.h>
1415 #include <linux/regulator/consumer.h>
1516 #include <linux/slab.h>
16
-#include <uapi/linux/uleds.h>
1717
1818 #define LM36922_MODEL 0
1919 #define LM36923_MODEL 1
....@@ -103,7 +103,6 @@
103103 * @regmap - Devices register map
104104 * @enable_gpio - VDDIO/EN gpio to enable communication interface
105105 * @regulator - LED supply regulator pointer
106
- * @label - LED label
107106 * @led_enable - LED sync to be enabled
108107 * @model_id - Current device model ID enumerated
109108 */
....@@ -114,9 +113,11 @@
114113 struct regmap *regmap;
115114 struct gpio_desc *enable_gpio;
116115 struct regulator *regulator;
117
- char label[LED_MAX_NAME_SIZE];
118116 int led_enable;
119117 int model_id;
118
+
119
+ u8 boost_ctrl, brightness_ctrl;
120
+ bool enabled;
120121 };
121122
122123 static const struct reg_default lm3692x_reg_defs[] = {
....@@ -165,48 +166,19 @@
165166 return read_buf;
166167 }
167168
168
-static int lm3692x_brightness_set(struct led_classdev *led_cdev,
169
- enum led_brightness brt_val)
170
-{
171
- struct lm3692x_led *led =
172
- container_of(led_cdev, struct lm3692x_led, led_dev);
173
- int ret;
174
- int led_brightness_lsb = (brt_val >> 5);
175
-
176
- mutex_lock(&led->lock);
177
-
178
- ret = lm3692x_fault_check(led);
179
- if (ret) {
180
- dev_err(&led->client->dev, "Cannot read/clear faults\n");
181
- goto out;
182
- }
183
-
184
- ret = regmap_write(led->regmap, LM3692X_BRT_MSB, brt_val);
185
- if (ret) {
186
- dev_err(&led->client->dev, "Cannot write MSB\n");
187
- goto out;
188
- }
189
-
190
- ret = regmap_write(led->regmap, LM3692X_BRT_LSB, led_brightness_lsb);
191
- if (ret) {
192
- dev_err(&led->client->dev, "Cannot write LSB\n");
193
- goto out;
194
- }
195
-out:
196
- mutex_unlock(&led->lock);
197
- return ret;
198
-}
199
-
200
-static int lm3692x_init(struct lm3692x_led *led)
169
+static int lm3692x_leds_enable(struct lm3692x_led *led)
201170 {
202171 int enable_state;
203
- int ret;
172
+ int ret, reg_ret;
173
+
174
+ if (led->enabled)
175
+ return 0;
204176
205177 if (led->regulator) {
206178 ret = regulator_enable(led->regulator);
207179 if (ret) {
208180 dev_err(&led->client->dev,
209
- "Failed to enable regulator\n");
181
+ "Failed to enable regulator: %d\n", ret);
210182 return ret;
211183 }
212184 }
....@@ -216,7 +188,8 @@
216188
217189 ret = lm3692x_fault_check(led);
218190 if (ret) {
219
- dev_err(&led->client->dev, "Cannot read/clear faults\n");
191
+ dev_err(&led->client->dev, "Cannot read/clear faults: %d\n",
192
+ ret);
220193 goto out;
221194 }
222195
....@@ -250,10 +223,7 @@
250223 if (ret)
251224 goto out;
252225
253
- ret = regmap_write(led->regmap, LM3692X_BOOST_CTRL,
254
- LM3692X_BRHT_MODE_RAMP_MULTI |
255
- LM3692X_BL_ADJ_POL |
256
- LM3692X_RAMP_RATE_250us);
226
+ ret = regmap_write(led->regmap, LM3692X_BOOST_CTRL, led->boost_ctrl);
257227 if (ret)
258228 goto out;
259229
....@@ -270,7 +240,7 @@
270240 goto out;
271241
272242 ret = regmap_write(led->regmap, LM3692X_BRT_CTRL,
273
- LM3692X_BL_ADJ_POL | LM3692X_PWM_HYSTER_4LSB);
243
+ LM3692X_BL_ADJ_POL | LM3692X_RAMP_EN);
274244 if (ret)
275245 goto out;
276246
....@@ -306,6 +276,7 @@
306276 ret = regmap_update_bits(led->regmap, LM3692X_EN, LM3692X_ENABLE_MASK,
307277 enable_state | LM3692X_DEVICE_EN);
308278
279
+ led->enabled = true;
309280 return ret;
310281 out:
311282 dev_err(&led->client->dev, "Fail writing initialization values\n");
....@@ -314,18 +285,101 @@
314285 gpiod_direction_output(led->enable_gpio, 0);
315286
316287 if (led->regulator) {
317
- ret = regulator_disable(led->regulator);
318
- if (ret)
288
+ reg_ret = regulator_disable(led->regulator);
289
+ if (reg_ret)
319290 dev_err(&led->client->dev,
320
- "Failed to disable regulator\n");
291
+ "Failed to disable regulator: %d\n", reg_ret);
321292 }
322293
323294 return ret;
324295 }
296
+
297
+static int lm3692x_leds_disable(struct lm3692x_led *led)
298
+{
299
+ int ret;
300
+
301
+ if (!led->enabled)
302
+ return 0;
303
+
304
+ ret = regmap_update_bits(led->regmap, LM3692X_EN, LM3692X_DEVICE_EN, 0);
305
+ if (ret) {
306
+ dev_err(&led->client->dev, "Failed to disable regulator: %d\n",
307
+ ret);
308
+ return ret;
309
+ }
310
+
311
+ if (led->enable_gpio)
312
+ gpiod_direction_output(led->enable_gpio, 0);
313
+
314
+ if (led->regulator) {
315
+ ret = regulator_disable(led->regulator);
316
+ if (ret)
317
+ dev_err(&led->client->dev,
318
+ "Failed to disable regulator: %d\n", ret);
319
+ }
320
+
321
+ led->enabled = false;
322
+ return ret;
323
+}
324
+
325
+static int lm3692x_brightness_set(struct led_classdev *led_cdev,
326
+ enum led_brightness brt_val)
327
+{
328
+ struct lm3692x_led *led =
329
+ container_of(led_cdev, struct lm3692x_led, led_dev);
330
+ int ret;
331
+ int led_brightness_lsb = (brt_val >> 5);
332
+
333
+ mutex_lock(&led->lock);
334
+
335
+ if (brt_val == 0) {
336
+ ret = lm3692x_leds_disable(led);
337
+ goto out;
338
+ } else {
339
+ lm3692x_leds_enable(led);
340
+ }
341
+
342
+ ret = lm3692x_fault_check(led);
343
+ if (ret) {
344
+ dev_err(&led->client->dev, "Cannot read/clear faults: %d\n",
345
+ ret);
346
+ goto out;
347
+ }
348
+
349
+ ret = regmap_write(led->regmap, LM3692X_BRT_MSB, brt_val);
350
+ if (ret) {
351
+ dev_err(&led->client->dev, "Cannot write MSB: %d\n", ret);
352
+ goto out;
353
+ }
354
+
355
+ ret = regmap_write(led->regmap, LM3692X_BRT_LSB, led_brightness_lsb);
356
+ if (ret) {
357
+ dev_err(&led->client->dev, "Cannot write LSB: %d\n", ret);
358
+ goto out;
359
+ }
360
+out:
361
+ mutex_unlock(&led->lock);
362
+ return ret;
363
+}
364
+
365
+static enum led_brightness lm3692x_max_brightness(struct lm3692x_led *led,
366
+ u32 max_cur)
367
+{
368
+ u32 max_code;
369
+
370
+ /* see p.12 of LM36922 data sheet for brightness formula */
371
+ max_code = ((max_cur * 1000) - 37806) / 12195;
372
+ if (max_code > 0x7FF)
373
+ max_code = 0x7FF;
374
+
375
+ return max_code >> 3;
376
+}
377
+
325378 static int lm3692x_probe_dt(struct lm3692x_led *led)
326379 {
327380 struct fwnode_handle *child = NULL;
328
- const char *name;
381
+ struct led_init_data init_data = {};
382
+ u32 ovp, max_cur;
329383 int ret;
330384
331385 led->enable_gpio = devm_gpiod_get_optional(&led->client->dev,
....@@ -340,14 +394,37 @@
340394 led->regulator = devm_regulator_get_optional(&led->client->dev, "vled");
341395 if (IS_ERR(led->regulator)) {
342396 ret = PTR_ERR(led->regulator);
343
- if (ret != -ENODEV) {
344
- if (ret != -EPROBE_DEFER)
345
- dev_err(&led->client->dev,
346
- "Failed to get vled regulator: %d\n",
347
- ret);
348
- return ret;
349
- }
397
+ if (ret != -ENODEV)
398
+ return dev_err_probe(&led->client->dev, ret,
399
+ "Failed to get vled regulator\n");
400
+
350401 led->regulator = NULL;
402
+ }
403
+
404
+ led->boost_ctrl = LM3692X_BOOST_SW_1MHZ |
405
+ LM3692X_BOOST_SW_NO_SHIFT |
406
+ LM3692X_OCP_PROT_1_5A;
407
+ ret = device_property_read_u32(&led->client->dev,
408
+ "ti,ovp-microvolt", &ovp);
409
+ if (ret) {
410
+ led->boost_ctrl |= LM3692X_OVP_29V;
411
+ } else {
412
+ switch (ovp) {
413
+ case 17000000:
414
+ break;
415
+ case 21000000:
416
+ led->boost_ctrl |= LM3692X_OVP_21V;
417
+ break;
418
+ case 25000000:
419
+ led->boost_ctrl |= LM3692X_OVP_25V;
420
+ break;
421
+ case 29000000:
422
+ led->boost_ctrl |= LM3692X_OVP_29V;
423
+ break;
424
+ default:
425
+ dev_err(&led->client->dev, "Invalid OVP %d\n", ovp);
426
+ return -EINVAL;
427
+ }
351428 }
352429
353430 child = device_get_next_child_node(&led->client->dev, child);
....@@ -356,34 +433,28 @@
356433 return -ENODEV;
357434 }
358435
359
- fwnode_property_read_string(child, "linux,default-trigger",
360
- &led->led_dev.default_trigger);
361
-
362
- ret = fwnode_property_read_string(child, "label", &name);
363
- if (ret)
364
- snprintf(led->label, sizeof(led->label),
365
- "%s::", led->client->name);
366
- else
367
- snprintf(led->label, sizeof(led->label),
368
- "%s:%s", led->client->name, name);
369
-
370436 ret = fwnode_property_read_u32(child, "reg", &led->led_enable);
371437 if (ret) {
438
+ fwnode_handle_put(child);
372439 dev_err(&led->client->dev, "reg DT property missing\n");
373440 return ret;
374441 }
375442
376
- led->led_dev.name = led->label;
443
+ ret = fwnode_property_read_u32(child, "led-max-microamp", &max_cur);
444
+ led->led_dev.max_brightness = ret ? LED_FULL :
445
+ lm3692x_max_brightness(led, max_cur);
377446
378
- ret = devm_led_classdev_register(&led->client->dev, &led->led_dev);
379
- if (ret) {
447
+ init_data.fwnode = child;
448
+ init_data.devicename = led->client->name;
449
+ init_data.default_label = ":";
450
+
451
+ ret = devm_led_classdev_register_ext(&led->client->dev, &led->led_dev,
452
+ &init_data);
453
+ if (ret)
380454 dev_err(&led->client->dev, "led register err: %d\n", ret);
381
- return ret;
382
- }
383455
384
- led->led_dev.dev->of_node = to_of_node(child);
385
-
386
- return 0;
456
+ fwnode_handle_put(init_data.fwnode);
457
+ return ret;
387458 }
388459
389460 static int lm3692x_probe(struct i2c_client *client,
....@@ -414,7 +485,7 @@
414485 if (ret)
415486 return ret;
416487
417
- ret = lm3692x_init(led);
488
+ ret = lm3692x_leds_enable(led);
418489 if (ret)
419490 return ret;
420491
....@@ -426,22 +497,9 @@
426497 struct lm3692x_led *led = i2c_get_clientdata(client);
427498 int ret;
428499
429
- ret = regmap_update_bits(led->regmap, LM3692X_EN, LM3692X_DEVICE_EN, 0);
430
- if (ret) {
431
- dev_err(&led->client->dev, "Failed to disable regulator\n");
500
+ ret = lm3692x_leds_disable(led);
501
+ if (ret)
432502 return ret;
433
- }
434
-
435
- if (led->enable_gpio)
436
- gpiod_direction_output(led->enable_gpio, 0);
437
-
438
- if (led->regulator) {
439
- ret = regulator_disable(led->regulator);
440
- if (ret)
441
- dev_err(&led->client->dev,
442
- "Failed to disable regulator\n");
443
- }
444
-
445503 mutex_destroy(&led->lock);
446504
447505 return 0;