diff options
Diffstat (limited to 'arch/arm/mach-pxa')
-rw-r--r-- | arch/arm/mach-pxa/Kconfig | 29 | ||||
-rw-r--r-- | arch/arm/mach-pxa/Makefile | 8 | ||||
-rw-r--r-- | arch/arm/mach-pxa/am200epd.c | 374 | ||||
-rw-r--r-- | arch/arm/mach-pxa/cm-x255.c | 258 | ||||
-rw-r--r-- | arch/arm/mach-pxa/cm-x270-pci.h | 13 | ||||
-rw-r--r-- | arch/arm/mach-pxa/cm-x270.c | 461 | ||||
-rw-r--r-- | arch/arm/mach-pxa/cm-x2xx-pci.c (renamed from arch/arm/mach-pxa/cm-x270-pci.c) | 56 | ||||
-rw-r--r-- | arch/arm/mach-pxa/cm-x2xx-pci.h | 13 | ||||
-rw-r--r-- | arch/arm/mach-pxa/cm-x2xx.c | 531 | ||||
-rw-r--r-- | arch/arm/mach-pxa/cm-x300.c | 473 | ||||
-rw-r--r-- | arch/arm/mach-pxa/gumstix.c | 100 | ||||
-rw-r--r-- | arch/arm/mach-pxa/include/mach/memory.h | 4 | ||||
-rw-r--r-- | arch/arm/mach-pxa/include/mach/mfp-pxa320.h | 8 | ||||
-rw-r--r-- | arch/arm/mach-pxa/include/mach/mioa701.h | 67 | ||||
-rw-r--r-- | arch/arm/mach-pxa/mioa701.c | 905 | ||||
-rw-r--r-- | arch/arm/mach-pxa/mioa701_bootresume.S | 36 | ||||
-rw-r--r-- | arch/arm/mach-pxa/mp900.c | 100 | ||||
-rw-r--r-- | arch/arm/mach-pxa/zylonite_pxa300.c | 8 | ||||
-rw-r--r-- | arch/arm/mach-pxa/zylonite_pxa320.c | 6 |
19 files changed, 2926 insertions, 524 deletions
diff --git a/arch/arm/mach-pxa/Kconfig b/arch/arm/mach-pxa/Kconfig index e8ee7ec9ff6d..4618f7c2e375 100644 --- a/arch/arm/mach-pxa/Kconfig +++ b/arch/arm/mach-pxa/Kconfig | |||
@@ -49,6 +49,10 @@ config MACH_MAINSTONE | |||
49 | select PXA27x | 49 | select PXA27x |
50 | select HAVE_PWM | 50 | select HAVE_PWM |
51 | 51 | ||
52 | config MACH_MP900C | ||
53 | bool "Nec Mobilepro 900/c" | ||
54 | select PXA25x | ||
55 | |||
52 | config ARCH_PXA_IDP | 56 | config ARCH_PXA_IDP |
53 | bool "Accelent Xscale IDP" | 57 | bool "Accelent Xscale IDP" |
54 | select PXA25x | 58 | select PXA25x |
@@ -189,6 +193,7 @@ config MACH_COLIBRI | |||
189 | config MACH_ZYLONITE | 193 | config MACH_ZYLONITE |
190 | bool "PXA3xx Development Platform (aka Zylonite)" | 194 | bool "PXA3xx Development Platform (aka Zylonite)" |
191 | select PXA3xx | 195 | select PXA3xx |
196 | select PXA_SSP | ||
192 | select HAVE_PWM | 197 | select HAVE_PWM |
193 | 198 | ||
194 | config MACH_LITTLETON | 199 | config MACH_LITTLETON |
@@ -207,15 +212,34 @@ config MACH_SAAR | |||
207 | select PXA930 | 212 | select PXA930 |
208 | 213 | ||
209 | config MACH_ARMCORE | 214 | config MACH_ARMCORE |
210 | bool "CompuLab CM-X270 modules" | 215 | bool "CompuLab CM-X255/CM-X270 modules" |
211 | select PXA27x | 216 | select PXA27x |
212 | select IWMMXT | 217 | select IWMMXT |
218 | select PXA25x | ||
219 | select PXA_SSP | ||
220 | |||
221 | config MACH_CM_X300 | ||
222 | bool "CompuLab CM-X300 modules" | ||
223 | select PXA3xx | ||
224 | select CPU_PXA300 | ||
213 | 225 | ||
214 | config MACH_MAGICIAN | 226 | config MACH_MAGICIAN |
215 | bool "Enable HTC Magician Support" | 227 | bool "Enable HTC Magician Support" |
216 | select PXA27x | 228 | select PXA27x |
217 | select IWMMXT | 229 | select IWMMXT |
218 | 230 | ||
231 | config MACH_MIOA701 | ||
232 | bool "Mitac Mio A701 Support" | ||
233 | select PXA27x | ||
234 | select IWMMXT | ||
235 | select LEDS_GPIO | ||
236 | select HAVE_PWM | ||
237 | select GPIO_SYSFS | ||
238 | help | ||
239 | Say Y here if you intend to run this kernel on a | ||
240 | MIO A701. Currently there is only basic support | ||
241 | for this PDA. | ||
242 | |||
219 | config MACH_PCM027 | 243 | config MACH_PCM027 |
220 | bool "Phytec phyCORE-PXA270 CPU module (PCM-027)" | 244 | bool "Phytec phyCORE-PXA270 CPU module (PCM-027)" |
221 | select PXA27x | 245 | select PXA27x |
@@ -256,6 +280,9 @@ config PCM990_DISPLAY_NONE | |||
256 | 280 | ||
257 | endchoice | 281 | endchoice |
258 | 282 | ||
283 | config MACH_AM200EPD | ||
284 | depends on MACH_GUMSTIX_F | ||
285 | bool "Enable AM200EPD board support" | ||
259 | 286 | ||
260 | config PXA_EZX | 287 | config PXA_EZX |
261 | bool "Motorola EZX Platform" | 288 | bool "Motorola EZX Platform" |
diff --git a/arch/arm/mach-pxa/Makefile b/arch/arm/mach-pxa/Makefile index fbedaaf74bd3..3b9454616d95 100644 --- a/arch/arm/mach-pxa/Makefile +++ b/arch/arm/mach-pxa/Makefile | |||
@@ -22,9 +22,11 @@ obj-$(CONFIG_CPU_PXA930) += pxa930.o | |||
22 | 22 | ||
23 | # Specific board support | 23 | # Specific board support |
24 | obj-$(CONFIG_ARCH_GUMSTIX) += gumstix.o | 24 | obj-$(CONFIG_ARCH_GUMSTIX) += gumstix.o |
25 | obj-$(CONFIG_MACH_AM200EPD) += am200epd.o | ||
25 | obj-$(CONFIG_ARCH_LUBBOCK) += lubbock.o | 26 | obj-$(CONFIG_ARCH_LUBBOCK) += lubbock.o |
26 | obj-$(CONFIG_MACH_LOGICPD_PXA270) += lpd270.o | 27 | obj-$(CONFIG_MACH_LOGICPD_PXA270) += lpd270.o |
27 | obj-$(CONFIG_MACH_MAINSTONE) += mainstone.o | 28 | obj-$(CONFIG_MACH_MAINSTONE) += mainstone.o |
29 | obj-$(CONFIG_MACH_MP900C) += mp900.o | ||
28 | obj-$(CONFIG_ARCH_PXA_IDP) += idp.o | 30 | obj-$(CONFIG_ARCH_PXA_IDP) += idp.o |
29 | obj-$(CONFIG_MACH_TRIZEPS4) += trizeps4.o | 31 | obj-$(CONFIG_MACH_TRIZEPS4) += trizeps4.o |
30 | obj-$(CONFIG_MACH_COLIBRI) += colibri.o | 32 | obj-$(CONFIG_MACH_COLIBRI) += colibri.o |
@@ -36,6 +38,7 @@ obj-$(CONFIG_MACH_PCM990_BASEBOARD) += pcm990-baseboard.o | |||
36 | obj-$(CONFIG_MACH_TOSA) += tosa.o | 38 | obj-$(CONFIG_MACH_TOSA) += tosa.o |
37 | obj-$(CONFIG_MACH_EM_X270) += em-x270.o | 39 | obj-$(CONFIG_MACH_EM_X270) += em-x270.o |
38 | obj-$(CONFIG_MACH_MAGICIAN) += magician.o | 40 | obj-$(CONFIG_MACH_MAGICIAN) += magician.o |
41 | obj-$(CONFIG_MACH_MIOA701) += mioa701.o mioa701_bootresume.o | ||
39 | obj-$(CONFIG_ARCH_PXA_ESERIES) += eseries.o eseries_udc.o | 42 | obj-$(CONFIG_ARCH_PXA_ESERIES) += eseries.o eseries_udc.o |
40 | obj-$(CONFIG_MACH_E740) += e740_lcd.o | 43 | obj-$(CONFIG_MACH_E740) += e740_lcd.o |
41 | obj-$(CONFIG_MACH_E750) += e750_lcd.o | 44 | obj-$(CONFIG_MACH_E750) += e750_lcd.o |
@@ -52,7 +55,8 @@ obj-$(CONFIG_MACH_LITTLETON) += littleton.o | |||
52 | obj-$(CONFIG_MACH_TAVOREVB) += tavorevb.o | 55 | obj-$(CONFIG_MACH_TAVOREVB) += tavorevb.o |
53 | obj-$(CONFIG_MACH_SAAR) += saar.o | 56 | obj-$(CONFIG_MACH_SAAR) += saar.o |
54 | 57 | ||
55 | obj-$(CONFIG_MACH_ARMCORE) += cm-x270.o | 58 | obj-$(CONFIG_MACH_ARMCORE) += cm-x2xx.o cm-x255.o cm-x270.o |
59 | obj-$(CONFIG_MACH_CM_X300) += cm-x300.o | ||
56 | obj-$(CONFIG_PXA_EZX) += ezx.o | 60 | obj-$(CONFIG_PXA_EZX) += ezx.o |
57 | 61 | ||
58 | # Support for blinky lights | 62 | # Support for blinky lights |
@@ -65,7 +69,7 @@ led-$(CONFIG_MACH_TRIZEPS4) += leds-trizeps4.o | |||
65 | obj-$(CONFIG_LEDS) += $(led-y) | 69 | obj-$(CONFIG_LEDS) += $(led-y) |
66 | 70 | ||
67 | ifeq ($(CONFIG_PCI),y) | 71 | ifeq ($(CONFIG_PCI),y) |
68 | obj-$(CONFIG_MACH_ARMCORE) += cm-x270-pci.o | 72 | obj-$(CONFIG_MACH_ARMCORE) += cm-x2xx-pci.o |
69 | endif | 73 | endif |
70 | 74 | ||
71 | obj-$(CONFIG_TOSA_BT) += tosa-bt.o | 75 | obj-$(CONFIG_TOSA_BT) += tosa-bt.o |
diff --git a/arch/arm/mach-pxa/am200epd.c b/arch/arm/mach-pxa/am200epd.c new file mode 100644 index 000000000000..b965085a37b9 --- /dev/null +++ b/arch/arm/mach-pxa/am200epd.c | |||
@@ -0,0 +1,374 @@ | |||
1 | /* | ||
2 | * am200epd.c -- Platform device for AM200 EPD kit | ||
3 | * | ||
4 | * Copyright (C) 2008, Jaya Kumar | ||
5 | * | ||
6 | * This file is subject to the terms and conditions of the GNU General Public | ||
7 | * License. See the file COPYING in the main directory of this archive for | ||
8 | * more details. | ||
9 | * | ||
10 | * Layout is based on skeletonfb.c by James Simmons and Geert Uytterhoeven. | ||
11 | * | ||
12 | * This work was made possible by help and equipment support from E-Ink | ||
13 | * Corporation. http://support.eink.com/community | ||
14 | * | ||
15 | * This driver is written to be used with the Metronome display controller. | ||
16 | * on the AM200 EPD prototype kit/development kit with an E-Ink 800x600 | ||
17 | * Vizplex EPD on a Gumstix board using the Lyre interface board. | ||
18 | * | ||
19 | */ | ||
20 | |||
21 | #include <linux/module.h> | ||
22 | #include <linux/kernel.h> | ||
23 | #include <linux/errno.h> | ||
24 | #include <linux/string.h> | ||
25 | #include <linux/delay.h> | ||
26 | #include <linux/interrupt.h> | ||
27 | #include <linux/fb.h> | ||
28 | #include <linux/init.h> | ||
29 | #include <linux/platform_device.h> | ||
30 | #include <linux/irq.h> | ||
31 | #include <linux/gpio.h> | ||
32 | |||
33 | #include <mach/pxafb.h> | ||
34 | |||
35 | #include <video/metronomefb.h> | ||
36 | |||
37 | static unsigned int panel_type = 6; | ||
38 | static struct platform_device *am200_device; | ||
39 | static struct metronome_board am200_board; | ||
40 | |||
41 | static struct pxafb_mode_info am200_fb_mode_9inch7 = { | ||
42 | .pixclock = 40000, | ||
43 | .xres = 1200, | ||
44 | .yres = 842, | ||
45 | .bpp = 16, | ||
46 | .hsync_len = 2, | ||
47 | .left_margin = 2, | ||
48 | .right_margin = 2, | ||
49 | .vsync_len = 1, | ||
50 | .upper_margin = 2, | ||
51 | .lower_margin = 25, | ||
52 | .sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, | ||
53 | }; | ||
54 | |||
55 | static struct pxafb_mode_info am200_fb_mode_8inch = { | ||
56 | .pixclock = 40000, | ||
57 | .xres = 1088, | ||
58 | .yres = 791, | ||
59 | .bpp = 16, | ||
60 | .hsync_len = 28, | ||
61 | .left_margin = 8, | ||
62 | .right_margin = 30, | ||
63 | .vsync_len = 8, | ||
64 | .upper_margin = 10, | ||
65 | .lower_margin = 8, | ||
66 | .sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, | ||
67 | }; | ||
68 | |||
69 | static struct pxafb_mode_info am200_fb_mode_6inch = { | ||
70 | .pixclock = 40189, | ||
71 | .xres = 832, | ||
72 | .yres = 622, | ||
73 | .bpp = 16, | ||
74 | .hsync_len = 28, | ||
75 | .left_margin = 34, | ||
76 | .right_margin = 34, | ||
77 | .vsync_len = 25, | ||
78 | .upper_margin = 0, | ||
79 | .lower_margin = 2, | ||
80 | .sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, | ||
81 | }; | ||
82 | |||
83 | static struct pxafb_mach_info am200_fb_info = { | ||
84 | .modes = &am200_fb_mode_6inch, | ||
85 | .num_modes = 1, | ||
86 | .lcd_conn = LCD_TYPE_COLOR_TFT | LCD_PCLK_EDGE_FALL | | ||
87 | LCD_AC_BIAS_FREQ(24), | ||
88 | }; | ||
89 | |||
90 | /* register offsets for gpio control */ | ||
91 | #define LED_GPIO_PIN 51 | ||
92 | #define STDBY_GPIO_PIN 48 | ||
93 | #define RST_GPIO_PIN 49 | ||
94 | #define RDY_GPIO_PIN 32 | ||
95 | #define ERR_GPIO_PIN 17 | ||
96 | #define PCBPWR_GPIO_PIN 16 | ||
97 | static int gpios[] = { LED_GPIO_PIN , STDBY_GPIO_PIN , RST_GPIO_PIN, | ||
98 | RDY_GPIO_PIN, ERR_GPIO_PIN, PCBPWR_GPIO_PIN }; | ||
99 | static char *gpio_names[] = { "LED" , "STDBY" , "RST", "RDY", "ERR", "PCBPWR" }; | ||
100 | |||
101 | static int am200_init_gpio_regs(struct metronomefb_par *par) | ||
102 | { | ||
103 | int i; | ||
104 | int err; | ||
105 | |||
106 | for (i = 0; i < ARRAY_SIZE(gpios); i++) { | ||
107 | err = gpio_request(gpios[i], gpio_names[i]); | ||
108 | if (err) { | ||
109 | dev_err(&am200_device->dev, "failed requesting " | ||
110 | "gpio %s, err=%d\n", gpio_names[i], err); | ||
111 | goto err_req_gpio; | ||
112 | } | ||
113 | } | ||
114 | |||
115 | gpio_direction_output(LED_GPIO_PIN, 0); | ||
116 | gpio_direction_output(STDBY_GPIO_PIN, 0); | ||
117 | gpio_direction_output(RST_GPIO_PIN, 0); | ||
118 | |||
119 | gpio_direction_input(RDY_GPIO_PIN); | ||
120 | gpio_direction_input(ERR_GPIO_PIN); | ||
121 | |||
122 | gpio_direction_output(PCBPWR_GPIO_PIN, 0); | ||
123 | |||
124 | return 0; | ||
125 | |||
126 | err_req_gpio: | ||
127 | while (i > 0) | ||
128 | gpio_free(gpios[i--]); | ||
129 | |||
130 | return err; | ||
131 | } | ||
132 | |||
133 | static void am200_cleanup(struct metronomefb_par *par) | ||
134 | { | ||
135 | int i; | ||
136 | |||
137 | free_irq(IRQ_GPIO(RDY_GPIO_PIN), par); | ||
138 | |||
139 | for (i = 0; i < ARRAY_SIZE(gpios); i++) | ||
140 | gpio_free(gpios[i]); | ||
141 | } | ||
142 | |||
143 | static int am200_share_video_mem(struct fb_info *info) | ||
144 | { | ||
145 | /* rough check if this is our desired fb and not something else */ | ||
146 | if ((info->var.xres != am200_fb_info.modes->xres) | ||
147 | || (info->var.yres != am200_fb_info.modes->yres)) | ||
148 | return 0; | ||
149 | |||
150 | /* we've now been notified that we have our new fb */ | ||
151 | am200_board.metromem = info->screen_base; | ||
152 | am200_board.host_fbinfo = info; | ||
153 | |||
154 | /* try to refcount host drv since we are the consumer after this */ | ||
155 | if (!try_module_get(info->fbops->owner)) | ||
156 | return -ENODEV; | ||
157 | |||
158 | return 0; | ||
159 | } | ||
160 | |||
161 | static int am200_unshare_video_mem(struct fb_info *info) | ||
162 | { | ||
163 | dev_dbg(&am200_device->dev, "ENTER %s\n", __func__); | ||
164 | |||
165 | if (info != am200_board.host_fbinfo) | ||
166 | return 0; | ||
167 | |||
168 | module_put(am200_board.host_fbinfo->fbops->owner); | ||
169 | return 0; | ||
170 | } | ||
171 | |||
172 | static int am200_fb_notifier_callback(struct notifier_block *self, | ||
173 | unsigned long event, void *data) | ||
174 | { | ||
175 | struct fb_event *evdata = data; | ||
176 | struct fb_info *info = evdata->info; | ||
177 | |||
178 | dev_dbg(&am200_device->dev, "ENTER %s\n", __func__); | ||
179 | |||
180 | if (event == FB_EVENT_FB_REGISTERED) | ||
181 | return am200_share_video_mem(info); | ||
182 | else if (event == FB_EVENT_FB_UNREGISTERED) | ||
183 | return am200_unshare_video_mem(info); | ||
184 | |||
185 | return 0; | ||
186 | } | ||
187 | |||
188 | static struct notifier_block am200_fb_notif = { | ||
189 | .notifier_call = am200_fb_notifier_callback, | ||
190 | }; | ||
191 | |||
192 | /* this gets called as part of our init. these steps must be done now so | ||
193 | * that we can use set_pxa_fb_info */ | ||
194 | static void __init am200_presetup_fb(void) | ||
195 | { | ||
196 | int fw; | ||
197 | int fh; | ||
198 | int padding_size; | ||
199 | int totalsize; | ||
200 | |||
201 | switch (panel_type) { | ||
202 | case 6: | ||
203 | am200_fb_info.modes = &am200_fb_mode_6inch; | ||
204 | break; | ||
205 | case 8: | ||
206 | am200_fb_info.modes = &am200_fb_mode_8inch; | ||
207 | break; | ||
208 | case 97: | ||
209 | am200_fb_info.modes = &am200_fb_mode_9inch7; | ||
210 | break; | ||
211 | default: | ||
212 | dev_err(&am200_device->dev, "invalid panel_type selection," | ||
213 | " setting to 6\n"); | ||
214 | am200_fb_info.modes = &am200_fb_mode_6inch; | ||
215 | break; | ||
216 | } | ||
217 | |||
218 | /* the frame buffer is divided as follows: | ||
219 | command | CRC | padding | ||
220 | 16kb waveform data | CRC | padding | ||
221 | image data | CRC | ||
222 | */ | ||
223 | |||
224 | fw = am200_fb_info.modes->xres; | ||
225 | fh = am200_fb_info.modes->yres; | ||
226 | |||
227 | /* waveform must be 16k + 2 for checksum */ | ||
228 | am200_board.wfm_size = roundup(16*1024 + 2, fw); | ||
229 | |||
230 | padding_size = PAGE_SIZE + (4 * fw); | ||
231 | |||
232 | /* total is 1 cmd , 1 wfm, padding and image */ | ||
233 | totalsize = fw + am200_board.wfm_size + padding_size + (fw*fh); | ||
234 | |||
235 | /* save this off because we're manipulating fw after this and | ||
236 | * we'll need it when we're ready to setup the framebuffer */ | ||
237 | am200_board.fw = fw; | ||
238 | am200_board.fh = fh; | ||
239 | |||
240 | /* the reason we do this adjustment is because we want to acquire | ||
241 | * more framebuffer memory without imposing custom awareness on the | ||
242 | * underlying pxafb driver */ | ||
243 | am200_fb_info.modes->yres = DIV_ROUND_UP(totalsize, fw); | ||
244 | |||
245 | /* we divide since we told the LCD controller we're 16bpp */ | ||
246 | am200_fb_info.modes->xres /= 2; | ||
247 | |||
248 | set_pxa_fb_info(&am200_fb_info); | ||
249 | |||
250 | } | ||
251 | |||
252 | /* this gets called by metronomefb as part of its init, in our case, we | ||
253 | * have already completed initial framebuffer init in presetup_fb so we | ||
254 | * can just setup the fb access pointers */ | ||
255 | static int am200_setup_fb(struct metronomefb_par *par) | ||
256 | { | ||
257 | int fw; | ||
258 | int fh; | ||
259 | |||
260 | fw = am200_board.fw; | ||
261 | fh = am200_board.fh; | ||
262 | |||
263 | /* metromem was set up by the notifier in share_video_mem so now | ||
264 | * we can use its value to calculate the other entries */ | ||
265 | par->metromem_cmd = (struct metromem_cmd *) am200_board.metromem; | ||
266 | par->metromem_wfm = am200_board.metromem + fw; | ||
267 | par->metromem_img = par->metromem_wfm + am200_board.wfm_size; | ||
268 | par->metromem_img_csum = (u16 *) (par->metromem_img + (fw * fh)); | ||
269 | par->metromem_dma = am200_board.host_fbinfo->fix.smem_start; | ||
270 | |||
271 | return 0; | ||
272 | } | ||
273 | |||
274 | static int am200_get_panel_type(void) | ||
275 | { | ||
276 | return panel_type; | ||
277 | } | ||
278 | |||
279 | static irqreturn_t am200_handle_irq(int irq, void *dev_id) | ||
280 | { | ||
281 | struct metronomefb_par *par = dev_id; | ||
282 | |||
283 | wake_up_interruptible(&par->waitq); | ||
284 | return IRQ_HANDLED; | ||
285 | } | ||
286 | |||
287 | static int am200_setup_irq(struct fb_info *info) | ||
288 | { | ||
289 | int ret; | ||
290 | |||
291 | ret = request_irq(IRQ_GPIO(RDY_GPIO_PIN), am200_handle_irq, | ||
292 | IRQF_DISABLED|IRQF_TRIGGER_FALLING, | ||
293 | "AM200", info->par); | ||
294 | if (ret) | ||
295 | dev_err(&am200_device->dev, "request_irq failed: %d\n", ret); | ||
296 | |||
297 | return ret; | ||
298 | } | ||
299 | |||
300 | static void am200_set_rst(struct metronomefb_par *par, int state) | ||
301 | { | ||
302 | gpio_set_value(RST_GPIO_PIN, state); | ||
303 | } | ||
304 | |||
305 | static void am200_set_stdby(struct metronomefb_par *par, int state) | ||
306 | { | ||
307 | gpio_set_value(STDBY_GPIO_PIN, state); | ||
308 | } | ||
309 | |||
310 | static int am200_wait_event(struct metronomefb_par *par) | ||
311 | { | ||
312 | return wait_event_timeout(par->waitq, gpio_get_value(RDY_GPIO_PIN), HZ); | ||
313 | } | ||
314 | |||
315 | static int am200_wait_event_intr(struct metronomefb_par *par) | ||
316 | { | ||
317 | return wait_event_interruptible_timeout(par->waitq, | ||
318 | gpio_get_value(RDY_GPIO_PIN), HZ); | ||
319 | } | ||
320 | |||
321 | static struct metronome_board am200_board = { | ||
322 | .owner = THIS_MODULE, | ||
323 | .setup_irq = am200_setup_irq, | ||
324 | .setup_io = am200_init_gpio_regs, | ||
325 | .setup_fb = am200_setup_fb, | ||
326 | .set_rst = am200_set_rst, | ||
327 | .set_stdby = am200_set_stdby, | ||
328 | .met_wait_event = am200_wait_event, | ||
329 | .met_wait_event_intr = am200_wait_event_intr, | ||
330 | .get_panel_type = am200_get_panel_type, | ||
331 | .cleanup = am200_cleanup, | ||
332 | }; | ||
333 | |||
334 | static int __init am200_init(void) | ||
335 | { | ||
336 | int ret; | ||
337 | |||
338 | /* before anything else, we request notification for any fb | ||
339 | * creation events */ | ||
340 | fb_register_client(&am200_fb_notif); | ||
341 | |||
342 | /* request our platform independent driver */ | ||
343 | request_module("metronomefb"); | ||
344 | |||
345 | am200_device = platform_device_alloc("metronomefb", -1); | ||
346 | if (!am200_device) | ||
347 | return -ENOMEM; | ||
348 | |||
349 | /* the am200_board that will be seen by metronomefb is a copy */ | ||
350 | platform_device_add_data(am200_device, &am200_board, | ||
351 | sizeof(am200_board)); | ||
352 | |||
353 | /* this _add binds metronomefb to am200. metronomefb refcounts am200 */ | ||
354 | ret = platform_device_add(am200_device); | ||
355 | |||
356 | if (ret) { | ||
357 | platform_device_put(am200_device); | ||
358 | fb_unregister_client(&am200_fb_notif); | ||
359 | return ret; | ||
360 | } | ||
361 | |||
362 | am200_presetup_fb(); | ||
363 | |||
364 | return 0; | ||
365 | } | ||
366 | |||
367 | module_param(panel_type, uint, 0); | ||
368 | MODULE_PARM_DESC(panel_type, "Select the panel type: 6, 8, 97"); | ||
369 | |||
370 | module_init(am200_init); | ||
371 | |||
372 | MODULE_DESCRIPTION("board driver for am200 metronome epd kit"); | ||
373 | MODULE_AUTHOR("Jaya Kumar"); | ||
374 | MODULE_LICENSE("GPL"); | ||
diff --git a/arch/arm/mach-pxa/cm-x255.c b/arch/arm/mach-pxa/cm-x255.c new file mode 100644 index 000000000000..83a4cdf08176 --- /dev/null +++ b/arch/arm/mach-pxa/cm-x255.c | |||
@@ -0,0 +1,258 @@ | |||
1 | /* | ||
2 | * linux/arch/arm/mach-pxa/cm-x255.c | ||
3 | * | ||
4 | * Copyright (C) 2007, 2008 CompuLab, Ltd. | ||
5 | * Mike Rapoport <mike@compulab.co.il> | ||
6 | * | ||
7 | * This program is free software; you can redistribute it and/or modify | ||
8 | * it under the terms of the GNU General Public License version 2 as | ||
9 | * published by the Free Software Foundation. | ||
10 | */ | ||
11 | |||
12 | #include <linux/platform_device.h> | ||
13 | #include <linux/irq.h> | ||
14 | #include <linux/gpio.h> | ||
15 | #include <linux/mtd/partitions.h> | ||
16 | #include <linux/mtd/physmap.h> | ||
17 | #include <linux/mtd/nand-gpio.h> | ||
18 | |||
19 | #include <linux/spi/spi.h> | ||
20 | |||
21 | #include <asm/mach/arch.h> | ||
22 | #include <asm/mach-types.h> | ||
23 | #include <asm/mach/map.h> | ||
24 | |||
25 | #include <mach/pxa2xx-regs.h> | ||
26 | #include <mach/mfp-pxa25x.h> | ||
27 | #include <mach/pxa2xx_spi.h> | ||
28 | #include <mach/bitfield.h> | ||
29 | |||
30 | #include "generic.h" | ||
31 | |||
32 | #define GPIO_NAND_CS (5) | ||
33 | #define GPIO_NAND_ALE (4) | ||
34 | #define GPIO_NAND_CLE (3) | ||
35 | #define GPIO_NAND_RB (10) | ||
36 | |||
37 | static unsigned long cmx255_pin_config[] = { | ||
38 | /* AC'97 */ | ||
39 | GPIO28_AC97_BITCLK, | ||
40 | GPIO29_AC97_SDATA_IN_0, | ||
41 | GPIO30_AC97_SDATA_OUT, | ||
42 | GPIO31_AC97_SYNC, | ||
43 | |||
44 | /* BTUART */ | ||
45 | GPIO42_BTUART_RXD, | ||
46 | GPIO43_BTUART_TXD, | ||
47 | GPIO44_BTUART_CTS, | ||
48 | GPIO45_BTUART_RTS, | ||
49 | |||
50 | /* STUART */ | ||
51 | GPIO46_STUART_RXD, | ||
52 | GPIO47_STUART_TXD, | ||
53 | |||
54 | /* LCD */ | ||
55 | GPIO58_LCD_LDD_0, | ||
56 | GPIO59_LCD_LDD_1, | ||
57 | GPIO60_LCD_LDD_2, | ||
58 | GPIO61_LCD_LDD_3, | ||
59 | GPIO62_LCD_LDD_4, | ||
60 | GPIO63_LCD_LDD_5, | ||
61 | GPIO64_LCD_LDD_6, | ||
62 | GPIO65_LCD_LDD_7, | ||
63 | GPIO66_LCD_LDD_8, | ||
64 | GPIO67_LCD_LDD_9, | ||
65 | GPIO68_LCD_LDD_10, | ||
66 | GPIO69_LCD_LDD_11, | ||
67 | GPIO70_LCD_LDD_12, | ||
68 | GPIO71_LCD_LDD_13, | ||
69 | GPIO72_LCD_LDD_14, | ||
70 | GPIO73_LCD_LDD_15, | ||
71 | GPIO74_LCD_FCLK, | ||
72 | GPIO75_LCD_LCLK, | ||
73 | GPIO76_LCD_PCLK, | ||
74 | GPIO77_LCD_BIAS, | ||
75 | |||
76 | /* SSP1 */ | ||
77 | GPIO23_SSP1_SCLK, | ||
78 | GPIO24_SSP1_SFRM, | ||
79 | GPIO25_SSP1_TXD, | ||
80 | GPIO26_SSP1_RXD, | ||
81 | |||
82 | /* SSP2 */ | ||
83 | GPIO81_SSP2_CLK_OUT, | ||
84 | GPIO82_SSP2_FRM_OUT, | ||
85 | GPIO83_SSP2_TXD, | ||
86 | GPIO84_SSP2_RXD, | ||
87 | |||
88 | /* PC Card */ | ||
89 | GPIO48_nPOE, | ||
90 | GPIO49_nPWE, | ||
91 | GPIO50_nPIOR, | ||
92 | GPIO51_nPIOW, | ||
93 | GPIO52_nPCE_1, | ||
94 | GPIO53_nPCE_2, | ||
95 | GPIO54_nPSKTSEL, | ||
96 | GPIO55_nPREG, | ||
97 | GPIO56_nPWAIT, | ||
98 | GPIO57_nIOIS16, | ||
99 | |||
100 | /* SDRAM and local bus */ | ||
101 | GPIO15_nCS_1, | ||
102 | GPIO78_nCS_2, | ||
103 | GPIO79_nCS_3, | ||
104 | GPIO80_nCS_4, | ||
105 | GPIO33_nCS_5, | ||
106 | GPIO18_RDY, | ||
107 | |||
108 | /* GPIO */ | ||
109 | GPIO0_GPIO | WAKEUP_ON_EDGE_BOTH, | ||
110 | GPIO9_GPIO, /* PC card reset */ | ||
111 | |||
112 | /* NAND controls */ | ||
113 | GPIO5_GPIO | MFP_LPM_DRIVE_HIGH, /* NAND CE# */ | ||
114 | GPIO4_GPIO | MFP_LPM_DRIVE_LOW, /* NAND ALE */ | ||
115 | GPIO3_GPIO | MFP_LPM_DRIVE_LOW, /* NAND CLE */ | ||
116 | GPIO10_GPIO, /* NAND Ready/Busy */ | ||
117 | |||
118 | /* interrupts */ | ||
119 | GPIO22_GPIO, /* DM9000 interrupt */ | ||
120 | }; | ||
121 | |||
122 | #if defined(CONFIG_SPI_PXA2XX) | ||
123 | static struct pxa2xx_spi_master pxa_ssp_master_info = { | ||
124 | .num_chipselect = 1, | ||
125 | }; | ||
126 | |||
127 | static struct spi_board_info spi_board_info[] __initdata = { | ||
128 | [0] = { | ||
129 | .modalias = "rtc-max6902", | ||
130 | .max_speed_hz = 1000000, | ||
131 | .bus_num = 1, | ||
132 | .chip_select = 0, | ||
133 | }, | ||
134 | }; | ||
135 | |||
136 | static void __init cmx255_init_rtc(void) | ||
137 | { | ||
138 | pxa2xx_set_spi_info(1, &pxa_ssp_master_info); | ||
139 | spi_register_board_info(ARRAY_AND_SIZE(spi_board_info)); | ||
140 | } | ||
141 | #else | ||
142 | static inline void cmx255_init_rtc(void) {} | ||
143 | #endif | ||
144 | |||
145 | #if defined(CONFIG_MTD_PHYSMAP) || defined(CONFIG_MTD_PHYSMAP_MODULE) | ||
146 | static struct mtd_partition cmx255_nor_partitions[] = { | ||
147 | { | ||
148 | .name = "ARMmon", | ||
149 | .size = 0x00030000, | ||
150 | .offset = 0, | ||
151 | .mask_flags = MTD_WRITEABLE /* force read-only */ | ||
152 | } , { | ||
153 | .name = "ARMmon setup block", | ||
154 | .size = 0x00010000, | ||
155 | .offset = MTDPART_OFS_APPEND, | ||
156 | .mask_flags = MTD_WRITEABLE /* force read-only */ | ||
157 | } , { | ||
158 | .name = "kernel", | ||
159 | .size = 0x00160000, | ||
160 | .offset = MTDPART_OFS_APPEND, | ||
161 | } , { | ||
162 | .name = "ramdisk", | ||
163 | .size = MTDPART_SIZ_FULL, | ||
164 | .offset = MTDPART_OFS_APPEND | ||
165 | } | ||
166 | }; | ||
167 | |||
168 | static struct physmap_flash_data cmx255_nor_flash_data[] = { | ||
169 | { | ||
170 | .width = 2, /* bankwidth in bytes */ | ||
171 | .parts = cmx255_nor_partitions, | ||
172 | .nr_parts = ARRAY_SIZE(cmx255_nor_partitions) | ||
173 | } | ||
174 | }; | ||
175 | |||
176 | static struct resource cmx255_nor_resource = { | ||
177 | .start = PXA_CS0_PHYS, | ||
178 | .end = PXA_CS0_PHYS + SZ_8M - 1, | ||
179 | .flags = IORESOURCE_MEM, | ||
180 | }; | ||
181 | |||
182 | static struct platform_device cmx255_nor = { | ||
183 | .name = "physmap-flash", | ||
184 | .id = -1, | ||
185 | .dev = { | ||
186 | .platform_data = cmx255_nor_flash_data, | ||
187 | }, | ||
188 | .resource = &cmx255_nor_resource, | ||
189 | .num_resources = 1, | ||
190 | }; | ||
191 | |||
192 | static void __init cmx255_init_nor(void) | ||
193 | { | ||
194 | platform_device_register(&cmx255_nor); | ||
195 | } | ||
196 | #else | ||
197 | static inline void cmx255_init_nor(void) {} | ||
198 | #endif | ||
199 | |||
200 | #if defined(CONFIG_MTD_NAND_GPIO) || defined(CONFIG_MTD_NAND_GPIO_MODULE) | ||
201 | static struct resource cmx255_nand_resource[] = { | ||
202 | [0] = { | ||
203 | .start = PXA_CS1_PHYS, | ||
204 | .end = PXA_CS1_PHYS + 11, | ||
205 | .flags = IORESOURCE_MEM, | ||
206 | }, | ||
207 | [1] = { | ||
208 | .start = PXA_CS5_PHYS, | ||
209 | .end = PXA_CS5_PHYS + 3, | ||
210 | .flags = IORESOURCE_MEM, | ||
211 | }, | ||
212 | }; | ||
213 | |||
214 | static struct mtd_partition cmx255_nand_parts[] = { | ||
215 | [0] = { | ||
216 | .name = "cmx255-nand", | ||
217 | .size = MTDPART_SIZ_FULL, | ||
218 | .offset = 0, | ||
219 | }, | ||
220 | }; | ||
221 | |||
222 | static struct gpio_nand_platdata cmx255_nand_platdata = { | ||
223 | .gpio_nce = GPIO_NAND_CS, | ||
224 | .gpio_cle = GPIO_NAND_CLE, | ||
225 | .gpio_ale = GPIO_NAND_ALE, | ||
226 | .gpio_rdy = GPIO_NAND_RB, | ||
227 | .gpio_nwp = -1, | ||
228 | .parts = cmx255_nand_parts, | ||
229 | .num_parts = ARRAY_SIZE(cmx255_nand_parts), | ||
230 | .chip_delay = 25, | ||
231 | }; | ||
232 | |||
233 | static struct platform_device cmx255_nand = { | ||
234 | .name = "gpio-nand", | ||
235 | .num_resources = ARRAY_SIZE(cmx255_nand_resource), | ||
236 | .resource = cmx255_nand_resource, | ||
237 | .id = -1, | ||
238 | .dev = { | ||
239 | .platform_data = &cmx255_nand_platdata, | ||
240 | } | ||
241 | }; | ||
242 | |||
243 | static void __init cmx255_init_nand(void) | ||
244 | { | ||
245 | platform_device_register(&cmx255_nand); | ||
246 | } | ||
247 | #else | ||
248 | static inline void cmx255_init_nand(void) {} | ||
249 | #endif | ||
250 | |||
251 | void __init cmx255_init(void) | ||
252 | { | ||
253 | pxa2xx_mfp_config(ARRAY_AND_SIZE(cmx255_pin_config)); | ||
254 | |||
255 | cmx255_init_rtc(); | ||
256 | cmx255_init_nor(); | ||
257 | cmx255_init_nand(); | ||
258 | } | ||
diff --git a/arch/arm/mach-pxa/cm-x270-pci.h b/arch/arm/mach-pxa/cm-x270-pci.h deleted file mode 100644 index 48f532f4cb51..000000000000 --- a/arch/arm/mach-pxa/cm-x270-pci.h +++ /dev/null | |||
@@ -1,13 +0,0 @@ | |||
1 | extern void __cmx270_pci_init_irq(int irq_gpio); | ||
2 | extern void __cmx270_pci_suspend(void); | ||
3 | extern void __cmx270_pci_resume(void); | ||
4 | |||
5 | #ifdef CONFIG_PCI | ||
6 | #define cmx270_pci_init_irq(x) __cmx270_pci_init_irq(x) | ||
7 | #define cmx270_pci_suspend(x) __cmx270_pci_suspend(x) | ||
8 | #define cmx270_pci_resume(x) __cmx270_pci_resume(x) | ||
9 | #else | ||
10 | #define cmx270_pci_init_irq(x) do {} while (0) | ||
11 | #define cmx270_pci_suspend(x) do {} while (0) | ||
12 | #define cmx270_pci_resume(x) do {} while (0) | ||
13 | #endif | ||
diff --git a/arch/arm/mach-pxa/cm-x270.c b/arch/arm/mach-pxa/cm-x270.c index af003a269534..102a43186618 100644 --- a/arch/arm/mach-pxa/cm-x270.c +++ b/arch/arm/mach-pxa/cm-x270.c | |||
@@ -14,46 +14,22 @@ | |||
14 | #include <linux/irq.h> | 14 | #include <linux/irq.h> |
15 | #include <linux/gpio.h> | 15 | #include <linux/gpio.h> |
16 | 16 | ||
17 | #include <linux/dm9000.h> | ||
18 | #include <linux/rtc-v3020.h> | 17 | #include <linux/rtc-v3020.h> |
19 | #include <video/mbxfb.h> | 18 | #include <video/mbxfb.h> |
20 | #include <linux/leds.h> | ||
21 | 19 | ||
22 | #include <asm/mach/arch.h> | ||
23 | #include <asm/mach-types.h> | ||
24 | #include <asm/mach/map.h> | ||
25 | |||
26 | #include <mach/pxa2xx-regs.h> | ||
27 | #include <mach/mfp-pxa27x.h> | 20 | #include <mach/mfp-pxa27x.h> |
28 | #include <mach/pxa-regs.h> | ||
29 | #include <mach/audio.h> | ||
30 | #include <mach/pxafb.h> | ||
31 | #include <mach/ohci.h> | 21 | #include <mach/ohci.h> |
32 | #include <mach/mmc.h> | 22 | #include <mach/mmc.h> |
33 | #include <mach/bitfield.h> | ||
34 | |||
35 | #include <asm/hardware/it8152.h> | ||
36 | 23 | ||
37 | #include "generic.h" | 24 | #include "generic.h" |
38 | #include "cm-x270-pci.h" | ||
39 | |||
40 | /* virtual addresses for statically mapped regions */ | ||
41 | #define CMX270_VIRT_BASE (0xe8000000) | ||
42 | #define CMX270_IT8152_VIRT (CMX270_VIRT_BASE) | ||
43 | 25 | ||
26 | /* physical address if local-bus attached devices */ | ||
44 | #define RTC_PHYS_BASE (PXA_CS1_PHYS + (5 << 22)) | 27 | #define RTC_PHYS_BASE (PXA_CS1_PHYS + (5 << 22)) |
45 | #define DM9000_PHYS_BASE (PXA_CS1_PHYS + (6 << 22)) | ||
46 | 28 | ||
47 | /* GPIO IRQ usage */ | 29 | /* GPIO IRQ usage */ |
48 | #define GPIO10_ETHIRQ (10) | ||
49 | #define GPIO22_IT8152_IRQ (22) | ||
50 | #define GPIO83_MMC_IRQ (83) | 30 | #define GPIO83_MMC_IRQ (83) |
51 | #define GPIO95_GFXIRQ (95) | ||
52 | 31 | ||
53 | #define CMX270_ETHIRQ IRQ_GPIO(GPIO10_ETHIRQ) | ||
54 | #define CMX270_IT8152_IRQ IRQ_GPIO(GPIO22_IT8152_IRQ) | ||
55 | #define CMX270_MMC_IRQ IRQ_GPIO(GPIO83_MMC_IRQ) | 32 | #define CMX270_MMC_IRQ IRQ_GPIO(GPIO83_MMC_IRQ) |
56 | #define CMX270_GFXIRQ IRQ_GPIO(GPIO95_GFXIRQ) | ||
57 | 33 | ||
58 | /* MMC power enable */ | 34 | /* MMC power enable */ |
59 | #define GPIO105_MMC_POWER (105) | 35 | #define GPIO105_MMC_POWER (105) |
@@ -157,62 +133,6 @@ static unsigned long cmx270_pin_config[] = { | |||
157 | GPIO83_GPIO, /* MMC card detect */ | 133 | GPIO83_GPIO, /* MMC card detect */ |
158 | }; | 134 | }; |
159 | 135 | ||
160 | #if defined(CONFIG_DM9000) || defined(CONFIG_DM9000_MODULE) | ||
161 | static struct resource cmx270_dm9000_resource[] = { | ||
162 | [0] = { | ||
163 | .start = DM9000_PHYS_BASE, | ||
164 | .end = DM9000_PHYS_BASE + 4, | ||
165 | .flags = IORESOURCE_MEM, | ||
166 | }, | ||
167 | [1] = { | ||
168 | .start = DM9000_PHYS_BASE + 8, | ||
169 | .end = DM9000_PHYS_BASE + 8 + 500, | ||
170 | .flags = IORESOURCE_MEM, | ||
171 | }, | ||
172 | [2] = { | ||
173 | .start = CMX270_ETHIRQ, | ||
174 | .end = CMX270_ETHIRQ, | ||
175 | .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHEDGE, | ||
176 | } | ||
177 | }; | ||
178 | |||
179 | static struct dm9000_plat_data cmx270_dm9000_platdata = { | ||
180 | .flags = DM9000_PLATF_32BITONLY, | ||
181 | }; | ||
182 | |||
183 | static struct platform_device cmx270_dm9000_device = { | ||
184 | .name = "dm9000", | ||
185 | .id = 0, | ||
186 | .num_resources = ARRAY_SIZE(cmx270_dm9000_resource), | ||
187 | .resource = cmx270_dm9000_resource, | ||
188 | .dev = { | ||
189 | .platform_data = &cmx270_dm9000_platdata, | ||
190 | } | ||
191 | }; | ||
192 | |||
193 | static void __init cmx270_init_dm9000(void) | ||
194 | { | ||
195 | platform_device_register(&cmx270_dm9000_device); | ||
196 | } | ||
197 | #else | ||
198 | static inline void cmx270_init_dm9000(void) {} | ||
199 | #endif | ||
200 | |||
201 | /* UCB1400 touchscreen controller */ | ||
202 | #if defined(CONFIG_TOUCHSCREEN_UCB1400) || defined(CONFIG_TOUCHSCREEN_UCB1400_MODULE) | ||
203 | static struct platform_device cmx270_ts_device = { | ||
204 | .name = "ucb1400_ts", | ||
205 | .id = -1, | ||
206 | }; | ||
207 | |||
208 | static void __init cmx270_init_touchscreen(void) | ||
209 | { | ||
210 | platform_device_register(&cmx270_ts_device); | ||
211 | } | ||
212 | #else | ||
213 | static inline void cmx270_init_touchscreen(void) {} | ||
214 | #endif | ||
215 | |||
216 | /* V3020 RTC */ | 136 | /* V3020 RTC */ |
217 | #if defined(CONFIG_RTC_DRV_V3020) || defined(CONFIG_RTC_DRV_V3020_MODULE) | 137 | #if defined(CONFIG_RTC_DRV_V3020) || defined(CONFIG_RTC_DRV_V3020_MODULE) |
218 | static struct resource cmx270_v3020_resource[] = { | 138 | static struct resource cmx270_v3020_resource[] = { |
@@ -242,45 +162,7 @@ static void __init cmx270_init_rtc(void) | |||
242 | platform_device_register(&cmx270_rtc_device); | 162 | platform_device_register(&cmx270_rtc_device); |
243 | } | 163 | } |
244 | #else | 164 | #else |
245 | static inline void cmx270_init_rtc(void) {} | 165 | static inline void cmx2xx_init_rtc(void) {} |
246 | #endif | ||
247 | |||
248 | /* CM-X270 LEDs */ | ||
249 | #if defined(CONFIG_LEDS_GPIO) || defined(CONFIG_LEDS_GPIO_MODULE) | ||
250 | static struct gpio_led cmx270_leds[] = { | ||
251 | [0] = { | ||
252 | .name = "cm-x270:red", | ||
253 | .default_trigger = "nand-disk", | ||
254 | .gpio = 93, | ||
255 | .active_low = 1, | ||
256 | }, | ||
257 | [1] = { | ||
258 | .name = "cm-x270:green", | ||
259 | .default_trigger = "heartbeat", | ||
260 | .gpio = 94, | ||
261 | .active_low = 1, | ||
262 | }, | ||
263 | }; | ||
264 | |||
265 | static struct gpio_led_platform_data cmx270_gpio_led_pdata = { | ||
266 | .num_leds = ARRAY_SIZE(cmx270_leds), | ||
267 | .leds = cmx270_leds, | ||
268 | }; | ||
269 | |||
270 | static struct platform_device cmx270_led_device = { | ||
271 | .name = "leds-gpio", | ||
272 | .id = -1, | ||
273 | .dev = { | ||
274 | .platform_data = &cmx270_gpio_led_pdata, | ||
275 | }, | ||
276 | }; | ||
277 | |||
278 | static void __init cmx270_init_leds(void) | ||
279 | { | ||
280 | platform_device_register(&cmx270_led_device); | ||
281 | } | ||
282 | #else | ||
283 | static inline void cmx270_init_leds(void) {} | ||
284 | #endif | 166 | #endif |
285 | 167 | ||
286 | /* 2700G graphics */ | 168 | /* 2700G graphics */ |
@@ -373,224 +255,6 @@ static void __init cmx270_init_2700G(void) | |||
373 | static inline void cmx270_init_2700G(void) {} | 255 | static inline void cmx270_init_2700G(void) {} |
374 | #endif | 256 | #endif |
375 | 257 | ||
376 | #if defined(CONFIG_FB_PXA) || defined(CONFIG_FB_PXA_MODULE) | ||
377 | /* | ||
378 | Display definitions | ||
379 | keep these for backwards compatibility, although symbolic names (as | ||
380 | e.g. in lpd270.c) looks better | ||
381 | */ | ||
382 | #define MTYPE_STN320x240 0 | ||
383 | #define MTYPE_TFT640x480 1 | ||
384 | #define MTYPE_CRT640x480 2 | ||
385 | #define MTYPE_CRT800x600 3 | ||
386 | #define MTYPE_TFT320x240 6 | ||
387 | #define MTYPE_STN640x480 7 | ||
388 | |||
389 | static struct pxafb_mode_info generic_stn_320x240_mode = { | ||
390 | .pixclock = 76923, | ||
391 | .bpp = 8, | ||
392 | .xres = 320, | ||
393 | .yres = 240, | ||
394 | .hsync_len = 3, | ||
395 | .vsync_len = 2, | ||
396 | .left_margin = 3, | ||
397 | .upper_margin = 0, | ||
398 | .right_margin = 3, | ||
399 | .lower_margin = 0, | ||
400 | .sync = (FB_SYNC_HOR_HIGH_ACT | | ||
401 | FB_SYNC_VERT_HIGH_ACT), | ||
402 | .cmap_greyscale = 0, | ||
403 | }; | ||
404 | |||
405 | static struct pxafb_mach_info generic_stn_320x240 = { | ||
406 | .modes = &generic_stn_320x240_mode, | ||
407 | .num_modes = 1, | ||
408 | .lccr0 = 0, | ||
409 | .lccr3 = (LCCR3_PixClkDiv(0x03) | | ||
410 | LCCR3_Acb(0xff) | | ||
411 | LCCR3_PCP), | ||
412 | .cmap_inverse = 0, | ||
413 | .cmap_static = 0, | ||
414 | }; | ||
415 | |||
416 | static struct pxafb_mode_info generic_tft_640x480_mode = { | ||
417 | .pixclock = 38461, | ||
418 | .bpp = 8, | ||
419 | .xres = 640, | ||
420 | .yres = 480, | ||
421 | .hsync_len = 60, | ||
422 | .vsync_len = 2, | ||
423 | .left_margin = 70, | ||
424 | .upper_margin = 10, | ||
425 | .right_margin = 70, | ||
426 | .lower_margin = 5, | ||
427 | .sync = 0, | ||
428 | .cmap_greyscale = 0, | ||
429 | }; | ||
430 | |||
431 | static struct pxafb_mach_info generic_tft_640x480 = { | ||
432 | .modes = &generic_tft_640x480_mode, | ||
433 | .num_modes = 1, | ||
434 | .lccr0 = (LCCR0_PAS), | ||
435 | .lccr3 = (LCCR3_PixClkDiv(0x01) | | ||
436 | LCCR3_Acb(0xff) | | ||
437 | LCCR3_PCP), | ||
438 | .cmap_inverse = 0, | ||
439 | .cmap_static = 0, | ||
440 | }; | ||
441 | |||
442 | static struct pxafb_mode_info generic_crt_640x480_mode = { | ||
443 | .pixclock = 38461, | ||
444 | .bpp = 8, | ||
445 | .xres = 640, | ||
446 | .yres = 480, | ||
447 | .hsync_len = 63, | ||
448 | .vsync_len = 2, | ||
449 | .left_margin = 81, | ||
450 | .upper_margin = 33, | ||
451 | .right_margin = 16, | ||
452 | .lower_margin = 10, | ||
453 | .sync = (FB_SYNC_HOR_HIGH_ACT | | ||
454 | FB_SYNC_VERT_HIGH_ACT), | ||
455 | .cmap_greyscale = 0, | ||
456 | }; | ||
457 | |||
458 | static struct pxafb_mach_info generic_crt_640x480 = { | ||
459 | .modes = &generic_crt_640x480_mode, | ||
460 | .num_modes = 1, | ||
461 | .lccr0 = (LCCR0_PAS), | ||
462 | .lccr3 = (LCCR3_PixClkDiv(0x01) | | ||
463 | LCCR3_Acb(0xff)), | ||
464 | .cmap_inverse = 0, | ||
465 | .cmap_static = 0, | ||
466 | }; | ||
467 | |||
468 | static struct pxafb_mode_info generic_crt_800x600_mode = { | ||
469 | .pixclock = 28846, | ||
470 | .bpp = 8, | ||
471 | .xres = 800, | ||
472 | .yres = 600, | ||
473 | .hsync_len = 63, | ||
474 | .vsync_len = 2, | ||
475 | .left_margin = 26, | ||
476 | .upper_margin = 21, | ||
477 | .right_margin = 26, | ||
478 | .lower_margin = 11, | ||
479 | .sync = (FB_SYNC_HOR_HIGH_ACT | | ||
480 | FB_SYNC_VERT_HIGH_ACT), | ||
481 | .cmap_greyscale = 0, | ||
482 | }; | ||
483 | |||
484 | static struct pxafb_mach_info generic_crt_800x600 = { | ||
485 | .modes = &generic_crt_800x600_mode, | ||
486 | .num_modes = 1, | ||
487 | .lccr0 = (LCCR0_PAS), | ||
488 | .lccr3 = (LCCR3_PixClkDiv(0x02) | | ||
489 | LCCR3_Acb(0xff)), | ||
490 | .cmap_inverse = 0, | ||
491 | .cmap_static = 0, | ||
492 | }; | ||
493 | |||
494 | static struct pxafb_mode_info generic_tft_320x240_mode = { | ||
495 | .pixclock = 134615, | ||
496 | .bpp = 16, | ||
497 | .xres = 320, | ||
498 | .yres = 240, | ||
499 | .hsync_len = 63, | ||
500 | .vsync_len = 7, | ||
501 | .left_margin = 75, | ||
502 | .upper_margin = 0, | ||
503 | .right_margin = 15, | ||
504 | .lower_margin = 15, | ||
505 | .sync = 0, | ||
506 | .cmap_greyscale = 0, | ||
507 | }; | ||
508 | |||
509 | static struct pxafb_mach_info generic_tft_320x240 = { | ||
510 | .modes = &generic_tft_320x240_mode, | ||
511 | .num_modes = 1, | ||
512 | .lccr0 = (LCCR0_PAS), | ||
513 | .lccr3 = (LCCR3_PixClkDiv(0x06) | | ||
514 | LCCR3_Acb(0xff) | | ||
515 | LCCR3_PCP), | ||
516 | .cmap_inverse = 0, | ||
517 | .cmap_static = 0, | ||
518 | }; | ||
519 | |||
520 | static struct pxafb_mode_info generic_stn_640x480_mode = { | ||
521 | .pixclock = 57692, | ||
522 | .bpp = 8, | ||
523 | .xres = 640, | ||
524 | .yres = 480, | ||
525 | .hsync_len = 4, | ||
526 | .vsync_len = 2, | ||
527 | .left_margin = 10, | ||
528 | .upper_margin = 5, | ||
529 | .right_margin = 10, | ||
530 | .lower_margin = 5, | ||
531 | .sync = (FB_SYNC_HOR_HIGH_ACT | | ||
532 | FB_SYNC_VERT_HIGH_ACT), | ||
533 | .cmap_greyscale = 0, | ||
534 | }; | ||
535 | |||
536 | static struct pxafb_mach_info generic_stn_640x480 = { | ||
537 | .modes = &generic_stn_640x480_mode, | ||
538 | .num_modes = 1, | ||
539 | .lccr0 = 0, | ||
540 | .lccr3 = (LCCR3_PixClkDiv(0x02) | | ||
541 | LCCR3_Acb(0xff)), | ||
542 | .cmap_inverse = 0, | ||
543 | .cmap_static = 0, | ||
544 | }; | ||
545 | |||
546 | static struct pxafb_mach_info *cmx270_display = &generic_crt_640x480; | ||
547 | |||
548 | static int __init cmx270_set_display(char *str) | ||
549 | { | ||
550 | int disp_type = simple_strtol(str, NULL, 0); | ||
551 | switch (disp_type) { | ||
552 | case MTYPE_STN320x240: | ||
553 | cmx270_display = &generic_stn_320x240; | ||
554 | break; | ||
555 | case MTYPE_TFT640x480: | ||
556 | cmx270_display = &generic_tft_640x480; | ||
557 | break; | ||
558 | case MTYPE_CRT640x480: | ||
559 | cmx270_display = &generic_crt_640x480; | ||
560 | break; | ||
561 | case MTYPE_CRT800x600: | ||
562 | cmx270_display = &generic_crt_800x600; | ||
563 | break; | ||
564 | case MTYPE_TFT320x240: | ||
565 | cmx270_display = &generic_tft_320x240; | ||
566 | break; | ||
567 | case MTYPE_STN640x480: | ||
568 | cmx270_display = &generic_stn_640x480; | ||
569 | break; | ||
570 | default: /* fallback to CRT 640x480 */ | ||
571 | cmx270_display = &generic_crt_640x480; | ||
572 | break; | ||
573 | } | ||
574 | return 1; | ||
575 | } | ||
576 | |||
577 | /* | ||
578 | This should be done really early to get proper configuration for | ||
579 | frame buffer. | ||
580 | Indeed, pxafb parameters can be used istead, but CM-X270 bootloader | ||
581 | has limitied line length for kernel command line, and also it will | ||
582 | break compatibitlty with proprietary releases already in field. | ||
583 | */ | ||
584 | __setup("monitor=", cmx270_set_display); | ||
585 | |||
586 | static void __init cmx270_init_display(void) | ||
587 | { | ||
588 | set_pxa_fb_info(cmx270_display); | ||
589 | } | ||
590 | #else | ||
591 | static inline void cmx270_init_display(void) {} | ||
592 | #endif | ||
593 | |||
594 | /* PXA27x OHCI controller setup */ | 258 | /* PXA27x OHCI controller setup */ |
595 | #if defined(CONFIG_USB_OHCI_HCD) || defined(CONFIG_USB_OHCI_HCD_MODULE) | 259 | #if defined(CONFIG_USB_OHCI_HCD) || defined(CONFIG_USB_OHCI_HCD_MODULE) |
596 | static int cmx270_ohci_init(struct device *dev) | 260 | static int cmx270_ohci_init(struct device *dev) |
@@ -676,131 +340,12 @@ static void __init cmx270_init_mmc(void) | |||
676 | static inline void cmx270_init_mmc(void) {} | 340 | static inline void cmx270_init_mmc(void) {} |
677 | #endif | 341 | #endif |
678 | 342 | ||
679 | #ifdef CONFIG_PM | 343 | void __init cmx270_init(void) |
680 | static unsigned long sleep_save_msc[10]; | ||
681 | |||
682 | static int cmx270_suspend(struct sys_device *dev, pm_message_t state) | ||
683 | { | ||
684 | cmx270_pci_suspend(); | ||
685 | |||
686 | /* save MSC registers */ | ||
687 | sleep_save_msc[0] = MSC0; | ||
688 | sleep_save_msc[1] = MSC1; | ||
689 | sleep_save_msc[2] = MSC2; | ||
690 | |||
691 | /* setup power saving mode registers */ | ||
692 | PCFR = 0x0; | ||
693 | PSLR = 0xff400000; | ||
694 | PMCR = 0x00000005; | ||
695 | PWER = 0x80000000; | ||
696 | PFER = 0x00000000; | ||
697 | PRER = 0x00000000; | ||
698 | PGSR0 = 0xC0018800; | ||
699 | PGSR1 = 0x004F0002; | ||
700 | PGSR2 = 0x6021C000; | ||
701 | PGSR3 = 0x00020000; | ||
702 | |||
703 | return 0; | ||
704 | } | ||
705 | |||
706 | static int cmx270_resume(struct sys_device *dev) | ||
707 | { | ||
708 | cmx270_pci_resume(); | ||
709 | |||
710 | /* restore MSC registers */ | ||
711 | MSC0 = sleep_save_msc[0]; | ||
712 | MSC1 = sleep_save_msc[1]; | ||
713 | MSC2 = sleep_save_msc[2]; | ||
714 | |||
715 | return 0; | ||
716 | } | ||
717 | |||
718 | static struct sysdev_class cmx270_pm_sysclass = { | ||
719 | .name = "pm", | ||
720 | .resume = cmx270_resume, | ||
721 | .suspend = cmx270_suspend, | ||
722 | }; | ||
723 | |||
724 | static struct sys_device cmx270_pm_device = { | ||
725 | .cls = &cmx270_pm_sysclass, | ||
726 | }; | ||
727 | |||
728 | static int __init cmx270_pm_init(void) | ||
729 | { | ||
730 | int error; | ||
731 | error = sysdev_class_register(&cmx270_pm_sysclass); | ||
732 | if (error == 0) | ||
733 | error = sysdev_register(&cmx270_pm_device); | ||
734 | return error; | ||
735 | } | ||
736 | #else | ||
737 | static int __init cmx270_pm_init(void) { return 0; } | ||
738 | #endif | ||
739 | |||
740 | #if defined(CONFIG_SND_PXA2XX_AC97) || defined(CONFIG_SND_PXA2XX_AC97_MODULE) | ||
741 | static void __init cmx270_init_ac97(void) | ||
742 | { | ||
743 | pxa_set_ac97_info(NULL); | ||
744 | } | ||
745 | #else | ||
746 | static inline void cmx270_init_ac97(void) {} | ||
747 | #endif | ||
748 | |||
749 | static void __init cmx270_init(void) | ||
750 | { | 344 | { |
751 | cmx270_pm_init(); | ||
752 | |||
753 | pxa2xx_mfp_config(ARRAY_AND_SIZE(cmx270_pin_config)); | 345 | pxa2xx_mfp_config(ARRAY_AND_SIZE(cmx270_pin_config)); |
754 | 346 | ||
755 | cmx270_init_dm9000(); | ||
756 | cmx270_init_rtc(); | 347 | cmx270_init_rtc(); |
757 | cmx270_init_display(); | ||
758 | cmx270_init_mmc(); | 348 | cmx270_init_mmc(); |
759 | cmx270_init_ohci(); | 349 | cmx270_init_ohci(); |
760 | cmx270_init_ac97(); | ||
761 | cmx270_init_touchscreen(); | ||
762 | cmx270_init_leds(); | ||
763 | cmx270_init_2700G(); | 350 | cmx270_init_2700G(); |
764 | } | 351 | } |
765 | |||
766 | static void __init cmx270_init_irq(void) | ||
767 | { | ||
768 | pxa27x_init_irq(); | ||
769 | |||
770 | cmx270_pci_init_irq(GPIO22_IT8152_IRQ); | ||
771 | } | ||
772 | |||
773 | #ifdef CONFIG_PCI | ||
774 | /* Map PCI companion statically */ | ||
775 | static struct map_desc cmx270_io_desc[] __initdata = { | ||
776 | [0] = { /* PCI bridge */ | ||
777 | .virtual = CMX270_IT8152_VIRT, | ||
778 | .pfn = __phys_to_pfn(PXA_CS4_PHYS), | ||
779 | .length = SZ_64M, | ||
780 | .type = MT_DEVICE | ||
781 | }, | ||
782 | }; | ||
783 | |||
784 | static void __init cmx270_map_io(void) | ||
785 | { | ||
786 | pxa_map_io(); | ||
787 | iotable_init(cmx270_io_desc, ARRAY_SIZE(cmx270_io_desc)); | ||
788 | |||
789 | it8152_base_address = CMX270_IT8152_VIRT; | ||
790 | } | ||
791 | #else | ||
792 | static void __init cmx270_map_io(void) | ||
793 | { | ||
794 | pxa_map_io(); | ||
795 | } | ||
796 | #endif | ||
797 | |||
798 | MACHINE_START(ARMCORE, "Compulab CM-x270") | ||
799 | .boot_params = 0xa0000100, | ||
800 | .phys_io = 0x40000000, | ||
801 | .io_pg_offst = (io_p2v(0x40000000) >> 18) & 0xfffc, | ||
802 | .map_io = cmx270_map_io, | ||
803 | .init_irq = cmx270_init_irq, | ||
804 | .timer = &pxa_timer, | ||
805 | .init_machine = cmx270_init, | ||
806 | MACHINE_END | ||
diff --git a/arch/arm/mach-pxa/cm-x270-pci.c b/arch/arm/mach-pxa/cm-x2xx-pci.c index 2d5bcea1e520..3156b25f6e9d 100644 --- a/arch/arm/mach-pxa/cm-x270-pci.c +++ b/arch/arm/mach-pxa/cm-x2xx-pci.c | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * linux/arch/arm/mach-pxa/cm-x270-pci.c | 2 | * linux/arch/arm/mach-pxa/cm-x2xx-pci.c |
3 | * | 3 | * |
4 | * PCI bios-type initialisation for PCI machines | 4 | * PCI bios-type initialisation for PCI machines |
5 | * | 5 | * |
@@ -28,7 +28,7 @@ | |||
28 | #include <asm/hardware/it8152.h> | 28 | #include <asm/hardware/it8152.h> |
29 | 29 | ||
30 | unsigned long it8152_base_address; | 30 | unsigned long it8152_base_address; |
31 | static int cmx270_it8152_irq_gpio; | 31 | static int cmx2xx_it8152_irq_gpio; |
32 | 32 | ||
33 | /* | 33 | /* |
34 | * Only first 64MB of memory can be accessed via PCI. | 34 | * Only first 64MB of memory can be accessed via PCI. |
@@ -36,13 +36,13 @@ static int cmx270_it8152_irq_gpio; | |||
36 | * This is really ugly and we need a better way of specifying | 36 | * This is really ugly and we need a better way of specifying |
37 | * DMA-capable regions of memory. | 37 | * DMA-capable regions of memory. |
38 | */ | 38 | */ |
39 | void __init cmx270_pci_adjust_zones(int node, unsigned long *zone_size, | 39 | void __init cmx2xx_pci_adjust_zones(int node, unsigned long *zone_size, |
40 | unsigned long *zhole_size) | 40 | unsigned long *zhole_size) |
41 | { | 41 | { |
42 | unsigned int sz = SZ_64M >> PAGE_SHIFT; | 42 | unsigned int sz = SZ_64M >> PAGE_SHIFT; |
43 | 43 | ||
44 | if (machine_is_armcore()) { | 44 | if (machine_is_armcore()) { |
45 | pr_info("Adjusting zones for CM-X270\n"); | 45 | pr_info("Adjusting zones for CM-X2XX\n"); |
46 | 46 | ||
47 | /* | 47 | /* |
48 | * Only adjust if > 64M on current system | 48 | * Only adjust if > 64M on current system |
@@ -57,29 +57,29 @@ void __init cmx270_pci_adjust_zones(int node, unsigned long *zone_size, | |||
57 | } | 57 | } |
58 | } | 58 | } |
59 | 59 | ||
60 | static void cmx270_it8152_irq_demux(unsigned int irq, struct irq_desc *desc) | 60 | static void cmx2xx_it8152_irq_demux(unsigned int irq, struct irq_desc *desc) |
61 | { | 61 | { |
62 | /* clear our parent irq */ | 62 | /* clear our parent irq */ |
63 | GEDR(cmx270_it8152_irq_gpio) = GPIO_bit(cmx270_it8152_irq_gpio); | 63 | GEDR(cmx2xx_it8152_irq_gpio) = GPIO_bit(cmx2xx_it8152_irq_gpio); |
64 | 64 | ||
65 | it8152_irq_demux(irq, desc); | 65 | it8152_irq_demux(irq, desc); |
66 | } | 66 | } |
67 | 67 | ||
68 | void __cmx270_pci_init_irq(int irq_gpio) | 68 | void __cmx2xx_pci_init_irq(int irq_gpio) |
69 | { | 69 | { |
70 | it8152_init_irq(); | 70 | it8152_init_irq(); |
71 | 71 | ||
72 | cmx270_it8152_irq_gpio = irq_gpio; | 72 | cmx2xx_it8152_irq_gpio = irq_gpio; |
73 | 73 | ||
74 | set_irq_type(gpio_to_irq(irq_gpio), IRQ_TYPE_EDGE_RISING); | 74 | set_irq_type(gpio_to_irq(irq_gpio), IRQ_TYPE_EDGE_RISING); |
75 | 75 | ||
76 | set_irq_chained_handler(gpio_to_irq(irq_gpio), cmx270_it8152_irq_demux); | 76 | set_irq_chained_handler(gpio_to_irq(irq_gpio), cmx2xx_it8152_irq_demux); |
77 | } | 77 | } |
78 | 78 | ||
79 | #ifdef CONFIG_PM | 79 | #ifdef CONFIG_PM |
80 | static unsigned long sleep_save_ite[10]; | 80 | static unsigned long sleep_save_ite[10]; |
81 | 81 | ||
82 | void __cmx270_pci_suspend(void) | 82 | void __cmx2xx_pci_suspend(void) |
83 | { | 83 | { |
84 | /* save ITE state */ | 84 | /* save ITE state */ |
85 | sleep_save_ite[0] = __raw_readl(IT8152_INTC_PDCNIMR); | 85 | sleep_save_ite[0] = __raw_readl(IT8152_INTC_PDCNIMR); |
@@ -91,7 +91,7 @@ void __cmx270_pci_suspend(void) | |||
91 | __raw_writel((0), IT8152_INTC_LPCNIRR); | 91 | __raw_writel((0), IT8152_INTC_LPCNIRR); |
92 | } | 92 | } |
93 | 93 | ||
94 | void __cmx270_pci_resume(void) | 94 | void __cmx2xx_pci_resume(void) |
95 | { | 95 | { |
96 | /* restore IT8152 state */ | 96 | /* restore IT8152 state */ |
97 | __raw_writel((sleep_save_ite[0]), IT8152_INTC_PDCNIMR); | 97 | __raw_writel((sleep_save_ite[0]), IT8152_INTC_PDCNIMR); |
@@ -99,12 +99,12 @@ void __cmx270_pci_resume(void) | |||
99 | __raw_writel((sleep_save_ite[2]), IT8152_INTC_LPNIAR); | 99 | __raw_writel((sleep_save_ite[2]), IT8152_INTC_LPNIAR); |
100 | } | 100 | } |
101 | #else | 101 | #else |
102 | void cmx270_pci_suspend(void) {} | 102 | void cmx2xx_pci_suspend(void) {} |
103 | void cmx270_pci_resume(void) {} | 103 | void cmx2xx_pci_resume(void) {} |
104 | #endif | 104 | #endif |
105 | 105 | ||
106 | /* PCI IRQ mapping*/ | 106 | /* PCI IRQ mapping*/ |
107 | static int __init cmx270_pci_map_irq(struct pci_dev *dev, u8 slot, u8 pin) | 107 | static int __init cmx2xx_pci_map_irq(struct pci_dev *dev, u8 slot, u8 pin) |
108 | { | 108 | { |
109 | int irq; | 109 | int irq; |
110 | 110 | ||
@@ -116,14 +116,14 @@ static int __init cmx270_pci_map_irq(struct pci_dev *dev, u8 slot, u8 pin) | |||
116 | 116 | ||
117 | /* | 117 | /* |
118 | Here comes the ugly part. The routing is baseboard specific, | 118 | Here comes the ugly part. The routing is baseboard specific, |
119 | but defining a platform for each possible base of CM-X270 is | 119 | but defining a platform for each possible base of CM-X2XX is |
120 | unrealistic. Here we keep mapping for ATXBase and SB-X270. | 120 | unrealistic. Here we keep mapping for ATXBase and SB-X2XX. |
121 | */ | 121 | */ |
122 | /* ATXBASE PCI slot */ | 122 | /* ATXBASE PCI slot */ |
123 | if (slot == 7) | 123 | if (slot == 7) |
124 | return IT8152_PCI_INTA; | 124 | return IT8152_PCI_INTA; |
125 | 125 | ||
126 | /* ATXBase/SB-x270 CardBus */ | 126 | /* ATXBase/SB-X2XX CardBus */ |
127 | if (slot == 8 || slot == 0) | 127 | if (slot == 8 || slot == 0) |
128 | return IT8152_PCI_INTB; | 128 | return IT8152_PCI_INTB; |
129 | 129 | ||
@@ -131,7 +131,11 @@ static int __init cmx270_pci_map_irq(struct pci_dev *dev, u8 slot, u8 pin) | |||
131 | if (slot == 9) | 131 | if (slot == 9) |
132 | return IT8152_PCI_INTA; | 132 | return IT8152_PCI_INTA; |
133 | 133 | ||
134 | /* SB-x270 Ethernet */ | 134 | /* CM-x255 Onboard Ethernet */ |
135 | if (slot == 15) | ||
136 | return IT8152_PCI_INTC; | ||
137 | |||
138 | /* SB-x2xx Ethernet */ | ||
135 | if (slot == 16) | 139 | if (slot == 16) |
136 | return IT8152_PCI_INTA; | 140 | return IT8152_PCI_INTA; |
137 | 141 | ||
@@ -144,9 +148,9 @@ static int __init cmx270_pci_map_irq(struct pci_dev *dev, u8 slot, u8 pin) | |||
144 | return(0); | 148 | return(0); |
145 | } | 149 | } |
146 | 150 | ||
147 | static void cmx270_pci_preinit(void) | 151 | static void cmx2xx_pci_preinit(void) |
148 | { | 152 | { |
149 | pr_info("Initializing CM-X270 PCI subsystem\n"); | 153 | pr_info("Initializing CM-X2XX PCI subsystem\n"); |
150 | 154 | ||
151 | __raw_writel(0x800, IT8152_PCI_CFG_ADDR); | 155 | __raw_writel(0x800, IT8152_PCI_CFG_ADDR); |
152 | if (__raw_readl(IT8152_PCI_CFG_DATA) == 0x81521283) { | 156 | if (__raw_readl(IT8152_PCI_CFG_DATA) == 0x81521283) { |
@@ -200,21 +204,21 @@ static void cmx270_pci_preinit(void) | |||
200 | } | 204 | } |
201 | } | 205 | } |
202 | 206 | ||
203 | static struct hw_pci cmx270_pci __initdata = { | 207 | static struct hw_pci cmx2xx_pci __initdata = { |
204 | .swizzle = pci_std_swizzle, | 208 | .swizzle = pci_std_swizzle, |
205 | .map_irq = cmx270_pci_map_irq, | 209 | .map_irq = cmx2xx_pci_map_irq, |
206 | .nr_controllers = 1, | 210 | .nr_controllers = 1, |
207 | .setup = it8152_pci_setup, | 211 | .setup = it8152_pci_setup, |
208 | .scan = it8152_pci_scan_bus, | 212 | .scan = it8152_pci_scan_bus, |
209 | .preinit = cmx270_pci_preinit, | 213 | .preinit = cmx2xx_pci_preinit, |
210 | }; | 214 | }; |
211 | 215 | ||
212 | static int __init cmx270_init_pci(void) | 216 | static int __init cmx2xx_init_pci(void) |
213 | { | 217 | { |
214 | if (machine_is_armcore()) | 218 | if (machine_is_armcore()) |
215 | pci_common_init(&cmx270_pci); | 219 | pci_common_init(&cmx2xx_pci); |
216 | 220 | ||
217 | return 0; | 221 | return 0; |
218 | } | 222 | } |
219 | 223 | ||
220 | subsys_initcall(cmx270_init_pci); | 224 | subsys_initcall(cmx2xx_init_pci); |
diff --git a/arch/arm/mach-pxa/cm-x2xx-pci.h b/arch/arm/mach-pxa/cm-x2xx-pci.h new file mode 100644 index 000000000000..e24aad2e3ad7 --- /dev/null +++ b/arch/arm/mach-pxa/cm-x2xx-pci.h | |||
@@ -0,0 +1,13 @@ | |||
1 | extern void __cmx2xx_pci_init_irq(int irq_gpio); | ||
2 | extern void __cmx2xx_pci_suspend(void); | ||
3 | extern void __cmx2xx_pci_resume(void); | ||
4 | |||
5 | #ifdef CONFIG_PCI | ||
6 | #define cmx2xx_pci_init_irq(x) __cmx2xx_pci_init_irq(x) | ||
7 | #define cmx2xx_pci_suspend(x) __cmx2xx_pci_suspend(x) | ||
8 | #define cmx2xx_pci_resume(x) __cmx2xx_pci_resume(x) | ||
9 | #else | ||
10 | #define cmx2xx_pci_init_irq(x) do {} while (0) | ||
11 | #define cmx2xx_pci_suspend(x) do {} while (0) | ||
12 | #define cmx2xx_pci_resume(x) do {} while (0) | ||
13 | #endif | ||
diff --git a/arch/arm/mach-pxa/cm-x2xx.c b/arch/arm/mach-pxa/cm-x2xx.c new file mode 100644 index 000000000000..0b3ce3b6d896 --- /dev/null +++ b/arch/arm/mach-pxa/cm-x2xx.c | |||
@@ -0,0 +1,531 @@ | |||
1 | /* | ||
2 | * linux/arch/arm/mach-pxa/cm-x2xx.c | ||
3 | * | ||
4 | * Copyright (C) 2008 CompuLab, Ltd. | ||
5 | * Mike Rapoport <mike@compulab.co.il> | ||
6 | * | ||
7 | * This program is free software; you can redistribute it and/or modify | ||
8 | * it under the terms of the GNU General Public License version 2 as | ||
9 | * published by the Free Software Foundation. | ||
10 | */ | ||
11 | |||
12 | #include <linux/platform_device.h> | ||
13 | #include <linux/sysdev.h> | ||
14 | #include <linux/irq.h> | ||
15 | #include <linux/gpio.h> | ||
16 | |||
17 | #include <linux/dm9000.h> | ||
18 | #include <linux/leds.h> | ||
19 | |||
20 | #include <asm/mach/arch.h> | ||
21 | #include <asm/mach-types.h> | ||
22 | #include <asm/mach/map.h> | ||
23 | |||
24 | #include <mach/pxa2xx-regs.h> | ||
25 | #include <mach/mfp-pxa27x.h> | ||
26 | #include <mach/pxa-regs.h> | ||
27 | #include <mach/audio.h> | ||
28 | #include <mach/pxafb.h> | ||
29 | |||
30 | #include <asm/hardware/it8152.h> | ||
31 | |||
32 | #include "generic.h" | ||
33 | #include "cm-x2xx-pci.h" | ||
34 | |||
35 | extern void cmx255_init(void); | ||
36 | extern void cmx270_init(void); | ||
37 | |||
38 | /* virtual addresses for statically mapped regions */ | ||
39 | #define CMX2XX_VIRT_BASE (0xe8000000) | ||
40 | #define CMX2XX_IT8152_VIRT (CMX2XX_VIRT_BASE) | ||
41 | |||
42 | /* physical address if local-bus attached devices */ | ||
43 | #define CMX255_DM9000_PHYS_BASE (PXA_CS1_PHYS + (8 << 22)) | ||
44 | #define CMX270_DM9000_PHYS_BASE (PXA_CS1_PHYS + (6 << 22)) | ||
45 | |||
46 | /* leds */ | ||
47 | #define CMX255_GPIO_RED (27) | ||
48 | #define CMX255_GPIO_GREEN (32) | ||
49 | #define CMX270_GPIO_RED (93) | ||
50 | #define CMX270_GPIO_GREEN (94) | ||
51 | |||
52 | /* GPIO IRQ usage */ | ||
53 | #define GPIO22_ETHIRQ (22) | ||
54 | #define GPIO10_ETHIRQ (10) | ||
55 | #define CMX255_GPIO_IT8152_IRQ (0) | ||
56 | #define CMX270_GPIO_IT8152_IRQ (22) | ||
57 | |||
58 | #define CMX255_ETHIRQ IRQ_GPIO(GPIO22_ETHIRQ) | ||
59 | #define CMX270_ETHIRQ IRQ_GPIO(GPIO10_ETHIRQ) | ||
60 | |||
61 | #if defined(CONFIG_DM9000) || defined(CONFIG_DM9000_MODULE) | ||
62 | static struct resource cmx255_dm9000_resource[] = { | ||
63 | [0] = { | ||
64 | .start = CMX255_DM9000_PHYS_BASE, | ||
65 | .end = CMX255_DM9000_PHYS_BASE + 3, | ||
66 | .flags = IORESOURCE_MEM, | ||
67 | }, | ||
68 | [1] = { | ||
69 | .start = CMX255_DM9000_PHYS_BASE + 4, | ||
70 | .end = CMX255_DM9000_PHYS_BASE + 4 + 500, | ||
71 | .flags = IORESOURCE_MEM, | ||
72 | }, | ||
73 | [2] = { | ||
74 | .start = CMX255_ETHIRQ, | ||
75 | .end = CMX255_ETHIRQ, | ||
76 | .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHEDGE, | ||
77 | } | ||
78 | }; | ||
79 | |||
80 | static struct resource cmx270_dm9000_resource[] = { | ||
81 | [0] = { | ||
82 | .start = CMX270_DM9000_PHYS_BASE, | ||
83 | .end = CMX270_DM9000_PHYS_BASE + 3, | ||
84 | .flags = IORESOURCE_MEM, | ||
85 | }, | ||
86 | [1] = { | ||
87 | .start = CMX270_DM9000_PHYS_BASE + 8, | ||
88 | .end = CMX270_DM9000_PHYS_BASE + 8 + 500, | ||
89 | .flags = IORESOURCE_MEM, | ||
90 | }, | ||
91 | [2] = { | ||
92 | .start = CMX270_ETHIRQ, | ||
93 | .end = CMX270_ETHIRQ, | ||
94 | .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHEDGE, | ||
95 | } | ||
96 | }; | ||
97 | |||
98 | static struct dm9000_plat_data cmx270_dm9000_platdata = { | ||
99 | .flags = DM9000_PLATF_32BITONLY, | ||
100 | }; | ||
101 | |||
102 | static struct platform_device cmx2xx_dm9000_device = { | ||
103 | .name = "dm9000", | ||
104 | .id = 0, | ||
105 | .num_resources = ARRAY_SIZE(cmx270_dm9000_resource), | ||
106 | .dev = { | ||
107 | .platform_data = &cmx270_dm9000_platdata, | ||
108 | } | ||
109 | }; | ||
110 | |||
111 | static void __init cmx2xx_init_dm9000(void) | ||
112 | { | ||
113 | if (cpu_is_pxa25x()) | ||
114 | cmx2xx_dm9000_device.resource = cmx255_dm9000_resource; | ||
115 | else | ||
116 | cmx2xx_dm9000_device.resource = cmx270_dm9000_resource; | ||
117 | platform_device_register(&cmx2xx_dm9000_device); | ||
118 | } | ||
119 | #else | ||
120 | static inline void cmx2xx_init_dm9000(void) {} | ||
121 | #endif | ||
122 | |||
123 | /* UCB1400 touchscreen controller */ | ||
124 | #if defined(CONFIG_TOUCHSCREEN_UCB1400) || defined(CONFIG_TOUCHSCREEN_UCB1400_MODULE) | ||
125 | static struct platform_device cmx2xx_ts_device = { | ||
126 | .name = "ucb1400_ts", | ||
127 | .id = -1, | ||
128 | }; | ||
129 | |||
130 | static void __init cmx2xx_init_touchscreen(void) | ||
131 | { | ||
132 | platform_device_register(&cmx2xx_ts_device); | ||
133 | } | ||
134 | #else | ||
135 | static inline void cmx2xx_init_touchscreen(void) {} | ||
136 | #endif | ||
137 | |||
138 | /* CM-X270 LEDs */ | ||
139 | #if defined(CONFIG_LEDS_GPIO) || defined(CONFIG_LEDS_GPIO_MODULE) | ||
140 | static struct gpio_led cmx2xx_leds[] = { | ||
141 | [0] = { | ||
142 | .name = "cm-x2xx:red", | ||
143 | .default_trigger = "nand-disk", | ||
144 | .active_low = 1, | ||
145 | }, | ||
146 | [1] = { | ||
147 | .name = "cm-x2xx:green", | ||
148 | .default_trigger = "heartbeat", | ||
149 | .active_low = 1, | ||
150 | }, | ||
151 | }; | ||
152 | |||
153 | static struct gpio_led_platform_data cmx2xx_gpio_led_pdata = { | ||
154 | .num_leds = ARRAY_SIZE(cmx2xx_leds), | ||
155 | .leds = cmx2xx_leds, | ||
156 | }; | ||
157 | |||
158 | static struct platform_device cmx2xx_led_device = { | ||
159 | .name = "leds-gpio", | ||
160 | .id = -1, | ||
161 | .dev = { | ||
162 | .platform_data = &cmx2xx_gpio_led_pdata, | ||
163 | }, | ||
164 | }; | ||
165 | |||
166 | static void __init cmx2xx_init_leds(void) | ||
167 | { | ||
168 | if (cpu_is_pxa25x()) { | ||
169 | cmx2xx_leds[0].gpio = CMX255_GPIO_RED; | ||
170 | cmx2xx_leds[1].gpio = CMX255_GPIO_GREEN; | ||
171 | } else { | ||
172 | cmx2xx_leds[0].gpio = CMX270_GPIO_RED; | ||
173 | cmx2xx_leds[1].gpio = CMX270_GPIO_GREEN; | ||
174 | } | ||
175 | platform_device_register(&cmx2xx_led_device); | ||
176 | } | ||
177 | #else | ||
178 | static inline void cmx2xx_init_leds(void) {} | ||
179 | #endif | ||
180 | |||
181 | #if defined(CONFIG_FB_PXA) || defined(CONFIG_FB_PXA_MODULE) | ||
182 | /* | ||
183 | Display definitions | ||
184 | keep these for backwards compatibility, although symbolic names (as | ||
185 | e.g. in lpd270.c) looks better | ||
186 | */ | ||
187 | #define MTYPE_STN320x240 0 | ||
188 | #define MTYPE_TFT640x480 1 | ||
189 | #define MTYPE_CRT640x480 2 | ||
190 | #define MTYPE_CRT800x600 3 | ||
191 | #define MTYPE_TFT320x240 6 | ||
192 | #define MTYPE_STN640x480 7 | ||
193 | |||
194 | static struct pxafb_mode_info generic_stn_320x240_mode = { | ||
195 | .pixclock = 76923, | ||
196 | .bpp = 8, | ||
197 | .xres = 320, | ||
198 | .yres = 240, | ||
199 | .hsync_len = 3, | ||
200 | .vsync_len = 2, | ||
201 | .left_margin = 3, | ||
202 | .upper_margin = 0, | ||
203 | .right_margin = 3, | ||
204 | .lower_margin = 0, | ||
205 | .sync = (FB_SYNC_HOR_HIGH_ACT | | ||
206 | FB_SYNC_VERT_HIGH_ACT), | ||
207 | .cmap_greyscale = 0, | ||
208 | }; | ||
209 | |||
210 | static struct pxafb_mach_info generic_stn_320x240 = { | ||
211 | .modes = &generic_stn_320x240_mode, | ||
212 | .num_modes = 1, | ||
213 | .lccr0 = 0, | ||
214 | .lccr3 = (LCCR3_PixClkDiv(0x03) | | ||
215 | LCCR3_Acb(0xff) | | ||
216 | LCCR3_PCP), | ||
217 | .cmap_inverse = 0, | ||
218 | .cmap_static = 0, | ||
219 | }; | ||
220 | |||
221 | static struct pxafb_mode_info generic_tft_640x480_mode = { | ||
222 | .pixclock = 38461, | ||
223 | .bpp = 8, | ||
224 | .xres = 640, | ||
225 | .yres = 480, | ||
226 | .hsync_len = 60, | ||
227 | .vsync_len = 2, | ||
228 | .left_margin = 70, | ||
229 | .upper_margin = 10, | ||
230 | .right_margin = 70, | ||
231 | .lower_margin = 5, | ||
232 | .sync = 0, | ||
233 | .cmap_greyscale = 0, | ||
234 | }; | ||
235 | |||
236 | static struct pxafb_mach_info generic_tft_640x480 = { | ||
237 | .modes = &generic_tft_640x480_mode, | ||
238 | .num_modes = 1, | ||
239 | .lccr0 = (LCCR0_PAS), | ||
240 | .lccr3 = (LCCR3_PixClkDiv(0x01) | | ||
241 | LCCR3_Acb(0xff) | | ||
242 | LCCR3_PCP), | ||
243 | .cmap_inverse = 0, | ||
244 | .cmap_static = 0, | ||
245 | }; | ||
246 | |||
247 | static struct pxafb_mode_info generic_crt_640x480_mode = { | ||
248 | .pixclock = 38461, | ||
249 | .bpp = 8, | ||
250 | .xres = 640, | ||
251 | .yres = 480, | ||
252 | .hsync_len = 63, | ||
253 | .vsync_len = 2, | ||
254 | .left_margin = 81, | ||
255 | .upper_margin = 33, | ||
256 | .right_margin = 16, | ||
257 | .lower_margin = 10, | ||
258 | .sync = (FB_SYNC_HOR_HIGH_ACT | | ||
259 | FB_SYNC_VERT_HIGH_ACT), | ||
260 | .cmap_greyscale = 0, | ||
261 | }; | ||
262 | |||
263 | static struct pxafb_mach_info generic_crt_640x480 = { | ||
264 | .modes = &generic_crt_640x480_mode, | ||
265 | .num_modes = 1, | ||
266 | .lccr0 = (LCCR0_PAS), | ||
267 | .lccr3 = (LCCR3_PixClkDiv(0x01) | | ||
268 | LCCR3_Acb(0xff)), | ||
269 | .cmap_inverse = 0, | ||
270 | .cmap_static = 0, | ||
271 | }; | ||
272 | |||
273 | static struct pxafb_mode_info generic_crt_800x600_mode = { | ||
274 | .pixclock = 28846, | ||
275 | .bpp = 8, | ||
276 | .xres = 800, | ||
277 | .yres = 600, | ||
278 | .hsync_len = 63, | ||
279 | .vsync_len = 2, | ||
280 | .left_margin = 26, | ||
281 | .upper_margin = 21, | ||
282 | .right_margin = 26, | ||
283 | .lower_margin = 11, | ||
284 | .sync = (FB_SYNC_HOR_HIGH_ACT | | ||
285 | FB_SYNC_VERT_HIGH_ACT), | ||
286 | .cmap_greyscale = 0, | ||
287 | }; | ||
288 | |||
289 | static struct pxafb_mach_info generic_crt_800x600 = { | ||
290 | .modes = &generic_crt_800x600_mode, | ||
291 | .num_modes = 1, | ||
292 | .lccr0 = (LCCR0_PAS), | ||
293 | .lccr3 = (LCCR3_PixClkDiv(0x02) | | ||
294 | LCCR3_Acb(0xff)), | ||
295 | .cmap_inverse = 0, | ||
296 | .cmap_static = 0, | ||
297 | }; | ||
298 | |||
299 | static struct pxafb_mode_info generic_tft_320x240_mode = { | ||
300 | .pixclock = 134615, | ||
301 | .bpp = 16, | ||
302 | .xres = 320, | ||
303 | .yres = 240, | ||
304 | .hsync_len = 63, | ||
305 | .vsync_len = 7, | ||
306 | .left_margin = 75, | ||
307 | .upper_margin = 0, | ||
308 | .right_margin = 15, | ||
309 | .lower_margin = 15, | ||
310 | .sync = 0, | ||
311 | .cmap_greyscale = 0, | ||
312 | }; | ||
313 | |||
314 | static struct pxafb_mach_info generic_tft_320x240 = { | ||
315 | .modes = &generic_tft_320x240_mode, | ||
316 | .num_modes = 1, | ||
317 | .lccr0 = (LCCR0_PAS), | ||
318 | .lccr3 = (LCCR3_PixClkDiv(0x06) | | ||
319 | LCCR3_Acb(0xff) | | ||
320 | LCCR3_PCP), | ||
321 | .cmap_inverse = 0, | ||
322 | .cmap_static = 0, | ||
323 | }; | ||
324 | |||
325 | static struct pxafb_mode_info generic_stn_640x480_mode = { | ||
326 | .pixclock = 57692, | ||
327 | .bpp = 8, | ||
328 | .xres = 640, | ||
329 | .yres = 480, | ||
330 | .hsync_len = 4, | ||
331 | .vsync_len = 2, | ||
332 | .left_margin = 10, | ||
333 | .upper_margin = 5, | ||
334 | .right_margin = 10, | ||
335 | .lower_margin = 5, | ||
336 | .sync = (FB_SYNC_HOR_HIGH_ACT | | ||
337 | FB_SYNC_VERT_HIGH_ACT), | ||
338 | .cmap_greyscale = 0, | ||
339 | }; | ||
340 | |||
341 | static struct pxafb_mach_info generic_stn_640x480 = { | ||
342 | .modes = &generic_stn_640x480_mode, | ||
343 | .num_modes = 1, | ||
344 | .lccr0 = 0, | ||
345 | .lccr3 = (LCCR3_PixClkDiv(0x02) | | ||
346 | LCCR3_Acb(0xff)), | ||
347 | .cmap_inverse = 0, | ||
348 | .cmap_static = 0, | ||
349 | }; | ||
350 | |||
351 | static struct pxafb_mach_info *cmx2xx_display = &generic_crt_640x480; | ||
352 | |||
353 | static int __init cmx2xx_set_display(char *str) | ||
354 | { | ||
355 | int disp_type = simple_strtol(str, NULL, 0); | ||
356 | switch (disp_type) { | ||
357 | case MTYPE_STN320x240: | ||
358 | cmx2xx_display = &generic_stn_320x240; | ||
359 | break; | ||
360 | case MTYPE_TFT640x480: | ||
361 | cmx2xx_display = &generic_tft_640x480; | ||
362 | break; | ||
363 | case MTYPE_CRT640x480: | ||
364 | cmx2xx_display = &generic_crt_640x480; | ||
365 | break; | ||
366 | case MTYPE_CRT800x600: | ||
367 | cmx2xx_display = &generic_crt_800x600; | ||
368 | break; | ||
369 | case MTYPE_TFT320x240: | ||
370 | cmx2xx_display = &generic_tft_320x240; | ||
371 | break; | ||
372 | case MTYPE_STN640x480: | ||
373 | cmx2xx_display = &generic_stn_640x480; | ||
374 | break; | ||
375 | default: /* fallback to CRT 640x480 */ | ||
376 | cmx2xx_display = &generic_crt_640x480; | ||
377 | break; | ||
378 | } | ||
379 | return 1; | ||
380 | } | ||
381 | |||
382 | /* | ||
383 | This should be done really early to get proper configuration for | ||
384 | frame buffer. | ||
385 | Indeed, pxafb parameters can be used istead, but CM-X2XX bootloader | ||
386 | has limitied line length for kernel command line, and also it will | ||
387 | break compatibitlty with proprietary releases already in field. | ||
388 | */ | ||
389 | __setup("monitor=", cmx2xx_set_display); | ||
390 | |||
391 | static void __init cmx2xx_init_display(void) | ||
392 | { | ||
393 | set_pxa_fb_info(cmx2xx_display); | ||
394 | } | ||
395 | #else | ||
396 | static inline void cmx2xx_init_display(void) {} | ||
397 | #endif | ||
398 | |||
399 | #ifdef CONFIG_PM | ||
400 | static unsigned long sleep_save_msc[10]; | ||
401 | |||
402 | static int cmx2xx_suspend(struct sys_device *dev, pm_message_t state) | ||
403 | { | ||
404 | cmx2xx_pci_suspend(); | ||
405 | |||
406 | /* save MSC registers */ | ||
407 | sleep_save_msc[0] = MSC0; | ||
408 | sleep_save_msc[1] = MSC1; | ||
409 | sleep_save_msc[2] = MSC2; | ||
410 | |||
411 | /* setup power saving mode registers */ | ||
412 | PCFR = 0x0; | ||
413 | PSLR = 0xff400000; | ||
414 | PMCR = 0x00000005; | ||
415 | PWER = 0x80000000; | ||
416 | PFER = 0x00000000; | ||
417 | PRER = 0x00000000; | ||
418 | PGSR0 = 0xC0018800; | ||
419 | PGSR1 = 0x004F0002; | ||
420 | PGSR2 = 0x6021C000; | ||
421 | PGSR3 = 0x00020000; | ||
422 | |||
423 | return 0; | ||
424 | } | ||
425 | |||
426 | static int cmx2xx_resume(struct sys_device *dev) | ||
427 | { | ||
428 | cmx2xx_pci_resume(); | ||
429 | |||
430 | /* restore MSC registers */ | ||
431 | MSC0 = sleep_save_msc[0]; | ||
432 | MSC1 = sleep_save_msc[1]; | ||
433 | MSC2 = sleep_save_msc[2]; | ||
434 | |||
435 | return 0; | ||
436 | } | ||
437 | |||
438 | static struct sysdev_class cmx2xx_pm_sysclass = { | ||
439 | .name = "pm", | ||
440 | .resume = cmx2xx_resume, | ||
441 | .suspend = cmx2xx_suspend, | ||
442 | }; | ||
443 | |||
444 | static struct sys_device cmx2xx_pm_device = { | ||
445 | .cls = &cmx2xx_pm_sysclass, | ||
446 | }; | ||
447 | |||
448 | static int __init cmx2xx_pm_init(void) | ||
449 | { | ||
450 | int error; | ||
451 | error = sysdev_class_register(&cmx2xx_pm_sysclass); | ||
452 | if (error == 0) | ||
453 | error = sysdev_register(&cmx2xx_pm_device); | ||
454 | return error; | ||
455 | } | ||
456 | #else | ||
457 | static int __init cmx2xx_pm_init(void) { return 0; } | ||
458 | #endif | ||
459 | |||
460 | #if defined(CONFIG_SND_PXA2XX_AC97) || defined(CONFIG_SND_PXA2XX_AC97_MODULE) | ||
461 | static void __init cmx2xx_init_ac97(void) | ||
462 | { | ||
463 | pxa_set_ac97_info(NULL); | ||
464 | } | ||
465 | #else | ||
466 | static inline void cmx2xx_init_ac97(void) {} | ||
467 | #endif | ||
468 | |||
469 | static void __init cmx2xx_init(void) | ||
470 | { | ||
471 | cmx2xx_pm_init(); | ||
472 | |||
473 | if (cpu_is_pxa25x()) | ||
474 | cmx255_init(); | ||
475 | else | ||
476 | cmx270_init(); | ||
477 | |||
478 | cmx2xx_init_dm9000(); | ||
479 | cmx2xx_init_display(); | ||
480 | cmx2xx_init_ac97(); | ||
481 | cmx2xx_init_touchscreen(); | ||
482 | cmx2xx_init_leds(); | ||
483 | } | ||
484 | |||
485 | static void __init cmx2xx_init_irq(void) | ||
486 | { | ||
487 | pxa27x_init_irq(); | ||
488 | |||
489 | if (cpu_is_pxa25x()) { | ||
490 | pxa25x_init_irq(); | ||
491 | cmx2xx_pci_init_irq(CMX255_GPIO_IT8152_IRQ); | ||
492 | } else { | ||
493 | pxa27x_init_irq(); | ||
494 | cmx2xx_pci_init_irq(CMX270_GPIO_IT8152_IRQ); | ||
495 | } | ||
496 | } | ||
497 | |||
498 | #ifdef CONFIG_PCI | ||
499 | /* Map PCI companion statically */ | ||
500 | static struct map_desc cmx2xx_io_desc[] __initdata = { | ||
501 | [0] = { /* PCI bridge */ | ||
502 | .virtual = CMX2XX_IT8152_VIRT, | ||
503 | .pfn = __phys_to_pfn(PXA_CS4_PHYS), | ||
504 | .length = SZ_64M, | ||
505 | .type = MT_DEVICE | ||
506 | }, | ||
507 | }; | ||
508 | |||
509 | static void __init cmx2xx_map_io(void) | ||
510 | { | ||
511 | pxa_map_io(); | ||
512 | iotable_init(cmx2xx_io_desc, ARRAY_SIZE(cmx2xx_io_desc)); | ||
513 | |||
514 | it8152_base_address = CMX2XX_IT8152_VIRT; | ||
515 | } | ||
516 | #else | ||
517 | static void __init cmx2xx_map_io(void) | ||
518 | { | ||
519 | pxa_map_io(); | ||
520 | } | ||
521 | #endif | ||
522 | |||
523 | MACHINE_START(ARMCORE, "Compulab CM-X2XX") | ||
524 | .boot_params = 0xa0000100, | ||
525 | .phys_io = 0x40000000, | ||
526 | .io_pg_offst = (io_p2v(0x40000000) >> 18) & 0xfffc, | ||
527 | .map_io = cmx2xx_map_io, | ||
528 | .init_irq = cmx2xx_init_irq, | ||
529 | .timer = &pxa_timer, | ||
530 | .init_machine = cmx2xx_init, | ||
531 | MACHINE_END | ||
diff --git a/arch/arm/mach-pxa/cm-x300.c b/arch/arm/mach-pxa/cm-x300.c new file mode 100644 index 000000000000..7bc5679b41ba --- /dev/null +++ b/arch/arm/mach-pxa/cm-x300.c | |||
@@ -0,0 +1,473 @@ | |||
1 | /* | ||
2 | * linux/arch/arm/mach-pxa/cm-x300.c | ||
3 | * | ||
4 | * Support for the CompuLab CM-X300 modules | ||
5 | * | ||
6 | * Copyright (C) 2008 CompuLab Ltd. | ||
7 | * | ||
8 | * Mike Rapoport <mike@compulab.co.il> | ||
9 | * | ||
10 | * This program is free software; you can redistribute it and/or modify | ||
11 | * it under the terms of the GNU General Public License version 2 as | ||
12 | * published by the Free Software Foundation. | ||
13 | */ | ||
14 | |||
15 | #include <linux/module.h> | ||
16 | #include <linux/kernel.h> | ||
17 | #include <linux/interrupt.h> | ||
18 | #include <linux/init.h> | ||
19 | #include <linux/platform_device.h> | ||
20 | |||
21 | #include <linux/gpio.h> | ||
22 | #include <linux/dm9000.h> | ||
23 | #include <linux/leds.h> | ||
24 | |||
25 | #include <linux/i2c.h> | ||
26 | #include <linux/i2c/pca953x.h> | ||
27 | |||
28 | #include <asm/mach-types.h> | ||
29 | #include <asm/mach/arch.h> | ||
30 | |||
31 | #include <mach/mfp-pxa300.h> | ||
32 | |||
33 | #include <mach/hardware.h> | ||
34 | #include <mach/gpio.h> | ||
35 | #include <mach/pxafb.h> | ||
36 | #include <mach/mmc.h> | ||
37 | #include <mach/ohci.h> | ||
38 | #include <mach/i2c.h> | ||
39 | #include <mach/pxa3xx_nand.h> | ||
40 | |||
41 | #include <asm/mach/map.h> | ||
42 | |||
43 | #include "generic.h" | ||
44 | |||
45 | #define CM_X300_ETH_PHYS 0x08000010 | ||
46 | |||
47 | #define GPIO82_MMC2_IRQ (82) | ||
48 | #define GPIO85_MMC2_WP (85) | ||
49 | |||
50 | #define CM_X300_MMC2_IRQ IRQ_GPIO(GPIO82_MMC2_IRQ) | ||
51 | |||
52 | static mfp_cfg_t cm_x300_mfp_cfg[] __initdata = { | ||
53 | /* LCD */ | ||
54 | GPIO54_LCD_LDD_0, | ||
55 | GPIO55_LCD_LDD_1, | ||
56 | GPIO56_LCD_LDD_2, | ||
57 | GPIO57_LCD_LDD_3, | ||
58 | GPIO58_LCD_LDD_4, | ||
59 | GPIO59_LCD_LDD_5, | ||
60 | GPIO60_LCD_LDD_6, | ||
61 | GPIO61_LCD_LDD_7, | ||
62 | GPIO62_LCD_LDD_8, | ||
63 | GPIO63_LCD_LDD_9, | ||
64 | GPIO64_LCD_LDD_10, | ||
65 | GPIO65_LCD_LDD_11, | ||
66 | GPIO66_LCD_LDD_12, | ||
67 | GPIO67_LCD_LDD_13, | ||
68 | GPIO68_LCD_LDD_14, | ||
69 | GPIO69_LCD_LDD_15, | ||
70 | GPIO72_LCD_FCLK, | ||
71 | GPIO73_LCD_LCLK, | ||
72 | GPIO74_LCD_PCLK, | ||
73 | GPIO75_LCD_BIAS, | ||
74 | |||
75 | /* BTUART */ | ||
76 | GPIO111_UART2_RTS, | ||
77 | GPIO112_UART2_RXD | MFP_LPM_EDGE_FALL, | ||
78 | GPIO113_UART2_TXD, | ||
79 | GPIO114_UART2_CTS | MFP_LPM_EDGE_BOTH, | ||
80 | |||
81 | /* STUART */ | ||
82 | GPIO109_UART3_TXD, | ||
83 | GPIO110_UART3_RXD | MFP_LPM_EDGE_FALL, | ||
84 | |||
85 | /* AC97 */ | ||
86 | GPIO23_AC97_nACRESET, | ||
87 | GPIO24_AC97_SYSCLK, | ||
88 | GPIO29_AC97_BITCLK, | ||
89 | GPIO25_AC97_SDATA_IN_0, | ||
90 | GPIO27_AC97_SDATA_OUT, | ||
91 | GPIO28_AC97_SYNC, | ||
92 | |||
93 | /* Keypad */ | ||
94 | GPIO115_KP_MKIN_0 | MFP_LPM_EDGE_BOTH, | ||
95 | GPIO116_KP_MKIN_1 | MFP_LPM_EDGE_BOTH, | ||
96 | GPIO117_KP_MKIN_2 | MFP_LPM_EDGE_BOTH, | ||
97 | GPIO118_KP_MKIN_3 | MFP_LPM_EDGE_BOTH, | ||
98 | GPIO119_KP_MKIN_4 | MFP_LPM_EDGE_BOTH, | ||
99 | GPIO120_KP_MKIN_5 | MFP_LPM_EDGE_BOTH, | ||
100 | GPIO2_2_KP_MKIN_6 | MFP_LPM_EDGE_BOTH, | ||
101 | GPIO3_2_KP_MKIN_7 | MFP_LPM_EDGE_BOTH, | ||
102 | GPIO121_KP_MKOUT_0, | ||
103 | GPIO122_KP_MKOUT_1, | ||
104 | GPIO123_KP_MKOUT_2, | ||
105 | GPIO124_KP_MKOUT_3, | ||
106 | GPIO125_KP_MKOUT_4, | ||
107 | GPIO4_2_KP_MKOUT_5, | ||
108 | |||
109 | /* MMC1 */ | ||
110 | GPIO3_MMC1_DAT0, | ||
111 | GPIO4_MMC1_DAT1 | MFP_LPM_EDGE_BOTH, | ||
112 | GPIO5_MMC1_DAT2, | ||
113 | GPIO6_MMC1_DAT3, | ||
114 | GPIO7_MMC1_CLK, | ||
115 | GPIO8_MMC1_CMD, /* CMD0 for slot 0 */ | ||
116 | |||
117 | /* MMC2 */ | ||
118 | GPIO9_MMC2_DAT0, | ||
119 | GPIO10_MMC2_DAT1 | MFP_LPM_EDGE_BOTH, | ||
120 | GPIO11_MMC2_DAT2, | ||
121 | GPIO12_MMC2_DAT3, | ||
122 | GPIO13_MMC2_CLK, | ||
123 | GPIO14_MMC2_CMD, | ||
124 | |||
125 | /* FFUART */ | ||
126 | GPIO30_UART1_RXD | MFP_LPM_EDGE_FALL, | ||
127 | GPIO31_UART1_TXD, | ||
128 | GPIO32_UART1_CTS, | ||
129 | GPIO37_UART1_RTS, | ||
130 | GPIO33_UART1_DCD, | ||
131 | GPIO34_UART1_DSR | MFP_LPM_EDGE_FALL, | ||
132 | GPIO35_UART1_RI, | ||
133 | GPIO36_UART1_DTR, | ||
134 | |||
135 | /* GPIOs */ | ||
136 | GPIO79_GPIO, /* LED */ | ||
137 | GPIO82_GPIO | MFP_PULL_HIGH, /* MMC CD */ | ||
138 | GPIO85_GPIO, /* MMC WP */ | ||
139 | GPIO99_GPIO, /* Ethernet IRQ */ | ||
140 | }; | ||
141 | |||
142 | #if defined(CONFIG_DM9000) || defined(CONFIG_DM9000_MODULE) | ||
143 | static struct resource dm9000_resources[] = { | ||
144 | [0] = { | ||
145 | .start = CM_X300_ETH_PHYS, | ||
146 | .end = CM_X300_ETH_PHYS + 0x3, | ||
147 | .flags = IORESOURCE_MEM, | ||
148 | }, | ||
149 | [1] = { | ||
150 | .start = CM_X300_ETH_PHYS + 0x4, | ||
151 | .end = CM_X300_ETH_PHYS + 0x4 + 500, | ||
152 | .flags = IORESOURCE_MEM, | ||
153 | }, | ||
154 | [2] = { | ||
155 | .start = IRQ_GPIO(mfp_to_gpio(MFP_PIN_GPIO99)), | ||
156 | .end = IRQ_GPIO(mfp_to_gpio(MFP_PIN_GPIO99)), | ||
157 | .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHEDGE, | ||
158 | } | ||
159 | }; | ||
160 | |||
161 | static struct dm9000_plat_data cm_x300_dm9000_platdata = { | ||
162 | .flags = DM9000_PLATF_16BITONLY, | ||
163 | }; | ||
164 | |||
165 | static struct platform_device dm9000_device = { | ||
166 | .name = "dm9000", | ||
167 | .id = 0, | ||
168 | .num_resources = ARRAY_SIZE(dm9000_resources), | ||
169 | .resource = dm9000_resources, | ||
170 | .dev = { | ||
171 | .platform_data = &cm_x300_dm9000_platdata, | ||
172 | } | ||
173 | |||
174 | }; | ||
175 | |||
176 | static void __init cm_x300_init_dm9000(void) | ||
177 | { | ||
178 | platform_device_register(&dm9000_device); | ||
179 | } | ||
180 | #else | ||
181 | static inline void cm_x300_init_dm9000(void) {} | ||
182 | #endif | ||
183 | |||
184 | #if defined(CONFIG_FB_PXA) || defined(CONFIG_FB_PXA_MODULE) | ||
185 | static struct pxafb_mode_info cm_x300_lcd_modes[] = { | ||
186 | [0] = { | ||
187 | .pixclock = 38000, | ||
188 | .bpp = 16, | ||
189 | .xres = 480, | ||
190 | .yres = 640, | ||
191 | .hsync_len = 8, | ||
192 | .vsync_len = 2, | ||
193 | .left_margin = 8, | ||
194 | .upper_margin = 0, | ||
195 | .right_margin = 24, | ||
196 | .lower_margin = 4, | ||
197 | .cmap_greyscale = 0, | ||
198 | }, | ||
199 | [1] = { | ||
200 | .pixclock = 153800, | ||
201 | .bpp = 16, | ||
202 | .xres = 240, | ||
203 | .yres = 320, | ||
204 | .hsync_len = 8, | ||
205 | .vsync_len = 2, | ||
206 | .left_margin = 8, | ||
207 | .upper_margin = 2, | ||
208 | .right_margin = 88, | ||
209 | .lower_margin = 2, | ||
210 | .cmap_greyscale = 0, | ||
211 | }, | ||
212 | }; | ||
213 | |||
214 | static struct pxafb_mach_info cm_x300_lcd = { | ||
215 | .modes = cm_x300_lcd_modes, | ||
216 | .num_modes = 2, | ||
217 | .lcd_conn = LCD_COLOR_TFT_16BPP | LCD_PCLK_EDGE_FALL, | ||
218 | }; | ||
219 | |||
220 | static void __init cm_x300_init_lcd(void) | ||
221 | { | ||
222 | set_pxa_fb_info(&cm_x300_lcd); | ||
223 | } | ||
224 | #else | ||
225 | static inline void cm_x300_init_lcd(void) {} | ||
226 | #endif | ||
227 | |||
228 | #if defined(CONFIG_MTD_NAND_PXA3xx) || defined(CONFIG_MTD_NAND_PXA3xx_MODULE) | ||
229 | static struct mtd_partition cm_x300_nand_partitions[] = { | ||
230 | [0] = { | ||
231 | .name = "OBM", | ||
232 | .offset = 0, | ||
233 | .size = SZ_256K, | ||
234 | .mask_flags = MTD_WRITEABLE, /* force read-only */ | ||
235 | }, | ||
236 | [1] = { | ||
237 | .name = "U-Boot", | ||
238 | .offset = MTDPART_OFS_APPEND, | ||
239 | .size = SZ_256K, | ||
240 | .mask_flags = MTD_WRITEABLE, /* force read-only */ | ||
241 | }, | ||
242 | [2] = { | ||
243 | .name = "Environment", | ||
244 | .offset = MTDPART_OFS_APPEND, | ||
245 | .size = SZ_256K, | ||
246 | }, | ||
247 | [3] = { | ||
248 | .name = "reserved", | ||
249 | .offset = MTDPART_OFS_APPEND, | ||
250 | .size = SZ_256K + SZ_1M, | ||
251 | .mask_flags = MTD_WRITEABLE, /* force read-only */ | ||
252 | }, | ||
253 | [4] = { | ||
254 | .name = "kernel", | ||
255 | .offset = MTDPART_OFS_APPEND, | ||
256 | .size = SZ_4M, | ||
257 | }, | ||
258 | [5] = { | ||
259 | .name = "fs", | ||
260 | .offset = MTDPART_OFS_APPEND, | ||
261 | .size = MTDPART_SIZ_FULL, | ||
262 | }, | ||
263 | }; | ||
264 | |||
265 | static struct pxa3xx_nand_platform_data cm_x300_nand_info = { | ||
266 | .enable_arbiter = 1, | ||
267 | .parts = cm_x300_nand_partitions, | ||
268 | .nr_parts = ARRAY_SIZE(cm_x300_nand_partitions), | ||
269 | }; | ||
270 | |||
271 | static void __init cm_x300_init_nand(void) | ||
272 | { | ||
273 | pxa3xx_set_nand_info(&cm_x300_nand_info); | ||
274 | } | ||
275 | #else | ||
276 | static inline void cm_x300_init_nand(void) {} | ||
277 | #endif | ||
278 | |||
279 | #if defined(CONFIG_MMC) || defined(CONFIG_MMC_MODULE) | ||
280 | /* The first MMC slot of CM-X300 is hardwired to Libertas card and has | ||
281 | no detection/ro pins */ | ||
282 | static int cm_x300_mci_init(struct device *dev, | ||
283 | irq_handler_t cm_x300_detect_int, | ||
284 | void *data) | ||
285 | { | ||
286 | return 0; | ||
287 | } | ||
288 | |||
289 | static void cm_x300_mci_exit(struct device *dev, void *data) | ||
290 | { | ||
291 | } | ||
292 | |||
293 | static struct pxamci_platform_data cm_x300_mci_platform_data = { | ||
294 | .detect_delay = 20, | ||
295 | .ocr_mask = MMC_VDD_32_33|MMC_VDD_33_34, | ||
296 | .init = cm_x300_mci_init, | ||
297 | .exit = cm_x300_mci_exit, | ||
298 | }; | ||
299 | |||
300 | static int cm_x300_mci2_ro(struct device *dev) | ||
301 | { | ||
302 | return gpio_get_value(GPIO85_MMC2_WP); | ||
303 | } | ||
304 | |||
305 | static int cm_x300_mci2_init(struct device *dev, | ||
306 | irq_handler_t cm_x300_detect_int, | ||
307 | void *data) | ||
308 | { | ||
309 | int err; | ||
310 | |||
311 | /* | ||
312 | * setup GPIO for CM-X300 MMC controller | ||
313 | */ | ||
314 | err = gpio_request(GPIO82_MMC2_IRQ, "mmc card detect"); | ||
315 | if (err) | ||
316 | goto err_request_cd; | ||
317 | gpio_direction_input(GPIO82_MMC2_IRQ); | ||
318 | |||
319 | err = gpio_request(GPIO85_MMC2_WP, "mmc write protect"); | ||
320 | if (err) | ||
321 | goto err_request_wp; | ||
322 | gpio_direction_input(GPIO85_MMC2_WP); | ||
323 | |||
324 | err = request_irq(CM_X300_MMC2_IRQ, cm_x300_detect_int, | ||
325 | IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING, | ||
326 | "MMC card detect", data); | ||
327 | if (err) { | ||
328 | printk(KERN_ERR "%s: MMC/SD/SDIO: " | ||
329 | "can't request card detect IRQ\n", __func__); | ||
330 | goto err_request_irq; | ||
331 | } | ||
332 | |||
333 | return 0; | ||
334 | |||
335 | err_request_irq: | ||
336 | gpio_free(GPIO85_MMC2_WP); | ||
337 | err_request_wp: | ||
338 | gpio_free(GPIO82_MMC2_IRQ); | ||
339 | err_request_cd: | ||
340 | return err; | ||
341 | } | ||
342 | |||
343 | static void cm_x300_mci2_exit(struct device *dev, void *data) | ||
344 | { | ||
345 | free_irq(CM_X300_MMC2_IRQ, data); | ||
346 | gpio_free(GPIO82_MMC2_IRQ); | ||
347 | gpio_free(GPIO85_MMC2_WP); | ||
348 | } | ||
349 | |||
350 | static struct pxamci_platform_data cm_x300_mci2_platform_data = { | ||
351 | .detect_delay = 20, | ||
352 | .ocr_mask = MMC_VDD_32_33|MMC_VDD_33_34, | ||
353 | .init = cm_x300_mci2_init, | ||
354 | .exit = cm_x300_mci2_exit, | ||
355 | .get_ro = cm_x300_mci2_ro, | ||
356 | }; | ||
357 | |||
358 | static void __init cm_x300_init_mmc(void) | ||
359 | { | ||
360 | pxa_set_mci_info(&cm_x300_mci_platform_data); | ||
361 | pxa3xx_set_mci2_info(&cm_x300_mci2_platform_data); | ||
362 | } | ||
363 | #else | ||
364 | static inline void cm_x300_init_mmc(void) {} | ||
365 | #endif | ||
366 | |||
367 | #if defined(CONFIG_USB_OHCI_HCD) || defined(CONFIG_USB_OHCI_HCD_MODULE) | ||
368 | static int cm_x300_ohci_init(struct device *dev) | ||
369 | { | ||
370 | /* Set the Power Control Polarity Low */ | ||
371 | UHCHR = (UHCHR | UHCHR_PCPL) & | ||
372 | ~(UHCHR_SSEP1 | UHCHR_SSEP2 | UHCHR_SSE); | ||
373 | |||
374 | return 0; | ||
375 | } | ||
376 | |||
377 | static struct pxaohci_platform_data cm_x300_ohci_platform_data = { | ||
378 | .port_mode = PMM_PERPORT_MODE, | ||
379 | .init = cm_x300_ohci_init, | ||
380 | }; | ||
381 | static void __init cm_x300_init_ohci(void) | ||
382 | { | ||
383 | pxa_set_ohci_info(&cm_x300_ohci_platform_data); | ||
384 | } | ||
385 | #else | ||
386 | static inline void cm_x300_init_ohci(void) {} | ||
387 | #endif | ||
388 | |||
389 | #if defined(CONFIG_LEDS_GPIO) || defined(CONFIG_LEDS_GPIO_MODULE) | ||
390 | static struct gpio_led cm_x300_leds[] = { | ||
391 | [0] = { | ||
392 | .name = "cm-x300:green", | ||
393 | .default_trigger = "heartbeat", | ||
394 | .gpio = 79, | ||
395 | .active_low = 1, | ||
396 | }, | ||
397 | }; | ||
398 | |||
399 | static struct gpio_led_platform_data cm_x300_gpio_led_pdata = { | ||
400 | .num_leds = ARRAY_SIZE(cm_x300_leds), | ||
401 | .leds = cm_x300_leds, | ||
402 | }; | ||
403 | |||
404 | static struct platform_device cm_x300_led_device = { | ||
405 | .name = "leds-gpio", | ||
406 | .id = -1, | ||
407 | .dev = { | ||
408 | .platform_data = &cm_x300_gpio_led_pdata, | ||
409 | }, | ||
410 | }; | ||
411 | |||
412 | static void __init cm_x300_init_leds(void) | ||
413 | { | ||
414 | platform_device_register(&cm_x300_led_device); | ||
415 | } | ||
416 | #else | ||
417 | static inline void cm_x300_init_leds(void) {} | ||
418 | #endif | ||
419 | |||
420 | #if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) | ||
421 | /* PCA9555 */ | ||
422 | static struct pca953x_platform_data cm_x300_gpio_ext_pdata_0 = { | ||
423 | .gpio_base = 128, | ||
424 | }; | ||
425 | |||
426 | static struct pca953x_platform_data cm_x300_gpio_ext_pdata_1 = { | ||
427 | .gpio_base = 144, | ||
428 | }; | ||
429 | |||
430 | static struct i2c_board_info cm_x300_gpio_ext_info[] = { | ||
431 | [0] = { | ||
432 | I2C_BOARD_INFO("pca9555", 0x24), | ||
433 | .platform_data = &cm_x300_gpio_ext_pdata_0, | ||
434 | }, | ||
435 | [1] = { | ||
436 | I2C_BOARD_INFO("pca9555", 0x25), | ||
437 | .platform_data = &cm_x300_gpio_ext_pdata_1, | ||
438 | }, | ||
439 | }; | ||
440 | |||
441 | static void __init cm_x300_init_i2c(void) | ||
442 | { | ||
443 | pxa_set_i2c_info(NULL); | ||
444 | i2c_register_board_info(0, cm_x300_gpio_ext_info, | ||
445 | ARRAY_SIZE(cm_x300_gpio_ext_info)); | ||
446 | } | ||
447 | #else | ||
448 | static inline void cm_x300_init_i2c(void) {} | ||
449 | #endif | ||
450 | |||
451 | static void __init cm_x300_init(void) | ||
452 | { | ||
453 | /* board-processor specific GPIO initialization */ | ||
454 | pxa3xx_mfp_config(ARRAY_AND_SIZE(cm_x300_mfp_cfg)); | ||
455 | |||
456 | cm_x300_init_dm9000(); | ||
457 | cm_x300_init_lcd(); | ||
458 | cm_x300_init_ohci(); | ||
459 | cm_x300_init_mmc(); | ||
460 | cm_x300_init_nand(); | ||
461 | cm_x300_init_leds(); | ||
462 | cm_x300_init_i2c(); | ||
463 | } | ||
464 | |||
465 | MACHINE_START(CM_X300, "CM-X300 module") | ||
466 | .phys_io = 0x40000000, | ||
467 | .boot_params = 0xa0000100, | ||
468 | .io_pg_offst = (io_p2v(0x40000000) >> 18) & 0xfffc, | ||
469 | .map_io = pxa_map_io, | ||
470 | .init_irq = pxa3xx_init_irq, | ||
471 | .timer = &pxa_timer, | ||
472 | .init_machine = cm_x300_init, | ||
473 | MACHINE_END | ||
diff --git a/arch/arm/mach-pxa/gumstix.c b/arch/arm/mach-pxa/gumstix.c index c0092472fa58..d8962a0fb98d 100644 --- a/arch/arm/mach-pxa/gumstix.c +++ b/arch/arm/mach-pxa/gumstix.c | |||
@@ -20,8 +20,12 @@ | |||
20 | #include <linux/init.h> | 20 | #include <linux/init.h> |
21 | #include <linux/platform_device.h> | 21 | #include <linux/platform_device.h> |
22 | #include <linux/interrupt.h> | 22 | #include <linux/interrupt.h> |
23 | #include <linux/delay.h> | ||
23 | #include <linux/mtd/mtd.h> | 24 | #include <linux/mtd/mtd.h> |
24 | #include <linux/mtd/partitions.h> | 25 | #include <linux/mtd/partitions.h> |
26 | #include <linux/gpio.h> | ||
27 | #include <linux/err.h> | ||
28 | #include <linux/clk.h> | ||
25 | 29 | ||
26 | #include <asm/setup.h> | 30 | #include <asm/setup.h> |
27 | #include <asm/memory.h> | 31 | #include <asm/memory.h> |
@@ -40,7 +44,7 @@ | |||
40 | 44 | ||
41 | #include <mach/pxa-regs.h> | 45 | #include <mach/pxa-regs.h> |
42 | #include <mach/pxa2xx-regs.h> | 46 | #include <mach/pxa2xx-regs.h> |
43 | #include <mach/pxa2xx-gpio.h> | 47 | #include <mach/mfp-pxa25x.h> |
44 | 48 | ||
45 | #include "generic.h" | 49 | #include "generic.h" |
46 | 50 | ||
@@ -85,21 +89,8 @@ static struct platform_device *devices[] __initdata = { | |||
85 | }; | 89 | }; |
86 | 90 | ||
87 | #ifdef CONFIG_MMC_PXA | 91 | #ifdef CONFIG_MMC_PXA |
88 | static struct pxamci_platform_data gumstix_mci_platform_data; | ||
89 | |||
90 | static int gumstix_mci_init(struct device *dev, irq_handler_t detect_int, | ||
91 | void *data) | ||
92 | { | ||
93 | pxa_gpio_mode(GPIO6_MMCCLK_MD); | ||
94 | pxa_gpio_mode(GPIO53_MMCCLK_MD); | ||
95 | pxa_gpio_mode(GPIO8_MMCCS0_MD); | ||
96 | |||
97 | return 0; | ||
98 | } | ||
99 | |||
100 | static struct pxamci_platform_data gumstix_mci_platform_data = { | 92 | static struct pxamci_platform_data gumstix_mci_platform_data = { |
101 | .ocr_mask = MMC_VDD_32_33|MMC_VDD_33_34, | 93 | .ocr_mask = MMC_VDD_32_33|MMC_VDD_33_34, |
102 | .init = gumstix_mci_init, | ||
103 | }; | 94 | }; |
104 | 95 | ||
105 | static void __init gumstix_mmc_init(void) | 96 | static void __init gumstix_mmc_init(void) |
@@ -109,11 +100,11 @@ static void __init gumstix_mmc_init(void) | |||
109 | #else | 100 | #else |
110 | static void __init gumstix_mmc_init(void) | 101 | static void __init gumstix_mmc_init(void) |
111 | { | 102 | { |
112 | printk(KERN_INFO "Gumstix mmc disabled\n"); | 103 | pr_debug("Gumstix mmc disabled\n"); |
113 | } | 104 | } |
114 | #endif | 105 | #endif |
115 | 106 | ||
116 | #ifdef CONFIG_USB_GADGET_PXA2XX | 107 | #ifdef CONFIG_USB_GADGET_PXA25X |
117 | static struct pxa2xx_udc_mach_info gumstix_udc_info __initdata = { | 108 | static struct pxa2xx_udc_mach_info gumstix_udc_info __initdata = { |
118 | .gpio_vbus = GPIO_GUMSTIX_USB_GPIOn, | 109 | .gpio_vbus = GPIO_GUMSTIX_USB_GPIOn, |
119 | .gpio_pullup = GPIO_GUMSTIX_USB_GPIOx, | 110 | .gpio_pullup = GPIO_GUMSTIX_USB_GPIOx, |
@@ -126,12 +117,87 @@ static void __init gumstix_udc_init(void) | |||
126 | #else | 117 | #else |
127 | static void gumstix_udc_init(void) | 118 | static void gumstix_udc_init(void) |
128 | { | 119 | { |
129 | printk(KERN_INFO "Gumstix udc is disabled\n"); | 120 | pr_debug("Gumstix udc is disabled\n"); |
130 | } | 121 | } |
131 | #endif | 122 | #endif |
132 | 123 | ||
124 | #ifdef CONFIG_BT | ||
125 | /* Normally, the bootloader would have enabled this 32kHz clock but many | ||
126 | ** boards still have u-boot 1.1.4 so we check if it has been turned on and | ||
127 | ** if not, we turn it on with a warning message. */ | ||
128 | static void gumstix_setup_bt_clock(void) | ||
129 | { | ||
130 | int timeout = 500; | ||
131 | |||
132 | if (!(OSCC & OSCC_OOK)) | ||
133 | pr_warning("32kHz clock was not on. Bootloader may need to " | ||
134 | "be updated\n"); | ||
135 | else | ||
136 | return; | ||
137 | |||
138 | OSCC |= OSCC_OON; | ||
139 | do { | ||
140 | if (OSCC & OSCC_OOK) | ||
141 | break; | ||
142 | udelay(1); | ||
143 | } while (--timeout); | ||
144 | if (!timeout) | ||
145 | pr_err("Failed to start 32kHz clock\n"); | ||
146 | } | ||
147 | |||
148 | static void __init gumstix_bluetooth_init(void) | ||
149 | { | ||
150 | int err; | ||
151 | |||
152 | gumstix_setup_bt_clock(); | ||
153 | |||
154 | err = gpio_request(GPIO_GUMSTIX_BTRESET, "BTRST"); | ||
155 | if (err) { | ||
156 | pr_err("gumstix: failed request gpio for bluetooth reset\n"); | ||
157 | return; | ||
158 | } | ||
159 | |||
160 | err = gpio_direction_output(GPIO_GUMSTIX_BTRESET, 1); | ||
161 | if (err) { | ||
162 | pr_err("gumstix: can't reset bluetooth\n"); | ||
163 | return; | ||
164 | } | ||
165 | gpio_set_value(GPIO_GUMSTIX_BTRESET, 0); | ||
166 | udelay(100); | ||
167 | gpio_set_value(GPIO_GUMSTIX_BTRESET, 1); | ||
168 | } | ||
169 | #else | ||
170 | static void gumstix_bluetooth_init(void) | ||
171 | { | ||
172 | pr_debug("Gumstix Bluetooth is disabled\n"); | ||
173 | } | ||
174 | #endif | ||
175 | |||
176 | static unsigned long gumstix_pin_config[] __initdata = { | ||
177 | GPIO12_32KHz, | ||
178 | /* BTUART */ | ||
179 | GPIO42_HWUART_RXD, | ||
180 | GPIO43_HWUART_TXD, | ||
181 | GPIO44_HWUART_CTS, | ||
182 | GPIO45_HWUART_RTS, | ||
183 | /* MMC */ | ||
184 | GPIO6_MMC_CLK, | ||
185 | GPIO53_MMC_CLK, | ||
186 | GPIO8_MMC_CS0, | ||
187 | /* these are used by AM200EPD */ | ||
188 | GPIO51_GPIO, | ||
189 | GPIO49_GPIO, | ||
190 | GPIO48_GPIO, | ||
191 | GPIO32_GPIO, | ||
192 | GPIO17_GPIO, | ||
193 | GPIO16_GPIO, | ||
194 | }; | ||
195 | |||
133 | static void __init gumstix_init(void) | 196 | static void __init gumstix_init(void) |
134 | { | 197 | { |
198 | pxa2xx_mfp_config(ARRAY_AND_SIZE(gumstix_pin_config)); | ||
199 | |||
200 | gumstix_bluetooth_init(); | ||
135 | gumstix_udc_init(); | 201 | gumstix_udc_init(); |
136 | gumstix_mmc_init(); | 202 | gumstix_mmc_init(); |
137 | (void) platform_add_devices(devices, ARRAY_SIZE(devices)); | 203 | (void) platform_add_devices(devices, ARRAY_SIZE(devices)); |
diff --git a/arch/arm/mach-pxa/include/mach/memory.h b/arch/arm/mach-pxa/include/mach/memory.h index 552eb7fa6579..59aef89808d6 100644 --- a/arch/arm/mach-pxa/include/mach/memory.h +++ b/arch/arm/mach-pxa/include/mach/memory.h | |||
@@ -40,11 +40,11 @@ | |||
40 | #define NODE_MEM_SIZE_BITS 26 | 40 | #define NODE_MEM_SIZE_BITS 26 |
41 | 41 | ||
42 | #if !defined(__ASSEMBLY__) && defined(CONFIG_MACH_ARMCORE) && defined(CONFIG_PCI) | 42 | #if !defined(__ASSEMBLY__) && defined(CONFIG_MACH_ARMCORE) && defined(CONFIG_PCI) |
43 | void cmx270_pci_adjust_zones(int node, unsigned long *size, | 43 | void cmx2xx_pci_adjust_zones(int node, unsigned long *size, |
44 | unsigned long *holes); | 44 | unsigned long *holes); |
45 | 45 | ||
46 | #define arch_adjust_zones(node, size, holes) \ | 46 | #define arch_adjust_zones(node, size, holes) \ |
47 | cmx270_pci_adjust_zones(node, size, holes) | 47 | cmx2xx_pci_adjust_zones(node, size, holes) |
48 | 48 | ||
49 | #define ISA_DMA_THRESHOLD (PHYS_OFFSET + SZ_64M - 1) | 49 | #define ISA_DMA_THRESHOLD (PHYS_OFFSET + SZ_64M - 1) |
50 | #endif | 50 | #endif |
diff --git a/arch/arm/mach-pxa/include/mach/mfp-pxa320.h b/arch/arm/mach-pxa/include/mach/mfp-pxa320.h index 74990510cf34..67f8385ea548 100644 --- a/arch/arm/mach-pxa/include/mach/mfp-pxa320.h +++ b/arch/arm/mach-pxa/include/mach/mfp-pxa320.h | |||
@@ -257,10 +257,10 @@ | |||
257 | #define GPIO38_SSP2_RXD MFP_CFG(GPIO38, AF2) | 257 | #define GPIO38_SSP2_RXD MFP_CFG(GPIO38, AF2) |
258 | #define GPIO38_SSP2_TXD MFP_CFG(GPIO38, AF5) | 258 | #define GPIO38_SSP2_TXD MFP_CFG(GPIO38, AF5) |
259 | 259 | ||
260 | #define GPIO69_SSP3_SCLK MFP_CFG(GPIO69, AF2, DS08X, FLOAT) | 260 | #define GPIO69_SSP3_SCLK MFP_CFG_X(GPIO69, AF2, DS08X, FLOAT) |
261 | #define GPIO70_SSP3_FRM MFP_CFG(GPIO70, AF2, DS08X, DRIVE_LOW) | 261 | #define GPIO70_SSP3_FRM MFP_CFG_X(GPIO70, AF2, DS08X, DRIVE_LOW) |
262 | #define GPIO89_SSP3_SCLK MFP_CFG(GPIO89, AF1, DS08X, FLOAT) | 262 | #define GPIO89_SSP3_SCLK MFP_CFG_X(GPIO89, AF1, DS08X, FLOAT) |
263 | #define GPIO90_SSP3_FRM MFP_CFG(GPIO90, AF1, DS08X, DRIVE_LOW) | 263 | #define GPIO90_SSP3_FRM MFP_CFG_X(GPIO90, AF1, DS08X, DRIVE_LOW) |
264 | #define GPIO71_SSP3_RXD MFP_CFG_X(GPIO71, AF5, DS08X, FLOAT) | 264 | #define GPIO71_SSP3_RXD MFP_CFG_X(GPIO71, AF5, DS08X, FLOAT) |
265 | #define GPIO71_SSP3_TXD MFP_CFG_X(GPIO71, AF2, DS08X, DRIVE_LOW) | 265 | #define GPIO71_SSP3_TXD MFP_CFG_X(GPIO71, AF2, DS08X, DRIVE_LOW) |
266 | #define GPIO72_SSP3_RXD MFP_CFG_X(GPIO72, AF2, DS08X, FLOAT) | 266 | #define GPIO72_SSP3_RXD MFP_CFG_X(GPIO72, AF2, DS08X, FLOAT) |
diff --git a/arch/arm/mach-pxa/include/mach/mioa701.h b/arch/arm/mach-pxa/include/mach/mioa701.h new file mode 100644 index 000000000000..8483cb511831 --- /dev/null +++ b/arch/arm/mach-pxa/include/mach/mioa701.h | |||
@@ -0,0 +1,67 @@ | |||
1 | #ifndef _MIOA701_H_ | ||
2 | #define _MIOA701_H_ | ||
3 | |||
4 | #define MIO_CFG_IN(pin, af) \ | ||
5 | ((MFP_CFG_DEFAULT & ~(MFP_AF_MASK | MFP_DIR_MASK)) |\ | ||
6 | (MFP_PIN(pin) | MFP_##af | MFP_DIR_IN)) | ||
7 | |||
8 | #define MIO_CFG_OUT(pin, af, state) \ | ||
9 | ((MFP_CFG_DEFAULT & ~(MFP_AF_MASK | MFP_DIR_MASK | MFP_LPM_STATE_MASK)) |\ | ||
10 | (MFP_PIN(pin) | MFP_##af | MFP_DIR_OUT | MFP_LPM_##state)) | ||
11 | |||
12 | /* Global GPIOs */ | ||
13 | #define GPIO9_CHARGE_nEN 9 | ||
14 | #define GPIO18_POWEROFF 18 | ||
15 | #define GPIO87_LCD_POWER 87 | ||
16 | |||
17 | /* USB */ | ||
18 | #define GPIO13_USB_DETECT 13 | ||
19 | #define GPIO22_USB_ENABLE 22 | ||
20 | |||
21 | /* SDIO bits */ | ||
22 | #define GPIO78_SDIO_RO 78 | ||
23 | #define GPIO15_SDIO_INSERT 15 | ||
24 | #define GPIO91_SDIO_EN 91 | ||
25 | |||
26 | /* Bluetooth */ | ||
27 | #define GPIO83_BT_ON 83 | ||
28 | |||
29 | /* GPS */ | ||
30 | #define GPIO23_GPS_UNKNOWN1 23 | ||
31 | #define GPIO26_GPS_ON 26 | ||
32 | #define GPIO27_GPS_RESET 27 | ||
33 | #define GPIO106_GPS_UNKNOWN2 106 | ||
34 | #define GPIO107_GPS_UNKNOWN3 107 | ||
35 | |||
36 | /* GSM */ | ||
37 | #define GPIO24_GSM_MOD_RESET_CMD 24 | ||
38 | #define GPIO88_GSM_nMOD_ON_CMD 88 | ||
39 | #define GPIO90_GSM_nMOD_OFF_CMD 90 | ||
40 | #define GPIO114_GSM_nMOD_DTE_UART_STATE 114 | ||
41 | #define GPIO25_GSM_MOD_ON_STATE 25 | ||
42 | #define GPIO113_GSM_EVENT 113 | ||
43 | |||
44 | /* SOUND */ | ||
45 | #define GPIO12_HPJACK_INSERT 12 | ||
46 | |||
47 | /* LEDS */ | ||
48 | #define GPIO10_LED_nCharging 10 | ||
49 | #define GPIO97_LED_nBlue 97 | ||
50 | #define GPIO98_LED_nOrange 98 | ||
51 | #define GPIO82_LED_nVibra 82 | ||
52 | #define GPIO115_LED_nKeyboard 115 | ||
53 | |||
54 | /* Keyboard */ | ||
55 | #define GPIO0_KEY_POWER 0 | ||
56 | #define GPIO93_KEY_VOLUME_UP 93 | ||
57 | #define GPIO94_KEY_VOLUME_DOWN 94 | ||
58 | |||
59 | extern struct input_dev *mioa701_evdev; | ||
60 | extern void mioa701_gpio_lpm_set(unsigned long mfp_pin); | ||
61 | |||
62 | /* Assembler externals mioa701_bootresume.S */ | ||
63 | extern u32 mioa701_bootstrap; | ||
64 | extern u32 mioa701_jumpaddr; | ||
65 | extern u32 mioa701_bootstrap_lg; | ||
66 | |||
67 | #endif /* _MIOA701_H */ | ||
diff --git a/arch/arm/mach-pxa/mioa701.c b/arch/arm/mach-pxa/mioa701.c new file mode 100644 index 000000000000..0842c531ee4d --- /dev/null +++ b/arch/arm/mach-pxa/mioa701.c | |||
@@ -0,0 +1,905 @@ | |||
1 | /* | ||
2 | * Handles the Mitac Mio A701 Board | ||
3 | * | ||
4 | * Copyright (C) 2008 Robert Jarzmik | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License as published by | ||
8 | * the Free Software Foundation; either version 2 of the License, or | ||
9 | * (at your option) any later version. | ||
10 | * | ||
11 | * This program is distributed in the hope that it will be useful, | ||
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
14 | * GNU General Public License for more details. | ||
15 | * | ||
16 | * You should have received a copy of the GNU General Public License | ||
17 | * along with this program; if not, write to the Free Software | ||
18 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
19 | * | ||
20 | */ | ||
21 | |||
22 | #include <linux/kernel.h> | ||
23 | #include <linux/init.h> | ||
24 | #include <linux/platform_device.h> | ||
25 | #include <linux/sysdev.h> | ||
26 | #include <linux/input.h> | ||
27 | #include <linux/delay.h> | ||
28 | #include <linux/gpio_keys.h> | ||
29 | #include <linux/pwm_backlight.h> | ||
30 | #include <linux/rtc.h> | ||
31 | #include <linux/leds.h> | ||
32 | #include <linux/gpio.h> | ||
33 | #include <linux/interrupt.h> | ||
34 | #include <linux/irq.h> | ||
35 | #include <linux/pda_power.h> | ||
36 | #include <linux/power_supply.h> | ||
37 | #include <linux/wm97xx.h> | ||
38 | #include <linux/mtd/physmap.h> | ||
39 | |||
40 | #include <asm/mach-types.h> | ||
41 | #include <asm/mach/arch.h> | ||
42 | #include <mach/mfp-pxa27x.h> | ||
43 | #include <mach/pxa27x_keypad.h> | ||
44 | #include <mach/pxafb.h> | ||
45 | #include <mach/pxa2xx-regs.h> | ||
46 | #include <mach/mmc.h> | ||
47 | #include <mach/udc.h> | ||
48 | #include <mach/pxa27x-udc.h> | ||
49 | |||
50 | #include <mach/mioa701.h> | ||
51 | |||
52 | #include "generic.h" | ||
53 | #include "devices.h" | ||
54 | |||
55 | static unsigned long mioa701_pin_config[] = { | ||
56 | /* Mio global */ | ||
57 | MIO_CFG_OUT(GPIO9_CHARGE_nEN, AF0, DRIVE_LOW), | ||
58 | MIO_CFG_OUT(GPIO18_POWEROFF, AF0, DRIVE_LOW), | ||
59 | MFP_CFG_OUT(GPIO3, AF0, DRIVE_HIGH), | ||
60 | MFP_CFG_OUT(GPIO4, AF0, DRIVE_HIGH), | ||
61 | |||
62 | /* Backlight PWM 0 */ | ||
63 | GPIO16_PWM0_OUT, | ||
64 | |||
65 | /* MMC */ | ||
66 | GPIO32_MMC_CLK, | ||
67 | GPIO92_MMC_DAT_0, | ||
68 | GPIO109_MMC_DAT_1, | ||
69 | GPIO110_MMC_DAT_2, | ||
70 | GPIO111_MMC_DAT_3, | ||
71 | GPIO112_MMC_CMD, | ||
72 | MIO_CFG_IN(GPIO78_SDIO_RO, AF0), | ||
73 | MIO_CFG_IN(GPIO15_SDIO_INSERT, AF0), | ||
74 | MIO_CFG_OUT(GPIO91_SDIO_EN, AF0, DRIVE_LOW), | ||
75 | |||
76 | /* USB */ | ||
77 | MIO_CFG_IN(GPIO13_USB_DETECT, AF0), | ||
78 | MIO_CFG_OUT(GPIO22_USB_ENABLE, AF0, DRIVE_LOW), | ||
79 | |||
80 | /* LCD */ | ||
81 | GPIO58_LCD_LDD_0, | ||
82 | GPIO59_LCD_LDD_1, | ||
83 | GPIO60_LCD_LDD_2, | ||
84 | GPIO61_LCD_LDD_3, | ||
85 | GPIO62_LCD_LDD_4, | ||
86 | GPIO63_LCD_LDD_5, | ||
87 | GPIO64_LCD_LDD_6, | ||
88 | GPIO65_LCD_LDD_7, | ||
89 | GPIO66_LCD_LDD_8, | ||
90 | GPIO67_LCD_LDD_9, | ||
91 | GPIO68_LCD_LDD_10, | ||
92 | GPIO69_LCD_LDD_11, | ||
93 | GPIO70_LCD_LDD_12, | ||
94 | GPIO71_LCD_LDD_13, | ||
95 | GPIO72_LCD_LDD_14, | ||
96 | GPIO73_LCD_LDD_15, | ||
97 | GPIO74_LCD_FCLK, | ||
98 | GPIO75_LCD_LCLK, | ||
99 | GPIO76_LCD_PCLK, | ||
100 | |||
101 | /* Bluetooth */ | ||
102 | GPIO44_BTUART_CTS, | ||
103 | GPIO42_BTUART_RXD, | ||
104 | GPIO45_BTUART_RTS, | ||
105 | GPIO43_BTUART_TXD, | ||
106 | MIO_CFG_OUT(GPIO83_BT_ON, AF0, DRIVE_LOW), | ||
107 | |||
108 | /* GPS */ | ||
109 | MIO_CFG_OUT(GPIO23_GPS_UNKNOWN1, AF0, DRIVE_LOW), | ||
110 | MIO_CFG_OUT(GPIO26_GPS_ON, AF0, DRIVE_LOW), | ||
111 | MIO_CFG_OUT(GPIO27_GPS_RESET, AF0, DRIVE_LOW), | ||
112 | MIO_CFG_OUT(GPIO106_GPS_UNKNOWN2, AF0, DRIVE_LOW), | ||
113 | MIO_CFG_OUT(GPIO107_GPS_UNKNOWN3, AF0, DRIVE_LOW), | ||
114 | GPIO46_STUART_RXD, | ||
115 | GPIO47_STUART_TXD, | ||
116 | |||
117 | /* GSM */ | ||
118 | MIO_CFG_OUT(GPIO24_GSM_MOD_RESET_CMD, AF0, DRIVE_LOW), | ||
119 | MIO_CFG_OUT(GPIO88_GSM_nMOD_ON_CMD, AF0, DRIVE_HIGH), | ||
120 | MIO_CFG_OUT(GPIO90_GSM_nMOD_OFF_CMD, AF0, DRIVE_HIGH), | ||
121 | MIO_CFG_OUT(GPIO114_GSM_nMOD_DTE_UART_STATE, AF0, DRIVE_HIGH), | ||
122 | MIO_CFG_IN(GPIO25_GSM_MOD_ON_STATE, AF0), | ||
123 | MIO_CFG_IN(GPIO113_GSM_EVENT, AF0) | WAKEUP_ON_EDGE_BOTH, | ||
124 | GPIO34_FFUART_RXD, | ||
125 | GPIO35_FFUART_CTS, | ||
126 | GPIO36_FFUART_DCD, | ||
127 | GPIO37_FFUART_DSR, | ||
128 | GPIO39_FFUART_TXD, | ||
129 | GPIO40_FFUART_DTR, | ||
130 | GPIO41_FFUART_RTS, | ||
131 | |||
132 | /* Sound */ | ||
133 | GPIO89_AC97_SYSCLK, | ||
134 | MIO_CFG_IN(GPIO12_HPJACK_INSERT, AF0), | ||
135 | |||
136 | /* Leds */ | ||
137 | MIO_CFG_OUT(GPIO10_LED_nCharging, AF0, DRIVE_HIGH), | ||
138 | MIO_CFG_OUT(GPIO97_LED_nBlue, AF0, DRIVE_HIGH), | ||
139 | MIO_CFG_OUT(GPIO98_LED_nOrange, AF0, DRIVE_HIGH), | ||
140 | MIO_CFG_OUT(GPIO82_LED_nVibra, AF0, DRIVE_HIGH), | ||
141 | MIO_CFG_OUT(GPIO115_LED_nKeyboard, AF0, DRIVE_HIGH), | ||
142 | |||
143 | /* Keyboard */ | ||
144 | MIO_CFG_IN(GPIO0_KEY_POWER, AF0) | WAKEUP_ON_EDGE_BOTH, | ||
145 | MIO_CFG_IN(GPIO93_KEY_VOLUME_UP, AF0), | ||
146 | MIO_CFG_IN(GPIO94_KEY_VOLUME_DOWN, AF0), | ||
147 | GPIO100_KP_MKIN_0, | ||
148 | GPIO101_KP_MKIN_1, | ||
149 | GPIO102_KP_MKIN_2, | ||
150 | GPIO103_KP_MKOUT_0, | ||
151 | GPIO104_KP_MKOUT_1, | ||
152 | GPIO105_KP_MKOUT_2, | ||
153 | |||
154 | /* Unknown */ | ||
155 | MFP_CFG_IN(GPIO14, AF0), | ||
156 | MFP_CFG_IN(GPIO20, AF0), | ||
157 | MFP_CFG_IN(GPIO21, AF0), | ||
158 | MFP_CFG_IN(GPIO33, AF0), | ||
159 | MFP_CFG_OUT(GPIO49, AF0, DRIVE_HIGH), | ||
160 | MFP_CFG_OUT(GPIO57, AF0, DRIVE_HIGH), | ||
161 | MFP_CFG_OUT(GPIO77, AF0, DRIVE_HIGH), | ||
162 | MFP_CFG_IN(GPIO80, AF0), | ||
163 | MFP_CFG_OUT(GPIO86, AF0, DRIVE_HIGH), | ||
164 | MFP_CFG_IN(GPIO96, AF0), | ||
165 | MFP_CFG_OUT(GPIO116, AF0, DRIVE_HIGH), | ||
166 | }; | ||
167 | |||
168 | #define MIO_GPIO_IN(num, _desc) \ | ||
169 | { .gpio = (num), .dir = 0, .desc = (_desc) } | ||
170 | #define MIO_GPIO_OUT(num, _init, _desc) \ | ||
171 | { .gpio = (num), .dir = 1, .init = (_init), .desc = (_desc) } | ||
172 | struct gpio_ress { | ||
173 | unsigned gpio : 8; | ||
174 | unsigned dir : 1; | ||
175 | unsigned init : 1; | ||
176 | char *desc; | ||
177 | }; | ||
178 | |||
179 | static int mio_gpio_request(struct gpio_ress *gpios, int size) | ||
180 | { | ||
181 | int i, rc = 0; | ||
182 | int gpio; | ||
183 | int dir; | ||
184 | |||
185 | for (i = 0; (!rc) && (i < size); i++) { | ||
186 | gpio = gpios[i].gpio; | ||
187 | dir = gpios[i].dir; | ||
188 | rc = gpio_request(gpio, gpios[i].desc); | ||
189 | if (rc) { | ||
190 | printk(KERN_ERR "Error requesting GPIO %d(%s) : %d\n", | ||
191 | gpio, gpios[i].desc, rc); | ||
192 | continue; | ||
193 | } | ||
194 | if (dir) | ||
195 | gpio_direction_output(gpio, gpios[i].init); | ||
196 | else | ||
197 | gpio_direction_input(gpio); | ||
198 | } | ||
199 | while ((rc) && (--i >= 0)) | ||
200 | gpio_free(gpios[i].gpio); | ||
201 | return rc; | ||
202 | } | ||
203 | |||
204 | static void mio_gpio_free(struct gpio_ress *gpios, int size) | ||
205 | { | ||
206 | int i; | ||
207 | |||
208 | for (i = 0; i < size; i++) | ||
209 | gpio_free(gpios[i].gpio); | ||
210 | } | ||
211 | |||
212 | /* LCD Screen and Backlight */ | ||
213 | static struct platform_pwm_backlight_data mioa701_backlight_data = { | ||
214 | .pwm_id = 0, | ||
215 | .max_brightness = 100, | ||
216 | .dft_brightness = 50, | ||
217 | .pwm_period_ns = 4000 * 1024, /* Fl = 250kHz */ | ||
218 | }; | ||
219 | |||
220 | /* | ||
221 | * LTM0305A776C LCD panel timings | ||
222 | * | ||
223 | * see: | ||
224 | * - the LTM0305A776C datasheet, | ||
225 | * - and the PXA27x Programmers' manual | ||
226 | */ | ||
227 | static struct pxafb_mode_info mioa701_ltm0305a776c = { | ||
228 | .pixclock = 220000, /* CLK=4.545 MHz */ | ||
229 | .xres = 240, | ||
230 | .yres = 320, | ||
231 | .bpp = 16, | ||
232 | .hsync_len = 4, | ||
233 | .vsync_len = 2, | ||
234 | .left_margin = 6, | ||
235 | .right_margin = 4, | ||
236 | .upper_margin = 5, | ||
237 | .lower_margin = 3, | ||
238 | }; | ||
239 | |||
240 | static void mioa701_lcd_power(int on, struct fb_var_screeninfo *si) | ||
241 | { | ||
242 | gpio_set_value(GPIO87_LCD_POWER, on); | ||
243 | } | ||
244 | |||
245 | static struct pxafb_mach_info mioa701_pxafb_info = { | ||
246 | .modes = &mioa701_ltm0305a776c, | ||
247 | .num_modes = 1, | ||
248 | .lcd_conn = LCD_COLOR_TFT_16BPP | LCD_PCLK_EDGE_FALL, | ||
249 | .pxafb_lcd_power = mioa701_lcd_power, | ||
250 | }; | ||
251 | |||
252 | /* | ||
253 | * Keyboard configuration | ||
254 | */ | ||
255 | static unsigned int mioa701_matrix_keys[] = { | ||
256 | KEY(0, 0, KEY_UP), | ||
257 | KEY(0, 1, KEY_RIGHT), | ||
258 | KEY(0, 2, KEY_MEDIA), | ||
259 | KEY(1, 0, KEY_DOWN), | ||
260 | KEY(1, 1, KEY_ENTER), | ||
261 | KEY(1, 2, KEY_CONNECT), /* GPS key */ | ||
262 | KEY(2, 0, KEY_LEFT), | ||
263 | KEY(2, 1, KEY_PHONE), /* Phone Green key */ | ||
264 | KEY(2, 2, KEY_CAMERA) /* Camera key */ | ||
265 | }; | ||
266 | static struct pxa27x_keypad_platform_data mioa701_keypad_info = { | ||
267 | .matrix_key_rows = 3, | ||
268 | .matrix_key_cols = 3, | ||
269 | .matrix_key_map = mioa701_matrix_keys, | ||
270 | .matrix_key_map_size = ARRAY_SIZE(mioa701_matrix_keys), | ||
271 | }; | ||
272 | |||
273 | /* | ||
274 | * GPIO Key Configuration | ||
275 | */ | ||
276 | #define MIO_KEY(key, _gpio, _desc, _wakeup) \ | ||
277 | { .code = (key), .gpio = (_gpio), .active_low = 0, \ | ||
278 | .desc = (_desc), .type = EV_KEY, .wakeup = (_wakeup) } | ||
279 | static struct gpio_keys_button mioa701_button_table[] = { | ||
280 | MIO_KEY(KEY_EXIT, GPIO0_KEY_POWER, "Power button", 1), | ||
281 | MIO_KEY(KEY_VOLUMEUP, GPIO93_KEY_VOLUME_UP, "Volume up", 0), | ||
282 | MIO_KEY(KEY_VOLUMEDOWN, GPIO94_KEY_VOLUME_DOWN, "Volume down", 0), | ||
283 | MIO_KEY(KEY_HP, GPIO12_HPJACK_INSERT, "HP jack detect", 0) | ||
284 | }; | ||
285 | |||
286 | static struct gpio_keys_platform_data mioa701_gpio_keys_data = { | ||
287 | .buttons = mioa701_button_table, | ||
288 | .nbuttons = ARRAY_SIZE(mioa701_button_table), | ||
289 | }; | ||
290 | |||
291 | /* | ||
292 | * Leds and vibrator | ||
293 | */ | ||
294 | #define ONE_LED(_gpio, _name) \ | ||
295 | { .gpio = (_gpio), .name = (_name), .active_low = true } | ||
296 | static struct gpio_led gpio_leds[] = { | ||
297 | ONE_LED(GPIO10_LED_nCharging, "mioa701:charging"), | ||
298 | ONE_LED(GPIO97_LED_nBlue, "mioa701:blue"), | ||
299 | ONE_LED(GPIO98_LED_nOrange, "mioa701:orange"), | ||
300 | ONE_LED(GPIO82_LED_nVibra, "mioa701:vibra"), | ||
301 | ONE_LED(GPIO115_LED_nKeyboard, "mioa701:keyboard") | ||
302 | }; | ||
303 | |||
304 | static struct gpio_led_platform_data gpio_led_info = { | ||
305 | .leds = gpio_leds, | ||
306 | .num_leds = ARRAY_SIZE(gpio_leds), | ||
307 | }; | ||
308 | |||
309 | /* | ||
310 | * GSM Sagem XS200 chip | ||
311 | * | ||
312 | * GSM handling was purged from kernel. For history, this is the way to go : | ||
313 | * - init : GPIO24_GSM_MOD_RESET_CMD = 0, GPIO114_GSM_nMOD_DTE_UART_STATE = 1 | ||
314 | * GPIO88_GSM_nMOD_ON_CMD = 1, GPIO90_GSM_nMOD_OFF_CMD = 1 | ||
315 | * - reset : GPIO24_GSM_MOD_RESET_CMD = 1, msleep(100), | ||
316 | * GPIO24_GSM_MOD_RESET_CMD = 0 | ||
317 | * - turn on : GPIO88_GSM_nMOD_ON_CMD = 0, msleep(1000), | ||
318 | * GPIO88_GSM_nMOD_ON_CMD = 1 | ||
319 | * - turn off : GPIO90_GSM_nMOD_OFF_CMD = 0, msleep(1000), | ||
320 | * GPIO90_GSM_nMOD_OFF_CMD = 1 | ||
321 | */ | ||
322 | static int is_gsm_on(void) | ||
323 | { | ||
324 | int is_on; | ||
325 | |||
326 | is_on = !!gpio_get_value(GPIO25_GSM_MOD_ON_STATE); | ||
327 | return is_on; | ||
328 | } | ||
329 | |||
330 | irqreturn_t gsm_on_irq(int irq, void *p) | ||
331 | { | ||
332 | printk(KERN_DEBUG "Mioa701: GSM status changed to %s\n", | ||
333 | is_gsm_on() ? "on" : "off"); | ||
334 | return IRQ_HANDLED; | ||
335 | } | ||
336 | |||
337 | struct gpio_ress gsm_gpios[] = { | ||
338 | MIO_GPIO_IN(GPIO25_GSM_MOD_ON_STATE, "GSM state"), | ||
339 | MIO_GPIO_IN(GPIO113_GSM_EVENT, "GSM event"), | ||
340 | }; | ||
341 | |||
342 | static int __init gsm_init(void) | ||
343 | { | ||
344 | int rc; | ||
345 | |||
346 | rc = mio_gpio_request(ARRAY_AND_SIZE(gsm_gpios)); | ||
347 | if (rc) | ||
348 | goto err_gpio; | ||
349 | rc = request_irq(gpio_to_irq(GPIO25_GSM_MOD_ON_STATE), gsm_on_irq, | ||
350 | IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING, | ||
351 | "GSM XS200 Power Irq", NULL); | ||
352 | if (rc) | ||
353 | goto err_irq; | ||
354 | |||
355 | gpio_set_wake(GPIO113_GSM_EVENT, 1); | ||
356 | return 0; | ||
357 | |||
358 | err_irq: | ||
359 | printk(KERN_ERR "Mioa701: Can't request GSM_ON irq\n"); | ||
360 | mio_gpio_free(ARRAY_AND_SIZE(gsm_gpios)); | ||
361 | err_gpio: | ||
362 | printk(KERN_ERR "Mioa701: gsm not available\n"); | ||
363 | return rc; | ||
364 | } | ||
365 | |||
366 | static void gsm_exit(void) | ||
367 | { | ||
368 | free_irq(gpio_to_irq(GPIO25_GSM_MOD_ON_STATE), NULL); | ||
369 | mio_gpio_free(ARRAY_AND_SIZE(gsm_gpios)); | ||
370 | } | ||
371 | |||
372 | /* | ||
373 | * Bluetooth BRF6150 chip | ||
374 | * | ||
375 | * BT handling was purged from kernel. For history, this is the way to go : | ||
376 | * - turn on : GPIO83_BT_ON = 1 | ||
377 | * - turn off : GPIO83_BT_ON = 0 | ||
378 | */ | ||
379 | |||
380 | /* | ||
381 | * GPS Sirf Star III chip | ||
382 | * | ||
383 | * GPS handling was purged from kernel. For history, this is the way to go : | ||
384 | * - init : GPIO23_GPS_UNKNOWN1 = 1, GPIO26_GPS_ON = 0, GPIO27_GPS_RESET = 0 | ||
385 | * GPIO106_GPS_UNKNOWN2 = 0, GPIO107_GPS_UNKNOWN3 = 0 | ||
386 | * - turn on : GPIO27_GPS_RESET = 1, GPIO26_GPS_ON = 1 | ||
387 | * - turn off : GPIO26_GPS_ON = 0, GPIO27_GPS_RESET = 0 | ||
388 | */ | ||
389 | |||
390 | /* | ||
391 | * USB UDC | ||
392 | */ | ||
393 | static void udc_power_command(int cmd) | ||
394 | { | ||
395 | switch (cmd) { | ||
396 | case PXA2XX_UDC_CMD_DISCONNECT: | ||
397 | gpio_set_value(GPIO22_USB_ENABLE, 0); | ||
398 | break; | ||
399 | case PXA2XX_UDC_CMD_CONNECT: | ||
400 | gpio_set_value(GPIO22_USB_ENABLE, 1); | ||
401 | break; | ||
402 | default: | ||
403 | printk(KERN_INFO "udc_control: unknown command (0x%x)!\n", cmd); | ||
404 | break; | ||
405 | } | ||
406 | } | ||
407 | |||
408 | static int is_usb_connected(void) | ||
409 | { | ||
410 | return !!gpio_get_value(GPIO13_USB_DETECT); | ||
411 | } | ||
412 | |||
413 | static struct pxa2xx_udc_mach_info mioa701_udc_info = { | ||
414 | .udc_is_connected = is_usb_connected, | ||
415 | .udc_command = udc_power_command, | ||
416 | }; | ||
417 | |||
418 | struct gpio_ress udc_gpios[] = { | ||
419 | MIO_GPIO_OUT(GPIO22_USB_ENABLE, 0, "USB Vbus enable") | ||
420 | }; | ||
421 | |||
422 | static int __init udc_init(void) | ||
423 | { | ||
424 | pxa_set_udc_info(&mioa701_udc_info); | ||
425 | return mio_gpio_request(ARRAY_AND_SIZE(udc_gpios)); | ||
426 | } | ||
427 | |||
428 | static void udc_exit(void) | ||
429 | { | ||
430 | mio_gpio_free(ARRAY_AND_SIZE(udc_gpios)); | ||
431 | } | ||
432 | |||
433 | /* | ||
434 | * SDIO/MMC Card controller | ||
435 | */ | ||
436 | static void mci_setpower(struct device *dev, unsigned int vdd) | ||
437 | { | ||
438 | struct pxamci_platform_data *p_d = dev->platform_data; | ||
439 | |||
440 | if ((1 << vdd) & p_d->ocr_mask) | ||
441 | gpio_set_value(GPIO91_SDIO_EN, 1); /* enable SDIO power */ | ||
442 | else | ||
443 | gpio_set_value(GPIO91_SDIO_EN, 0); /* disable SDIO power */ | ||
444 | } | ||
445 | |||
446 | static int mci_get_ro(struct device *dev) | ||
447 | { | ||
448 | return gpio_get_value(GPIO78_SDIO_RO); | ||
449 | } | ||
450 | |||
451 | struct gpio_ress mci_gpios[] = { | ||
452 | MIO_GPIO_IN(GPIO78_SDIO_RO, "SDIO readonly detect"), | ||
453 | MIO_GPIO_IN(GPIO15_SDIO_INSERT, "SDIO insertion detect"), | ||
454 | MIO_GPIO_OUT(GPIO91_SDIO_EN, 0, "SDIO power enable") | ||
455 | }; | ||
456 | |||
457 | static void mci_exit(struct device *dev, void *data) | ||
458 | { | ||
459 | mio_gpio_free(ARRAY_AND_SIZE(mci_gpios)); | ||
460 | free_irq(gpio_to_irq(GPIO15_SDIO_INSERT), data); | ||
461 | } | ||
462 | |||
463 | static struct pxamci_platform_data mioa701_mci_info; | ||
464 | |||
465 | /** | ||
466 | * The card detect interrupt isn't debounced so we delay it by 250ms | ||
467 | * to give the card a chance to fully insert/eject. | ||
468 | */ | ||
469 | static int mci_init(struct device *dev, irq_handler_t detect_int, void *data) | ||
470 | { | ||
471 | int rc; | ||
472 | int irq = gpio_to_irq(GPIO15_SDIO_INSERT); | ||
473 | |||
474 | rc = mio_gpio_request(ARRAY_AND_SIZE(mci_gpios)); | ||
475 | if (rc) | ||
476 | goto err_gpio; | ||
477 | /* enable RE/FE interrupt on card insertion and removal */ | ||
478 | rc = request_irq(irq, detect_int, | ||
479 | IRQF_DISABLED | IRQF_TRIGGER_RISING | | ||
480 | IRQF_TRIGGER_FALLING, | ||
481 | "MMC card detect", data); | ||
482 | if (rc) | ||
483 | goto err_irq; | ||
484 | |||
485 | mioa701_mci_info.detect_delay = msecs_to_jiffies(250); | ||
486 | return 0; | ||
487 | |||
488 | err_irq: | ||
489 | dev_err(dev, "mioa701_mci_init: MMC/SD:" | ||
490 | " can't request MMC card detect IRQ\n"); | ||
491 | mio_gpio_free(ARRAY_AND_SIZE(mci_gpios)); | ||
492 | err_gpio: | ||
493 | return rc; | ||
494 | } | ||
495 | |||
496 | static struct pxamci_platform_data mioa701_mci_info = { | ||
497 | .ocr_mask = MMC_VDD_32_33 | MMC_VDD_33_34, | ||
498 | .init = mci_init, | ||
499 | .get_ro = mci_get_ro, | ||
500 | .setpower = mci_setpower, | ||
501 | .exit = mci_exit, | ||
502 | }; | ||
503 | |||
504 | /* FlashRAM */ | ||
505 | static struct resource strataflash_resource = { | ||
506 | .start = PXA_CS0_PHYS, | ||
507 | .end = PXA_CS0_PHYS + SZ_64M - 1, | ||
508 | .flags = IORESOURCE_MEM, | ||
509 | }; | ||
510 | |||
511 | static struct physmap_flash_data strataflash_data = { | ||
512 | .width = 2, | ||
513 | /* .set_vpp = mioa701_set_vpp, */ | ||
514 | }; | ||
515 | |||
516 | static struct platform_device strataflash = { | ||
517 | .name = "physmap-flash", | ||
518 | .id = -1, | ||
519 | .resource = &strataflash_resource, | ||
520 | .num_resources = 1, | ||
521 | .dev = { | ||
522 | .platform_data = &strataflash_data, | ||
523 | }, | ||
524 | }; | ||
525 | |||
526 | /* | ||
527 | * Suspend/Resume bootstrap management | ||
528 | * | ||
529 | * MIO A701 reboot sequence is highly ROM dependant. From the one dissassembled, | ||
530 | * this sequence is as follows : | ||
531 | * - disables interrupts | ||
532 | * - initialize SDRAM (self refresh RAM into active RAM) | ||
533 | * - initialize GPIOs (depends on value at 0xa020b020) | ||
534 | * - initialize coprossessors | ||
535 | * - if edge detect on PWR_SCL(GPIO3), then proceed to cold start | ||
536 | * - or if value at 0xa020b000 not equal to 0x0f0f0f0f, proceed to cold start | ||
537 | * - else do a resume, ie. jump to addr 0xa0100000 | ||
538 | */ | ||
539 | #define RESUME_ENABLE_ADDR 0xa020b000 | ||
540 | #define RESUME_ENABLE_VAL 0x0f0f0f0f | ||
541 | #define RESUME_BT_ADDR 0xa020b020 | ||
542 | #define RESUME_UNKNOWN_ADDR 0xa020b024 | ||
543 | #define RESUME_VECTOR_ADDR 0xa0100000 | ||
544 | #define BOOTSTRAP_WORDS mioa701_bootstrap_lg/4 | ||
545 | |||
546 | static u32 *save_buffer; | ||
547 | |||
548 | static void install_bootstrap(void) | ||
549 | { | ||
550 | int i; | ||
551 | u32 *rom_bootstrap = phys_to_virt(RESUME_VECTOR_ADDR); | ||
552 | u32 *src = &mioa701_bootstrap; | ||
553 | |||
554 | for (i = 0; i < BOOTSTRAP_WORDS; i++) | ||
555 | rom_bootstrap[i] = src[i]; | ||
556 | } | ||
557 | |||
558 | |||
559 | static int mioa701_sys_suspend(struct sys_device *sysdev, pm_message_t state) | ||
560 | { | ||
561 | int i = 0, is_bt_on; | ||
562 | u32 *mem_resume_vector = phys_to_virt(RESUME_VECTOR_ADDR); | ||
563 | u32 *mem_resume_enabler = phys_to_virt(RESUME_ENABLE_ADDR); | ||
564 | u32 *mem_resume_bt = phys_to_virt(RESUME_BT_ADDR); | ||
565 | u32 *mem_resume_unknown = phys_to_virt(RESUME_UNKNOWN_ADDR); | ||
566 | |||
567 | /* Devices prepare suspend */ | ||
568 | is_bt_on = gpio_get_value(GPIO83_BT_ON); | ||
569 | pxa2xx_mfp_set_lpm(GPIO83_BT_ON, | ||
570 | is_bt_on ? MFP_LPM_DRIVE_HIGH : MFP_LPM_DRIVE_LOW); | ||
571 | |||
572 | for (i = 0; i < BOOTSTRAP_WORDS; i++) | ||
573 | save_buffer[i] = mem_resume_vector[i]; | ||
574 | save_buffer[i++] = *mem_resume_enabler; | ||
575 | save_buffer[i++] = *mem_resume_bt; | ||
576 | save_buffer[i++] = *mem_resume_unknown; | ||
577 | |||
578 | *mem_resume_enabler = RESUME_ENABLE_VAL; | ||
579 | *mem_resume_bt = is_bt_on; | ||
580 | |||
581 | install_bootstrap(); | ||
582 | return 0; | ||
583 | } | ||
584 | |||
585 | static int mioa701_sys_resume(struct sys_device *sysdev) | ||
586 | { | ||
587 | int i = 0; | ||
588 | u32 *mem_resume_vector = phys_to_virt(RESUME_VECTOR_ADDR); | ||
589 | u32 *mem_resume_enabler = phys_to_virt(RESUME_ENABLE_ADDR); | ||
590 | u32 *mem_resume_bt = phys_to_virt(RESUME_BT_ADDR); | ||
591 | u32 *mem_resume_unknown = phys_to_virt(RESUME_UNKNOWN_ADDR); | ||
592 | |||
593 | for (i = 0; i < BOOTSTRAP_WORDS; i++) | ||
594 | mem_resume_vector[i] = save_buffer[i]; | ||
595 | *mem_resume_enabler = save_buffer[i++]; | ||
596 | *mem_resume_bt = save_buffer[i++]; | ||
597 | *mem_resume_unknown = save_buffer[i++]; | ||
598 | |||
599 | return 0; | ||
600 | } | ||
601 | |||
602 | static struct sysdev_class mioa701_sysclass = { | ||
603 | .name = "mioa701", | ||
604 | }; | ||
605 | |||
606 | static struct sys_device sysdev_bootstrap = { | ||
607 | .cls = &mioa701_sysclass, | ||
608 | }; | ||
609 | |||
610 | static struct sysdev_driver driver_bootstrap = { | ||
611 | .suspend = &mioa701_sys_suspend, | ||
612 | .resume = &mioa701_sys_resume, | ||
613 | }; | ||
614 | |||
615 | static int __init bootstrap_init(void) | ||
616 | { | ||
617 | int rc; | ||
618 | int save_size = mioa701_bootstrap_lg + (sizeof(u32) * 3); | ||
619 | |||
620 | rc = sysdev_class_register(&mioa701_sysclass); | ||
621 | if (rc) { | ||
622 | printk(KERN_ERR "Failed registering mioa701 sys class\n"); | ||
623 | return -ENODEV; | ||
624 | } | ||
625 | rc = sysdev_register(&sysdev_bootstrap); | ||
626 | if (rc) { | ||
627 | printk(KERN_ERR "Failed registering mioa701 sys device\n"); | ||
628 | return -ENODEV; | ||
629 | } | ||
630 | rc = sysdev_driver_register(&mioa701_sysclass, &driver_bootstrap); | ||
631 | if (rc) { | ||
632 | printk(KERN_ERR "Failed registering PMU sys driver\n"); | ||
633 | return -ENODEV; | ||
634 | } | ||
635 | |||
636 | save_buffer = kmalloc(save_size, GFP_KERNEL); | ||
637 | if (!save_buffer) | ||
638 | return -ENOMEM; | ||
639 | printk(KERN_INFO "MioA701: allocated %d bytes for bootstrap\n", | ||
640 | save_size); | ||
641 | return 0; | ||
642 | } | ||
643 | |||
644 | static void bootstrap_exit(void) | ||
645 | { | ||
646 | kfree(save_buffer); | ||
647 | sysdev_driver_unregister(&mioa701_sysclass, &driver_bootstrap); | ||
648 | sysdev_unregister(&sysdev_bootstrap); | ||
649 | sysdev_class_unregister(&mioa701_sysclass); | ||
650 | |||
651 | printk(KERN_CRIT "Unregistering mioa701 suspend will hang next" | ||
652 | "resume !!!\n"); | ||
653 | } | ||
654 | |||
655 | /* | ||
656 | * Power Supply | ||
657 | */ | ||
658 | static char *supplicants[] = { | ||
659 | "mioa701_battery" | ||
660 | }; | ||
661 | |||
662 | static void mioa701_set_charge(int flags) | ||
663 | { | ||
664 | gpio_set_value(GPIO9_CHARGE_nEN, !flags); | ||
665 | } | ||
666 | |||
667 | static struct pda_power_pdata power_pdata = { | ||
668 | .is_ac_online = is_usb_connected, | ||
669 | .set_charge = mioa701_set_charge, | ||
670 | .supplied_to = supplicants, | ||
671 | .num_supplicants = ARRAY_SIZE(supplicants), | ||
672 | }; | ||
673 | |||
674 | static struct resource power_resources[] = { | ||
675 | [0] = { | ||
676 | .name = "ac", | ||
677 | .start = gpio_to_irq(GPIO13_USB_DETECT), | ||
678 | .end = gpio_to_irq(GPIO13_USB_DETECT), | ||
679 | .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHEDGE | | ||
680 | IORESOURCE_IRQ_LOWEDGE, | ||
681 | }, | ||
682 | }; | ||
683 | |||
684 | static struct platform_device power_dev = { | ||
685 | .name = "pda-power", | ||
686 | .id = -1, | ||
687 | .resource = power_resources, | ||
688 | .num_resources = ARRAY_SIZE(power_resources), | ||
689 | .dev = { | ||
690 | .platform_data = &power_pdata, | ||
691 | }, | ||
692 | }; | ||
693 | |||
694 | #if defined(CONFIG_PDA_POWER) && defined(CONFIG_TOUCHSCREEN_WM97XX) | ||
695 | static struct wm97xx *battery_wm; | ||
696 | |||
697 | static enum power_supply_property battery_props[] = { | ||
698 | POWER_SUPPLY_PROP_STATUS, | ||
699 | POWER_SUPPLY_PROP_VOLTAGE_MAX_DESIGN, | ||
700 | POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN, | ||
701 | POWER_SUPPLY_PROP_VOLTAGE_NOW, | ||
702 | POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN, /* Necessary for apm */ | ||
703 | }; | ||
704 | |||
705 | static int get_battery_voltage(void) | ||
706 | { | ||
707 | int adc = -1; | ||
708 | |||
709 | if (battery_wm) | ||
710 | adc = wm97xx_read_aux_adc(battery_wm, WM97XX_AUX_ID1); | ||
711 | return adc; | ||
712 | } | ||
713 | |||
714 | static int get_battery_status(struct power_supply *b) | ||
715 | { | ||
716 | int status; | ||
717 | |||
718 | if (is_usb_connected()) | ||
719 | status = POWER_SUPPLY_STATUS_CHARGING; | ||
720 | else | ||
721 | status = POWER_SUPPLY_STATUS_DISCHARGING; | ||
722 | |||
723 | return status; | ||
724 | } | ||
725 | |||
726 | static int get_property(struct power_supply *b, | ||
727 | enum power_supply_property psp, | ||
728 | union power_supply_propval *val) | ||
729 | { | ||
730 | int rc = 0; | ||
731 | |||
732 | switch (psp) { | ||
733 | case POWER_SUPPLY_PROP_STATUS: | ||
734 | val->intval = get_battery_status(b); | ||
735 | break; | ||
736 | case POWER_SUPPLY_PROP_VOLTAGE_MAX_DESIGN: | ||
737 | val->intval = 0xfd0; | ||
738 | break; | ||
739 | case POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN: | ||
740 | val->intval = 0xc00; | ||
741 | break; | ||
742 | case POWER_SUPPLY_PROP_VOLTAGE_NOW: | ||
743 | val->intval = get_battery_voltage(); | ||
744 | break; | ||
745 | case POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN: | ||
746 | val->intval = 100; | ||
747 | break; | ||
748 | default: | ||
749 | val->intval = -1; | ||
750 | rc = -1; | ||
751 | } | ||
752 | |||
753 | return rc; | ||
754 | }; | ||
755 | |||
756 | static struct power_supply battery_ps = { | ||
757 | .name = "mioa701_battery", | ||
758 | .type = POWER_SUPPLY_TYPE_BATTERY, | ||
759 | .get_property = get_property, | ||
760 | .properties = battery_props, | ||
761 | .num_properties = ARRAY_SIZE(battery_props), | ||
762 | }; | ||
763 | |||
764 | static int battery_probe(struct platform_device *pdev) | ||
765 | { | ||
766 | struct wm97xx *wm = platform_get_drvdata(pdev); | ||
767 | int rc; | ||
768 | |||
769 | battery_wm = wm; | ||
770 | |||
771 | rc = power_supply_register(NULL, &battery_ps); | ||
772 | if (rc) | ||
773 | dev_err(&pdev->dev, | ||
774 | "Could not register mioa701 battery -> %d\n", rc); | ||
775 | return rc; | ||
776 | } | ||
777 | |||
778 | static int battery_remove(struct platform_device *pdev) | ||
779 | { | ||
780 | battery_wm = NULL; | ||
781 | return 0; | ||
782 | } | ||
783 | |||
784 | static struct platform_driver mioa701_battery_driver = { | ||
785 | .driver = { | ||
786 | .name = "wm97xx-battery", | ||
787 | }, | ||
788 | .probe = battery_probe, | ||
789 | .remove = battery_remove | ||
790 | }; | ||
791 | |||
792 | static int __init mioa701_battery_init(void) | ||
793 | { | ||
794 | int rc; | ||
795 | |||
796 | rc = platform_driver_register(&mioa701_battery_driver); | ||
797 | if (rc) | ||
798 | printk(KERN_ERR "Could not register mioa701 battery driver\n"); | ||
799 | return rc; | ||
800 | } | ||
801 | |||
802 | #else | ||
803 | static int __init mioa701_battery_init(void) | ||
804 | { | ||
805 | return 0; | ||
806 | } | ||
807 | #endif | ||
808 | |||
809 | /* | ||
810 | * Mio global | ||
811 | */ | ||
812 | |||
813 | /* Devices */ | ||
814 | #define MIO_PARENT_DEV(var, strname, tparent, pdata) \ | ||
815 | static struct platform_device var = { \ | ||
816 | .name = strname, \ | ||
817 | .id = -1, \ | ||
818 | .dev = { \ | ||
819 | .platform_data = pdata, \ | ||
820 | .parent = tparent, \ | ||
821 | }, \ | ||
822 | }; | ||
823 | #define MIO_SIMPLE_DEV(var, strname, pdata) \ | ||
824 | MIO_PARENT_DEV(var, strname, NULL, pdata) | ||
825 | |||
826 | MIO_SIMPLE_DEV(mioa701_gpio_keys, "gpio-keys", &mioa701_gpio_keys_data) | ||
827 | MIO_PARENT_DEV(mioa701_backlight, "pwm-backlight", &pxa27x_device_pwm0.dev, | ||
828 | &mioa701_backlight_data); | ||
829 | MIO_SIMPLE_DEV(mioa701_led, "leds-gpio", &gpio_led_info) | ||
830 | MIO_SIMPLE_DEV(pxa2xx_pcm, "pxa2xx-pcm", NULL) | ||
831 | MIO_SIMPLE_DEV(pxa2xx_ac97, "pxa2xx-ac97", NULL) | ||
832 | MIO_PARENT_DEV(mio_wm9713_codec, "wm9713-codec", &pxa2xx_ac97.dev, NULL) | ||
833 | MIO_SIMPLE_DEV(mioa701_sound, "mioa701-wm9713", NULL) | ||
834 | MIO_SIMPLE_DEV(mioa701_board, "mioa701-board", NULL) | ||
835 | |||
836 | static struct platform_device *devices[] __initdata = { | ||
837 | &mioa701_gpio_keys, | ||
838 | &mioa701_backlight, | ||
839 | &mioa701_led, | ||
840 | &pxa2xx_pcm, | ||
841 | &pxa2xx_ac97, | ||
842 | &mio_wm9713_codec, | ||
843 | &mioa701_sound, | ||
844 | &power_dev, | ||
845 | &strataflash, | ||
846 | &mioa701_board | ||
847 | }; | ||
848 | |||
849 | static void mioa701_machine_exit(void); | ||
850 | |||
851 | static void mioa701_poweroff(void) | ||
852 | { | ||
853 | mioa701_machine_exit(); | ||
854 | gpio_set_value(GPIO18_POWEROFF, 1); | ||
855 | } | ||
856 | |||
857 | static void mioa701_restart(char c) | ||
858 | { | ||
859 | mioa701_machine_exit(); | ||
860 | arm_machine_restart(c); | ||
861 | } | ||
862 | |||
863 | struct gpio_ress global_gpios[] = { | ||
864 | MIO_GPIO_OUT(GPIO9_CHARGE_nEN, 1, "Charger enable"), | ||
865 | MIO_GPIO_OUT(GPIO18_POWEROFF, 0, "Power Off"), | ||
866 | MIO_GPIO_OUT(GPIO87_LCD_POWER, 0, "LCD Power") | ||
867 | }; | ||
868 | |||
869 | static void __init mioa701_machine_init(void) | ||
870 | { | ||
871 | PSLR = 0xff100000; /* SYSDEL=125ms, PWRDEL=125ms, PSLR_SL_ROD=1 */ | ||
872 | PCFR = PCFR_DC_EN | PCFR_GPR_EN | PCFR_OPDE; | ||
873 | RTTR = 32768 - 1; /* Reset crazy WinCE value */ | ||
874 | UP2OCR = UP2OCR_HXOE; | ||
875 | |||
876 | pxa2xx_mfp_config(ARRAY_AND_SIZE(mioa701_pin_config)); | ||
877 | mio_gpio_request(ARRAY_AND_SIZE(global_gpios)); | ||
878 | bootstrap_init(); | ||
879 | set_pxa_fb_info(&mioa701_pxafb_info); | ||
880 | pxa_set_mci_info(&mioa701_mci_info); | ||
881 | pxa_set_keypad_info(&mioa701_keypad_info); | ||
882 | udc_init(); | ||
883 | pm_power_off = mioa701_poweroff; | ||
884 | arm_pm_restart = mioa701_restart; | ||
885 | platform_add_devices(devices, ARRAY_SIZE(devices)); | ||
886 | gsm_init(); | ||
887 | mioa701_battery_init(); | ||
888 | } | ||
889 | |||
890 | static void mioa701_machine_exit(void) | ||
891 | { | ||
892 | udc_exit(); | ||
893 | bootstrap_exit(); | ||
894 | gsm_exit(); | ||
895 | } | ||
896 | |||
897 | MACHINE_START(MIOA701, "MIO A701") | ||
898 | .phys_io = 0x40000000, | ||
899 | .io_pg_offst = (io_p2v(0x40000000) >> 18) & 0xfffc, | ||
900 | .boot_params = 0xa0000100, | ||
901 | .map_io = &pxa_map_io, | ||
902 | .init_irq = &pxa27x_init_irq, | ||
903 | .init_machine = mioa701_machine_init, | ||
904 | .timer = &pxa_timer, | ||
905 | MACHINE_END | ||
diff --git a/arch/arm/mach-pxa/mioa701_bootresume.S b/arch/arm/mach-pxa/mioa701_bootresume.S new file mode 100644 index 000000000000..a647693d9856 --- /dev/null +++ b/arch/arm/mach-pxa/mioa701_bootresume.S | |||
@@ -0,0 +1,36 @@ | |||
1 | /* Bootloader to resume MIO A701 | ||
2 | * | ||
3 | * 2007-1-12 Robert Jarzmik | ||
4 | * | ||
5 | * This code is licenced under the GPLv2. | ||
6 | */ | ||
7 | |||
8 | #include <linux/linkage.h> | ||
9 | #include <asm/assembler.h> | ||
10 | |||
11 | /* | ||
12 | * Note: Yes, part of the following code is located into the .data section. | ||
13 | * This is to allow jumpaddr to be accessed with a relative load | ||
14 | * while we can't rely on any MMU translation. We could have put | ||
15 | * sleep_save_sp in the .text section as well, but some setups might | ||
16 | * insist on it to be truly read-only. | ||
17 | */ | ||
18 | .data | ||
19 | ENTRY(mioa701_bootstrap) | ||
20 | 0: | ||
21 | b 1f | ||
22 | ENTRY(mioa701_jumpaddr) | ||
23 | .word 0x40f00008 @ PSPR in no-MMU mode | ||
24 | 1: | ||
25 | mov r0, #0xa0000000 @ Don't suppose memory access works | ||
26 | orr r0, r0, #0x00200000 @ even if it's supposed to | ||
27 | mov r1, #0 | ||
28 | str r1, [r0] @ Early disable resume for next boot | ||
29 | ldr r0, mioa701_jumpaddr @ (Murphy's Law) | ||
30 | ldr r0, [r0] | ||
31 | mov pc, r0 | ||
32 | 2: | ||
33 | |||
34 | ENTRY(mioa701_bootstrap_lg) | ||
35 | .data | ||
36 | .word 2b-0b | ||
diff --git a/arch/arm/mach-pxa/mp900.c b/arch/arm/mach-pxa/mp900.c new file mode 100644 index 000000000000..8a73814126b1 --- /dev/null +++ b/arch/arm/mach-pxa/mp900.c | |||
@@ -0,0 +1,100 @@ | |||
1 | /* | ||
2 | * linux/arch/arm/mach-pxa/mp900.c | ||
3 | * | ||
4 | * Support for the NEC MobilePro900/C platform | ||
5 | * | ||
6 | * Based on mach-pxa/gumstix.c | ||
7 | * | ||
8 | * 2007, 2008 Kristoffer Ericson <kristoffer.ericson@gmail.com> | ||
9 | * 2007, 2008 Michael Petchkovsky <mkpetch@internode.on.net> | ||
10 | * | ||
11 | * This program is free software; you can redistribute it and/or modify | ||
12 | * it under the terms of the GNU General Public License version 2 as | ||
13 | * published by the Free Software Foundation. | ||
14 | */ | ||
15 | |||
16 | #include <linux/init.h> | ||
17 | #include <linux/device.h> | ||
18 | #include <linux/platform_device.h> | ||
19 | #include <linux/types.h> | ||
20 | #include <linux/usb/isp116x.h> | ||
21 | |||
22 | #include <mach/hardware.h> | ||
23 | #include <mach/pxa-regs.h> | ||
24 | #include <asm/mach-types.h> | ||
25 | #include <asm/mach/arch.h> | ||
26 | #include "generic.h" | ||
27 | |||
28 | static void isp116x_pfm_delay(struct device *dev, int delay) | ||
29 | { | ||
30 | |||
31 | /* 400Mhz PXA2 = 2.5ns / instruction */ | ||
32 | |||
33 | int cyc = delay / 10; | ||
34 | |||
35 | /* 4 Instructions = 4 x 2.5ns = 10ns */ | ||
36 | __asm__ volatile ("0:\n" | ||
37 | "subs %0, %1, #1\n" | ||
38 | "bge 0b\n" | ||
39 | :"=r" (cyc) | ||
40 | :"0"(cyc) | ||
41 | ); | ||
42 | } | ||
43 | |||
44 | static struct isp116x_platform_data isp116x_pfm_data = { | ||
45 | .remote_wakeup_enable = 1, | ||
46 | .delay = isp116x_pfm_delay, | ||
47 | }; | ||
48 | |||
49 | static struct resource isp116x_pfm_resources[] = { | ||
50 | [0] = { | ||
51 | .start = 0x0d000000, | ||
52 | .end = 0x0d000000 + 1, | ||
53 | .flags = IORESOURCE_MEM, | ||
54 | }, | ||
55 | [1] = { | ||
56 | .start = 0x0d000000 + 4, | ||
57 | .end = 0x0d000000 + 5, | ||
58 | .flags = IORESOURCE_MEM, | ||
59 | }, | ||
60 | [2] = { | ||
61 | .start = 61, | ||
62 | .end = 61, | ||
63 | .flags = IORESOURCE_IRQ, | ||
64 | }, | ||
65 | }; | ||
66 | |||
67 | static struct platform_device mp900c_dummy_device = { | ||
68 | .name = "mp900c_dummy", | ||
69 | .id = -1, | ||
70 | }; | ||
71 | |||
72 | static struct platform_device mp900c_usb = { | ||
73 | .name = "isp116x-hcd", | ||
74 | .num_resources = ARRAY_SIZE(isp116x_pfm_resources), | ||
75 | .resource = isp116x_pfm_resources, | ||
76 | .dev.platform_data = &isp116x_pfm_data, | ||
77 | }; | ||
78 | |||
79 | static struct platform_device *devices[] __initdata = { | ||
80 | &mp900c_dummy_device, | ||
81 | &mp900c_usb, | ||
82 | }; | ||
83 | |||
84 | static void __init mp900c_init(void) | ||
85 | { | ||
86 | printk(KERN_INFO "MobilePro 900/C machine init\n"); | ||
87 | platform_add_devices(devices, ARRAY_SIZE(devices)); | ||
88 | } | ||
89 | |||
90 | /* Maintainer - Michael Petchkovsky <mkpetch@internode.on.net> */ | ||
91 | MACHINE_START(NEC_MP900, "MobilePro900/C") | ||
92 | .phys_io = 0x40000000, | ||
93 | .boot_params = 0xa0220100, | ||
94 | .io_pg_offst = (io_p2v(0x40000000) >> 18) & 0xfffc, | ||
95 | .timer = &pxa_timer, | ||
96 | .map_io = pxa_map_io, | ||
97 | .init_irq = pxa25x_init_irq, | ||
98 | .init_machine = mp900c_init, | ||
99 | MACHINE_END | ||
100 | |||
diff --git a/arch/arm/mach-pxa/zylonite_pxa300.c b/arch/arm/mach-pxa/zylonite_pxa300.c index 095f5c648236..1f4d7c052c22 100644 --- a/arch/arm/mach-pxa/zylonite_pxa300.c +++ b/arch/arm/mach-pxa/zylonite_pxa300.c | |||
@@ -73,6 +73,12 @@ static mfp_cfg_t common_mfp_cfg[] __initdata = { | |||
73 | GPIO27_AC97_SDATA_OUT, | 73 | GPIO27_AC97_SDATA_OUT, |
74 | GPIO28_AC97_SYNC, | 74 | GPIO28_AC97_SYNC, |
75 | 75 | ||
76 | /* SSP3 */ | ||
77 | GPIO91_SSP3_SCLK, | ||
78 | GPIO92_SSP3_FRM, | ||
79 | GPIO93_SSP3_TXD, | ||
80 | GPIO94_SSP3_RXD, | ||
81 | |||
76 | /* WM9713 IRQ */ | 82 | /* WM9713 IRQ */ |
77 | GPIO26_GPIO, | 83 | GPIO26_GPIO, |
78 | 84 | ||
@@ -209,7 +215,7 @@ static struct pca953x_platform_data gpio_exp[] = { | |||
209 | }, | 215 | }, |
210 | }; | 216 | }; |
211 | 217 | ||
212 | struct i2c_board_info zylonite_i2c_board_info[] = { | 218 | static struct i2c_board_info zylonite_i2c_board_info[] = { |
213 | { | 219 | { |
214 | .type = "pca9539", | 220 | .type = "pca9539", |
215 | .addr = 0x74, | 221 | .addr = 0x74, |
diff --git a/arch/arm/mach-pxa/zylonite_pxa320.c b/arch/arm/mach-pxa/zylonite_pxa320.c index 9879d7da2df5..755e87fa8ab9 100644 --- a/arch/arm/mach-pxa/zylonite_pxa320.c +++ b/arch/arm/mach-pxa/zylonite_pxa320.c | |||
@@ -69,6 +69,12 @@ static mfp_cfg_t mfp_cfg[] __initdata = { | |||
69 | GPIO39_AC97_BITCLK, | 69 | GPIO39_AC97_BITCLK, |
70 | GPIO40_AC97_nACRESET, | 70 | GPIO40_AC97_nACRESET, |
71 | 71 | ||
72 | /* SSP3 */ | ||
73 | GPIO89_SSP3_SCLK, | ||
74 | GPIO90_SSP3_FRM, | ||
75 | GPIO91_SSP3_TXD, | ||
76 | GPIO92_SSP3_RXD, | ||
77 | |||
72 | /* WM9713 IRQ */ | 78 | /* WM9713 IRQ */ |
73 | GPIO15_GPIO, | 79 | GPIO15_GPIO, |
74 | 80 | ||