Skip to content

Commit 8fbce8e

Browse files
masneybLee Jones
authored andcommitted
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. Signed-off-by: Brian Masney <[email protected]> Reviewed-by: Dan Murphy <[email protected]> Acked-by: Daniel Thompson <[email protected]> Acked-by: Pavel Machek <[email protected]> Signed-off-by: Lee Jones <[email protected]>
1 parent 32fcb75 commit 8fbce8e

File tree

2 files changed

+148
-5
lines changed

2 files changed

+148
-5
lines changed

drivers/video/backlight/lm3630a_bl.c

Lines changed: 144 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,14 @@
3535
#define REG_MAX 0x50
3636

3737
#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+
3846
struct lm3630a_chip {
3947
struct device *dev;
4048
struct delayed_work work;
@@ -329,15 +337,17 @@ static const struct backlight_ops lm3630a_bank_b_ops = {
329337

330338
static int lm3630a_backlight_register(struct lm3630a_chip *pchip)
331339
{
332-
struct backlight_properties props;
333340
struct lm3630a_platform_data *pdata = pchip->pdata;
341+
struct backlight_properties props;
342+
const char *label;
334343

335344
props.type = BACKLIGHT_RAW;
336345
if (pdata->leda_ctrl != LM3630A_LEDA_DISABLE) {
337346
props.brightness = pdata->leda_init_brt;
338347
props.max_brightness = pdata->leda_max_brt;
348+
label = pdata->leda_label ? pdata->leda_label : "lm3630a_leda";
339349
pchip->bleda =
340-
devm_backlight_device_register(pchip->dev, "lm3630a_leda",
350+
devm_backlight_device_register(pchip->dev, label,
341351
pchip->dev, pchip,
342352
&lm3630a_bank_a_ops, &props);
343353
if (IS_ERR(pchip->bleda))
@@ -348,8 +358,9 @@ static int lm3630a_backlight_register(struct lm3630a_chip *pchip)
348358
(pdata->ledb_ctrl != LM3630A_LEDB_ON_A)) {
349359
props.brightness = pdata->ledb_init_brt;
350360
props.max_brightness = pdata->ledb_max_brt;
361+
label = pdata->ledb_label ? pdata->ledb_label : "lm3630a_ledb";
351362
pchip->bledb =
352-
devm_backlight_device_register(pchip->dev, "lm3630a_ledb",
363+
devm_backlight_device_register(pchip->dev, label,
353364
pchip->dev, pchip,
354365
&lm3630a_bank_b_ops, &props);
355366
if (IS_ERR(pchip->bledb))
@@ -364,6 +375,123 @@ static const struct regmap_config lm3630a_regmap = {
364375
.max_register = REG_MAX,
365376
};
366377

378+
static 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+
406+
static 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+
480+
static 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+
367495
static int lm3630a_probe(struct i2c_client *client,
368496
const struct i2c_device_id *id)
369497
{
@@ -396,13 +524,18 @@ static int lm3630a_probe(struct i2c_client *client,
396524
GFP_KERNEL);
397525
if (pdata == NULL)
398526
return -ENOMEM;
527+
399528
/* default values */
400-
pdata->leda_ctrl = LM3630A_LEDA_ENABLE;
401-
pdata->ledb_ctrl = LM3630A_LEDB_ENABLE;
402529
pdata->leda_max_brt = LM3630A_MAX_BRIGHTNESS;
403530
pdata->ledb_max_brt = LM3630A_MAX_BRIGHTNESS;
404531
pdata->leda_init_brt = LM3630A_MAX_BRIGHTNESS;
405532
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+
}
406539
}
407540
pchip->pdata = pdata;
408541

@@ -470,11 +603,17 @@ static const struct i2c_device_id lm3630a_id[] = {
470603
{}
471604
};
472605

606+
static const struct of_device_id lm3630a_match_table[] = {
607+
{ .compatible = "ti,lm3630a", },
608+
{ },
609+
};
610+
473611
MODULE_DEVICE_TABLE(i2c, lm3630a_id);
474612

475613
static struct i2c_driver lm3630a_i2c_driver = {
476614
.driver = {
477615
.name = LM3630A_NAME,
616+
.of_match_table = lm3630a_match_table,
478617
},
479618
.probe = lm3630a_probe,
480619
.remove = lm3630a_remove,

include/linux/platform_data/lm3630a_bl.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,9 +38,11 @@ enum lm3630a_ledb_ctrl {
3838

3939
#define LM3630A_MAX_BRIGHTNESS 255
4040
/*
41+
*@leda_label : optional led a label.
4142
*@leda_init_brt : led a init brightness. 4~255
4243
*@leda_max_brt : led a max brightness. 4~255
4344
*@leda_ctrl : led a disable, enable linear, enable exponential
45+
*@ledb_label : optional led b label.
4446
*@ledb_init_brt : led b init brightness. 4~255
4547
*@ledb_max_brt : led b max brightness. 4~255
4648
*@ledb_ctrl : led b disable, enable linear, enable exponential
@@ -50,10 +52,12 @@ enum lm3630a_ledb_ctrl {
5052
struct lm3630a_platform_data {
5153

5254
/* led a config. */
55+
const char *leda_label;
5356
int leda_init_brt;
5457
int leda_max_brt;
5558
enum lm3630a_leda_ctrl leda_ctrl;
5659
/* led b config. */
60+
const char *ledb_label;
5761
int ledb_init_brt;
5862
int ledb_max_brt;
5963
enum lm3630a_ledb_ctrl ledb_ctrl;

0 commit comments

Comments
 (0)