aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorEric Miao <eric.miao@marvell.com>2008-09-06 23:30:06 -0400
committerRussell King <rmk+kernel@arm.linux.org.uk>2008-09-25 04:38:14 -0400
commitff7a4c7130c0ad97d55f7ab3f0a35fbc1f41b376 (patch)
treee24ccea4bdb38720511e63f2f870e84b6fb2d7ac /drivers
parentf72de6638b8e55283739de174b57c0ae4203c446 (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.c83
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
394static int corgi_bl_set_intensity(struct corgi_lcd *lcd, int intensity) 398static 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
483static 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
527err_free_backlight_on:
528 if (gpio_is_valid(lcd->gpio_backlight_on))
529 gpio_free(lcd->gpio_backlight_on);
530 return err;
531}
532
471static int __devinit corgi_lcd_probe(struct spi_device *spi) 533static 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
585err_unregister_bl:
586 backlight_device_unregister(lcd->bl_dev);
520err_unregister_lcd: 587err_unregister_lcd:
521 lcd_device_unregister(lcd->lcd_dev); 588 lcd_device_unregister(lcd->lcd_dev);
522err_free_lcd: 589err_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);