
#
# Patch managed by http://www.holgerschurig.de/patcher.html
#

--- /dev/null
+++ linux-2.6.10/arch/arm/mach-pxa/corgi_ssp.c
@@ -0,0 +1,242 @@
+/*
+ *  SSP glue logic for Sharp Corgi
+ *
+ *  Copyright (c) 2004 Richard Purdie
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License version 2 as
+ *  published by the Free Software Foundation.
+ *
+ */
+
+#include <linux/config.h>
+#include <linux/module.h>
+#include <linux/sched.h>
+#include <linux/slab.h>
+#include <linux/interrupt.h>
+#include <linux/random.h>
+#include <linux/delay.h>
+#include <linux/init.h>
+#include <linux/device.h>
+
+#include <asm/hardware.h>
+#include <asm/irq.h>
+#include <asm/arch/ssp.h>
+#include <asm/arch/corgi.h>
+#include <asm/arch/pxa-regs.h>
+
+static spinlock_t corgi_ssp_lock = SPIN_LOCK_UNLOCKED;
+
+static struct ssp_dev corgi_ssp_dev;
+static struct ssp_state corgi_ssp_state;
+
+/*
+ *  ADS7846 Routines
+ */
+
+unsigned long corgi_ssp_ads7846_putget(ulong data)
+{
+	unsigned long ret, flag;
+
+	spin_lock_irqsave(&corgi_ssp_lock, flag);
+	GPCR0 = GPIO_bit(GPIO24_SFRM); /* ADS7846 */
+
+	ssp_write_word(&corgi_ssp_dev,data);
+	ret = ssp_read_word(&corgi_ssp_dev);
+
+	GPSR0 = GPIO_bit(GPIO24_SFRM); /* ADS7846 */
+	spin_unlock_irqrestore(&corgi_ssp_lock, flag);
+
+	return ret;
+}
+
+/*
+ * Critical timing requirements when reading the touchscreen 
+ * result in the following functions. They are *always* called
+ * in interrupt context and hence lock things differently.
+ *
+ */
+
+void corgi_ssp_ads7846_lock(void)
+{
+	spin_lock(&corgi_ssp_lock);
+	GPCR0 = GPIO_bit(GPIO24_SFRM); /* ADS7846 */
+}
+
+void corgi_ssp_ads7846_unlock(void)
+{
+	GPSR0 = GPIO_bit(GPIO24_SFRM); /* ADS7846 */
+	spin_unlock(&corgi_ssp_lock);
+}
+
+void corgi_ssp_ads7846_put(ulong data)
+{
+	ssp_write_word(&corgi_ssp_dev,data);
+}
+
+unsigned long corgi_ssp_ads7846_get(void)
+{
+	return ssp_read_word(&corgi_ssp_dev);
+}
+
+EXPORT_SYMBOL(corgi_ssp_ads7846_putget);
+EXPORT_SYMBOL(corgi_ssp_ads7846_lock);
+EXPORT_SYMBOL(corgi_ssp_ads7846_unlock);
+EXPORT_SYMBOL(corgi_ssp_ads7846_put);
+EXPORT_SYMBOL(corgi_ssp_ads7846_get);
+
+
+/*
+ *  LCD/Backlight Routines
+ */
+
+unsigned long corgi_ssp_dac_put(ulong data)
+{
+	unsigned long flag;
+	
+	spin_lock_irqsave(&corgi_ssp_lock, flag);
+	GPCR0 = GPIO_bit(GPIO19_DREQ1); /* TG */
+
+	ssp_disable(&corgi_ssp_dev);
+    ssp_config(&corgi_ssp_dev,(SSCR0_Motorola | (SSCR0_DSS & 0x07 )),SSCR1_SPH,0,SSCR0_SerClkDiv(76));
+    ssp_enable(&corgi_ssp_dev);
+
+	ssp_write_word(&corgi_ssp_dev,data);
+	/* Read null data back from device to prevent SSP overflow */
+	ssp_read_word(&corgi_ssp_dev);
+
+    ssp_disable(&corgi_ssp_dev);
+	ssp_config(&corgi_ssp_dev,(SSCR0_National | (SSCR0_DSS & 0x0b )),0,0,SSCR0_SerClkDiv(2));
+	ssp_enable(&corgi_ssp_dev);
+    GPSR0 = GPIO_bit(GPIO19_DREQ1); /* TG */
+	spin_unlock_irqrestore(&corgi_ssp_lock, flag);
+
+	return 0;
+}
+
+void corgi_ssp_lcdtg_send(u8 adrs, u8 data)
+{
+	corgi_ssp_dac_put(((adrs & 0x07) << 5) | (data & 0x1f));
+}
+
+void corgi_ssp_blduty_set(int duty) 
+{
+	corgi_ssp_lcdtg_send(0x02,duty);
+}
+
+EXPORT_SYMBOL(corgi_ssp_lcdtg_send);
+EXPORT_SYMBOL(corgi_ssp_blduty_set);
+
+/*
+ *  Max1111 Routines
+ */
+
+int corgi_ssp_max1111_get(ulong data)
+{
+    int voltage,voltage1,voltage2;
+    unsigned long flag;
+
+    spin_lock_irqsave(&corgi_ssp_lock, flag);
+    GPCR0 = GPIO_bit(GPIO20_DREQ0); /* MAX1111 */
+    ssp_disable(&corgi_ssp_dev);
+    ssp_config(&corgi_ssp_dev,(SSCR0_Motorola | (SSCR0_DSS & 0x07 )),0,0,SSCR0_SerClkDiv(8));
+    ssp_enable(&corgi_ssp_dev);
+
+    udelay(1);
+
+	/* TB1/RB1 */
+	ssp_write_word(&corgi_ssp_dev,data);
+	ssp_read_word(&corgi_ssp_dev); /* null read */
+
+	/* TB12/RB2 */
+	ssp_write_word(&corgi_ssp_dev,0);
+	voltage1=ssp_read_word(&corgi_ssp_dev);
+
+	/* TB13/RB3*/
+	ssp_write_word(&corgi_ssp_dev,0);
+	voltage2=ssp_read_word(&corgi_ssp_dev);
+
+    ssp_disable(&corgi_ssp_dev);
+	ssp_config(&corgi_ssp_dev,(SSCR0_National | (SSCR0_DSS & 0x0b )),0,0,SSCR0_SerClkDiv(2));
+	ssp_enable(&corgi_ssp_dev);
+    GPSR0 = GPIO_bit(GPIO20_DREQ0); /* MAX1111 */
+    spin_unlock_irqrestore(&corgi_ssp_lock, flag);
+
+    if (voltage1 & 0xc0 || voltage2 & 0x3f)	voltage = -1;
+    else voltage = ((voltage1 << 2) & 0xfc) | ((voltage2 >> 6) & 0x03);
+
+    return voltage;
+}
+
+EXPORT_SYMBOL(corgi_ssp_max1111_get);
+
+/*
+ *  Support Routines
+ */
+
+int __init corgi_ssp_probe(struct device *dev)
+{
+	int ret;
+
+	/* Chip Select - disable all */
+	GPDR0 |= GPIO_bit(GPIO19_DREQ1); /* output */
+	GPSR0 = GPIO_bit(GPIO19_DREQ1);  /* High - Disable LCD Control/Timing Gen */
+	GPDR0 |= GPIO_bit(GPIO20_DREQ0); /* output */
+	GPSR0 = GPIO_bit(GPIO20_DREQ0);  /* High - Disable MAX1111*/
+	GPDR0 |= GPIO_bit(GPIO24_SFRM);  /* output */
+	GPSR0 = GPIO_bit(GPIO24_SFRM);   /* High - Disable ADS7846*/
+
+	ret=ssp_init(&corgi_ssp_dev,1);
+
+	if (ret) 
+		printk("Unable to register SSP handler!\n");
+	else {
+		ssp_disable(&corgi_ssp_dev);
+		ssp_config(&corgi_ssp_dev,(SSCR0_National | (SSCR0_DSS & 0x0b )),0,0,SSCR0_SerClkDiv(2));
+		ssp_enable(&corgi_ssp_dev);
+	}
+	
+	return ret;
+}
+
+static int corgi_ssp_remove(struct device *dev)
+{
+	ssp_exit(&corgi_ssp_dev);
+	return 0;
+}
+
+static int corgi_ssp_suspend(struct device *dev, u32 state, u32 level)
+{
+	if (level == SUSPEND_POWER_DOWN) {
+		ssp_save_state(&corgi_ssp_dev,&corgi_ssp_state);
+	}
+	return 0;
+}
+
+static int corgi_ssp_resume(struct device *dev, u32 level)
+{
+	if (level == RESUME_POWER_ON) {
+		GPSR0 = GPIO_bit(GPIO19_DREQ1);  /* High - Disable LCD Control/Timing Gen */
+		GPSR0 = GPIO_bit(GPIO20_DREQ0);  /* High - Disable MAX1111*/
+		GPSR0 = GPIO_bit(GPIO24_SFRM);   /* High - Disable ADS7846*/		
+		ssp_restore_state(&corgi_ssp_dev,&corgi_ssp_state);
+		ssp_enable(&corgi_ssp_dev);
+	}
+	return 0;
+}
+
+static struct device_driver corgissp_driver = {
+	.name		= "corgi-ssp",
+	.bus		= &platform_bus_type,
+	.probe		= corgi_ssp_probe,
+	.remove		= corgi_ssp_remove,
+	.suspend	= corgi_ssp_suspend,
+	.resume		= corgi_ssp_resume,
+};
+
+int __init corgi_ssp_init(void)
+{
+	return driver_register(&corgissp_driver);
+}
+
+arch_initcall(corgi_ssp_init);
--- linux-2.6.10/arch/arm/mach-pxa/Makefile~corgi_ssp-r3.patch
+++ linux-2.6.10/arch/arm/mach-pxa/Makefile
@@ -11,7 +11,7 @@
 obj-$(CONFIG_ARCH_LUBBOCK) += lubbock.o
 obj-$(CONFIG_MACH_MAINSTONE) += mainstone.o
 obj-$(CONFIG_ARCH_PXA_IDP) += idp.o
-obj-$(CONFIG_PXA_SHARPSL)	+= corgi.o
+obj-$(CONFIG_PXA_SHARPSL)	+= corgi.o corgi_ssp.o ssp.o
 
 # Support for blinky lights
 led-y := leds.o

