Root/
1 | /* |
2 | * arch/arm/mach-at91/at91sam9263_devices.c |
3 | * |
4 | * Copyright (C) 2007 Atmel Corporation. |
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 | */ |
12 | #include <asm/mach/arch.h> |
13 | #include <asm/mach/map.h> |
14 | |
15 | #include <linux/dma-mapping.h> |
16 | #include <linux/platform_device.h> |
17 | #include <linux/i2c-gpio.h> |
18 | |
19 | #include <linux/fb.h> |
20 | #include <video/atmel_lcdc.h> |
21 | |
22 | #include <mach/board.h> |
23 | #include <mach/gpio.h> |
24 | #include <mach/at91sam9263.h> |
25 | #include <mach/at91sam9263_matrix.h> |
26 | #include <mach/at91sam9_smc.h> |
27 | |
28 | #include "generic.h" |
29 | |
30 | |
31 | /* -------------------------------------------------------------------- |
32 | * USB Host |
33 | * -------------------------------------------------------------------- */ |
34 | |
35 | #if defined(CONFIG_USB_OHCI_HCD) || defined(CONFIG_USB_OHCI_HCD_MODULE) |
36 | static u64 ohci_dmamask = DMA_BIT_MASK(32); |
37 | static struct at91_usbh_data usbh_data; |
38 | |
39 | static struct resource usbh_resources[] = { |
40 | [0] = { |
41 | .start = AT91SAM9263_UHP_BASE, |
42 | .end = AT91SAM9263_UHP_BASE + SZ_1M - 1, |
43 | .flags = IORESOURCE_MEM, |
44 | }, |
45 | [1] = { |
46 | .start = AT91SAM9263_ID_UHP, |
47 | .end = AT91SAM9263_ID_UHP, |
48 | .flags = IORESOURCE_IRQ, |
49 | }, |
50 | }; |
51 | |
52 | static struct platform_device at91_usbh_device = { |
53 | .name = "at91_ohci", |
54 | .id = -1, |
55 | .dev = { |
56 | .dma_mask = &ohci_dmamask, |
57 | .coherent_dma_mask = DMA_BIT_MASK(32), |
58 | .platform_data = &usbh_data, |
59 | }, |
60 | .resource = usbh_resources, |
61 | .num_resources = ARRAY_SIZE(usbh_resources), |
62 | }; |
63 | |
64 | void __init at91_add_device_usbh(struct at91_usbh_data *data) |
65 | { |
66 | int i; |
67 | |
68 | if (!data) |
69 | return; |
70 | |
71 | /* Enable VBus control for UHP ports */ |
72 | for (i = 0; i < data->ports; i++) { |
73 | if (data->vbus_pin[i]) |
74 | at91_set_gpio_output(data->vbus_pin[i], 0); |
75 | } |
76 | |
77 | usbh_data = *data; |
78 | platform_device_register(&at91_usbh_device); |
79 | } |
80 | #else |
81 | void __init at91_add_device_usbh(struct at91_usbh_data *data) {} |
82 | #endif |
83 | |
84 | |
85 | /* -------------------------------------------------------------------- |
86 | * USB Device (Gadget) |
87 | * -------------------------------------------------------------------- */ |
88 | |
89 | #ifdef CONFIG_USB_GADGET_AT91 |
90 | static struct at91_udc_data udc_data; |
91 | |
92 | static struct resource udc_resources[] = { |
93 | [0] = { |
94 | .start = AT91SAM9263_BASE_UDP, |
95 | .end = AT91SAM9263_BASE_UDP + SZ_16K - 1, |
96 | .flags = IORESOURCE_MEM, |
97 | }, |
98 | [1] = { |
99 | .start = AT91SAM9263_ID_UDP, |
100 | .end = AT91SAM9263_ID_UDP, |
101 | .flags = IORESOURCE_IRQ, |
102 | }, |
103 | }; |
104 | |
105 | static struct platform_device at91_udc_device = { |
106 | .name = "at91_udc", |
107 | .id = -1, |
108 | .dev = { |
109 | .platform_data = &udc_data, |
110 | }, |
111 | .resource = udc_resources, |
112 | .num_resources = ARRAY_SIZE(udc_resources), |
113 | }; |
114 | |
115 | void __init at91_add_device_udc(struct at91_udc_data *data) |
116 | { |
117 | if (!data) |
118 | return; |
119 | |
120 | if (data->vbus_pin) { |
121 | at91_set_gpio_input(data->vbus_pin, 0); |
122 | at91_set_deglitch(data->vbus_pin, 1); |
123 | } |
124 | |
125 | /* Pullup pin is handled internally by USB device peripheral */ |
126 | |
127 | udc_data = *data; |
128 | platform_device_register(&at91_udc_device); |
129 | } |
130 | #else |
131 | void __init at91_add_device_udc(struct at91_udc_data *data) {} |
132 | #endif |
133 | |
134 | |
135 | /* -------------------------------------------------------------------- |
136 | * Ethernet |
137 | * -------------------------------------------------------------------- */ |
138 | |
139 | #if defined(CONFIG_MACB) || defined(CONFIG_MACB_MODULE) |
140 | static u64 eth_dmamask = DMA_BIT_MASK(32); |
141 | static struct at91_eth_data eth_data; |
142 | |
143 | static struct resource eth_resources[] = { |
144 | [0] = { |
145 | .start = AT91SAM9263_BASE_EMAC, |
146 | .end = AT91SAM9263_BASE_EMAC + SZ_16K - 1, |
147 | .flags = IORESOURCE_MEM, |
148 | }, |
149 | [1] = { |
150 | .start = AT91SAM9263_ID_EMAC, |
151 | .end = AT91SAM9263_ID_EMAC, |
152 | .flags = IORESOURCE_IRQ, |
153 | }, |
154 | }; |
155 | |
156 | static struct platform_device at91sam9263_eth_device = { |
157 | .name = "macb", |
158 | .id = -1, |
159 | .dev = { |
160 | .dma_mask = ð_dmamask, |
161 | .coherent_dma_mask = DMA_BIT_MASK(32), |
162 | .platform_data = ð_data, |
163 | }, |
164 | .resource = eth_resources, |
165 | .num_resources = ARRAY_SIZE(eth_resources), |
166 | }; |
167 | |
168 | void __init at91_add_device_eth(struct at91_eth_data *data) |
169 | { |
170 | if (!data) |
171 | return; |
172 | |
173 | if (data->phy_irq_pin) { |
174 | at91_set_gpio_input(data->phy_irq_pin, 0); |
175 | at91_set_deglitch(data->phy_irq_pin, 1); |
176 | } |
177 | |
178 | /* Pins used for MII and RMII */ |
179 | at91_set_A_periph(AT91_PIN_PE21, 0); /* ETXCK_EREFCK */ |
180 | at91_set_B_periph(AT91_PIN_PC25, 0); /* ERXDV */ |
181 | at91_set_A_periph(AT91_PIN_PE25, 0); /* ERX0 */ |
182 | at91_set_A_periph(AT91_PIN_PE26, 0); /* ERX1 */ |
183 | at91_set_A_periph(AT91_PIN_PE27, 0); /* ERXER */ |
184 | at91_set_A_periph(AT91_PIN_PE28, 0); /* ETXEN */ |
185 | at91_set_A_periph(AT91_PIN_PE23, 0); /* ETX0 */ |
186 | at91_set_A_periph(AT91_PIN_PE24, 0); /* ETX1 */ |
187 | at91_set_A_periph(AT91_PIN_PE30, 0); /* EMDIO */ |
188 | at91_set_A_periph(AT91_PIN_PE29, 0); /* EMDC */ |
189 | |
190 | if (!data->is_rmii) { |
191 | at91_set_A_periph(AT91_PIN_PE22, 0); /* ECRS */ |
192 | at91_set_B_periph(AT91_PIN_PC26, 0); /* ECOL */ |
193 | at91_set_B_periph(AT91_PIN_PC22, 0); /* ERX2 */ |
194 | at91_set_B_periph(AT91_PIN_PC23, 0); /* ERX3 */ |
195 | at91_set_B_periph(AT91_PIN_PC27, 0); /* ERXCK */ |
196 | at91_set_B_periph(AT91_PIN_PC20, 0); /* ETX2 */ |
197 | at91_set_B_periph(AT91_PIN_PC21, 0); /* ETX3 */ |
198 | at91_set_B_periph(AT91_PIN_PC24, 0); /* ETXER */ |
199 | } |
200 | |
201 | eth_data = *data; |
202 | platform_device_register(&at91sam9263_eth_device); |
203 | } |
204 | #else |
205 | void __init at91_add_device_eth(struct at91_eth_data *data) {} |
206 | #endif |
207 | |
208 | |
209 | /* -------------------------------------------------------------------- |
210 | * MMC / SD |
211 | * -------------------------------------------------------------------- */ |
212 | |
213 | #if defined(CONFIG_MMC_AT91) || defined(CONFIG_MMC_AT91_MODULE) |
214 | static u64 mmc_dmamask = DMA_BIT_MASK(32); |
215 | static struct at91_mmc_data mmc0_data, mmc1_data; |
216 | |
217 | static struct resource mmc0_resources[] = { |
218 | [0] = { |
219 | .start = AT91SAM9263_BASE_MCI0, |
220 | .end = AT91SAM9263_BASE_MCI0 + SZ_16K - 1, |
221 | .flags = IORESOURCE_MEM, |
222 | }, |
223 | [1] = { |
224 | .start = AT91SAM9263_ID_MCI0, |
225 | .end = AT91SAM9263_ID_MCI0, |
226 | .flags = IORESOURCE_IRQ, |
227 | }, |
228 | }; |
229 | |
230 | static struct platform_device at91sam9263_mmc0_device = { |
231 | .name = "at91_mci", |
232 | .id = 0, |
233 | .dev = { |
234 | .dma_mask = &mmc_dmamask, |
235 | .coherent_dma_mask = DMA_BIT_MASK(32), |
236 | .platform_data = &mmc0_data, |
237 | }, |
238 | .resource = mmc0_resources, |
239 | .num_resources = ARRAY_SIZE(mmc0_resources), |
240 | }; |
241 | |
242 | static struct resource mmc1_resources[] = { |
243 | [0] = { |
244 | .start = AT91SAM9263_BASE_MCI1, |
245 | .end = AT91SAM9263_BASE_MCI1 + SZ_16K - 1, |
246 | .flags = IORESOURCE_MEM, |
247 | }, |
248 | [1] = { |
249 | .start = AT91SAM9263_ID_MCI1, |
250 | .end = AT91SAM9263_ID_MCI1, |
251 | .flags = IORESOURCE_IRQ, |
252 | }, |
253 | }; |
254 | |
255 | static struct platform_device at91sam9263_mmc1_device = { |
256 | .name = "at91_mci", |
257 | .id = 1, |
258 | .dev = { |
259 | .dma_mask = &mmc_dmamask, |
260 | .coherent_dma_mask = DMA_BIT_MASK(32), |
261 | .platform_data = &mmc1_data, |
262 | }, |
263 | .resource = mmc1_resources, |
264 | .num_resources = ARRAY_SIZE(mmc1_resources), |
265 | }; |
266 | |
267 | void __init at91_add_device_mmc(short mmc_id, struct at91_mmc_data *data) |
268 | { |
269 | if (!data) |
270 | return; |
271 | |
272 | /* input/irq */ |
273 | if (data->det_pin) { |
274 | at91_set_gpio_input(data->det_pin, 1); |
275 | at91_set_deglitch(data->det_pin, 1); |
276 | } |
277 | if (data->wp_pin) |
278 | at91_set_gpio_input(data->wp_pin, 1); |
279 | if (data->vcc_pin) |
280 | at91_set_gpio_output(data->vcc_pin, 0); |
281 | |
282 | if (mmc_id == 0) { /* MCI0 */ |
283 | /* CLK */ |
284 | at91_set_A_periph(AT91_PIN_PA12, 0); |
285 | |
286 | if (data->slot_b) { |
287 | /* CMD */ |
288 | at91_set_A_periph(AT91_PIN_PA16, 1); |
289 | |
290 | /* DAT0, maybe DAT1..DAT3 */ |
291 | at91_set_A_periph(AT91_PIN_PA17, 1); |
292 | if (data->wire4) { |
293 | at91_set_A_periph(AT91_PIN_PA18, 1); |
294 | at91_set_A_periph(AT91_PIN_PA19, 1); |
295 | at91_set_A_periph(AT91_PIN_PA20, 1); |
296 | } |
297 | } else { |
298 | /* CMD */ |
299 | at91_set_A_periph(AT91_PIN_PA1, 1); |
300 | |
301 | /* DAT0, maybe DAT1..DAT3 */ |
302 | at91_set_A_periph(AT91_PIN_PA0, 1); |
303 | if (data->wire4) { |
304 | at91_set_A_periph(AT91_PIN_PA3, 1); |
305 | at91_set_A_periph(AT91_PIN_PA4, 1); |
306 | at91_set_A_periph(AT91_PIN_PA5, 1); |
307 | } |
308 | } |
309 | |
310 | mmc0_data = *data; |
311 | at91_clock_associate("mci0_clk", &at91sam9263_mmc0_device.dev, "mci_clk"); |
312 | platform_device_register(&at91sam9263_mmc0_device); |
313 | } else { /* MCI1 */ |
314 | /* CLK */ |
315 | at91_set_A_periph(AT91_PIN_PA6, 0); |
316 | |
317 | if (data->slot_b) { |
318 | /* CMD */ |
319 | at91_set_A_periph(AT91_PIN_PA21, 1); |
320 | |
321 | /* DAT0, maybe DAT1..DAT3 */ |
322 | at91_set_A_periph(AT91_PIN_PA22, 1); |
323 | if (data->wire4) { |
324 | at91_set_A_periph(AT91_PIN_PA23, 1); |
325 | at91_set_A_periph(AT91_PIN_PA24, 1); |
326 | at91_set_A_periph(AT91_PIN_PA25, 1); |
327 | } |
328 | } else { |
329 | /* CMD */ |
330 | at91_set_A_periph(AT91_PIN_PA7, 1); |
331 | |
332 | /* DAT0, maybe DAT1..DAT3 */ |
333 | at91_set_A_periph(AT91_PIN_PA8, 1); |
334 | if (data->wire4) { |
335 | at91_set_A_periph(AT91_PIN_PA9, 1); |
336 | at91_set_A_periph(AT91_PIN_PA10, 1); |
337 | at91_set_A_periph(AT91_PIN_PA11, 1); |
338 | } |
339 | } |
340 | |
341 | mmc1_data = *data; |
342 | at91_clock_associate("mci1_clk", &at91sam9263_mmc1_device.dev, "mci_clk"); |
343 | platform_device_register(&at91sam9263_mmc1_device); |
344 | } |
345 | } |
346 | #else |
347 | void __init at91_add_device_mmc(short mmc_id, struct at91_mmc_data *data) {} |
348 | #endif |
349 | |
350 | /* -------------------------------------------------------------------- |
351 | * Compact Flash (PCMCIA or IDE) |
352 | * -------------------------------------------------------------------- */ |
353 | |
354 | #if defined(CONFIG_AT91_CF) || defined(CONFIG_AT91_CF_MODULE) || \ |
355 | defined(CONFIG_BLK_DEV_IDE_AT91) || defined(CONFIG_BLK_DEV_IDE_AT91_MODULE) |
356 | |
357 | static struct at91_cf_data cf0_data; |
358 | |
359 | static struct resource cf0_resources[] = { |
360 | [0] = { |
361 | .start = AT91_CHIPSELECT_4, |
362 | .end = AT91_CHIPSELECT_4 + SZ_256M - 1, |
363 | .flags = IORESOURCE_MEM | IORESOURCE_MEM_8AND16BIT, |
364 | } |
365 | }; |
366 | |
367 | static struct platform_device cf0_device = { |
368 | .id = 0, |
369 | .dev = { |
370 | .platform_data = &cf0_data, |
371 | }, |
372 | .resource = cf0_resources, |
373 | .num_resources = ARRAY_SIZE(cf0_resources), |
374 | }; |
375 | |
376 | static struct at91_cf_data cf1_data; |
377 | |
378 | static struct resource cf1_resources[] = { |
379 | [0] = { |
380 | .start = AT91_CHIPSELECT_5, |
381 | .end = AT91_CHIPSELECT_5 + SZ_256M - 1, |
382 | .flags = IORESOURCE_MEM | IORESOURCE_MEM_8AND16BIT, |
383 | } |
384 | }; |
385 | |
386 | static struct platform_device cf1_device = { |
387 | .id = 1, |
388 | .dev = { |
389 | .platform_data = &cf1_data, |
390 | }, |
391 | .resource = cf1_resources, |
392 | .num_resources = ARRAY_SIZE(cf1_resources), |
393 | }; |
394 | |
395 | void __init at91_add_device_cf(struct at91_cf_data *data) |
396 | { |
397 | unsigned long ebi0_csa; |
398 | struct platform_device *pdev; |
399 | |
400 | if (!data) |
401 | return; |
402 | |
403 | /* |
404 | * assign CS4 or CS5 to SMC with Compact Flash logic support, |
405 | * we assume SMC timings are configured by board code, |
406 | * except True IDE where timings are controlled by driver |
407 | */ |
408 | ebi0_csa = at91_sys_read(AT91_MATRIX_EBI0CSA); |
409 | switch (data->chipselect) { |
410 | case 4: |
411 | at91_set_A_periph(AT91_PIN_PD6, 0); /* EBI0_NCS4/CFCS0 */ |
412 | ebi0_csa |= AT91_MATRIX_EBI0_CS4A_SMC_CF1; |
413 | cf0_data = *data; |
414 | pdev = &cf0_device; |
415 | break; |
416 | case 5: |
417 | at91_set_A_periph(AT91_PIN_PD7, 0); /* EBI0_NCS5/CFCS1 */ |
418 | ebi0_csa |= AT91_MATRIX_EBI0_CS5A_SMC_CF2; |
419 | cf1_data = *data; |
420 | pdev = &cf1_device; |
421 | break; |
422 | default: |
423 | printk(KERN_ERR "AT91 CF: bad chip-select requested (%u)\n", |
424 | data->chipselect); |
425 | return; |
426 | } |
427 | at91_sys_write(AT91_MATRIX_EBI0CSA, ebi0_csa); |
428 | |
429 | if (data->det_pin) { |
430 | at91_set_gpio_input(data->det_pin, 1); |
431 | at91_set_deglitch(data->det_pin, 1); |
432 | } |
433 | |
434 | if (data->irq_pin) { |
435 | at91_set_gpio_input(data->irq_pin, 1); |
436 | at91_set_deglitch(data->irq_pin, 1); |
437 | } |
438 | |
439 | if (data->vcc_pin) |
440 | /* initially off */ |
441 | at91_set_gpio_output(data->vcc_pin, 0); |
442 | |
443 | /* enable EBI controlled pins */ |
444 | at91_set_A_periph(AT91_PIN_PD5, 1); /* NWAIT */ |
445 | at91_set_A_periph(AT91_PIN_PD8, 0); /* CFCE1 */ |
446 | at91_set_A_periph(AT91_PIN_PD9, 0); /* CFCE2 */ |
447 | at91_set_A_periph(AT91_PIN_PD14, 0); /* CFNRW */ |
448 | |
449 | pdev->name = (data->flags & AT91_CF_TRUE_IDE) ? "at91_ide" : "at91_cf"; |
450 | platform_device_register(pdev); |
451 | } |
452 | #else |
453 | void __init at91_add_device_cf(struct at91_cf_data *data) {} |
454 | #endif |
455 | |
456 | /* -------------------------------------------------------------------- |
457 | * NAND / SmartMedia |
458 | * -------------------------------------------------------------------- */ |
459 | |
460 | #if defined(CONFIG_MTD_NAND_ATMEL) || defined(CONFIG_MTD_NAND_ATMEL_MODULE) |
461 | static struct atmel_nand_data nand_data; |
462 | |
463 | #define NAND_BASE AT91_CHIPSELECT_3 |
464 | |
465 | static struct resource nand_resources[] = { |
466 | [0] = { |
467 | .start = NAND_BASE, |
468 | .end = NAND_BASE + SZ_256M - 1, |
469 | .flags = IORESOURCE_MEM, |
470 | }, |
471 | [1] = { |
472 | .start = AT91_BASE_SYS + AT91_ECC0, |
473 | .end = AT91_BASE_SYS + AT91_ECC0 + SZ_512 - 1, |
474 | .flags = IORESOURCE_MEM, |
475 | } |
476 | }; |
477 | |
478 | static struct platform_device at91sam9263_nand_device = { |
479 | .name = "atmel_nand", |
480 | .id = -1, |
481 | .dev = { |
482 | .platform_data = &nand_data, |
483 | }, |
484 | .resource = nand_resources, |
485 | .num_resources = ARRAY_SIZE(nand_resources), |
486 | }; |
487 | |
488 | void __init at91_add_device_nand(struct atmel_nand_data *data) |
489 | { |
490 | unsigned long csa; |
491 | |
492 | if (!data) |
493 | return; |
494 | |
495 | csa = at91_sys_read(AT91_MATRIX_EBI0CSA); |
496 | at91_sys_write(AT91_MATRIX_EBI0CSA, csa | AT91_MATRIX_EBI0_CS3A_SMC_SMARTMEDIA); |
497 | |
498 | /* enable pin */ |
499 | if (data->enable_pin) |
500 | at91_set_gpio_output(data->enable_pin, 1); |
501 | |
502 | /* ready/busy pin */ |
503 | if (data->rdy_pin) |
504 | at91_set_gpio_input(data->rdy_pin, 1); |
505 | |
506 | /* card detect pin */ |
507 | if (data->det_pin) |
508 | at91_set_gpio_input(data->det_pin, 1); |
509 | |
510 | nand_data = *data; |
511 | platform_device_register(&at91sam9263_nand_device); |
512 | } |
513 | #else |
514 | void __init at91_add_device_nand(struct atmel_nand_data *data) {} |
515 | #endif |
516 | |
517 | |
518 | /* -------------------------------------------------------------------- |
519 | * TWI (i2c) |
520 | * -------------------------------------------------------------------- */ |
521 | |
522 | /* |
523 | * Prefer the GPIO code since the TWI controller isn't robust |
524 | * (gets overruns and underruns under load) and can only issue |
525 | * repeated STARTs in one scenario (the driver doesn't yet handle them). |
526 | */ |
527 | #if defined(CONFIG_I2C_GPIO) || defined(CONFIG_I2C_GPIO_MODULE) |
528 | |
529 | static struct i2c_gpio_platform_data pdata = { |
530 | .sda_pin = AT91_PIN_PB4, |
531 | .sda_is_open_drain = 1, |
532 | .scl_pin = AT91_PIN_PB5, |
533 | .scl_is_open_drain = 1, |
534 | .udelay = 2, /* ~100 kHz */ |
535 | }; |
536 | |
537 | static struct platform_device at91sam9263_twi_device = { |
538 | .name = "i2c-gpio", |
539 | .id = -1, |
540 | .dev.platform_data = &pdata, |
541 | }; |
542 | |
543 | void __init at91_add_device_i2c(struct i2c_board_info *devices, int nr_devices) |
544 | { |
545 | at91_set_GPIO_periph(AT91_PIN_PB4, 1); /* TWD (SDA) */ |
546 | at91_set_multi_drive(AT91_PIN_PB4, 1); |
547 | |
548 | at91_set_GPIO_periph(AT91_PIN_PB5, 1); /* TWCK (SCL) */ |
549 | at91_set_multi_drive(AT91_PIN_PB5, 1); |
550 | |
551 | i2c_register_board_info(0, devices, nr_devices); |
552 | platform_device_register(&at91sam9263_twi_device); |
553 | } |
554 | |
555 | #elif defined(CONFIG_I2C_AT91) || defined(CONFIG_I2C_AT91_MODULE) |
556 | |
557 | static struct resource twi_resources[] = { |
558 | [0] = { |
559 | .start = AT91SAM9263_BASE_TWI, |
560 | .end = AT91SAM9263_BASE_TWI + SZ_16K - 1, |
561 | .flags = IORESOURCE_MEM, |
562 | }, |
563 | [1] = { |
564 | .start = AT91SAM9263_ID_TWI, |
565 | .end = AT91SAM9263_ID_TWI, |
566 | .flags = IORESOURCE_IRQ, |
567 | }, |
568 | }; |
569 | |
570 | static struct platform_device at91sam9263_twi_device = { |
571 | .name = "at91_i2c", |
572 | .id = -1, |
573 | .resource = twi_resources, |
574 | .num_resources = ARRAY_SIZE(twi_resources), |
575 | }; |
576 | |
577 | void __init at91_add_device_i2c(struct i2c_board_info *devices, int nr_devices) |
578 | { |
579 | /* pins used for TWI interface */ |
580 | at91_set_A_periph(AT91_PIN_PB4, 0); /* TWD */ |
581 | at91_set_multi_drive(AT91_PIN_PB4, 1); |
582 | |
583 | at91_set_A_periph(AT91_PIN_PB5, 0); /* TWCK */ |
584 | at91_set_multi_drive(AT91_PIN_PB5, 1); |
585 | |
586 | i2c_register_board_info(0, devices, nr_devices); |
587 | platform_device_register(&at91sam9263_twi_device); |
588 | } |
589 | #else |
590 | void __init at91_add_device_i2c(struct i2c_board_info *devices, int nr_devices) {} |
591 | #endif |
592 | |
593 | |
594 | /* -------------------------------------------------------------------- |
595 | * SPI |
596 | * -------------------------------------------------------------------- */ |
597 | |
598 | #if defined(CONFIG_SPI_ATMEL) || defined(CONFIG_SPI_ATMEL_MODULE) |
599 | static u64 spi_dmamask = DMA_BIT_MASK(32); |
600 | |
601 | static struct resource spi0_resources[] = { |
602 | [0] = { |
603 | .start = AT91SAM9263_BASE_SPI0, |
604 | .end = AT91SAM9263_BASE_SPI0 + SZ_16K - 1, |
605 | .flags = IORESOURCE_MEM, |
606 | }, |
607 | [1] = { |
608 | .start = AT91SAM9263_ID_SPI0, |
609 | .end = AT91SAM9263_ID_SPI0, |
610 | .flags = IORESOURCE_IRQ, |
611 | }, |
612 | }; |
613 | |
614 | static struct platform_device at91sam9263_spi0_device = { |
615 | .name = "atmel_spi", |
616 | .id = 0, |
617 | .dev = { |
618 | .dma_mask = &spi_dmamask, |
619 | .coherent_dma_mask = DMA_BIT_MASK(32), |
620 | }, |
621 | .resource = spi0_resources, |
622 | .num_resources = ARRAY_SIZE(spi0_resources), |
623 | }; |
624 | |
625 | static const unsigned spi0_standard_cs[4] = { AT91_PIN_PA5, AT91_PIN_PA3, AT91_PIN_PA4, AT91_PIN_PB11 }; |
626 | |
627 | static struct resource spi1_resources[] = { |
628 | [0] = { |
629 | .start = AT91SAM9263_BASE_SPI1, |
630 | .end = AT91SAM9263_BASE_SPI1 + SZ_16K - 1, |
631 | .flags = IORESOURCE_MEM, |
632 | }, |
633 | [1] = { |
634 | .start = AT91SAM9263_ID_SPI1, |
635 | .end = AT91SAM9263_ID_SPI1, |
636 | .flags = IORESOURCE_IRQ, |
637 | }, |
638 | }; |
639 | |
640 | static struct platform_device at91sam9263_spi1_device = { |
641 | .name = "atmel_spi", |
642 | .id = 1, |
643 | .dev = { |
644 | .dma_mask = &spi_dmamask, |
645 | .coherent_dma_mask = DMA_BIT_MASK(32), |
646 | }, |
647 | .resource = spi1_resources, |
648 | .num_resources = ARRAY_SIZE(spi1_resources), |
649 | }; |
650 | |
651 | static const unsigned spi1_standard_cs[4] = { AT91_PIN_PB15, AT91_PIN_PB16, AT91_PIN_PB17, AT91_PIN_PB18 }; |
652 | |
653 | void __init at91_add_device_spi(struct spi_board_info *devices, int nr_devices) |
654 | { |
655 | int i; |
656 | unsigned long cs_pin; |
657 | short enable_spi0 = 0; |
658 | short enable_spi1 = 0; |
659 | |
660 | /* Choose SPI chip-selects */ |
661 | for (i = 0; i < nr_devices; i++) { |
662 | if (devices[i].controller_data) |
663 | cs_pin = (unsigned long) devices[i].controller_data; |
664 | else if (devices[i].bus_num == 0) |
665 | cs_pin = spi0_standard_cs[devices[i].chip_select]; |
666 | else |
667 | cs_pin = spi1_standard_cs[devices[i].chip_select]; |
668 | |
669 | if (devices[i].bus_num == 0) |
670 | enable_spi0 = 1; |
671 | else |
672 | enable_spi1 = 1; |
673 | |
674 | /* enable chip-select pin */ |
675 | at91_set_gpio_output(cs_pin, 1); |
676 | |
677 | /* pass chip-select pin to driver */ |
678 | devices[i].controller_data = (void *) cs_pin; |
679 | } |
680 | |
681 | spi_register_board_info(devices, nr_devices); |
682 | |
683 | /* Configure SPI bus(es) */ |
684 | if (enable_spi0) { |
685 | at91_set_B_periph(AT91_PIN_PA0, 0); /* SPI0_MISO */ |
686 | at91_set_B_periph(AT91_PIN_PA1, 0); /* SPI0_MOSI */ |
687 | at91_set_B_periph(AT91_PIN_PA2, 0); /* SPI0_SPCK */ |
688 | |
689 | at91_clock_associate("spi0_clk", &at91sam9263_spi0_device.dev, "spi_clk"); |
690 | platform_device_register(&at91sam9263_spi0_device); |
691 | } |
692 | if (enable_spi1) { |
693 | at91_set_A_periph(AT91_PIN_PB12, 0); /* SPI1_MISO */ |
694 | at91_set_A_periph(AT91_PIN_PB13, 0); /* SPI1_MOSI */ |
695 | at91_set_A_periph(AT91_PIN_PB14, 0); /* SPI1_SPCK */ |
696 | |
697 | at91_clock_associate("spi1_clk", &at91sam9263_spi1_device.dev, "spi_clk"); |
698 | platform_device_register(&at91sam9263_spi1_device); |
699 | } |
700 | } |
701 | #else |
702 | void __init at91_add_device_spi(struct spi_board_info *devices, int nr_devices) {} |
703 | #endif |
704 | |
705 | |
706 | /* -------------------------------------------------------------------- |
707 | * AC97 |
708 | * -------------------------------------------------------------------- */ |
709 | |
710 | #if defined(CONFIG_SND_ATMEL_AC97C) || defined(CONFIG_SND_ATMEL_AC97C_MODULE) |
711 | static u64 ac97_dmamask = DMA_BIT_MASK(32); |
712 | static struct ac97c_platform_data ac97_data; |
713 | |
714 | static struct resource ac97_resources[] = { |
715 | [0] = { |
716 | .start = AT91SAM9263_BASE_AC97C, |
717 | .end = AT91SAM9263_BASE_AC97C + SZ_16K - 1, |
718 | .flags = IORESOURCE_MEM, |
719 | }, |
720 | [1] = { |
721 | .start = AT91SAM9263_ID_AC97C, |
722 | .end = AT91SAM9263_ID_AC97C, |
723 | .flags = IORESOURCE_IRQ, |
724 | }, |
725 | }; |
726 | |
727 | static struct platform_device at91sam9263_ac97_device = { |
728 | .name = "atmel_ac97c", |
729 | .id = 0, |
730 | .dev = { |
731 | .dma_mask = &ac97_dmamask, |
732 | .coherent_dma_mask = DMA_BIT_MASK(32), |
733 | .platform_data = &ac97_data, |
734 | }, |
735 | .resource = ac97_resources, |
736 | .num_resources = ARRAY_SIZE(ac97_resources), |
737 | }; |
738 | |
739 | void __init at91_add_device_ac97(struct ac97c_platform_data *data) |
740 | { |
741 | if (!data) |
742 | return; |
743 | |
744 | at91_set_A_periph(AT91_PIN_PB0, 0); /* AC97FS */ |
745 | at91_set_A_periph(AT91_PIN_PB1, 0); /* AC97CK */ |
746 | at91_set_A_periph(AT91_PIN_PB2, 0); /* AC97TX */ |
747 | at91_set_A_periph(AT91_PIN_PB3, 0); /* AC97RX */ |
748 | |
749 | /* reset */ |
750 | if (data->reset_pin) |
751 | at91_set_gpio_output(data->reset_pin, 0); |
752 | |
753 | ac97_data = *data; |
754 | platform_device_register(&at91sam9263_ac97_device); |
755 | } |
756 | #else |
757 | void __init at91_add_device_ac97(struct ac97c_platform_data *data) {} |
758 | #endif |
759 | |
760 | /* -------------------------------------------------------------------- |
761 | * CAN Controller |
762 | * -------------------------------------------------------------------- */ |
763 | |
764 | #if defined(CONFIG_CAN_AT91) || defined(CONFIG_CAN_AT91_MODULE) |
765 | static struct resource can_resources[] = { |
766 | [0] = { |
767 | .start = AT91SAM9263_BASE_CAN, |
768 | .end = AT91SAM9263_BASE_CAN + SZ_16K - 1, |
769 | .flags = IORESOURCE_MEM, |
770 | }, |
771 | [1] = { |
772 | .start = AT91SAM9263_ID_CAN, |
773 | .end = AT91SAM9263_ID_CAN, |
774 | .flags = IORESOURCE_IRQ, |
775 | }, |
776 | }; |
777 | |
778 | static struct platform_device at91sam9263_can_device = { |
779 | .name = "at91_can", |
780 | .id = -1, |
781 | .resource = can_resources, |
782 | .num_resources = ARRAY_SIZE(can_resources), |
783 | }; |
784 | |
785 | void __init at91_add_device_can(struct at91_can_data *data) |
786 | { |
787 | at91_set_A_periph(AT91_PIN_PA13, 0); /* CANTX */ |
788 | at91_set_A_periph(AT91_PIN_PA14, 0); /* CANRX */ |
789 | at91sam9263_can_device.dev.platform_data = data; |
790 | |
791 | platform_device_register(&at91sam9263_can_device); |
792 | } |
793 | #else |
794 | void __init at91_add_device_can(struct at91_can_data *data) {} |
795 | #endif |
796 | |
797 | /* -------------------------------------------------------------------- |
798 | * LCD Controller |
799 | * -------------------------------------------------------------------- */ |
800 | |
801 | #if defined(CONFIG_FB_ATMEL) || defined(CONFIG_FB_ATMEL_MODULE) |
802 | static u64 lcdc_dmamask = DMA_BIT_MASK(32); |
803 | static struct atmel_lcdfb_info lcdc_data; |
804 | |
805 | static struct resource lcdc_resources[] = { |
806 | [0] = { |
807 | .start = AT91SAM9263_LCDC_BASE, |
808 | .end = AT91SAM9263_LCDC_BASE + SZ_4K - 1, |
809 | .flags = IORESOURCE_MEM, |
810 | }, |
811 | [1] = { |
812 | .start = AT91SAM9263_ID_LCDC, |
813 | .end = AT91SAM9263_ID_LCDC, |
814 | .flags = IORESOURCE_IRQ, |
815 | }, |
816 | }; |
817 | |
818 | static struct platform_device at91_lcdc_device = { |
819 | .name = "atmel_lcdfb", |
820 | .id = 0, |
821 | .dev = { |
822 | .dma_mask = &lcdc_dmamask, |
823 | .coherent_dma_mask = DMA_BIT_MASK(32), |
824 | .platform_data = &lcdc_data, |
825 | }, |
826 | .resource = lcdc_resources, |
827 | .num_resources = ARRAY_SIZE(lcdc_resources), |
828 | }; |
829 | |
830 | void __init at91_add_device_lcdc(struct atmel_lcdfb_info *data) |
831 | { |
832 | if (!data) |
833 | return; |
834 | |
835 | at91_set_A_periph(AT91_PIN_PC1, 0); /* LCDHSYNC */ |
836 | at91_set_A_periph(AT91_PIN_PC2, 0); /* LCDDOTCK */ |
837 | at91_set_A_periph(AT91_PIN_PC3, 0); /* LCDDEN */ |
838 | at91_set_B_periph(AT91_PIN_PB9, 0); /* LCDCC */ |
839 | at91_set_A_periph(AT91_PIN_PC6, 0); /* LCDD2 */ |
840 | at91_set_A_periph(AT91_PIN_PC7, 0); /* LCDD3 */ |
841 | at91_set_A_periph(AT91_PIN_PC8, 0); /* LCDD4 */ |
842 | at91_set_A_periph(AT91_PIN_PC9, 0); /* LCDD5 */ |
843 | at91_set_A_periph(AT91_PIN_PC10, 0); /* LCDD6 */ |
844 | at91_set_A_periph(AT91_PIN_PC11, 0); /* LCDD7 */ |
845 | at91_set_A_periph(AT91_PIN_PC14, 0); /* LCDD10 */ |
846 | at91_set_A_periph(AT91_PIN_PC15, 0); /* LCDD11 */ |
847 | at91_set_A_periph(AT91_PIN_PC16, 0); /* LCDD12 */ |
848 | at91_set_B_periph(AT91_PIN_PC12, 0); /* LCDD13 */ |
849 | at91_set_A_periph(AT91_PIN_PC18, 0); /* LCDD14 */ |
850 | at91_set_A_periph(AT91_PIN_PC19, 0); /* LCDD15 */ |
851 | at91_set_A_periph(AT91_PIN_PC22, 0); /* LCDD18 */ |
852 | at91_set_A_periph(AT91_PIN_PC23, 0); /* LCDD19 */ |
853 | at91_set_A_periph(AT91_PIN_PC24, 0); /* LCDD20 */ |
854 | at91_set_B_periph(AT91_PIN_PC17, 0); /* LCDD21 */ |
855 | at91_set_A_periph(AT91_PIN_PC26, 0); /* LCDD22 */ |
856 | at91_set_A_periph(AT91_PIN_PC27, 0); /* LCDD23 */ |
857 | |
858 | lcdc_data = *data; |
859 | platform_device_register(&at91_lcdc_device); |
860 | } |
861 | #else |
862 | void __init at91_add_device_lcdc(struct atmel_lcdfb_info *data) {} |
863 | #endif |
864 | |
865 | |
866 | /* -------------------------------------------------------------------- |
867 | * Image Sensor Interface |
868 | * -------------------------------------------------------------------- */ |
869 | |
870 | #if defined(CONFIG_VIDEO_AT91_ISI) || defined(CONFIG_VIDEO_AT91_ISI_MODULE) |
871 | |
872 | struct resource isi_resources[] = { |
873 | [0] = { |
874 | .start = AT91SAM9263_BASE_ISI, |
875 | .end = AT91SAM9263_BASE_ISI + SZ_16K - 1, |
876 | .flags = IORESOURCE_MEM, |
877 | }, |
878 | [1] = { |
879 | .start = AT91SAM9263_ID_ISI, |
880 | .end = AT91SAM9263_ID_ISI, |
881 | .flags = IORESOURCE_IRQ, |
882 | }, |
883 | }; |
884 | |
885 | static struct platform_device at91sam9263_isi_device = { |
886 | .name = "at91_isi", |
887 | .id = -1, |
888 | .resource = isi_resources, |
889 | .num_resources = ARRAY_SIZE(isi_resources), |
890 | }; |
891 | |
892 | void __init at91_add_device_isi(void) |
893 | { |
894 | at91_set_A_periph(AT91_PIN_PE0, 0); /* ISI_D0 */ |
895 | at91_set_A_periph(AT91_PIN_PE1, 0); /* ISI_D1 */ |
896 | at91_set_A_periph(AT91_PIN_PE2, 0); /* ISI_D2 */ |
897 | at91_set_A_periph(AT91_PIN_PE3, 0); /* ISI_D3 */ |
898 | at91_set_A_periph(AT91_PIN_PE4, 0); /* ISI_D4 */ |
899 | at91_set_A_periph(AT91_PIN_PE5, 0); /* ISI_D5 */ |
900 | at91_set_A_periph(AT91_PIN_PE6, 0); /* ISI_D6 */ |
901 | at91_set_A_periph(AT91_PIN_PE7, 0); /* ISI_D7 */ |
902 | at91_set_A_periph(AT91_PIN_PE8, 0); /* ISI_PCK */ |
903 | at91_set_A_periph(AT91_PIN_PE9, 0); /* ISI_HSYNC */ |
904 | at91_set_A_periph(AT91_PIN_PE10, 0); /* ISI_VSYNC */ |
905 | at91_set_B_periph(AT91_PIN_PE11, 0); /* ISI_MCK (PCK3) */ |
906 | at91_set_B_periph(AT91_PIN_PE12, 0); /* ISI_PD8 */ |
907 | at91_set_B_periph(AT91_PIN_PE13, 0); /* ISI_PD9 */ |
908 | at91_set_B_periph(AT91_PIN_PE14, 0); /* ISI_PD10 */ |
909 | at91_set_B_periph(AT91_PIN_PE15, 0); /* ISI_PD11 */ |
910 | } |
911 | #else |
912 | void __init at91_add_device_isi(void) {} |
913 | #endif |
914 | |
915 | |
916 | /* -------------------------------------------------------------------- |
917 | * Timer/Counter block |
918 | * -------------------------------------------------------------------- */ |
919 | |
920 | #ifdef CONFIG_ATMEL_TCLIB |
921 | |
922 | static struct resource tcb_resources[] = { |
923 | [0] = { |
924 | .start = AT91SAM9263_BASE_TCB0, |
925 | .end = AT91SAM9263_BASE_TCB0 + SZ_16K - 1, |
926 | .flags = IORESOURCE_MEM, |
927 | }, |
928 | [1] = { |
929 | .start = AT91SAM9263_ID_TCB, |
930 | .end = AT91SAM9263_ID_TCB, |
931 | .flags = IORESOURCE_IRQ, |
932 | }, |
933 | }; |
934 | |
935 | static struct platform_device at91sam9263_tcb_device = { |
936 | .name = "atmel_tcb", |
937 | .id = 0, |
938 | .resource = tcb_resources, |
939 | .num_resources = ARRAY_SIZE(tcb_resources), |
940 | }; |
941 | |
942 | static void __init at91_add_device_tc(void) |
943 | { |
944 | /* this chip has one clock and irq for all three TC channels */ |
945 | at91_clock_associate("tcb_clk", &at91sam9263_tcb_device.dev, "t0_clk"); |
946 | platform_device_register(&at91sam9263_tcb_device); |
947 | } |
948 | #else |
949 | static void __init at91_add_device_tc(void) { } |
950 | #endif |
951 | |
952 | |
953 | /* -------------------------------------------------------------------- |
954 | * RTT |
955 | * -------------------------------------------------------------------- */ |
956 | |
957 | static struct resource rtt0_resources[] = { |
958 | { |
959 | .start = AT91_BASE_SYS + AT91_RTT0, |
960 | .end = AT91_BASE_SYS + AT91_RTT0 + SZ_16 - 1, |
961 | .flags = IORESOURCE_MEM, |
962 | } |
963 | }; |
964 | |
965 | static struct platform_device at91sam9263_rtt0_device = { |
966 | .name = "at91_rtt", |
967 | .id = 0, |
968 | .resource = rtt0_resources, |
969 | .num_resources = ARRAY_SIZE(rtt0_resources), |
970 | }; |
971 | |
972 | static struct resource rtt1_resources[] = { |
973 | { |
974 | .start = AT91_BASE_SYS + AT91_RTT1, |
975 | .end = AT91_BASE_SYS + AT91_RTT1 + SZ_16 - 1, |
976 | .flags = IORESOURCE_MEM, |
977 | } |
978 | }; |
979 | |
980 | static struct platform_device at91sam9263_rtt1_device = { |
981 | .name = "at91_rtt", |
982 | .id = 1, |
983 | .resource = rtt1_resources, |
984 | .num_resources = ARRAY_SIZE(rtt1_resources), |
985 | }; |
986 | |
987 | static void __init at91_add_device_rtt(void) |
988 | { |
989 | platform_device_register(&at91sam9263_rtt0_device); |
990 | platform_device_register(&at91sam9263_rtt1_device); |
991 | } |
992 | |
993 | |
994 | /* -------------------------------------------------------------------- |
995 | * Watchdog |
996 | * -------------------------------------------------------------------- */ |
997 | |
998 | #if defined(CONFIG_AT91SAM9X_WATCHDOG) || defined(CONFIG_AT91SAM9X_WATCHDOG_MODULE) |
999 | static struct platform_device at91sam9263_wdt_device = { |
1000 | .name = "at91_wdt", |
1001 | .id = -1, |
1002 | .num_resources = 0, |
1003 | }; |
1004 | |
1005 | static void __init at91_add_device_watchdog(void) |
1006 | { |
1007 | platform_device_register(&at91sam9263_wdt_device); |
1008 | } |
1009 | #else |
1010 | static void __init at91_add_device_watchdog(void) {} |
1011 | #endif |
1012 | |
1013 | |
1014 | /* -------------------------------------------------------------------- |
1015 | * PWM |
1016 | * --------------------------------------------------------------------*/ |
1017 | |
1018 | #if defined(CONFIG_ATMEL_PWM) |
1019 | static u32 pwm_mask; |
1020 | |
1021 | static struct resource pwm_resources[] = { |
1022 | [0] = { |
1023 | .start = AT91SAM9263_BASE_PWMC, |
1024 | .end = AT91SAM9263_BASE_PWMC + SZ_16K - 1, |
1025 | .flags = IORESOURCE_MEM, |
1026 | }, |
1027 | [1] = { |
1028 | .start = AT91SAM9263_ID_PWMC, |
1029 | .end = AT91SAM9263_ID_PWMC, |
1030 | .flags = IORESOURCE_IRQ, |
1031 | }, |
1032 | }; |
1033 | |
1034 | static struct platform_device at91sam9263_pwm0_device = { |
1035 | .name = "atmel_pwm", |
1036 | .id = -1, |
1037 | .dev = { |
1038 | .platform_data = &pwm_mask, |
1039 | }, |
1040 | .resource = pwm_resources, |
1041 | .num_resources = ARRAY_SIZE(pwm_resources), |
1042 | }; |
1043 | |
1044 | void __init at91_add_device_pwm(u32 mask) |
1045 | { |
1046 | if (mask & (1 << AT91_PWM0)) |
1047 | at91_set_B_periph(AT91_PIN_PB7, 1); /* enable PWM0 */ |
1048 | |
1049 | if (mask & (1 << AT91_PWM1)) |
1050 | at91_set_B_periph(AT91_PIN_PB8, 1); /* enable PWM1 */ |
1051 | |
1052 | if (mask & (1 << AT91_PWM2)) |
1053 | at91_set_B_periph(AT91_PIN_PC29, 1); /* enable PWM2 */ |
1054 | |
1055 | if (mask & (1 << AT91_PWM3)) |
1056 | at91_set_B_periph(AT91_PIN_PB29, 1); /* enable PWM3 */ |
1057 | |
1058 | pwm_mask = mask; |
1059 | |
1060 | platform_device_register(&at91sam9263_pwm0_device); |
1061 | } |
1062 | #else |
1063 | void __init at91_add_device_pwm(u32 mask) {} |
1064 | #endif |
1065 | |
1066 | |
1067 | /* -------------------------------------------------------------------- |
1068 | * SSC -- Synchronous Serial Controller |
1069 | * -------------------------------------------------------------------- */ |
1070 | |
1071 | #if defined(CONFIG_ATMEL_SSC) || defined(CONFIG_ATMEL_SSC_MODULE) |
1072 | static u64 ssc0_dmamask = DMA_BIT_MASK(32); |
1073 | |
1074 | static struct resource ssc0_resources[] = { |
1075 | [0] = { |
1076 | .start = AT91SAM9263_BASE_SSC0, |
1077 | .end = AT91SAM9263_BASE_SSC0 + SZ_16K - 1, |
1078 | .flags = IORESOURCE_MEM, |
1079 | }, |
1080 | [1] = { |
1081 | .start = AT91SAM9263_ID_SSC0, |
1082 | .end = AT91SAM9263_ID_SSC0, |
1083 | .flags = IORESOURCE_IRQ, |
1084 | }, |
1085 | }; |
1086 | |
1087 | static struct platform_device at91sam9263_ssc0_device = { |
1088 | .name = "ssc", |
1089 | .id = 0, |
1090 | .dev = { |
1091 | .dma_mask = &ssc0_dmamask, |
1092 | .coherent_dma_mask = DMA_BIT_MASK(32), |
1093 | }, |
1094 | .resource = ssc0_resources, |
1095 | .num_resources = ARRAY_SIZE(ssc0_resources), |
1096 | }; |
1097 | |
1098 | static inline void configure_ssc0_pins(unsigned pins) |
1099 | { |
1100 | if (pins & ATMEL_SSC_TF) |
1101 | at91_set_B_periph(AT91_PIN_PB0, 1); |
1102 | if (pins & ATMEL_SSC_TK) |
1103 | at91_set_B_periph(AT91_PIN_PB1, 1); |
1104 | if (pins & ATMEL_SSC_TD) |
1105 | at91_set_B_periph(AT91_PIN_PB2, 1); |
1106 | if (pins & ATMEL_SSC_RD) |
1107 | at91_set_B_periph(AT91_PIN_PB3, 1); |
1108 | if (pins & ATMEL_SSC_RK) |
1109 | at91_set_B_periph(AT91_PIN_PB4, 1); |
1110 | if (pins & ATMEL_SSC_RF) |
1111 | at91_set_B_periph(AT91_PIN_PB5, 1); |
1112 | } |
1113 | |
1114 | static u64 ssc1_dmamask = DMA_BIT_MASK(32); |
1115 | |
1116 | static struct resource ssc1_resources[] = { |
1117 | [0] = { |
1118 | .start = AT91SAM9263_BASE_SSC1, |
1119 | .end = AT91SAM9263_BASE_SSC1 + SZ_16K - 1, |
1120 | .flags = IORESOURCE_MEM, |
1121 | }, |
1122 | [1] = { |
1123 | .start = AT91SAM9263_ID_SSC1, |
1124 | .end = AT91SAM9263_ID_SSC1, |
1125 | .flags = IORESOURCE_IRQ, |
1126 | }, |
1127 | }; |
1128 | |
1129 | static struct platform_device at91sam9263_ssc1_device = { |
1130 | .name = "ssc", |
1131 | .id = 1, |
1132 | .dev = { |
1133 | .dma_mask = &ssc1_dmamask, |
1134 | .coherent_dma_mask = DMA_BIT_MASK(32), |
1135 | }, |
1136 | .resource = ssc1_resources, |
1137 | .num_resources = ARRAY_SIZE(ssc1_resources), |
1138 | }; |
1139 | |
1140 | static inline void configure_ssc1_pins(unsigned pins) |
1141 | { |
1142 | if (pins & ATMEL_SSC_TF) |
1143 | at91_set_A_periph(AT91_PIN_PB6, 1); |
1144 | if (pins & ATMEL_SSC_TK) |
1145 | at91_set_A_periph(AT91_PIN_PB7, 1); |
1146 | if (pins & ATMEL_SSC_TD) |
1147 | at91_set_A_periph(AT91_PIN_PB8, 1); |
1148 | if (pins & ATMEL_SSC_RD) |
1149 | at91_set_A_periph(AT91_PIN_PB9, 1); |
1150 | if (pins & ATMEL_SSC_RK) |
1151 | at91_set_A_periph(AT91_PIN_PB10, 1); |
1152 | if (pins & ATMEL_SSC_RF) |
1153 | at91_set_A_periph(AT91_PIN_PB11, 1); |
1154 | } |
1155 | |
1156 | /* |
1157 | * SSC controllers are accessed through library code, instead of any |
1158 | * kind of all-singing/all-dancing driver. For example one could be |
1159 | * used by a particular I2S audio codec's driver, while another one |
1160 | * on the same system might be used by a custom data capture driver. |
1161 | */ |
1162 | void __init at91_add_device_ssc(unsigned id, unsigned pins) |
1163 | { |
1164 | struct platform_device *pdev; |
1165 | |
1166 | /* |
1167 | * NOTE: caller is responsible for passing information matching |
1168 | * "pins" to whatever will be using each particular controller. |
1169 | */ |
1170 | switch (id) { |
1171 | case AT91SAM9263_ID_SSC0: |
1172 | pdev = &at91sam9263_ssc0_device; |
1173 | configure_ssc0_pins(pins); |
1174 | at91_clock_associate("ssc0_clk", &pdev->dev, "pclk"); |
1175 | break; |
1176 | case AT91SAM9263_ID_SSC1: |
1177 | pdev = &at91sam9263_ssc1_device; |
1178 | configure_ssc1_pins(pins); |
1179 | at91_clock_associate("ssc1_clk", &pdev->dev, "pclk"); |
1180 | break; |
1181 | default: |
1182 | return; |
1183 | } |
1184 | |
1185 | platform_device_register(pdev); |
1186 | } |
1187 | |
1188 | #else |
1189 | void __init at91_add_device_ssc(unsigned id, unsigned pins) {} |
1190 | #endif |
1191 | |
1192 | |
1193 | /* -------------------------------------------------------------------- |
1194 | * UART |
1195 | * -------------------------------------------------------------------- */ |
1196 | |
1197 | #if defined(CONFIG_SERIAL_ATMEL) |
1198 | |
1199 | static struct resource dbgu_resources[] = { |
1200 | [0] = { |
1201 | .start = AT91_VA_BASE_SYS + AT91_DBGU, |
1202 | .end = AT91_VA_BASE_SYS + AT91_DBGU + SZ_512 - 1, |
1203 | .flags = IORESOURCE_MEM, |
1204 | }, |
1205 | [1] = { |
1206 | .start = AT91_ID_SYS, |
1207 | .end = AT91_ID_SYS, |
1208 | .flags = IORESOURCE_IRQ, |
1209 | }, |
1210 | }; |
1211 | |
1212 | static struct atmel_uart_data dbgu_data = { |
1213 | .use_dma_tx = 0, |
1214 | .use_dma_rx = 0, /* DBGU not capable of receive DMA */ |
1215 | .regs = (void __iomem *)(AT91_VA_BASE_SYS + AT91_DBGU), |
1216 | }; |
1217 | |
1218 | static u64 dbgu_dmamask = DMA_BIT_MASK(32); |
1219 | |
1220 | static struct platform_device at91sam9263_dbgu_device = { |
1221 | .name = "atmel_usart", |
1222 | .id = 0, |
1223 | .dev = { |
1224 | .dma_mask = &dbgu_dmamask, |
1225 | .coherent_dma_mask = DMA_BIT_MASK(32), |
1226 | .platform_data = &dbgu_data, |
1227 | }, |
1228 | .resource = dbgu_resources, |
1229 | .num_resources = ARRAY_SIZE(dbgu_resources), |
1230 | }; |
1231 | |
1232 | static inline void configure_dbgu_pins(void) |
1233 | { |
1234 | at91_set_A_periph(AT91_PIN_PC30, 0); /* DRXD */ |
1235 | at91_set_A_periph(AT91_PIN_PC31, 1); /* DTXD */ |
1236 | } |
1237 | |
1238 | static struct resource uart0_resources[] = { |
1239 | [0] = { |
1240 | .start = AT91SAM9263_BASE_US0, |
1241 | .end = AT91SAM9263_BASE_US0 + SZ_16K - 1, |
1242 | .flags = IORESOURCE_MEM, |
1243 | }, |
1244 | [1] = { |
1245 | .start = AT91SAM9263_ID_US0, |
1246 | .end = AT91SAM9263_ID_US0, |
1247 | .flags = IORESOURCE_IRQ, |
1248 | }, |
1249 | }; |
1250 | |
1251 | static struct atmel_uart_data uart0_data = { |
1252 | .use_dma_tx = 1, |
1253 | .use_dma_rx = 1, |
1254 | }; |
1255 | |
1256 | static u64 uart0_dmamask = DMA_BIT_MASK(32); |
1257 | |
1258 | static struct platform_device at91sam9263_uart0_device = { |
1259 | .name = "atmel_usart", |
1260 | .id = 1, |
1261 | .dev = { |
1262 | .dma_mask = &uart0_dmamask, |
1263 | .coherent_dma_mask = DMA_BIT_MASK(32), |
1264 | .platform_data = &uart0_data, |
1265 | }, |
1266 | .resource = uart0_resources, |
1267 | .num_resources = ARRAY_SIZE(uart0_resources), |
1268 | }; |
1269 | |
1270 | static inline void configure_usart0_pins(unsigned pins) |
1271 | { |
1272 | at91_set_A_periph(AT91_PIN_PA26, 1); /* TXD0 */ |
1273 | at91_set_A_periph(AT91_PIN_PA27, 0); /* RXD0 */ |
1274 | |
1275 | if (pins & ATMEL_UART_RTS) |
1276 | at91_set_A_periph(AT91_PIN_PA28, 0); /* RTS0 */ |
1277 | if (pins & ATMEL_UART_CTS) |
1278 | at91_set_A_periph(AT91_PIN_PA29, 0); /* CTS0 */ |
1279 | } |
1280 | |
1281 | static struct resource uart1_resources[] = { |
1282 | [0] = { |
1283 | .start = AT91SAM9263_BASE_US1, |
1284 | .end = AT91SAM9263_BASE_US1 + SZ_16K - 1, |
1285 | .flags = IORESOURCE_MEM, |
1286 | }, |
1287 | [1] = { |
1288 | .start = AT91SAM9263_ID_US1, |
1289 | .end = AT91SAM9263_ID_US1, |
1290 | .flags = IORESOURCE_IRQ, |
1291 | }, |
1292 | }; |
1293 | |
1294 | static struct atmel_uart_data uart1_data = { |
1295 | .use_dma_tx = 1, |
1296 | .use_dma_rx = 1, |
1297 | }; |
1298 | |
1299 | static u64 uart1_dmamask = DMA_BIT_MASK(32); |
1300 | |
1301 | static struct platform_device at91sam9263_uart1_device = { |
1302 | .name = "atmel_usart", |
1303 | .id = 2, |
1304 | .dev = { |
1305 | .dma_mask = &uart1_dmamask, |
1306 | .coherent_dma_mask = DMA_BIT_MASK(32), |
1307 | .platform_data = &uart1_data, |
1308 | }, |
1309 | .resource = uart1_resources, |
1310 | .num_resources = ARRAY_SIZE(uart1_resources), |
1311 | }; |
1312 | |
1313 | static inline void configure_usart1_pins(unsigned pins) |
1314 | { |
1315 | at91_set_A_periph(AT91_PIN_PD0, 1); /* TXD1 */ |
1316 | at91_set_A_periph(AT91_PIN_PD1, 0); /* RXD1 */ |
1317 | |
1318 | if (pins & ATMEL_UART_RTS) |
1319 | at91_set_B_periph(AT91_PIN_PD7, 0); /* RTS1 */ |
1320 | if (pins & ATMEL_UART_CTS) |
1321 | at91_set_B_periph(AT91_PIN_PD8, 0); /* CTS1 */ |
1322 | } |
1323 | |
1324 | static struct resource uart2_resources[] = { |
1325 | [0] = { |
1326 | .start = AT91SAM9263_BASE_US2, |
1327 | .end = AT91SAM9263_BASE_US2 + SZ_16K - 1, |
1328 | .flags = IORESOURCE_MEM, |
1329 | }, |
1330 | [1] = { |
1331 | .start = AT91SAM9263_ID_US2, |
1332 | .end = AT91SAM9263_ID_US2, |
1333 | .flags = IORESOURCE_IRQ, |
1334 | }, |
1335 | }; |
1336 | |
1337 | static struct atmel_uart_data uart2_data = { |
1338 | .use_dma_tx = 1, |
1339 | .use_dma_rx = 1, |
1340 | }; |
1341 | |
1342 | static u64 uart2_dmamask = DMA_BIT_MASK(32); |
1343 | |
1344 | static struct platform_device at91sam9263_uart2_device = { |
1345 | .name = "atmel_usart", |
1346 | .id = 3, |
1347 | .dev = { |
1348 | .dma_mask = &uart2_dmamask, |
1349 | .coherent_dma_mask = DMA_BIT_MASK(32), |
1350 | .platform_data = &uart2_data, |
1351 | }, |
1352 | .resource = uart2_resources, |
1353 | .num_resources = ARRAY_SIZE(uart2_resources), |
1354 | }; |
1355 | |
1356 | static inline void configure_usart2_pins(unsigned pins) |
1357 | { |
1358 | at91_set_A_periph(AT91_PIN_PD2, 1); /* TXD2 */ |
1359 | at91_set_A_periph(AT91_PIN_PD3, 0); /* RXD2 */ |
1360 | |
1361 | if (pins & ATMEL_UART_RTS) |
1362 | at91_set_B_periph(AT91_PIN_PD5, 0); /* RTS2 */ |
1363 | if (pins & ATMEL_UART_CTS) |
1364 | at91_set_B_periph(AT91_PIN_PD6, 0); /* CTS2 */ |
1365 | } |
1366 | |
1367 | static struct platform_device *__initdata at91_uarts[ATMEL_MAX_UART]; /* the UARTs to use */ |
1368 | struct platform_device *atmel_default_console_device; /* the serial console device */ |
1369 | |
1370 | void __init at91_register_uart(unsigned id, unsigned portnr, unsigned pins) |
1371 | { |
1372 | struct platform_device *pdev; |
1373 | |
1374 | switch (id) { |
1375 | case 0: /* DBGU */ |
1376 | pdev = &at91sam9263_dbgu_device; |
1377 | configure_dbgu_pins(); |
1378 | at91_clock_associate("mck", &pdev->dev, "usart"); |
1379 | break; |
1380 | case AT91SAM9263_ID_US0: |
1381 | pdev = &at91sam9263_uart0_device; |
1382 | configure_usart0_pins(pins); |
1383 | at91_clock_associate("usart0_clk", &pdev->dev, "usart"); |
1384 | break; |
1385 | case AT91SAM9263_ID_US1: |
1386 | pdev = &at91sam9263_uart1_device; |
1387 | configure_usart1_pins(pins); |
1388 | at91_clock_associate("usart1_clk", &pdev->dev, "usart"); |
1389 | break; |
1390 | case AT91SAM9263_ID_US2: |
1391 | pdev = &at91sam9263_uart2_device; |
1392 | configure_usart2_pins(pins); |
1393 | at91_clock_associate("usart2_clk", &pdev->dev, "usart"); |
1394 | break; |
1395 | default: |
1396 | return; |
1397 | } |
1398 | pdev->id = portnr; /* update to mapped ID */ |
1399 | |
1400 | if (portnr < ATMEL_MAX_UART) |
1401 | at91_uarts[portnr] = pdev; |
1402 | } |
1403 | |
1404 | void __init at91_set_serial_console(unsigned portnr) |
1405 | { |
1406 | if (portnr < ATMEL_MAX_UART) |
1407 | atmel_default_console_device = at91_uarts[portnr]; |
1408 | } |
1409 | |
1410 | void __init at91_add_device_serial(void) |
1411 | { |
1412 | int i; |
1413 | |
1414 | for (i = 0; i < ATMEL_MAX_UART; i++) { |
1415 | if (at91_uarts[i]) |
1416 | platform_device_register(at91_uarts[i]); |
1417 | } |
1418 | |
1419 | if (!atmel_default_console_device) |
1420 | printk(KERN_INFO "AT91: No default serial console defined.\n"); |
1421 | } |
1422 | #else |
1423 | void __init at91_register_uart(unsigned id, unsigned portnr, unsigned pins) {} |
1424 | void __init at91_set_serial_console(unsigned portnr) {} |
1425 | void __init at91_add_device_serial(void) {} |
1426 | #endif |
1427 | |
1428 | |
1429 | /* -------------------------------------------------------------------- */ |
1430 | /* |
1431 | * These devices are always present and don't need any board-specific |
1432 | * setup. |
1433 | */ |
1434 | static int __init at91_add_standard_devices(void) |
1435 | { |
1436 | at91_add_device_rtt(); |
1437 | at91_add_device_watchdog(); |
1438 | at91_add_device_tc(); |
1439 | return 0; |
1440 | } |
1441 | |
1442 | arch_initcall(at91_add_standard_devices); |
1443 |
Branches:
ben-wpan
ben-wpan-stefan
javiroman/ks7010
jz-2.6.34
jz-2.6.34-rc5
jz-2.6.34-rc6
jz-2.6.34-rc7
jz-2.6.35
jz-2.6.36
jz-2.6.37
jz-2.6.38
jz-2.6.39
jz-3.0
jz-3.1
jz-3.11
jz-3.12
jz-3.13
jz-3.15
jz-3.16
jz-3.18-dt
jz-3.2
jz-3.3
jz-3.4
jz-3.5
jz-3.6
jz-3.6-rc2-pwm
jz-3.9
jz-3.9-clk
jz-3.9-rc8
jz47xx
jz47xx-2.6.38
master
Tags:
od-2011-09-04
od-2011-09-18
v2.6.34-rc5
v2.6.34-rc6
v2.6.34-rc7
v3.9