[ARM] pxa: make pxa2xx_spi driver use ssp_request()/ssp_free()
[deliverable/linux.git] / arch / arm / mach-pxa / lubbock.c
CommitLineData
1da177e4
LT
1/*
2 * linux/arch/arm/mach-pxa/lubbock.c
3 *
4 * Support for the Intel DBPXA250 Development Platform.
5 *
6 * Author: Nicolas Pitre
7 * Created: Jun 15, 2001
8 * Copyright: MontaVista Software Inc.
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#include <linux/module.h>
15#include <linux/kernel.h>
16#include <linux/init.h>
d052d1be 17#include <linux/platform_device.h>
22f11c4e 18#include <linux/sysdev.h>
1da177e4
LT
19#include <linux/major.h>
20#include <linux/fb.h>
21#include <linux/interrupt.h>
74ec71e1
TP
22#include <linux/mtd/mtd.h>
23#include <linux/mtd/partitions.h>
1da177e4 24
9df5db80
DB
25#include <linux/spi/spi.h>
26#include <linux/spi/ads7846.h>
27#include <asm/arch/pxa2xx_spi.h>
28
1da177e4
LT
29#include <asm/setup.h>
30#include <asm/memory.h>
31#include <asm/mach-types.h>
32#include <asm/hardware.h>
33#include <asm/irq.h>
74ec71e1 34#include <asm/sizes.h>
1da177e4
LT
35
36#include <asm/mach/arch.h>
37#include <asm/mach/map.h>
38#include <asm/mach/irq.h>
74ec71e1 39#include <asm/mach/flash.h>
1da177e4
LT
40
41#include <asm/hardware/sa1111.h>
42
43#include <asm/arch/pxa-regs.h>
44#include <asm/arch/lubbock.h>
45#include <asm/arch/udc.h>
6f475c01 46#include <asm/arch/irda.h>
1da177e4
LT
47#include <asm/arch/pxafb.h>
48#include <asm/arch/mmc.h>
49
50#include "generic.h"
46c41e62 51#include "devices.h"
1da177e4
LT
52
53
54#define LUB_MISC_WR __LUB_REG(LUBBOCK_FPGA_PHYS + 0x080)
55
56void lubbock_set_misc_wr(unsigned int mask, unsigned int set)
57{
58 unsigned long flags;
59
60 local_irq_save(flags);
61 LUB_MISC_WR = (LUB_MISC_WR & ~mask) | (set & mask);
62 local_irq_restore(flags);
63}
64EXPORT_SYMBOL(lubbock_set_misc_wr);
65
66static unsigned long lubbock_irq_enabled;
67
68static void lubbock_mask_irq(unsigned int irq)
69{
70 int lubbock_irq = (irq - LUBBOCK_IRQ(0));
71 LUB_IRQ_MASK_EN = (lubbock_irq_enabled &= ~(1 << lubbock_irq));
72}
73
74static void lubbock_unmask_irq(unsigned int irq)
75{
76 int lubbock_irq = (irq - LUBBOCK_IRQ(0));
77 /* the irq can be acknowledged only if deasserted, so it's done here */
78 LUB_IRQ_SET_CLR &= ~(1 << lubbock_irq);
79 LUB_IRQ_MASK_EN = (lubbock_irq_enabled |= (1 << lubbock_irq));
80}
81
38c677cb
DB
82static struct irq_chip lubbock_irq_chip = {
83 .name = "FPGA",
1da177e4
LT
84 .ack = lubbock_mask_irq,
85 .mask = lubbock_mask_irq,
86 .unmask = lubbock_unmask_irq,
87};
88
10dd5ce2 89static void lubbock_irq_handler(unsigned int irq, struct irq_desc *desc)
1da177e4
LT
90{
91 unsigned long pending = LUB_IRQ_SET_CLR & lubbock_irq_enabled;
92 do {
93 GEDR(0) = GPIO_bit(0); /* clear our parent irq */
94 if (likely(pending)) {
95 irq = LUBBOCK_IRQ(0) + __ffs(pending);
96 desc = irq_desc + irq;
0cd61b68 97 desc_handle_irq(irq, desc);
1da177e4
LT
98 }
99 pending = LUB_IRQ_SET_CLR & lubbock_irq_enabled;
100 } while (pending);
101}
102
103static void __init lubbock_init_irq(void)
104{
105 int irq;
106
cd49104d 107 pxa25x_init_irq();
1da177e4
LT
108
109 /* setup extra lubbock irqs */
110 for (irq = LUBBOCK_IRQ(0); irq <= LUBBOCK_LAST_IRQ; irq++) {
111 set_irq_chip(irq, &lubbock_irq_chip);
10dd5ce2 112 set_irq_handler(irq, handle_level_irq);
1da177e4
LT
113 set_irq_flags(irq, IRQF_VALID | IRQF_PROBE);
114 }
115
116 set_irq_chained_handler(IRQ_GPIO(0), lubbock_irq_handler);
117 set_irq_type(IRQ_GPIO(0), IRQT_FALLING);
118}
119
22f11c4e
NP
120#ifdef CONFIG_PM
121
122static int lubbock_irq_resume(struct sys_device *dev)
123{
124 LUB_IRQ_MASK_EN = lubbock_irq_enabled;
125 return 0;
126}
127
128static struct sysdev_class lubbock_irq_sysclass = {
af5ca3f4 129 .name = "cpld_irq",
22f11c4e
NP
130 .resume = lubbock_irq_resume,
131};
132
133static struct sys_device lubbock_irq_device = {
134 .cls = &lubbock_irq_sysclass,
135};
136
137static int __init lubbock_irq_device_init(void)
138{
139 int ret = sysdev_class_register(&lubbock_irq_sysclass);
140 if (ret == 0)
141 ret = sysdev_register(&lubbock_irq_device);
142 return ret;
143}
144
145device_initcall(lubbock_irq_device_init);
146
147#endif
148
1da177e4
LT
149static int lubbock_udc_is_connected(void)
150{
151 return (LUB_MISC_RD & (1 << 9)) == 0;
152}
153
154static struct pxa2xx_udc_mach_info udc_info __initdata = {
155 .udc_is_connected = lubbock_udc_is_connected,
156 // no D+ pullup; lubbock can't connect/disconnect in software
157};
158
2cef2d55
NP
159static struct platform_device lub_audio_device = {
160 .name = "pxa2xx-ac97",
161 .id = -1,
162};
163
1da177e4
LT
164static struct resource sa1111_resources[] = {
165 [0] = {
166 .start = 0x10000000,
167 .end = 0x10001fff,
168 .flags = IORESOURCE_MEM,
169 },
170 [1] = {
171 .start = LUBBOCK_SA1111_IRQ,
172 .end = LUBBOCK_SA1111_IRQ,
173 .flags = IORESOURCE_IRQ,
174 },
175};
176
177static struct platform_device sa1111_device = {
178 .name = "sa1111",
179 .id = -1,
180 .num_resources = ARRAY_SIZE(sa1111_resources),
181 .resource = sa1111_resources,
182};
183
184static struct resource smc91x_resources[] = {
185 [0] = {
186 .name = "smc91x-regs",
85eb226c 187 .start = 0x0c000c00,
1da177e4
LT
188 .end = 0x0c0fffff,
189 .flags = IORESOURCE_MEM,
190 },
191 [1] = {
192 .start = LUBBOCK_ETH_IRQ,
193 .end = LUBBOCK_ETH_IRQ,
194 .flags = IORESOURCE_IRQ,
195 },
196 [2] = {
197 .name = "smc91x-attrib",
198 .start = 0x0e000000,
199 .end = 0x0e0fffff,
200 .flags = IORESOURCE_MEM,
201 },
202};
203
9df5db80
DB
204/* ADS7846 is connected through SSP ... and if your board has J5 populated,
205 * you can select it to replace the ucb1400 by switching the touchscreen cable
206 * (to J5) and poking board registers (as done below). Else it's only useful
207 * for the temperature sensors.
208 */
9df5db80 209static struct pxa2xx_spi_master pxa_ssp_master_info = {
9df5db80
DB
210 .num_chipselect = 0,
211};
212
213static struct platform_device pxa_ssp = {
214 .name = "pxa2xx-spi",
215 .id = 1,
9df5db80
DB
216 .dev = {
217 .platform_data = &pxa_ssp_master_info,
218 },
219};
220
221static int lubbock_ads7846_pendown_state(void)
222{
223 /* TS_BUSY is bit 8 in LUB_MISC_RD, but pendown is irq-only */
224 return 0;
225}
226
227static struct ads7846_platform_data ads_info = {
228 .model = 7846,
229 .vref_delay_usecs = 100, /* internal, no cap */
230 .get_pendown_state = lubbock_ads7846_pendown_state,
231 // .x_plate_ohms = 500, /* GUESS! */
232 // .y_plate_ohms = 500, /* GUESS! */
233};
234
235static void ads7846_cs(u32 command)
236{
237 static const unsigned TS_nCS = 1 << 11;
238 lubbock_set_misc_wr(TS_nCS, (command == PXA2XX_CS_ASSERT) ? 0 : TS_nCS);
239}
240
241static struct pxa2xx_spi_chip ads_hw = {
242 .tx_threshold = 1,
243 .rx_threshold = 2,
244 .cs_control = ads7846_cs,
245};
246
247static struct spi_board_info spi_board_info[] __initdata = { {
248 .modalias = "ads7846",
249 .platform_data = &ads_info,
250 .controller_data = &ads_hw,
251 .irq = LUBBOCK_BB_IRQ,
252 .max_speed_hz = 120000 /* max sample rate at 3V */
253 * 26 /* command + data + overhead */,
254 .bus_num = 1,
255 .chip_select = 0,
256},
257};
258
1da177e4
LT
259static struct platform_device smc91x_device = {
260 .name = "smc91x",
261 .id = -1,
262 .num_resources = ARRAY_SIZE(smc91x_resources),
263 .resource = smc91x_resources,
264};
265
74ec71e1
TP
266static struct resource flash_resources[] = {
267 [0] = {
268 .start = 0x00000000,
269 .end = SZ_64M - 1,
270 .flags = IORESOURCE_MEM,
271 },
272 [1] = {
273 .start = 0x04000000,
274 .end = 0x04000000 + SZ_64M - 1,
275 .flags = IORESOURCE_MEM,
276 },
277};
278
279static struct mtd_partition lubbock_partitions[] = {
280 {
281 .name = "Bootloader",
282 .size = 0x00040000,
283 .offset = 0,
284 .mask_flags = MTD_WRITEABLE /* force read-only */
285 },{
286 .name = "Kernel",
287 .size = 0x00100000,
288 .offset = 0x00040000,
289 },{
290 .name = "Filesystem",
291 .size = MTDPART_SIZ_FULL,
292 .offset = 0x00140000
293 }
294};
295
296static struct flash_platform_data lubbock_flash_data[2] = {
297 {
298 .map_name = "cfi_probe",
299 .parts = lubbock_partitions,
300 .nr_parts = ARRAY_SIZE(lubbock_partitions),
301 }, {
302 .map_name = "cfi_probe",
303 .parts = NULL,
304 .nr_parts = 0,
305 }
306};
307
308static struct platform_device lubbock_flash_device[2] = {
309 {
310 .name = "pxa2xx-flash",
311 .id = 0,
312 .dev = {
313 .platform_data = &lubbock_flash_data[0],
314 },
315 .resource = &flash_resources[0],
316 .num_resources = 1,
317 },
318 {
319 .name = "pxa2xx-flash",
320 .id = 1,
321 .dev = {
322 .platform_data = &lubbock_flash_data[1],
323 },
324 .resource = &flash_resources[1],
325 .num_resources = 1,
326 },
327};
328
1da177e4
LT
329static struct platform_device *devices[] __initdata = {
330 &sa1111_device,
2cef2d55 331 &lub_audio_device,
1da177e4 332 &smc91x_device,
74ec71e1
TP
333 &lubbock_flash_device[0],
334 &lubbock_flash_device[1],
9df5db80 335 &pxa_ssp,
1da177e4
LT
336};
337
d14b272b 338static struct pxafb_mode_info sharp_lm8v31_mode = {
1da177e4
LT
339 .pixclock = 270000,
340 .xres = 640,
341 .yres = 480,
342 .bpp = 16,
343 .hsync_len = 1,
344 .left_margin = 3,
345 .right_margin = 3,
346 .vsync_len = 1,
347 .upper_margin = 0,
348 .lower_margin = 0,
349 .sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
350 .cmap_greyscale = 0,
d14b272b
RP
351};
352
353static struct pxafb_mach_info sharp_lm8v31 = {
354 .modes = &sharp_lm8v31_mode,
355 .num_modes = 1,
1da177e4
LT
356 .cmap_inverse = 0,
357 .cmap_static = 0,
358 .lccr0 = LCCR0_SDS,
359 .lccr3 = LCCR3_PCP | LCCR3_Acb(255),
360};
361
85eb226c
DB
362#define MMC_POLL_RATE msecs_to_jiffies(1000)
363
364static void lubbock_mmc_poll(unsigned long);
40220c1a 365static irq_handler_t mmc_detect_int;
85eb226c
DB
366
367static struct timer_list mmc_timer = {
368 .function = lubbock_mmc_poll,
369};
370
371static void lubbock_mmc_poll(unsigned long data)
372{
373 unsigned long flags;
374
375 /* clear any previous irq state, then ... */
376 local_irq_save(flags);
377 LUB_IRQ_SET_CLR &= ~(1 << 0);
378 local_irq_restore(flags);
379
380 /* poll until mmc/sd card is removed */
381 if (LUB_IRQ_SET_CLR & (1 << 0))
382 mod_timer(&mmc_timer, jiffies + MMC_POLL_RATE);
383 else {
2326eb98 384 (void) mmc_detect_int(LUBBOCK_SD_IRQ, (void *)data);
85eb226c
DB
385 enable_irq(LUBBOCK_SD_IRQ);
386 }
387}
388
0cd61b68 389static irqreturn_t lubbock_detect_int(int irq, void *data)
85eb226c
DB
390{
391 /* IRQ is level triggered; disable, and poll for removal */
392 disable_irq(irq);
393 mod_timer(&mmc_timer, jiffies + MMC_POLL_RATE);
394
0cd61b68 395 return mmc_detect_int(irq, data);
85eb226c
DB
396}
397
398static int lubbock_mci_init(struct device *dev,
40220c1a 399 irq_handler_t detect_int,
85eb226c 400 void *data)
1da177e4
LT
401{
402 /* setup GPIO for PXA25x MMC controller */
403 pxa_gpio_mode(GPIO6_MMCCLK_MD);
404 pxa_gpio_mode(GPIO8_MMCCS0_MD);
405
85eb226c
DB
406 /* detect card insert/eject */
407 mmc_detect_int = detect_int;
408 init_timer(&mmc_timer);
409 mmc_timer.data = (unsigned long) data;
410 return request_irq(LUBBOCK_SD_IRQ, lubbock_detect_int,
52e405ea 411 IRQF_SAMPLE_RANDOM, "lubbock-sd-detect", data);
85eb226c
DB
412}
413
414static int lubbock_mci_get_ro(struct device *dev)
415{
416 return (LUB_MISC_RD & (1 << 2)) != 0;
417}
418
419static void lubbock_mci_exit(struct device *dev, void *data)
420{
421 free_irq(LUBBOCK_SD_IRQ, data);
422 del_timer_sync(&mmc_timer);
1da177e4
LT
423}
424
425static struct pxamci_platform_data lubbock_mci_platform_data = {
426 .ocr_mask = MMC_VDD_32_33|MMC_VDD_33_34,
85eb226c 427 .detect_delay = 1,
1da177e4 428 .init = lubbock_mci_init,
85eb226c
DB
429 .get_ro = lubbock_mci_get_ro,
430 .exit = lubbock_mci_exit,
1da177e4
LT
431};
432
6f475c01
NP
433static void lubbock_irda_transceiver_mode(struct device *dev, int mode)
434{
435 unsigned long flags;
436
437 local_irq_save(flags);
438 if (mode & IR_SIRMODE) {
439 LUB_MISC_WR &= ~(1 << 4);
440 } else if (mode & IR_FIRMODE) {
441 LUB_MISC_WR |= 1 << 4;
442 }
443 local_irq_restore(flags);
444}
445
446static struct pxaficp_platform_data lubbock_ficp_platform_data = {
447 .transceiver_cap = IR_SIRMODE | IR_FIRMODE,
448 .transceiver_mode = lubbock_irda_transceiver_mode,
449};
450
1da177e4
LT
451static void __init lubbock_init(void)
452{
74ec71e1
TP
453 int flashboot = (LUB_CONF_SWITCHES & 1);
454
1da177e4
LT
455 pxa_set_udc_info(&udc_info);
456 set_pxa_fb_info(&sharp_lm8v31);
457 pxa_set_mci_info(&lubbock_mci_platform_data);
6f475c01 458 pxa_set_ficp_info(&lubbock_ficp_platform_data);
74ec71e1
TP
459
460 lubbock_flash_data[0].width = lubbock_flash_data[1].width =
461 (BOOT_DEF & 1) ? 2 : 4;
462 /* Compensate for the nROMBT switch which swaps the flash banks */
463 printk(KERN_NOTICE "Lubbock configured to boot from %s (bank %d)\n",
464 flashboot?"Flash":"ROM", flashboot);
465
466 lubbock_flash_data[flashboot^1].name = "application-flash";
467 lubbock_flash_data[flashboot].name = "boot-rom";
1da177e4 468 (void) platform_add_devices(devices, ARRAY_SIZE(devices));
9df5db80
DB
469
470 spi_register_board_info(spi_board_info, ARRAY_SIZE(spi_board_info));
1da177e4
LT
471}
472
473static struct map_desc lubbock_io_desc[] __initdata = {
6f9182eb
DS
474 { /* CPLD */
475 .virtual = LUBBOCK_FPGA_VIRT,
476 .pfn = __phys_to_pfn(LUBBOCK_FPGA_PHYS),
477 .length = 0x00100000,
478 .type = MT_DEVICE
479 }
1da177e4
LT
480};
481
482static void __init lubbock_map_io(void)
483{
484 pxa_map_io();
485 iotable_init(lubbock_io_desc, ARRAY_SIZE(lubbock_io_desc));
486
9df5db80
DB
487 /* SSP data pins */
488 pxa_gpio_mode(GPIO23_SCLK_MD);
489 pxa_gpio_mode(GPIO25_STXD_MD);
490 pxa_gpio_mode(GPIO26_SRXD_MD);
491
1da177e4
LT
492 /* This enables the BTUART */
493 pxa_gpio_mode(GPIO42_BTRXD_MD);
494 pxa_gpio_mode(GPIO43_BTTXD_MD);
495 pxa_gpio_mode(GPIO44_BTCTS_MD);
496 pxa_gpio_mode(GPIO45_BTRTS_MD);
497
693d9d95
RK
498 GPSR(GPIO48_nPOE) =
499 GPIO_bit(GPIO48_nPOE) |
500 GPIO_bit(GPIO49_nPWE) |
501 GPIO_bit(GPIO50_nPIOR) |
502 GPIO_bit(GPIO51_nPIOW) |
503 GPIO_bit(GPIO52_nPCE_1) |
504 GPIO_bit(GPIO53_nPCE_2);
505
506 pxa_gpio_mode(GPIO48_nPOE_MD);
507 pxa_gpio_mode(GPIO49_nPWE_MD);
508 pxa_gpio_mode(GPIO50_nPIOR_MD);
509 pxa_gpio_mode(GPIO51_nPIOW_MD);
510 pxa_gpio_mode(GPIO52_nPCE_1_MD);
511 pxa_gpio_mode(GPIO53_nPCE_2_MD);
512 pxa_gpio_mode(GPIO54_pSKTSEL_MD);
513 pxa_gpio_mode(GPIO55_nPREG_MD);
514 pxa_gpio_mode(GPIO56_nPWAIT_MD);
515 pxa_gpio_mode(GPIO57_nIOIS16_MD);
516
1da177e4
LT
517 /* This is for the SMC chip select */
518 pxa_gpio_mode(GPIO79_nCS_3_MD);
519
520 /* setup sleep mode values */
521 PWER = 0x00000002;
522 PFER = 0x00000000;
523 PRER = 0x00000002;
524 PGSR0 = 0x00008000;
525 PGSR1 = 0x003F0202;
526 PGSR2 = 0x0001C000;
527 PCFR |= PCFR_OPDE;
528}
529
530MACHINE_START(LUBBOCK, "Intel DBPXA250 Development Platform (aka Lubbock)")
e9dea0c6 531 /* Maintainer: MontaVista Software Inc. */
e9dea0c6 532 .phys_io = 0x40000000,
68070bde 533 .io_pg_offst = (io_p2v(0x40000000) >> 18) & 0xfffc,
e9dea0c6
RK
534 .map_io = lubbock_map_io,
535 .init_irq = lubbock_init_irq,
1da177e4 536 .timer = &pxa_timer,
e9dea0c6 537 .init_machine = lubbock_init,
1da177e4 538MACHINE_END
This page took 0.285282 seconds and 5 git commands to generate.