diff options
author | Richard Purdie <rpurdie@rpsys.net> | 2005-09-13 04:25:30 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@g5.osdl.org> | 2005-09-13 11:22:31 -0400 |
commit | 50a5de44821352354a3ee804e2c7cbfee5a81c06 (patch) | |
tree | 8b6a4472e4e21038df8c9494daa7d2b00a26c743 | |
parent | 610827dee82731c7be5a135d750d194ac56881a9 (diff) |
[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>
-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 | ||||
-rw-r--r-- | include/asm-arm/arch-pxa/corgi.h | 12 | ||||
-rw-r--r-- | include/asm-arm/arch-pxa/sharpsl.h | 12 |
5 files changed, 79 insertions, 39 deletions
diff --git a/arch/arm/mach-pxa/corgi.c b/arch/arm/mach-pxa/corgi.c index 07b5dd453565..3678d1e0e826 100644 --- a/arch/arm/mach-pxa/corgi.c +++ b/arch/arm/mach-pxa/corgi.c | |||
@@ -41,6 +41,7 @@ | |||
41 | #include <asm/hardware/scoop.h> | 41 | #include <asm/hardware/scoop.h> |
42 | 42 | ||
43 | #include "generic.h" | 43 | #include "generic.h" |
44 | #include "sharpsl.h" | ||
44 | 45 | ||
45 | 46 | ||
46 | /* | 47 | /* |
@@ -94,6 +95,16 @@ struct platform_device corgissp_device = { | |||
94 | .id = -1, | 95 | .id = -1, |
95 | }; | 96 | }; |
96 | 97 | ||
98 | struct corgissp_machinfo corgi_ssp_machinfo = { | ||
99 | .port = 1, | ||
100 | .cs_lcdcon = CORGI_GPIO_LCDCON_CS, | ||
101 | .cs_ads7846 = CORGI_GPIO_ADS7846_CS, | ||
102 | .cs_max1111 = CORGI_GPIO_MAX1111_CS, | ||
103 | .clk_lcdcon = 76, | ||
104 | .clk_ads7846 = 2, | ||
105 | .clk_max1111 = 8, | ||
106 | }; | ||
107 | |||
97 | 108 | ||
98 | /* | 109 | /* |
99 | * Corgi Backlight Device | 110 | * Corgi Backlight Device |
@@ -225,6 +236,8 @@ static struct platform_device *devices[] __initdata = { | |||
225 | 236 | ||
226 | static void __init corgi_init(void) | 237 | static void __init corgi_init(void) |
227 | { | 238 | { |
239 | corgi_ssp_set_machinfo(&corgi_ssp_machinfo); | ||
240 | |||
228 | pxa_gpio_mode(CORGI_GPIO_USB_PULLUP | GPIO_OUT); | 241 | pxa_gpio_mode(CORGI_GPIO_USB_PULLUP | GPIO_OUT); |
229 | pxa_set_udc_info(&udc_info); | 242 | pxa_set_udc_info(&udc_info); |
230 | pxa_set_mci_info(&corgi_mci_platform_data); | 243 | 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 366a9bde3d8b..0ef428287055 100644 --- a/arch/arm/mach-pxa/corgi_ssp.c +++ b/arch/arm/mach-pxa/corgi_ssp.c | |||
@@ -1,7 +1,7 @@ | |||
1 | /* | 1 | /* |
2 | * SSP control code for Sharp Corgi devices | 2 | * SSP control code for Sharp Corgi devices |
3 | * | 3 | * |
4 | * Copyright (c) 2004 Richard Purdie | 4 | * Copyright (c) 2004-2005 Richard Purdie |
5 | * | 5 | * |
6 | * This program is free software; you can redistribute it and/or modify | 6 | * This program is free software; you can redistribute it and/or modify |
7 | * it under the terms of the GNU General Public License version 2 as | 7 | * it under the terms of the GNU General Public License version 2 as |
@@ -17,14 +17,16 @@ | |||
17 | #include <linux/delay.h> | 17 | #include <linux/delay.h> |
18 | #include <linux/device.h> | 18 | #include <linux/device.h> |
19 | #include <asm/hardware.h> | 19 | #include <asm/hardware.h> |
20 | #include <asm/mach-types.h> | ||
20 | 21 | ||
21 | #include <asm/arch/ssp.h> | 22 | #include <asm/arch/ssp.h> |
22 | #include <asm/arch/corgi.h> | ||
23 | #include <asm/arch/pxa-regs.h> | 23 | #include <asm/arch/pxa-regs.h> |
24 | #include "sharpsl.h" | ||
24 | 25 | ||
25 | static DEFINE_SPINLOCK(corgi_ssp_lock); | 26 | static DEFINE_SPINLOCK(corgi_ssp_lock); |
26 | static struct ssp_dev corgi_ssp_dev; | 27 | static struct ssp_dev corgi_ssp_dev; |
27 | static struct ssp_state corgi_ssp_state; | 28 | static struct ssp_state corgi_ssp_state; |
29 | static struct corgissp_machinfo *ssp_machinfo; | ||
28 | 30 | ||
29 | /* | 31 | /* |
30 | * There are three devices connected to the SSP interface: | 32 | * There are three devices connected to the SSP interface: |
@@ -48,12 +50,12 @@ unsigned long corgi_ssp_ads7846_putget(ulong data) | |||
48 | unsigned long ret,flag; | 50 | unsigned long ret,flag; |
49 | 51 | ||
50 | spin_lock_irqsave(&corgi_ssp_lock, flag); | 52 | spin_lock_irqsave(&corgi_ssp_lock, flag); |
51 | GPCR0 = GPIO_bit(CORGI_GPIO_ADS7846_CS); | 53 | GPCR(ssp_machinfo->cs_ads7846) = GPIO_bit(ssp_machinfo->cs_ads7846); |
52 | 54 | ||
53 | ssp_write_word(&corgi_ssp_dev,data); | 55 | ssp_write_word(&corgi_ssp_dev,data); |
54 | ret = ssp_read_word(&corgi_ssp_dev); | 56 | ret = ssp_read_word(&corgi_ssp_dev); |
55 | 57 | ||
56 | GPSR0 = GPIO_bit(CORGI_GPIO_ADS7846_CS); | 58 | GPSR(ssp_machinfo->cs_ads7846) = GPIO_bit(ssp_machinfo->cs_ads7846); |
57 | spin_unlock_irqrestore(&corgi_ssp_lock, flag); | 59 | spin_unlock_irqrestore(&corgi_ssp_lock, flag); |
58 | 60 | ||
59 | return ret; | 61 | return ret; |
@@ -66,12 +68,12 @@ unsigned long corgi_ssp_ads7846_putget(ulong data) | |||
66 | void corgi_ssp_ads7846_lock(void) | 68 | void corgi_ssp_ads7846_lock(void) |
67 | { | 69 | { |
68 | spin_lock(&corgi_ssp_lock); | 70 | spin_lock(&corgi_ssp_lock); |
69 | GPCR0 = GPIO_bit(CORGI_GPIO_ADS7846_CS); | 71 | GPCR(ssp_machinfo->cs_ads7846) = GPIO_bit(ssp_machinfo->cs_ads7846); |
70 | } | 72 | } |
71 | 73 | ||
72 | void corgi_ssp_ads7846_unlock(void) | 74 | void corgi_ssp_ads7846_unlock(void) |
73 | { | 75 | { |
74 | GPSR0 = GPIO_bit(CORGI_GPIO_ADS7846_CS); | 76 | GPSR(ssp_machinfo->cs_ads7846) = GPIO_bit(ssp_machinfo->cs_ads7846); |
75 | spin_unlock(&corgi_ssp_lock); | 77 | spin_unlock(&corgi_ssp_lock); |
76 | } | 78 | } |
77 | 79 | ||
@@ -97,23 +99,27 @@ EXPORT_SYMBOL(corgi_ssp_ads7846_get); | |||
97 | */ | 99 | */ |
98 | unsigned long corgi_ssp_dac_put(ulong data) | 100 | unsigned long corgi_ssp_dac_put(ulong data) |
99 | { | 101 | { |
100 | unsigned long flag; | 102 | unsigned long flag, sscr1 = SSCR1_SPH; |
101 | 103 | ||
102 | spin_lock_irqsave(&corgi_ssp_lock, flag); | 104 | spin_lock_irqsave(&corgi_ssp_lock, flag); |
103 | GPCR0 = GPIO_bit(CORGI_GPIO_LCDCON_CS); | 105 | |
106 | if (machine_is_spitz() || machine_is_akita() || machine_is_borzoi()) | ||
107 | sscr1 = 0; | ||
104 | 108 | ||
105 | ssp_disable(&corgi_ssp_dev); | 109 | ssp_disable(&corgi_ssp_dev); |
106 | ssp_config(&corgi_ssp_dev, (SSCR0_Motorola | (SSCR0_DSS & 0x07 )), SSCR1_SPH, 0, SSCR0_SerClkDiv(76)); | 110 | ssp_config(&corgi_ssp_dev, (SSCR0_Motorola | (SSCR0_DSS & 0x07 )), sscr1, 0, SSCR0_SerClkDiv(ssp_machinfo->clk_lcdcon)); |
107 | ssp_enable(&corgi_ssp_dev); | 111 | ssp_enable(&corgi_ssp_dev); |
108 | 112 | ||
113 | GPCR(ssp_machinfo->cs_lcdcon) = GPIO_bit(ssp_machinfo->cs_lcdcon); | ||
109 | ssp_write_word(&corgi_ssp_dev,data); | 114 | ssp_write_word(&corgi_ssp_dev,data); |
110 | /* Read null data back from device to prevent SSP overflow */ | 115 | /* Read null data back from device to prevent SSP overflow */ |
111 | ssp_read_word(&corgi_ssp_dev); | 116 | ssp_read_word(&corgi_ssp_dev); |
117 | GPSR(ssp_machinfo->cs_lcdcon) = GPIO_bit(ssp_machinfo->cs_lcdcon); | ||
112 | 118 | ||
113 | ssp_disable(&corgi_ssp_dev); | 119 | ssp_disable(&corgi_ssp_dev); |
114 | ssp_config(&corgi_ssp_dev, (SSCR0_National | (SSCR0_DSS & 0x0b )), 0, 0, SSCR0_SerClkDiv(2)); | 120 | ssp_config(&corgi_ssp_dev, (SSCR0_National | (SSCR0_DSS & 0x0b )), 0, 0, SSCR0_SerClkDiv(ssp_machinfo->clk_ads7846)); |
115 | ssp_enable(&corgi_ssp_dev); | 121 | ssp_enable(&corgi_ssp_dev); |
116 | GPSR0 = GPIO_bit(CORGI_GPIO_LCDCON_CS); | 122 | |
117 | spin_unlock_irqrestore(&corgi_ssp_lock, flag); | 123 | spin_unlock_irqrestore(&corgi_ssp_lock, flag); |
118 | 124 | ||
119 | return 0; | 125 | return 0; |
@@ -141,9 +147,9 @@ int corgi_ssp_max1111_get(ulong data) | |||
141 | int voltage,voltage1,voltage2; | 147 | int voltage,voltage1,voltage2; |
142 | 148 | ||
143 | spin_lock_irqsave(&corgi_ssp_lock, flag); | 149 | spin_lock_irqsave(&corgi_ssp_lock, flag); |
144 | GPCR0 = GPIO_bit(CORGI_GPIO_MAX1111_CS); | 150 | GPCR(ssp_machinfo->cs_max1111) = GPIO_bit(ssp_machinfo->cs_max1111); |
145 | ssp_disable(&corgi_ssp_dev); | 151 | ssp_disable(&corgi_ssp_dev); |
146 | ssp_config(&corgi_ssp_dev, (SSCR0_Motorola | (SSCR0_DSS & 0x07 )), 0, 0, SSCR0_SerClkDiv(8)); | 152 | ssp_config(&corgi_ssp_dev, (SSCR0_Motorola | (SSCR0_DSS & 0x07 )), 0, 0, SSCR0_SerClkDiv(ssp_machinfo->clk_max1111)); |
147 | ssp_enable(&corgi_ssp_dev); | 153 | ssp_enable(&corgi_ssp_dev); |
148 | 154 | ||
149 | udelay(1); | 155 | udelay(1); |
@@ -161,9 +167,9 @@ int corgi_ssp_max1111_get(ulong data) | |||
161 | voltage2=ssp_read_word(&corgi_ssp_dev); | 167 | voltage2=ssp_read_word(&corgi_ssp_dev); |
162 | 168 | ||
163 | ssp_disable(&corgi_ssp_dev); | 169 | ssp_disable(&corgi_ssp_dev); |
164 | ssp_config(&corgi_ssp_dev, (SSCR0_National | (SSCR0_DSS & 0x0b )), 0, 0, SSCR0_SerClkDiv(2)); | 170 | ssp_config(&corgi_ssp_dev, (SSCR0_National | (SSCR0_DSS & 0x0b )), 0, 0, SSCR0_SerClkDiv(ssp_machinfo->clk_ads7846)); |
165 | ssp_enable(&corgi_ssp_dev); | 171 | ssp_enable(&corgi_ssp_dev); |
166 | GPSR0 = GPIO_bit(CORGI_GPIO_MAX1111_CS); | 172 | GPSR(ssp_machinfo->cs_max1111) = GPIO_bit(ssp_machinfo->cs_max1111); |
167 | spin_unlock_irqrestore(&corgi_ssp_lock, flag); | 173 | spin_unlock_irqrestore(&corgi_ssp_lock, flag); |
168 | 174 | ||
169 | if (voltage1 & 0xc0 || voltage2 & 0x3f) | 175 | if (voltage1 & 0xc0 || voltage2 & 0x3f) |
@@ -179,25 +185,31 @@ EXPORT_SYMBOL(corgi_ssp_max1111_get); | |||
179 | /* | 185 | /* |
180 | * Support Routines | 186 | * Support Routines |
181 | */ | 187 | */ |
182 | int __init corgi_ssp_probe(struct device *dev) | 188 | |
189 | void __init corgi_ssp_set_machinfo(struct corgissp_machinfo *machinfo) | ||
190 | { | ||
191 | ssp_machinfo = machinfo; | ||
192 | } | ||
193 | |||
194 | static int __init corgi_ssp_probe(struct device *dev) | ||
183 | { | 195 | { |
184 | int ret; | 196 | int ret; |
185 | 197 | ||
186 | /* Chip Select - Disable All */ | 198 | /* Chip Select - Disable All */ |
187 | GPDR0 |= GPIO_bit(CORGI_GPIO_LCDCON_CS); /* output */ | 199 | GPDR(ssp_machinfo->cs_lcdcon) |= GPIO_bit(ssp_machinfo->cs_lcdcon); /* output */ |
188 | GPSR0 = GPIO_bit(CORGI_GPIO_LCDCON_CS); /* High - Disable LCD Control/Timing Gen */ | 200 | GPSR(ssp_machinfo->cs_lcdcon) = GPIO_bit(ssp_machinfo->cs_lcdcon); /* High - Disable LCD Control/Timing Gen */ |
189 | GPDR0 |= GPIO_bit(CORGI_GPIO_MAX1111_CS); /* output */ | 201 | GPDR(ssp_machinfo->cs_max1111) |= GPIO_bit(ssp_machinfo->cs_max1111); /* output */ |
190 | GPSR0 = GPIO_bit(CORGI_GPIO_MAX1111_CS); /* High - Disable MAX1111*/ | 202 | GPSR(ssp_machinfo->cs_max1111) = GPIO_bit(ssp_machinfo->cs_max1111); /* High - Disable MAX1111*/ |
191 | GPDR0 |= GPIO_bit(CORGI_GPIO_ADS7846_CS); /* output */ | 203 | GPDR(ssp_machinfo->cs_ads7846) |= GPIO_bit(ssp_machinfo->cs_ads7846); /* output */ |
192 | GPSR0 = GPIO_bit(CORGI_GPIO_ADS7846_CS); /* High - Disable ADS7846*/ | 204 | GPSR(ssp_machinfo->cs_ads7846) = GPIO_bit(ssp_machinfo->cs_ads7846); /* High - Disable ADS7846*/ |
193 | 205 | ||
194 | ret=ssp_init(&corgi_ssp_dev,1); | 206 | ret = ssp_init(&corgi_ssp_dev,ssp_machinfo->port); |
195 | 207 | ||
196 | if (ret) | 208 | if (ret) |
197 | printk(KERN_ERR "Unable to register SSP handler!\n"); | 209 | printk(KERN_ERR "Unable to register SSP handler!\n"); |
198 | else { | 210 | else { |
199 | ssp_disable(&corgi_ssp_dev); | 211 | ssp_disable(&corgi_ssp_dev); |
200 | ssp_config(&corgi_ssp_dev, (SSCR0_National | (SSCR0_DSS & 0x0b )), 0, 0, SSCR0_SerClkDiv(2)); | 212 | ssp_config(&corgi_ssp_dev, (SSCR0_National | (SSCR0_DSS & 0x0b )), 0, 0, SSCR0_SerClkDiv(ssp_machinfo->clk_ads7846)); |
201 | ssp_enable(&corgi_ssp_dev); | 213 | ssp_enable(&corgi_ssp_dev); |
202 | } | 214 | } |
203 | 215 | ||
@@ -222,9 +234,9 @@ static int corgi_ssp_suspend(struct device *dev, pm_message_t state, u32 level) | |||
222 | static int corgi_ssp_resume(struct device *dev, u32 level) | 234 | static int corgi_ssp_resume(struct device *dev, u32 level) |
223 | { | 235 | { |
224 | if (level == RESUME_POWER_ON) { | 236 | if (level == RESUME_POWER_ON) { |
225 | GPSR0 = GPIO_bit(CORGI_GPIO_LCDCON_CS); /* High - Disable LCD Control/Timing Gen */ | 237 | GPSR(ssp_machinfo->cs_lcdcon) = GPIO_bit(ssp_machinfo->cs_lcdcon); /* High - Disable LCD Control/Timing Gen */ |
226 | GPSR0 = GPIO_bit(CORGI_GPIO_MAX1111_CS); /* High - Disable MAX1111*/ | 238 | GPSR(ssp_machinfo->cs_max1111) = GPIO_bit(ssp_machinfo->cs_max1111); /* High - Disable MAX1111*/ |
227 | GPSR0 = GPIO_bit(CORGI_GPIO_ADS7846_CS); /* High - Disable ADS7846*/ | 239 | GPSR(ssp_machinfo->cs_ads7846) = GPIO_bit(ssp_machinfo->cs_ads7846); /* High - Disable ADS7846*/ |
228 | ssp_restore_state(&corgi_ssp_dev,&corgi_ssp_state); | 240 | ssp_restore_state(&corgi_ssp_dev,&corgi_ssp_state); |
229 | ssp_enable(&corgi_ssp_dev); | 241 | ssp_enable(&corgi_ssp_dev); |
230 | } | 242 | } |
diff --git a/arch/arm/mach-pxa/sharpsl.h b/arch/arm/mach-pxa/sharpsl.h new file mode 100644 index 000000000000..672262ee9d2b --- /dev/null +++ b/arch/arm/mach-pxa/sharpsl.h | |||
@@ -0,0 +1,15 @@ | |||
1 | /* | ||
2 | * SharpSL SSP Driver | ||
3 | */ | ||
4 | |||
5 | struct corgissp_machinfo { | ||
6 | int port; | ||
7 | int cs_lcdcon; | ||
8 | int cs_ads7846; | ||
9 | int cs_max1111; | ||
10 | int clk_lcdcon; | ||
11 | int clk_ads7846; | ||
12 | int clk_max1111; | ||
13 | }; | ||
14 | |||
15 | void corgi_ssp_set_machinfo(struct corgissp_machinfo *machinfo); | ||
diff --git a/include/asm-arm/arch-pxa/corgi.h b/include/asm-arm/arch-pxa/corgi.h index 4b7aa0b8391e..e554caa0d18b 100644 --- a/include/asm-arm/arch-pxa/corgi.h +++ b/include/asm-arm/arch-pxa/corgi.h | |||
@@ -106,17 +106,5 @@ extern struct platform_device corgiscoop_device; | |||
106 | extern struct platform_device corgissp_device; | 106 | extern struct platform_device corgissp_device; |
107 | extern struct platform_device corgifb_device; | 107 | extern struct platform_device corgifb_device; |
108 | 108 | ||
109 | /* | ||
110 | * External Functions | ||
111 | */ | ||
112 | extern unsigned long corgi_ssp_ads7846_putget(unsigned long); | ||
113 | extern unsigned long corgi_ssp_ads7846_get(void); | ||
114 | extern void corgi_ssp_ads7846_put(unsigned long data); | ||
115 | extern void corgi_ssp_ads7846_lock(void); | ||
116 | extern void corgi_ssp_ads7846_unlock(void); | ||
117 | extern void corgi_ssp_lcdtg_send (unsigned char adrs, unsigned char data); | ||
118 | extern void corgi_ssp_blduty_set(int duty); | ||
119 | extern int corgi_ssp_max1111_get(unsigned long data); | ||
120 | |||
121 | #endif /* __ASM_ARCH_CORGI_H */ | 109 | #endif /* __ASM_ARCH_CORGI_H */ |
122 | 110 | ||
diff --git a/include/asm-arm/arch-pxa/sharpsl.h b/include/asm-arm/arch-pxa/sharpsl.h new file mode 100644 index 000000000000..5ce6d05631e8 --- /dev/null +++ b/include/asm-arm/arch-pxa/sharpsl.h | |||
@@ -0,0 +1,12 @@ | |||
1 | /* | ||
2 | * SharpSL SSP Driver | ||
3 | */ | ||
4 | |||
5 | unsigned long corgi_ssp_ads7846_putget(unsigned long); | ||
6 | unsigned long corgi_ssp_ads7846_get(void); | ||
7 | void corgi_ssp_ads7846_put(unsigned long data); | ||
8 | void corgi_ssp_ads7846_lock(void); | ||
9 | void corgi_ssp_ads7846_unlock(void); | ||
10 | void corgi_ssp_lcdtg_send (unsigned char adrs, unsigned char data); | ||
11 | void corgi_ssp_blduty_set(int duty); | ||
12 | int corgi_ssp_max1111_get(unsigned long data); | ||