Commit | Line | Data |
---|---|---|
73a59c1c | 1 | /* |
9d041268 | 2 | * arch/arm/mach-at91/at91rm9200_devices.c |
73a59c1c SP |
3 | * |
4 | * Copyright (C) 2005 Thibaut VARENE <varenet@parisc-linux.org> | |
5 | * Copyright (C) 2005 David Brownell | |
6 | * | |
7 | * This program is free software; you can redistribute it and/or modify | |
8 | * it under the terms of the GNU General Public License as published by | |
9 | * the Free Software Foundation; either version 2 of the License, or | |
10 | * (at your option) any later version. | |
11 | * | |
12 | */ | |
13 | #include <asm/mach/arch.h> | |
14 | #include <asm/mach/map.h> | |
15 | ||
73a59c1c SP |
16 | #include <linux/platform_device.h> |
17 | ||
18 | #include <asm/arch/board.h> | |
2e836402 | 19 | #include <asm/arch/gpio.h> |
69c5eccd AV |
20 | #include <asm/arch/at91rm9200.h> |
21 | #include <asm/arch/at91rm9200_mc.h> | |
73a59c1c | 22 | |
2e836402 AV |
23 | #include "generic.h" |
24 | ||
73a59c1c SP |
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 | ||
69c5eccd | 34 | static struct resource usbh_resources[] = { |
73a59c1c | 35 | [0] = { |
72729910 AV |
36 | .start = AT91RM9200_UHP_BASE, |
37 | .end = AT91RM9200_UHP_BASE + SZ_1M - 1, | |
73a59c1c SP |
38 | .flags = IORESOURCE_MEM, |
39 | }, | |
40 | [1] = { | |
72729910 AV |
41 | .start = AT91RM9200_ID_UHP, |
42 | .end = AT91RM9200_ID_UHP, | |
73a59c1c SP |
43 | .flags = IORESOURCE_IRQ, |
44 | }, | |
45 | }; | |
46 | ||
47 | static struct platform_device at91rm9200_usbh_device = { | |
2e836402 | 48 | .name = "at91_ohci", |
73a59c1c SP |
49 | .id = -1, |
50 | .dev = { | |
51 | .dma_mask = &ohci_dmamask, | |
52 | .coherent_dma_mask = 0xffffffff, | |
53 | .platform_data = &usbh_data, | |
54 | }, | |
69c5eccd AV |
55 | .resource = usbh_resources, |
56 | .num_resources = ARRAY_SIZE(usbh_resources), | |
73a59c1c SP |
57 | }; |
58 | ||
59 | void __init at91_add_device_usbh(struct at91_usbh_data *data) | |
60 | { | |
61 | if (!data) | |
62 | return; | |
63 | ||
64 | usbh_data = *data; | |
65 | platform_device_register(&at91rm9200_usbh_device); | |
66 | } | |
67 | #else | |
68 | void __init at91_add_device_usbh(struct at91_usbh_data *data) {} | |
69 | #endif | |
70 | ||
71 | ||
72 | /* -------------------------------------------------------------------- | |
73 | * USB Device (Gadget) | |
74 | * -------------------------------------------------------------------- */ | |
75 | ||
76 | #ifdef CONFIG_USB_GADGET_AT91 | |
77 | static struct at91_udc_data udc_data; | |
78 | ||
69c5eccd | 79 | static struct resource udc_resources[] = { |
2e836402 | 80 | [0] = { |
72729910 AV |
81 | .start = AT91RM9200_BASE_UDP, |
82 | .end = AT91RM9200_BASE_UDP + SZ_16K - 1, | |
73a59c1c | 83 | .flags = IORESOURCE_MEM, |
2e836402 AV |
84 | }, |
85 | [1] = { | |
72729910 AV |
86 | .start = AT91RM9200_ID_UDP, |
87 | .end = AT91RM9200_ID_UDP, | |
2e836402 AV |
88 | .flags = IORESOURCE_IRQ, |
89 | }, | |
73a59c1c SP |
90 | }; |
91 | ||
92 | static struct platform_device at91rm9200_udc_device = { | |
93 | .name = "at91_udc", | |
94 | .id = -1, | |
95 | .dev = { | |
96 | .platform_data = &udc_data, | |
97 | }, | |
69c5eccd AV |
98 | .resource = udc_resources, |
99 | .num_resources = ARRAY_SIZE(udc_resources), | |
73a59c1c SP |
100 | }; |
101 | ||
102 | void __init at91_add_device_udc(struct at91_udc_data *data) | |
103 | { | |
104 | if (!data) | |
105 | return; | |
106 | ||
107 | if (data->vbus_pin) { | |
108 | at91_set_gpio_input(data->vbus_pin, 0); | |
109 | at91_set_deglitch(data->vbus_pin, 1); | |
110 | } | |
2e836402 | 111 | if (data->pullup_pin) |
73a59c1c SP |
112 | at91_set_gpio_output(data->pullup_pin, 0); |
113 | ||
114 | udc_data = *data; | |
115 | platform_device_register(&at91rm9200_udc_device); | |
116 | } | |
117 | #else | |
118 | void __init at91_add_device_udc(struct at91_udc_data *data) {} | |
119 | #endif | |
120 | ||
121 | ||
122 | /* -------------------------------------------------------------------- | |
123 | * Ethernet | |
124 | * -------------------------------------------------------------------- */ | |
125 | ||
126 | #if defined(CONFIG_ARM_AT91_ETHER) || defined(CONFIG_ARM_AT91_ETHER_MODULE) | |
127 | static u64 eth_dmamask = 0xffffffffUL; | |
128 | static struct at91_eth_data eth_data; | |
129 | ||
69c5eccd | 130 | static struct resource eth_resources[] = { |
3267c077 | 131 | [0] = { |
1f51c10c AV |
132 | .start = AT91_VA_BASE_EMAC, |
133 | .end = AT91_VA_BASE_EMAC + SZ_16K - 1, | |
3267c077 AV |
134 | .flags = IORESOURCE_MEM, |
135 | }, | |
136 | [1] = { | |
72729910 AV |
137 | .start = AT91RM9200_ID_EMAC, |
138 | .end = AT91RM9200_ID_EMAC, | |
3267c077 AV |
139 | .flags = IORESOURCE_IRQ, |
140 | }, | |
141 | }; | |
142 | ||
73a59c1c SP |
143 | static struct platform_device at91rm9200_eth_device = { |
144 | .name = "at91_ether", | |
145 | .id = -1, | |
146 | .dev = { | |
147 | .dma_mask = ð_dmamask, | |
148 | .coherent_dma_mask = 0xffffffff, | |
149 | .platform_data = ð_data, | |
150 | }, | |
69c5eccd AV |
151 | .resource = eth_resources, |
152 | .num_resources = ARRAY_SIZE(eth_resources), | |
73a59c1c SP |
153 | }; |
154 | ||
155 | void __init at91_add_device_eth(struct at91_eth_data *data) | |
156 | { | |
157 | if (!data) | |
158 | return; | |
159 | ||
160 | if (data->phy_irq_pin) { | |
161 | at91_set_gpio_input(data->phy_irq_pin, 0); | |
162 | at91_set_deglitch(data->phy_irq_pin, 1); | |
163 | } | |
164 | ||
165 | /* Pins used for MII and RMII */ | |
166 | at91_set_A_periph(AT91_PIN_PA16, 0); /* EMDIO */ | |
167 | at91_set_A_periph(AT91_PIN_PA15, 0); /* EMDC */ | |
168 | at91_set_A_periph(AT91_PIN_PA14, 0); /* ERXER */ | |
169 | at91_set_A_periph(AT91_PIN_PA13, 0); /* ERX1 */ | |
170 | at91_set_A_periph(AT91_PIN_PA12, 0); /* ERX0 */ | |
171 | at91_set_A_periph(AT91_PIN_PA11, 0); /* ECRS_ECRSDV */ | |
172 | at91_set_A_periph(AT91_PIN_PA10, 0); /* ETX1 */ | |
173 | at91_set_A_periph(AT91_PIN_PA9, 0); /* ETX0 */ | |
174 | at91_set_A_periph(AT91_PIN_PA8, 0); /* ETXEN */ | |
175 | at91_set_A_periph(AT91_PIN_PA7, 0); /* ETXCK_EREFCK */ | |
176 | ||
177 | if (!data->is_rmii) { | |
178 | at91_set_B_periph(AT91_PIN_PB19, 0); /* ERXCK */ | |
179 | at91_set_B_periph(AT91_PIN_PB18, 0); /* ECOL */ | |
180 | at91_set_B_periph(AT91_PIN_PB17, 0); /* ERXDV */ | |
181 | at91_set_B_periph(AT91_PIN_PB16, 0); /* ERX3 */ | |
182 | at91_set_B_periph(AT91_PIN_PB15, 0); /* ERX2 */ | |
183 | at91_set_B_periph(AT91_PIN_PB14, 0); /* ETXER */ | |
184 | at91_set_B_periph(AT91_PIN_PB13, 0); /* ETX3 */ | |
185 | at91_set_B_periph(AT91_PIN_PB12, 0); /* ETX2 */ | |
186 | } | |
187 | ||
188 | eth_data = *data; | |
189 | platform_device_register(&at91rm9200_eth_device); | |
190 | } | |
191 | #else | |
192 | void __init at91_add_device_eth(struct at91_eth_data *data) {} | |
193 | #endif | |
194 | ||
195 | ||
196 | /* -------------------------------------------------------------------- | |
197 | * Compact Flash / PCMCIA | |
198 | * -------------------------------------------------------------------- */ | |
199 | ||
200 | #if defined(CONFIG_AT91_CF) || defined(CONFIG_AT91_CF_MODULE) | |
201 | static struct at91_cf_data cf_data; | |
202 | ||
69c5eccd AV |
203 | #define CF_BASE AT91_CHIPSELECT_4 |
204 | ||
205 | static struct resource cf_resources[] = { | |
2c536200 | 206 | [0] = { |
69c5eccd | 207 | .start = CF_BASE, |
2e836402 | 208 | /* ties up CS4, CS5 and CS6 */ |
69c5eccd | 209 | .end = CF_BASE + (0x30000000 - 1), |
2c536200 DB |
210 | .flags = IORESOURCE_MEM | IORESOURCE_MEM_8AND16BIT, |
211 | }, | |
212 | }; | |
213 | ||
73a59c1c SP |
214 | static struct platform_device at91rm9200_cf_device = { |
215 | .name = "at91_cf", | |
216 | .id = -1, | |
217 | .dev = { | |
218 | .platform_data = &cf_data, | |
219 | }, | |
69c5eccd AV |
220 | .resource = cf_resources, |
221 | .num_resources = ARRAY_SIZE(cf_resources), | |
73a59c1c SP |
222 | }; |
223 | ||
224 | void __init at91_add_device_cf(struct at91_cf_data *data) | |
225 | { | |
69c5eccd AV |
226 | unsigned int csa; |
227 | ||
73a59c1c SP |
228 | if (!data) |
229 | return; | |
230 | ||
69c5eccd AV |
231 | data->chipselect = 4; /* can only use EBI ChipSelect 4 */ |
232 | ||
233 | /* CF takes over CS4, CS5, CS6 */ | |
234 | csa = at91_sys_read(AT91_EBI_CSA); | |
235 | at91_sys_write(AT91_EBI_CSA, csa | AT91_EBI_CS4A_SMC_COMPACTFLASH); | |
236 | ||
237 | /* | |
238 | * Static memory controller timing adjustments. | |
239 | * REVISIT: these timings are in terms of MCK cycles, so | |
240 | * when MCK changes (cpufreq etc) so must these values... | |
241 | */ | |
242 | at91_sys_write(AT91_SMC_CSR(4), | |
243 | AT91_SMC_ACSS_STD | |
244 | | AT91_SMC_DBW_16 | |
245 | | AT91_SMC_BAT | |
246 | | AT91_SMC_WSEN | |
247 | | AT91_SMC_NWS_(32) /* wait states */ | |
248 | | AT91_SMC_RWSETUP_(6) /* setup time */ | |
249 | | AT91_SMC_RWHOLD_(4) /* hold time */ | |
250 | ); | |
251 | ||
73a59c1c SP |
252 | /* input/irq */ |
253 | if (data->irq_pin) { | |
254 | at91_set_gpio_input(data->irq_pin, 1); | |
255 | at91_set_deglitch(data->irq_pin, 1); | |
256 | } | |
257 | at91_set_gpio_input(data->det_pin, 1); | |
258 | at91_set_deglitch(data->det_pin, 1); | |
259 | ||
260 | /* outputs, initially off */ | |
261 | if (data->vcc_pin) | |
262 | at91_set_gpio_output(data->vcc_pin, 0); | |
263 | at91_set_gpio_output(data->rst_pin, 0); | |
264 | ||
2e836402 AV |
265 | /* force poweron defaults for these pins ... */ |
266 | at91_set_A_periph(AT91_PIN_PC9, 0); /* A25/CFRNW */ | |
267 | at91_set_A_periph(AT91_PIN_PC10, 0); /* NCS4/CFCS */ | |
268 | at91_set_A_periph(AT91_PIN_PC11, 0); /* NCS5/CFCE1 */ | |
269 | at91_set_A_periph(AT91_PIN_PC12, 0); /* NCS6/CFCE2 */ | |
270 | ||
69c5eccd | 271 | /* nWAIT is _not_ a default setting */ |
a14d5273 | 272 | at91_set_A_periph(AT91_PIN_PC6, 1); /* nWAIT */ |
69c5eccd | 273 | |
73a59c1c SP |
274 | cf_data = *data; |
275 | platform_device_register(&at91rm9200_cf_device); | |
276 | } | |
277 | #else | |
278 | void __init at91_add_device_cf(struct at91_cf_data *data) {} | |
279 | #endif | |
280 | ||
281 | ||
282 | /* -------------------------------------------------------------------- | |
283 | * MMC / SD | |
284 | * -------------------------------------------------------------------- */ | |
285 | ||
69c5eccd | 286 | #if defined(CONFIG_MMC_AT91) || defined(CONFIG_MMC_AT91_MODULE) |
73a59c1c SP |
287 | static u64 mmc_dmamask = 0xffffffffUL; |
288 | static struct at91_mmc_data mmc_data; | |
289 | ||
69c5eccd | 290 | static struct resource mmc_resources[] = { |
3267c077 | 291 | [0] = { |
72729910 AV |
292 | .start = AT91RM9200_BASE_MCI, |
293 | .end = AT91RM9200_BASE_MCI + SZ_16K - 1, | |
73a59c1c | 294 | .flags = IORESOURCE_MEM, |
3267c077 AV |
295 | }, |
296 | [1] = { | |
72729910 AV |
297 | .start = AT91RM9200_ID_MCI, |
298 | .end = AT91RM9200_ID_MCI, | |
3267c077 AV |
299 | .flags = IORESOURCE_IRQ, |
300 | }, | |
73a59c1c SP |
301 | }; |
302 | ||
303 | static struct platform_device at91rm9200_mmc_device = { | |
3267c077 | 304 | .name = "at91_mci", |
73a59c1c SP |
305 | .id = -1, |
306 | .dev = { | |
307 | .dma_mask = &mmc_dmamask, | |
308 | .coherent_dma_mask = 0xffffffff, | |
309 | .platform_data = &mmc_data, | |
310 | }, | |
69c5eccd AV |
311 | .resource = mmc_resources, |
312 | .num_resources = ARRAY_SIZE(mmc_resources), | |
73a59c1c SP |
313 | }; |
314 | ||
d0760b3b | 315 | void __init at91_add_device_mmc(short mmc_id, struct at91_mmc_data *data) |
73a59c1c SP |
316 | { |
317 | if (!data) | |
318 | return; | |
319 | ||
320 | /* input/irq */ | |
321 | if (data->det_pin) { | |
322 | at91_set_gpio_input(data->det_pin, 1); | |
323 | at91_set_deglitch(data->det_pin, 1); | |
324 | } | |
325 | if (data->wp_pin) | |
326 | at91_set_gpio_input(data->wp_pin, 1); | |
69c5eccd AV |
327 | if (data->vcc_pin) |
328 | at91_set_gpio_output(data->vcc_pin, 0); | |
73a59c1c SP |
329 | |
330 | /* CLK */ | |
331 | at91_set_A_periph(AT91_PIN_PA27, 0); | |
332 | ||
69c5eccd | 333 | if (data->slot_b) { |
73a59c1c | 334 | /* CMD */ |
69c5eccd | 335 | at91_set_B_periph(AT91_PIN_PA8, 1); |
73a59c1c SP |
336 | |
337 | /* DAT0, maybe DAT1..DAT3 */ | |
69c5eccd | 338 | at91_set_B_periph(AT91_PIN_PA9, 1); |
73a59c1c | 339 | if (data->wire4) { |
69c5eccd AV |
340 | at91_set_B_periph(AT91_PIN_PA10, 1); |
341 | at91_set_B_periph(AT91_PIN_PA11, 1); | |
342 | at91_set_B_periph(AT91_PIN_PA12, 1); | |
73a59c1c SP |
343 | } |
344 | } else { | |
345 | /* CMD */ | |
69c5eccd | 346 | at91_set_A_periph(AT91_PIN_PA28, 1); |
73a59c1c SP |
347 | |
348 | /* DAT0, maybe DAT1..DAT3 */ | |
69c5eccd | 349 | at91_set_A_periph(AT91_PIN_PA29, 1); |
73a59c1c | 350 | if (data->wire4) { |
69c5eccd AV |
351 | at91_set_B_periph(AT91_PIN_PB3, 1); |
352 | at91_set_B_periph(AT91_PIN_PB4, 1); | |
353 | at91_set_B_periph(AT91_PIN_PB5, 1); | |
73a59c1c SP |
354 | } |
355 | } | |
356 | ||
357 | mmc_data = *data; | |
358 | platform_device_register(&at91rm9200_mmc_device); | |
359 | } | |
360 | #else | |
d0760b3b | 361 | void __init at91_add_device_mmc(short mmc_id, struct at91_mmc_data *data) {} |
73a59c1c SP |
362 | #endif |
363 | ||
2e836402 | 364 | |
3267c077 AV |
365 | /* -------------------------------------------------------------------- |
366 | * NAND / SmartMedia | |
367 | * -------------------------------------------------------------------- */ | |
368 | ||
369 | #if defined(CONFIG_MTD_NAND_AT91) || defined(CONFIG_MTD_NAND_AT91_MODULE) | |
370 | static struct at91_nand_data nand_data; | |
371 | ||
69c5eccd AV |
372 | #define NAND_BASE AT91_CHIPSELECT_3 |
373 | ||
374 | static struct resource nand_resources[] = { | |
3267c077 | 375 | { |
69c5eccd AV |
376 | .start = NAND_BASE, |
377 | .end = NAND_BASE + SZ_8M - 1, | |
3267c077 AV |
378 | .flags = IORESOURCE_MEM, |
379 | } | |
380 | }; | |
381 | ||
69c5eccd | 382 | static struct platform_device at91rm9200_nand_device = { |
3267c077 AV |
383 | .name = "at91_nand", |
384 | .id = -1, | |
385 | .dev = { | |
386 | .platform_data = &nand_data, | |
387 | }, | |
69c5eccd AV |
388 | .resource = nand_resources, |
389 | .num_resources = ARRAY_SIZE(nand_resources), | |
3267c077 AV |
390 | }; |
391 | ||
392 | void __init at91_add_device_nand(struct at91_nand_data *data) | |
393 | { | |
69c5eccd AV |
394 | unsigned int csa; |
395 | ||
3267c077 AV |
396 | if (!data) |
397 | return; | |
398 | ||
69c5eccd AV |
399 | /* enable the address range of CS3 */ |
400 | csa = at91_sys_read(AT91_EBI_CSA); | |
401 | at91_sys_write(AT91_EBI_CSA, csa | AT91_EBI_CS3A_SMC_SMARTMEDIA); | |
402 | ||
403 | /* set the bus interface characteristics */ | |
404 | at91_sys_write(AT91_SMC_CSR(3), AT91_SMC_ACSS_STD | AT91_SMC_DBW_8 | AT91_SMC_WSEN | |
405 | | AT91_SMC_NWS_(5) | |
406 | | AT91_SMC_TDF_(1) | |
407 | | AT91_SMC_RWSETUP_(0) /* tDS Data Set up Time 30 - ns */ | |
408 | | AT91_SMC_RWHOLD_(1) /* tDH Data Hold Time 20 - ns */ | |
409 | ); | |
410 | ||
3267c077 AV |
411 | /* enable pin */ |
412 | if (data->enable_pin) | |
413 | at91_set_gpio_output(data->enable_pin, 1); | |
414 | ||
415 | /* ready/busy pin */ | |
416 | if (data->rdy_pin) | |
417 | at91_set_gpio_input(data->rdy_pin, 1); | |
418 | ||
419 | /* card detect pin */ | |
420 | if (data->det_pin) | |
421 | at91_set_gpio_input(data->det_pin, 1); | |
422 | ||
423 | at91_set_A_periph(AT91_PIN_PC1, 0); /* SMOE */ | |
424 | at91_set_A_periph(AT91_PIN_PC3, 0); /* SMWE */ | |
425 | ||
426 | nand_data = *data; | |
69c5eccd | 427 | platform_device_register(&at91rm9200_nand_device); |
3267c077 AV |
428 | } |
429 | #else | |
430 | void __init at91_add_device_nand(struct at91_nand_data *data) {} | |
431 | #endif | |
432 | ||
433 | ||
434 | /* -------------------------------------------------------------------- | |
435 | * TWI (i2c) | |
436 | * -------------------------------------------------------------------- */ | |
437 | ||
438 | #if defined(CONFIG_I2C_AT91) || defined(CONFIG_I2C_AT91_MODULE) | |
69c5eccd AV |
439 | |
440 | static struct resource twi_resources[] = { | |
441 | [0] = { | |
442 | .start = AT91RM9200_BASE_TWI, | |
443 | .end = AT91RM9200_BASE_TWI + SZ_16K - 1, | |
444 | .flags = IORESOURCE_MEM, | |
445 | }, | |
446 | [1] = { | |
447 | .start = AT91RM9200_ID_TWI, | |
448 | .end = AT91RM9200_ID_TWI, | |
449 | .flags = IORESOURCE_IRQ, | |
450 | }, | |
451 | }; | |
452 | ||
3267c077 AV |
453 | static struct platform_device at91rm9200_twi_device = { |
454 | .name = "at91_i2c", | |
455 | .id = -1, | |
69c5eccd AV |
456 | .resource = twi_resources, |
457 | .num_resources = ARRAY_SIZE(twi_resources), | |
3267c077 AV |
458 | }; |
459 | ||
460 | void __init at91_add_device_i2c(void) | |
461 | { | |
462 | /* pins used for TWI interface */ | |
463 | at91_set_A_periph(AT91_PIN_PA25, 0); /* TWD */ | |
464 | at91_set_multi_drive(AT91_PIN_PA25, 1); | |
465 | ||
466 | at91_set_A_periph(AT91_PIN_PA26, 0); /* TWCK */ | |
467 | at91_set_multi_drive(AT91_PIN_PA26, 1); | |
468 | ||
469 | platform_device_register(&at91rm9200_twi_device); | |
470 | } | |
471 | #else | |
472 | void __init at91_add_device_i2c(void) {} | |
473 | #endif | |
474 | ||
475 | ||
2e836402 AV |
476 | /* -------------------------------------------------------------------- |
477 | * SPI | |
478 | * -------------------------------------------------------------------- */ | |
479 | ||
480 | #if defined(CONFIG_SPI_AT91) || defined(CONFIG_SPI_AT91_MODULE) || defined(CONFIG_AT91_SPI) || defined(CONFIG_AT91_SPI_MODULE) | |
481 | static u64 spi_dmamask = 0xffffffffUL; | |
482 | ||
69c5eccd | 483 | static struct resource spi_resources[] = { |
2e836402 | 484 | [0] = { |
72729910 AV |
485 | .start = AT91RM9200_BASE_SPI, |
486 | .end = AT91RM9200_BASE_SPI + SZ_16K - 1, | |
2e836402 AV |
487 | .flags = IORESOURCE_MEM, |
488 | }, | |
489 | [1] = { | |
72729910 AV |
490 | .start = AT91RM9200_ID_SPI, |
491 | .end = AT91RM9200_ID_SPI, | |
2e836402 AV |
492 | .flags = IORESOURCE_IRQ, |
493 | }, | |
494 | }; | |
495 | ||
496 | static struct platform_device at91rm9200_spi_device = { | |
497 | .name = "at91_spi", | |
498 | .id = 0, | |
499 | .dev = { | |
69c5eccd AV |
500 | .dma_mask = &spi_dmamask, |
501 | .coherent_dma_mask = 0xffffffff, | |
2e836402 | 502 | }, |
69c5eccd AV |
503 | .resource = spi_resources, |
504 | .num_resources = ARRAY_SIZE(spi_resources), | |
2e836402 AV |
505 | }; |
506 | ||
69c5eccd | 507 | static const unsigned spi_standard_cs[4] = { AT91_PIN_PA3, AT91_PIN_PA4, AT91_PIN_PA5, AT91_PIN_PA6 }; |
2e836402 AV |
508 | |
509 | void __init at91_add_device_spi(struct spi_board_info *devices, int nr_devices) | |
510 | { | |
511 | int i; | |
512 | unsigned long cs_pin; | |
513 | ||
514 | at91_set_A_periph(AT91_PIN_PA0, 0); /* MISO */ | |
515 | at91_set_A_periph(AT91_PIN_PA1, 0); /* MOSI */ | |
516 | at91_set_A_periph(AT91_PIN_PA2, 0); /* SPCK */ | |
517 | ||
518 | /* Enable SPI chip-selects */ | |
519 | for (i = 0; i < nr_devices; i++) { | |
520 | if (devices[i].controller_data) | |
521 | cs_pin = (unsigned long) devices[i].controller_data; | |
522 | else | |
69c5eccd | 523 | cs_pin = spi_standard_cs[devices[i].chip_select]; |
2e836402 AV |
524 | |
525 | #ifdef CONFIG_SPI_AT91_MANUAL_CS | |
526 | at91_set_gpio_output(cs_pin, 1); | |
527 | #else | |
528 | at91_set_A_periph(cs_pin, 0); | |
529 | #endif | |
530 | ||
531 | /* pass chip-select pin to driver */ | |
532 | devices[i].controller_data = (void *) cs_pin; | |
533 | } | |
534 | ||
535 | spi_register_board_info(devices, nr_devices); | |
69c5eccd | 536 | at91_clock_associate("spi_clk", &at91rm9200_spi_device.dev, "spi"); |
2e836402 AV |
537 | platform_device_register(&at91rm9200_spi_device); |
538 | } | |
539 | #else | |
540 | void __init at91_add_device_spi(struct spi_board_info *devices, int nr_devices) {} | |
541 | #endif | |
542 | ||
543 | ||
3267c077 AV |
544 | /* -------------------------------------------------------------------- |
545 | * RTC | |
546 | * -------------------------------------------------------------------- */ | |
547 | ||
69c5eccd | 548 | #if defined(CONFIG_RTC_DRV_AT91RM9200) || defined(CONFIG_RTC_DRV_AT91RM9200_MODULE) |
3267c077 AV |
549 | static struct platform_device at91rm9200_rtc_device = { |
550 | .name = "at91_rtc", | |
551 | .id = -1, | |
552 | .num_resources = 0, | |
553 | }; | |
554 | ||
2e836402 | 555 | static void __init at91_add_device_rtc(void) |
3267c077 AV |
556 | { |
557 | platform_device_register(&at91rm9200_rtc_device); | |
558 | } | |
559 | #else | |
2e836402 AV |
560 | static void __init at91_add_device_rtc(void) {} |
561 | #endif | |
562 | ||
563 | ||
564 | /* -------------------------------------------------------------------- | |
565 | * Watchdog | |
566 | * -------------------------------------------------------------------- */ | |
567 | ||
69c5eccd | 568 | #if defined(CONFIG_AT91RM9200_WATCHDOG) || defined(CONFIG_AT91RM9200_WATCHDOG_MODULE) |
2e836402 AV |
569 | static struct platform_device at91rm9200_wdt_device = { |
570 | .name = "at91_wdt", | |
571 | .id = -1, | |
572 | .num_resources = 0, | |
573 | }; | |
574 | ||
575 | static void __init at91_add_device_watchdog(void) | |
576 | { | |
577 | platform_device_register(&at91rm9200_wdt_device); | |
578 | } | |
579 | #else | |
580 | static void __init at91_add_device_watchdog(void) {} | |
3267c077 AV |
581 | #endif |
582 | ||
583 | ||
cc2832a1 AV |
584 | /* -------------------------------------------------------------------- |
585 | * LEDs | |
586 | * -------------------------------------------------------------------- */ | |
587 | ||
588 | #if defined(CONFIG_LEDS) | |
589 | u8 at91_leds_cpu; | |
590 | u8 at91_leds_timer; | |
591 | ||
592 | void __init at91_init_leds(u8 cpu_led, u8 timer_led) | |
593 | { | |
da11d02c AV |
594 | /* Enable GPIO to access the LEDs */ |
595 | at91_set_gpio_output(cpu_led, 1); | |
596 | at91_set_gpio_output(timer_led, 1); | |
597 | ||
2e836402 AV |
598 | at91_leds_cpu = cpu_led; |
599 | at91_leds_timer = timer_led; | |
cc2832a1 | 600 | } |
cc2832a1 AV |
601 | #else |
602 | void __init at91_init_leds(u8 cpu_led, u8 timer_led) {} | |
603 | #endif | |
604 | ||
605 | ||
2e836402 AV |
606 | /* -------------------------------------------------------------------- |
607 | * UART | |
608 | * -------------------------------------------------------------------- */ | |
609 | ||
749c4e60 | 610 | #if defined(CONFIG_SERIAL_ATMEL) |
2e836402 AV |
611 | static struct resource dbgu_resources[] = { |
612 | [0] = { | |
613 | .start = AT91_VA_BASE_SYS + AT91_DBGU, | |
614 | .end = AT91_VA_BASE_SYS + AT91_DBGU + SZ_512 - 1, | |
615 | .flags = IORESOURCE_MEM, | |
616 | }, | |
617 | [1] = { | |
618 | .start = AT91_ID_SYS, | |
619 | .end = AT91_ID_SYS, | |
620 | .flags = IORESOURCE_IRQ, | |
621 | }, | |
622 | }; | |
623 | ||
73e2798b | 624 | static struct atmel_uart_data dbgu_data = { |
2e836402 AV |
625 | .use_dma_tx = 0, |
626 | .use_dma_rx = 0, /* DBGU not capable of receive DMA */ | |
75d35213 | 627 | .regs = (void __iomem *)(AT91_VA_BASE_SYS + AT91_DBGU), |
2e836402 AV |
628 | }; |
629 | ||
630 | static struct platform_device at91rm9200_dbgu_device = { | |
1e8ea802 | 631 | .name = "atmel_usart", |
2e836402 AV |
632 | .id = 0, |
633 | .dev = { | |
634 | .platform_data = &dbgu_data, | |
635 | .coherent_dma_mask = 0xffffffff, | |
636 | }, | |
637 | .resource = dbgu_resources, | |
638 | .num_resources = ARRAY_SIZE(dbgu_resources), | |
639 | }; | |
640 | ||
641 | static inline void configure_dbgu_pins(void) | |
642 | { | |
643 | at91_set_A_periph(AT91_PIN_PA30, 0); /* DRXD */ | |
644 | at91_set_A_periph(AT91_PIN_PA31, 1); /* DTXD */ | |
645 | } | |
646 | ||
647 | static struct resource uart0_resources[] = { | |
648 | [0] = { | |
72729910 AV |
649 | .start = AT91RM9200_BASE_US0, |
650 | .end = AT91RM9200_BASE_US0 + SZ_16K - 1, | |
2e836402 AV |
651 | .flags = IORESOURCE_MEM, |
652 | }, | |
653 | [1] = { | |
72729910 AV |
654 | .start = AT91RM9200_ID_US0, |
655 | .end = AT91RM9200_ID_US0, | |
2e836402 AV |
656 | .flags = IORESOURCE_IRQ, |
657 | }, | |
658 | }; | |
659 | ||
73e2798b | 660 | static struct atmel_uart_data uart0_data = { |
2e836402 AV |
661 | .use_dma_tx = 1, |
662 | .use_dma_rx = 1, | |
663 | }; | |
664 | ||
665 | static struct platform_device at91rm9200_uart0_device = { | |
1e8ea802 | 666 | .name = "atmel_usart", |
2e836402 AV |
667 | .id = 1, |
668 | .dev = { | |
669 | .platform_data = &uart0_data, | |
670 | .coherent_dma_mask = 0xffffffff, | |
671 | }, | |
672 | .resource = uart0_resources, | |
673 | .num_resources = ARRAY_SIZE(uart0_resources), | |
674 | }; | |
675 | ||
676 | static inline void configure_usart0_pins(void) | |
677 | { | |
678 | at91_set_A_periph(AT91_PIN_PA17, 1); /* TXD0 */ | |
679 | at91_set_A_periph(AT91_PIN_PA18, 0); /* RXD0 */ | |
680 | at91_set_A_periph(AT91_PIN_PA20, 0); /* CTS0 */ | |
681 | ||
682 | /* | |
683 | * AT91RM9200 Errata #39 - RTS0 is not internally connected to PA21. | |
684 | * We need to drive the pin manually. Default is off (RTS is active low). | |
685 | */ | |
686 | at91_set_gpio_output(AT91_PIN_PA21, 1); | |
687 | } | |
688 | ||
689 | static struct resource uart1_resources[] = { | |
690 | [0] = { | |
72729910 AV |
691 | .start = AT91RM9200_BASE_US1, |
692 | .end = AT91RM9200_BASE_US1 + SZ_16K - 1, | |
2e836402 AV |
693 | .flags = IORESOURCE_MEM, |
694 | }, | |
695 | [1] = { | |
72729910 AV |
696 | .start = AT91RM9200_ID_US1, |
697 | .end = AT91RM9200_ID_US1, | |
2e836402 AV |
698 | .flags = IORESOURCE_IRQ, |
699 | }, | |
700 | }; | |
701 | ||
73e2798b | 702 | static struct atmel_uart_data uart1_data = { |
2e836402 AV |
703 | .use_dma_tx = 1, |
704 | .use_dma_rx = 1, | |
705 | }; | |
706 | ||
707 | static struct platform_device at91rm9200_uart1_device = { | |
1e8ea802 | 708 | .name = "atmel_usart", |
2e836402 AV |
709 | .id = 2, |
710 | .dev = { | |
711 | .platform_data = &uart1_data, | |
712 | .coherent_dma_mask = 0xffffffff, | |
713 | }, | |
714 | .resource = uart1_resources, | |
715 | .num_resources = ARRAY_SIZE(uart1_resources), | |
716 | }; | |
717 | ||
718 | static inline void configure_usart1_pins(void) | |
719 | { | |
720 | at91_set_A_periph(AT91_PIN_PB18, 0); /* RI1 */ | |
721 | at91_set_A_periph(AT91_PIN_PB19, 0); /* DTR1 */ | |
722 | at91_set_A_periph(AT91_PIN_PB20, 1); /* TXD1 */ | |
723 | at91_set_A_periph(AT91_PIN_PB21, 0); /* RXD1 */ | |
724 | at91_set_A_periph(AT91_PIN_PB23, 0); /* DCD1 */ | |
725 | at91_set_A_periph(AT91_PIN_PB24, 0); /* CTS1 */ | |
726 | at91_set_A_periph(AT91_PIN_PB25, 0); /* DSR1 */ | |
727 | at91_set_A_periph(AT91_PIN_PB26, 0); /* RTS1 */ | |
728 | } | |
729 | ||
730 | static struct resource uart2_resources[] = { | |
731 | [0] = { | |
72729910 AV |
732 | .start = AT91RM9200_BASE_US2, |
733 | .end = AT91RM9200_BASE_US2 + SZ_16K - 1, | |
2e836402 AV |
734 | .flags = IORESOURCE_MEM, |
735 | }, | |
736 | [1] = { | |
72729910 AV |
737 | .start = AT91RM9200_ID_US2, |
738 | .end = AT91RM9200_ID_US2, | |
2e836402 AV |
739 | .flags = IORESOURCE_IRQ, |
740 | }, | |
741 | }; | |
742 | ||
73e2798b | 743 | static struct atmel_uart_data uart2_data = { |
2e836402 AV |
744 | .use_dma_tx = 1, |
745 | .use_dma_rx = 1, | |
746 | }; | |
747 | ||
748 | static struct platform_device at91rm9200_uart2_device = { | |
1e8ea802 | 749 | .name = "atmel_usart", |
2e836402 AV |
750 | .id = 3, |
751 | .dev = { | |
752 | .platform_data = &uart2_data, | |
753 | .coherent_dma_mask = 0xffffffff, | |
754 | }, | |
755 | .resource = uart2_resources, | |
756 | .num_resources = ARRAY_SIZE(uart2_resources), | |
757 | }; | |
758 | ||
759 | static inline void configure_usart2_pins(void) | |
760 | { | |
761 | at91_set_A_periph(AT91_PIN_PA22, 0); /* RXD2 */ | |
762 | at91_set_A_periph(AT91_PIN_PA23, 1); /* TXD2 */ | |
763 | } | |
764 | ||
765 | static struct resource uart3_resources[] = { | |
766 | [0] = { | |
72729910 AV |
767 | .start = AT91RM9200_BASE_US3, |
768 | .end = AT91RM9200_BASE_US3 + SZ_16K - 1, | |
2e836402 AV |
769 | .flags = IORESOURCE_MEM, |
770 | }, | |
771 | [1] = { | |
72729910 AV |
772 | .start = AT91RM9200_ID_US3, |
773 | .end = AT91RM9200_ID_US3, | |
2e836402 AV |
774 | .flags = IORESOURCE_IRQ, |
775 | }, | |
776 | }; | |
777 | ||
73e2798b | 778 | static struct atmel_uart_data uart3_data = { |
2e836402 AV |
779 | .use_dma_tx = 1, |
780 | .use_dma_rx = 1, | |
781 | }; | |
782 | ||
783 | static struct platform_device at91rm9200_uart3_device = { | |
1e8ea802 | 784 | .name = "atmel_usart", |
2e836402 AV |
785 | .id = 4, |
786 | .dev = { | |
787 | .platform_data = &uart3_data, | |
788 | .coherent_dma_mask = 0xffffffff, | |
789 | }, | |
790 | .resource = uart3_resources, | |
791 | .num_resources = ARRAY_SIZE(uart3_resources), | |
792 | }; | |
793 | ||
794 | static inline void configure_usart3_pins(void) | |
795 | { | |
796 | at91_set_B_periph(AT91_PIN_PA5, 1); /* TXD3 */ | |
797 | at91_set_B_periph(AT91_PIN_PA6, 0); /* RXD3 */ | |
798 | } | |
799 | ||
73e2798b HS |
800 | struct platform_device *at91_uarts[ATMEL_MAX_UART]; /* the UARTs to use */ |
801 | struct platform_device *atmel_default_console_device; /* the serial console device */ | |
2e836402 AV |
802 | |
803 | void __init at91_init_serial(struct at91_uart_config *config) | |
804 | { | |
805 | int i; | |
806 | ||
807 | /* Fill in list of supported UARTs */ | |
808 | for (i = 0; i < config->nr_tty; i++) { | |
809 | switch (config->tty_map[i]) { | |
810 | case 0: | |
811 | configure_usart0_pins(); | |
812 | at91_uarts[i] = &at91rm9200_uart0_device; | |
813 | at91_clock_associate("usart0_clk", &at91rm9200_uart0_device.dev, "usart"); | |
814 | break; | |
815 | case 1: | |
816 | configure_usart1_pins(); | |
817 | at91_uarts[i] = &at91rm9200_uart1_device; | |
818 | at91_clock_associate("usart1_clk", &at91rm9200_uart1_device.dev, "usart"); | |
819 | break; | |
820 | case 2: | |
821 | configure_usart2_pins(); | |
822 | at91_uarts[i] = &at91rm9200_uart2_device; | |
823 | at91_clock_associate("usart2_clk", &at91rm9200_uart2_device.dev, "usart"); | |
824 | break; | |
825 | case 3: | |
826 | configure_usart3_pins(); | |
827 | at91_uarts[i] = &at91rm9200_uart3_device; | |
828 | at91_clock_associate("usart3_clk", &at91rm9200_uart3_device.dev, "usart"); | |
829 | break; | |
830 | case 4: | |
831 | configure_dbgu_pins(); | |
832 | at91_uarts[i] = &at91rm9200_dbgu_device; | |
833 | at91_clock_associate("mck", &at91rm9200_dbgu_device.dev, "usart"); | |
834 | break; | |
835 | default: | |
836 | continue; | |
837 | } | |
838 | at91_uarts[i]->id = i; /* update ID number to mapped ID */ | |
839 | } | |
840 | ||
841 | /* Set serial console device */ | |
73e2798b HS |
842 | if (config->console_tty < ATMEL_MAX_UART) |
843 | atmel_default_console_device = at91_uarts[config->console_tty]; | |
844 | if (!atmel_default_console_device) | |
2e836402 AV |
845 | printk(KERN_INFO "AT91: No default serial console defined.\n"); |
846 | } | |
847 | ||
848 | void __init at91_add_device_serial(void) | |
849 | { | |
850 | int i; | |
851 | ||
73e2798b | 852 | for (i = 0; i < ATMEL_MAX_UART; i++) { |
2e836402 AV |
853 | if (at91_uarts[i]) |
854 | platform_device_register(at91_uarts[i]); | |
855 | } | |
856 | } | |
857 | #else | |
858 | void __init at91_init_serial(struct at91_uart_config *config) {} | |
859 | void __init at91_add_device_serial(void) {} | |
860 | #endif | |
861 | ||
862 | ||
73a59c1c | 863 | /* -------------------------------------------------------------------- */ |
2e836402 AV |
864 | |
865 | /* | |
866 | * These devices are always present and don't need any board-specific | |
867 | * setup. | |
868 | */ | |
869 | static int __init at91_add_standard_devices(void) | |
870 | { | |
871 | at91_add_device_rtc(); | |
872 | at91_add_device_watchdog(); | |
873 | return 0; | |
874 | } | |
875 | ||
876 | arch_initcall(at91_add_standard_devices); |