Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

backlight: lp855x: add a device tree structure

Enable supporting the DT structure of LP855x family devices. If the
platform data is NULL, the driver tries to parse a DT structure. Then,
the platform data is copied from the DT. Documentation is added as well.

Signed-off-by: Milo(Woogyom) Kim <milo.kim@ti.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>

authored by

Kim, Milo and committed by
Linus Torvalds
4add0664 c365e59d

+112 -2
+41
Documentation/devicetree/bindings/video/backlight/lp855x.txt
··· 1 + lp855x bindings 2 + 3 + Required properties: 4 + - compatible: "ti,lp8550", "ti,lp8551", "ti,lp8552", "ti,lp8553", 5 + "ti,lp8556", "ti,lp8557" 6 + - reg: I2C slave address (u8) 7 + - dev-ctrl: Value of DEVICE CONTROL register (u8). It depends on the device. 8 + 9 + Optional properties: 10 + - bl-name: Backlight device name (string) 11 + - init-brt: Initial value of backlight brightness (u8) 12 + - pwm-period: PWM period value. Set only PWM input mode used (u32) 13 + - rom-addr: Register address of ROM area to be updated (u8) 14 + - rom-val: Register value to be updated (u8) 15 + 16 + Example: 17 + 18 + /* LP8556 */ 19 + backlight@2c { 20 + compatible = "ti,lp8556"; 21 + reg = <0x2c>; 22 + 23 + bl-name = "lcd-bl"; 24 + dev-ctrl = /bits/ 8 <0x85>; 25 + init-brt = /bits/ 8 <0x10>; 26 + }; 27 + 28 + /* LP8557 */ 29 + backlight@2c { 30 + compatible = "ti,lp8557"; 31 + reg = <0x2c>; 32 + 33 + dev-ctrl = /bits/ 8 <0x41>; 34 + init-brt = /bits/ 8 <0x0a>; 35 + 36 + /* 4V OV, 4 output LED string enabled */ 37 + rom_14h { 38 + rom-addr = /bits/ 8 <0x14>; 39 + rom-val = /bits/ 8 <0xcf>; 40 + }; 41 + };
+71 -2
drivers/video/backlight/lp855x_bl.c
··· 14 14 #include <linux/i2c.h> 15 15 #include <linux/backlight.h> 16 16 #include <linux/err.h> 17 + #include <linux/of.h> 17 18 #include <linux/platform_data/lp855x.h> 18 19 #include <linux/pwm.h> 19 20 ··· 339 338 .attrs = lp855x_attributes, 340 339 }; 341 340 341 + #ifdef CONFIG_OF 342 + static int lp855x_parse_dt(struct device *dev, struct device_node *node) 343 + { 344 + struct lp855x_platform_data *pdata; 345 + int rom_length; 346 + 347 + if (!node) { 348 + dev_err(dev, "no platform data\n"); 349 + return -EINVAL; 350 + } 351 + 352 + pdata = devm_kzalloc(dev, sizeof(*pdata), GFP_KERNEL); 353 + if (!pdata) 354 + return -ENOMEM; 355 + 356 + of_property_read_string(node, "bl-name", &pdata->name); 357 + of_property_read_u8(node, "dev-ctrl", &pdata->device_control); 358 + of_property_read_u8(node, "init-brt", &pdata->initial_brightness); 359 + of_property_read_u32(node, "pwm-period", &pdata->period_ns); 360 + 361 + /* Fill ROM platform data if defined */ 362 + rom_length = of_get_child_count(node); 363 + if (rom_length > 0) { 364 + struct lp855x_rom_data *rom; 365 + struct device_node *child; 366 + int i = 0; 367 + 368 + rom = devm_kzalloc(dev, sizeof(*rom) * rom_length, GFP_KERNEL); 369 + if (!rom) 370 + return -ENOMEM; 371 + 372 + for_each_child_of_node(node, child) { 373 + of_property_read_u8(child, "rom-addr", &rom[i].addr); 374 + of_property_read_u8(child, "rom-val", &rom[i].val); 375 + i++; 376 + } 377 + 378 + pdata->size_program = rom_length; 379 + pdata->rom_data = &rom[0]; 380 + } 381 + 382 + dev->platform_data = pdata; 383 + 384 + return 0; 385 + } 386 + #else 387 + static int lp855x_parse_dt(struct device *dev, struct device_node *node) 388 + { 389 + return -EINVAL; 390 + } 391 + #endif 392 + 342 393 static int lp855x_probe(struct i2c_client *cl, const struct i2c_device_id *id) 343 394 { 344 395 struct lp855x *lp; 345 396 struct lp855x_platform_data *pdata = cl->dev.platform_data; 397 + struct device_node *node = cl->dev.of_node; 346 398 int ret; 347 399 348 400 if (!pdata) { 349 - dev_err(&cl->dev, "no platform data supplied\n"); 350 - return -EINVAL; 401 + ret = lp855x_parse_dt(&cl->dev, node); 402 + if (ret < 0) 403 + return ret; 404 + 405 + pdata = cl->dev.platform_data; 351 406 } 352 407 353 408 if (!i2c_check_functionality(cl->adapter, I2C_FUNC_SMBUS_I2C_BLOCK)) ··· 465 408 return 0; 466 409 } 467 410 411 + static const struct of_device_id lp855x_dt_ids[] = { 412 + { .compatible = "ti,lp8550", }, 413 + { .compatible = "ti,lp8551", }, 414 + { .compatible = "ti,lp8552", }, 415 + { .compatible = "ti,lp8553", }, 416 + { .compatible = "ti,lp8556", }, 417 + { .compatible = "ti,lp8557", }, 418 + { } 419 + }; 420 + MODULE_DEVICE_TABLE(of, lp855x_dt_ids); 421 + 468 422 static const struct i2c_device_id lp855x_ids[] = { 469 423 {"lp8550", LP8550}, 470 424 {"lp8551", LP8551}, ··· 490 422 static struct i2c_driver lp855x_driver = { 491 423 .driver = { 492 424 .name = "lp855x", 425 + .of_match_table = of_match_ptr(lp855x_dt_ids), 493 426 }, 494 427 .probe = lp855x_probe, 495 428 .remove = lp855x_remove,