forked from ~ljy/RK356X_SDK_RELEASE

hc
2024-01-31 f70575805708cabdedea7498aaa3f710fde4d920
kernel/drivers/video/backlight/lm3630a_bl.c
....@@ -1,11 +1,7 @@
1
+// SPDX-License-Identifier: GPL-2.0-only
12 /*
23 * Simple driver for Texas Instruments LM3630A Backlight driver chip
34 * Copyright (C) 2012 Texas Instruments
4
-*
5
-* This program is free software; you can redistribute it and/or modify
6
-* it under the terms of the GNU General Public License version 2 as
7
-* published by the Free Software Foundation.
8
-*
95 */
106 #include <linux/module.h>
117 #include <linux/slab.h>
....@@ -16,6 +12,7 @@
1612 #include <linux/uaccess.h>
1713 #include <linux/interrupt.h>
1814 #include <linux/regmap.h>
15
+#include <linux/gpio/consumer.h>
1916 #include <linux/pwm.h>
2017 #include <linux/platform_data/lm3630a_bl.h>
2118
....@@ -35,6 +32,14 @@
3532 #define REG_MAX 0x50
3633
3734 #define INT_DEBOUNCE_MSEC 10
35
+
36
+#define LM3630A_BANK_0 0
37
+#define LM3630A_BANK_1 1
38
+
39
+#define LM3630A_NUM_SINKS 2
40
+#define LM3630A_SINK_0 0
41
+#define LM3630A_SINK_1 1
42
+
3843 struct lm3630a_chip {
3944 struct device *dev;
4045 struct delayed_work work;
....@@ -44,6 +49,7 @@
4449 struct lm3630a_platform_data *pdata;
4550 struct backlight_device *bleda;
4651 struct backlight_device *bledb;
52
+ struct gpio_desc *enable_gpio;
4753 struct regmap *regmap;
4854 struct pwm_device *pwmd;
4955 };
....@@ -329,15 +335,17 @@
329335
330336 static int lm3630a_backlight_register(struct lm3630a_chip *pchip)
331337 {
332
- struct backlight_properties props;
333338 struct lm3630a_platform_data *pdata = pchip->pdata;
339
+ struct backlight_properties props;
340
+ const char *label;
334341
335342 props.type = BACKLIGHT_RAW;
336343 if (pdata->leda_ctrl != LM3630A_LEDA_DISABLE) {
337344 props.brightness = pdata->leda_init_brt;
338345 props.max_brightness = pdata->leda_max_brt;
346
+ label = pdata->leda_label ? pdata->leda_label : "lm3630a_leda";
339347 pchip->bleda =
340
- devm_backlight_device_register(pchip->dev, "lm3630a_leda",
348
+ devm_backlight_device_register(pchip->dev, label,
341349 pchip->dev, pchip,
342350 &lm3630a_bank_a_ops, &props);
343351 if (IS_ERR(pchip->bleda))
....@@ -348,8 +356,9 @@
348356 (pdata->ledb_ctrl != LM3630A_LEDB_ON_A)) {
349357 props.brightness = pdata->ledb_init_brt;
350358 props.max_brightness = pdata->ledb_max_brt;
359
+ label = pdata->ledb_label ? pdata->ledb_label : "lm3630a_ledb";
351360 pchip->bledb =
352
- devm_backlight_device_register(pchip->dev, "lm3630a_ledb",
361
+ devm_backlight_device_register(pchip->dev, label,
353362 pchip->dev, pchip,
354363 &lm3630a_bank_b_ops, &props);
355364 if (IS_ERR(pchip->bledb))
....@@ -363,6 +372,124 @@
363372 .val_bits = 8,
364373 .max_register = REG_MAX,
365374 };
375
+
376
+static int lm3630a_parse_led_sources(struct fwnode_handle *node,
377
+ int default_led_sources)
378
+{
379
+ u32 sources[LM3630A_NUM_SINKS];
380
+ int ret, num_sources, i;
381
+
382
+ num_sources = fwnode_property_count_u32(node, "led-sources");
383
+ if (num_sources < 0)
384
+ return default_led_sources;
385
+ else if (num_sources > ARRAY_SIZE(sources))
386
+ return -EINVAL;
387
+
388
+ ret = fwnode_property_read_u32_array(node, "led-sources", sources,
389
+ num_sources);
390
+ if (ret)
391
+ return ret;
392
+
393
+ for (i = 0; i < num_sources; i++) {
394
+ if (sources[i] != LM3630A_SINK_0 && sources[i] != LM3630A_SINK_1)
395
+ return -EINVAL;
396
+
397
+ ret |= BIT(sources[i]);
398
+ }
399
+
400
+ return ret;
401
+}
402
+
403
+static int lm3630a_parse_bank(struct lm3630a_platform_data *pdata,
404
+ struct fwnode_handle *node, int *seen_led_sources)
405
+{
406
+ int led_sources, ret;
407
+ const char *label;
408
+ u32 bank, val;
409
+ bool linear;
410
+
411
+ ret = fwnode_property_read_u32(node, "reg", &bank);
412
+ if (ret)
413
+ return ret;
414
+
415
+ if (bank != LM3630A_BANK_0 && bank != LM3630A_BANK_1)
416
+ return -EINVAL;
417
+
418
+ led_sources = lm3630a_parse_led_sources(node, BIT(bank));
419
+ if (led_sources < 0)
420
+ return led_sources;
421
+
422
+ if (*seen_led_sources & led_sources)
423
+ return -EINVAL;
424
+
425
+ *seen_led_sources |= led_sources;
426
+
427
+ linear = fwnode_property_read_bool(node,
428
+ "ti,linear-mapping-mode");
429
+ if (bank) {
430
+ if (led_sources & BIT(LM3630A_SINK_0) ||
431
+ !(led_sources & BIT(LM3630A_SINK_1)))
432
+ return -EINVAL;
433
+
434
+ pdata->ledb_ctrl = linear ?
435
+ LM3630A_LEDB_ENABLE_LINEAR :
436
+ LM3630A_LEDB_ENABLE;
437
+ } else {
438
+ if (!(led_sources & BIT(LM3630A_SINK_0)))
439
+ return -EINVAL;
440
+
441
+ pdata->leda_ctrl = linear ?
442
+ LM3630A_LEDA_ENABLE_LINEAR :
443
+ LM3630A_LEDA_ENABLE;
444
+
445
+ if (led_sources & BIT(LM3630A_SINK_1))
446
+ pdata->ledb_ctrl = LM3630A_LEDB_ON_A;
447
+ }
448
+
449
+ ret = fwnode_property_read_string(node, "label", &label);
450
+ if (!ret) {
451
+ if (bank)
452
+ pdata->ledb_label = label;
453
+ else
454
+ pdata->leda_label = label;
455
+ }
456
+
457
+ ret = fwnode_property_read_u32(node, "default-brightness",
458
+ &val);
459
+ if (!ret) {
460
+ if (bank)
461
+ pdata->ledb_init_brt = val;
462
+ else
463
+ pdata->leda_init_brt = val;
464
+ }
465
+
466
+ ret = fwnode_property_read_u32(node, "max-brightness", &val);
467
+ if (!ret) {
468
+ if (bank)
469
+ pdata->ledb_max_brt = val;
470
+ else
471
+ pdata->leda_max_brt = val;
472
+ }
473
+
474
+ return 0;
475
+}
476
+
477
+static int lm3630a_parse_node(struct lm3630a_chip *pchip,
478
+ struct lm3630a_platform_data *pdata)
479
+{
480
+ int ret = -ENODEV, seen_led_sources = 0;
481
+ struct fwnode_handle *node;
482
+
483
+ device_for_each_child_node(pchip->dev, node) {
484
+ ret = lm3630a_parse_bank(pdata, node, &seen_led_sources);
485
+ if (ret) {
486
+ fwnode_handle_put(node);
487
+ return ret;
488
+ }
489
+ }
490
+
491
+ return ret;
492
+}
366493
367494 static int lm3630a_probe(struct i2c_client *client,
368495 const struct i2c_device_id *id)
....@@ -396,15 +523,27 @@
396523 GFP_KERNEL);
397524 if (pdata == NULL)
398525 return -ENOMEM;
526
+
399527 /* default values */
400
- pdata->leda_ctrl = LM3630A_LEDA_ENABLE;
401
- pdata->ledb_ctrl = LM3630A_LEDB_ENABLE;
402528 pdata->leda_max_brt = LM3630A_MAX_BRIGHTNESS;
403529 pdata->ledb_max_brt = LM3630A_MAX_BRIGHTNESS;
404530 pdata->leda_init_brt = LM3630A_MAX_BRIGHTNESS;
405531 pdata->ledb_init_brt = LM3630A_MAX_BRIGHTNESS;
532
+
533
+ rval = lm3630a_parse_node(pchip, pdata);
534
+ if (rval) {
535
+ dev_err(&client->dev, "fail : parse node\n");
536
+ return rval;
537
+ }
406538 }
407539 pchip->pdata = pdata;
540
+
541
+ pchip->enable_gpio = devm_gpiod_get_optional(&client->dev, "enable",
542
+ GPIOD_OUT_HIGH);
543
+ if (IS_ERR(pchip->enable_gpio)) {
544
+ rval = PTR_ERR(pchip->enable_gpio);
545
+ return rval;
546
+ }
408547
409548 /* chip initialize */
410549 rval = lm3630a_chip_init(pchip);
....@@ -472,9 +611,17 @@
472611
473612 MODULE_DEVICE_TABLE(i2c, lm3630a_id);
474613
614
+static const struct of_device_id lm3630a_match_table[] = {
615
+ { .compatible = "ti,lm3630a", },
616
+ { },
617
+};
618
+
619
+MODULE_DEVICE_TABLE(of, lm3630a_match_table);
620
+
475621 static struct i2c_driver lm3630a_i2c_driver = {
476622 .driver = {
477623 .name = LM3630A_NAME,
624
+ .of_match_table = lm3630a_match_table,
478625 },
479626 .probe = lm3630a_probe,
480627 .remove = lm3630a_remove,