blob: 96e2adcd5a841907be15beda7bdbb67dd87b5259 [file] [log] [blame]
Nicolas Ferre789b23b2009-06-26 15:36:58 +01001/*
2 * On-Chip devices setup code for the AT91SAM9G45 family
3 *
4 * Copyright (C) 2009 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>
Russell King2f8163b2011-07-26 10:53:52 +010016#include <linux/gpio.h>
Nicolas Ferre789b23b2009-06-26 15:36:58 +010017#include <linux/platform_device.h>
18#include <linux/i2c-gpio.h>
Nicolas Ferre75305d72010-10-22 18:27:48 +020019#include <linux/atmel-mci.h>
Nicolas Ferre789b23b2009-06-26 15:36:58 +010020
21#include <linux/fb.h>
22#include <video/atmel_lcdc.h>
23
24#include <mach/board.h>
Nicolas Ferre789b23b2009-06-26 15:36:58 +010025#include <mach/at91sam9g45.h>
26#include <mach/at91sam9g45_matrix.h>
27#include <mach/at91sam9_smc.h>
Nicolas Ferre40262b22009-07-24 11:43:01 +010028#include <mach/at_hdmac.h>
Nicolas Ferre75305d72010-10-22 18:27:48 +020029#include <mach/atmel-mci.h>
Nicolas Ferre789b23b2009-06-26 15:36:58 +010030
31#include "generic.h"
32
33
34/* --------------------------------------------------------------------
Nicolas Ferre40262b22009-07-24 11:43:01 +010035 * HDMAC - AHB DMA Controller
36 * -------------------------------------------------------------------- */
37
38#if defined(CONFIG_AT_HDMAC) || defined(CONFIG_AT_HDMAC_MODULE)
39static u64 hdmac_dmamask = DMA_BIT_MASK(32);
40
Nicolas Ferre40262b22009-07-24 11:43:01 +010041static struct resource hdmac_resources[] = {
42 [0] = {
Jean-Christophe PLAGNIOL-VILLARD9627b202011-10-15 15:47:51 +080043 .start = AT91SAM9G45_BASE_DMA,
44 .end = AT91SAM9G45_BASE_DMA + SZ_512 - 1,
Nicolas Ferre40262b22009-07-24 11:43:01 +010045 .flags = IORESOURCE_MEM,
46 },
Nicolas Ferre8d2602e2010-08-20 16:44:33 +020047 [1] = {
Nicolas Ferre40262b22009-07-24 11:43:01 +010048 .start = AT91SAM9G45_ID_DMA,
49 .end = AT91SAM9G45_ID_DMA,
50 .flags = IORESOURCE_IRQ,
51 },
52};
53
54static struct platform_device at_hdmac_device = {
Nicolas Ferrebdad0b92011-10-10 14:55:17 +020055 .name = "at91sam9g45_dma",
Nicolas Ferre40262b22009-07-24 11:43:01 +010056 .id = -1,
57 .dev = {
58 .dma_mask = &hdmac_dmamask,
59 .coherent_dma_mask = DMA_BIT_MASK(32),
Nicolas Ferre40262b22009-07-24 11:43:01 +010060 },
61 .resource = hdmac_resources,
62 .num_resources = ARRAY_SIZE(hdmac_resources),
63};
64
65void __init at91_add_device_hdmac(void)
66{
Nicolas Ferre2756bf52011-10-10 16:50:43 +020067#if defined(CONFIG_OF)
68 struct device_node *of_node =
69 of_find_node_by_name(NULL, "dma-controller");
70
71 if (of_node)
72 of_node_put(of_node);
73 else
74#endif
75 platform_device_register(&at_hdmac_device);
Nicolas Ferre40262b22009-07-24 11:43:01 +010076}
77#else
78void __init at91_add_device_hdmac(void) {}
79#endif
80
81
82/* --------------------------------------------------------------------
Nicolas Ferre789b23b2009-06-26 15:36:58 +010083 * USB Host (OHCI)
84 * -------------------------------------------------------------------- */
85
86#if defined(CONFIG_USB_OHCI_HCD) || defined(CONFIG_USB_OHCI_HCD_MODULE)
87static u64 ohci_dmamask = DMA_BIT_MASK(32);
88static struct at91_usbh_data usbh_ohci_data;
89
90static struct resource usbh_ohci_resources[] = {
91 [0] = {
92 .start = AT91SAM9G45_OHCI_BASE,
93 .end = AT91SAM9G45_OHCI_BASE + SZ_1M - 1,
94 .flags = IORESOURCE_MEM,
95 },
96 [1] = {
97 .start = AT91SAM9G45_ID_UHPHS,
98 .end = AT91SAM9G45_ID_UHPHS,
99 .flags = IORESOURCE_IRQ,
100 },
101};
102
103static struct platform_device at91_usbh_ohci_device = {
104 .name = "at91_ohci",
105 .id = -1,
106 .dev = {
107 .dma_mask = &ohci_dmamask,
108 .coherent_dma_mask = DMA_BIT_MASK(32),
109 .platform_data = &usbh_ohci_data,
110 },
111 .resource = usbh_ohci_resources,
112 .num_resources = ARRAY_SIZE(usbh_ohci_resources),
113};
114
115void __init at91_add_device_usbh_ohci(struct at91_usbh_data *data)
116{
117 int i;
118
119 if (!data)
120 return;
121
122 /* Enable VBus control for UHP ports */
123 for (i = 0; i < data->ports; i++) {
Jean-Christophe PLAGNIOL-VILLARDcc9f9ae2011-09-19 15:28:25 +0800124 if (gpio_is_valid(data->vbus_pin[i]))
Nicolas Ferre789b23b2009-06-26 15:36:58 +0100125 at91_set_gpio_output(data->vbus_pin[i], 0);
126 }
127
Thomas Petazzoni1fcaea72011-07-13 11:29:18 +0200128 /* Enable overcurrent notification */
129 for (i = 0; i < data->ports; i++) {
130 if (data->overcurrent_pin[i])
131 at91_set_gpio_input(data->overcurrent_pin[i], 1);
132 }
133
Nicolas Ferre789b23b2009-06-26 15:36:58 +0100134 usbh_ohci_data = *data;
135 platform_device_register(&at91_usbh_ohci_device);
136}
137#else
138void __init at91_add_device_usbh_ohci(struct at91_usbh_data *data) {}
139#endif
140
141
142/* --------------------------------------------------------------------
Nicolas Ferref51f78c2009-09-25 12:11:32 +0100143 * USB Host HS (EHCI)
144 * Needs an OHCI host for low and full speed management
145 * -------------------------------------------------------------------- */
146
147#if defined(CONFIG_USB_EHCI_HCD) || defined(CONFIG_USB_EHCI_HCD_MODULE)
148static u64 ehci_dmamask = DMA_BIT_MASK(32);
149static struct at91_usbh_data usbh_ehci_data;
150
151static struct resource usbh_ehci_resources[] = {
152 [0] = {
153 .start = AT91SAM9G45_EHCI_BASE,
154 .end = AT91SAM9G45_EHCI_BASE + SZ_1M - 1,
155 .flags = IORESOURCE_MEM,
156 },
157 [1] = {
158 .start = AT91SAM9G45_ID_UHPHS,
159 .end = AT91SAM9G45_ID_UHPHS,
160 .flags = IORESOURCE_IRQ,
161 },
162};
163
164static struct platform_device at91_usbh_ehci_device = {
165 .name = "atmel-ehci",
166 .id = -1,
167 .dev = {
168 .dma_mask = &ehci_dmamask,
169 .coherent_dma_mask = DMA_BIT_MASK(32),
170 .platform_data = &usbh_ehci_data,
171 },
172 .resource = usbh_ehci_resources,
173 .num_resources = ARRAY_SIZE(usbh_ehci_resources),
174};
175
176void __init at91_add_device_usbh_ehci(struct at91_usbh_data *data)
177{
178 int i;
179
180 if (!data)
181 return;
182
183 /* Enable VBus control for UHP ports */
184 for (i = 0; i < data->ports; i++) {
Jean-Christophe PLAGNIOL-VILLARDcc9f9ae2011-09-19 15:28:25 +0800185 if (gpio_is_valid(data->vbus_pin[i]))
Nicolas Ferref51f78c2009-09-25 12:11:32 +0100186 at91_set_gpio_output(data->vbus_pin[i], 0);
187 }
188
189 usbh_ehci_data = *data;
Nicolas Ferref51f78c2009-09-25 12:11:32 +0100190 platform_device_register(&at91_usbh_ehci_device);
191}
192#else
193void __init at91_add_device_usbh_ehci(struct at91_usbh_data *data) {}
194#endif
195
196
197/* --------------------------------------------------------------------
Nicolas Ferre789b23b2009-06-26 15:36:58 +0100198 * USB HS Device (Gadget)
199 * -------------------------------------------------------------------- */
200
Jochen Friedrichdd0b3822011-10-25 20:51:06 +0200201#if defined(CONFIG_USB_ATMEL_USBA) || defined(CONFIG_USB_ATMEL_USBA_MODULE)
Nicolas Ferre789b23b2009-06-26 15:36:58 +0100202static struct resource usba_udc_resources[] = {
203 [0] = {
204 .start = AT91SAM9G45_UDPHS_FIFO,
205 .end = AT91SAM9G45_UDPHS_FIFO + SZ_512K - 1,
206 .flags = IORESOURCE_MEM,
207 },
208 [1] = {
209 .start = AT91SAM9G45_BASE_UDPHS,
210 .end = AT91SAM9G45_BASE_UDPHS + SZ_1K - 1,
211 .flags = IORESOURCE_MEM,
212 },
213 [2] = {
214 .start = AT91SAM9G45_ID_UDPHS,
215 .end = AT91SAM9G45_ID_UDPHS,
216 .flags = IORESOURCE_IRQ,
217 },
218};
219
220#define EP(nam, idx, maxpkt, maxbk, dma, isoc) \
221 [idx] = { \
222 .name = nam, \
223 .index = idx, \
224 .fifo_size = maxpkt, \
225 .nr_banks = maxbk, \
226 .can_dma = dma, \
227 .can_isoc = isoc, \
228 }
229
230static struct usba_ep_data usba_udc_ep[] __initdata = {
231 EP("ep0", 0, 64, 1, 0, 0),
232 EP("ep1", 1, 1024, 2, 1, 1),
233 EP("ep2", 2, 1024, 2, 1, 1),
234 EP("ep3", 3, 1024, 3, 1, 0),
235 EP("ep4", 4, 1024, 3, 1, 0),
236 EP("ep5", 5, 1024, 3, 1, 1),
237 EP("ep6", 6, 1024, 3, 1, 1),
238};
239
240#undef EP
241
242/*
243 * pdata doesn't have room for any endpoints, so we need to
244 * append room for the ones we need right after it.
245 */
246static struct {
247 struct usba_platform_data pdata;
248 struct usba_ep_data ep[7];
249} usba_udc_data;
250
251static struct platform_device at91_usba_udc_device = {
252 .name = "atmel_usba_udc",
253 .id = -1,
254 .dev = {
255 .platform_data = &usba_udc_data.pdata,
256 },
257 .resource = usba_udc_resources,
258 .num_resources = ARRAY_SIZE(usba_udc_resources),
259};
260
261void __init at91_add_device_usba(struct usba_platform_data *data)
262{
263 usba_udc_data.pdata.vbus_pin = -EINVAL;
264 usba_udc_data.pdata.num_ep = ARRAY_SIZE(usba_udc_ep);
Justin P. Mattock6eab04a2011-04-08 19:49:08 -0700265 memcpy(usba_udc_data.ep, usba_udc_ep, sizeof(usba_udc_ep));
Nicolas Ferre789b23b2009-06-26 15:36:58 +0100266
Jean-Christophe PLAGNIOL-VILLARDcc9f9ae2011-09-19 15:28:25 +0800267 if (data && gpio_is_valid(data->vbus_pin)) {
Nicolas Ferre789b23b2009-06-26 15:36:58 +0100268 at91_set_gpio_input(data->vbus_pin, 0);
269 at91_set_deglitch(data->vbus_pin, 1);
270 usba_udc_data.pdata.vbus_pin = data->vbus_pin;
271 }
272
273 /* Pullup pin is handled internally by USB device peripheral */
274
Nicolas Ferre789b23b2009-06-26 15:36:58 +0100275 platform_device_register(&at91_usba_udc_device);
276}
277#else
278void __init at91_add_device_usba(struct usba_platform_data *data) {}
279#endif
280
281
282/* --------------------------------------------------------------------
283 * Ethernet
284 * -------------------------------------------------------------------- */
285
286#if defined(CONFIG_MACB) || defined(CONFIG_MACB_MODULE)
287static u64 eth_dmamask = DMA_BIT_MASK(32);
Jamie Iles84e0cdb2011-03-08 20:17:06 +0000288static struct macb_platform_data eth_data;
Nicolas Ferre789b23b2009-06-26 15:36:58 +0100289
290static struct resource eth_resources[] = {
291 [0] = {
292 .start = AT91SAM9G45_BASE_EMAC,
293 .end = AT91SAM9G45_BASE_EMAC + SZ_16K - 1,
294 .flags = IORESOURCE_MEM,
295 },
296 [1] = {
297 .start = AT91SAM9G45_ID_EMAC,
298 .end = AT91SAM9G45_ID_EMAC,
299 .flags = IORESOURCE_IRQ,
300 },
301};
302
303static struct platform_device at91sam9g45_eth_device = {
304 .name = "macb",
305 .id = -1,
306 .dev = {
307 .dma_mask = &eth_dmamask,
308 .coherent_dma_mask = DMA_BIT_MASK(32),
309 .platform_data = &eth_data,
310 },
311 .resource = eth_resources,
312 .num_resources = ARRAY_SIZE(eth_resources),
313};
314
Jamie Iles84e0cdb2011-03-08 20:17:06 +0000315void __init at91_add_device_eth(struct macb_platform_data *data)
Nicolas Ferre789b23b2009-06-26 15:36:58 +0100316{
317 if (!data)
318 return;
319
Jean-Christophe PLAGNIOL-VILLARDcc9f9ae2011-09-19 15:28:25 +0800320 if (gpio_is_valid(data->phy_irq_pin)) {
Nicolas Ferre789b23b2009-06-26 15:36:58 +0100321 at91_set_gpio_input(data->phy_irq_pin, 0);
322 at91_set_deglitch(data->phy_irq_pin, 1);
323 }
324
325 /* Pins used for MII and RMII */
326 at91_set_A_periph(AT91_PIN_PA17, 0); /* ETXCK_EREFCK */
327 at91_set_A_periph(AT91_PIN_PA15, 0); /* ERXDV */
328 at91_set_A_periph(AT91_PIN_PA12, 0); /* ERX0 */
329 at91_set_A_periph(AT91_PIN_PA13, 0); /* ERX1 */
330 at91_set_A_periph(AT91_PIN_PA16, 0); /* ERXER */
331 at91_set_A_periph(AT91_PIN_PA14, 0); /* ETXEN */
332 at91_set_A_periph(AT91_PIN_PA10, 0); /* ETX0 */
333 at91_set_A_periph(AT91_PIN_PA11, 0); /* ETX1 */
334 at91_set_A_periph(AT91_PIN_PA19, 0); /* EMDIO */
335 at91_set_A_periph(AT91_PIN_PA18, 0); /* EMDC */
336
337 if (!data->is_rmii) {
338 at91_set_B_periph(AT91_PIN_PA29, 0); /* ECRS */
339 at91_set_B_periph(AT91_PIN_PA30, 0); /* ECOL */
340 at91_set_B_periph(AT91_PIN_PA8, 0); /* ERX2 */
341 at91_set_B_periph(AT91_PIN_PA9, 0); /* ERX3 */
342 at91_set_B_periph(AT91_PIN_PA28, 0); /* ERXCK */
343 at91_set_B_periph(AT91_PIN_PA6, 0); /* ETX2 */
344 at91_set_B_periph(AT91_PIN_PA7, 0); /* ETX3 */
345 at91_set_B_periph(AT91_PIN_PA27, 0); /* ETXER */
346 }
347
348 eth_data = *data;
349 platform_device_register(&at91sam9g45_eth_device);
350}
351#else
Jamie Iles84e0cdb2011-03-08 20:17:06 +0000352void __init at91_add_device_eth(struct macb_platform_data *data) {}
Nicolas Ferre789b23b2009-06-26 15:36:58 +0100353#endif
354
355
356/* --------------------------------------------------------------------
Nicolas Ferre75305d72010-10-22 18:27:48 +0200357 * MMC / SD
358 * -------------------------------------------------------------------- */
359
360#if defined(CONFIG_MMC_ATMELMCI) || defined(CONFIG_MMC_ATMELMCI_MODULE)
361static u64 mmc_dmamask = DMA_BIT_MASK(32);
362static struct mci_platform_data mmc0_data, mmc1_data;
363
364static struct resource mmc0_resources[] = {
365 [0] = {
366 .start = AT91SAM9G45_BASE_MCI0,
367 .end = AT91SAM9G45_BASE_MCI0 + SZ_16K - 1,
368 .flags = IORESOURCE_MEM,
369 },
370 [1] = {
371 .start = AT91SAM9G45_ID_MCI0,
372 .end = AT91SAM9G45_ID_MCI0,
373 .flags = IORESOURCE_IRQ,
374 },
375};
376
377static struct platform_device at91sam9g45_mmc0_device = {
378 .name = "atmel_mci",
379 .id = 0,
380 .dev = {
381 .dma_mask = &mmc_dmamask,
382 .coherent_dma_mask = DMA_BIT_MASK(32),
383 .platform_data = &mmc0_data,
384 },
385 .resource = mmc0_resources,
386 .num_resources = ARRAY_SIZE(mmc0_resources),
387};
388
389static struct resource mmc1_resources[] = {
390 [0] = {
391 .start = AT91SAM9G45_BASE_MCI1,
392 .end = AT91SAM9G45_BASE_MCI1 + SZ_16K - 1,
393 .flags = IORESOURCE_MEM,
394 },
395 [1] = {
396 .start = AT91SAM9G45_ID_MCI1,
397 .end = AT91SAM9G45_ID_MCI1,
398 .flags = IORESOURCE_IRQ,
399 },
400};
401
402static struct platform_device at91sam9g45_mmc1_device = {
403 .name = "atmel_mci",
404 .id = 1,
405 .dev = {
406 .dma_mask = &mmc_dmamask,
407 .coherent_dma_mask = DMA_BIT_MASK(32),
408 .platform_data = &mmc1_data,
409 },
410 .resource = mmc1_resources,
411 .num_resources = ARRAY_SIZE(mmc1_resources),
412};
413
414/* Consider only one slot : slot 0 */
415void __init at91_add_device_mci(short mmc_id, struct mci_platform_data *data)
416{
417
418 if (!data)
419 return;
420
421 /* Must have at least one usable slot */
422 if (!data->slot[0].bus_width)
423 return;
424
425#if defined(CONFIG_AT_HDMAC) || defined(CONFIG_AT_HDMAC_MODULE)
426 {
427 struct at_dma_slave *atslave;
428 struct mci_dma_data *alt_atslave;
429
430 alt_atslave = kzalloc(sizeof(struct mci_dma_data), GFP_KERNEL);
431 atslave = &alt_atslave->sdata;
432
433 /* DMA slave channel configuration */
434 atslave->dma_dev = &at_hdmac_device.dev;
435 atslave->reg_width = AT_DMA_SLAVE_WIDTH_32BIT;
436 atslave->cfg = ATC_FIFOCFG_HALFFIFO
437 | ATC_SRC_H2SEL_HW | ATC_DST_H2SEL_HW;
438 atslave->ctrla = ATC_SCSIZE_16 | ATC_DCSIZE_16;
439 if (mmc_id == 0) /* MCI0 */
440 atslave->cfg |= ATC_SRC_PER(AT_DMA_ID_MCI0)
441 | ATC_DST_PER(AT_DMA_ID_MCI0);
442
443 else /* MCI1 */
444 atslave->cfg |= ATC_SRC_PER(AT_DMA_ID_MCI1)
445 | ATC_DST_PER(AT_DMA_ID_MCI1);
446
447 data->dma_slave = alt_atslave;
448 }
449#endif
450
451
452 /* input/irq */
Jean-Christophe PLAGNIOL-VILLARDcc9f9ae2011-09-19 15:28:25 +0800453 if (gpio_is_valid(data->slot[0].detect_pin)) {
Nicolas Ferre75305d72010-10-22 18:27:48 +0200454 at91_set_gpio_input(data->slot[0].detect_pin, 1);
455 at91_set_deglitch(data->slot[0].detect_pin, 1);
456 }
Jean-Christophe PLAGNIOL-VILLARDcc9f9ae2011-09-19 15:28:25 +0800457 if (gpio_is_valid(data->slot[0].wp_pin))
Nicolas Ferre75305d72010-10-22 18:27:48 +0200458 at91_set_gpio_input(data->slot[0].wp_pin, 1);
459
460 if (mmc_id == 0) { /* MCI0 */
461
462 /* CLK */
463 at91_set_A_periph(AT91_PIN_PA0, 0);
464
465 /* CMD */
466 at91_set_A_periph(AT91_PIN_PA1, 1);
467
468 /* DAT0, maybe DAT1..DAT3 and maybe DAT4..DAT7 */
469 at91_set_A_periph(AT91_PIN_PA2, 1);
470 if (data->slot[0].bus_width == 4) {
471 at91_set_A_periph(AT91_PIN_PA3, 1);
472 at91_set_A_periph(AT91_PIN_PA4, 1);
473 at91_set_A_periph(AT91_PIN_PA5, 1);
474 if (data->slot[0].bus_width == 8) {
475 at91_set_A_periph(AT91_PIN_PA6, 1);
476 at91_set_A_periph(AT91_PIN_PA7, 1);
477 at91_set_A_periph(AT91_PIN_PA8, 1);
478 at91_set_A_periph(AT91_PIN_PA9, 1);
479 }
480 }
481
482 mmc0_data = *data;
Nicolas Ferre75305d72010-10-22 18:27:48 +0200483 platform_device_register(&at91sam9g45_mmc0_device);
484
485 } else { /* MCI1 */
486
487 /* CLK */
488 at91_set_A_periph(AT91_PIN_PA31, 0);
489
490 /* CMD */
491 at91_set_A_periph(AT91_PIN_PA22, 1);
492
493 /* DAT0, maybe DAT1..DAT3 and maybe DAT4..DAT7 */
494 at91_set_A_periph(AT91_PIN_PA23, 1);
495 if (data->slot[0].bus_width == 4) {
496 at91_set_A_periph(AT91_PIN_PA24, 1);
497 at91_set_A_periph(AT91_PIN_PA25, 1);
498 at91_set_A_periph(AT91_PIN_PA26, 1);
499 if (data->slot[0].bus_width == 8) {
500 at91_set_A_periph(AT91_PIN_PA27, 1);
501 at91_set_A_periph(AT91_PIN_PA28, 1);
502 at91_set_A_periph(AT91_PIN_PA29, 1);
503 at91_set_A_periph(AT91_PIN_PA30, 1);
504 }
505 }
506
507 mmc1_data = *data;
Nicolas Ferre75305d72010-10-22 18:27:48 +0200508 platform_device_register(&at91sam9g45_mmc1_device);
509
510 }
511}
512#else
513void __init at91_add_device_mci(short mmc_id, struct mci_platform_data *data) {}
514#endif
515
516
517/* --------------------------------------------------------------------
Nicolas Ferre789b23b2009-06-26 15:36:58 +0100518 * NAND / SmartMedia
519 * -------------------------------------------------------------------- */
520
521#if defined(CONFIG_MTD_NAND_ATMEL) || defined(CONFIG_MTD_NAND_ATMEL_MODULE)
522static struct atmel_nand_data nand_data;
523
524#define NAND_BASE AT91_CHIPSELECT_3
525
526static struct resource nand_resources[] = {
527 [0] = {
528 .start = NAND_BASE,
529 .end = NAND_BASE + SZ_256M - 1,
530 .flags = IORESOURCE_MEM,
531 },
532 [1] = {
Jean-Christophe PLAGNIOL-VILLARDd28edd12011-09-18 09:31:56 +0800533 .start = AT91SAM9G45_BASE_ECC,
534 .end = AT91SAM9G45_BASE_ECC + SZ_512 - 1,
Nicolas Ferre789b23b2009-06-26 15:36:58 +0100535 .flags = IORESOURCE_MEM,
536 }
537};
538
539static struct platform_device at91sam9g45_nand_device = {
540 .name = "atmel_nand",
541 .id = -1,
542 .dev = {
543 .platform_data = &nand_data,
544 },
545 .resource = nand_resources,
546 .num_resources = ARRAY_SIZE(nand_resources),
547};
548
549void __init at91_add_device_nand(struct atmel_nand_data *data)
550{
551 unsigned long csa;
552
553 if (!data)
554 return;
555
556 csa = at91_sys_read(AT91_MATRIX_EBICSA);
557 at91_sys_write(AT91_MATRIX_EBICSA, csa | AT91_MATRIX_EBI_CS3A_SMC_SMARTMEDIA);
558
559 /* enable pin */
Jean-Christophe PLAGNIOL-VILLARDcc9f9ae2011-09-19 15:28:25 +0800560 if (gpio_is_valid(data->enable_pin))
Nicolas Ferre789b23b2009-06-26 15:36:58 +0100561 at91_set_gpio_output(data->enable_pin, 1);
562
563 /* ready/busy pin */
Jean-Christophe PLAGNIOL-VILLARDcc9f9ae2011-09-19 15:28:25 +0800564 if (gpio_is_valid(data->rdy_pin))
Nicolas Ferre789b23b2009-06-26 15:36:58 +0100565 at91_set_gpio_input(data->rdy_pin, 1);
566
567 /* card detect pin */
Jean-Christophe PLAGNIOL-VILLARDcc9f9ae2011-09-19 15:28:25 +0800568 if (gpio_is_valid(data->det_pin))
Nicolas Ferre789b23b2009-06-26 15:36:58 +0100569 at91_set_gpio_input(data->det_pin, 1);
570
571 nand_data = *data;
572 platform_device_register(&at91sam9g45_nand_device);
573}
574#else
575void __init at91_add_device_nand(struct atmel_nand_data *data) {}
576#endif
577
578
579/* --------------------------------------------------------------------
580 * TWI (i2c)
581 * -------------------------------------------------------------------- */
582
583/*
584 * Prefer the GPIO code since the TWI controller isn't robust
585 * (gets overruns and underruns under load) and can only issue
586 * repeated STARTs in one scenario (the driver doesn't yet handle them).
587 */
588#if defined(CONFIG_I2C_GPIO) || defined(CONFIG_I2C_GPIO_MODULE)
589static struct i2c_gpio_platform_data pdata_i2c0 = {
590 .sda_pin = AT91_PIN_PA20,
591 .sda_is_open_drain = 1,
592 .scl_pin = AT91_PIN_PA21,
593 .scl_is_open_drain = 1,
Peter Korsgaard1d5b4c02010-09-22 21:29:59 +0100594 .udelay = 5, /* ~100 kHz */
Nicolas Ferre789b23b2009-06-26 15:36:58 +0100595};
596
597static struct platform_device at91sam9g45_twi0_device = {
598 .name = "i2c-gpio",
599 .id = 0,
600 .dev.platform_data = &pdata_i2c0,
601};
602
603static struct i2c_gpio_platform_data pdata_i2c1 = {
604 .sda_pin = AT91_PIN_PB10,
605 .sda_is_open_drain = 1,
606 .scl_pin = AT91_PIN_PB11,
607 .scl_is_open_drain = 1,
Peter Korsgaard1d5b4c02010-09-22 21:29:59 +0100608 .udelay = 5, /* ~100 kHz */
Nicolas Ferre789b23b2009-06-26 15:36:58 +0100609};
610
611static struct platform_device at91sam9g45_twi1_device = {
612 .name = "i2c-gpio",
613 .id = 1,
614 .dev.platform_data = &pdata_i2c1,
615};
616
617void __init at91_add_device_i2c(short i2c_id, struct i2c_board_info *devices, int nr_devices)
618{
619 i2c_register_board_info(i2c_id, devices, nr_devices);
620
621 if (i2c_id == 0) {
622 at91_set_GPIO_periph(AT91_PIN_PA20, 1); /* TWD (SDA) */
623 at91_set_multi_drive(AT91_PIN_PA20, 1);
624
625 at91_set_GPIO_periph(AT91_PIN_PA21, 1); /* TWCK (SCL) */
626 at91_set_multi_drive(AT91_PIN_PA21, 1);
627
628 platform_device_register(&at91sam9g45_twi0_device);
629 } else {
630 at91_set_GPIO_periph(AT91_PIN_PB10, 1); /* TWD (SDA) */
631 at91_set_multi_drive(AT91_PIN_PB10, 1);
632
633 at91_set_GPIO_periph(AT91_PIN_PB11, 1); /* TWCK (SCL) */
634 at91_set_multi_drive(AT91_PIN_PB11, 1);
635
636 platform_device_register(&at91sam9g45_twi1_device);
637 }
638}
639
640#elif defined(CONFIG_I2C_AT91) || defined(CONFIG_I2C_AT91_MODULE)
641static struct resource twi0_resources[] = {
642 [0] = {
643 .start = AT91SAM9G45_BASE_TWI0,
644 .end = AT91SAM9G45_BASE_TWI0 + SZ_16K - 1,
645 .flags = IORESOURCE_MEM,
646 },
647 [1] = {
648 .start = AT91SAM9G45_ID_TWI0,
649 .end = AT91SAM9G45_ID_TWI0,
650 .flags = IORESOURCE_IRQ,
651 },
652};
653
654static struct platform_device at91sam9g45_twi0_device = {
655 .name = "at91_i2c",
656 .id = 0,
657 .resource = twi0_resources,
658 .num_resources = ARRAY_SIZE(twi0_resources),
659};
660
661static struct resource twi1_resources[] = {
662 [0] = {
663 .start = AT91SAM9G45_BASE_TWI1,
664 .end = AT91SAM9G45_BASE_TWI1 + SZ_16K - 1,
665 .flags = IORESOURCE_MEM,
666 },
667 [1] = {
668 .start = AT91SAM9G45_ID_TWI1,
669 .end = AT91SAM9G45_ID_TWI1,
670 .flags = IORESOURCE_IRQ,
671 },
672};
673
674static struct platform_device at91sam9g45_twi1_device = {
675 .name = "at91_i2c",
676 .id = 1,
677 .resource = twi1_resources,
678 .num_resources = ARRAY_SIZE(twi1_resources),
679};
680
681void __init at91_add_device_i2c(short i2c_id, struct i2c_board_info *devices, int nr_devices)
682{
683 i2c_register_board_info(i2c_id, devices, nr_devices);
684
685 /* pins used for TWI interface */
686 if (i2c_id == 0) {
687 at91_set_A_periph(AT91_PIN_PA20, 0); /* TWD */
688 at91_set_multi_drive(AT91_PIN_PA20, 1);
689
690 at91_set_A_periph(AT91_PIN_PA21, 0); /* TWCK */
691 at91_set_multi_drive(AT91_PIN_PA21, 1);
692
693 platform_device_register(&at91sam9g45_twi0_device);
694 } else {
695 at91_set_A_periph(AT91_PIN_PB10, 0); /* TWD */
696 at91_set_multi_drive(AT91_PIN_PB10, 1);
697
698 at91_set_A_periph(AT91_PIN_PB11, 0); /* TWCK */
699 at91_set_multi_drive(AT91_PIN_PB11, 1);
700
701 platform_device_register(&at91sam9g45_twi1_device);
702 }
703}
704#else
705void __init at91_add_device_i2c(short i2c_id, struct i2c_board_info *devices, int nr_devices) {}
706#endif
707
708
709/* --------------------------------------------------------------------
710 * SPI
711 * -------------------------------------------------------------------- */
712
713#if defined(CONFIG_SPI_ATMEL) || defined(CONFIG_SPI_ATMEL_MODULE)
714static u64 spi_dmamask = DMA_BIT_MASK(32);
715
716static struct resource spi0_resources[] = {
717 [0] = {
718 .start = AT91SAM9G45_BASE_SPI0,
719 .end = AT91SAM9G45_BASE_SPI0 + SZ_16K - 1,
720 .flags = IORESOURCE_MEM,
721 },
722 [1] = {
723 .start = AT91SAM9G45_ID_SPI0,
724 .end = AT91SAM9G45_ID_SPI0,
725 .flags = IORESOURCE_IRQ,
726 },
727};
728
729static struct platform_device at91sam9g45_spi0_device = {
730 .name = "atmel_spi",
731 .id = 0,
732 .dev = {
733 .dma_mask = &spi_dmamask,
734 .coherent_dma_mask = DMA_BIT_MASK(32),
735 },
736 .resource = spi0_resources,
737 .num_resources = ARRAY_SIZE(spi0_resources),
738};
739
740static const unsigned spi0_standard_cs[4] = { AT91_PIN_PB3, AT91_PIN_PB18, AT91_PIN_PB19, AT91_PIN_PD27 };
741
742static struct resource spi1_resources[] = {
743 [0] = {
744 .start = AT91SAM9G45_BASE_SPI1,
745 .end = AT91SAM9G45_BASE_SPI1 + SZ_16K - 1,
746 .flags = IORESOURCE_MEM,
747 },
748 [1] = {
749 .start = AT91SAM9G45_ID_SPI1,
750 .end = AT91SAM9G45_ID_SPI1,
751 .flags = IORESOURCE_IRQ,
752 },
753};
754
755static struct platform_device at91sam9g45_spi1_device = {
756 .name = "atmel_spi",
757 .id = 1,
758 .dev = {
759 .dma_mask = &spi_dmamask,
760 .coherent_dma_mask = DMA_BIT_MASK(32),
761 },
762 .resource = spi1_resources,
763 .num_resources = ARRAY_SIZE(spi1_resources),
764};
765
766static const unsigned spi1_standard_cs[4] = { AT91_PIN_PB17, AT91_PIN_PD28, AT91_PIN_PD18, AT91_PIN_PD19 };
767
768void __init at91_add_device_spi(struct spi_board_info *devices, int nr_devices)
769{
770 int i;
771 unsigned long cs_pin;
772 short enable_spi0 = 0;
773 short enable_spi1 = 0;
774
775 /* Choose SPI chip-selects */
776 for (i = 0; i < nr_devices; i++) {
777 if (devices[i].controller_data)
778 cs_pin = (unsigned long) devices[i].controller_data;
779 else if (devices[i].bus_num == 0)
780 cs_pin = spi0_standard_cs[devices[i].chip_select];
781 else
782 cs_pin = spi1_standard_cs[devices[i].chip_select];
783
784 if (devices[i].bus_num == 0)
785 enable_spi0 = 1;
786 else
787 enable_spi1 = 1;
788
789 /* enable chip-select pin */
790 at91_set_gpio_output(cs_pin, 1);
791
792 /* pass chip-select pin to driver */
793 devices[i].controller_data = (void *) cs_pin;
794 }
795
796 spi_register_board_info(devices, nr_devices);
797
798 /* Configure SPI bus(es) */
799 if (enable_spi0) {
800 at91_set_A_periph(AT91_PIN_PB0, 0); /* SPI0_MISO */
801 at91_set_A_periph(AT91_PIN_PB1, 0); /* SPI0_MOSI */
802 at91_set_A_periph(AT91_PIN_PB2, 0); /* SPI0_SPCK */
803
Nicolas Ferre789b23b2009-06-26 15:36:58 +0100804 platform_device_register(&at91sam9g45_spi0_device);
805 }
806 if (enable_spi1) {
807 at91_set_A_periph(AT91_PIN_PB14, 0); /* SPI1_MISO */
808 at91_set_A_periph(AT91_PIN_PB15, 0); /* SPI1_MOSI */
809 at91_set_A_periph(AT91_PIN_PB16, 0); /* SPI1_SPCK */
810
Nicolas Ferre789b23b2009-06-26 15:36:58 +0100811 platform_device_register(&at91sam9g45_spi1_device);
812 }
813}
814#else
815void __init at91_add_device_spi(struct spi_board_info *devices, int nr_devices) {}
816#endif
817
818
819/* --------------------------------------------------------------------
Nicolas Ferre378ac652009-09-18 16:14:22 +0100820 * AC97
821 * -------------------------------------------------------------------- */
822
823#if defined(CONFIG_SND_ATMEL_AC97C) || defined(CONFIG_SND_ATMEL_AC97C_MODULE)
824static u64 ac97_dmamask = DMA_BIT_MASK(32);
825static struct ac97c_platform_data ac97_data;
826
827static struct resource ac97_resources[] = {
828 [0] = {
829 .start = AT91SAM9G45_BASE_AC97C,
830 .end = AT91SAM9G45_BASE_AC97C + SZ_16K - 1,
831 .flags = IORESOURCE_MEM,
832 },
833 [1] = {
834 .start = AT91SAM9G45_ID_AC97C,
835 .end = AT91SAM9G45_ID_AC97C,
836 .flags = IORESOURCE_IRQ,
837 },
838};
839
840static struct platform_device at91sam9g45_ac97_device = {
841 .name = "atmel_ac97c",
842 .id = 0,
843 .dev = {
844 .dma_mask = &ac97_dmamask,
845 .coherent_dma_mask = DMA_BIT_MASK(32),
846 .platform_data = &ac97_data,
847 },
848 .resource = ac97_resources,
849 .num_resources = ARRAY_SIZE(ac97_resources),
850};
851
852void __init at91_add_device_ac97(struct ac97c_platform_data *data)
853{
854 if (!data)
855 return;
856
857 at91_set_A_periph(AT91_PIN_PD8, 0); /* AC97FS */
858 at91_set_A_periph(AT91_PIN_PD9, 0); /* AC97CK */
859 at91_set_A_periph(AT91_PIN_PD7, 0); /* AC97TX */
860 at91_set_A_periph(AT91_PIN_PD6, 0); /* AC97RX */
861
862 /* reset */
Jean-Christophe PLAGNIOL-VILLARDcc9f9ae2011-09-19 15:28:25 +0800863 if (gpio_is_valid(data->reset_pin))
Nicolas Ferre378ac652009-09-18 16:14:22 +0100864 at91_set_gpio_output(data->reset_pin, 0);
865
866 ac97_data = *data;
867 platform_device_register(&at91sam9g45_ac97_device);
868}
869#else
870void __init at91_add_device_ac97(struct ac97c_platform_data *data) {}
871#endif
872
873
874/* --------------------------------------------------------------------
Nicolas Ferre789b23b2009-06-26 15:36:58 +0100875 * LCD Controller
876 * -------------------------------------------------------------------- */
877
878#if defined(CONFIG_FB_ATMEL) || defined(CONFIG_FB_ATMEL_MODULE)
879static u64 lcdc_dmamask = DMA_BIT_MASK(32);
880static struct atmel_lcdfb_info lcdc_data;
881
882static struct resource lcdc_resources[] = {
883 [0] = {
884 .start = AT91SAM9G45_LCDC_BASE,
885 .end = AT91SAM9G45_LCDC_BASE + SZ_4K - 1,
886 .flags = IORESOURCE_MEM,
887 },
888 [1] = {
889 .start = AT91SAM9G45_ID_LCDC,
890 .end = AT91SAM9G45_ID_LCDC,
891 .flags = IORESOURCE_IRQ,
892 },
893};
894
895static struct platform_device at91_lcdc_device = {
896 .name = "atmel_lcdfb",
897 .id = 0,
898 .dev = {
899 .dma_mask = &lcdc_dmamask,
900 .coherent_dma_mask = DMA_BIT_MASK(32),
901 .platform_data = &lcdc_data,
902 },
903 .resource = lcdc_resources,
904 .num_resources = ARRAY_SIZE(lcdc_resources),
905};
906
907void __init at91_add_device_lcdc(struct atmel_lcdfb_info *data)
908{
909 if (!data)
910 return;
911
912 at91_set_A_periph(AT91_PIN_PE0, 0); /* LCDDPWR */
913
914 at91_set_A_periph(AT91_PIN_PE2, 0); /* LCDCC */
915 at91_set_A_periph(AT91_PIN_PE3, 0); /* LCDVSYNC */
916 at91_set_A_periph(AT91_PIN_PE4, 0); /* LCDHSYNC */
917 at91_set_A_periph(AT91_PIN_PE5, 0); /* LCDDOTCK */
918 at91_set_A_periph(AT91_PIN_PE6, 0); /* LCDDEN */
919 at91_set_A_periph(AT91_PIN_PE7, 0); /* LCDD0 */
920 at91_set_A_periph(AT91_PIN_PE8, 0); /* LCDD1 */
921 at91_set_A_periph(AT91_PIN_PE9, 0); /* LCDD2 */
922 at91_set_A_periph(AT91_PIN_PE10, 0); /* LCDD3 */
923 at91_set_A_periph(AT91_PIN_PE11, 0); /* LCDD4 */
924 at91_set_A_periph(AT91_PIN_PE12, 0); /* LCDD5 */
925 at91_set_A_periph(AT91_PIN_PE13, 0); /* LCDD6 */
926 at91_set_A_periph(AT91_PIN_PE14, 0); /* LCDD7 */
927 at91_set_A_periph(AT91_PIN_PE15, 0); /* LCDD8 */
928 at91_set_A_periph(AT91_PIN_PE16, 0); /* LCDD9 */
929 at91_set_A_periph(AT91_PIN_PE17, 0); /* LCDD10 */
930 at91_set_A_periph(AT91_PIN_PE18, 0); /* LCDD11 */
931 at91_set_A_periph(AT91_PIN_PE19, 0); /* LCDD12 */
932 at91_set_A_periph(AT91_PIN_PE20, 0); /* LCDD13 */
933 at91_set_A_periph(AT91_PIN_PE21, 0); /* LCDD14 */
934 at91_set_A_periph(AT91_PIN_PE22, 0); /* LCDD15 */
935 at91_set_A_periph(AT91_PIN_PE23, 0); /* LCDD16 */
936 at91_set_A_periph(AT91_PIN_PE24, 0); /* LCDD17 */
937 at91_set_A_periph(AT91_PIN_PE25, 0); /* LCDD18 */
938 at91_set_A_periph(AT91_PIN_PE26, 0); /* LCDD19 */
939 at91_set_A_periph(AT91_PIN_PE27, 0); /* LCDD20 */
940 at91_set_A_periph(AT91_PIN_PE28, 0); /* LCDD21 */
941 at91_set_A_periph(AT91_PIN_PE29, 0); /* LCDD22 */
942 at91_set_A_periph(AT91_PIN_PE30, 0); /* LCDD23 */
943
944 lcdc_data = *data;
945 platform_device_register(&at91_lcdc_device);
946}
947#else
948void __init at91_add_device_lcdc(struct atmel_lcdfb_info *data) {}
949#endif
950
951
952/* --------------------------------------------------------------------
953 * Timer/Counter block
954 * -------------------------------------------------------------------- */
955
956#ifdef CONFIG_ATMEL_TCLIB
957static struct resource tcb0_resources[] = {
958 [0] = {
959 .start = AT91SAM9G45_BASE_TCB0,
960 .end = AT91SAM9G45_BASE_TCB0 + SZ_16K - 1,
961 .flags = IORESOURCE_MEM,
962 },
963 [1] = {
964 .start = AT91SAM9G45_ID_TCB,
965 .end = AT91SAM9G45_ID_TCB,
966 .flags = IORESOURCE_IRQ,
967 },
968};
969
970static struct platform_device at91sam9g45_tcb0_device = {
971 .name = "atmel_tcb",
972 .id = 0,
973 .resource = tcb0_resources,
974 .num_resources = ARRAY_SIZE(tcb0_resources),
975};
976
977/* TCB1 begins with TC3 */
978static struct resource tcb1_resources[] = {
979 [0] = {
980 .start = AT91SAM9G45_BASE_TCB1,
981 .end = AT91SAM9G45_BASE_TCB1 + SZ_16K - 1,
982 .flags = IORESOURCE_MEM,
983 },
984 [1] = {
985 .start = AT91SAM9G45_ID_TCB,
986 .end = AT91SAM9G45_ID_TCB,
987 .flags = IORESOURCE_IRQ,
988 },
989};
990
991static struct platform_device at91sam9g45_tcb1_device = {
992 .name = "atmel_tcb",
993 .id = 1,
994 .resource = tcb1_resources,
995 .num_resources = ARRAY_SIZE(tcb1_resources),
996};
997
998static void __init at91_add_device_tc(void)
999{
Nicolas Ferre789b23b2009-06-26 15:36:58 +01001000 platform_device_register(&at91sam9g45_tcb0_device);
Nicolas Ferre789b23b2009-06-26 15:36:58 +01001001 platform_device_register(&at91sam9g45_tcb1_device);
1002}
1003#else
1004static void __init at91_add_device_tc(void) { }
1005#endif
1006
1007
1008/* --------------------------------------------------------------------
1009 * RTC
1010 * -------------------------------------------------------------------- */
1011
1012#if defined(CONFIG_RTC_DRV_AT91RM9200) || defined(CONFIG_RTC_DRV_AT91RM9200_MODULE)
Jean-Christophe PLAGNIOL-VILLARDd28bdfc2011-11-14 14:24:53 +08001013static struct resource rtc_resources[] = {
1014 [0] = {
1015 .start = AT91SAM9G45_BASE_RTC,
1016 .end = AT91SAM9G45_BASE_RTC + SZ_256 - 1,
1017 .flags = IORESOURCE_MEM,
1018 },
1019 [1] = {
1020 .start = AT91_ID_SYS,
1021 .end = AT91_ID_SYS,
1022 .flags = IORESOURCE_IRQ,
1023 },
1024};
1025
Nicolas Ferre789b23b2009-06-26 15:36:58 +01001026static struct platform_device at91sam9g45_rtc_device = {
1027 .name = "at91_rtc",
1028 .id = -1,
Jean-Christophe PLAGNIOL-VILLARDd28bdfc2011-11-14 14:24:53 +08001029 .resource = rtc_resources,
1030 .num_resources = ARRAY_SIZE(rtc_resources),
Nicolas Ferre789b23b2009-06-26 15:36:58 +01001031};
1032
1033static void __init at91_add_device_rtc(void)
1034{
1035 platform_device_register(&at91sam9g45_rtc_device);
1036}
1037#else
1038static void __init at91_add_device_rtc(void) {}
1039#endif
1040
1041
1042/* --------------------------------------------------------------------
Nicolas Ferre985f37f2009-11-19 09:32:52 -08001043 * Touchscreen
1044 * -------------------------------------------------------------------- */
1045
1046#if defined(CONFIG_TOUCHSCREEN_ATMEL_TSADCC) || defined(CONFIG_TOUCHSCREEN_ATMEL_TSADCC_MODULE)
1047static u64 tsadcc_dmamask = DMA_BIT_MASK(32);
1048static struct at91_tsadcc_data tsadcc_data;
1049
1050static struct resource tsadcc_resources[] = {
1051 [0] = {
1052 .start = AT91SAM9G45_BASE_TSC,
1053 .end = AT91SAM9G45_BASE_TSC + SZ_16K - 1,
1054 .flags = IORESOURCE_MEM,
1055 },
1056 [1] = {
1057 .start = AT91SAM9G45_ID_TSC,
1058 .end = AT91SAM9G45_ID_TSC,
1059 .flags = IORESOURCE_IRQ,
1060 }
1061};
1062
1063static struct platform_device at91sam9g45_tsadcc_device = {
1064 .name = "atmel_tsadcc",
1065 .id = -1,
1066 .dev = {
1067 .dma_mask = &tsadcc_dmamask,
1068 .coherent_dma_mask = DMA_BIT_MASK(32),
1069 .platform_data = &tsadcc_data,
1070 },
1071 .resource = tsadcc_resources,
1072 .num_resources = ARRAY_SIZE(tsadcc_resources),
1073};
1074
1075void __init at91_add_device_tsadcc(struct at91_tsadcc_data *data)
1076{
1077 if (!data)
1078 return;
1079
1080 at91_set_gpio_input(AT91_PIN_PD20, 0); /* AD0_XR */
1081 at91_set_gpio_input(AT91_PIN_PD21, 0); /* AD1_XL */
1082 at91_set_gpio_input(AT91_PIN_PD22, 0); /* AD2_YT */
1083 at91_set_gpio_input(AT91_PIN_PD23, 0); /* AD3_TB */
1084
1085 tsadcc_data = *data;
1086 platform_device_register(&at91sam9g45_tsadcc_device);
1087}
1088#else
1089void __init at91_add_device_tsadcc(struct at91_tsadcc_data *data) {}
1090#endif
1091
1092
1093/* --------------------------------------------------------------------
Nicolas Ferre789b23b2009-06-26 15:36:58 +01001094 * RTT
1095 * -------------------------------------------------------------------- */
1096
1097static struct resource rtt_resources[] = {
1098 {
Jean-Christophe PLAGNIOL-VILLARDeab5fd62011-09-18 10:12:00 +08001099 .start = AT91SAM9G45_BASE_RTT,
1100 .end = AT91SAM9G45_BASE_RTT + SZ_16 - 1,
Nicolas Ferre789b23b2009-06-26 15:36:58 +01001101 .flags = IORESOURCE_MEM,
1102 }
1103};
1104
1105static struct platform_device at91sam9g45_rtt_device = {
1106 .name = "at91_rtt",
1107 .id = 0,
1108 .resource = rtt_resources,
1109 .num_resources = ARRAY_SIZE(rtt_resources),
1110};
1111
1112static void __init at91_add_device_rtt(void)
1113{
1114 platform_device_register(&at91sam9g45_rtt_device);
1115}
1116
1117
1118/* --------------------------------------------------------------------
Peter Korsgaard237a62a2011-10-06 17:41:33 +02001119 * TRNG
1120 * -------------------------------------------------------------------- */
1121
1122#if defined(CONFIG_HW_RANDOM_ATMEL) || defined(CONFIG_HW_RANDOM_ATMEL_MODULE)
1123static struct resource trng_resources[] = {
1124 {
1125 .start = AT91SAM9G45_BASE_TRNG,
1126 .end = AT91SAM9G45_BASE_TRNG + SZ_16K - 1,
1127 .flags = IORESOURCE_MEM,
1128 },
1129};
1130
1131static struct platform_device at91sam9g45_trng_device = {
1132 .name = "atmel-trng",
1133 .id = -1,
1134 .resource = trng_resources,
1135 .num_resources = ARRAY_SIZE(trng_resources),
1136};
1137
1138static void __init at91_add_device_trng(void)
1139{
1140 platform_device_register(&at91sam9g45_trng_device);
1141}
1142#else
1143static void __init at91_add_device_trng(void) {}
1144#endif
1145
1146/* --------------------------------------------------------------------
Nicolas Ferre789b23b2009-06-26 15:36:58 +01001147 * Watchdog
1148 * -------------------------------------------------------------------- */
1149
Yegor Yefremov47263742009-10-20 08:39:41 +01001150#if defined(CONFIG_AT91SAM9X_WATCHDOG) || defined(CONFIG_AT91SAM9X_WATCHDOG_MODULE)
Jean-Christophe PLAGNIOL-VILLARDc1c30a22011-11-02 01:43:31 +08001151static struct resource wdt_resources[] = {
1152 {
1153 .start = AT91SAM9G45_BASE_WDT,
1154 .end = AT91SAM9G45_BASE_WDT + SZ_16 - 1,
1155 .flags = IORESOURCE_MEM,
1156 }
1157};
1158
Nicolas Ferre789b23b2009-06-26 15:36:58 +01001159static struct platform_device at91sam9g45_wdt_device = {
1160 .name = "at91_wdt",
1161 .id = -1,
Jean-Christophe PLAGNIOL-VILLARDc1c30a22011-11-02 01:43:31 +08001162 .resource = wdt_resources,
1163 .num_resources = ARRAY_SIZE(wdt_resources),
Nicolas Ferre789b23b2009-06-26 15:36:58 +01001164};
1165
1166static void __init at91_add_device_watchdog(void)
1167{
1168 platform_device_register(&at91sam9g45_wdt_device);
1169}
1170#else
1171static void __init at91_add_device_watchdog(void) {}
1172#endif
1173
1174
1175/* --------------------------------------------------------------------
1176 * PWM
1177 * --------------------------------------------------------------------*/
1178
1179#if defined(CONFIG_ATMEL_PWM) || defined(CONFIG_ATMEL_PWM_MODULE)
1180static u32 pwm_mask;
1181
1182static struct resource pwm_resources[] = {
1183 [0] = {
1184 .start = AT91SAM9G45_BASE_PWMC,
1185 .end = AT91SAM9G45_BASE_PWMC + SZ_16K - 1,
1186 .flags = IORESOURCE_MEM,
1187 },
1188 [1] = {
1189 .start = AT91SAM9G45_ID_PWMC,
1190 .end = AT91SAM9G45_ID_PWMC,
1191 .flags = IORESOURCE_IRQ,
1192 },
1193};
1194
1195static struct platform_device at91sam9g45_pwm0_device = {
1196 .name = "atmel_pwm",
1197 .id = -1,
1198 .dev = {
1199 .platform_data = &pwm_mask,
1200 },
1201 .resource = pwm_resources,
1202 .num_resources = ARRAY_SIZE(pwm_resources),
1203};
1204
1205void __init at91_add_device_pwm(u32 mask)
1206{
1207 if (mask & (1 << AT91_PWM0))
1208 at91_set_B_periph(AT91_PIN_PD24, 1); /* enable PWM0 */
1209
1210 if (mask & (1 << AT91_PWM1))
1211 at91_set_B_periph(AT91_PIN_PD31, 1); /* enable PWM1 */
1212
1213 if (mask & (1 << AT91_PWM2))
1214 at91_set_B_periph(AT91_PIN_PD26, 1); /* enable PWM2 */
1215
1216 if (mask & (1 << AT91_PWM3))
1217 at91_set_B_periph(AT91_PIN_PD0, 1); /* enable PWM3 */
1218
1219 pwm_mask = mask;
1220
1221 platform_device_register(&at91sam9g45_pwm0_device);
1222}
1223#else
1224void __init at91_add_device_pwm(u32 mask) {}
1225#endif
1226
1227
1228/* --------------------------------------------------------------------
1229 * SSC -- Synchronous Serial Controller
1230 * -------------------------------------------------------------------- */
1231
1232#if defined(CONFIG_ATMEL_SSC) || defined(CONFIG_ATMEL_SSC_MODULE)
1233static u64 ssc0_dmamask = DMA_BIT_MASK(32);
1234
1235static struct resource ssc0_resources[] = {
1236 [0] = {
1237 .start = AT91SAM9G45_BASE_SSC0,
1238 .end = AT91SAM9G45_BASE_SSC0 + SZ_16K - 1,
1239 .flags = IORESOURCE_MEM,
1240 },
1241 [1] = {
1242 .start = AT91SAM9G45_ID_SSC0,
1243 .end = AT91SAM9G45_ID_SSC0,
1244 .flags = IORESOURCE_IRQ,
1245 },
1246};
1247
1248static struct platform_device at91sam9g45_ssc0_device = {
1249 .name = "ssc",
1250 .id = 0,
1251 .dev = {
1252 .dma_mask = &ssc0_dmamask,
1253 .coherent_dma_mask = DMA_BIT_MASK(32),
1254 },
1255 .resource = ssc0_resources,
1256 .num_resources = ARRAY_SIZE(ssc0_resources),
1257};
1258
1259static inline void configure_ssc0_pins(unsigned pins)
1260{
1261 if (pins & ATMEL_SSC_TF)
1262 at91_set_A_periph(AT91_PIN_PD1, 1);
1263 if (pins & ATMEL_SSC_TK)
1264 at91_set_A_periph(AT91_PIN_PD0, 1);
1265 if (pins & ATMEL_SSC_TD)
1266 at91_set_A_periph(AT91_PIN_PD2, 1);
1267 if (pins & ATMEL_SSC_RD)
1268 at91_set_A_periph(AT91_PIN_PD3, 1);
1269 if (pins & ATMEL_SSC_RK)
1270 at91_set_A_periph(AT91_PIN_PD4, 1);
1271 if (pins & ATMEL_SSC_RF)
1272 at91_set_A_periph(AT91_PIN_PD5, 1);
1273}
1274
1275static u64 ssc1_dmamask = DMA_BIT_MASK(32);
1276
1277static struct resource ssc1_resources[] = {
1278 [0] = {
1279 .start = AT91SAM9G45_BASE_SSC1,
1280 .end = AT91SAM9G45_BASE_SSC1 + SZ_16K - 1,
1281 .flags = IORESOURCE_MEM,
1282 },
1283 [1] = {
1284 .start = AT91SAM9G45_ID_SSC1,
1285 .end = AT91SAM9G45_ID_SSC1,
1286 .flags = IORESOURCE_IRQ,
1287 },
1288};
1289
1290static struct platform_device at91sam9g45_ssc1_device = {
1291 .name = "ssc",
1292 .id = 1,
1293 .dev = {
1294 .dma_mask = &ssc1_dmamask,
1295 .coherent_dma_mask = DMA_BIT_MASK(32),
1296 },
1297 .resource = ssc1_resources,
1298 .num_resources = ARRAY_SIZE(ssc1_resources),
1299};
1300
1301static inline void configure_ssc1_pins(unsigned pins)
1302{
1303 if (pins & ATMEL_SSC_TF)
1304 at91_set_A_periph(AT91_PIN_PD14, 1);
1305 if (pins & ATMEL_SSC_TK)
1306 at91_set_A_periph(AT91_PIN_PD12, 1);
1307 if (pins & ATMEL_SSC_TD)
1308 at91_set_A_periph(AT91_PIN_PD10, 1);
1309 if (pins & ATMEL_SSC_RD)
1310 at91_set_A_periph(AT91_PIN_PD11, 1);
1311 if (pins & ATMEL_SSC_RK)
1312 at91_set_A_periph(AT91_PIN_PD13, 1);
1313 if (pins & ATMEL_SSC_RF)
1314 at91_set_A_periph(AT91_PIN_PD15, 1);
1315}
1316
1317/*
1318 * SSC controllers are accessed through library code, instead of any
1319 * kind of all-singing/all-dancing driver. For example one could be
1320 * used by a particular I2S audio codec's driver, while another one
1321 * on the same system might be used by a custom data capture driver.
1322 */
1323void __init at91_add_device_ssc(unsigned id, unsigned pins)
1324{
1325 struct platform_device *pdev;
1326
1327 /*
1328 * NOTE: caller is responsible for passing information matching
1329 * "pins" to whatever will be using each particular controller.
1330 */
1331 switch (id) {
1332 case AT91SAM9G45_ID_SSC0:
1333 pdev = &at91sam9g45_ssc0_device;
1334 configure_ssc0_pins(pins);
Nicolas Ferre789b23b2009-06-26 15:36:58 +01001335 break;
1336 case AT91SAM9G45_ID_SSC1:
1337 pdev = &at91sam9g45_ssc1_device;
1338 configure_ssc1_pins(pins);
Nicolas Ferre789b23b2009-06-26 15:36:58 +01001339 break;
1340 default:
1341 return;
1342 }
1343
1344 platform_device_register(pdev);
1345}
1346
1347#else
1348void __init at91_add_device_ssc(unsigned id, unsigned pins) {}
1349#endif
1350
1351
1352/* --------------------------------------------------------------------
1353 * UART
1354 * -------------------------------------------------------------------- */
1355
1356#if defined(CONFIG_SERIAL_ATMEL)
1357static struct resource dbgu_resources[] = {
1358 [0] = {
Jean-Christophe PLAGNIOL-VILLARD13079a72011-11-02 01:43:31 +08001359 .start = AT91SAM9G45_BASE_DBGU,
1360 .end = AT91SAM9G45_BASE_DBGU + SZ_512 - 1,
Nicolas Ferre789b23b2009-06-26 15:36:58 +01001361 .flags = IORESOURCE_MEM,
1362 },
1363 [1] = {
1364 .start = AT91_ID_SYS,
1365 .end = AT91_ID_SYS,
1366 .flags = IORESOURCE_IRQ,
1367 },
1368};
1369
1370static struct atmel_uart_data dbgu_data = {
1371 .use_dma_tx = 0,
1372 .use_dma_rx = 0,
Nicolas Ferre789b23b2009-06-26 15:36:58 +01001373};
1374
1375static u64 dbgu_dmamask = DMA_BIT_MASK(32);
1376
1377static struct platform_device at91sam9g45_dbgu_device = {
1378 .name = "atmel_usart",
1379 .id = 0,
1380 .dev = {
1381 .dma_mask = &dbgu_dmamask,
1382 .coherent_dma_mask = DMA_BIT_MASK(32),
1383 .platform_data = &dbgu_data,
1384 },
1385 .resource = dbgu_resources,
1386 .num_resources = ARRAY_SIZE(dbgu_resources),
1387};
1388
1389static inline void configure_dbgu_pins(void)
1390{
1391 at91_set_A_periph(AT91_PIN_PB12, 0); /* DRXD */
1392 at91_set_A_periph(AT91_PIN_PB13, 1); /* DTXD */
1393}
1394
1395static struct resource uart0_resources[] = {
1396 [0] = {
1397 .start = AT91SAM9G45_BASE_US0,
1398 .end = AT91SAM9G45_BASE_US0 + SZ_16K - 1,
1399 .flags = IORESOURCE_MEM,
1400 },
1401 [1] = {
1402 .start = AT91SAM9G45_ID_US0,
1403 .end = AT91SAM9G45_ID_US0,
1404 .flags = IORESOURCE_IRQ,
1405 },
1406};
1407
1408static struct atmel_uart_data uart0_data = {
1409 .use_dma_tx = 1,
1410 .use_dma_rx = 1,
1411};
1412
1413static u64 uart0_dmamask = DMA_BIT_MASK(32);
1414
1415static struct platform_device at91sam9g45_uart0_device = {
1416 .name = "atmel_usart",
1417 .id = 1,
1418 .dev = {
1419 .dma_mask = &uart0_dmamask,
1420 .coherent_dma_mask = DMA_BIT_MASK(32),
1421 .platform_data = &uart0_data,
1422 },
1423 .resource = uart0_resources,
1424 .num_resources = ARRAY_SIZE(uart0_resources),
1425};
1426
1427static inline void configure_usart0_pins(unsigned pins)
1428{
1429 at91_set_A_periph(AT91_PIN_PB19, 1); /* TXD0 */
1430 at91_set_A_periph(AT91_PIN_PB18, 0); /* RXD0 */
1431
1432 if (pins & ATMEL_UART_RTS)
1433 at91_set_B_periph(AT91_PIN_PB17, 0); /* RTS0 */
1434 if (pins & ATMEL_UART_CTS)
1435 at91_set_B_periph(AT91_PIN_PB15, 0); /* CTS0 */
1436}
1437
1438static struct resource uart1_resources[] = {
1439 [0] = {
1440 .start = AT91SAM9G45_BASE_US1,
1441 .end = AT91SAM9G45_BASE_US1 + SZ_16K - 1,
1442 .flags = IORESOURCE_MEM,
1443 },
1444 [1] = {
1445 .start = AT91SAM9G45_ID_US1,
1446 .end = AT91SAM9G45_ID_US1,
1447 .flags = IORESOURCE_IRQ,
1448 },
1449};
1450
1451static struct atmel_uart_data uart1_data = {
1452 .use_dma_tx = 1,
1453 .use_dma_rx = 1,
1454};
1455
1456static u64 uart1_dmamask = DMA_BIT_MASK(32);
1457
1458static struct platform_device at91sam9g45_uart1_device = {
1459 .name = "atmel_usart",
1460 .id = 2,
1461 .dev = {
1462 .dma_mask = &uart1_dmamask,
1463 .coherent_dma_mask = DMA_BIT_MASK(32),
1464 .platform_data = &uart1_data,
1465 },
1466 .resource = uart1_resources,
1467 .num_resources = ARRAY_SIZE(uart1_resources),
1468};
1469
1470static inline void configure_usart1_pins(unsigned pins)
1471{
1472 at91_set_A_periph(AT91_PIN_PB4, 1); /* TXD1 */
1473 at91_set_A_periph(AT91_PIN_PB5, 0); /* RXD1 */
1474
1475 if (pins & ATMEL_UART_RTS)
1476 at91_set_A_periph(AT91_PIN_PD16, 0); /* RTS1 */
1477 if (pins & ATMEL_UART_CTS)
1478 at91_set_A_periph(AT91_PIN_PD17, 0); /* CTS1 */
1479}
1480
1481static struct resource uart2_resources[] = {
1482 [0] = {
1483 .start = AT91SAM9G45_BASE_US2,
1484 .end = AT91SAM9G45_BASE_US2 + SZ_16K - 1,
1485 .flags = IORESOURCE_MEM,
1486 },
1487 [1] = {
1488 .start = AT91SAM9G45_ID_US2,
1489 .end = AT91SAM9G45_ID_US2,
1490 .flags = IORESOURCE_IRQ,
1491 },
1492};
1493
1494static struct atmel_uart_data uart2_data = {
1495 .use_dma_tx = 1,
1496 .use_dma_rx = 1,
1497};
1498
1499static u64 uart2_dmamask = DMA_BIT_MASK(32);
1500
1501static struct platform_device at91sam9g45_uart2_device = {
1502 .name = "atmel_usart",
1503 .id = 3,
1504 .dev = {
1505 .dma_mask = &uart2_dmamask,
1506 .coherent_dma_mask = DMA_BIT_MASK(32),
1507 .platform_data = &uart2_data,
1508 },
1509 .resource = uart2_resources,
1510 .num_resources = ARRAY_SIZE(uart2_resources),
1511};
1512
1513static inline void configure_usart2_pins(unsigned pins)
1514{
1515 at91_set_A_periph(AT91_PIN_PB6, 1); /* TXD2 */
1516 at91_set_A_periph(AT91_PIN_PB7, 0); /* RXD2 */
1517
1518 if (pins & ATMEL_UART_RTS)
1519 at91_set_B_periph(AT91_PIN_PC9, 0); /* RTS2 */
1520 if (pins & ATMEL_UART_CTS)
1521 at91_set_B_periph(AT91_PIN_PC11, 0); /* CTS2 */
1522}
1523
1524static struct resource uart3_resources[] = {
1525 [0] = {
1526 .start = AT91SAM9G45_BASE_US3,
1527 .end = AT91SAM9G45_BASE_US3 + SZ_16K - 1,
1528 .flags = IORESOURCE_MEM,
1529 },
1530 [1] = {
1531 .start = AT91SAM9G45_ID_US3,
1532 .end = AT91SAM9G45_ID_US3,
1533 .flags = IORESOURCE_IRQ,
1534 },
1535};
1536
1537static struct atmel_uart_data uart3_data = {
1538 .use_dma_tx = 1,
1539 .use_dma_rx = 1,
1540};
1541
1542static u64 uart3_dmamask = DMA_BIT_MASK(32);
1543
1544static struct platform_device at91sam9g45_uart3_device = {
1545 .name = "atmel_usart",
1546 .id = 4,
1547 .dev = {
1548 .dma_mask = &uart3_dmamask,
1549 .coherent_dma_mask = DMA_BIT_MASK(32),
1550 .platform_data = &uart3_data,
1551 },
1552 .resource = uart3_resources,
1553 .num_resources = ARRAY_SIZE(uart3_resources),
1554};
1555
1556static inline void configure_usart3_pins(unsigned pins)
1557{
1558 at91_set_A_periph(AT91_PIN_PB8, 1); /* TXD3 */
1559 at91_set_A_periph(AT91_PIN_PB9, 0); /* RXD3 */
1560
1561 if (pins & ATMEL_UART_RTS)
1562 at91_set_B_periph(AT91_PIN_PA23, 0); /* RTS3 */
1563 if (pins & ATMEL_UART_CTS)
1564 at91_set_B_periph(AT91_PIN_PA24, 0); /* CTS3 */
1565}
1566
1567static struct platform_device *__initdata at91_uarts[ATMEL_MAX_UART]; /* the UARTs to use */
1568struct platform_device *atmel_default_console_device; /* the serial console device */
1569
1570void __init at91_register_uart(unsigned id, unsigned portnr, unsigned pins)
1571{
1572 struct platform_device *pdev;
Jean-Christophe PLAGNIOL-VILLARD2b348e22011-04-10 14:10:05 +08001573 struct atmel_uart_data *pdata;
Nicolas Ferre789b23b2009-06-26 15:36:58 +01001574
1575 switch (id) {
1576 case 0: /* DBGU */
1577 pdev = &at91sam9g45_dbgu_device;
1578 configure_dbgu_pins();
Nicolas Ferre789b23b2009-06-26 15:36:58 +01001579 break;
1580 case AT91SAM9G45_ID_US0:
1581 pdev = &at91sam9g45_uart0_device;
1582 configure_usart0_pins(pins);
Nicolas Ferre789b23b2009-06-26 15:36:58 +01001583 break;
1584 case AT91SAM9G45_ID_US1:
1585 pdev = &at91sam9g45_uart1_device;
1586 configure_usart1_pins(pins);
Nicolas Ferre789b23b2009-06-26 15:36:58 +01001587 break;
1588 case AT91SAM9G45_ID_US2:
1589 pdev = &at91sam9g45_uart2_device;
1590 configure_usart2_pins(pins);
Nicolas Ferre789b23b2009-06-26 15:36:58 +01001591 break;
1592 case AT91SAM9G45_ID_US3:
1593 pdev = &at91sam9g45_uart3_device;
1594 configure_usart3_pins(pins);
Nicolas Ferre789b23b2009-06-26 15:36:58 +01001595 break;
1596 default:
1597 return;
1598 }
Jean-Christophe PLAGNIOL-VILLARD2b348e22011-04-10 14:10:05 +08001599 pdata = pdev->dev.platform_data;
1600 pdata->num = portnr; /* update to mapped ID */
Nicolas Ferre789b23b2009-06-26 15:36:58 +01001601
1602 if (portnr < ATMEL_MAX_UART)
1603 at91_uarts[portnr] = pdev;
1604}
1605
1606void __init at91_set_serial_console(unsigned portnr)
1607{
Jean-Christophe PLAGNIOL-VILLARDbd602992011-02-02 07:27:07 +01001608 if (portnr < ATMEL_MAX_UART) {
Nicolas Ferre789b23b2009-06-26 15:36:58 +01001609 atmel_default_console_device = at91_uarts[portnr];
Jean-Christophe PLAGNIOL-VILLARD5c1f9662011-06-21 11:24:33 +08001610 at91sam9g45_set_console_clock(at91_uarts[portnr]->id);
Jean-Christophe PLAGNIOL-VILLARDbd602992011-02-02 07:27:07 +01001611 }
Nicolas Ferre789b23b2009-06-26 15:36:58 +01001612}
1613
1614void __init at91_add_device_serial(void)
1615{
1616 int i;
1617
1618 for (i = 0; i < ATMEL_MAX_UART; i++) {
1619 if (at91_uarts[i])
1620 platform_device_register(at91_uarts[i]);
1621 }
1622
1623 if (!atmel_default_console_device)
1624 printk(KERN_INFO "AT91: No default serial console defined.\n");
1625}
1626#else
1627void __init at91_register_uart(unsigned id, unsigned portnr, unsigned pins) {}
1628void __init at91_set_serial_console(unsigned portnr) {}
1629void __init at91_add_device_serial(void) {}
1630#endif
1631
1632
1633/* -------------------------------------------------------------------- */
1634/*
1635 * These devices are always present and don't need any board-specific
1636 * setup.
1637 */
1638static int __init at91_add_standard_devices(void)
1639{
Nicolas Ferre40262b22009-07-24 11:43:01 +01001640 at91_add_device_hdmac();
Nicolas Ferre789b23b2009-06-26 15:36:58 +01001641 at91_add_device_rtc();
1642 at91_add_device_rtt();
Peter Korsgaard237a62a2011-10-06 17:41:33 +02001643 at91_add_device_trng();
Nicolas Ferre789b23b2009-06-26 15:36:58 +01001644 at91_add_device_watchdog();
1645 at91_add_device_tc();
1646 return 0;
1647}
1648
1649arch_initcall(at91_add_standard_devices);