aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/video/backlight/lm3630a_bl.c149
-rw-r--r--include/linux/platform_data/lm3630a_bl.h4
2 files changed, 148 insertions, 5 deletions
diff --git a/drivers/video/backlight/lm3630a_bl.c b/drivers/video/backlight/lm3630a_bl.c
index ef2553f452ca..75d996490cf0 100644
--- a/drivers/video/backlight/lm3630a_bl.c
+++ b/drivers/video/backlight/lm3630a_bl.c
@@ -35,6 +35,14 @@
35#define REG_MAX 0x50 35#define REG_MAX 0x50
36 36
37#define INT_DEBOUNCE_MSEC 10 37#define INT_DEBOUNCE_MSEC 10
38
39#define LM3630A_BANK_0 0
40#define LM3630A_BANK_1 1
41
42#define LM3630A_NUM_SINKS 2
43#define LM3630A_SINK_0 0
44#define LM3630A_SINK_1 1
45
38struct lm3630a_chip { 46struct lm3630a_chip {
39 struct device *dev; 47 struct device *dev;
40 struct delayed_work work; 48 struct delayed_work work;
@@ -329,15 +337,17 @@ static const struct backlight_ops lm3630a_bank_b_ops = {
329 337
330static int lm3630a_backlight_register(struct lm3630a_chip *pchip) 338static int lm3630a_backlight_register(struct lm3630a_chip *pchip)
331{ 339{
332 struct backlight_properties props;
333 struct lm3630a_platform_data *pdata = pchip->pdata; 340 struct lm3630a_platform_data *pdata = pchip->pdata;
341 struct backlight_properties props;
342 const char *label;
334 343
335 props.type = BACKLIGHT_RAW; 344 props.type = BACKLIGHT_RAW;
336 if (pdata->leda_ctrl != LM3630A_LEDA_DISABLE) { 345 if (pdata->leda_ctrl != LM3630A_LEDA_DISABLE) {
337 props.brightness = pdata->leda_init_brt; 346 props.brightness = pdata->leda_init_brt;
338 props.max_brightness = pdata->leda_max_brt; 347 props.max_brightness = pdata->leda_max_brt;
348 label = pdata->leda_label ? pdata->leda_label : "lm3630a_leda";
339 pchip->bleda = 349 pchip->bleda =
340 devm_backlight_device_register(pchip->dev, "lm3630a_leda", 350 devm_backlight_device_register(pchip->dev, label,
341 pchip->dev, pchip, 351 pchip->dev, pchip,
342 &lm3630a_bank_a_ops, &props); 352 &lm3630a_bank_a_ops, &props);
343 if (IS_ERR(pchip->bleda)) 353 if (IS_ERR(pchip->bleda))
@@ -348,8 +358,9 @@ static int lm3630a_backlight_register(struct lm3630a_chip *pchip)
348 (pdata->ledb_ctrl != LM3630A_LEDB_ON_A)) { 358 (pdata->ledb_ctrl != LM3630A_LEDB_ON_A)) {
349 props.brightness = pdata->ledb_init_brt; 359 props.brightness = pdata->ledb_init_brt;
350 props.max_brightness = pdata->ledb_max_brt; 360 props.max_brightness = pdata->ledb_max_brt;
361 label = pdata->ledb_label ? pdata->ledb_label : "lm3630a_ledb";
351 pchip->bledb = 362 pchip->bledb =
352 devm_backlight_device_register(pchip->dev, "lm3630a_ledb", 363 devm_backlight_device_register(pchip->dev, label,
353 pchip->dev, pchip, 364 pchip->dev, pchip,
354 &lm3630a_bank_b_ops, &props); 365 &lm3630a_bank_b_ops, &props);
355 if (IS_ERR(pchip->bledb)) 366 if (IS_ERR(pchip->bledb))
@@ -364,6 +375,123 @@ static const struct regmap_config lm3630a_regmap = {
364 .max_register = REG_MAX, 375 .max_register = REG_MAX,
365}; 376};
366 377
378static int lm3630a_parse_led_sources(struct fwnode_handle *node,
379 int default_led_sources)
380{
381 u32 sources[LM3630A_NUM_SINKS];
382 int ret, num_sources, i;
383
384 num_sources = fwnode_property_read_u32_array(node, "led-sources", NULL,
385 0);
386 if (num_sources < 0)
387 return default_led_sources;
388 else if (num_sources > ARRAY_SIZE(sources))
389 return -EINVAL;
390
391 ret = fwnode_property_read_u32_array(node, "led-sources", sources,
392 num_sources);
393 if (ret)
394 return ret;
395
396 for (i = 0; i < num_sources; i++) {
397 if (sources[i] < LM3630A_SINK_0 || sources[i] > LM3630A_SINK_1)
398 return -EINVAL;
399
400 ret |= BIT(sources[i]);
401 }
402
403 return ret;
404}
405
406static int lm3630a_parse_bank(struct lm3630a_platform_data *pdata,
407 struct fwnode_handle *node, int *seen_led_sources)
408{
409 int led_sources, ret;
410 const char *label;
411 u32 bank, val;
412 bool linear;
413
414 ret = fwnode_property_read_u32(node, "reg", &bank);
415 if (ret)
416 return ret;
417
418 if (bank < LM3630A_BANK_0 || bank > LM3630A_BANK_1)
419 return -EINVAL;
420
421 led_sources = lm3630a_parse_led_sources(node, BIT(bank));
422 if (led_sources < 0)
423 return led_sources;
424
425 if (*seen_led_sources & led_sources)
426 return -EINVAL;
427
428 *seen_led_sources |= led_sources;
429
430 linear = fwnode_property_read_bool(node,
431 "ti,linear-mapping-mode");
432 if (bank) {
433 if (led_sources & BIT(LM3630A_SINK_0) ||
434 !(led_sources & BIT(LM3630A_SINK_1)))
435 return -EINVAL;
436
437 pdata->ledb_ctrl = linear ?
438 LM3630A_LEDB_ENABLE_LINEAR :
439 LM3630A_LEDB_ENABLE;
440 } else {
441 if (!(led_sources & BIT(LM3630A_SINK_0)))
442 return -EINVAL;
443
444 pdata->leda_ctrl = linear ?
445 LM3630A_LEDA_ENABLE_LINEAR :
446 LM3630A_LEDA_ENABLE;
447
448 if (led_sources & BIT(LM3630A_SINK_1))
449 pdata->ledb_ctrl = LM3630A_LEDB_ON_A;
450 }
451
452 ret = fwnode_property_read_string(node, "label", &label);
453 if (!ret) {
454 if (bank)
455 pdata->ledb_label = label;
456 else
457 pdata->leda_label = label;
458 }
459
460 ret = fwnode_property_read_u32(node, "default-brightness",
461 &val);
462 if (!ret) {
463 if (bank)
464 pdata->ledb_init_brt = val;
465 else
466 pdata->leda_init_brt = val;
467 }
468
469 ret = fwnode_property_read_u32(node, "max-brightness", &val);
470 if (!ret) {
471 if (bank)
472 pdata->ledb_max_brt = val;
473 else
474 pdata->leda_max_brt = val;
475 }
476
477 return 0;
478}
479
480static int lm3630a_parse_node(struct lm3630a_chip *pchip,
481 struct lm3630a_platform_data *pdata)
482{
483 int ret = -ENODEV, seen_led_sources = 0;
484 struct fwnode_handle *node;
485
486 device_for_each_child_node(pchip->dev, node) {
487 ret = lm3630a_parse_bank(pdata, node, &seen_led_sources);
488 if (ret)
489 return ret;
490 }
491
492 return ret;
493}
494
367static int lm3630a_probe(struct i2c_client *client, 495static int lm3630a_probe(struct i2c_client *client,
368 const struct i2c_device_id *id) 496 const struct i2c_device_id *id)
369{ 497{
@@ -396,13 +524,18 @@ static int lm3630a_probe(struct i2c_client *client,
396 GFP_KERNEL); 524 GFP_KERNEL);
397 if (pdata == NULL) 525 if (pdata == NULL)
398 return -ENOMEM; 526 return -ENOMEM;
527
399 /* default values */ 528 /* default values */
400 pdata->leda_ctrl = LM3630A_LEDA_ENABLE;
401 pdata->ledb_ctrl = LM3630A_LEDB_ENABLE;
402 pdata->leda_max_brt = LM3630A_MAX_BRIGHTNESS; 529 pdata->leda_max_brt = LM3630A_MAX_BRIGHTNESS;
403 pdata->ledb_max_brt = LM3630A_MAX_BRIGHTNESS; 530 pdata->ledb_max_brt = LM3630A_MAX_BRIGHTNESS;
404 pdata->leda_init_brt = LM3630A_MAX_BRIGHTNESS; 531 pdata->leda_init_brt = LM3630A_MAX_BRIGHTNESS;
405 pdata->ledb_init_brt = LM3630A_MAX_BRIGHTNESS; 532 pdata->ledb_init_brt = LM3630A_MAX_BRIGHTNESS;
533
534 rval = lm3630a_parse_node(pchip, pdata);
535 if (rval) {
536 dev_err(&client->dev, "fail : parse node\n");
537 return rval;
538 }
406 } 539 }
407 pchip->pdata = pdata; 540 pchip->pdata = pdata;
408 541
@@ -470,11 +603,17 @@ static const struct i2c_device_id lm3630a_id[] = {
470 {} 603 {}
471}; 604};
472 605
606static const struct of_device_id lm3630a_match_table[] = {
607 { .compatible = "ti,lm3630a", },
608 { },
609};
610
473MODULE_DEVICE_TABLE(i2c, lm3630a_id); 611MODULE_DEVICE_TABLE(i2c, lm3630a_id);
474 612
475static struct i2c_driver lm3630a_i2c_driver = { 613static struct i2c_driver lm3630a_i2c_driver = {
476 .driver = { 614 .driver = {
477 .name = LM3630A_NAME, 615 .name = LM3630A_NAME,
616 .of_match_table = lm3630a_match_table,
478 }, 617 },
479 .probe = lm3630a_probe, 618 .probe = lm3630a_probe,
480 .remove = lm3630a_remove, 619 .remove = lm3630a_remove,
diff --git a/include/linux/platform_data/lm3630a_bl.h b/include/linux/platform_data/lm3630a_bl.h
index 7538e38e270b..762e68956f31 100644
--- a/include/linux/platform_data/lm3630a_bl.h
+++ b/include/linux/platform_data/lm3630a_bl.h
@@ -38,9 +38,11 @@ enum lm3630a_ledb_ctrl {
38 38
39#define LM3630A_MAX_BRIGHTNESS 255 39#define LM3630A_MAX_BRIGHTNESS 255
40/* 40/*
41 *@leda_label : optional led a label.
41 *@leda_init_brt : led a init brightness. 4~255 42 *@leda_init_brt : led a init brightness. 4~255
42 *@leda_max_brt : led a max brightness. 4~255 43 *@leda_max_brt : led a max brightness. 4~255
43 *@leda_ctrl : led a disable, enable linear, enable exponential 44 *@leda_ctrl : led a disable, enable linear, enable exponential
45 *@ledb_label : optional led b label.
44 *@ledb_init_brt : led b init brightness. 4~255 46 *@ledb_init_brt : led b init brightness. 4~255
45 *@ledb_max_brt : led b max brightness. 4~255 47 *@ledb_max_brt : led b max brightness. 4~255
46 *@ledb_ctrl : led b disable, enable linear, enable exponential 48 *@ledb_ctrl : led b disable, enable linear, enable exponential
@@ -50,10 +52,12 @@ enum lm3630a_ledb_ctrl {
50struct lm3630a_platform_data { 52struct lm3630a_platform_data {
51 53
52 /* led a config. */ 54 /* led a config. */
55 const char *leda_label;
53 int leda_init_brt; 56 int leda_init_brt;
54 int leda_max_brt; 57 int leda_max_brt;
55 enum lm3630a_leda_ctrl leda_ctrl; 58 enum lm3630a_leda_ctrl leda_ctrl;
56 /* led b config. */ 59 /* led b config. */
60 const char *ledb_label;
57 int ledb_init_brt; 61 int ledb_init_brt;
58 int ledb_max_brt; 62 int ledb_max_brt;
59 enum lm3630a_ledb_ctrl ledb_ctrl; 63 enum lm3630a_ledb_ctrl ledb_ctrl;