diff options
author | Eric Miao <eric.miao@marvell.com> | 2008-09-06 23:30:06 -0400 |
---|---|---|
committer | Russell King <rmk+kernel@arm.linux.org.uk> | 2008-09-25 04:38:14 -0400 |
commit | ff7a4c7130c0ad97d55f7ab3f0a35fbc1f41b376 (patch) | |
tree | e24ccea4bdb38720511e63f2f870e84b6fb2d7ac /drivers | |
parent | f72de6638b8e55283739de174b57c0ae4203c446 (diff) |
[ARM] corgi_lcd: use GPIO API for BACKLIGHT_ON and BACKLIGHT_CONT
Signed-off-by: Eric Miao <eric.miao@marvell.com>
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/video/backlight/corgi_lcd.c | 83 |
1 files changed, 78 insertions, 5 deletions
diff --git a/drivers/video/backlight/corgi_lcd.c b/drivers/video/backlight/corgi_lcd.c index 068f14864099..2afd47eefe74 100644 --- a/drivers/video/backlight/corgi_lcd.c +++ b/drivers/video/backlight/corgi_lcd.c | |||
@@ -19,6 +19,7 @@ | |||
19 | #include <linux/kernel.h> | 19 | #include <linux/kernel.h> |
20 | #include <linux/init.h> | 20 | #include <linux/init.h> |
21 | #include <linux/delay.h> | 21 | #include <linux/delay.h> |
22 | #include <linux/gpio.h> | ||
22 | #include <linux/fb.h> | 23 | #include <linux/fb.h> |
23 | #include <linux/lcd.h> | 24 | #include <linux/lcd.h> |
24 | #include <linux/spi/spi.h> | 25 | #include <linux/spi/spi.h> |
@@ -92,7 +93,10 @@ struct corgi_lcd { | |||
92 | int mode; | 93 | int mode; |
93 | char buf[2]; | 94 | char buf[2]; |
94 | 95 | ||
95 | void (*notify)(int intensity); | 96 | int gpio_backlight_on; |
97 | int gpio_backlight_cont; | ||
98 | int gpio_backlight_cont_inverted; | ||
99 | |||
96 | void (*kick_battery)(void); | 100 | void (*kick_battery)(void); |
97 | }; | 101 | }; |
98 | 102 | ||
@@ -393,18 +397,26 @@ static int corgi_bl_get_intensity(struct backlight_device *bd) | |||
393 | 397 | ||
394 | static int corgi_bl_set_intensity(struct corgi_lcd *lcd, int intensity) | 398 | static int corgi_bl_set_intensity(struct corgi_lcd *lcd, int intensity) |
395 | { | 399 | { |
400 | int cont; | ||
401 | |||
396 | if (intensity > 0x10) | 402 | if (intensity > 0x10) |
397 | intensity += 0x10; | 403 | intensity += 0x10; |
398 | 404 | ||
399 | corgi_ssp_lcdtg_send(lcd, DUTYCTRL_ADRS, intensity); | 405 | corgi_ssp_lcdtg_send(lcd, DUTYCTRL_ADRS, intensity); |
400 | lcd->intensity = intensity; | ||
401 | 406 | ||
402 | if (lcd->notify) | 407 | /* Bit 5 via GPIO_BACKLIGHT_CONT */ |
403 | lcd->notify(intensity); | 408 | cont = !!(intensity & 0x20) ^ lcd->gpio_backlight_cont_inverted; |
409 | |||
410 | if (gpio_is_valid(lcd->gpio_backlight_cont)) | ||
411 | gpio_set_value(lcd->gpio_backlight_cont, cont); | ||
412 | |||
413 | if (gpio_is_valid(lcd->gpio_backlight_on)) | ||
414 | gpio_set_value(lcd->gpio_backlight_on, intensity); | ||
404 | 415 | ||
405 | if (lcd->kick_battery) | 416 | if (lcd->kick_battery) |
406 | lcd->kick_battery(); | 417 | lcd->kick_battery(); |
407 | 418 | ||
419 | lcd->intensity = intensity; | ||
408 | return 0; | 420 | return 0; |
409 | } | 421 | } |
410 | 422 | ||
@@ -468,6 +480,56 @@ static int corgi_lcd_resume(struct spi_device *spi) | |||
468 | #define corgi_lcd_resume NULL | 480 | #define corgi_lcd_resume NULL |
469 | #endif | 481 | #endif |
470 | 482 | ||
483 | static int setup_gpio_backlight(struct corgi_lcd *lcd, | ||
484 | struct corgi_lcd_platform_data *pdata) | ||
485 | { | ||
486 | struct spi_device *spi = lcd->spi_dev; | ||
487 | int err; | ||
488 | |||
489 | lcd->gpio_backlight_on = -1; | ||
490 | lcd->gpio_backlight_cont = -1; | ||
491 | |||
492 | if (gpio_is_valid(pdata->gpio_backlight_on)) { | ||
493 | err = gpio_request(pdata->gpio_backlight_on, "BL_ON"); | ||
494 | if (err) { | ||
495 | dev_err(&spi->dev, "failed to request GPIO%d for " | ||
496 | "backlight_on\n", pdata->gpio_backlight_on); | ||
497 | return err; | ||
498 | } | ||
499 | |||
500 | lcd->gpio_backlight_on = pdata->gpio_backlight_on; | ||
501 | gpio_direction_output(lcd->gpio_backlight_on, 0); | ||
502 | } | ||
503 | |||
504 | if (gpio_is_valid(pdata->gpio_backlight_cont)) { | ||
505 | err = gpio_request(pdata->gpio_backlight_cont, "BL_CONT"); | ||
506 | if (err) { | ||
507 | dev_err(&spi->dev, "failed to request GPIO%d for " | ||
508 | "backlight_cont\n", pdata->gpio_backlight_cont); | ||
509 | goto err_free_backlight_on; | ||
510 | } | ||
511 | |||
512 | lcd->gpio_backlight_cont = pdata->gpio_backlight_cont; | ||
513 | |||
514 | /* spitz and akita use both GPIOs for backlight, and | ||
515 | * have inverted polarity of GPIO_BACKLIGHT_CONT | ||
516 | */ | ||
517 | if (gpio_is_valid(lcd->gpio_backlight_on)) { | ||
518 | lcd->gpio_backlight_cont_inverted = 1; | ||
519 | gpio_direction_output(lcd->gpio_backlight_cont, 1); | ||
520 | } else { | ||
521 | lcd->gpio_backlight_cont_inverted = 0; | ||
522 | gpio_direction_output(lcd->gpio_backlight_cont, 0); | ||
523 | } | ||
524 | } | ||
525 | return 0; | ||
526 | |||
527 | err_free_backlight_on: | ||
528 | if (gpio_is_valid(lcd->gpio_backlight_on)) | ||
529 | gpio_free(lcd->gpio_backlight_on); | ||
530 | return err; | ||
531 | } | ||
532 | |||
471 | static int __devinit corgi_lcd_probe(struct spi_device *spi) | 533 | static int __devinit corgi_lcd_probe(struct spi_device *spi) |
472 | { | 534 | { |
473 | struct corgi_lcd_platform_data *pdata = spi->dev.platform_data; | 535 | struct corgi_lcd_platform_data *pdata = spi->dev.platform_data; |
@@ -506,7 +568,10 @@ static int __devinit corgi_lcd_probe(struct spi_device *spi) | |||
506 | lcd->bl_dev->props.brightness = pdata->default_intensity; | 568 | lcd->bl_dev->props.brightness = pdata->default_intensity; |
507 | lcd->bl_dev->props.power = FB_BLANK_UNBLANK; | 569 | lcd->bl_dev->props.power = FB_BLANK_UNBLANK; |
508 | 570 | ||
509 | lcd->notify = pdata->notify; | 571 | ret = setup_gpio_backlight(lcd, pdata); |
572 | if (ret) | ||
573 | goto err_unregister_bl; | ||
574 | |||
510 | lcd->kick_battery = pdata->kick_battery; | 575 | lcd->kick_battery = pdata->kick_battery; |
511 | 576 | ||
512 | dev_set_drvdata(&spi->dev, lcd); | 577 | dev_set_drvdata(&spi->dev, lcd); |
@@ -517,6 +582,8 @@ static int __devinit corgi_lcd_probe(struct spi_device *spi) | |||
517 | the_corgi_lcd = lcd; | 582 | the_corgi_lcd = lcd; |
518 | return 0; | 583 | return 0; |
519 | 584 | ||
585 | err_unregister_bl: | ||
586 | backlight_device_unregister(lcd->bl_dev); | ||
520 | err_unregister_lcd: | 587 | err_unregister_lcd: |
521 | lcd_device_unregister(lcd->lcd_dev); | 588 | lcd_device_unregister(lcd->lcd_dev); |
522 | err_free_lcd: | 589 | err_free_lcd: |
@@ -533,6 +600,12 @@ static int __devexit corgi_lcd_remove(struct spi_device *spi) | |||
533 | backlight_update_status(lcd->bl_dev); | 600 | backlight_update_status(lcd->bl_dev); |
534 | backlight_device_unregister(lcd->bl_dev); | 601 | backlight_device_unregister(lcd->bl_dev); |
535 | 602 | ||
603 | if (gpio_is_valid(lcd->gpio_backlight_on)) | ||
604 | gpio_free(lcd->gpio_backlight_on); | ||
605 | |||
606 | if (gpio_is_valid(lcd->gpio_backlight_cont)) | ||
607 | gpio_free(lcd->gpio_backlight_cont); | ||
608 | |||
536 | corgi_lcd_set_power(lcd->lcd_dev, FB_BLANK_POWERDOWN); | 609 | corgi_lcd_set_power(lcd->lcd_dev, FB_BLANK_POWERDOWN); |
537 | lcd_device_unregister(lcd->lcd_dev); | 610 | lcd_device_unregister(lcd->lcd_dev); |
538 | kfree(lcd); | 611 | kfree(lcd); |