arch/arm/mach-pxa/Kconfig    |    5 
 arch/arm/mach-pxa/Makefile   |    2 
 arch/arm/mach-pxa/tosa.c     |   49 +++++-
 arch/arm/mach-pxa/tosa_lcd.c |  344 +++++++++++++++++++++++++++++++++++++++++++
 4 files changed, 396 insertions(+), 4 deletions(-)

Index: git/arch/arm/mach-pxa/Makefile
===================================================================
--- git.orig/arch/arm/mach-pxa/Makefile	2006-11-07 22:13:10.000000000 +0000
+++ git/arch/arm/mach-pxa/Makefile	2006-11-07 23:29:38.000000000 +0000
@@ -17,7 +17,7 @@ obj-$(CONFIG_PXA_SHARP_C7xx)	+= corgi.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 corgi_ssp.o sharpsl_pm.o poodle_pm.o
-obj-$(CONFIG_MACH_TOSA)         += tosa.o sharpsl_pm.o tosa_pm.o
+obj-$(CONFIG_MACH_TOSA)         += tosa.o sharpsl_pm.o tosa_pm.o tosa_lcd.o
 obj-$(CONFIG_MACH_HX2750)	+= hx2750.o hx2750_test.o
 
 # Support for blinky lights
Index: git/arch/arm/mach-pxa/tosa_lcd.c
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ git/arch/arm/mach-pxa/tosa_lcd.c	2006-11-07 23:29:25.000000000 +0000
@@ -0,0 +1,344 @@
+/*
+ *  LCD / Backlight control code for Sharp SL-6000x (tosa)
+ *
+ *  Copyright (c) 2005		Dirk Opfer
+ *
+ *  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/module.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/slab.h>
+#include <linux/delay.h>
+#include <linux/platform_device.h>
+#include <linux/i2c.h>
+#include <linux/fb.h>
+
+#include <asm/mach/sharpsl_param.h>
+#include <asm/hardware.h>
+#include <asm/hardware/scoop.h>
+#include <asm/hardware/tmio.h>
+#include <asm/arch/ssp.h>
+#include <asm/arch/sharpsl.h>
+#include <asm/arch/tosa.h>
+#include <asm/arch/pxa-regs.h>
+
+#define	DAC_BASE	0x4e
+#define DAC_CH1		0
+#define DAC_CH2		1
+
+#define TG_REG0_VQV	0x0001
+#define TG_REG0_COLOR	0x0002
+#define TG_REG0_UD	0x0004
+#define TG_REG0_LR	0x0008
+#define COMADJ_DEFAULT 	97
+#define TOSA_LCD_I2C_DEVICEID	0x4711			// Fixme: new value
+
+static void tosa_lcd_tg_init(struct device *dev);
+static void tosa_lcd_tg_on(struct device *dev, const struct fb_videomode *mode);
+static void tosa_lcd_tg_off(struct device *dev);
+static void tosa_set_backlight(int intensity);
+
+const static struct tmio_lcd_ops tosa_tc6393_lcd_ops = {
+	.init = tosa_lcd_tg_init,
+	.tg_on = tosa_lcd_tg_on,
+	.tg_off = tosa_lcd_tg_off,
+};
+
+static struct platform_device *tosabl_device;
+static struct i2c_driver tosa_driver;
+static struct i2c_client* tosa_i2c_dac;
+static int initialised;
+static int comadj;
+static int bl_intensity;
+static struct ssp_dev tosa_nssp_dev;
+static struct ssp_state tosa_nssp_state;
+static spinlock_t tosa_nssp_lock;
+
+static unsigned short normal_i2c[] = {
+	DAC_BASE,
+	I2C_CLIENT_END 
+};
+I2C_CLIENT_INSMOD;
+
+static struct corgibl_machinfo tosa_bl_machinfo = {
+	.max_intensity = 255,
+	.default_intensity = 68,
+	.limit_mask = 0x0b,
+	.set_bl_intensity = tosa_set_backlight,
+};
+
+int tosa_bl_intensity(void)
+{
+	return bl_intensity;
+}
+
+static void pxa_nssp_output(unsigned char reg, unsigned char data)
+{
+	unsigned long flag, dummy;
+	u32 dat = ( ((reg << 5) & 0xe0) | (data & 0x1f) );
+	spin_lock_irqsave(&tosa_nssp_lock, flag);
+
+	ssp_config(&tosa_nssp_dev, (SSCR0_Motorola | (SSCR0_DSS & 0x07 )), 0, 0, SSCR0_SerClkDiv(128));
+	ssp_enable(&tosa_nssp_dev);
+
+	ssp_write_word(&tosa_nssp_dev,dat);
+
+	/* Read null data back from device to prevent SSP overflow */
+	ssp_read_word(&tosa_nssp_dev, &dummy);
+	ssp_disable(&tosa_nssp_dev);
+	spin_unlock_irqrestore(&tosa_nssp_lock, flag);
+
+}
+
+static void tosa_set_backlight(int intensity)
+{
+	if (!tosa_i2c_dac)
+		return;
+
+	bl_intensity = intensity;
+	/* SetBacklightDuty */
+	i2c_smbus_write_byte_data(tosa_i2c_dac, DAC_CH2, (unsigned char)intensity);
+
+	/* SetBacklightVR */
+	if (intensity)
+		set_tc6393_gpio(&tc6393_device.dev,TOSA_TC6393_BL_C20MA);
+	else
+		reset_tc6393_gpio(&tc6393_device.dev,TOSA_TC6393_BL_C20MA);
+
+	/* bl_enable GP04=1 otherwise GP04=0*/
+	pxa_nssp_output(TG_GPODR2, intensity ? 0x01 : 0x00);	
+}
+
+static void tosa_lcd_tg_init(struct device *dev)
+{
+	/* L3V On */
+	set_scoop_gpio( &tosascoop_jc_device.dev,TOSA_SCOOP_JC_TC3693_L3V_ON); 
+	mdelay(60);
+
+	/* TG On */
+	reset_tc6393_gpio(&tc6393_device.dev,TOSA_TC6393_TG_ON);
+	mdelay(60);
+
+	pxa_nssp_output(TG_TPOSCTL,0x00);	/* delayed 0clk TCTL signal for VGA */
+	pxa_nssp_output(TG_GPOSR,0x02);		/* GPOS0=powercontrol, GPOS1=GPIO, GPOS2=TCTL */
+}
+
+static void tosa_lcd_tg_on(struct device *dev, const struct fb_videomode *mode)
+{
+	const int value = TG_REG0_COLOR | TG_REG0_UD | TG_REG0_LR;
+	pxa_nssp_output(TG_PNLCTL, value | (mode->yres == 320 ? 0 :  TG_REG0_VQV));
+
+	/* TG LCD pannel power up */
+	pxa_nssp_output(TG_PINICTL,0x4);
+	mdelay(50);
+
+	/* TG LCD GVSS */
+	pxa_nssp_output(TG_PINICTL,0x0);
+
+	if (!initialised)
+	{
+		/* after the pannel is powered up the first time, we can access the i2c bus */
+		/* so probe for the DAC */
+		i2c_add_driver(&tosa_driver);
+		initialised = 1;
+		mdelay(50);
+	}
+	if (tosa_i2c_dac)
+		/* set common voltage */
+		i2c_smbus_write_byte_data(tosa_i2c_dac, DAC_CH1, comadj);
+
+}
+
+static void tosa_lcd_tg_off(struct device *dev)
+{
+	/* TG LCD VHSA off */
+	pxa_nssp_output(TG_PINICTL,0x4);
+	mdelay(50);
+	
+	/* TG LCD signal off */
+	pxa_nssp_output(TG_PINICTL,0x6);
+	mdelay(50);
+	
+	/* TG Off */
+	set_tc6393_gpio(&tc6393_device.dev, TOSA_TC6393_TG_ON);
+	mdelay(100);
+	
+	/* L3V Off */
+	reset_scoop_gpio( &tosascoop_jc_device.dev,TOSA_SCOOP_JC_TC3693_L3V_ON); 
+}
+
+static int tosa_detect_client(struct i2c_adapter* adapter, int address, int kind) {
+	int err = 0;
+
+	printk("Tosa-LCD: DAC detected address:0x%2.2x\n",address);
+	if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA ))
+		goto ERROR0;
+
+	if (!(tosa_i2c_dac = (struct i2c_client*)kzalloc(sizeof(*tosa_i2c_dac), GFP_KERNEL))) {
+		err = -ENOMEM;
+		goto ERROR0;
+	}
+
+	//i2c_set_clientdata(tosa_i2c_dac, data);
+	tosa_i2c_dac->addr = address;
+	tosa_i2c_dac->adapter = adapter;
+	tosa_i2c_dac->driver = &tosa_driver;
+	tosa_i2c_dac->dev.parent = &tc6393_device.dev;
+	strcpy(tosa_i2c_dac->name, "tosa lcd");
+	if ((err = i2c_attach_client(tosa_i2c_dac)))
+		goto ERROR3;
+
+	/* Now i2c is ready, allocate the backlight device*/
+	tosabl_device = platform_device_alloc("corgi-bl", -1);
+	if (!tosabl_device) {
+		err = -ENOMEM;
+		goto ERROR4;
+	}
+
+	/* set parent device */
+	tosabl_device->dev.parent = &tosa_i2c_dac->dev;
+	tosabl_device->dev.platform_data  = &tosa_bl_machinfo;
+
+	err = platform_device_add(tosabl_device);
+
+	if (err)
+		platform_device_put(tosabl_device);
+
+	/* set common voltage */
+	i2c_smbus_write_byte_data(tosa_i2c_dac, DAC_CH1, comadj);
+
+	return 0;
+ERROR4:
+	i2c_detach_client(tosa_i2c_dac);
+ERROR3:
+	kfree(tosa_i2c_dac);
+ERROR0:
+	return err;
+}
+
+static int tosa_attach_adapter(struct i2c_adapter* adapter) {
+	return i2c_probe(adapter, &addr_data, &tosa_detect_client);
+}
+
+static int tosa_detach_client(struct i2c_client* client) {
+	int err;
+
+	if ((err = i2c_detach_client(client))) {
+		printk(KERN_ERR "tosa: Cannot deregister client\n");
+		return err;
+	}
+	kfree(client);
+	return 0;
+}
+
+static struct i2c_driver tosa_driver={
+	.id		= TOSA_LCD_I2C_DEVICEID,
+	.attach_adapter	= tosa_attach_adapter,
+	.detach_client	= tosa_detach_client,
+};
+
+static int __init tosa_lcd_probe(struct platform_device *pdev)
+{
+	int ret;
+	spin_lock_init(&tosa_nssp_lock);
+
+	if (!pdev->dev.platform_data)
+		return -EINVAL;
+
+	/* Set Common Voltage */
+	comadj = sharpsl_param.comadj == -1 ? COMADJ_DEFAULT : sharpsl_param.comadj;
+
+	ret=ssp_init(&tosa_nssp_dev,2,0);
+
+	/* initialize SSP */
+	pxa_gpio_mode(GPIO83_NSSP_TX);
+	pxa_gpio_mode(GPIO81_NSSP_CLK_OUT);
+	pxa_gpio_mode(GPIO82_NSSP_FRM_OUT);
+
+	if (ret) 
+		printk(KERN_ERR "Unable to register NSSP handler!\n");
+	else {
+		struct tmio_lcd_ops* *tmio_ops = pdev->dev.platform_data;
+		ssp_disable(&tosa_nssp_dev);
+		initialised = 0;
+
+		/* Set the lcd functions */
+		*tmio_ops = (struct tmio_lcd_ops*) &tosa_tc6393_lcd_ops;
+	}
+
+	return ret;
+}
+
+static int tosa_lcd_remove(struct platform_device *pdev)
+{
+	/* delete the lcd functions */
+	struct tmio_lcd_ops* *tmio_ops = pdev->dev.platform_data;
+	*tmio_ops = NULL;
+	
+	ssp_exit(&tosa_nssp_dev);
+	
+	if (tosa_i2c_dac) {
+		i2c_detach_client(tosa_i2c_dac);
+		kfree(tosa_i2c_dac);
+	}
+
+	return 0;
+}
+
+#ifdef CONFIG_PM 
+
+static int tosa_lcd_suspend(struct platform_device *pdev, pm_message_t state)
+{
+	ssp_flush(&tosa_nssp_dev);
+	ssp_save_state(&tosa_nssp_dev,&tosa_nssp_state);
+	return 0;
+}
+
+static int tosa_lcd_resume(struct platform_device *pdev)
+{
+	printk("tosa_lcd_resume\n");
+	ssp_restore_state(&tosa_nssp_dev,&tosa_nssp_state);
+	ssp_enable(&tosa_nssp_dev);
+	printk("tosa_lcd_resume ok\n");	
+	return 0;
+}
+#else
+
+#define tosa_lcd_suspend NULL
+#define tosa_lcd_resume NULL
+
+#endif
+
+
+static struct platform_driver tosalcd_driver = {
+	.probe		= tosa_lcd_probe,
+	.remove		= tosa_lcd_remove,
+	.suspend	= tosa_lcd_suspend,
+	.resume		= tosa_lcd_resume,
+	.driver		= {
+		.name		= "tosa-lcd",
+	},
+};
+
+static int __init tosa_lcd_init(void)
+{
+	return platform_driver_register(&tosalcd_driver);
+}
+
+static void __exit tosa_lcd_cleanup (void)
+{
+	platform_driver_unregister (&tosalcd_driver);
+}
+
+device_initcall(tosa_lcd_init);
+module_exit (tosa_lcd_cleanup);
+
+MODULE_DESCRIPTION ("Tosa LCD device");
+MODULE_AUTHOR ("Dirk Opfer");
+MODULE_LICENSE ("GPL v2");
Index: git/arch/arm/mach-pxa/tosa.c
===================================================================
--- git.orig/arch/arm/mach-pxa/tosa.c	2006-11-07 22:13:10.000000000 +0000
+++ git/arch/arm/mach-pxa/tosa.c	2006-11-07 23:29:38.000000000 +0000
@@ -24,6 +24,7 @@
 #include <linux/mtd/partitions.h>
 #include <linux/pm.h>
 #include <linux/delay.h>
+#include <linux/fb.h>
 
 #include <asm/setup.h>
 #include <asm/memory.h>
@@ -48,7 +49,6 @@
 
 #include "generic.h"
 
-
 /*
  * SCOOP Device
  */
@@ -345,7 +345,38 @@ static struct tmio_nand_platform_data to
 	.badblock_pattern = &tosa_tc6393_nand_bbt,
 };
 
-extern struct tmio_lcd_platform_data tosa_tc6393_lcd_platform_data;
+static struct fb_videomode tosa_tc6393_lcd_mode[] = {
+    {
+        .xres = 480,
+        .yres = 640,
+        .pixclock = 0x002cdf00,/* PLL divisor */
+        .left_margin = 0x004c,
+        .right_margin = 0x005b,
+        .upper_margin = 0x0001,
+        .lower_margin = 0x000d,
+        .hsync_len = 0x0002,
+        .vsync_len = 0x0001,
+        .sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
+        .vmode = FB_VMODE_NONINTERLACED,
+    },{
+	.xres = 240,
+	.yres = 320,
+	.pixclock = 0x00e7f203,/* PLL divisor */
+	.left_margin = 0x0024,
+	.right_margin = 0x002f,
+	.upper_margin = 0x0001,
+	.lower_margin = 0x000d,
+	.hsync_len = 0x0002,
+	.vsync_len = 0x0001,
+	.sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
+	.vmode = FB_VMODE_NONINTERLACED,
+}};
+
+struct tmio_lcd_platform_data tosa_tc6393_lcd_platform_data = {
+    .ops = NULL,
+    .modelist = tosa_tc6393_lcd_mode,
+    .num_modes = ARRAY_SIZE(tosa_tc6393_lcd_mode),
+};
 
 static struct tmio_cell tosa_tc6393_cells[] = {
 	{
@@ -384,6 +415,19 @@ struct platform_device tc6393_device = {
 	.num_resources	= ARRAY_SIZE(tc6393_resources),
 	.resource	= tc6393_resources,
 };
+EXPORT_SYMBOL (tc6393_device);
+
+/*
+ * Tosa LCD / Backlight stuff
+ */
+static struct platform_device tosalcd_device = {
+    .name	= "tosa-lcd",
+    .id		= -1,
+    .dev	= {
+	.parent	= &tc6393_device.dev,
+	.platform_data = &tosa_tc6393_lcd_platform_data.ops,
+    },
+};
 
 static struct platform_device *devices[] __initdata = {
 	&tosascoop_device,
@@ -391,6 +435,7 @@ static struct platform_device *devices[]
 	&tosakbd_device,
 	&tosaled_device,
 	&tc6393_device,
+	&tosalcd_device,
 };
 
 static void tosa_poweroff(void)
Index: git/arch/arm/mach-pxa/Kconfig
===================================================================
--- git.orig/arch/arm/mach-pxa/Kconfig	2006-11-07 22:13:10.000000000 +0000
+++ git/arch/arm/mach-pxa/Kconfig	2006-11-07 22:13:10.000000000 +0000
@@ -129,7 +129,10 @@ config MACH_TOSA
 	bool "Enable Sharp SL-6000x (Tosa) Support"
 	depends PXA_SHARPSL_25x
 	select TOSHIBA_TC6393XB
-	select SHARPSL_PM	
+	select I2C
+	select I2C_PXA
+	select SHARPSL_PM
+	select PXA_SSP
 
 config PXA25x
 	bool