summaryrefslogtreecommitdiff
path: root/packages/linux/linux-rp-2.6.23/tosa-tmio-lcd-r10.patch
diff options
context:
space:
mode:
authorMarcin Juszkiewicz <hrw@openembedded.org>2007-10-30 15:21:19 +0000
committerMarcin Juszkiewicz <hrw@openembedded.org>2007-10-30 15:21:19 +0000
commita43e2b53a23bbd6955209a01a8388508f9205857 (patch)
treed9c5818b83a56f33baf0cb5d5a3bb34c49365845 /packages/linux/linux-rp-2.6.23/tosa-tmio-lcd-r10.patch
parent18f5c86801714259eaaa1e1a81565984f58ecd14 (diff)
linux-rp: update Tosa patchset in 2.6.22 and 2.6.23 - close #3233
USB Host patches are not updated
Diffstat (limited to 'packages/linux/linux-rp-2.6.23/tosa-tmio-lcd-r10.patch')
-rw-r--r--packages/linux/linux-rp-2.6.23/tosa-tmio-lcd-r10.patch928
1 files changed, 928 insertions, 0 deletions
diff --git a/packages/linux/linux-rp-2.6.23/tosa-tmio-lcd-r10.patch b/packages/linux/linux-rp-2.6.23/tosa-tmio-lcd-r10.patch
new file mode 100644
index 0000000000..cd24cc6cdc
--- /dev/null
+++ b/packages/linux/linux-rp-2.6.23/tosa-tmio-lcd-r10.patch
@@ -0,0 +1,928 @@
+ 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_EM_X270) += em-x270.o
+ obj-$(CONFIG_MACH_HX2750) += hx2750.o hx2750_test.o
+
+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>
+@@ -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
+ 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_EM_X270) += em-x270.o
+ obj-$(CONFIG_MACH_HX2750) += hx2750.o hx2750_test.o
+
+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>
+@@ -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