Google
  Web www.spinics.net

[PATCH 7/7] corgi_lcd: use GPIO API for BACKLIGHT_ON and BACKLIGHT_CONT

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]


Signed-off-by: Eric Miao <eric.miao@xxxxxxxxxxx>
---
 arch/arm/mach-pxa/corgi.c           |    9 +---
 arch/arm/mach-pxa/spitz.c           |   21 ++-------
 drivers/video/backlight/corgi_lcd.c |   83 ++++++++++++++++++++++++++++++++--
 include/linux/spi/corgi_lcd.h       |    3 +
 4 files changed, 88 insertions(+), 28 deletions(-)

diff --git a/arch/arm/mach-pxa/corgi.c b/arch/arm/mach-pxa/corgi.c
index 47b6f9d..201b49a 100644
--- a/arch/arm/mach-pxa/corgi.c
+++ b/arch/arm/mach-pxa/corgi.c
@@ -439,12 +439,6 @@ static struct pxa2xx_spi_chip corgi_ads7846_chip = {
 	.gpio_cs	= CORGI_GPIO_ADS7846_CS,
 };

-static void corgi_notify_intensity(int intensity)
-{
-	/* Bit 5 is via SCOOP */
-	gpio_set_value(CORGI_GPIO_BACKLIGHT_CONT, !!(intensity & 0x0020));
-}
-
 static void corgi_bl_kick_battery(void)
 {
 	void (*kick_batt)(void);
@@ -461,7 +455,8 @@ static struct corgi_lcd_platform_data corgi_lcdcon_info = {
 	.max_intensity		= 0x2f,
 	.default_intensity	= 0x1f,
 	.limit_mask		= 0x0b,
-	.notify			= corgi_notify_intensity,
+	.gpio_backlight_cont	= CORGI_GPIO_BACKLIGHT_CONT,
+	.gpio_backlight_on	= -1,
 	.kick_battery		= corgi_bl_kick_battery,
 };

diff --git a/arch/arm/mach-pxa/spitz.c b/arch/arm/mach-pxa/spitz.c
index 26a4184..08efb44 100644
--- a/arch/arm/mach-pxa/spitz.c
+++ b/arch/arm/mach-pxa/spitz.c
@@ -300,21 +300,6 @@ static struct pxa2xx_spi_chip spitz_ads7846_chip = {
 	.gpio_cs		= SPITZ_GPIO_ADS7846_CS,
 };

-static void spitz_notify_intensity(int intensity)
-{
-	if (machine_is_spitz() || machine_is_borzoi()) {
-		gpio_set_value(SPITZ_GPIO_BACKLIGHT_CONT, !(intensity & 0x20));
-		gpio_set_value(SPITZ_GPIO_BACKLIGHT_ON, intensity);
-		return;
-	}
-
-	if (machine_is_akita()) {
-		gpio_set_value(AKITA_GPIO_BACKLIGHT_CONT, !(intensity & 0x20));
-		gpio_set_value(AKITA_GPIO_BACKLIGHT_ON, intensity);
-		return;
-	}
-}
-
 static void spitz_bl_kick_battery(void)
 {
 	void (*kick_batt)(void);
@@ -331,7 +316,8 @@ static struct corgi_lcd_platform_data spitz_lcdcon_info = {
 	.max_intensity		= 0x2f,
 	.default_intensity	= 0x1f,
 	.limit_mask		= 0x0b,
-	.notify			= spitz_notify_intensity,
+	.gpio_backlight_cont	= SPITZ_GPIO_BACKLIGHT_CONT,
+	.gpio_backlight_on	= SPITZ_GPIO_BACKLIGHT_ON,
 	.kick_battery		= spitz_bl_kick_battery,
 };

@@ -658,6 +644,9 @@ static void __init akita_init(void)
 	i2c_register_board_info(0, ARRAY_AND_SIZE(akita_i2c_board_info));

 	common_init();
+
+	spitz_lcdcon_info.gpio_backlight_cont = AKITA_GPIO_BACKLIGHT_CONT;
+	spitz_lcdcon_info.gpio_backlight_on = AKITA_GPIO_BACKLIGHT_ON;
 }
 #endif

diff --git a/drivers/video/backlight/corgi_lcd.c
b/drivers/video/backlight/corgi_lcd.c
index 068f148..2afd47e 100644
--- a/drivers/video/backlight/corgi_lcd.c
+++ b/drivers/video/backlight/corgi_lcd.c
@@ -19,6 +19,7 @@
 #include <linux/kernel.h>
 #include <linux/init.h>
 #include <linux/delay.h>
+#include <linux/gpio.h>
 #include <linux/fb.h>
 #include <linux/lcd.h>
 #include <linux/spi/spi.h>
@@ -92,7 +93,10 @@ struct corgi_lcd {
 	int	mode;
 	char	buf[2];

-	void (*notify)(int intensity);
+	int	gpio_backlight_on;
+	int	gpio_backlight_cont;
+	int	gpio_backlight_cont_inverted;
+
 	void (*kick_battery)(void);
 };

@@ -393,18 +397,26 @@ static int corgi_bl_get_intensity(struct
backlight_device *bd)

 static int corgi_bl_set_intensity(struct corgi_lcd *lcd, int intensity)
 {
+	int cont;
+
 	if (intensity > 0x10)
 		intensity += 0x10;

 	corgi_ssp_lcdtg_send(lcd, DUTYCTRL_ADRS, intensity);
-	lcd->intensity = intensity;

-	if (lcd->notify)
-		lcd->notify(intensity);
+	/* Bit 5 via GPIO_BACKLIGHT_CONT */
+	cont = !!(intensity & 0x20) ^ lcd->gpio_backlight_cont_inverted;
+
+	if (gpio_is_valid(lcd->gpio_backlight_cont))
+		gpio_set_value(lcd->gpio_backlight_cont, cont);
+
+	if (gpio_is_valid(lcd->gpio_backlight_on))
+		gpio_set_value(lcd->gpio_backlight_on, intensity);

 	if (lcd->kick_battery)
 		lcd->kick_battery();

+	lcd->intensity = intensity;
 	return 0;
 }

@@ -468,6 +480,56 @@ static int corgi_lcd_resume(struct spi_device *spi)
 #define corgi_lcd_resume	NULL
 #endif

+static int setup_gpio_backlight(struct corgi_lcd *lcd,
+				struct corgi_lcd_platform_data *pdata)
+{
+	struct spi_device *spi = lcd->spi_dev;
+	int err;
+
+	lcd->gpio_backlight_on = -1;
+	lcd->gpio_backlight_cont = -1;
+
+	if (gpio_is_valid(pdata->gpio_backlight_on)) {
+		err = gpio_request(pdata->gpio_backlight_on, "BL_ON");
+		if (err) {
+			dev_err(&spi->dev, "failed to request GPIO%d for "
+				"backlight_on\n", pdata->gpio_backlight_on);
+			return err;
+		}
+
+		lcd->gpio_backlight_on = pdata->gpio_backlight_on;
+		gpio_direction_output(lcd->gpio_backlight_on, 0);
+	}
+
+	if (gpio_is_valid(pdata->gpio_backlight_cont)) {
+		err = gpio_request(pdata->gpio_backlight_cont, "BL_CONT");
+		if (err) {
+			dev_err(&spi->dev, "failed to request GPIO%d for "
+				"backlight_cont\n", pdata->gpio_backlight_cont);
+			goto err_free_backlight_on;
+		}
+
+		lcd->gpio_backlight_cont = pdata->gpio_backlight_cont;
+
+		/* spitz and akita use both GPIOs for backlight, and
+		 * have inverted polarity of GPIO_BACKLIGHT_CONT
+		 */
+		if (gpio_is_valid(lcd->gpio_backlight_on)) {
+			lcd->gpio_backlight_cont_inverted = 1;
+			gpio_direction_output(lcd->gpio_backlight_cont, 1);
+		} else {
+			lcd->gpio_backlight_cont_inverted = 0;
+			gpio_direction_output(lcd->gpio_backlight_cont, 0);
+		}
+	}
+	return 0;
+
+err_free_backlight_on:
+	if (gpio_is_valid(lcd->gpio_backlight_on))
+		gpio_free(lcd->gpio_backlight_on);
+	return err;
+}
+
 static int __devinit corgi_lcd_probe(struct spi_device *spi)
 {
 	struct corgi_lcd_platform_data *pdata = spi->dev.platform_data;
@@ -506,7 +568,10 @@ static int __devinit corgi_lcd_probe(struct
spi_device *spi)
 	lcd->bl_dev->props.brightness = pdata->default_intensity;
 	lcd->bl_dev->props.power = FB_BLANK_UNBLANK;

-	lcd->notify = pdata->notify;
+	ret = setup_gpio_backlight(lcd, pdata);
+	if (ret)
+		goto err_unregister_bl;
+
 	lcd->kick_battery = pdata->kick_battery;

 	dev_set_drvdata(&spi->dev, lcd);
@@ -517,6 +582,8 @@ static int __devinit corgi_lcd_probe(struct spi_device *spi)
 	the_corgi_lcd = lcd;
 	return 0;

+err_unregister_bl:
+	backlight_device_unregister(lcd->bl_dev);
 err_unregister_lcd:
 	lcd_device_unregister(lcd->lcd_dev);
 err_free_lcd:
@@ -533,6 +600,12 @@ static int __devexit corgi_lcd_remove(struct
spi_device *spi)
 	backlight_update_status(lcd->bl_dev);
 	backlight_device_unregister(lcd->bl_dev);

+	if (gpio_is_valid(lcd->gpio_backlight_on))
+		gpio_free(lcd->gpio_backlight_on);
+
+	if (gpio_is_valid(lcd->gpio_backlight_cont))
+		gpio_free(lcd->gpio_backlight_cont);
+
 	corgi_lcd_set_power(lcd->lcd_dev, FB_BLANK_POWERDOWN);
 	lcd_device_unregister(lcd->lcd_dev);
 	kfree(lcd);
diff --git a/include/linux/spi/corgi_lcd.h b/include/linux/spi/corgi_lcd.h
index b6161aa..6692b34 100644
--- a/include/linux/spi/corgi_lcd.h
+++ b/include/linux/spi/corgi_lcd.h
@@ -10,6 +10,9 @@ struct corgi_lcd_platform_data {
 	int	default_intensity;
 	int	limit_mask;

+	int	gpio_backlight_on;	/* -1 if n/a */
+	int	gpio_backlight_cont;	/* -1 if n/a */
+
 	void (*notify)(int intensity);
 	void (*kick_battery)(void);
 };
-- 
1.5.4.3

-------------------------------------------------------------------
List admin: http://lists.arm.linux.org.uk/mailman/listinfo/linux-arm-kernel
FAQ:        http://www.arm.linux.org.uk/mailinglists/faq.php
Etiquette:  http://www.arm.linux.org.uk/mailinglists/etiquette.php

[Site Home]     [Linux Arm]     [Fedora ARM]     [Gcc Help]     [Git]     [DCCP]     [IETF Announce]     [Security]     [PDAs]     [Linux]     [Linux Book List]     [Linux MIPS]     [Yosemite Campsites]     [Photos]

Add to Google Google PageRank Checking tool