blob: 00f0c897e5f81795f14a68d30d9496479afd6447 [file] [log] [blame]
Linus Torvalds1da177e2005-04-16 15:20:36 -07001/*
2 * linux/arch/arm/mach-pxa/poodle.c
3 *
4 * Support for the SHARP Poodle Board.
5 *
6 * Based on:
7 * linux/arch/arm/mach-pxa/lubbock.c Author: Nicolas Pitre
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License version 2 as
11 * published by the Free Software Foundation.
12 *
13 * Change Log
14 * 12-Dec-2002 Sharp Corporation for Poodle
15 * John Lenz <lenz@cs.wisc.edu> updates to 2.6
16 */
17#include <linux/kernel.h>
18#include <linux/init.h>
Russell Kingd052d1b2005-10-29 19:07:23 +010019#include <linux/platform_device.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070020#include <linux/fb.h>
Richard Purdie74617fb2006-06-19 19:57:12 +010021#include <linux/pm.h>
Richard Purdie88660352006-06-19 19:58:51 +010022#include <linux/delay.h>
Eric Miaoce5291472008-07-18 08:59:04 +080023#include <linux/gpio.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070024
Russell Kinga09e64f2008-08-05 16:14:15 +010025#include <mach/hardware.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070026#include <asm/mach-types.h>
27#include <asm/irq.h>
28#include <asm/setup.h>
Richard Purdie74617fb2006-06-19 19:57:12 +010029#include <asm/system.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070030
31#include <asm/mach/arch.h>
32#include <asm/mach/map.h>
33#include <asm/mach/irq.h>
34
Russell Kinga09e64f2008-08-05 16:14:15 +010035#include <mach/pxa-regs.h>
36#include <mach/pxa2xx-regs.h>
37#include <mach/pxa2xx-gpio.h>
38#include <mach/mmc.h>
39#include <mach/udc.h>
Mark Brownf8787fd2008-08-26 13:30:03 +010040#include <mach/i2c.h>
Russell Kinga09e64f2008-08-05 16:14:15 +010041#include <mach/irda.h>
42#include <mach/poodle.h>
43#include <mach/pxafb.h>
44#include <mach/sharpsl.h>
45#include <mach/ssp.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070046
47#include <asm/hardware/scoop.h>
48#include <asm/hardware/locomo.h>
49#include <asm/mach/sharpsl_param.h>
50
51#include "generic.h"
Russell King46c41e62007-05-15 15:39:36 +010052#include "devices.h"
Richard Purdiefaed5682006-06-19 20:46:05 +010053#include "sharpsl.h"
Linus Torvalds1da177e2005-04-16 15:20:36 -070054
55static struct resource poodle_scoop_resources[] = {
56 [0] = {
57 .start = 0x10800000,
58 .end = 0x10800fff,
59 .flags = IORESOURCE_MEM,
60 },
61};
62
63static struct scoop_config poodle_scoop_setup = {
64 .io_dir = POODLE_SCOOP_IO_DIR,
65 .io_out = POODLE_SCOOP_IO_OUT,
66};
67
68struct platform_device poodle_scoop_device = {
69 .name = "sharp-scoop",
70 .id = -1,
71 .dev = {
72 .platform_data = &poodle_scoop_setup,
73 },
74 .num_resources = ARRAY_SIZE(poodle_scoop_resources),
75 .resource = poodle_scoop_resources,
76};
77
Richard Purdiea63ae442005-11-08 19:15:43 +000078static void poodle_pcmcia_init(void)
79{
80 /* Setup default state of GPIO outputs
81 before we enable them as outputs. */
82 GPSR(GPIO48_nPOE) = GPIO_bit(GPIO48_nPOE) |
83 GPIO_bit(GPIO49_nPWE) | GPIO_bit(GPIO50_nPIOR) |
84 GPIO_bit(GPIO51_nPIOW) | GPIO_bit(GPIO52_nPCE_1) |
85 GPIO_bit(GPIO53_nPCE_2);
86
87 pxa_gpio_mode(GPIO48_nPOE_MD);
88 pxa_gpio_mode(GPIO49_nPWE_MD);
89 pxa_gpio_mode(GPIO50_nPIOR_MD);
90 pxa_gpio_mode(GPIO51_nPIOW_MD);
91 pxa_gpio_mode(GPIO55_nPREG_MD);
92 pxa_gpio_mode(GPIO56_nPWAIT_MD);
93 pxa_gpio_mode(GPIO57_nIOIS16_MD);
94 pxa_gpio_mode(GPIO52_nPCE_1_MD);
95 pxa_gpio_mode(GPIO53_nPCE_2_MD);
96 pxa_gpio_mode(GPIO54_pSKTSEL_MD);
97}
98
Richard Purdie0ce76252005-09-05 20:49:54 +010099static struct scoop_pcmcia_dev poodle_pcmcia_scoop[] = {
100{
101 .dev = &poodle_scoop_device.dev,
102 .irq = POODLE_IRQ_GPIO_CF_IRQ,
103 .cd_irq = POODLE_IRQ_GPIO_CF_CD,
104 .cd_irq_str = "PCMCIA0 CD",
105},
106};
107
Richard Purdiea63ae442005-11-08 19:15:43 +0000108static struct scoop_pcmcia_config poodle_pcmcia_config = {
109 .devs = &poodle_pcmcia_scoop[0],
110 .num_devs = 1,
111 .pcmcia_init = poodle_pcmcia_init,
112};
113
114EXPORT_SYMBOL(poodle_scoop_device);
115
Linus Torvalds1da177e2005-04-16 15:20:36 -0700116
117/* LoCoMo device */
118static struct resource locomo_resources[] = {
119 [0] = {
120 .start = 0x10000000,
121 .end = 0x10001fff,
122 .flags = IORESOURCE_MEM,
123 },
124 [1] = {
125 .start = IRQ_GPIO(10),
126 .end = IRQ_GPIO(10),
127 .flags = IORESOURCE_IRQ,
128 },
129};
130
Richard Purdiefaed5682006-06-19 20:46:05 +0100131struct platform_device poodle_locomo_device = {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700132 .name = "locomo",
133 .id = 0,
134 .num_resources = ARRAY_SIZE(locomo_resources),
135 .resource = locomo_resources,
136};
137
Richard Purdiefaed5682006-06-19 20:46:05 +0100138EXPORT_SYMBOL(poodle_locomo_device);
139
140/*
141 * Poodle SSP Device
142 */
143
144struct platform_device poodle_ssp_device = {
145 .name = "corgi-ssp",
146 .id = -1,
147};
148
149struct corgissp_machinfo poodle_ssp_machinfo = {
150 .port = 1,
151 .cs_lcdcon = -1,
152 .cs_ads7846 = -1,
153 .cs_max1111 = -1,
154 .clk_lcdcon = 2,
155 .clk_ads7846 = 36,
156 .clk_max1111 = 2,
157};
158
159
160/*
161 * Poodle Touch Screen Device
162 */
163static struct resource poodlets_resources[] = {
164 [0] = {
165 .start = POODLE_IRQ_GPIO_TP_INT,
166 .end = POODLE_IRQ_GPIO_TP_INT,
167 .flags = IORESOURCE_IRQ,
168 },
169};
170
eric miao6a0bd092008-01-31 02:41:16 +0100171static unsigned long poodle_get_hsync_invperiod(void)
Richard Purdiefaed5682006-06-19 20:46:05 +0100172{
173 return 0;
174}
175
176static void poodle_null_hsync(void)
177{
178}
179
180static struct corgits_machinfo poodle_ts_machinfo = {
eric miao6a0bd092008-01-31 02:41:16 +0100181 .get_hsync_invperiod = poodle_get_hsync_invperiod,
182 .put_hsync = poodle_null_hsync,
183 .wait_hsync = poodle_null_hsync,
Richard Purdiefaed5682006-06-19 20:46:05 +0100184};
185
186static struct platform_device poodle_ts_device = {
187 .name = "corgi-ts",
188 .dev = {
189 .platform_data = &poodle_ts_machinfo,
190 },
191 .id = -1,
192 .num_resources = ARRAY_SIZE(poodlets_resources),
193 .resource = poodlets_resources,
194};
195
Richard Purdie13b9d472005-09-15 14:53:22 +0100196
197/*
198 * MMC/SD Device
199 *
200 * The card detect interrupt isn't debounced so we delay it by 250ms
201 * to give the card a chance to fully insert/eject.
202 */
203static struct pxamci_platform_data poodle_mci_platform_data;
204
David Howells40220c12006-10-09 12:19:47 +0100205static int poodle_mci_init(struct device *dev, irq_handler_t poodle_detect_int, void *data)
Richard Purdie13b9d472005-09-15 14:53:22 +0100206{
207 int err;
208
209 /* setup GPIO for PXA25x MMC controller */
210 pxa_gpio_mode(GPIO6_MMCCLK_MD);
211 pxa_gpio_mode(GPIO8_MMCCS0_MD);
Eric Miaoce5291472008-07-18 08:59:04 +0800212
213 err = gpio_request(POODLE_GPIO_nSD_DETECT, "nSD_DETECT");
214 if (err)
215 goto err_out;
216
217 err = gpio_request(POODLE_GPIO_nSD_WP, "nSD_WP");
218 if (err)
219 goto err_free_1;
220
221 err = gpio_request(POODLE_GPIO_SD_PWR, "SD_PWR");
222 if (err)
223 goto err_free_2;
224
225 err = gpio_request(POODLE_GPIO_SD_PWR1, "SD_PWR1");
226 if (err)
227 goto err_free_3;
228
229 gpio_direction_input(POODLE_GPIO_nSD_DETECT);
230 gpio_direction_input(POODLE_GPIO_nSD_WP);
231
232 gpio_direction_output(POODLE_GPIO_SD_PWR, 0);
233 gpio_direction_output(POODLE_GPIO_SD_PWR1, 0);
Richard Purdie13b9d472005-09-15 14:53:22 +0100234
235 poodle_mci_platform_data.detect_delay = msecs_to_jiffies(250);
236
Russell King9ded96f2006-01-08 01:02:07 -0800237 err = request_irq(POODLE_IRQ_GPIO_nSD_DETECT, poodle_detect_int,
Thomas Gleixner52e405e2006-07-03 02:20:05 +0200238 IRQF_DISABLED | IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING,
Russell King9ded96f2006-01-08 01:02:07 -0800239 "MMC card detect", data);
Eric Miaoce5291472008-07-18 08:59:04 +0800240 if (err) {
241 pr_err("%s: MMC/SD: can't request MMC card detect IRQ\n",
242 __func__);
243 goto err_free_4;
244 }
Richard Purdie13b9d472005-09-15 14:53:22 +0100245
Eric Miaoce5291472008-07-18 08:59:04 +0800246 return 0;
247
248err_free_4:
249 gpio_free(POODLE_GPIO_SD_PWR1);
250err_free_3:
251 gpio_free(POODLE_GPIO_SD_PWR);
252err_free_2:
253 gpio_free(POODLE_GPIO_nSD_WP);
254err_free_1:
255 gpio_free(POODLE_GPIO_nSD_DETECT);
256err_out:
Russell King2687bd32008-01-23 14:05:58 +0000257 return err;
Richard Purdie13b9d472005-09-15 14:53:22 +0100258}
259
260static void poodle_mci_setpower(struct device *dev, unsigned int vdd)
261{
262 struct pxamci_platform_data* p_d = dev->platform_data;
263
Eric Miaoce5291472008-07-18 08:59:04 +0800264 if ((1 << vdd) & p_d->ocr_mask) {
265 gpio_set_value(POODLE_GPIO_SD_PWR, 1);
Richard Purdie88660352006-06-19 19:58:51 +0100266 mdelay(2);
Eric Miaoce5291472008-07-18 08:59:04 +0800267 gpio_set_value(POODLE_GPIO_SD_PWR1, 1);
Richard Purdie88660352006-06-19 19:58:51 +0100268 } else {
Eric Miaoce5291472008-07-18 08:59:04 +0800269 gpio_set_value(POODLE_GPIO_SD_PWR1, 0);
270 gpio_set_value(POODLE_GPIO_SD_PWR, 0);
Richard Purdie88660352006-06-19 19:58:51 +0100271 }
Richard Purdie13b9d472005-09-15 14:53:22 +0100272}
273
Richard Purdie88660352006-06-19 19:58:51 +0100274static int poodle_mci_get_ro(struct device *dev)
275{
Eric Miaoce5291472008-07-18 08:59:04 +0800276 return !!gpio_get_value(POODLE_GPIO_nSD_WP);
Richard Purdie88660352006-06-19 19:58:51 +0100277 return GPLR(POODLE_GPIO_nSD_WP) & GPIO_bit(POODLE_GPIO_nSD_WP);
278}
279
280
Richard Purdie13b9d472005-09-15 14:53:22 +0100281static void poodle_mci_exit(struct device *dev, void *data)
282{
283 free_irq(POODLE_IRQ_GPIO_nSD_DETECT, data);
Eric Miaoce5291472008-07-18 08:59:04 +0800284 gpio_free(POODLE_GPIO_SD_PWR1);
285 gpio_free(POODLE_GPIO_SD_PWR);
286 gpio_free(POODLE_GPIO_nSD_WP);
287 gpio_free(POODLE_GPIO_nSD_DETECT);
Richard Purdie13b9d472005-09-15 14:53:22 +0100288}
289
290static struct pxamci_platform_data poodle_mci_platform_data = {
291 .ocr_mask = MMC_VDD_32_33|MMC_VDD_33_34,
292 .init = poodle_mci_init,
Richard Purdie88660352006-06-19 19:58:51 +0100293 .get_ro = poodle_mci_get_ro,
Richard Purdie13b9d472005-09-15 14:53:22 +0100294 .setpower = poodle_mci_setpower,
295 .exit = poodle_mci_exit,
296};
297
298
299/*
Richard Purdie8e4b8712005-10-30 14:38:52 +0000300 * Irda
301 */
302static void poodle_irda_transceiver_mode(struct device *dev, int mode)
303{
Eric Miaoce5291472008-07-18 08:59:04 +0800304 gpio_set_value(POODLE_GPIO_IR_ON, mode & IR_OFF);
Dmitry Baryshkov0fc3ff32008-07-02 13:54:46 +0100305 pxa2xx_transceiver_mode(dev, mode);
Richard Purdie8e4b8712005-10-30 14:38:52 +0000306}
307
Eric Miaoce5291472008-07-18 08:59:04 +0800308static int poodle_irda_startup(struct device *dev)
309{
310 int err;
311
312 err = gpio_request(POODLE_GPIO_IR_ON, "IR_ON");
313 if (err)
314 return err;
315
316 gpio_direction_output(POODLE_GPIO_IR_ON, 1);
317 return 0;
318}
319
320static void poodle_irda_shutdown(struct device *dev)
321{
322 gpio_free(POODLE_GPIO_IR_ON);
323}
324
Richard Purdie8e4b8712005-10-30 14:38:52 +0000325static struct pxaficp_platform_data poodle_ficp_platform_data = {
Eric Miaoce5291472008-07-18 08:59:04 +0800326 .transceiver_cap = IR_SIRMODE | IR_OFF,
327 .transceiver_mode = poodle_irda_transceiver_mode,
328 .startup = poodle_irda_startup,
329 .shutdown = poodle_irda_shutdown,
Richard Purdie8e4b8712005-10-30 14:38:52 +0000330};
331
332
333/*
Richard Purdie13b9d472005-09-15 14:53:22 +0100334 * USB Device Controller
335 */
Richard Purdie13b9d472005-09-15 14:53:22 +0100336static struct pxa2xx_udc_mach_info udc_info __initdata = {
337 /* no connect GPIO; poodle can't tell connection status */
Eric Miao1730aad2008-07-18 08:51:07 +0800338 .gpio_pullup = POODLE_GPIO_USB_PULLUP,
Richard Purdie13b9d472005-09-15 14:53:22 +0100339};
340
341
Linus Torvalds1da177e2005-04-16 15:20:36 -0700342/* PXAFB device */
Richard Purdied14b2722006-09-20 22:54:21 +0100343static struct pxafb_mode_info poodle_fb_mode = {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700344 .pixclock = 144700,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700345 .xres = 320,
346 .yres = 240,
347 .bpp = 16,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700348 .hsync_len = 7,
349 .left_margin = 11,
350 .right_margin = 30,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700351 .vsync_len = 2,
352 .upper_margin = 2,
353 .lower_margin = 0,
354 .sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
Richard Purdied14b2722006-09-20 22:54:21 +0100355};
Linus Torvalds1da177e2005-04-16 15:20:36 -0700356
Richard Purdied14b2722006-09-20 22:54:21 +0100357static struct pxafb_mach_info poodle_fb_info = {
358 .modes = &poodle_fb_mode,
359 .num_modes = 1,
Eric Miaocf5eb8c2008-07-18 08:53:52 +0800360 .lcd_conn = LCD_COLOR_TFT_16BPP,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700361};
362
363static struct platform_device *devices[] __initdata = {
Richard Purdiefaed5682006-06-19 20:46:05 +0100364 &poodle_locomo_device,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700365 &poodle_scoop_device,
Richard Purdiefaed5682006-06-19 20:46:05 +0100366 &poodle_ssp_device,
367 &poodle_ts_device,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700368};
369
Richard Purdie74617fb2006-06-19 19:57:12 +0100370static void poodle_poweroff(void)
371{
Richard Purdie74617fb2006-06-19 19:57:12 +0100372 arm_machine_restart('h');
373}
374
375static void poodle_restart(char mode)
376{
Richard Purdie74617fb2006-06-19 19:57:12 +0100377 arm_machine_restart('h');
378}
379
Linus Torvalds1da177e2005-04-16 15:20:36 -0700380static void __init poodle_init(void)
381{
382 int ret = 0;
383
Richard Purdie74617fb2006-06-19 19:57:12 +0100384 pm_power_off = poodle_poweroff;
385 arm_pm_restart = poodle_restart;
386
Richard Purdief29d2452005-09-15 14:53:22 +0100387 /* setup sleep mode values */
388 PWER = 0x00000002;
389 PFER = 0x00000000;
390 PRER = 0x00000002;
391 PGSR0 = 0x00008000;
392 PGSR1 = 0x003F0202;
393 PGSR2 = 0x0001C000;
394 PCFR |= PCFR_OPDE;
395
Linus Torvalds1da177e2005-04-16 15:20:36 -0700396 /* cpu initialize */
397 /* Pgsr Register */
398 PGSR0 = 0x0146dd80;
399 PGSR1 = 0x03bf0890;
400 PGSR2 = 0x0001c000;
401
402 /* Alternate Register */
403 GAFR0_L = 0x01001000;
404 GAFR0_U = 0x591a8010;
405 GAFR1_L = 0x900a8451;
406 GAFR1_U = 0xaaa5aaaa;
407 GAFR2_L = 0x8aaaaaaa;
408 GAFR2_U = 0x00000002;
409
410 /* Direction Register */
411 GPDR0 = 0xd3f0904c;
412 GPDR1 = 0xfcffb7d3;
413 GPDR2 = 0x0001ffff;
414
415 /* Output Register */
416 GPCR0 = 0x00000000;
417 GPCR1 = 0x00000000;
418 GPCR2 = 0x00000000;
419
420 GPSR0 = 0x00400000;
421 GPSR1 = 0x00000000;
422 GPSR2 = 0x00000000;
423
Eric Miao2b0defd2008-08-09 05:54:22 -0400424 platform_scoop_config = &poodle_pcmcia_config;
425 corgi_ssp_set_machinfo(&poodle_ssp_machinfo);
426
427 ret = platform_add_devices(devices, ARRAY_SIZE(devices));
428 if (ret)
429 pr_warning("poodle: Unable to register LoCoMo device\n");
430
Richard Purdiefaed5682006-06-19 20:46:05 +0100431 set_pxa_fb_parent(&poodle_locomo_device.dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700432 set_pxa_fb_info(&poodle_fb_info);
Richard Purdie13b9d472005-09-15 14:53:22 +0100433 pxa_gpio_mode(POODLE_GPIO_USB_PULLUP | GPIO_OUT);
Richard Purdie8e4b8712005-10-30 14:38:52 +0000434 pxa_gpio_mode(POODLE_GPIO_IR_ON | GPIO_OUT);
Richard Purdie13b9d472005-09-15 14:53:22 +0100435 pxa_set_udc_info(&udc_info);
436 pxa_set_mci_info(&poodle_mci_platform_data);
Richard Purdie8e4b8712005-10-30 14:38:52 +0000437 pxa_set_ficp_info(&poodle_ficp_platform_data);
Mark Brownf8787fd2008-08-26 13:30:03 +0100438 pxa_set_i2c_info(NULL);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700439}
440
441static void __init fixup_poodle(struct machine_desc *desc,
442 struct tag *tags, char **cmdline, struct meminfo *mi)
443{
444 sharpsl_save_param();
Richard Purdieb2e6f752006-04-02 17:11:00 +0100445 mi->nr_banks=1;
446 mi->bank[0].start = 0xa0000000;
447 mi->bank[0].node = 0;
448 mi->bank[0].size = (32*1024*1024);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700449}
450
Linus Torvalds1da177e2005-04-16 15:20:36 -0700451MACHINE_START(POODLE, "SHARP Poodle")
Russell Kinge9dea0c2005-07-03 17:38:58 +0100452 .phys_io = 0x40000000,
Russell King68070bd2005-07-04 10:44:34 +0100453 .io_pg_offst = (io_p2v(0x40000000) >> 18) & 0xfffc,
Russell Kinge9dea0c2005-07-03 17:38:58 +0100454 .fixup = fixup_poodle,
Richard Purdief29d2452005-09-15 14:53:22 +0100455 .map_io = pxa_map_io,
Eric Miaocd491042007-06-22 04:14:09 +0100456 .init_irq = pxa25x_init_irq,
Russell Kinge9dea0c2005-07-03 17:38:58 +0100457 .timer = &pxa_timer,
458 .init_machine = poodle_init,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700459MACHINE_END