From b032fccca80cbbedaa80e5a72a202a43f08aa97e Mon Sep 17 00:00:00 2001
From: Dmitry Baryshkov <dbaryshkov@gmail.com>
Date: Thu, 12 Jun 2008 11:42:07 +0100
Subject: [PATCH] [ARM] 5083/2: Tosa: fix IrDA transciver powerup.

On tosa the tranciver LED isn't powered down if
the GPIO47 (STUART_TX) isn't configured as low-level.
Power it down if IrDA is off to save a bit of power.

Signed-off-by: Dmitry Baryshkov <dbaryshkov@gmail.com>
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
---
 arch/arm/mach-pxa/tosa.c        | 58 ++++++++++++++++++++++++++-------
 include/asm-arm/arch-pxa/tosa.h |  1 +
 2 files changed, 47 insertions(+), 12 deletions(-)

diff --git a/arch/arm/mach-pxa/tosa.c b/arch/arm/mach-pxa/tosa.c
index 9892464d7abc0..7a89f764acf31 100644
--- a/arch/arm/mach-pxa/tosa.c
+++ b/arch/arm/mach-pxa/tosa.c
@@ -117,10 +117,6 @@ static unsigned long tosa_pin_config[] = {
 	GPIO44_BTUART_CTS,
 	GPIO45_BTUART_RTS,
 
-	/* IrDA */
-	GPIO46_STUART_RXD,
-	GPIO47_STUART_TXD,
-
 	/* Keybd */
 	GPIO58_GPIO | MFP_LPM_DRIVE_LOW,
 	GPIO59_GPIO | MFP_LPM_DRIVE_LOW,
@@ -147,6 +143,17 @@ static unsigned long tosa_pin_config[] = {
 	GPIO83_SSP2_TXD,
 };
 
+static unsigned long tosa_pin_irda_off[] = {
+	GPIO46_STUART_RXD,
+	GPIO47_GPIO | MFP_LPM_DRIVE_LOW,
+};
+
+static unsigned long tosa_pin_irda_on[] = {
+	GPIO46_STUART_RXD,
+	GPIO47_STUART_TXD,
+};
+
+
 /*
  * SCOOP Device
  */
@@ -341,29 +348,55 @@ static struct pxamci_platform_data tosa_mci_platform_data = {
 /*
  * Irda
  */
+static void tosa_irda_transceiver_mode(struct device *dev, int mode)
+{
+	if (mode & IR_OFF) {
+		gpio_set_value(TOSA_GPIO_IR_POWERDWN, 0);
+		pxa2xx_mfp_config(ARRAY_AND_SIZE(tosa_pin_irda_off));
+		gpio_direction_output(TOSA_GPIO_IRDA_TX, 0);
+	} else {
+		pxa2xx_mfp_config(ARRAY_AND_SIZE(tosa_pin_irda_on));
+		gpio_set_value(TOSA_GPIO_IR_POWERDWN, 1);
+	}
+}
+
 static int tosa_irda_startup(struct device *dev)
 {
 	int ret;
 
+	ret = gpio_request(TOSA_GPIO_IRDA_TX, "IrDA TX");
+	if (ret)
+		goto err_tx;
+	ret = gpio_direction_output(TOSA_GPIO_IRDA_TX, 0);
+	if (ret)
+		goto err_tx_dir;
+
 	ret = gpio_request(TOSA_GPIO_IR_POWERDWN, "IrDA powerdown");
 	if (ret)
-		return ret;
+		goto err_pwr;
 
 	ret = gpio_direction_output(TOSA_GPIO_IR_POWERDWN, 0);
 	if (ret)
-		gpio_free(TOSA_GPIO_IR_POWERDWN);
+		goto err_pwr_dir;
 
-	return ret;
-	}
+	tosa_irda_transceiver_mode(dev, IR_SIRMODE | IR_OFF);
 
-static void tosa_irda_shutdown(struct device *dev)
-{
+	return 0;
+
+err_pwr_dir:
 	gpio_free(TOSA_GPIO_IR_POWERDWN);
+err_pwr:
+err_tx_dir:
+	gpio_free(TOSA_GPIO_IRDA_TX);
+err_tx:
+	return ret;
 }
 
-static void tosa_irda_transceiver_mode(struct device *dev, int mode)
+static void tosa_irda_shutdown(struct device *dev)
 {
-	gpio_set_value(TOSA_GPIO_IR_POWERDWN, !(mode & IR_OFF));
+	tosa_irda_transceiver_mode(dev, IR_SIRMODE | IR_OFF);
+	gpio_free(TOSA_GPIO_IR_POWERDWN);
+	gpio_free(TOSA_GPIO_IRDA_TX);
 }
 
 static struct pxaficp_platform_data tosa_ficp_platform_data = {
@@ -501,6 +534,7 @@ static void tosa_restart(char mode)
 static void __init tosa_init(void)
 {
 	pxa2xx_mfp_config(ARRAY_AND_SIZE(tosa_pin_config));
+	pxa2xx_mfp_config(ARRAY_AND_SIZE(tosa_pin_irda_off));
 	gpio_set_wake(MFP_PIN_GPIO1, 1);
 	/* We can't pass to gpio-keys since it will drop the Reset altfunc */
 
diff --git a/include/asm-arm/arch-pxa/tosa.h b/include/asm-arm/arch-pxa/tosa.h
index c5b6fde6907c4..1882262161542 100644
--- a/include/asm-arm/arch-pxa/tosa.h
+++ b/include/asm-arm/arch-pxa/tosa.h
@@ -99,6 +99,7 @@
 #define TOSA_GPIO_TP_INT		(32)	/* Touch Panel pen down interrupt */
 #define TOSA_GPIO_JC_CF_IRQ		(36)	/* CF slot1 Ready */
 #define TOSA_GPIO_BAT_LOCKED		(38)	/* Battery locked */
+#define TOSA_GPIO_IRDA_TX		(47)
 #define TOSA_GPIO_TG_SPI_SCLK		(81)
 #define TOSA_GPIO_TG_SPI_CS		(82)
 #define TOSA_GPIO_TG_SPI_MOSI		(83)
-- 
GitLab