Commit | Line | Data |
---|---|---|
b2c65616 AV |
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/platform_device.h> | |
16 | ||
17 | #include <asm/arch/board.h> | |
18 | #include <asm/arch/gpio.h> | |
19 | #include <asm/arch/at91sam9263.h> | |
20 | #include <asm/arch/at91sam926x_mc.h> | |
21 | #include <asm/arch/at91sam9263_matrix.h> | |
22 | ||
23 | #include "generic.h" | |
24 | ||
b2c65616 AV |
25 | |
26 | /* -------------------------------------------------------------------- | |
27 | * USB Host | |
28 | * -------------------------------------------------------------------- */ | |
29 | ||
30 | #if defined(CONFIG_USB_OHCI_HCD) || defined(CONFIG_USB_OHCI_HCD_MODULE) | |
31 | static u64 ohci_dmamask = 0xffffffffUL; | |
32 | static struct at91_usbh_data usbh_data; | |
33 | ||
34 | static struct resource usbh_resources[] = { | |
35 | [0] = { | |
36 | .start = AT91SAM9263_UHP_BASE, | |
37 | .end = AT91SAM9263_UHP_BASE + SZ_1M - 1, | |
38 | .flags = IORESOURCE_MEM, | |
39 | }, | |
40 | [1] = { | |
41 | .start = AT91SAM9263_ID_UHP, | |
42 | .end = AT91SAM9263_ID_UHP, | |
43 | .flags = IORESOURCE_IRQ, | |
44 | }, | |
45 | }; | |
46 | ||
47 | static struct platform_device at91_usbh_device = { | |
48 | .name = "at91_ohci", | |
49 | .id = -1, | |
50 | .dev = { | |
51 | .dma_mask = &ohci_dmamask, | |
52 | .coherent_dma_mask = 0xffffffff, | |
53 | .platform_data = &usbh_data, | |
54 | }, | |
55 | .resource = usbh_resources, | |
56 | .num_resources = ARRAY_SIZE(usbh_resources), | |
57 | }; | |
58 | ||
59 | void __init at91_add_device_usbh(struct at91_usbh_data *data) | |
60 | { | |
61 | int i; | |
62 | ||
63 | if (!data) | |
64 | return; | |
65 | ||
66 | /* Enable VBus control for UHP ports */ | |
67 | for (i = 0; i < data->ports; i++) { | |
68 | if (data->vbus_pin[i]) | |
69 | at91_set_gpio_output(data->vbus_pin[i], 0); | |
70 | } | |
71 | ||
72 | usbh_data = *data; | |
73 | platform_device_register(&at91_usbh_device); | |
74 | } | |
75 | #else | |
76 | void __init at91_add_device_usbh(struct at91_usbh_data *data) {} | |
77 | #endif | |
78 | ||
79 | ||
80 | /* -------------------------------------------------------------------- | |
81 | * USB Device (Gadget) | |
82 | * -------------------------------------------------------------------- */ | |
83 | ||
84 | #ifdef CONFIG_USB_GADGET_AT91 | |
85 | static struct at91_udc_data udc_data; | |
86 | ||
87 | static struct resource udc_resources[] = { | |
88 | [0] = { | |
89 | .start = AT91SAM9263_BASE_UDP, | |
90 | .end = AT91SAM9263_BASE_UDP + SZ_16K - 1, | |
91 | .flags = IORESOURCE_MEM, | |
92 | }, | |
93 | [1] = { | |
94 | .start = AT91SAM9263_ID_UDP, | |
95 | .end = AT91SAM9263_ID_UDP, | |
96 | .flags = IORESOURCE_IRQ, | |
97 | }, | |
98 | }; | |
99 | ||
100 | static struct platform_device at91_udc_device = { | |
101 | .name = "at91_udc", | |
102 | .id = -1, | |
103 | .dev = { | |
104 | .platform_data = &udc_data, | |
105 | }, | |
106 | .resource = udc_resources, | |
107 | .num_resources = ARRAY_SIZE(udc_resources), | |
108 | }; | |
109 | ||
110 | void __init at91_add_device_udc(struct at91_udc_data *data) | |
111 | { | |
112 | if (!data) | |
113 | return; | |
114 | ||
115 | if (data->vbus_pin) { | |
116 | at91_set_gpio_input(data->vbus_pin, 0); | |
117 | at91_set_deglitch(data->vbus_pin, 1); | |
118 | } | |
119 | ||
120 | /* Pullup pin is handled internally by USB device peripheral */ | |
121 | ||
122 | udc_data = *data; | |
123 | platform_device_register(&at91_udc_device); | |
124 | } | |
125 | #else | |
126 | void __init at91_add_device_udc(struct at91_udc_data *data) {} | |
127 | #endif | |
128 | ||
129 | ||
130 | /* -------------------------------------------------------------------- | |
131 | * Ethernet | |
132 | * -------------------------------------------------------------------- */ | |
133 | ||
134 | #if defined(CONFIG_MACB) || defined(CONFIG_MACB_MODULE) | |
135 | static u64 eth_dmamask = 0xffffffffUL; | |
136 | static struct at91_eth_data eth_data; | |
137 | ||
138 | static struct resource eth_resources[] = { | |
139 | [0] = { | |
140 | .start = AT91SAM9263_BASE_EMAC, | |
141 | .end = AT91SAM9263_BASE_EMAC + SZ_16K - 1, | |
142 | .flags = IORESOURCE_MEM, | |
143 | }, | |
144 | [1] = { | |
145 | .start = AT91SAM9263_ID_EMAC, | |
146 | .end = AT91SAM9263_ID_EMAC, | |
147 | .flags = IORESOURCE_IRQ, | |
148 | }, | |
149 | }; | |
150 | ||
151 | static struct platform_device at91sam9263_eth_device = { | |
152 | .name = "macb", | |
153 | .id = -1, | |
154 | .dev = { | |
155 | .dma_mask = ð_dmamask, | |
156 | .coherent_dma_mask = 0xffffffff, | |
157 | .platform_data = ð_data, | |
158 | }, | |
159 | .resource = eth_resources, | |
160 | .num_resources = ARRAY_SIZE(eth_resources), | |
161 | }; | |
162 | ||
163 | void __init at91_add_device_eth(struct at91_eth_data *data) | |
164 | { | |
165 | if (!data) | |
166 | return; | |
167 | ||
168 | if (data->phy_irq_pin) { | |
169 | at91_set_gpio_input(data->phy_irq_pin, 0); | |
170 | at91_set_deglitch(data->phy_irq_pin, 1); | |
171 | } | |
172 | ||
173 | /* Pins used for MII and RMII */ | |
174 | at91_set_A_periph(AT91_PIN_PE21, 0); /* ETXCK_EREFCK */ | |
175 | at91_set_B_periph(AT91_PIN_PC25, 0); /* ERXDV */ | |
176 | at91_set_A_periph(AT91_PIN_PE25, 0); /* ERX0 */ | |
177 | at91_set_A_periph(AT91_PIN_PE26, 0); /* ERX1 */ | |
178 | at91_set_A_periph(AT91_PIN_PE27, 0); /* ERXER */ | |
179 | at91_set_A_periph(AT91_PIN_PE28, 0); /* ETXEN */ | |
180 | at91_set_A_periph(AT91_PIN_PE23, 0); /* ETX0 */ | |
181 | at91_set_A_periph(AT91_PIN_PE24, 0); /* ETX1 */ | |
182 | at91_set_A_periph(AT91_PIN_PE30, 0); /* EMDIO */ | |
183 | at91_set_A_periph(AT91_PIN_PE29, 0); /* EMDC */ | |
184 | ||
185 | if (!data->is_rmii) { | |
186 | at91_set_A_periph(AT91_PIN_PE22, 0); /* ECRS */ | |
187 | at91_set_B_periph(AT91_PIN_PC26, 0); /* ECOL */ | |
188 | at91_set_B_periph(AT91_PIN_PC22, 0); /* ERX2 */ | |
189 | at91_set_B_periph(AT91_PIN_PC23, 0); /* ERX3 */ | |
190 | at91_set_B_periph(AT91_PIN_PC27, 0); /* ERXCK */ | |
191 | at91_set_B_periph(AT91_PIN_PC20, 0); /* ETX2 */ | |
192 | at91_set_B_periph(AT91_PIN_PC21, 0); /* ETX3 */ | |
193 | at91_set_B_periph(AT91_PIN_PC24, 0); /* ETXER */ | |
194 | } | |
195 | ||
196 | eth_data = *data; | |
197 | platform_device_register(&at91sam9263_eth_device); | |
198 | } | |
199 | #else | |
200 | void __init at91_add_device_eth(struct at91_eth_data *data) {} | |
201 | #endif | |
202 | ||
203 | ||
204 | /* -------------------------------------------------------------------- | |
205 | * MMC / SD | |
206 | * -------------------------------------------------------------------- */ | |
207 | ||
208 | #if defined(CONFIG_MMC_AT91) || defined(CONFIG_MMC_AT91_MODULE) | |
209 | static u64 mmc_dmamask = 0xffffffffUL; | |
210 | static struct at91_mmc_data mmc0_data, mmc1_data; | |
211 | ||
212 | static struct resource mmc0_resources[] = { | |
213 | [0] = { | |
214 | .start = AT91SAM9263_BASE_MCI0, | |
215 | .end = AT91SAM9263_BASE_MCI0 + SZ_16K - 1, | |
216 | .flags = IORESOURCE_MEM, | |
217 | }, | |
218 | [1] = { | |
219 | .start = AT91SAM9263_ID_MCI0, | |
220 | .end = AT91SAM9263_ID_MCI0, | |
221 | .flags = IORESOURCE_IRQ, | |
222 | }, | |
223 | }; | |
224 | ||
225 | static struct platform_device at91sam9263_mmc0_device = { | |
226 | .name = "at91_mci", | |
227 | .id = 0, | |
228 | .dev = { | |
229 | .dma_mask = &mmc_dmamask, | |
230 | .coherent_dma_mask = 0xffffffff, | |
231 | .platform_data = &mmc0_data, | |
232 | }, | |
233 | .resource = mmc0_resources, | |
234 | .num_resources = ARRAY_SIZE(mmc0_resources), | |
235 | }; | |
236 | ||
237 | static struct resource mmc1_resources[] = { | |
238 | [0] = { | |
239 | .start = AT91SAM9263_BASE_MCI1, | |
240 | .end = AT91SAM9263_BASE_MCI1 + SZ_16K - 1, | |
241 | .flags = IORESOURCE_MEM, | |
242 | }, | |
243 | [1] = { | |
244 | .start = AT91SAM9263_ID_MCI1, | |
245 | .end = AT91SAM9263_ID_MCI1, | |
246 | .flags = IORESOURCE_IRQ, | |
247 | }, | |
248 | }; | |
249 | ||
250 | static struct platform_device at91sam9263_mmc1_device = { | |
251 | .name = "at91_mci", | |
252 | .id = 1, | |
253 | .dev = { | |
254 | .dma_mask = &mmc_dmamask, | |
255 | .coherent_dma_mask = 0xffffffff, | |
256 | .platform_data = &mmc1_data, | |
257 | }, | |
258 | .resource = mmc1_resources, | |
259 | .num_resources = ARRAY_SIZE(mmc1_resources), | |
260 | }; | |
261 | ||
262 | void __init at91_add_device_mmc(short mmc_id, struct at91_mmc_data *data) | |
263 | { | |
264 | if (!data) | |
265 | return; | |
266 | ||
267 | /* input/irq */ | |
268 | if (data->det_pin) { | |
269 | at91_set_gpio_input(data->det_pin, 1); | |
270 | at91_set_deglitch(data->det_pin, 1); | |
271 | } | |
272 | if (data->wp_pin) | |
273 | at91_set_gpio_input(data->wp_pin, 1); | |
274 | if (data->vcc_pin) | |
275 | at91_set_gpio_output(data->vcc_pin, 0); | |
276 | ||
277 | if (mmc_id == 0) { /* MCI0 */ | |
278 | /* CLK */ | |
279 | at91_set_A_periph(AT91_PIN_PA12, 0); | |
280 | ||
281 | if (data->slot_b) { | |
282 | /* CMD */ | |
283 | at91_set_A_periph(AT91_PIN_PA16, 1); | |
284 | ||
285 | /* DAT0, maybe DAT1..DAT3 */ | |
286 | at91_set_A_periph(AT91_PIN_PA17, 1); | |
287 | if (data->wire4) { | |
288 | at91_set_A_periph(AT91_PIN_PA18, 1); | |
289 | at91_set_A_periph(AT91_PIN_PA19, 1); | |
290 | at91_set_A_periph(AT91_PIN_PA20, 1); | |
291 | } | |
292 | } else { | |
293 | /* CMD */ | |
294 | at91_set_A_periph(AT91_PIN_PA1, 1); | |
295 | ||
296 | /* DAT0, maybe DAT1..DAT3 */ | |
297 | at91_set_A_periph(AT91_PIN_PA0, 1); | |
298 | if (data->wire4) { | |
299 | at91_set_A_periph(AT91_PIN_PA3, 1); | |
300 | at91_set_A_periph(AT91_PIN_PA4, 1); | |
301 | at91_set_A_periph(AT91_PIN_PA5, 1); | |
302 | } | |
303 | } | |
304 | ||
305 | mmc0_data = *data; | |
306 | at91_clock_associate("mci0_clk", &at91sam9263_mmc1_device.dev, "mci_clk"); | |
307 | platform_device_register(&at91sam9263_mmc0_device); | |
308 | } else { /* MCI1 */ | |
309 | /* CLK */ | |
310 | at91_set_A_periph(AT91_PIN_PA6, 0); | |
311 | ||
312 | if (data->slot_b) { | |
313 | /* CMD */ | |
314 | at91_set_A_periph(AT91_PIN_PA21, 1); | |
315 | ||
316 | /* DAT0, maybe DAT1..DAT3 */ | |
317 | at91_set_A_periph(AT91_PIN_PA22, 1); | |
318 | if (data->wire4) { | |
319 | at91_set_A_periph(AT91_PIN_PA23, 1); | |
320 | at91_set_A_periph(AT91_PIN_PA24, 1); | |
321 | at91_set_A_periph(AT91_PIN_PA25, 1); | |
322 | } | |
323 | } else { | |
324 | /* CMD */ | |
325 | at91_set_A_periph(AT91_PIN_PA7, 1); | |
326 | ||
327 | /* DAT0, maybe DAT1..DAT3 */ | |
328 | at91_set_A_periph(AT91_PIN_PA8, 1); | |
329 | if (data->wire4) { | |
330 | at91_set_A_periph(AT91_PIN_PA9, 1); | |
331 | at91_set_A_periph(AT91_PIN_PA10, 1); | |
332 | at91_set_A_periph(AT91_PIN_PA11, 1); | |
333 | } | |
334 | } | |
335 | ||
336 | mmc1_data = *data; | |
337 | at91_clock_associate("mci1_clk", &at91sam9263_mmc1_device.dev, "mci_clk"); | |
338 | platform_device_register(&at91sam9263_mmc1_device); | |
339 | } | |
340 | } | |
341 | #else | |
342 | void __init at91_add_device_mmc(short mmc_id, struct at91_mmc_data *data) {} | |
343 | #endif | |
344 | ||
345 | ||
346 | /* -------------------------------------------------------------------- | |
347 | * NAND / SmartMedia | |
348 | * -------------------------------------------------------------------- */ | |
349 | ||
350 | #if defined(CONFIG_MTD_NAND_AT91) || defined(CONFIG_MTD_NAND_AT91_MODULE) | |
351 | static struct at91_nand_data nand_data; | |
352 | ||
353 | #define NAND_BASE AT91_CHIPSELECT_3 | |
354 | ||
355 | static struct resource nand_resources[] = { | |
356 | { | |
357 | .start = NAND_BASE, | |
358 | .end = NAND_BASE + SZ_256M - 1, | |
359 | .flags = IORESOURCE_MEM, | |
360 | } | |
361 | }; | |
362 | ||
363 | static struct platform_device at91sam9263_nand_device = { | |
364 | .name = "at91_nand", | |
365 | .id = -1, | |
366 | .dev = { | |
367 | .platform_data = &nand_data, | |
368 | }, | |
369 | .resource = nand_resources, | |
370 | .num_resources = ARRAY_SIZE(nand_resources), | |
371 | }; | |
372 | ||
373 | void __init at91_add_device_nand(struct at91_nand_data *data) | |
374 | { | |
375 | unsigned long csa, mode; | |
376 | ||
377 | if (!data) | |
378 | return; | |
379 | ||
380 | csa = at91_sys_read(AT91_MATRIX_EBI0CSA); | |
381 | at91_sys_write(AT91_MATRIX_EBI0CSA, csa | AT91_MATRIX_EBI0_CS3A_SMC); | |
382 | ||
383 | /* set the bus interface characteristics */ | |
384 | at91_sys_write(AT91_SMC_SETUP(3), AT91_SMC_NWESETUP_(0) | AT91_SMC_NCS_WRSETUP_(0) | |
385 | | AT91_SMC_NRDSETUP_(0) | AT91_SMC_NCS_RDSETUP_(0)); | |
386 | ||
387 | at91_sys_write(AT91_SMC_PULSE(3), AT91_SMC_NWEPULSE_(3) | AT91_SMC_NCS_WRPULSE_(3) | |
388 | | AT91_SMC_NRDPULSE_(3) | AT91_SMC_NCS_RDPULSE_(3)); | |
389 | ||
390 | at91_sys_write(AT91_SMC_CYCLE(3), AT91_SMC_NWECYCLE_(5) | AT91_SMC_NRDCYCLE_(5)); | |
391 | ||
392 | if (data->bus_width_16) | |
393 | mode = AT91_SMC_DBW_16; | |
394 | else | |
395 | mode = AT91_SMC_DBW_8; | |
396 | at91_sys_write(AT91_SMC_MODE(3), mode | AT91_SMC_READMODE | AT91_SMC_WRITEMODE | AT91_SMC_EXNWMODE_DISABLE | AT91_SMC_TDF_(2)); | |
397 | ||
398 | /* enable pin */ | |
399 | if (data->enable_pin) | |
400 | at91_set_gpio_output(data->enable_pin, 1); | |
401 | ||
402 | /* ready/busy pin */ | |
403 | if (data->rdy_pin) | |
404 | at91_set_gpio_input(data->rdy_pin, 1); | |
405 | ||
406 | /* card detect pin */ | |
407 | if (data->det_pin) | |
408 | at91_set_gpio_input(data->det_pin, 1); | |
409 | ||
410 | nand_data = *data; | |
411 | platform_device_register(&at91sam9263_nand_device); | |
412 | } | |
413 | #else | |
414 | void __init at91_add_device_nand(struct at91_nand_data *data) {} | |
415 | #endif | |
416 | ||
417 | ||
418 | /* -------------------------------------------------------------------- | |
419 | * TWI (i2c) | |
420 | * -------------------------------------------------------------------- */ | |
421 | ||
422 | #if defined(CONFIG_I2C_AT91) || defined(CONFIG_I2C_AT91_MODULE) | |
423 | ||
424 | static struct resource twi_resources[] = { | |
425 | [0] = { | |
426 | .start = AT91SAM9263_BASE_TWI, | |
427 | .end = AT91SAM9263_BASE_TWI + SZ_16K - 1, | |
428 | .flags = IORESOURCE_MEM, | |
429 | }, | |
430 | [1] = { | |
431 | .start = AT91SAM9263_ID_TWI, | |
432 | .end = AT91SAM9263_ID_TWI, | |
433 | .flags = IORESOURCE_IRQ, | |
434 | }, | |
435 | }; | |
436 | ||
437 | static struct platform_device at91sam9263_twi_device = { | |
438 | .name = "at91_i2c", | |
439 | .id = -1, | |
440 | .resource = twi_resources, | |
441 | .num_resources = ARRAY_SIZE(twi_resources), | |
442 | }; | |
443 | ||
444 | void __init at91_add_device_i2c(void) | |
445 | { | |
446 | /* pins used for TWI interface */ | |
447 | at91_set_A_periph(AT91_PIN_PB4, 0); /* TWD */ | |
448 | at91_set_multi_drive(AT91_PIN_PB4, 1); | |
449 | ||
450 | at91_set_A_periph(AT91_PIN_PB5, 0); /* TWCK */ | |
451 | at91_set_multi_drive(AT91_PIN_PB5, 1); | |
452 | ||
453 | platform_device_register(&at91sam9263_twi_device); | |
454 | } | |
455 | #else | |
456 | void __init at91_add_device_i2c(void) {} | |
457 | #endif | |
458 | ||
459 | ||
460 | /* -------------------------------------------------------------------- | |
461 | * SPI | |
462 | * -------------------------------------------------------------------- */ | |
463 | ||
464 | #if defined(CONFIG_SPI_ATMEL) || defined(CONFIG_SPI_ATMEL_MODULE) | |
465 | static u64 spi_dmamask = 0xffffffffUL; | |
466 | ||
467 | static struct resource spi0_resources[] = { | |
468 | [0] = { | |
469 | .start = AT91SAM9263_BASE_SPI0, | |
470 | .end = AT91SAM9263_BASE_SPI0 + SZ_16K - 1, | |
471 | .flags = IORESOURCE_MEM, | |
472 | }, | |
473 | [1] = { | |
474 | .start = AT91SAM9263_ID_SPI0, | |
475 | .end = AT91SAM9263_ID_SPI0, | |
476 | .flags = IORESOURCE_IRQ, | |
477 | }, | |
478 | }; | |
479 | ||
480 | static struct platform_device at91sam9263_spi0_device = { | |
481 | .name = "atmel_spi", | |
482 | .id = 0, | |
483 | .dev = { | |
484 | .dma_mask = &spi_dmamask, | |
485 | .coherent_dma_mask = 0xffffffff, | |
486 | }, | |
487 | .resource = spi0_resources, | |
488 | .num_resources = ARRAY_SIZE(spi0_resources), | |
489 | }; | |
490 | ||
491 | static const unsigned spi0_standard_cs[4] = { AT91_PIN_PA5, AT91_PIN_PA3, AT91_PIN_PA4, AT91_PIN_PB11 }; | |
492 | ||
493 | static struct resource spi1_resources[] = { | |
494 | [0] = { | |
495 | .start = AT91SAM9263_BASE_SPI1, | |
496 | .end = AT91SAM9263_BASE_SPI1 + SZ_16K - 1, | |
497 | .flags = IORESOURCE_MEM, | |
498 | }, | |
499 | [1] = { | |
500 | .start = AT91SAM9263_ID_SPI1, | |
501 | .end = AT91SAM9263_ID_SPI1, | |
502 | .flags = IORESOURCE_IRQ, | |
503 | }, | |
504 | }; | |
505 | ||
506 | static struct platform_device at91sam9263_spi1_device = { | |
507 | .name = "atmel_spi", | |
508 | .id = 1, | |
509 | .dev = { | |
510 | .dma_mask = &spi_dmamask, | |
511 | .coherent_dma_mask = 0xffffffff, | |
512 | }, | |
513 | .resource = spi1_resources, | |
514 | .num_resources = ARRAY_SIZE(spi1_resources), | |
515 | }; | |
516 | ||
517 | static const unsigned spi1_standard_cs[4] = { AT91_PIN_PB15, AT91_PIN_PB16, AT91_PIN_PB17, AT91_PIN_PB18 }; | |
518 | ||
519 | void __init at91_add_device_spi(struct spi_board_info *devices, int nr_devices) | |
520 | { | |
521 | int i; | |
522 | unsigned long cs_pin; | |
523 | short enable_spi0 = 0; | |
524 | short enable_spi1 = 0; | |
525 | ||
526 | /* Choose SPI chip-selects */ | |
527 | for (i = 0; i < nr_devices; i++) { | |
528 | if (devices[i].controller_data) | |
529 | cs_pin = (unsigned long) devices[i].controller_data; | |
530 | else if (devices[i].bus_num == 0) | |
531 | cs_pin = spi0_standard_cs[devices[i].chip_select]; | |
532 | else | |
533 | cs_pin = spi1_standard_cs[devices[i].chip_select]; | |
534 | ||
535 | if (devices[i].bus_num == 0) | |
536 | enable_spi0 = 1; | |
537 | else | |
538 | enable_spi1 = 1; | |
539 | ||
540 | /* enable chip-select pin */ | |
541 | at91_set_gpio_output(cs_pin, 1); | |
542 | ||
543 | /* pass chip-select pin to driver */ | |
544 | devices[i].controller_data = (void *) cs_pin; | |
545 | } | |
546 | ||
547 | spi_register_board_info(devices, nr_devices); | |
548 | ||
549 | /* Configure SPI bus(es) */ | |
550 | if (enable_spi0) { | |
551 | at91_set_B_periph(AT91_PIN_PA0, 0); /* SPI0_MISO */ | |
552 | at91_set_B_periph(AT91_PIN_PA1, 0); /* SPI0_MOSI */ | |
7f6e2d99 | 553 | at91_set_B_periph(AT91_PIN_PA2, 0); /* SPI0_SPCK */ |
b2c65616 AV |
554 | |
555 | at91_clock_associate("spi0_clk", &at91sam9263_spi0_device.dev, "spi_clk"); | |
556 | platform_device_register(&at91sam9263_spi0_device); | |
557 | } | |
558 | if (enable_spi1) { | |
559 | at91_set_A_periph(AT91_PIN_PB12, 0); /* SPI1_MISO */ | |
560 | at91_set_A_periph(AT91_PIN_PB13, 0); /* SPI1_MOSI */ | |
561 | at91_set_A_periph(AT91_PIN_PB14, 0); /* SPI1_SPCK */ | |
562 | ||
563 | at91_clock_associate("spi1_clk", &at91sam9263_spi1_device.dev, "spi_clk"); | |
564 | platform_device_register(&at91sam9263_spi1_device); | |
565 | } | |
566 | } | |
567 | #else | |
568 | void __init at91_add_device_spi(struct spi_board_info *devices, int nr_devices) {} | |
569 | #endif | |
570 | ||
571 | ||
7776a94c AV |
572 | /* -------------------------------------------------------------------- |
573 | * AC97 | |
574 | * -------------------------------------------------------------------- */ | |
575 | ||
576 | #if defined(CONFIG_SND_AT91_AC97) || defined(CONFIG_SND_AT91_AC97_MODULE) | |
577 | static u64 ac97_dmamask = 0xffffffffUL; | |
578 | static struct atmel_ac97_data ac97_data; | |
579 | ||
580 | static struct resource ac97_resources[] = { | |
581 | [0] = { | |
582 | .start = AT91SAM9263_BASE_AC97C, | |
583 | .end = AT91SAM9263_BASE_AC97C + SZ_16K - 1, | |
584 | .flags = IORESOURCE_MEM, | |
585 | }, | |
586 | [1] = { | |
587 | .start = AT91SAM9263_ID_AC97C, | |
588 | .end = AT91SAM9263_ID_AC97C, | |
589 | .flags = IORESOURCE_IRQ, | |
590 | }, | |
591 | }; | |
592 | ||
593 | static struct platform_device at91sam9263_ac97_device = { | |
594 | .name = "ac97c", | |
595 | .id = 1, | |
596 | .dev = { | |
597 | .dma_mask = &ac97_dmamask, | |
598 | .coherent_dma_mask = 0xffffffff, | |
599 | .platform_data = &ac97_data, | |
600 | }, | |
601 | .resource = ac97_resources, | |
602 | .num_resources = ARRAY_SIZE(ac97_resources), | |
603 | }; | |
604 | ||
605 | void __init at91_add_device_ac97(struct atmel_ac97_data *data) | |
606 | { | |
607 | if (!data) | |
608 | return; | |
609 | ||
610 | at91_set_A_periph(AT91_PIN_PB0, 0); /* AC97FS */ | |
611 | at91_set_A_periph(AT91_PIN_PB1, 0); /* AC97CK */ | |
612 | at91_set_A_periph(AT91_PIN_PB2, 0); /* AC97TX */ | |
613 | at91_set_A_periph(AT91_PIN_PB3, 0); /* AC97RX */ | |
614 | ||
615 | /* reset */ | |
616 | if (data->reset_pin) | |
617 | at91_set_gpio_output(data->reset_pin, 0); | |
618 | ||
619 | ac97_data = *ek_data; | |
620 | platform_device_register(&at91sam9263_ac97_device); | |
621 | } | |
622 | #else | |
623 | void __init at91_add_device_ac97(struct atmel_ac97_data *data) {} | |
624 | #endif | |
625 | ||
626 | ||
627 | /* -------------------------------------------------------------------- | |
628 | * LCD Controller | |
629 | * -------------------------------------------------------------------- */ | |
630 | ||
631 | #if defined(CONFIG_FB_ATMEL) || defined(CONFIG_FB_ATMEL_MODULE) | |
632 | static u64 lcdc_dmamask = 0xffffffffUL; | |
633 | static struct atmel_lcdfb_info lcdc_data; | |
634 | ||
635 | static struct resource lcdc_resources[] = { | |
636 | [0] = { | |
637 | .start = AT91SAM9263_LCDC_BASE, | |
638 | .end = AT91SAM9263_LCDC_BASE + SZ_4K - 1, | |
639 | .flags = IORESOURCE_MEM, | |
640 | }, | |
641 | [1] = { | |
642 | .start = AT91SAM9263_ID_LCDC, | |
643 | .end = AT91SAM9263_ID_LCDC, | |
644 | .flags = IORESOURCE_IRQ, | |
645 | }, | |
646 | }; | |
647 | ||
648 | static struct platform_device at91_lcdc_device = { | |
649 | .name = "atmel_lcdfb", | |
650 | .id = 0, | |
651 | .dev = { | |
652 | .dma_mask = &lcdc_dmamask, | |
653 | .coherent_dma_mask = 0xffffffff, | |
654 | .platform_data = &lcdc_data, | |
655 | }, | |
656 | .resource = lcdc_resources, | |
657 | .num_resources = ARRAY_SIZE(lcdc_resources), | |
658 | }; | |
659 | ||
660 | void __init at91_add_device_lcdc(struct atmel_lcdfb_info *data) | |
661 | { | |
662 | if (!data) | |
663 | return; | |
664 | ||
665 | at91_set_A_periph(AT91_PIN_PC1, 0); /* LCDHSYNC */ | |
666 | at91_set_A_periph(AT91_PIN_PC2, 0); /* LCDDOTCK */ | |
667 | at91_set_A_periph(AT91_PIN_PC3, 0); /* LCDDEN */ | |
668 | at91_set_B_periph(AT91_PIN_PB9, 0); /* LCDCC */ | |
669 | at91_set_A_periph(AT91_PIN_PC6, 0); /* LCDD2 */ | |
670 | at91_set_A_periph(AT91_PIN_PC7, 0); /* LCDD3 */ | |
671 | at91_set_A_periph(AT91_PIN_PC8, 0); /* LCDD4 */ | |
672 | at91_set_A_periph(AT91_PIN_PC9, 0); /* LCDD5 */ | |
673 | at91_set_A_periph(AT91_PIN_PC10, 0); /* LCDD6 */ | |
674 | at91_set_A_periph(AT91_PIN_PC11, 0); /* LCDD7 */ | |
675 | at91_set_A_periph(AT91_PIN_PC14, 0); /* LCDD10 */ | |
676 | at91_set_A_periph(AT91_PIN_PC15, 0); /* LCDD11 */ | |
677 | at91_set_A_periph(AT91_PIN_PC16, 0); /* LCDD12 */ | |
678 | at91_set_B_periph(AT91_PIN_PC12, 0); /* LCDD13 */ | |
679 | at91_set_A_periph(AT91_PIN_PC18, 0); /* LCDD14 */ | |
680 | at91_set_A_periph(AT91_PIN_PC19, 0); /* LCDD15 */ | |
681 | at91_set_A_periph(AT91_PIN_PC22, 0); /* LCDD18 */ | |
682 | at91_set_A_periph(AT91_PIN_PC23, 0); /* LCDD19 */ | |
683 | at91_set_A_periph(AT91_PIN_PC24, 0); /* LCDD20 */ | |
684 | at91_set_B_periph(AT91_PIN_PC17, 0); /* LCDD21 */ | |
685 | at91_set_A_periph(AT91_PIN_PC26, 0); /* LCDD22 */ | |
686 | at91_set_A_periph(AT91_PIN_PC27, 0); /* LCDD23 */ | |
687 | ||
688 | lcdc_data = *data; | |
689 | platform_device_register(&at91_lcdc_device); | |
690 | } | |
691 | #else | |
692 | void __init at91_add_device_lcdc(struct atmel_lcdfb_info *data) {} | |
693 | #endif | |
694 | ||
695 | ||
b2c65616 AV |
696 | /* -------------------------------------------------------------------- |
697 | * LEDs | |
698 | * -------------------------------------------------------------------- */ | |
699 | ||
700 | #if defined(CONFIG_LEDS) | |
701 | u8 at91_leds_cpu; | |
702 | u8 at91_leds_timer; | |
703 | ||
704 | void __init at91_init_leds(u8 cpu_led, u8 timer_led) | |
705 | { | |
706 | /* Enable GPIO to access the LEDs */ | |
707 | at91_set_gpio_output(cpu_led, 1); | |
708 | at91_set_gpio_output(timer_led, 1); | |
709 | ||
710 | at91_leds_cpu = cpu_led; | |
711 | at91_leds_timer = timer_led; | |
712 | } | |
713 | #else | |
714 | void __init at91_init_leds(u8 cpu_led, u8 timer_led) {} | |
715 | #endif | |
716 | ||
717 | ||
718 | /* -------------------------------------------------------------------- | |
719 | * UART | |
720 | * -------------------------------------------------------------------- */ | |
721 | ||
722 | #if defined(CONFIG_SERIAL_ATMEL) | |
723 | ||
724 | static struct resource dbgu_resources[] = { | |
725 | [0] = { | |
726 | .start = AT91_VA_BASE_SYS + AT91_DBGU, | |
727 | .end = AT91_VA_BASE_SYS + AT91_DBGU + SZ_512 - 1, | |
728 | .flags = IORESOURCE_MEM, | |
729 | }, | |
730 | [1] = { | |
731 | .start = AT91_ID_SYS, | |
732 | .end = AT91_ID_SYS, | |
733 | .flags = IORESOURCE_IRQ, | |
734 | }, | |
735 | }; | |
736 | ||
737 | static struct atmel_uart_data dbgu_data = { | |
738 | .use_dma_tx = 0, | |
739 | .use_dma_rx = 0, /* DBGU not capable of receive DMA */ | |
740 | .regs = (void __iomem *)(AT91_VA_BASE_SYS + AT91_DBGU), | |
741 | }; | |
742 | ||
743 | static struct platform_device at91sam9263_dbgu_device = { | |
744 | .name = "atmel_usart", | |
745 | .id = 0, | |
746 | .dev = { | |
747 | .platform_data = &dbgu_data, | |
748 | .coherent_dma_mask = 0xffffffff, | |
749 | }, | |
750 | .resource = dbgu_resources, | |
751 | .num_resources = ARRAY_SIZE(dbgu_resources), | |
752 | }; | |
753 | ||
754 | static inline void configure_dbgu_pins(void) | |
755 | { | |
756 | at91_set_A_periph(AT91_PIN_PC30, 0); /* DRXD */ | |
757 | at91_set_A_periph(AT91_PIN_PC31, 1); /* DTXD */ | |
758 | } | |
759 | ||
760 | static struct resource uart0_resources[] = { | |
761 | [0] = { | |
762 | .start = AT91SAM9263_BASE_US0, | |
763 | .end = AT91SAM9263_BASE_US0 + SZ_16K - 1, | |
764 | .flags = IORESOURCE_MEM, | |
765 | }, | |
766 | [1] = { | |
767 | .start = AT91SAM9263_ID_US0, | |
768 | .end = AT91SAM9263_ID_US0, | |
769 | .flags = IORESOURCE_IRQ, | |
770 | }, | |
771 | }; | |
772 | ||
773 | static struct atmel_uart_data uart0_data = { | |
774 | .use_dma_tx = 1, | |
775 | .use_dma_rx = 1, | |
776 | }; | |
777 | ||
778 | static struct platform_device at91sam9263_uart0_device = { | |
779 | .name = "atmel_usart", | |
780 | .id = 1, | |
781 | .dev = { | |
782 | .platform_data = &uart0_data, | |
783 | .coherent_dma_mask = 0xffffffff, | |
784 | }, | |
785 | .resource = uart0_resources, | |
786 | .num_resources = ARRAY_SIZE(uart0_resources), | |
787 | }; | |
788 | ||
789 | static inline void configure_usart0_pins(void) | |
790 | { | |
791 | at91_set_A_periph(AT91_PIN_PA26, 1); /* TXD0 */ | |
792 | at91_set_A_periph(AT91_PIN_PA27, 0); /* RXD0 */ | |
793 | at91_set_A_periph(AT91_PIN_PA28, 0); /* RTS0 */ | |
794 | at91_set_A_periph(AT91_PIN_PA29, 0); /* CTS0 */ | |
795 | } | |
796 | ||
797 | static struct resource uart1_resources[] = { | |
798 | [0] = { | |
799 | .start = AT91SAM9263_BASE_US1, | |
800 | .end = AT91SAM9263_BASE_US1 + SZ_16K - 1, | |
801 | .flags = IORESOURCE_MEM, | |
802 | }, | |
803 | [1] = { | |
804 | .start = AT91SAM9263_ID_US1, | |
805 | .end = AT91SAM9263_ID_US1, | |
806 | .flags = IORESOURCE_IRQ, | |
807 | }, | |
808 | }; | |
809 | ||
810 | static struct atmel_uart_data uart1_data = { | |
811 | .use_dma_tx = 1, | |
812 | .use_dma_rx = 1, | |
813 | }; | |
814 | ||
815 | static struct platform_device at91sam9263_uart1_device = { | |
816 | .name = "atmel_usart", | |
817 | .id = 2, | |
818 | .dev = { | |
819 | .platform_data = &uart1_data, | |
820 | .coherent_dma_mask = 0xffffffff, | |
821 | }, | |
822 | .resource = uart1_resources, | |
823 | .num_resources = ARRAY_SIZE(uart1_resources), | |
824 | }; | |
825 | ||
826 | static inline void configure_usart1_pins(void) | |
827 | { | |
828 | at91_set_A_periph(AT91_PIN_PD0, 1); /* TXD1 */ | |
829 | at91_set_A_periph(AT91_PIN_PD1, 0); /* RXD1 */ | |
830 | at91_set_B_periph(AT91_PIN_PD7, 0); /* RTS1 */ | |
831 | at91_set_B_periph(AT91_PIN_PD8, 0); /* CTS1 */ | |
832 | } | |
833 | ||
834 | static struct resource uart2_resources[] = { | |
835 | [0] = { | |
836 | .start = AT91SAM9263_BASE_US2, | |
837 | .end = AT91SAM9263_BASE_US2 + SZ_16K - 1, | |
838 | .flags = IORESOURCE_MEM, | |
839 | }, | |
840 | [1] = { | |
841 | .start = AT91SAM9263_ID_US2, | |
842 | .end = AT91SAM9263_ID_US2, | |
843 | .flags = IORESOURCE_IRQ, | |
844 | }, | |
845 | }; | |
846 | ||
847 | static struct atmel_uart_data uart2_data = { | |
848 | .use_dma_tx = 1, | |
849 | .use_dma_rx = 1, | |
850 | }; | |
851 | ||
852 | static struct platform_device at91sam9263_uart2_device = { | |
853 | .name = "atmel_usart", | |
854 | .id = 3, | |
855 | .dev = { | |
856 | .platform_data = &uart2_data, | |
857 | .coherent_dma_mask = 0xffffffff, | |
858 | }, | |
859 | .resource = uart2_resources, | |
860 | .num_resources = ARRAY_SIZE(uart2_resources), | |
861 | }; | |
862 | ||
863 | static inline void configure_usart2_pins(void) | |
864 | { | |
865 | at91_set_A_periph(AT91_PIN_PD2, 1); /* TXD2 */ | |
866 | at91_set_A_periph(AT91_PIN_PD3, 0); /* RXD2 */ | |
867 | at91_set_B_periph(AT91_PIN_PD5, 0); /* RTS2 */ | |
868 | at91_set_B_periph(AT91_PIN_PD6, 0); /* CTS2 */ | |
869 | } | |
870 | ||
871 | struct platform_device *at91_uarts[ATMEL_MAX_UART]; /* the UARTs to use */ | |
872 | struct platform_device *atmel_default_console_device; /* the serial console device */ | |
873 | ||
874 | void __init at91_init_serial(struct at91_uart_config *config) | |
875 | { | |
876 | int i; | |
877 | ||
878 | /* Fill in list of supported UARTs */ | |
879 | for (i = 0; i < config->nr_tty; i++) { | |
880 | switch (config->tty_map[i]) { | |
881 | case 0: | |
882 | configure_usart0_pins(); | |
883 | at91_uarts[i] = &at91sam9263_uart0_device; | |
884 | at91_clock_associate("usart0_clk", &at91sam9263_uart0_device.dev, "usart"); | |
885 | break; | |
886 | case 1: | |
887 | configure_usart1_pins(); | |
888 | at91_uarts[i] = &at91sam9263_uart1_device; | |
889 | at91_clock_associate("usart1_clk", &at91sam9263_uart1_device.dev, "usart"); | |
890 | break; | |
891 | case 2: | |
892 | configure_usart2_pins(); | |
893 | at91_uarts[i] = &at91sam9263_uart2_device; | |
894 | at91_clock_associate("usart2_clk", &at91sam9263_uart2_device.dev, "usart"); | |
895 | break; | |
896 | case 3: | |
897 | configure_dbgu_pins(); | |
898 | at91_uarts[i] = &at91sam9263_dbgu_device; | |
899 | at91_clock_associate("mck", &at91sam9263_dbgu_device.dev, "usart"); | |
900 | break; | |
901 | default: | |
902 | continue; | |
903 | } | |
904 | at91_uarts[i]->id = i; /* update ID number to mapped ID */ | |
905 | } | |
906 | ||
907 | /* Set serial console device */ | |
908 | if (config->console_tty < ATMEL_MAX_UART) | |
909 | atmel_default_console_device = at91_uarts[config->console_tty]; | |
910 | if (!atmel_default_console_device) | |
911 | printk(KERN_INFO "AT91: No default serial console defined.\n"); | |
912 | } | |
913 | ||
914 | void __init at91_add_device_serial(void) | |
915 | { | |
916 | int i; | |
917 | ||
918 | for (i = 0; i < ATMEL_MAX_UART; i++) { | |
919 | if (at91_uarts[i]) | |
920 | platform_device_register(at91_uarts[i]); | |
921 | } | |
922 | } | |
923 | #else | |
924 | void __init at91_init_serial(struct at91_uart_config *config) {} | |
925 | void __init at91_add_device_serial(void) {} | |
926 | #endif | |
927 | ||
928 | ||
929 | /* -------------------------------------------------------------------- */ | |
930 | /* | |
931 | * These devices are always present and don't need any board-specific | |
932 | * setup. | |
933 | */ | |
934 | static int __init at91_add_standard_devices(void) | |
935 | { | |
936 | return 0; | |
937 | } | |
938 | ||
939 | arch_initcall(at91_add_standard_devices); |