diff options
author | Richard Purdie <rpurdie@rpsys.net> | 2005-09-13 01:25:30 -0700 |
---|---|---|
committer | Linus Torvalds <torvalds@g5.osdl.org> | 2005-09-13 08:22:31 -0700 |
commit | 50a5de44821352354a3ee804e2c7cbfee5a81c06 (patch) | |
tree | 8b6a4472e4e21038df8c9494daa7d2b00a26c743 /arch/arm/mach-pxa | |
parent | 610827dee82731c7be5a135d750d194ac56881a9 (diff) | |
download | op-kernel-dev-50a5de44821352354a3ee804e2c7cbfee5a81c06.zip op-kernel-dev-50a5de44821352354a3ee804e2c7cbfee5a81c06.tar.gz |
[PATCH] SharpSL: Abstract c7x0 specifics from Corgi SSP
Sharp's newer range of Zaurus clamshell handhelds, the cxx00's are similar to
the c7x0 series yet different. This patch series abstracts the differences
and generates a set of common drivers that support both series of devices. It
then adds machine support for Spitz (SL-C3000) and Borzoi (SL-C3100). Hooks
for Akita (SL-C1000) differences are also added. The I2C driver for its IO
expander is the only missing piece.
This patch:
Separate out the Sharp Zaurus c7x0 series specific code from corgi_ssp.c so
that other models such as the cxx00's can share it. Create sharpsl.h which
will be used to abstract machine/model specifics.
This enables the driver to be used by the Zaurus cxx00 series.
Signed-Off-by: Richard Purdie <rpurdie@rpsys.net>
Cc: Vojtech Pavlik <vojtech@suse.cz>
Cc: Russell King <rmk@arm.linux.org.uk>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'arch/arm/mach-pxa')
-rw-r--r-- | arch/arm/mach-pxa/corgi.c | 13 | ||||
-rw-r--r-- | arch/arm/mach-pxa/corgi_ssp.c | 66 | ||||
-rw-r--r-- | arch/arm/mach-pxa/sharpsl.h | 15 |
3 files changed, 67 insertions, 27 deletions
diff --git a/arch/arm/mach-pxa/corgi.c b/arch/arm/mach-pxa/corgi.c index 07b5dd4..3678d1e 100644 --- a/arch/arm/mach-pxa/corgi.c +++ b/arch/arm/mach-pxa/corgi.c @@ -41,6 +41,7 @@ #include <asm/hardware/scoop.h> #include "generic.h" +#include "sharpsl.h" /* @@ -94,6 +95,16 @@ struct platform_device corgissp_device = { .id = -1, }; +struct corgissp_machinfo corgi_ssp_machinfo = { + .port = 1, + .cs_lcdcon = CORGI_GPIO_LCDCON_CS, + .cs_ads7846 = CORGI_GPIO_ADS7846_CS, + .cs_max1111 = CORGI_GPIO_MAX1111_CS, + .clk_lcdcon = 76, + .clk_ads7846 = 2, + .clk_max1111 = 8, +}; + /* * Corgi Backlight Device @@ -225,6 +236,8 @@ static struct platform_device *devices[] __initdata = { static void __init corgi_init(void) { + corgi_ssp_set_machinfo(&corgi_ssp_machinfo); + pxa_gpio_mode(CORGI_GPIO_USB_PULLUP | GPIO_OUT); pxa_set_udc_info(&udc_info); pxa_set_mci_info(&corgi_mci_platform_data); diff --git a/arch/arm/mach-pxa/corgi_ssp.c b/arch/arm/mach-pxa/corgi_ssp.c index 366a9bd..0ef4282 100644 --- a/arch/arm/mach-pxa/corgi_ssp.c +++ b/arch/arm/mach-pxa/corgi_ssp.c @@ -1,7 +1,7 @@ /* * SSP control code for Sharp Corgi devices * - * Copyright (c) 2004 Richard Purdie + * Copyright (c) 2004-2005 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 @@ -17,14 +17,16 @@ #include <linux/delay.h> #include <linux/device.h> #include <asm/hardware.h> +#include <asm/mach-types.h> #include <asm/arch/ssp.h> -#include <asm/arch/corgi.h> #include <asm/arch/pxa-regs.h> +#include "sharpsl.h" static DEFINE_SPINLOCK(corgi_ssp_lock); static struct ssp_dev corgi_ssp_dev; static struct ssp_state corgi_ssp_state; +static struct corgissp_machinfo *ssp_machinfo; /* * There are three devices connected to the SSP interface: @@ -48,12 +50,12 @@ unsigned long corgi_ssp_ads7846_putget(ulong data) unsigned long ret,flag; spin_lock_irqsave(&corgi_ssp_lock, flag); - GPCR0 = GPIO_bit(CORGI_GPIO_ADS7846_CS); + 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); - GPSR0 = GPIO_bit(CORGI_GPIO_ADS7846_CS); + GPSR(ssp_machinfo->cs_ads7846) = GPIO_bit(ssp_machinfo->cs_ads7846); spin_unlock_irqrestore(&corgi_ssp_lock, flag); return ret; @@ -66,12 +68,12 @@ unsigned long corgi_ssp_ads7846_putget(ulong data) void corgi_ssp_ads7846_lock(void) { spin_lock(&corgi_ssp_lock); - GPCR0 = GPIO_bit(CORGI_GPIO_ADS7846_CS); + GPCR(ssp_machinfo->cs_ads7846) = GPIO_bit(ssp_machinfo->cs_ads7846); } void corgi_ssp_ads7846_unlock(void) { - GPSR0 = GPIO_bit(CORGI_GPIO_ADS7846_CS); + GPSR(ssp_machinfo->cs_ads7846) = GPIO_bit(ssp_machinfo->cs_ads7846); spin_unlock(&corgi_ssp_lock); } @@ -97,23 +99,27 @@ EXPORT_SYMBOL(corgi_ssp_ads7846_get); */ unsigned long corgi_ssp_dac_put(ulong data) { - unsigned long flag; + unsigned long flag, sscr1 = SSCR1_SPH; spin_lock_irqsave(&corgi_ssp_lock, flag); - GPCR0 = GPIO_bit(CORGI_GPIO_LCDCON_CS); + + if (machine_is_spitz() || machine_is_akita() || machine_is_borzoi()) + sscr1 = 0; ssp_disable(&corgi_ssp_dev); - ssp_config(&corgi_ssp_dev, (SSCR0_Motorola | (SSCR0_DSS & 0x07 )), SSCR1_SPH, 0, SSCR0_SerClkDiv(76)); + 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); 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); ssp_disable(&corgi_ssp_dev); - ssp_config(&corgi_ssp_dev, (SSCR0_National | (SSCR0_DSS & 0x0b )), 0, 0, SSCR0_SerClkDiv(2)); + ssp_config(&corgi_ssp_dev, (SSCR0_National | (SSCR0_DSS & 0x0b )), 0, 0, SSCR0_SerClkDiv(ssp_machinfo->clk_ads7846)); ssp_enable(&corgi_ssp_dev); - GPSR0 = GPIO_bit(CORGI_GPIO_LCDCON_CS); + spin_unlock_irqrestore(&corgi_ssp_lock, flag); return 0; @@ -141,9 +147,9 @@ int corgi_ssp_max1111_get(ulong data) int voltage,voltage1,voltage2; spin_lock_irqsave(&corgi_ssp_lock, flag); - GPCR0 = GPIO_bit(CORGI_GPIO_MAX1111_CS); + 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(8)); + ssp_config(&corgi_ssp_dev, (SSCR0_Motorola | (SSCR0_DSS & 0x07 )), 0, 0, SSCR0_SerClkDiv(ssp_machinfo->clk_max1111)); ssp_enable(&corgi_ssp_dev); udelay(1); @@ -161,9 +167,9 @@ int corgi_ssp_max1111_get(ulong data) 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_config(&corgi_ssp_dev, (SSCR0_National | (SSCR0_DSS & 0x0b )), 0, 0, SSCR0_SerClkDiv(ssp_machinfo->clk_ads7846)); ssp_enable(&corgi_ssp_dev); - GPSR0 = GPIO_bit(CORGI_GPIO_MAX1111_CS); + GPSR(ssp_machinfo->cs_max1111) = GPIO_bit(ssp_machinfo->cs_max1111); spin_unlock_irqrestore(&corgi_ssp_lock, flag); if (voltage1 & 0xc0 || voltage2 & 0x3f) @@ -179,25 +185,31 @@ EXPORT_SYMBOL(corgi_ssp_max1111_get); /* * Support Routines */ -int __init corgi_ssp_probe(struct device *dev) + +void __init corgi_ssp_set_machinfo(struct corgissp_machinfo *machinfo) +{ + ssp_machinfo = machinfo; +} + +static int __init corgi_ssp_probe(struct device *dev) { int ret; /* Chip Select - Disable All */ - GPDR0 |= GPIO_bit(CORGI_GPIO_LCDCON_CS); /* output */ - GPSR0 = GPIO_bit(CORGI_GPIO_LCDCON_CS); /* High - Disable LCD Control/Timing Gen */ - GPDR0 |= GPIO_bit(CORGI_GPIO_MAX1111_CS); /* output */ - GPSR0 = GPIO_bit(CORGI_GPIO_MAX1111_CS); /* High - Disable MAX1111*/ - GPDR0 |= GPIO_bit(CORGI_GPIO_ADS7846_CS); /* output */ - GPSR0 = GPIO_bit(CORGI_GPIO_ADS7846_CS); /* High - Disable ADS7846*/ + GPDR(ssp_machinfo->cs_lcdcon) |= GPIO_bit(ssp_machinfo->cs_lcdcon); /* output */ + GPSR(ssp_machinfo->cs_lcdcon) = GPIO_bit(ssp_machinfo->cs_lcdcon); /* High - Disable LCD Control/Timing Gen */ + GPDR(ssp_machinfo->cs_max1111) |= GPIO_bit(ssp_machinfo->cs_max1111); /* output */ + GPSR(ssp_machinfo->cs_max1111) = GPIO_bit(ssp_machinfo->cs_max1111); /* High - Disable MAX1111*/ + GPDR(ssp_machinfo->cs_ads7846) |= GPIO_bit(ssp_machinfo->cs_ads7846); /* output */ + GPSR(ssp_machinfo->cs_ads7846) = GPIO_bit(ssp_machinfo->cs_ads7846); /* High - Disable ADS7846*/ - ret=ssp_init(&corgi_ssp_dev,1); + ret = ssp_init(&corgi_ssp_dev,ssp_machinfo->port); if (ret) printk(KERN_ERR "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_config(&corgi_ssp_dev, (SSCR0_National | (SSCR0_DSS & 0x0b )), 0, 0, SSCR0_SerClkDiv(ssp_machinfo->clk_ads7846)); ssp_enable(&corgi_ssp_dev); } @@ -222,9 +234,9 @@ static int corgi_ssp_suspend(struct device *dev, pm_message_t state, u32 level) static int corgi_ssp_resume(struct device *dev, u32 level) { if (level == RESUME_POWER_ON) { - GPSR0 = GPIO_bit(CORGI_GPIO_LCDCON_CS); /* High - Disable LCD Control/Timing Gen */ - GPSR0 = GPIO_bit(CORGI_GPIO_MAX1111_CS); /* High - Disable MAX1111*/ - GPSR0 = GPIO_bit(CORGI_GPIO_ADS7846_CS); /* High - Disable ADS7846*/ + 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*/ ssp_restore_state(&corgi_ssp_dev,&corgi_ssp_state); ssp_enable(&corgi_ssp_dev); } diff --git a/arch/arm/mach-pxa/sharpsl.h b/arch/arm/mach-pxa/sharpsl.h new file mode 100644 index 0000000..672262e --- /dev/null +++ b/arch/arm/mach-pxa/sharpsl.h @@ -0,0 +1,15 @@ +/* + * SharpSL SSP Driver + */ + +struct corgissp_machinfo { + int port; + int cs_lcdcon; + int cs_ads7846; + int cs_max1111; + int clk_lcdcon; + int clk_ads7846; + int clk_max1111; +}; + +void corgi_ssp_set_machinfo(struct corgissp_machinfo *machinfo); |