History

backlight: lm3630a: Add firmware node support

Add fwnode support to the lm3630a driver and optionally allow configuring the label, default brightness level, and maximum brightness level. The two outputs can be controlled by bank A and B independently or bank A can control both outputs. If the platform data was not configured, then the driver defaults to enabling both banks. This patch changes the default value to disable both banks before parsing the firmware node so that just a single bank can be enabled if desired. There are no in-tree users of this driver. Driver was tested on a LG Nexus 5 (hammerhead) phone.

Brian Masney committed 7 years ago

Commit 8fbce8e1 parent 32fcb752 files · +148 −5Browse files

Unified · Split

2 files
  1. drivers/video/backlight/lm3630a_bl.c +144 −5
  2. include/linux/platform_data/lm3630a_bl.h +4 −0
drivers/video/backlight/lm3630a_bl.c+144−5
@@ -35,6 +35,14 @@ · 34 unmodified lines
35#define REG_MAX 0x5035#define REG_MAX 0x50
36 36
37#define INT_DEBOUNCE_MSEC 1037#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 = { · 288 unmodified lines
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) · 4 unmodified lines
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 = { · 8 unmodified lines
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, · 26 unmodified lines
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[] = { · 61 unmodified lines
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,
include/linux/platform_data/lm3630a_bl.h+4−0
@@ -38,9 +38,11 @@ enum lm3630a_ledb_ctrl { · 37 unmodified lines
38 38
39#define LM3630A_MAX_BRIGHTNESS 25539#define LM3630A_MAX_BRIGHTNESS 255
40/*40/*
41 *@leda_label : optional led a label.
41 *@leda_init_brt : led a init brightness. 4~25542 *@leda_init_brt : led a init brightness. 4~255
42 *@leda_max_brt : led a max brightness. 4~25543 *@leda_max_brt : led a max brightness. 4~255
43 *@leda_ctrl : led a disable, enable linear, enable exponential44 *@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~25546 *@ledb_init_brt : led b init brightness. 4~255
45 *@ledb_max_brt : led b max brightness. 4~25547 *@ledb_max_brt : led b max brightness. 4~255
46 *@ledb_ctrl : led b disable, enable linear, enable exponential48 *@ledb_ctrl : led b disable, enable linear, enable exponential
@@ -50,10 +52,12 @@ enum lm3630a_ledb_ctrl { · 3 unmodified lines
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;

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t