diff options
author | Olof Johansson <olof@lixom.net> | 2013-08-04 15:20:23 -0400 |
---|---|---|
committer | Olof Johansson <olof@lixom.net> | 2013-08-04 15:20:23 -0400 |
commit | 16649596d701c0f4f767bbcad7da4d6343ba8a9e (patch) | |
tree | 271e71f83890ac9789d75902a1761a47a82f57b7 | |
parent | ad81f0545ef01ea651886dddac4bef6cec930092 (diff) | |
parent | 0fb19cdabfc3f8884bac53fd81b02bf61c7904af (diff) |
Merge tag 'renesas-backlight-for-v3.12' of git://git.kernel.org/pub/scm/linux/kernel/git/horms/renesas into next/boards
From Simon Horman:
Renesas ARM and SH based SoC backlight drivers for v3.12
Backlight drivers used by SH and ARM SH-Mobile boards.
* tag 'renesas-backlight-for-v3.12' of git://git.kernel.org/pub/scm/linux/kernel/git/horms/renesas:
ARM: mach-shmobile: ag5evm: Use bd6107 backlight driver
sh: kfr2r09: Use lv5207lp backlight
sh: ecovec24: Use gpio-backlight
ARM: mach-shmobile: mackerel: Use gpio-backlight
backlight: Add ROHM BD6107 backlight driver
backlight: Add Sanyo LV5207LP backlight driver
backlight: Add GPIO-based backlight driver
Signed-off-by: Olof Johansson <olof@lixom.net>
-rw-r--r-- | arch/arm/mach-shmobile/board-ag5evm.c | 65 | ||||
-rw-r--r-- | arch/arm/mach-shmobile/board-mackerel.c | 34 | ||||
-rw-r--r-- | arch/sh/boards/mach-ecovec24/setup.c | 37 | ||||
-rw-r--r-- | arch/sh/boards/mach-kfr2r09/lcd_wqvga.c | 48 | ||||
-rw-r--r-- | arch/sh/boards/mach-kfr2r09/setup.c | 19 | ||||
-rw-r--r-- | arch/sh/include/mach-kfr2r09/mach/kfr2r09.h | 2 | ||||
-rw-r--r-- | drivers/video/backlight/Kconfig | 19 | ||||
-rw-r--r-- | drivers/video/backlight/Makefile | 3 | ||||
-rw-r--r-- | drivers/video/backlight/bd6107.c | 213 | ||||
-rw-r--r-- | drivers/video/backlight/gpio_backlight.c | 133 | ||||
-rw-r--r-- | drivers/video/backlight/lv5207lp.c | 171 | ||||
-rw-r--r-- | include/linux/platform_data/bd6107.h | 19 | ||||
-rw-r--r-- | include/linux/platform_data/gpio_backlight.h | 21 | ||||
-rw-r--r-- | include/linux/platform_data/lv5207lp.h | 19 |
14 files changed, 665 insertions, 138 deletions
diff --git a/arch/arm/mach-shmobile/board-ag5evm.c b/arch/arm/mach-shmobile/board-ag5evm.c index c7540710906f..f6d64495c405 100644 --- a/arch/arm/mach-shmobile/board-ag5evm.c +++ b/arch/arm/mach-shmobile/board-ag5evm.c | |||
@@ -41,6 +41,7 @@ | |||
41 | #include <linux/mmc/sh_mmcif.h> | 41 | #include <linux/mmc/sh_mmcif.h> |
42 | #include <linux/mmc/sh_mobile_sdhi.h> | 42 | #include <linux/mmc/sh_mobile_sdhi.h> |
43 | #include <linux/mfd/tmio.h> | 43 | #include <linux/mfd/tmio.h> |
44 | #include <linux/platform_data/bd6107.h> | ||
44 | #include <linux/sh_clk.h> | 45 | #include <linux/sh_clk.h> |
45 | #include <linux/irqchip/arm-gic.h> | 46 | #include <linux/irqchip/arm-gic.h> |
46 | #include <video/sh_mobile_lcdc.h> | 47 | #include <video/sh_mobile_lcdc.h> |
@@ -291,47 +292,7 @@ static struct platform_device mipidsi0_device = { | |||
291 | }, | 292 | }, |
292 | }; | 293 | }; |
293 | 294 | ||
294 | static unsigned char lcd_backlight_seq[3][2] = { | 295 | /* LCDC0 and backlight */ |
295 | { 0x04, 0x07 }, | ||
296 | { 0x23, 0x80 }, | ||
297 | { 0x03, 0x01 }, | ||
298 | }; | ||
299 | |||
300 | static int lcd_backlight_set_brightness(int brightness) | ||
301 | { | ||
302 | struct i2c_adapter *adap; | ||
303 | struct i2c_msg msg; | ||
304 | unsigned int i; | ||
305 | int ret; | ||
306 | |||
307 | if (brightness == 0) { | ||
308 | /* Reset the chip */ | ||
309 | gpio_set_value(235, 0); | ||
310 | mdelay(24); | ||
311 | gpio_set_value(235, 1); | ||
312 | return 0; | ||
313 | } | ||
314 | |||
315 | adap = i2c_get_adapter(1); | ||
316 | if (adap == NULL) | ||
317 | return -ENODEV; | ||
318 | |||
319 | for (i = 0; i < ARRAY_SIZE(lcd_backlight_seq); i++) { | ||
320 | msg.addr = 0x6d; | ||
321 | msg.buf = &lcd_backlight_seq[i][0]; | ||
322 | msg.len = 2; | ||
323 | msg.flags = 0; | ||
324 | |||
325 | ret = i2c_transfer(adap, &msg, 1); | ||
326 | if (ret < 0) | ||
327 | break; | ||
328 | } | ||
329 | |||
330 | i2c_put_adapter(adap); | ||
331 | return ret < 0 ? ret : 0; | ||
332 | } | ||
333 | |||
334 | /* LCDC0 */ | ||
335 | static const struct fb_videomode lcdc0_modes[] = { | 296 | static const struct fb_videomode lcdc0_modes[] = { |
336 | { | 297 | { |
337 | .name = "R63302(QHD)", | 298 | .name = "R63302(QHD)", |
@@ -361,11 +322,6 @@ static struct sh_mobile_lcdc_info lcdc0_info = { | |||
361 | .width = 44, | 322 | .width = 44, |
362 | .height = 79, | 323 | .height = 79, |
363 | }, | 324 | }, |
364 | .bl_info = { | ||
365 | .name = "sh_mobile_lcdc_bl", | ||
366 | .max_brightness = 1, | ||
367 | .set_brightness = lcd_backlight_set_brightness, | ||
368 | }, | ||
369 | .tx_dev = &mipidsi0_device, | 325 | .tx_dev = &mipidsi0_device, |
370 | } | 326 | } |
371 | }; | 327 | }; |
@@ -394,6 +350,17 @@ static struct platform_device lcdc0_device = { | |||
394 | }, | 350 | }, |
395 | }; | 351 | }; |
396 | 352 | ||
353 | static struct bd6107_platform_data backlight_data = { | ||
354 | .fbdev = &lcdc0_device.dev, | ||
355 | .reset = 235, | ||
356 | .def_value = 0, | ||
357 | }; | ||
358 | |||
359 | static struct i2c_board_info backlight_board_info = { | ||
360 | I2C_BOARD_INFO("bd6107", 0x6d), | ||
361 | .platform_data = &backlight_data, | ||
362 | }; | ||
363 | |||
397 | /* Fixed 2.8V regulators to be used by SDHI0 */ | 364 | /* Fixed 2.8V regulators to be used by SDHI0 */ |
398 | static struct regulator_consumer_supply fixed2v8_power_consumers[] = | 365 | static struct regulator_consumer_supply fixed2v8_power_consumers[] = |
399 | { | 366 | { |
@@ -648,15 +615,15 @@ static void __init ag5evm_init(void) | |||
648 | gpio_set_value(217, 1); | 615 | gpio_set_value(217, 1); |
649 | mdelay(100); | 616 | mdelay(100); |
650 | 617 | ||
651 | /* LCD backlight controller */ | ||
652 | gpio_request_one(235, GPIOF_OUT_INIT_LOW, NULL); /* RESET */ | ||
653 | lcd_backlight_set_brightness(0); | ||
654 | 618 | ||
655 | #ifdef CONFIG_CACHE_L2X0 | 619 | #ifdef CONFIG_CACHE_L2X0 |
656 | /* Shared attribute override enable, 64K*8way */ | 620 | /* Shared attribute override enable, 64K*8way */ |
657 | l2x0_init(IOMEM(0xf0100000), 0x00460000, 0xc2000fff); | 621 | l2x0_init(IOMEM(0xf0100000), 0x00460000, 0xc2000fff); |
658 | #endif | 622 | #endif |
659 | sh73a0_add_standard_devices(); | 623 | sh73a0_add_standard_devices(); |
624 | |||
625 | i2c_register_board_info(1, &backlight_board_info, 1); | ||
626 | |||
660 | platform_add_devices(ag5evm_devices, ARRAY_SIZE(ag5evm_devices)); | 627 | platform_add_devices(ag5evm_devices, ARRAY_SIZE(ag5evm_devices)); |
661 | } | 628 | } |
662 | 629 | ||
diff --git a/arch/arm/mach-shmobile/board-mackerel.c b/arch/arm/mach-shmobile/board-mackerel.c index 85f51a849a50..af06753eb809 100644 --- a/arch/arm/mach-shmobile/board-mackerel.c +++ b/arch/arm/mach-shmobile/board-mackerel.c | |||
@@ -41,6 +41,7 @@ | |||
41 | #include <linux/mtd/physmap.h> | 41 | #include <linux/mtd/physmap.h> |
42 | #include <linux/mtd/sh_flctl.h> | 42 | #include <linux/mtd/sh_flctl.h> |
43 | #include <linux/pinctrl/machine.h> | 43 | #include <linux/pinctrl/machine.h> |
44 | #include <linux/platform_data/gpio_backlight.h> | ||
44 | #include <linux/pm_clock.h> | 45 | #include <linux/pm_clock.h> |
45 | #include <linux/regulator/fixed.h> | 46 | #include <linux/regulator/fixed.h> |
46 | #include <linux/regulator/machine.h> | 47 | #include <linux/regulator/machine.h> |
@@ -49,7 +50,6 @@ | |||
49 | #include <linux/tca6416_keypad.h> | 50 | #include <linux/tca6416_keypad.h> |
50 | #include <linux/usb/renesas_usbhs.h> | 51 | #include <linux/usb/renesas_usbhs.h> |
51 | #include <linux/dma-mapping.h> | 52 | #include <linux/dma-mapping.h> |
52 | |||
53 | #include <video/sh_mobile_hdmi.h> | 53 | #include <video/sh_mobile_hdmi.h> |
54 | #include <video/sh_mobile_lcdc.h> | 54 | #include <video/sh_mobile_lcdc.h> |
55 | #include <media/sh_mobile_ceu.h> | 55 | #include <media/sh_mobile_ceu.h> |
@@ -346,7 +346,7 @@ static struct platform_device meram_device = { | |||
346 | }, | 346 | }, |
347 | }; | 347 | }; |
348 | 348 | ||
349 | /* LCDC */ | 349 | /* LCDC and backlight */ |
350 | static struct fb_videomode mackerel_lcdc_modes[] = { | 350 | static struct fb_videomode mackerel_lcdc_modes[] = { |
351 | { | 351 | { |
352 | .name = "WVGA Panel", | 352 | .name = "WVGA Panel", |
@@ -362,13 +362,6 @@ static struct fb_videomode mackerel_lcdc_modes[] = { | |||
362 | }, | 362 | }, |
363 | }; | 363 | }; |
364 | 364 | ||
365 | static int mackerel_set_brightness(int brightness) | ||
366 | { | ||
367 | gpio_set_value(31, brightness); | ||
368 | |||
369 | return 0; | ||
370 | } | ||
371 | |||
372 | static const struct sh_mobile_meram_cfg lcd_meram_cfg = { | 365 | static const struct sh_mobile_meram_cfg lcd_meram_cfg = { |
373 | .icb[0] = { | 366 | .icb[0] = { |
374 | .meram_size = 0x40, | 367 | .meram_size = 0x40, |
@@ -393,11 +386,6 @@ static struct sh_mobile_lcdc_info lcdc_info = { | |||
393 | .width = 152, | 386 | .width = 152, |
394 | .height = 91, | 387 | .height = 91, |
395 | }, | 388 | }, |
396 | .bl_info = { | ||
397 | .name = "sh_mobile_lcdc_bl", | ||
398 | .max_brightness = 1, | ||
399 | .set_brightness = mackerel_set_brightness, | ||
400 | }, | ||
401 | .meram_cfg = &lcd_meram_cfg, | 389 | .meram_cfg = &lcd_meram_cfg, |
402 | } | 390 | } |
403 | }; | 391 | }; |
@@ -425,6 +413,20 @@ static struct platform_device lcdc_device = { | |||
425 | }, | 413 | }, |
426 | }; | 414 | }; |
427 | 415 | ||
416 | static struct gpio_backlight_platform_data gpio_backlight_data = { | ||
417 | .fbdev = &lcdc_device.dev, | ||
418 | .gpio = 31, | ||
419 | .def_value = 1, | ||
420 | .name = "backlight", | ||
421 | }; | ||
422 | |||
423 | static struct platform_device gpio_backlight_device = { | ||
424 | .name = "gpio-backlight", | ||
425 | .dev = { | ||
426 | .platform_data = &gpio_backlight_data, | ||
427 | }, | ||
428 | }; | ||
429 | |||
428 | /* HDMI */ | 430 | /* HDMI */ |
429 | static struct sh_mobile_hdmi_info hdmi_info = { | 431 | static struct sh_mobile_hdmi_info hdmi_info = { |
430 | .flags = HDMI_SND_SRC_SPDIF, | 432 | .flags = HDMI_SND_SRC_SPDIF, |
@@ -1231,6 +1233,7 @@ static struct platform_device *mackerel_devices[] __initdata = { | |||
1231 | &nor_flash_device, | 1233 | &nor_flash_device, |
1232 | &smc911x_device, | 1234 | &smc911x_device, |
1233 | &lcdc_device, | 1235 | &lcdc_device, |
1236 | &gpio_backlight_device, | ||
1234 | &usbhs0_device, | 1237 | &usbhs0_device, |
1235 | &usbhs1_device, | 1238 | &usbhs1_device, |
1236 | &leds_device, | 1239 | &leds_device, |
@@ -1441,9 +1444,6 @@ static void __init mackerel_init(void) | |||
1441 | ARRAY_SIZE(mackerel_pinctrl_map)); | 1444 | ARRAY_SIZE(mackerel_pinctrl_map)); |
1442 | sh7372_pinmux_init(); | 1445 | sh7372_pinmux_init(); |
1443 | 1446 | ||
1444 | /* backlight, off by default */ | ||
1445 | gpio_request_one(31, GPIOF_OUT_INIT_LOW, NULL); | ||
1446 | |||
1447 | gpio_request_one(151, GPIOF_OUT_INIT_HIGH, NULL); /* LCDDON */ | 1447 | gpio_request_one(151, GPIOF_OUT_INIT_HIGH, NULL); /* LCDDON */ |
1448 | 1448 | ||
1449 | /* USBHS0 */ | 1449 | /* USBHS0 */ |
diff --git a/arch/sh/boards/mach-ecovec24/setup.c b/arch/sh/boards/mach-ecovec24/setup.c index 61fade0ffa96..bcbb86bd659e 100644 --- a/arch/sh/boards/mach-ecovec24/setup.c +++ b/arch/sh/boards/mach-ecovec24/setup.c | |||
@@ -30,6 +30,7 @@ | |||
30 | #include <linux/spi/mmc_spi.h> | 30 | #include <linux/spi/mmc_spi.h> |
31 | #include <linux/input.h> | 31 | #include <linux/input.h> |
32 | #include <linux/input/sh_keysc.h> | 32 | #include <linux/input/sh_keysc.h> |
33 | #include <linux/platform_data/gpio_backlight.h> | ||
33 | #include <linux/sh_eth.h> | 34 | #include <linux/sh_eth.h> |
34 | #include <linux/sh_intc.h> | 35 | #include <linux/sh_intc.h> |
35 | #include <linux/videodev2.h> | 36 | #include <linux/videodev2.h> |
@@ -303,7 +304,7 @@ static struct platform_device usbhs_device = { | |||
303 | .resource = usbhs_resources, | 304 | .resource = usbhs_resources, |
304 | }; | 305 | }; |
305 | 306 | ||
306 | /* LCDC */ | 307 | /* LCDC and backlight */ |
307 | static const struct fb_videomode ecovec_lcd_modes[] = { | 308 | static const struct fb_videomode ecovec_lcd_modes[] = { |
308 | { | 309 | { |
309 | .name = "Panel", | 310 | .name = "Panel", |
@@ -334,13 +335,6 @@ static const struct fb_videomode ecovec_dvi_modes[] = { | |||
334 | }, | 335 | }, |
335 | }; | 336 | }; |
336 | 337 | ||
337 | static int ecovec24_set_brightness(int brightness) | ||
338 | { | ||
339 | gpio_set_value(GPIO_PTR1, brightness); | ||
340 | |||
341 | return 0; | ||
342 | } | ||
343 | |||
344 | static struct sh_mobile_lcdc_info lcdc_info = { | 338 | static struct sh_mobile_lcdc_info lcdc_info = { |
345 | .ch[0] = { | 339 | .ch[0] = { |
346 | .interface_type = RGB18, | 340 | .interface_type = RGB18, |
@@ -350,11 +344,6 @@ static struct sh_mobile_lcdc_info lcdc_info = { | |||
350 | .width = 152, | 344 | .width = 152, |
351 | .height = 91, | 345 | .height = 91, |
352 | }, | 346 | }, |
353 | .bl_info = { | ||
354 | .name = "sh_mobile_lcdc_bl", | ||
355 | .max_brightness = 1, | ||
356 | .set_brightness = ecovec24_set_brightness, | ||
357 | }, | ||
358 | } | 347 | } |
359 | }; | 348 | }; |
360 | 349 | ||
@@ -380,6 +369,20 @@ static struct platform_device lcdc_device = { | |||
380 | }, | 369 | }, |
381 | }; | 370 | }; |
382 | 371 | ||
372 | static struct gpio_backlight_platform_data gpio_backlight_data = { | ||
373 | .fbdev = &lcdc_device.dev, | ||
374 | .gpio = GPIO_PTR1, | ||
375 | .def_value = 1, | ||
376 | .name = "backlight", | ||
377 | }; | ||
378 | |||
379 | static struct platform_device gpio_backlight_device = { | ||
380 | .name = "gpio-backlight", | ||
381 | .dev = { | ||
382 | .platform_data = &gpio_backlight_data, | ||
383 | }, | ||
384 | }; | ||
385 | |||
383 | /* CEU0 */ | 386 | /* CEU0 */ |
384 | static struct sh_mobile_ceu_info sh_mobile_ceu0_info = { | 387 | static struct sh_mobile_ceu_info sh_mobile_ceu0_info = { |
385 | .flags = SH_CEU_FLAG_USE_8BIT_BUS, | 388 | .flags = SH_CEU_FLAG_USE_8BIT_BUS, |
@@ -1049,6 +1052,7 @@ static struct platform_device *ecovec_devices[] __initdata = { | |||
1049 | &usb1_common_device, | 1052 | &usb1_common_device, |
1050 | &usbhs_device, | 1053 | &usbhs_device, |
1051 | &lcdc_device, | 1054 | &lcdc_device, |
1055 | &gpio_backlight_device, | ||
1052 | &ceu0_device, | 1056 | &ceu0_device, |
1053 | &ceu1_device, | 1057 | &ceu1_device, |
1054 | &keysc_device, | 1058 | &keysc_device, |
@@ -1239,11 +1243,9 @@ static int __init arch_setup(void) | |||
1239 | 1243 | ||
1240 | gpio_request(GPIO_PTE6, NULL); | 1244 | gpio_request(GPIO_PTE6, NULL); |
1241 | gpio_request(GPIO_PTU1, NULL); | 1245 | gpio_request(GPIO_PTU1, NULL); |
1242 | gpio_request(GPIO_PTR1, NULL); | ||
1243 | gpio_request(GPIO_PTA2, NULL); | 1246 | gpio_request(GPIO_PTA2, NULL); |
1244 | gpio_direction_input(GPIO_PTE6); | 1247 | gpio_direction_input(GPIO_PTE6); |
1245 | gpio_direction_output(GPIO_PTU1, 0); | 1248 | gpio_direction_output(GPIO_PTU1, 0); |
1246 | gpio_direction_output(GPIO_PTR1, 0); | ||
1247 | gpio_direction_output(GPIO_PTA2, 0); | 1249 | gpio_direction_output(GPIO_PTA2, 0); |
1248 | 1250 | ||
1249 | /* I/O buffer drive ability is high */ | 1251 | /* I/O buffer drive ability is high */ |
@@ -1256,6 +1258,9 @@ static int __init arch_setup(void) | |||
1256 | lcdc_info.ch[0].lcd_modes = ecovec_dvi_modes; | 1258 | lcdc_info.ch[0].lcd_modes = ecovec_dvi_modes; |
1257 | lcdc_info.ch[0].num_modes = ARRAY_SIZE(ecovec_dvi_modes); | 1259 | lcdc_info.ch[0].num_modes = ARRAY_SIZE(ecovec_dvi_modes); |
1258 | 1260 | ||
1261 | /* No backlight */ | ||
1262 | gpio_backlight_data.fbdev = NULL; | ||
1263 | |||
1259 | gpio_set_value(GPIO_PTA2, 1); | 1264 | gpio_set_value(GPIO_PTA2, 1); |
1260 | gpio_set_value(GPIO_PTU1, 1); | 1265 | gpio_set_value(GPIO_PTU1, 1); |
1261 | } else { | 1266 | } else { |
@@ -1265,8 +1270,6 @@ static int __init arch_setup(void) | |||
1265 | lcdc_info.ch[0].lcd_modes = ecovec_lcd_modes; | 1270 | lcdc_info.ch[0].lcd_modes = ecovec_lcd_modes; |
1266 | lcdc_info.ch[0].num_modes = ARRAY_SIZE(ecovec_lcd_modes); | 1271 | lcdc_info.ch[0].num_modes = ARRAY_SIZE(ecovec_lcd_modes); |
1267 | 1272 | ||
1268 | gpio_set_value(GPIO_PTR1, 1); | ||
1269 | |||
1270 | /* FIXME | 1273 | /* FIXME |
1271 | * | 1274 | * |
1272 | * LCDDON control is needed for Panel, | 1275 | * LCDDON control is needed for Panel, |
diff --git a/arch/sh/boards/mach-kfr2r09/lcd_wqvga.c b/arch/sh/boards/mach-kfr2r09/lcd_wqvga.c index c62050332629..355a78a3b313 100644 --- a/arch/sh/boards/mach-kfr2r09/lcd_wqvga.c +++ b/arch/sh/boards/mach-kfr2r09/lcd_wqvga.c | |||
@@ -276,51 +276,3 @@ void kfr2r09_lcd_start(void *sohandle, struct sh_mobile_lcdc_sys_bus_ops *so) | |||
276 | { | 276 | { |
277 | write_memory_start(sohandle, so); | 277 | write_memory_start(sohandle, so); |
278 | } | 278 | } |
279 | |||
280 | #define CTRL_CKSW 0x10 | ||
281 | #define CTRL_C10 0x20 | ||
282 | #define CTRL_CPSW 0x80 | ||
283 | #define MAIN_MLED4 0x40 | ||
284 | #define MAIN_MSW 0x80 | ||
285 | |||
286 | int kfr2r09_lcd_set_brightness(int brightness) | ||
287 | { | ||
288 | struct i2c_adapter *a; | ||
289 | struct i2c_msg msg; | ||
290 | unsigned char buf[2]; | ||
291 | int ret; | ||
292 | |||
293 | a = i2c_get_adapter(0); | ||
294 | if (!a) | ||
295 | return -ENODEV; | ||
296 | |||
297 | buf[0] = 0x00; | ||
298 | if (brightness) | ||
299 | buf[1] = CTRL_CPSW | CTRL_C10 | CTRL_CKSW; | ||
300 | else | ||
301 | buf[1] = 0; | ||
302 | |||
303 | msg.addr = 0x75; | ||
304 | msg.buf = buf; | ||
305 | msg.len = 2; | ||
306 | msg.flags = 0; | ||
307 | ret = i2c_transfer(a, &msg, 1); | ||
308 | if (ret != 1) | ||
309 | return -ENODEV; | ||
310 | |||
311 | buf[0] = 0x01; | ||
312 | if (brightness) | ||
313 | buf[1] = MAIN_MSW | MAIN_MLED4 | 0x0c; | ||
314 | else | ||
315 | buf[1] = 0; | ||
316 | |||
317 | msg.addr = 0x75; | ||
318 | msg.buf = buf; | ||
319 | msg.len = 2; | ||
320 | msg.flags = 0; | ||
321 | ret = i2c_transfer(a, &msg, 1); | ||
322 | if (ret != 1) | ||
323 | return -ENODEV; | ||
324 | |||
325 | return 0; | ||
326 | } | ||
diff --git a/arch/sh/boards/mach-kfr2r09/setup.c b/arch/sh/boards/mach-kfr2r09/setup.c index ab502f12ef57..1df4398f8375 100644 --- a/arch/sh/boards/mach-kfr2r09/setup.c +++ b/arch/sh/boards/mach-kfr2r09/setup.c | |||
@@ -21,6 +21,7 @@ | |||
21 | #include <linux/input.h> | 21 | #include <linux/input.h> |
22 | #include <linux/input/sh_keysc.h> | 22 | #include <linux/input/sh_keysc.h> |
23 | #include <linux/i2c.h> | 23 | #include <linux/i2c.h> |
24 | #include <linux/platform_data/lv5207lp.h> | ||
24 | #include <linux/regulator/fixed.h> | 25 | #include <linux/regulator/fixed.h> |
25 | #include <linux/regulator/machine.h> | 26 | #include <linux/regulator/machine.h> |
26 | #include <linux/usb/r8a66597.h> | 27 | #include <linux/usb/r8a66597.h> |
@@ -159,11 +160,6 @@ static struct sh_mobile_lcdc_info kfr2r09_sh_lcdc_info = { | |||
159 | .setup_sys = kfr2r09_lcd_setup, | 160 | .setup_sys = kfr2r09_lcd_setup, |
160 | .start_transfer = kfr2r09_lcd_start, | 161 | .start_transfer = kfr2r09_lcd_start, |
161 | }, | 162 | }, |
162 | .bl_info = { | ||
163 | .name = "sh_mobile_lcdc_bl", | ||
164 | .max_brightness = 1, | ||
165 | .set_brightness = kfr2r09_lcd_set_brightness, | ||
166 | }, | ||
167 | .sys_bus_cfg = { | 163 | .sys_bus_cfg = { |
168 | .ldmt2r = 0x07010904, | 164 | .ldmt2r = 0x07010904, |
169 | .ldmt3r = 0x14012914, | 165 | .ldmt3r = 0x14012914, |
@@ -195,6 +191,17 @@ static struct platform_device kfr2r09_sh_lcdc_device = { | |||
195 | }, | 191 | }, |
196 | }; | 192 | }; |
197 | 193 | ||
194 | static struct lv5207lp_platform_data kfr2r09_backlight_data = { | ||
195 | .fbdev = &kfr2r09_sh_lcdc_device.dev, | ||
196 | .def_value = 13, | ||
197 | .max_value = 13, | ||
198 | }; | ||
199 | |||
200 | static struct i2c_board_info kfr2r09_backlight_board_info = { | ||
201 | I2C_BOARD_INFO("lv5207lp", 0x75), | ||
202 | .platform_data = &kfr2r09_backlight_data, | ||
203 | }; | ||
204 | |||
198 | static struct r8a66597_platdata kfr2r09_usb0_gadget_data = { | 205 | static struct r8a66597_platdata kfr2r09_usb0_gadget_data = { |
199 | .on_chip = 1, | 206 | .on_chip = 1, |
200 | }; | 207 | }; |
@@ -627,6 +634,8 @@ static int __init kfr2r09_devices_setup(void) | |||
627 | gpio_request(GPIO_FN_SDHI0CMD, NULL); | 634 | gpio_request(GPIO_FN_SDHI0CMD, NULL); |
628 | gpio_request(GPIO_FN_SDHI0CLK, NULL); | 635 | gpio_request(GPIO_FN_SDHI0CLK, NULL); |
629 | 636 | ||
637 | i2c_register_board_info(0, &kfr2r09_backlight_board_info, 1); | ||
638 | |||
630 | return platform_add_devices(kfr2r09_devices, | 639 | return platform_add_devices(kfr2r09_devices, |
631 | ARRAY_SIZE(kfr2r09_devices)); | 640 | ARRAY_SIZE(kfr2r09_devices)); |
632 | } | 641 | } |
diff --git a/arch/sh/include/mach-kfr2r09/mach/kfr2r09.h b/arch/sh/include/mach-kfr2r09/mach/kfr2r09.h index c20c9e5f5eab..79f154e5cb9c 100644 --- a/arch/sh/include/mach-kfr2r09/mach/kfr2r09.h +++ b/arch/sh/include/mach-kfr2r09/mach/kfr2r09.h | |||
@@ -4,13 +4,11 @@ | |||
4 | #include <video/sh_mobile_lcdc.h> | 4 | #include <video/sh_mobile_lcdc.h> |
5 | 5 | ||
6 | #if defined(CONFIG_FB_SH_MOBILE_LCDC) || defined(CONFIG_FB_SH_MOBILE_LCDC_MODULE) | 6 | #if defined(CONFIG_FB_SH_MOBILE_LCDC) || defined(CONFIG_FB_SH_MOBILE_LCDC_MODULE) |
7 | int kfr2r09_lcd_set_brightness(int brightness); | ||
8 | int kfr2r09_lcd_setup(void *sys_ops_handle, | 7 | int kfr2r09_lcd_setup(void *sys_ops_handle, |
9 | struct sh_mobile_lcdc_sys_bus_ops *sys_ops); | 8 | struct sh_mobile_lcdc_sys_bus_ops *sys_ops); |
10 | void kfr2r09_lcd_start(void *sys_ops_handle, | 9 | void kfr2r09_lcd_start(void *sys_ops_handle, |
11 | struct sh_mobile_lcdc_sys_bus_ops *sys_ops); | 10 | struct sh_mobile_lcdc_sys_bus_ops *sys_ops); |
12 | #else | 11 | #else |
13 | static int kfr2r09_lcd_set_brightness(int brightness) {} | ||
14 | static int kfr2r09_lcd_setup(void *sys_ops_handle, | 12 | static int kfr2r09_lcd_setup(void *sys_ops_handle, |
15 | struct sh_mobile_lcdc_sys_bus_ops *sys_ops) | 13 | struct sh_mobile_lcdc_sys_bus_ops *sys_ops) |
16 | { | 14 | { |
diff --git a/drivers/video/backlight/Kconfig b/drivers/video/backlight/Kconfig index d5ab6583f440..d4a7a351d67c 100644 --- a/drivers/video/backlight/Kconfig +++ b/drivers/video/backlight/Kconfig | |||
@@ -425,6 +425,25 @@ config BACKLIGHT_AS3711 | |||
425 | If you have an Austrian Microsystems AS3711 say Y to enable the | 425 | If you have an Austrian Microsystems AS3711 say Y to enable the |
426 | backlight driver. | 426 | backlight driver. |
427 | 427 | ||
428 | config BACKLIGHT_GPIO | ||
429 | tristate "Generic GPIO based Backlight Driver" | ||
430 | depends on GPIOLIB | ||
431 | help | ||
432 | If you have a LCD backlight adjustable by GPIO, say Y to enable | ||
433 | this driver. | ||
434 | |||
435 | config BACKLIGHT_LV5207LP | ||
436 | tristate "Sanyo LV5207LP Backlight" | ||
437 | depends on I2C | ||
438 | help | ||
439 | If you have a Sanyo LV5207LP say Y to enable the backlight driver. | ||
440 | |||
441 | config BACKLIGHT_BD6107 | ||
442 | tristate "Rohm BD6107 Backlight" | ||
443 | depends on I2C | ||
444 | help | ||
445 | If you have a Rohm BD6107 say Y to enable the backlight driver. | ||
446 | |||
428 | endif # BACKLIGHT_CLASS_DEVICE | 447 | endif # BACKLIGHT_CLASS_DEVICE |
429 | 448 | ||
430 | endif # BACKLIGHT_LCD_SUPPORT | 449 | endif # BACKLIGHT_LCD_SUPPORT |
diff --git a/drivers/video/backlight/Makefile b/drivers/video/backlight/Makefile index 92711fe60464..38e1babb1946 100644 --- a/drivers/video/backlight/Makefile +++ b/drivers/video/backlight/Makefile | |||
@@ -26,12 +26,14 @@ obj-$(CONFIG_BACKLIGHT_ADP8870) += adp8870_bl.o | |||
26 | obj-$(CONFIG_BACKLIGHT_APPLE) += apple_bl.o | 26 | obj-$(CONFIG_BACKLIGHT_APPLE) += apple_bl.o |
27 | obj-$(CONFIG_BACKLIGHT_AS3711) += as3711_bl.o | 27 | obj-$(CONFIG_BACKLIGHT_AS3711) += as3711_bl.o |
28 | obj-$(CONFIG_BACKLIGHT_ATMEL_PWM) += atmel-pwm-bl.o | 28 | obj-$(CONFIG_BACKLIGHT_ATMEL_PWM) += atmel-pwm-bl.o |
29 | obj-$(CONFIG_BACKLIGHT_BD6107) += bd6107.o | ||
29 | obj-$(CONFIG_BACKLIGHT_CARILLO_RANCH) += cr_bllcd.o | 30 | obj-$(CONFIG_BACKLIGHT_CARILLO_RANCH) += cr_bllcd.o |
30 | obj-$(CONFIG_BACKLIGHT_CLASS_DEVICE) += backlight.o | 31 | obj-$(CONFIG_BACKLIGHT_CLASS_DEVICE) += backlight.o |
31 | obj-$(CONFIG_BACKLIGHT_DA903X) += da903x_bl.o | 32 | obj-$(CONFIG_BACKLIGHT_DA903X) += da903x_bl.o |
32 | obj-$(CONFIG_BACKLIGHT_DA9052) += da9052_bl.o | 33 | obj-$(CONFIG_BACKLIGHT_DA9052) += da9052_bl.o |
33 | obj-$(CONFIG_BACKLIGHT_EP93XX) += ep93xx_bl.o | 34 | obj-$(CONFIG_BACKLIGHT_EP93XX) += ep93xx_bl.o |
34 | obj-$(CONFIG_BACKLIGHT_GENERIC) += generic_bl.o | 35 | obj-$(CONFIG_BACKLIGHT_GENERIC) += generic_bl.o |
36 | obj-$(CONFIG_BACKLIGHT_GPIO) += gpio_backlight.o | ||
35 | obj-$(CONFIG_BACKLIGHT_HP680) += hp680_bl.o | 37 | obj-$(CONFIG_BACKLIGHT_HP680) += hp680_bl.o |
36 | obj-$(CONFIG_BACKLIGHT_HP700) += jornada720_bl.o | 38 | obj-$(CONFIG_BACKLIGHT_HP700) += jornada720_bl.o |
37 | obj-$(CONFIG_BACKLIGHT_LM3533) += lm3533_bl.o | 39 | obj-$(CONFIG_BACKLIGHT_LM3533) += lm3533_bl.o |
@@ -40,6 +42,7 @@ obj-$(CONFIG_BACKLIGHT_LM3639) += lm3639_bl.o | |||
40 | obj-$(CONFIG_BACKLIGHT_LOCOMO) += locomolcd.o | 42 | obj-$(CONFIG_BACKLIGHT_LOCOMO) += locomolcd.o |
41 | obj-$(CONFIG_BACKLIGHT_LP855X) += lp855x_bl.o | 43 | obj-$(CONFIG_BACKLIGHT_LP855X) += lp855x_bl.o |
42 | obj-$(CONFIG_BACKLIGHT_LP8788) += lp8788_bl.o | 44 | obj-$(CONFIG_BACKLIGHT_LP8788) += lp8788_bl.o |
45 | obj-$(CONFIG_BACKLIGHT_LV5207LP) += lv5207lp.o | ||
43 | obj-$(CONFIG_BACKLIGHT_MAX8925) += max8925_bl.o | 46 | obj-$(CONFIG_BACKLIGHT_MAX8925) += max8925_bl.o |
44 | obj-$(CONFIG_BACKLIGHT_OMAP1) += omap1_bl.o | 47 | obj-$(CONFIG_BACKLIGHT_OMAP1) += omap1_bl.o |
45 | obj-$(CONFIG_BACKLIGHT_OT200) += ot200_bl.o | 48 | obj-$(CONFIG_BACKLIGHT_OT200) += ot200_bl.o |
diff --git a/drivers/video/backlight/bd6107.c b/drivers/video/backlight/bd6107.c new file mode 100644 index 000000000000..15e3294b29fe --- /dev/null +++ b/drivers/video/backlight/bd6107.c | |||
@@ -0,0 +1,213 @@ | |||
1 | /* | ||
2 | * ROHM Semiconductor BD6107 LED Driver | ||
3 | * | ||
4 | * Copyright (C) 2013 Ideas on board SPRL | ||
5 | * | ||
6 | * Contact: Laurent Pinchart <laurent.pinchart@ideasonboard.com> | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or modify | ||
9 | * it under the terms of the GNU General Public License version 2 as | ||
10 | * published by the Free Software Foundation. | ||
11 | */ | ||
12 | |||
13 | #include <linux/backlight.h> | ||
14 | #include <linux/delay.h> | ||
15 | #include <linux/err.h> | ||
16 | #include <linux/fb.h> | ||
17 | #include <linux/gpio.h> | ||
18 | #include <linux/i2c.h> | ||
19 | #include <linux/module.h> | ||
20 | #include <linux/platform_data/bd6107.h> | ||
21 | #include <linux/slab.h> | ||
22 | |||
23 | #define BD6107_PSCNT1 0x00 | ||
24 | #define BD6107_PSCNT1_PSCNTREG2 (1 << 2) | ||
25 | #define BD6107_PSCNT1_PSCNTREG1 (1 << 0) | ||
26 | #define BD6107_REGVSET 0x02 | ||
27 | #define BD6107_REGVSET_REG1VSET_2_85V (1 << 2) | ||
28 | #define BD6107_REGVSET_REG1VSET_2_80V (0 << 2) | ||
29 | #define BD6107_LEDCNT1 0x03 | ||
30 | #define BD6107_LEDCNT1_LEDONOFF2 (1 << 1) | ||
31 | #define BD6107_LEDCNT1_LEDONOFF1 (1 << 0) | ||
32 | #define BD6107_PORTSEL 0x04 | ||
33 | #define BD6107_PORTSEL_LEDM(n) (1 << (n)) | ||
34 | #define BD6107_RGB1CNT1 0x05 | ||
35 | #define BD6107_RGB1CNT2 0x06 | ||
36 | #define BD6107_RGB1CNT3 0x07 | ||
37 | #define BD6107_RGB1CNT4 0x08 | ||
38 | #define BD6107_RGB1CNT5 0x09 | ||
39 | #define BD6107_RGB1FLM 0x0a | ||
40 | #define BD6107_RGB2CNT1 0x0b | ||
41 | #define BD6107_RGB2CNT2 0x0c | ||
42 | #define BD6107_RGB2CNT3 0x0d | ||
43 | #define BD6107_RGB2CNT4 0x0e | ||
44 | #define BD6107_RGB2CNT5 0x0f | ||
45 | #define BD6107_RGB2FLM 0x10 | ||
46 | #define BD6107_PSCONT3 0x11 | ||
47 | #define BD6107_SMMONCNT 0x12 | ||
48 | #define BD6107_DCDCCNT 0x13 | ||
49 | #define BD6107_IOSEL 0x14 | ||
50 | #define BD6107_OUT1 0x15 | ||
51 | #define BD6107_OUT2 0x16 | ||
52 | #define BD6107_MASK1 0x17 | ||
53 | #define BD6107_MASK2 0x18 | ||
54 | #define BD6107_FACTOR1 0x19 | ||
55 | #define BD6107_FACTOR2 0x1a | ||
56 | #define BD6107_CLRFACT1 0x1b | ||
57 | #define BD6107_CLRFACT2 0x1c | ||
58 | #define BD6107_STATE1 0x1d | ||
59 | #define BD6107_LSIVER 0x1e | ||
60 | #define BD6107_GRPSEL 0x1f | ||
61 | #define BD6107_LEDCNT2 0x20 | ||
62 | #define BD6107_LEDCNT3 0x21 | ||
63 | #define BD6107_MCURRENT 0x22 | ||
64 | #define BD6107_MAINCNT1 0x23 | ||
65 | #define BD6107_MAINCNT2 0x24 | ||
66 | #define BD6107_SLOPECNT 0x25 | ||
67 | #define BD6107_MSLOPE 0x26 | ||
68 | #define BD6107_RGBSLOPE 0x27 | ||
69 | #define BD6107_TEST 0x29 | ||
70 | #define BD6107_SFTRST 0x2a | ||
71 | #define BD6107_SFTRSTGD 0x2b | ||
72 | |||
73 | struct bd6107 { | ||
74 | struct i2c_client *client; | ||
75 | struct backlight_device *backlight; | ||
76 | struct bd6107_platform_data *pdata; | ||
77 | }; | ||
78 | |||
79 | static int bd6107_write(struct bd6107 *bd, u8 reg, u8 data) | ||
80 | { | ||
81 | return i2c_smbus_write_byte_data(bd->client, reg, data); | ||
82 | } | ||
83 | |||
84 | static int bd6107_backlight_update_status(struct backlight_device *backlight) | ||
85 | { | ||
86 | struct bd6107 *bd = bl_get_data(backlight); | ||
87 | int brightness = backlight->props.brightness; | ||
88 | |||
89 | if (backlight->props.power != FB_BLANK_UNBLANK || | ||
90 | backlight->props.fb_blank != FB_BLANK_UNBLANK || | ||
91 | backlight->props.state & (BL_CORE_SUSPENDED | BL_CORE_FBBLANK)) | ||
92 | brightness = 0; | ||
93 | |||
94 | if (brightness) { | ||
95 | bd6107_write(bd, BD6107_PORTSEL, BD6107_PORTSEL_LEDM(2) | | ||
96 | BD6107_PORTSEL_LEDM(1) | BD6107_PORTSEL_LEDM(0)); | ||
97 | bd6107_write(bd, BD6107_MAINCNT1, brightness); | ||
98 | bd6107_write(bd, BD6107_LEDCNT1, BD6107_LEDCNT1_LEDONOFF1); | ||
99 | } else { | ||
100 | gpio_set_value(bd->pdata->reset, 0); | ||
101 | msleep(24); | ||
102 | gpio_set_value(bd->pdata->reset, 1); | ||
103 | } | ||
104 | |||
105 | return 0; | ||
106 | } | ||
107 | |||
108 | static int bd6107_backlight_get_brightness(struct backlight_device *backlight) | ||
109 | { | ||
110 | return backlight->props.brightness; | ||
111 | } | ||
112 | |||
113 | static int bd6107_backlight_check_fb(struct backlight_device *backlight, | ||
114 | struct fb_info *info) | ||
115 | { | ||
116 | struct bd6107 *bd = bl_get_data(backlight); | ||
117 | |||
118 | return bd->pdata->fbdev == NULL || bd->pdata->fbdev == info->dev; | ||
119 | } | ||
120 | |||
121 | static const struct backlight_ops bd6107_backlight_ops = { | ||
122 | .options = BL_CORE_SUSPENDRESUME, | ||
123 | .update_status = bd6107_backlight_update_status, | ||
124 | .get_brightness = bd6107_backlight_get_brightness, | ||
125 | .check_fb = bd6107_backlight_check_fb, | ||
126 | }; | ||
127 | |||
128 | static int bd6107_probe(struct i2c_client *client, | ||
129 | const struct i2c_device_id *id) | ||
130 | { | ||
131 | struct bd6107_platform_data *pdata = client->dev.platform_data; | ||
132 | struct backlight_device *backlight; | ||
133 | struct backlight_properties props; | ||
134 | struct bd6107 *bd; | ||
135 | int ret; | ||
136 | |||
137 | if (pdata == NULL || !pdata->reset) { | ||
138 | dev_err(&client->dev, "No reset GPIO in platform data\n"); | ||
139 | return -EINVAL; | ||
140 | } | ||
141 | |||
142 | if (!i2c_check_functionality(client->adapter, | ||
143 | I2C_FUNC_SMBUS_BYTE_DATA)) { | ||
144 | dev_warn(&client->dev, | ||
145 | "I2C adapter doesn't support I2C_FUNC_SMBUS_BYTE\n"); | ||
146 | return -EIO; | ||
147 | } | ||
148 | |||
149 | bd = devm_kzalloc(&client->dev, sizeof(*bd), GFP_KERNEL); | ||
150 | if (!bd) | ||
151 | return -ENOMEM; | ||
152 | |||
153 | bd->client = client; | ||
154 | bd->pdata = pdata; | ||
155 | |||
156 | ret = devm_gpio_request_one(&client->dev, pdata->reset, | ||
157 | GPIOF_DIR_OUT | GPIOF_INIT_LOW, "reset"); | ||
158 | if (ret < 0) { | ||
159 | dev_err(&client->dev, "unable to request reset GPIO\n"); | ||
160 | return ret; | ||
161 | } | ||
162 | |||
163 | memset(&props, 0, sizeof(props)); | ||
164 | props.type = BACKLIGHT_RAW; | ||
165 | props.max_brightness = 128; | ||
166 | props.brightness = clamp_t(unsigned int, pdata->def_value, 0, | ||
167 | props.max_brightness); | ||
168 | |||
169 | backlight = backlight_device_register(dev_name(&client->dev), | ||
170 | &bd->client->dev, bd, | ||
171 | &bd6107_backlight_ops, &props); | ||
172 | if (IS_ERR(backlight)) { | ||
173 | dev_err(&client->dev, "failed to register backlight\n"); | ||
174 | return PTR_ERR(backlight); | ||
175 | } | ||
176 | |||
177 | backlight_update_status(backlight); | ||
178 | i2c_set_clientdata(client, backlight); | ||
179 | |||
180 | return 0; | ||
181 | } | ||
182 | |||
183 | static int bd6107_remove(struct i2c_client *client) | ||
184 | { | ||
185 | struct backlight_device *backlight = i2c_get_clientdata(client); | ||
186 | |||
187 | backlight->props.brightness = 0; | ||
188 | backlight_update_status(backlight); | ||
189 | backlight_device_unregister(backlight); | ||
190 | |||
191 | return 0; | ||
192 | } | ||
193 | |||
194 | static const struct i2c_device_id bd6107_ids[] = { | ||
195 | { "bd6107", 0 }, | ||
196 | { } | ||
197 | }; | ||
198 | MODULE_DEVICE_TABLE(i2c, bd6107_ids); | ||
199 | |||
200 | static struct i2c_driver bd6107_driver = { | ||
201 | .driver = { | ||
202 | .name = "bd6107", | ||
203 | }, | ||
204 | .probe = bd6107_probe, | ||
205 | .remove = bd6107_remove, | ||
206 | .id_table = bd6107_ids, | ||
207 | }; | ||
208 | |||
209 | module_i2c_driver(bd6107_driver); | ||
210 | |||
211 | MODULE_DESCRIPTION("Rohm BD6107 Backlight Driver"); | ||
212 | MODULE_AUTHOR("Laurent Pinchart <laurent.pinchart@ideasonboard.com>"); | ||
213 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/video/backlight/gpio_backlight.c b/drivers/video/backlight/gpio_backlight.c new file mode 100644 index 000000000000..5fa217f9f445 --- /dev/null +++ b/drivers/video/backlight/gpio_backlight.c | |||
@@ -0,0 +1,133 @@ | |||
1 | /* | ||
2 | * gpio_backlight.c - Simple GPIO-controlled backlight | ||
3 | * | ||
4 | * This program is free software; you can redistribute it and/or modify | ||
5 | * it under the terms of the GNU General Public License version 2 as | ||
6 | * published by the Free Software Foundation. | ||
7 | */ | ||
8 | |||
9 | #include <linux/backlight.h> | ||
10 | #include <linux/err.h> | ||
11 | #include <linux/fb.h> | ||
12 | #include <linux/gpio.h> | ||
13 | #include <linux/init.h> | ||
14 | #include <linux/kernel.h> | ||
15 | #include <linux/module.h> | ||
16 | #include <linux/platform_data/gpio_backlight.h> | ||
17 | #include <linux/platform_device.h> | ||
18 | #include <linux/slab.h> | ||
19 | |||
20 | struct gpio_backlight { | ||
21 | struct device *dev; | ||
22 | struct device *fbdev; | ||
23 | |||
24 | int gpio; | ||
25 | int active; | ||
26 | }; | ||
27 | |||
28 | static int gpio_backlight_update_status(struct backlight_device *bl) | ||
29 | { | ||
30 | struct gpio_backlight *gbl = bl_get_data(bl); | ||
31 | int brightness = bl->props.brightness; | ||
32 | |||
33 | if (bl->props.power != FB_BLANK_UNBLANK || | ||
34 | bl->props.fb_blank != FB_BLANK_UNBLANK || | ||
35 | bl->props.state & (BL_CORE_SUSPENDED | BL_CORE_FBBLANK)) | ||
36 | brightness = 0; | ||
37 | |||
38 | gpio_set_value(gbl->gpio, brightness ? gbl->active : !gbl->active); | ||
39 | |||
40 | return 0; | ||
41 | } | ||
42 | |||
43 | static int gpio_backlight_get_brightness(struct backlight_device *bl) | ||
44 | { | ||
45 | return bl->props.brightness; | ||
46 | } | ||
47 | |||
48 | static int gpio_backlight_check_fb(struct backlight_device *bl, | ||
49 | struct fb_info *info) | ||
50 | { | ||
51 | struct gpio_backlight *gbl = bl_get_data(bl); | ||
52 | |||
53 | return gbl->fbdev == NULL || gbl->fbdev == info->dev; | ||
54 | } | ||
55 | |||
56 | static const struct backlight_ops gpio_backlight_ops = { | ||
57 | .options = BL_CORE_SUSPENDRESUME, | ||
58 | .update_status = gpio_backlight_update_status, | ||
59 | .get_brightness = gpio_backlight_get_brightness, | ||
60 | .check_fb = gpio_backlight_check_fb, | ||
61 | }; | ||
62 | |||
63 | static int gpio_backlight_probe(struct platform_device *pdev) | ||
64 | { | ||
65 | struct gpio_backlight_platform_data *pdata = pdev->dev.platform_data; | ||
66 | struct backlight_properties props; | ||
67 | struct backlight_device *bl; | ||
68 | struct gpio_backlight *gbl; | ||
69 | int ret; | ||
70 | |||
71 | if (!pdata) { | ||
72 | dev_err(&pdev->dev, "failed to find platform data\n"); | ||
73 | return -ENODEV; | ||
74 | } | ||
75 | |||
76 | gbl = devm_kzalloc(&pdev->dev, sizeof(*gbl), GFP_KERNEL); | ||
77 | if (gbl == NULL) | ||
78 | return -ENOMEM; | ||
79 | |||
80 | gbl->dev = &pdev->dev; | ||
81 | gbl->fbdev = pdata->fbdev; | ||
82 | gbl->gpio = pdata->gpio; | ||
83 | gbl->active = pdata->active_low ? 0 : 1; | ||
84 | |||
85 | ret = devm_gpio_request_one(gbl->dev, gbl->gpio, GPIOF_DIR_OUT | | ||
86 | (gbl->active ? GPIOF_INIT_LOW | ||
87 | : GPIOF_INIT_HIGH), | ||
88 | pdata->name); | ||
89 | if (ret < 0) { | ||
90 | dev_err(&pdev->dev, "unable to request GPIO\n"); | ||
91 | return ret; | ||
92 | } | ||
93 | |||
94 | memset(&props, 0, sizeof(props)); | ||
95 | props.type = BACKLIGHT_RAW; | ||
96 | props.max_brightness = 1; | ||
97 | bl = backlight_device_register(dev_name(&pdev->dev), &pdev->dev, gbl, | ||
98 | &gpio_backlight_ops, &props); | ||
99 | if (IS_ERR(bl)) { | ||
100 | dev_err(&pdev->dev, "failed to register backlight\n"); | ||
101 | return PTR_ERR(bl); | ||
102 | } | ||
103 | |||
104 | bl->props.brightness = pdata->def_value; | ||
105 | backlight_update_status(bl); | ||
106 | |||
107 | platform_set_drvdata(pdev, bl); | ||
108 | return 0; | ||
109 | } | ||
110 | |||
111 | static int gpio_backlight_remove(struct platform_device *pdev) | ||
112 | { | ||
113 | struct backlight_device *bl = platform_get_drvdata(pdev); | ||
114 | |||
115 | backlight_device_unregister(bl); | ||
116 | return 0; | ||
117 | } | ||
118 | |||
119 | static struct platform_driver gpio_backlight_driver = { | ||
120 | .driver = { | ||
121 | .name = "gpio-backlight", | ||
122 | .owner = THIS_MODULE, | ||
123 | }, | ||
124 | .probe = gpio_backlight_probe, | ||
125 | .remove = gpio_backlight_remove, | ||
126 | }; | ||
127 | |||
128 | module_platform_driver(gpio_backlight_driver); | ||
129 | |||
130 | MODULE_AUTHOR("Laurent Pinchart <laurent.pinchart@ideasonboard.com>"); | ||
131 | MODULE_DESCRIPTION("GPIO-based Backlight Driver"); | ||
132 | MODULE_LICENSE("GPL"); | ||
133 | MODULE_ALIAS("platform:gpio-backlight"); | ||
diff --git a/drivers/video/backlight/lv5207lp.c b/drivers/video/backlight/lv5207lp.c new file mode 100644 index 000000000000..498fd73d59b9 --- /dev/null +++ b/drivers/video/backlight/lv5207lp.c | |||
@@ -0,0 +1,171 @@ | |||
1 | /* | ||
2 | * Sanyo LV5207LP LED Driver | ||
3 | * | ||
4 | * Copyright (C) 2013 Ideas on board SPRL | ||
5 | * | ||
6 | * Contact: Laurent Pinchart <laurent.pinchart@ideasonboard.com> | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or modify | ||
9 | * it under the terms of the GNU General Public License version 2 as | ||
10 | * published by the Free Software Foundation. | ||
11 | */ | ||
12 | |||
13 | #include <linux/backlight.h> | ||
14 | #include <linux/err.h> | ||
15 | #include <linux/fb.h> | ||
16 | #include <linux/i2c.h> | ||
17 | #include <linux/module.h> | ||
18 | #include <linux/platform_data/lv5207lp.h> | ||
19 | #include <linux/slab.h> | ||
20 | |||
21 | #define LV5207LP_CTRL1 0x00 | ||
22 | #define LV5207LP_CPSW (1 << 7) | ||
23 | #define LV5207LP_SCTEN (1 << 6) | ||
24 | #define LV5207LP_C10 (1 << 5) | ||
25 | #define LV5207LP_CKSW (1 << 4) | ||
26 | #define LV5207LP_RSW (1 << 3) | ||
27 | #define LV5207LP_GSW (1 << 2) | ||
28 | #define LV5207LP_BSW (1 << 1) | ||
29 | #define LV5207LP_CTRL2 0x01 | ||
30 | #define LV5207LP_MSW (1 << 7) | ||
31 | #define LV5207LP_MLED4 (1 << 6) | ||
32 | #define LV5207LP_RED 0x02 | ||
33 | #define LV5207LP_GREEN 0x03 | ||
34 | #define LV5207LP_BLUE 0x04 | ||
35 | |||
36 | #define LV5207LP_MAX_BRIGHTNESS 32 | ||
37 | |||
38 | struct lv5207lp { | ||
39 | struct i2c_client *client; | ||
40 | struct backlight_device *backlight; | ||
41 | struct lv5207lp_platform_data *pdata; | ||
42 | }; | ||
43 | |||
44 | static int lv5207lp_write(struct lv5207lp *lv, u8 reg, u8 data) | ||
45 | { | ||
46 | return i2c_smbus_write_byte_data(lv->client, reg, data); | ||
47 | } | ||
48 | |||
49 | static int lv5207lp_backlight_update_status(struct backlight_device *backlight) | ||
50 | { | ||
51 | struct lv5207lp *lv = bl_get_data(backlight); | ||
52 | int brightness = backlight->props.brightness; | ||
53 | |||
54 | if (backlight->props.power != FB_BLANK_UNBLANK || | ||
55 | backlight->props.fb_blank != FB_BLANK_UNBLANK || | ||
56 | backlight->props.state & (BL_CORE_SUSPENDED | BL_CORE_FBBLANK)) | ||
57 | brightness = 0; | ||
58 | |||
59 | if (brightness) { | ||
60 | lv5207lp_write(lv, LV5207LP_CTRL1, | ||
61 | LV5207LP_CPSW | LV5207LP_C10 | LV5207LP_CKSW); | ||
62 | lv5207lp_write(lv, LV5207LP_CTRL2, | ||
63 | LV5207LP_MSW | LV5207LP_MLED4 | | ||
64 | (brightness - 1)); | ||
65 | } else { | ||
66 | lv5207lp_write(lv, LV5207LP_CTRL1, 0); | ||
67 | lv5207lp_write(lv, LV5207LP_CTRL2, 0); | ||
68 | } | ||
69 | |||
70 | return 0; | ||
71 | } | ||
72 | |||
73 | static int lv5207lp_backlight_get_brightness(struct backlight_device *backlight) | ||
74 | { | ||
75 | return backlight->props.brightness; | ||
76 | } | ||
77 | |||
78 | static int lv5207lp_backlight_check_fb(struct backlight_device *backlight, | ||
79 | struct fb_info *info) | ||
80 | { | ||
81 | struct lv5207lp *lv = bl_get_data(backlight); | ||
82 | |||
83 | return lv->pdata->fbdev == NULL || lv->pdata->fbdev == info->dev; | ||
84 | } | ||
85 | |||
86 | static const struct backlight_ops lv5207lp_backlight_ops = { | ||
87 | .options = BL_CORE_SUSPENDRESUME, | ||
88 | .update_status = lv5207lp_backlight_update_status, | ||
89 | .get_brightness = lv5207lp_backlight_get_brightness, | ||
90 | .check_fb = lv5207lp_backlight_check_fb, | ||
91 | }; | ||
92 | |||
93 | static int lv5207lp_probe(struct i2c_client *client, | ||
94 | const struct i2c_device_id *id) | ||
95 | { | ||
96 | struct lv5207lp_platform_data *pdata = client->dev.platform_data; | ||
97 | struct backlight_device *backlight; | ||
98 | struct backlight_properties props; | ||
99 | struct lv5207lp *lv; | ||
100 | |||
101 | if (pdata == NULL) { | ||
102 | dev_err(&client->dev, "No platform data supplied\n"); | ||
103 | return -EINVAL; | ||
104 | } | ||
105 | |||
106 | if (!i2c_check_functionality(client->adapter, | ||
107 | I2C_FUNC_SMBUS_BYTE_DATA)) { | ||
108 | dev_warn(&client->dev, | ||
109 | "I2C adapter doesn't support I2C_FUNC_SMBUS_BYTE\n"); | ||
110 | return -EIO; | ||
111 | } | ||
112 | |||
113 | lv = devm_kzalloc(&client->dev, sizeof(*lv), GFP_KERNEL); | ||
114 | if (!lv) | ||
115 | return -ENOMEM; | ||
116 | |||
117 | lv->client = client; | ||
118 | lv->pdata = pdata; | ||
119 | |||
120 | memset(&props, 0, sizeof(props)); | ||
121 | props.type = BACKLIGHT_RAW; | ||
122 | props.max_brightness = min_t(unsigned int, pdata->max_value, | ||
123 | LV5207LP_MAX_BRIGHTNESS); | ||
124 | props.brightness = clamp_t(unsigned int, pdata->def_value, 0, | ||
125 | props.max_brightness); | ||
126 | |||
127 | backlight = backlight_device_register(dev_name(&client->dev), | ||
128 | &lv->client->dev, lv, | ||
129 | &lv5207lp_backlight_ops, &props); | ||
130 | if (IS_ERR(backlight)) { | ||
131 | dev_err(&client->dev, "failed to register backlight\n"); | ||
132 | return PTR_ERR(backlight); | ||
133 | } | ||
134 | |||
135 | backlight_update_status(backlight); | ||
136 | i2c_set_clientdata(client, backlight); | ||
137 | |||
138 | return 0; | ||
139 | } | ||
140 | |||
141 | static int lv5207lp_remove(struct i2c_client *client) | ||
142 | { | ||
143 | struct backlight_device *backlight = i2c_get_clientdata(client); | ||
144 | |||
145 | backlight->props.brightness = 0; | ||
146 | backlight_update_status(backlight); | ||
147 | backlight_device_unregister(backlight); | ||
148 | |||
149 | return 0; | ||
150 | } | ||
151 | |||
152 | static const struct i2c_device_id lv5207lp_ids[] = { | ||
153 | { "lv5207lp", 0 }, | ||
154 | { } | ||
155 | }; | ||
156 | MODULE_DEVICE_TABLE(i2c, lv5207lp_ids); | ||
157 | |||
158 | static struct i2c_driver lv5207lp_driver = { | ||
159 | .driver = { | ||
160 | .name = "lv5207lp", | ||
161 | }, | ||
162 | .probe = lv5207lp_probe, | ||
163 | .remove = lv5207lp_remove, | ||
164 | .id_table = lv5207lp_ids, | ||
165 | }; | ||
166 | |||
167 | module_i2c_driver(lv5207lp_driver); | ||
168 | |||
169 | MODULE_DESCRIPTION("Sanyo LV5207LP Backlight Driver"); | ||
170 | MODULE_AUTHOR("Laurent Pinchart <laurent.pinchart@ideasonboard.com>"); | ||
171 | MODULE_LICENSE("GPL"); | ||
diff --git a/include/linux/platform_data/bd6107.h b/include/linux/platform_data/bd6107.h new file mode 100644 index 000000000000..671d6502d241 --- /dev/null +++ b/include/linux/platform_data/bd6107.h | |||
@@ -0,0 +1,19 @@ | |||
1 | /* | ||
2 | * bd6107.h - Rohm BD6107 LEDs Driver | ||
3 | * | ||
4 | * This program is free software; you can redistribute it and/or modify | ||
5 | * it under the terms of the GNU General Public License version 2 as | ||
6 | * published by the Free Software Foundation. | ||
7 | */ | ||
8 | #ifndef __BD6107_H__ | ||
9 | #define __BD6107_H__ | ||
10 | |||
11 | struct device; | ||
12 | |||
13 | struct bd6107_platform_data { | ||
14 | struct device *fbdev; | ||
15 | int reset; /* Reset GPIO */ | ||
16 | unsigned int def_value; | ||
17 | }; | ||
18 | |||
19 | #endif | ||
diff --git a/include/linux/platform_data/gpio_backlight.h b/include/linux/platform_data/gpio_backlight.h new file mode 100644 index 000000000000..5ae0d9c80d4d --- /dev/null +++ b/include/linux/platform_data/gpio_backlight.h | |||
@@ -0,0 +1,21 @@ | |||
1 | /* | ||
2 | * gpio_backlight.h - Simple GPIO-controlled backlight | ||
3 | * | ||
4 | * This program is free software; you can redistribute it and/or modify | ||
5 | * it under the terms of the GNU General Public License version 2 as | ||
6 | * published by the Free Software Foundation. | ||
7 | */ | ||
8 | #ifndef __GPIO_BACKLIGHT_H__ | ||
9 | #define __GPIO_BACKLIGHT_H__ | ||
10 | |||
11 | struct device; | ||
12 | |||
13 | struct gpio_backlight_platform_data { | ||
14 | struct device *fbdev; | ||
15 | int gpio; | ||
16 | int def_value; | ||
17 | bool active_low; | ||
18 | const char *name; | ||
19 | }; | ||
20 | |||
21 | #endif | ||
diff --git a/include/linux/platform_data/lv5207lp.h b/include/linux/platform_data/lv5207lp.h new file mode 100644 index 000000000000..7dc4d9a219a6 --- /dev/null +++ b/include/linux/platform_data/lv5207lp.h | |||
@@ -0,0 +1,19 @@ | |||
1 | /* | ||
2 | * lv5207lp.h - Sanyo LV5207LP LEDs Driver | ||
3 | * | ||
4 | * This program is free software; you can redistribute it and/or modify | ||
5 | * it under the terms of the GNU General Public License version 2 as | ||
6 | * published by the Free Software Foundation. | ||
7 | */ | ||
8 | #ifndef __LV5207LP_H__ | ||
9 | #define __LV5207LP_H__ | ||
10 | |||
11 | struct device; | ||
12 | |||
13 | struct lv5207lp_platform_data { | ||
14 | struct device *fbdev; | ||
15 | unsigned int max_value; | ||
16 | unsigned int def_value; | ||
17 | }; | ||
18 | |||
19 | #endif | ||