[ARM] 3594/1: Poodle: Add touchscreen support + other updates

Patch from Richard Purdie

Poodle Updates:
* Update corgi_ssp to make the GPIO chip selects optional
* Enable corgi_ssp for use by poodle
* Add corgi touchscreen platform device for poodle
* Export locomo platform device.
* Set framebuffer device parent correctly

Signed-off-by: Richard Purdie <rpurdie@rpsys.net>
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
diff --git a/arch/arm/mach-pxa/Kconfig b/arch/arm/mach-pxa/Kconfig
index 0104fd1..ea5137f 100644
--- a/arch/arm/mach-pxa/Kconfig
+++ b/arch/arm/mach-pxa/Kconfig
@@ -61,6 +61,7 @@
 	bool "Enable Sharp SL-5600 (Poodle) Support"
 	depends PXA_SHARPSL_25x
 	select SHARP_LOCOMO
+	select PXA_SSP
 
 config MACH_CORGI
 	bool "Enable Sharp SL-C700 (Corgi) Support"
diff --git a/arch/arm/mach-pxa/Makefile b/arch/arm/mach-pxa/Makefile
index 4e8a983..1610690 100644
--- a/arch/arm/mach-pxa/Makefile
+++ b/arch/arm/mach-pxa/Makefile
@@ -15,7 +15,7 @@
 obj-$(CONFIG_PXA_SHARP_C7xx)	+= corgi.o corgi_ssp.o corgi_lcd.o sharpsl_pm.o corgi_pm.o
 obj-$(CONFIG_PXA_SHARP_Cxx00)	+= spitz.o corgi_ssp.o corgi_lcd.o sharpsl_pm.o spitz_pm.o
 obj-$(CONFIG_MACH_AKITA)	+= akita-ioexp.o
-obj-$(CONFIG_MACH_POODLE)	+= poodle.o
+obj-$(CONFIG_MACH_POODLE)	+= poodle.o corgi_ssp.o
 obj-$(CONFIG_MACH_TOSA)         += tosa.o
 
 # Support for blinky lights
diff --git a/arch/arm/mach-pxa/corgi_ssp.c b/arch/arm/mach-pxa/corgi_ssp.c
index 8a25a1c..f942131 100644
--- a/arch/arm/mach-pxa/corgi_ssp.c
+++ b/arch/arm/mach-pxa/corgi_ssp.c
@@ -50,12 +50,14 @@
 	unsigned long ret,flag;
 
 	spin_lock_irqsave(&corgi_ssp_lock, flag);
-	GPCR(ssp_machinfo->cs_ads7846) = GPIO_bit(ssp_machinfo->cs_ads7846);
+	if (ssp_machinfo->cs_ads7846 >= 0)
+		GPCR(ssp_machinfo->cs_ads7846) = GPIO_bit(ssp_machinfo->cs_ads7846);
 
 	ssp_write_word(&corgi_ssp_dev,data);
 	ret = ssp_read_word(&corgi_ssp_dev);
 
-	GPSR(ssp_machinfo->cs_ads7846) = GPIO_bit(ssp_machinfo->cs_ads7846);
+	if (ssp_machinfo->cs_ads7846 >= 0)
+		GPSR(ssp_machinfo->cs_ads7846) = GPIO_bit(ssp_machinfo->cs_ads7846);
 	spin_unlock_irqrestore(&corgi_ssp_lock, flag);
 
 	return ret;
@@ -68,12 +70,14 @@
 void corgi_ssp_ads7846_lock(void)
 {
 	spin_lock(&corgi_ssp_lock);
-	GPCR(ssp_machinfo->cs_ads7846) = GPIO_bit(ssp_machinfo->cs_ads7846);
+	if (ssp_machinfo->cs_ads7846 >= 0)
+		GPCR(ssp_machinfo->cs_ads7846) = GPIO_bit(ssp_machinfo->cs_ads7846);
 }
 
 void corgi_ssp_ads7846_unlock(void)
 {
-	GPSR(ssp_machinfo->cs_ads7846) = GPIO_bit(ssp_machinfo->cs_ads7846);
+	if (ssp_machinfo->cs_ads7846 >= 0)
+		GPSR(ssp_machinfo->cs_ads7846) = GPIO_bit(ssp_machinfo->cs_ads7846);
 	spin_unlock(&corgi_ssp_lock);
 }
 
@@ -110,11 +114,13 @@
 	ssp_config(&corgi_ssp_dev, (SSCR0_Motorola | (SSCR0_DSS & 0x07 )), sscr1, 0, SSCR0_SerClkDiv(ssp_machinfo->clk_lcdcon));
 	ssp_enable(&corgi_ssp_dev);
 
-	GPCR(ssp_machinfo->cs_lcdcon) = GPIO_bit(ssp_machinfo->cs_lcdcon);
+	if (ssp_machinfo->cs_lcdcon >= 0)
+		GPCR(ssp_machinfo->cs_lcdcon) = GPIO_bit(ssp_machinfo->cs_lcdcon);
 	ssp_write_word(&corgi_ssp_dev,data);
 	/* Read null data back from device to prevent SSP overflow */
 	ssp_read_word(&corgi_ssp_dev);
-	GPSR(ssp_machinfo->cs_lcdcon) = GPIO_bit(ssp_machinfo->cs_lcdcon);
+	if (ssp_machinfo->cs_lcdcon >= 0)
+		GPSR(ssp_machinfo->cs_lcdcon) = GPIO_bit(ssp_machinfo->cs_lcdcon);
 
 	ssp_disable(&corgi_ssp_dev);
 	ssp_config(&corgi_ssp_dev, (SSCR0_National | (SSCR0_DSS & 0x0b )), 0, 0, SSCR0_SerClkDiv(ssp_machinfo->clk_ads7846));
@@ -147,7 +153,8 @@
 	int voltage,voltage1,voltage2;
 
 	spin_lock_irqsave(&corgi_ssp_lock, flag);
-	GPCR(ssp_machinfo->cs_max1111) = GPIO_bit(ssp_machinfo->cs_max1111);
+	if (ssp_machinfo->cs_max1111 >= 0)
+		GPCR(ssp_machinfo->cs_max1111) = GPIO_bit(ssp_machinfo->cs_max1111);
 	ssp_disable(&corgi_ssp_dev);
 	ssp_config(&corgi_ssp_dev, (SSCR0_Motorola | (SSCR0_DSS & 0x07 )), 0, 0, SSCR0_SerClkDiv(ssp_machinfo->clk_max1111));
 	ssp_enable(&corgi_ssp_dev);
@@ -169,7 +176,8 @@
 	ssp_disable(&corgi_ssp_dev);
 	ssp_config(&corgi_ssp_dev, (SSCR0_National | (SSCR0_DSS & 0x0b )), 0, 0, SSCR0_SerClkDiv(ssp_machinfo->clk_ads7846));
 	ssp_enable(&corgi_ssp_dev);
-	GPSR(ssp_machinfo->cs_max1111) = GPIO_bit(ssp_machinfo->cs_max1111);
+	if (ssp_machinfo->cs_max1111 >= 0)
+		GPSR(ssp_machinfo->cs_max1111) = GPIO_bit(ssp_machinfo->cs_max1111);
 	spin_unlock_irqrestore(&corgi_ssp_lock, flag);
 
 	if (voltage1 & 0xc0 || voltage2 & 0x3f)
@@ -196,9 +204,12 @@
 	int ret;
 
 	/* Chip Select - Disable All */
-	pxa_gpio_mode(ssp_machinfo->cs_lcdcon  | GPIO_OUT | GPIO_DFLT_HIGH);
-        pxa_gpio_mode(ssp_machinfo->cs_max1111 | GPIO_OUT | GPIO_DFLT_HIGH);
-        pxa_gpio_mode(ssp_machinfo->cs_ads7846 | GPIO_OUT | GPIO_DFLT_HIGH);
+	if (ssp_machinfo->cs_lcdcon >= 0)
+		pxa_gpio_mode(ssp_machinfo->cs_lcdcon  | GPIO_OUT | GPIO_DFLT_HIGH);
+	if (ssp_machinfo->cs_max1111 >= 0)
+	        pxa_gpio_mode(ssp_machinfo->cs_max1111 | GPIO_OUT | GPIO_DFLT_HIGH);
+	if (ssp_machinfo->cs_ads7846 >= 0)
+        	pxa_gpio_mode(ssp_machinfo->cs_ads7846 | GPIO_OUT | GPIO_DFLT_HIGH);
 
 	ret = ssp_init(&corgi_ssp_dev, ssp_machinfo->port, 0);
 
@@ -229,9 +240,12 @@
 
 static int corgi_ssp_resume(struct platform_device *dev)
 {
-	GPSR(ssp_machinfo->cs_lcdcon) = GPIO_bit(ssp_machinfo->cs_lcdcon);  /* High - Disable LCD Control/Timing Gen */
-	GPSR(ssp_machinfo->cs_max1111) = GPIO_bit(ssp_machinfo->cs_max1111); /* High - Disable MAX1111*/
-	GPSR(ssp_machinfo->cs_ads7846) = GPIO_bit(ssp_machinfo->cs_ads7846); /* High - Disable ADS7846*/
+	if (ssp_machinfo->cs_lcdcon >= 0)
+		GPSR(ssp_machinfo->cs_lcdcon) = GPIO_bit(ssp_machinfo->cs_lcdcon);  /* High - Disable LCD Control/Timing Gen */
+	if (ssp_machinfo->cs_max1111 >= 0)
+		GPSR(ssp_machinfo->cs_max1111) = GPIO_bit(ssp_machinfo->cs_max1111); /* High - Disable MAX1111*/
+	if (ssp_machinfo->cs_ads7846 >= 0)
+		GPSR(ssp_machinfo->cs_ads7846) = GPIO_bit(ssp_machinfo->cs_ads7846); /* High - Disable ADS7846*/
 	ssp_restore_state(&corgi_ssp_dev,&corgi_ssp_state);
 	ssp_enable(&corgi_ssp_dev);
 
diff --git a/arch/arm/mach-pxa/poodle.c b/arch/arm/mach-pxa/poodle.c
index 234877a..9a9fa87 100644
--- a/arch/arm/mach-pxa/poodle.c
+++ b/arch/arm/mach-pxa/poodle.c
@@ -37,12 +37,15 @@
 #include <asm/arch/irda.h>
 #include <asm/arch/poodle.h>
 #include <asm/arch/pxafb.h>
+#include <asm/arch/sharpsl.h>
+#include <asm/arch/ssp.h>
 
 #include <asm/hardware/scoop.h>
 #include <asm/hardware/locomo.h>
 #include <asm/mach/sharpsl_param.h>
 
 #include "generic.h"
+#include "sharpsl.h"
 
 static struct resource poodle_scoop_resources[] = {
 	[0] = {
@@ -120,13 +123,71 @@
 	},
 };
 
-static struct platform_device locomo_device = {
+struct platform_device poodle_locomo_device = {
 	.name		= "locomo",
 	.id		= 0,
 	.num_resources	= ARRAY_SIZE(locomo_resources),
 	.resource	= locomo_resources,
 };
 
+EXPORT_SYMBOL(poodle_locomo_device);
+
+/*
+ * Poodle SSP Device
+ */
+
+struct platform_device poodle_ssp_device = {
+	.name		= "corgi-ssp",
+	.id		= -1,
+};
+
+struct corgissp_machinfo poodle_ssp_machinfo = {
+	.port		= 1,
+	.cs_lcdcon	= -1,
+	.cs_ads7846	= -1,
+	.cs_max1111	= -1,
+	.clk_lcdcon	= 2,
+	.clk_ads7846	= 36,
+	.clk_max1111	= 2,
+};
+
+
+/*
+ * Poodle Touch Screen Device
+ */
+static struct resource poodlets_resources[] = {
+	[0] = {
+		.start		= POODLE_IRQ_GPIO_TP_INT,
+		.end		= POODLE_IRQ_GPIO_TP_INT,
+		.flags		= IORESOURCE_IRQ,
+	},
+};
+
+static unsigned long poodle_get_hsync_len(void)
+{
+	return 0;
+}
+
+static void poodle_null_hsync(void)
+{
+}
+
+static struct corgits_machinfo  poodle_ts_machinfo = {
+	.get_hsync_len   = poodle_get_hsync_len,
+	.put_hsync       = poodle_null_hsync,
+	.wait_hsync      = poodle_null_hsync,
+};
+
+static struct platform_device poodle_ts_device = {
+	.name		= "corgi-ts",
+	.dev		= {
+		.platform_data	= &poodle_ts_machinfo,
+	},
+	.id		= -1,
+	.num_resources	= ARRAY_SIZE(poodlets_resources),
+	.resource	= poodlets_resources,
+};
+
 
 /*
  * MMC/SD Device
@@ -259,8 +320,10 @@
 };
 
 static struct platform_device *devices[] __initdata = {
-	&locomo_device,
+	&poodle_locomo_device,
 	&poodle_scoop_device,
+	&poodle_ssp_device,
+	&poodle_ts_device,
 };
 
 static void poodle_poweroff(void)
@@ -319,6 +382,7 @@
   	GPSR1 = 0x00000000;
         GPSR2 = 0x00000000;
 
+	set_pxa_fb_parent(&poodle_locomo_device.dev);
 	set_pxa_fb_info(&poodle_fb_info);
 	pxa_gpio_mode(POODLE_GPIO_USB_PULLUP | GPIO_OUT);
 	pxa_gpio_mode(POODLE_GPIO_IR_ON | GPIO_OUT);
@@ -332,6 +396,7 @@
 	if (ret) {
 		printk(KERN_WARNING "poodle: Unable to register LoCoMo device\n");
 	}
+	corgi_ssp_set_machinfo(&poodle_ssp_machinfo);
 }
 
 static void __init fixup_poodle(struct machine_desc *desc,
diff --git a/include/asm-arm/arch-pxa/poodle.h b/include/asm-arm/arch-pxa/poodle.h
index 6079e0a..4d6a403 100644
--- a/include/asm-arm/arch-pxa/poodle.h
+++ b/include/asm-arm/arch-pxa/poodle.h
@@ -70,4 +70,6 @@
 #define POODLE_SCOOP_IO_DIR	( POODLE_SCOOP_VPEN | POODLE_SCOOP_HS_OUT )
 #define POODLE_SCOOP_IO_OUT	( 0 )
 
+extern struct platform_device poodle_locomo_device;
+
 #endif /* __ASM_ARCH_POODLE_H  */