blob: 6b008aee1dffad648874e6318e397d7d640e2d31 [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>
Josh Wu343754f2011-10-22 15:17:40 +080017#include <linux/clk.h>
Nicolas Ferre789b23b2009-06-26 15:36:58 +010018#include <linux/platform_device.h>
19#include <linux/i2c-gpio.h>
Nicolas Ferre75305d72010-10-22 18:27:48 +020020#include <linux/atmel-mci.h>
Nicolas Ferre789b23b2009-06-26 15:36:58 +010021
22#include <linux/fb.h>
23#include <video/atmel_lcdc.h>
24
25#include <mach/board.h>
Nicolas Ferre789b23b2009-06-26 15:36:58 +010026#include <mach/at91sam9g45.h>
27#include <mach/at91sam9g45_matrix.h>
Jean-Christophe PLAGNIOL-VILLARD4342d642011-11-27 23:15:50 +080028#include <mach/at91_matrix.h>
Nicolas Ferre789b23b2009-06-26 15:36:58 +010029#include <mach/at91sam9_smc.h>
Nicolas Ferre40262b22009-07-24 11:43:01 +010030#include <mach/at_hdmac.h>
Nicolas Ferre75305d72010-10-22 18:27:48 +020031#include <mach/atmel-mci.h>
Nicolas Ferre789b23b2009-06-26 15:36:58 +010032
Josh Wu343754f2011-10-22 15:17:40 +080033#include <media/atmel-isi.h>
34
Nicolas Ferre789b23b2009-06-26 15:36:58 +010035#include "generic.h"
Josh Wu343754f2011-10-22 15:17:40 +080036#include "clock.h"
Nicolas Ferre789b23b2009-06-26 15:36:58 +010037
38
39/* --------------------------------------------------------------------
Nicolas Ferre40262b22009-07-24 11:43:01 +010040 * HDMAC - AHB DMA Controller
41 * -------------------------------------------------------------------- */
42
43#if defined(CONFIG_AT_HDMAC) || defined(CONFIG_AT_HDMAC_MODULE)
44static u64 hdmac_dmamask = DMA_BIT_MASK(32);
45
Nicolas Ferre40262b22009-07-24 11:43:01 +010046static struct resource hdmac_resources[] = {
47 [0] = {
Jean-Christophe PLAGNIOL-VILLARD9627b202011-10-15 15:47:51 +080048 .start = AT91SAM9G45_BASE_DMA,
49 .end = AT91SAM9G45_BASE_DMA + SZ_512 - 1,
Nicolas Ferre40262b22009-07-24 11:43:01 +010050 .flags = IORESOURCE_MEM,
51 },
Nicolas Ferre8d2602e2010-08-20 16:44:33 +020052 [1] = {
Nicolas Ferre40262b22009-07-24 11:43:01 +010053 .start = AT91SAM9G45_ID_DMA,
54 .end = AT91SAM9G45_ID_DMA,
55 .flags = IORESOURCE_IRQ,
56 },
57};
58
59static struct platform_device at_hdmac_device = {
Nicolas Ferrebdad0b92011-10-10 14:55:17 +020060 .name = "at91sam9g45_dma",
Nicolas Ferre40262b22009-07-24 11:43:01 +010061 .id = -1,
62 .dev = {
63 .dma_mask = &hdmac_dmamask,
64 .coherent_dma_mask = DMA_BIT_MASK(32),
Nicolas Ferre40262b22009-07-24 11:43:01 +010065 },
66 .resource = hdmac_resources,
67 .num_resources = ARRAY_SIZE(hdmac_resources),
68};
69
70void __init at91_add_device_hdmac(void)
71{
Nicolas Ferre2756bf52011-10-10 16:50:43 +020072#if defined(CONFIG_OF)
73 struct device_node *of_node =
74 of_find_node_by_name(NULL, "dma-controller");
75
76 if (of_node)
77 of_node_put(of_node);
78 else
79#endif
80 platform_device_register(&at_hdmac_device);
Nicolas Ferre40262b22009-07-24 11:43:01 +010081}
82#else
83void __init at91_add_device_hdmac(void) {}
84#endif
85
86
87/* --------------------------------------------------------------------
Nicolas Ferre789b23b2009-06-26 15:36:58 +010088 * USB Host (OHCI)
89 * -------------------------------------------------------------------- */
90
91#if defined(CONFIG_USB_OHCI_HCD) || defined(CONFIG_USB_OHCI_HCD_MODULE)
92static u64 ohci_dmamask = DMA_BIT_MASK(32);
93static struct at91_usbh_data usbh_ohci_data;
94
95static struct resource usbh_ohci_resources[] = {
96 [0] = {
97 .start = AT91SAM9G45_OHCI_BASE,
98 .end = AT91SAM9G45_OHCI_BASE + SZ_1M - 1,
99 .flags = IORESOURCE_MEM,
100 },
101 [1] = {
102 .start = AT91SAM9G45_ID_UHPHS,
103 .end = AT91SAM9G45_ID_UHPHS,
104 .flags = IORESOURCE_IRQ,
105 },
106};
107
108static struct platform_device at91_usbh_ohci_device = {
109 .name = "at91_ohci",
110 .id = -1,
111 .dev = {
112 .dma_mask = &ohci_dmamask,
113 .coherent_dma_mask = DMA_BIT_MASK(32),
114 .platform_data = &usbh_ohci_data,
115 },
116 .resource = usbh_ohci_resources,
117 .num_resources = ARRAY_SIZE(usbh_ohci_resources),
118};
119
120void __init at91_add_device_usbh_ohci(struct at91_usbh_data *data)
121{
122 int i;
123
124 if (!data)
125 return;
126
127 /* Enable VBus control for UHP ports */
128 for (i = 0; i < data->ports; i++) {
Jean-Christophe PLAGNIOL-VILLARDcc9f9ae2011-09-19 15:28:25 +0800129 if (gpio_is_valid(data->vbus_pin[i]))
Nicolas Ferrecca03552012-03-28 11:56:28 +0200130 at91_set_gpio_output(data->vbus_pin[i],
131 data->vbus_pin_active_low[i]);
Nicolas Ferre789b23b2009-06-26 15:36:58 +0100132 }
133
Thomas Petazzoni1fcaea72011-07-13 11:29:18 +0200134 /* Enable overcurrent notification */
135 for (i = 0; i < data->ports; i++) {
Nicolas Ferre0c2c1f62012-03-28 11:58:58 +0200136 if (gpio_is_valid(data->overcurrent_pin[i]))
Thomas Petazzoni1fcaea72011-07-13 11:29:18 +0200137 at91_set_gpio_input(data->overcurrent_pin[i], 1);
138 }
139
Nicolas Ferre789b23b2009-06-26 15:36:58 +0100140 usbh_ohci_data = *data;
141 platform_device_register(&at91_usbh_ohci_device);
142}
143#else
144void __init at91_add_device_usbh_ohci(struct at91_usbh_data *data) {}
145#endif
146
147
148/* --------------------------------------------------------------------
Nicolas Ferref51f78c2009-09-25 12:11:32 +0100149 * USB Host HS (EHCI)
150 * Needs an OHCI host for low and full speed management
151 * -------------------------------------------------------------------- */
152
153#if defined(CONFIG_USB_EHCI_HCD) || defined(CONFIG_USB_EHCI_HCD_MODULE)
154static u64 ehci_dmamask = DMA_BIT_MASK(32);
155static struct at91_usbh_data usbh_ehci_data;
156
157static struct resource usbh_ehci_resources[] = {
158 [0] = {
159 .start = AT91SAM9G45_EHCI_BASE,
160 .end = AT91SAM9G45_EHCI_BASE + SZ_1M - 1,
161 .flags = IORESOURCE_MEM,
162 },
163 [1] = {
164 .start = AT91SAM9G45_ID_UHPHS,
165 .end = AT91SAM9G45_ID_UHPHS,
166 .flags = IORESOURCE_IRQ,
167 },
168};
169
170static struct platform_device at91_usbh_ehci_device = {
171 .name = "atmel-ehci",
172 .id = -1,
173 .dev = {
174 .dma_mask = &ehci_dmamask,
175 .coherent_dma_mask = DMA_BIT_MASK(32),
176 .platform_data = &usbh_ehci_data,
177 },
178 .resource = usbh_ehci_resources,
179 .num_resources = ARRAY_SIZE(usbh_ehci_resources),
180};
181
182void __init at91_add_device_usbh_ehci(struct at91_usbh_data *data)
183{
184 int i;
185
186 if (!data)
187 return;
188
189 /* Enable VBus control for UHP ports */
190 for (i = 0; i < data->ports; i++) {
Jean-Christophe PLAGNIOL-VILLARDcc9f9ae2011-09-19 15:28:25 +0800191 if (gpio_is_valid(data->vbus_pin[i]))
Nicolas Ferrecca03552012-03-28 11:56:28 +0200192 at91_set_gpio_output(data->vbus_pin[i],
193 data->vbus_pin_active_low[i]);
Nicolas Ferref51f78c2009-09-25 12:11:32 +0100194 }
195
196 usbh_ehci_data = *data;
Nicolas Ferref51f78c2009-09-25 12:11:32 +0100197 platform_device_register(&at91_usbh_ehci_device);
198}
199#else
200void __init at91_add_device_usbh_ehci(struct at91_usbh_data *data) {}
201#endif
202
203
204/* --------------------------------------------------------------------
Nicolas Ferre789b23b2009-06-26 15:36:58 +0100205 * USB HS Device (Gadget)
206 * -------------------------------------------------------------------- */
207
Jochen Friedrichdd0b3822011-10-25 20:51:06 +0200208#if defined(CONFIG_USB_ATMEL_USBA) || defined(CONFIG_USB_ATMEL_USBA_MODULE)
Nicolas Ferre789b23b2009-06-26 15:36:58 +0100209static struct resource usba_udc_resources[] = {
210 [0] = {
211 .start = AT91SAM9G45_UDPHS_FIFO,
212 .end = AT91SAM9G45_UDPHS_FIFO + SZ_512K - 1,
213 .flags = IORESOURCE_MEM,
214 },
215 [1] = {
216 .start = AT91SAM9G45_BASE_UDPHS,
217 .end = AT91SAM9G45_BASE_UDPHS + SZ_1K - 1,
218 .flags = IORESOURCE_MEM,
219 },
220 [2] = {
221 .start = AT91SAM9G45_ID_UDPHS,
222 .end = AT91SAM9G45_ID_UDPHS,
223 .flags = IORESOURCE_IRQ,
224 },
225};
226
227#define EP(nam, idx, maxpkt, maxbk, dma, isoc) \
228 [idx] = { \
229 .name = nam, \
230 .index = idx, \
231 .fifo_size = maxpkt, \
232 .nr_banks = maxbk, \
233 .can_dma = dma, \
234 .can_isoc = isoc, \
235 }
236
237static struct usba_ep_data usba_udc_ep[] __initdata = {
238 EP("ep0", 0, 64, 1, 0, 0),
239 EP("ep1", 1, 1024, 2, 1, 1),
240 EP("ep2", 2, 1024, 2, 1, 1),
241 EP("ep3", 3, 1024, 3, 1, 0),
242 EP("ep4", 4, 1024, 3, 1, 0),
243 EP("ep5", 5, 1024, 3, 1, 1),
244 EP("ep6", 6, 1024, 3, 1, 1),
245};
246
247#undef EP
248
249/*
250 * pdata doesn't have room for any endpoints, so we need to
251 * append room for the ones we need right after it.
252 */
253static struct {
254 struct usba_platform_data pdata;
255 struct usba_ep_data ep[7];
256} usba_udc_data;
257
258static struct platform_device at91_usba_udc_device = {
259 .name = "atmel_usba_udc",
260 .id = -1,
261 .dev = {
262 .platform_data = &usba_udc_data.pdata,
263 },
264 .resource = usba_udc_resources,
265 .num_resources = ARRAY_SIZE(usba_udc_resources),
266};
267
268void __init at91_add_device_usba(struct usba_platform_data *data)
269{
270 usba_udc_data.pdata.vbus_pin = -EINVAL;
271 usba_udc_data.pdata.num_ep = ARRAY_SIZE(usba_udc_ep);
Justin P. Mattock6eab04a2011-04-08 19:49:08 -0700272 memcpy(usba_udc_data.ep, usba_udc_ep, sizeof(usba_udc_ep));
Nicolas Ferre789b23b2009-06-26 15:36:58 +0100273
Jean-Christophe PLAGNIOL-VILLARDcc9f9ae2011-09-19 15:28:25 +0800274 if (data && gpio_is_valid(data->vbus_pin)) {
Nicolas Ferre789b23b2009-06-26 15:36:58 +0100275 at91_set_gpio_input(data->vbus_pin, 0);
276 at91_set_deglitch(data->vbus_pin, 1);
277 usba_udc_data.pdata.vbus_pin = data->vbus_pin;
278 }
279
280 /* Pullup pin is handled internally by USB device peripheral */
281
Nicolas Ferre789b23b2009-06-26 15:36:58 +0100282 platform_device_register(&at91_usba_udc_device);
283}
284#else
285void __init at91_add_device_usba(struct usba_platform_data *data) {}
286#endif
287
288
289/* --------------------------------------------------------------------
290 * Ethernet
291 * -------------------------------------------------------------------- */
292
293#if defined(CONFIG_MACB) || defined(CONFIG_MACB_MODULE)
294static u64 eth_dmamask = DMA_BIT_MASK(32);
Jamie Iles84e0cdb2011-03-08 20:17:06 +0000295static struct macb_platform_data eth_data;
Nicolas Ferre789b23b2009-06-26 15:36:58 +0100296
297static struct resource eth_resources[] = {
298 [0] = {
299 .start = AT91SAM9G45_BASE_EMAC,
300 .end = AT91SAM9G45_BASE_EMAC + SZ_16K - 1,
301 .flags = IORESOURCE_MEM,
302 },
303 [1] = {
304 .start = AT91SAM9G45_ID_EMAC,
305 .end = AT91SAM9G45_ID_EMAC,
306 .flags = IORESOURCE_IRQ,
307 },
308};
309
310static struct platform_device at91sam9g45_eth_device = {
311 .name = "macb",
312 .id = -1,
313 .dev = {
314 .dma_mask = &eth_dmamask,
315 .coherent_dma_mask = DMA_BIT_MASK(32),
316 .platform_data = &eth_data,
317 },
318 .resource = eth_resources,
319 .num_resources = ARRAY_SIZE(eth_resources),
320};
321
Jamie Iles84e0cdb2011-03-08 20:17:06 +0000322void __init at91_add_device_eth(struct macb_platform_data *data)
Nicolas Ferre789b23b2009-06-26 15:36:58 +0100323{
324 if (!data)
325 return;
326
Jean-Christophe PLAGNIOL-VILLARDcc9f9ae2011-09-19 15:28:25 +0800327 if (gpio_is_valid(data->phy_irq_pin)) {
Nicolas Ferre789b23b2009-06-26 15:36:58 +0100328 at91_set_gpio_input(data->phy_irq_pin, 0);
329 at91_set_deglitch(data->phy_irq_pin, 1);
330 }
331
332 /* Pins used for MII and RMII */
333 at91_set_A_periph(AT91_PIN_PA17, 0); /* ETXCK_EREFCK */
334 at91_set_A_periph(AT91_PIN_PA15, 0); /* ERXDV */
335 at91_set_A_periph(AT91_PIN_PA12, 0); /* ERX0 */
336 at91_set_A_periph(AT91_PIN_PA13, 0); /* ERX1 */
337 at91_set_A_periph(AT91_PIN_PA16, 0); /* ERXER */
338 at91_set_A_periph(AT91_PIN_PA14, 0); /* ETXEN */
339 at91_set_A_periph(AT91_PIN_PA10, 0); /* ETX0 */
340 at91_set_A_periph(AT91_PIN_PA11, 0); /* ETX1 */
341 at91_set_A_periph(AT91_PIN_PA19, 0); /* EMDIO */
342 at91_set_A_periph(AT91_PIN_PA18, 0); /* EMDC */
343
344 if (!data->is_rmii) {
345 at91_set_B_periph(AT91_PIN_PA29, 0); /* ECRS */
346 at91_set_B_periph(AT91_PIN_PA30, 0); /* ECOL */
347 at91_set_B_periph(AT91_PIN_PA8, 0); /* ERX2 */
348 at91_set_B_periph(AT91_PIN_PA9, 0); /* ERX3 */
349 at91_set_B_periph(AT91_PIN_PA28, 0); /* ERXCK */
350 at91_set_B_periph(AT91_PIN_PA6, 0); /* ETX2 */
351 at91_set_B_periph(AT91_PIN_PA7, 0); /* ETX3 */
352 at91_set_B_periph(AT91_PIN_PA27, 0); /* ETXER */
353 }
354
355 eth_data = *data;
356 platform_device_register(&at91sam9g45_eth_device);
357}
358#else
Jamie Iles84e0cdb2011-03-08 20:17:06 +0000359void __init at91_add_device_eth(struct macb_platform_data *data) {}
Nicolas Ferre789b23b2009-06-26 15:36:58 +0100360#endif
361
362
363/* --------------------------------------------------------------------
Nicolas Ferre75305d72010-10-22 18:27:48 +0200364 * MMC / SD
365 * -------------------------------------------------------------------- */
366
367#if defined(CONFIG_MMC_ATMELMCI) || defined(CONFIG_MMC_ATMELMCI_MODULE)
368static u64 mmc_dmamask = DMA_BIT_MASK(32);
369static struct mci_platform_data mmc0_data, mmc1_data;
370
371static struct resource mmc0_resources[] = {
372 [0] = {
373 .start = AT91SAM9G45_BASE_MCI0,
374 .end = AT91SAM9G45_BASE_MCI0 + SZ_16K - 1,
375 .flags = IORESOURCE_MEM,
376 },
377 [1] = {
378 .start = AT91SAM9G45_ID_MCI0,
379 .end = AT91SAM9G45_ID_MCI0,
380 .flags = IORESOURCE_IRQ,
381 },
382};
383
384static struct platform_device at91sam9g45_mmc0_device = {
385 .name = "atmel_mci",
386 .id = 0,
387 .dev = {
388 .dma_mask = &mmc_dmamask,
389 .coherent_dma_mask = DMA_BIT_MASK(32),
390 .platform_data = &mmc0_data,
391 },
392 .resource = mmc0_resources,
393 .num_resources = ARRAY_SIZE(mmc0_resources),
394};
395
396static struct resource mmc1_resources[] = {
397 [0] = {
398 .start = AT91SAM9G45_BASE_MCI1,
399 .end = AT91SAM9G45_BASE_MCI1 + SZ_16K - 1,
400 .flags = IORESOURCE_MEM,
401 },
402 [1] = {
403 .start = AT91SAM9G45_ID_MCI1,
404 .end = AT91SAM9G45_ID_MCI1,
405 .flags = IORESOURCE_IRQ,
406 },
407};
408
409static struct platform_device at91sam9g45_mmc1_device = {
410 .name = "atmel_mci",
411 .id = 1,
412 .dev = {
413 .dma_mask = &mmc_dmamask,
414 .coherent_dma_mask = DMA_BIT_MASK(32),
415 .platform_data = &mmc1_data,
416 },
417 .resource = mmc1_resources,
418 .num_resources = ARRAY_SIZE(mmc1_resources),
419};
420
421/* Consider only one slot : slot 0 */
422void __init at91_add_device_mci(short mmc_id, struct mci_platform_data *data)
423{
424
425 if (!data)
426 return;
427
428 /* Must have at least one usable slot */
429 if (!data->slot[0].bus_width)
430 return;
431
432#if defined(CONFIG_AT_HDMAC) || defined(CONFIG_AT_HDMAC_MODULE)
433 {
434 struct at_dma_slave *atslave;
435 struct mci_dma_data *alt_atslave;
436
437 alt_atslave = kzalloc(sizeof(struct mci_dma_data), GFP_KERNEL);
438 atslave = &alt_atslave->sdata;
439
440 /* DMA slave channel configuration */
441 atslave->dma_dev = &at_hdmac_device.dev;
Nicolas Ferre75305d72010-10-22 18:27:48 +0200442 atslave->cfg = ATC_FIFOCFG_HALFFIFO
443 | ATC_SRC_H2SEL_HW | ATC_DST_H2SEL_HW;
444 atslave->ctrla = ATC_SCSIZE_16 | ATC_DCSIZE_16;
445 if (mmc_id == 0) /* MCI0 */
446 atslave->cfg |= ATC_SRC_PER(AT_DMA_ID_MCI0)
447 | ATC_DST_PER(AT_DMA_ID_MCI0);
448
449 else /* MCI1 */
450 atslave->cfg |= ATC_SRC_PER(AT_DMA_ID_MCI1)
451 | ATC_DST_PER(AT_DMA_ID_MCI1);
452
453 data->dma_slave = alt_atslave;
454 }
455#endif
456
457
458 /* input/irq */
Jean-Christophe PLAGNIOL-VILLARDcc9f9ae2011-09-19 15:28:25 +0800459 if (gpio_is_valid(data->slot[0].detect_pin)) {
Nicolas Ferre75305d72010-10-22 18:27:48 +0200460 at91_set_gpio_input(data->slot[0].detect_pin, 1);
461 at91_set_deglitch(data->slot[0].detect_pin, 1);
462 }
Jean-Christophe PLAGNIOL-VILLARDcc9f9ae2011-09-19 15:28:25 +0800463 if (gpio_is_valid(data->slot[0].wp_pin))
Nicolas Ferre75305d72010-10-22 18:27:48 +0200464 at91_set_gpio_input(data->slot[0].wp_pin, 1);
465
466 if (mmc_id == 0) { /* MCI0 */
467
468 /* CLK */
469 at91_set_A_periph(AT91_PIN_PA0, 0);
470
471 /* CMD */
472 at91_set_A_periph(AT91_PIN_PA1, 1);
473
474 /* DAT0, maybe DAT1..DAT3 and maybe DAT4..DAT7 */
475 at91_set_A_periph(AT91_PIN_PA2, 1);
476 if (data->slot[0].bus_width == 4) {
477 at91_set_A_periph(AT91_PIN_PA3, 1);
478 at91_set_A_periph(AT91_PIN_PA4, 1);
479 at91_set_A_periph(AT91_PIN_PA5, 1);
480 if (data->slot[0].bus_width == 8) {
481 at91_set_A_periph(AT91_PIN_PA6, 1);
482 at91_set_A_periph(AT91_PIN_PA7, 1);
483 at91_set_A_periph(AT91_PIN_PA8, 1);
484 at91_set_A_periph(AT91_PIN_PA9, 1);
485 }
486 }
487
488 mmc0_data = *data;
Nicolas Ferre75305d72010-10-22 18:27:48 +0200489 platform_device_register(&at91sam9g45_mmc0_device);
490
491 } else { /* MCI1 */
492
493 /* CLK */
494 at91_set_A_periph(AT91_PIN_PA31, 0);
495
496 /* CMD */
497 at91_set_A_periph(AT91_PIN_PA22, 1);
498
499 /* DAT0, maybe DAT1..DAT3 and maybe DAT4..DAT7 */
500 at91_set_A_periph(AT91_PIN_PA23, 1);
501 if (data->slot[0].bus_width == 4) {
502 at91_set_A_periph(AT91_PIN_PA24, 1);
503 at91_set_A_periph(AT91_PIN_PA25, 1);
504 at91_set_A_periph(AT91_PIN_PA26, 1);
505 if (data->slot[0].bus_width == 8) {
506 at91_set_A_periph(AT91_PIN_PA27, 1);
507 at91_set_A_periph(AT91_PIN_PA28, 1);
508 at91_set_A_periph(AT91_PIN_PA29, 1);
509 at91_set_A_periph(AT91_PIN_PA30, 1);
510 }
511 }
512
513 mmc1_data = *data;
Nicolas Ferre75305d72010-10-22 18:27:48 +0200514 platform_device_register(&at91sam9g45_mmc1_device);
515
516 }
517}
518#else
519void __init at91_add_device_mci(short mmc_id, struct mci_platform_data *data) {}
520#endif
521
522
523/* --------------------------------------------------------------------
Nicolas Ferre789b23b2009-06-26 15:36:58 +0100524 * NAND / SmartMedia
525 * -------------------------------------------------------------------- */
526
527#if defined(CONFIG_MTD_NAND_ATMEL) || defined(CONFIG_MTD_NAND_ATMEL_MODULE)
528static struct atmel_nand_data nand_data;
529
530#define NAND_BASE AT91_CHIPSELECT_3
531
532static struct resource nand_resources[] = {
533 [0] = {
534 .start = NAND_BASE,
535 .end = NAND_BASE + SZ_256M - 1,
536 .flags = IORESOURCE_MEM,
537 },
538 [1] = {
Jean-Christophe PLAGNIOL-VILLARDd28edd12011-09-18 09:31:56 +0800539 .start = AT91SAM9G45_BASE_ECC,
540 .end = AT91SAM9G45_BASE_ECC + SZ_512 - 1,
Nicolas Ferre789b23b2009-06-26 15:36:58 +0100541 .flags = IORESOURCE_MEM,
542 }
543};
544
545static struct platform_device at91sam9g45_nand_device = {
546 .name = "atmel_nand",
547 .id = -1,
548 .dev = {
549 .platform_data = &nand_data,
550 },
551 .resource = nand_resources,
552 .num_resources = ARRAY_SIZE(nand_resources),
553};
554
555void __init at91_add_device_nand(struct atmel_nand_data *data)
556{
557 unsigned long csa;
558
559 if (!data)
560 return;
561
Jean-Christophe PLAGNIOL-VILLARD4342d642011-11-27 23:15:50 +0800562 csa = at91_matrix_read(AT91_MATRIX_EBICSA);
563 at91_matrix_write(AT91_MATRIX_EBICSA, csa | AT91_MATRIX_EBI_CS3A_SMC_SMARTMEDIA);
Nicolas Ferre789b23b2009-06-26 15:36:58 +0100564
565 /* enable pin */
Jean-Christophe PLAGNIOL-VILLARDcc9f9ae2011-09-19 15:28:25 +0800566 if (gpio_is_valid(data->enable_pin))
Nicolas Ferre789b23b2009-06-26 15:36:58 +0100567 at91_set_gpio_output(data->enable_pin, 1);
568
569 /* ready/busy pin */
Jean-Christophe PLAGNIOL-VILLARDcc9f9ae2011-09-19 15:28:25 +0800570 if (gpio_is_valid(data->rdy_pin))
Nicolas Ferre789b23b2009-06-26 15:36:58 +0100571 at91_set_gpio_input(data->rdy_pin, 1);
572
573 /* card detect pin */
Jean-Christophe PLAGNIOL-VILLARDcc9f9ae2011-09-19 15:28:25 +0800574 if (gpio_is_valid(data->det_pin))
Nicolas Ferre789b23b2009-06-26 15:36:58 +0100575 at91_set_gpio_input(data->det_pin, 1);
576
577 nand_data = *data;
578 platform_device_register(&at91sam9g45_nand_device);
579}
580#else
581void __init at91_add_device_nand(struct atmel_nand_data *data) {}
582#endif
583
584
585/* --------------------------------------------------------------------
586 * TWI (i2c)
587 * -------------------------------------------------------------------- */
588
589/*
590 * Prefer the GPIO code since the TWI controller isn't robust
591 * (gets overruns and underruns under load) and can only issue
592 * repeated STARTs in one scenario (the driver doesn't yet handle them).
593 */
594#if defined(CONFIG_I2C_GPIO) || defined(CONFIG_I2C_GPIO_MODULE)
595static struct i2c_gpio_platform_data pdata_i2c0 = {
596 .sda_pin = AT91_PIN_PA20,
597 .sda_is_open_drain = 1,
598 .scl_pin = AT91_PIN_PA21,
599 .scl_is_open_drain = 1,
Peter Korsgaard1d5b4c02010-09-22 21:29:59 +0100600 .udelay = 5, /* ~100 kHz */
Nicolas Ferre789b23b2009-06-26 15:36:58 +0100601};
602
603static struct platform_device at91sam9g45_twi0_device = {
604 .name = "i2c-gpio",
605 .id = 0,
606 .dev.platform_data = &pdata_i2c0,
607};
608
609static struct i2c_gpio_platform_data pdata_i2c1 = {
610 .sda_pin = AT91_PIN_PB10,
611 .sda_is_open_drain = 1,
612 .scl_pin = AT91_PIN_PB11,
613 .scl_is_open_drain = 1,
Peter Korsgaard1d5b4c02010-09-22 21:29:59 +0100614 .udelay = 5, /* ~100 kHz */
Nicolas Ferre789b23b2009-06-26 15:36:58 +0100615};
616
617static struct platform_device at91sam9g45_twi1_device = {
618 .name = "i2c-gpio",
619 .id = 1,
620 .dev.platform_data = &pdata_i2c1,
621};
622
623void __init at91_add_device_i2c(short i2c_id, struct i2c_board_info *devices, int nr_devices)
624{
625 i2c_register_board_info(i2c_id, devices, nr_devices);
626
627 if (i2c_id == 0) {
628 at91_set_GPIO_periph(AT91_PIN_PA20, 1); /* TWD (SDA) */
629 at91_set_multi_drive(AT91_PIN_PA20, 1);
630
631 at91_set_GPIO_periph(AT91_PIN_PA21, 1); /* TWCK (SCL) */
632 at91_set_multi_drive(AT91_PIN_PA21, 1);
633
634 platform_device_register(&at91sam9g45_twi0_device);
635 } else {
636 at91_set_GPIO_periph(AT91_PIN_PB10, 1); /* TWD (SDA) */
637 at91_set_multi_drive(AT91_PIN_PB10, 1);
638
639 at91_set_GPIO_periph(AT91_PIN_PB11, 1); /* TWCK (SCL) */
640 at91_set_multi_drive(AT91_PIN_PB11, 1);
641
642 platform_device_register(&at91sam9g45_twi1_device);
643 }
644}
645
646#elif defined(CONFIG_I2C_AT91) || defined(CONFIG_I2C_AT91_MODULE)
647static struct resource twi0_resources[] = {
648 [0] = {
649 .start = AT91SAM9G45_BASE_TWI0,
650 .end = AT91SAM9G45_BASE_TWI0 + SZ_16K - 1,
651 .flags = IORESOURCE_MEM,
652 },
653 [1] = {
654 .start = AT91SAM9G45_ID_TWI0,
655 .end = AT91SAM9G45_ID_TWI0,
656 .flags = IORESOURCE_IRQ,
657 },
658};
659
660static struct platform_device at91sam9g45_twi0_device = {
661 .name = "at91_i2c",
662 .id = 0,
663 .resource = twi0_resources,
664 .num_resources = ARRAY_SIZE(twi0_resources),
665};
666
667static struct resource twi1_resources[] = {
668 [0] = {
669 .start = AT91SAM9G45_BASE_TWI1,
670 .end = AT91SAM9G45_BASE_TWI1 + SZ_16K - 1,
671 .flags = IORESOURCE_MEM,
672 },
673 [1] = {
674 .start = AT91SAM9G45_ID_TWI1,
675 .end = AT91SAM9G45_ID_TWI1,
676 .flags = IORESOURCE_IRQ,
677 },
678};
679
680static struct platform_device at91sam9g45_twi1_device = {
681 .name = "at91_i2c",
682 .id = 1,
683 .resource = twi1_resources,
684 .num_resources = ARRAY_SIZE(twi1_resources),
685};
686
687void __init at91_add_device_i2c(short i2c_id, struct i2c_board_info *devices, int nr_devices)
688{
689 i2c_register_board_info(i2c_id, devices, nr_devices);
690
691 /* pins used for TWI interface */
692 if (i2c_id == 0) {
693 at91_set_A_periph(AT91_PIN_PA20, 0); /* TWD */
694 at91_set_multi_drive(AT91_PIN_PA20, 1);
695
696 at91_set_A_periph(AT91_PIN_PA21, 0); /* TWCK */
697 at91_set_multi_drive(AT91_PIN_PA21, 1);
698
699 platform_device_register(&at91sam9g45_twi0_device);
700 } else {
701 at91_set_A_periph(AT91_PIN_PB10, 0); /* TWD */
702 at91_set_multi_drive(AT91_PIN_PB10, 1);
703
704 at91_set_A_periph(AT91_PIN_PB11, 0); /* TWCK */
705 at91_set_multi_drive(AT91_PIN_PB11, 1);
706
707 platform_device_register(&at91sam9g45_twi1_device);
708 }
709}
710#else
711void __init at91_add_device_i2c(short i2c_id, struct i2c_board_info *devices, int nr_devices) {}
712#endif
713
714
715/* --------------------------------------------------------------------
716 * SPI
717 * -------------------------------------------------------------------- */
718
719#if defined(CONFIG_SPI_ATMEL) || defined(CONFIG_SPI_ATMEL_MODULE)
720static u64 spi_dmamask = DMA_BIT_MASK(32);
721
722static struct resource spi0_resources[] = {
723 [0] = {
724 .start = AT91SAM9G45_BASE_SPI0,
725 .end = AT91SAM9G45_BASE_SPI0 + SZ_16K - 1,
726 .flags = IORESOURCE_MEM,
727 },
728 [1] = {
729 .start = AT91SAM9G45_ID_SPI0,
730 .end = AT91SAM9G45_ID_SPI0,
731 .flags = IORESOURCE_IRQ,
732 },
733};
734
735static struct platform_device at91sam9g45_spi0_device = {
736 .name = "atmel_spi",
737 .id = 0,
738 .dev = {
739 .dma_mask = &spi_dmamask,
740 .coherent_dma_mask = DMA_BIT_MASK(32),
741 },
742 .resource = spi0_resources,
743 .num_resources = ARRAY_SIZE(spi0_resources),
744};
745
746static const unsigned spi0_standard_cs[4] = { AT91_PIN_PB3, AT91_PIN_PB18, AT91_PIN_PB19, AT91_PIN_PD27 };
747
748static struct resource spi1_resources[] = {
749 [0] = {
750 .start = AT91SAM9G45_BASE_SPI1,
751 .end = AT91SAM9G45_BASE_SPI1 + SZ_16K - 1,
752 .flags = IORESOURCE_MEM,
753 },
754 [1] = {
755 .start = AT91SAM9G45_ID_SPI1,
756 .end = AT91SAM9G45_ID_SPI1,
757 .flags = IORESOURCE_IRQ,
758 },
759};
760
761static struct platform_device at91sam9g45_spi1_device = {
762 .name = "atmel_spi",
763 .id = 1,
764 .dev = {
765 .dma_mask = &spi_dmamask,
766 .coherent_dma_mask = DMA_BIT_MASK(32),
767 },
768 .resource = spi1_resources,
769 .num_resources = ARRAY_SIZE(spi1_resources),
770};
771
772static const unsigned spi1_standard_cs[4] = { AT91_PIN_PB17, AT91_PIN_PD28, AT91_PIN_PD18, AT91_PIN_PD19 };
773
774void __init at91_add_device_spi(struct spi_board_info *devices, int nr_devices)
775{
776 int i;
777 unsigned long cs_pin;
778 short enable_spi0 = 0;
779 short enable_spi1 = 0;
780
781 /* Choose SPI chip-selects */
782 for (i = 0; i < nr_devices; i++) {
783 if (devices[i].controller_data)
784 cs_pin = (unsigned long) devices[i].controller_data;
785 else if (devices[i].bus_num == 0)
786 cs_pin = spi0_standard_cs[devices[i].chip_select];
787 else
788 cs_pin = spi1_standard_cs[devices[i].chip_select];
789
Nicolas Ferre0c2c1f62012-03-28 11:58:58 +0200790 if (!gpio_is_valid(cs_pin))
791 continue;
792
Nicolas Ferre789b23b2009-06-26 15:36:58 +0100793 if (devices[i].bus_num == 0)
794 enable_spi0 = 1;
795 else
796 enable_spi1 = 1;
797
798 /* enable chip-select pin */
799 at91_set_gpio_output(cs_pin, 1);
800
801 /* pass chip-select pin to driver */
802 devices[i].controller_data = (void *) cs_pin;
803 }
804
805 spi_register_board_info(devices, nr_devices);
806
807 /* Configure SPI bus(es) */
808 if (enable_spi0) {
809 at91_set_A_periph(AT91_PIN_PB0, 0); /* SPI0_MISO */
810 at91_set_A_periph(AT91_PIN_PB1, 0); /* SPI0_MOSI */
811 at91_set_A_periph(AT91_PIN_PB2, 0); /* SPI0_SPCK */
812
Nicolas Ferre789b23b2009-06-26 15:36:58 +0100813 platform_device_register(&at91sam9g45_spi0_device);
814 }
815 if (enable_spi1) {
816 at91_set_A_periph(AT91_PIN_PB14, 0); /* SPI1_MISO */
817 at91_set_A_periph(AT91_PIN_PB15, 0); /* SPI1_MOSI */
818 at91_set_A_periph(AT91_PIN_PB16, 0); /* SPI1_SPCK */
819
Nicolas Ferre789b23b2009-06-26 15:36:58 +0100820 platform_device_register(&at91sam9g45_spi1_device);
821 }
822}
823#else
824void __init at91_add_device_spi(struct spi_board_info *devices, int nr_devices) {}
825#endif
826
827
828/* --------------------------------------------------------------------
Nicolas Ferre378ac652009-09-18 16:14:22 +0100829 * AC97
830 * -------------------------------------------------------------------- */
831
832#if defined(CONFIG_SND_ATMEL_AC97C) || defined(CONFIG_SND_ATMEL_AC97C_MODULE)
833static u64 ac97_dmamask = DMA_BIT_MASK(32);
834static struct ac97c_platform_data ac97_data;
835
836static struct resource ac97_resources[] = {
837 [0] = {
838 .start = AT91SAM9G45_BASE_AC97C,
839 .end = AT91SAM9G45_BASE_AC97C + SZ_16K - 1,
840 .flags = IORESOURCE_MEM,
841 },
842 [1] = {
843 .start = AT91SAM9G45_ID_AC97C,
844 .end = AT91SAM9G45_ID_AC97C,
845 .flags = IORESOURCE_IRQ,
846 },
847};
848
849static struct platform_device at91sam9g45_ac97_device = {
850 .name = "atmel_ac97c",
851 .id = 0,
852 .dev = {
853 .dma_mask = &ac97_dmamask,
854 .coherent_dma_mask = DMA_BIT_MASK(32),
855 .platform_data = &ac97_data,
856 },
857 .resource = ac97_resources,
858 .num_resources = ARRAY_SIZE(ac97_resources),
859};
860
861void __init at91_add_device_ac97(struct ac97c_platform_data *data)
862{
863 if (!data)
864 return;
865
866 at91_set_A_periph(AT91_PIN_PD8, 0); /* AC97FS */
867 at91_set_A_periph(AT91_PIN_PD9, 0); /* AC97CK */
868 at91_set_A_periph(AT91_PIN_PD7, 0); /* AC97TX */
869 at91_set_A_periph(AT91_PIN_PD6, 0); /* AC97RX */
870
871 /* reset */
Jean-Christophe PLAGNIOL-VILLARDcc9f9ae2011-09-19 15:28:25 +0800872 if (gpio_is_valid(data->reset_pin))
Nicolas Ferre378ac652009-09-18 16:14:22 +0100873 at91_set_gpio_output(data->reset_pin, 0);
874
875 ac97_data = *data;
876 platform_device_register(&at91sam9g45_ac97_device);
877}
878#else
879void __init at91_add_device_ac97(struct ac97c_platform_data *data) {}
880#endif
881
Josh Wu343754f2011-10-22 15:17:40 +0800882/* --------------------------------------------------------------------
883 * Image Sensor Interface
884 * -------------------------------------------------------------------- */
885#if defined(CONFIG_VIDEO_ATMEL_ISI) || defined(CONFIG_VIDEO_ATMEL_ISI_MODULE)
886static u64 isi_dmamask = DMA_BIT_MASK(32);
887static struct isi_platform_data isi_data;
888
889struct resource isi_resources[] = {
890 [0] = {
891 .start = AT91SAM9G45_BASE_ISI,
892 .end = AT91SAM9G45_BASE_ISI + SZ_16K - 1,
893 .flags = IORESOURCE_MEM,
894 },
895 [1] = {
896 .start = AT91SAM9G45_ID_ISI,
897 .end = AT91SAM9G45_ID_ISI,
898 .flags = IORESOURCE_IRQ,
899 },
900};
901
902static struct platform_device at91sam9g45_isi_device = {
903 .name = "atmel_isi",
904 .id = 0,
905 .dev = {
906 .dma_mask = &isi_dmamask,
907 .coherent_dma_mask = DMA_BIT_MASK(32),
908 .platform_data = &isi_data,
909 },
910 .resource = isi_resources,
911 .num_resources = ARRAY_SIZE(isi_resources),
912};
913
914static struct clk_lookup isi_mck_lookups[] = {
915 CLKDEV_CON_DEV_ID("isi_mck", "atmel_isi.0", NULL),
916};
917
918void __init at91_add_device_isi(struct isi_platform_data *data,
919 bool use_pck_as_mck)
920{
921 struct clk *pck;
922 struct clk *parent;
923
924 if (!data)
925 return;
926 isi_data = *data;
927
928 at91_set_A_periph(AT91_PIN_PB20, 0); /* ISI_D0 */
929 at91_set_A_periph(AT91_PIN_PB21, 0); /* ISI_D1 */
930 at91_set_A_periph(AT91_PIN_PB22, 0); /* ISI_D2 */
931 at91_set_A_periph(AT91_PIN_PB23, 0); /* ISI_D3 */
932 at91_set_A_periph(AT91_PIN_PB24, 0); /* ISI_D4 */
933 at91_set_A_periph(AT91_PIN_PB25, 0); /* ISI_D5 */
934 at91_set_A_periph(AT91_PIN_PB26, 0); /* ISI_D6 */
935 at91_set_A_periph(AT91_PIN_PB27, 0); /* ISI_D7 */
936 at91_set_A_periph(AT91_PIN_PB28, 0); /* ISI_PCK */
937 at91_set_A_periph(AT91_PIN_PB30, 0); /* ISI_HSYNC */
938 at91_set_A_periph(AT91_PIN_PB29, 0); /* ISI_VSYNC */
939 at91_set_B_periph(AT91_PIN_PB8, 0); /* ISI_PD8 */
940 at91_set_B_periph(AT91_PIN_PB9, 0); /* ISI_PD9 */
941 at91_set_B_periph(AT91_PIN_PB10, 0); /* ISI_PD10 */
942 at91_set_B_periph(AT91_PIN_PB11, 0); /* ISI_PD11 */
943
944 platform_device_register(&at91sam9g45_isi_device);
945
946 if (use_pck_as_mck) {
947 at91_set_B_periph(AT91_PIN_PB31, 0); /* ISI_MCK (PCK1) */
948
949 pck = clk_get(NULL, "pck1");
950 parent = clk_get(NULL, "plla");
951
952 BUG_ON(IS_ERR(pck) || IS_ERR(parent));
953
954 if (clk_set_parent(pck, parent)) {
955 pr_err("Failed to set PCK's parent\n");
956 } else {
957 /* Register PCK as ISI_MCK */
958 isi_mck_lookups[0].clk = pck;
959 clkdev_add_table(isi_mck_lookups,
960 ARRAY_SIZE(isi_mck_lookups));
961 }
962
963 clk_put(pck);
964 clk_put(parent);
965 }
966}
967#else
968void __init at91_add_device_isi(struct isi_platform_data *data,
969 bool use_pck_as_mck) {}
970#endif
971
Nicolas Ferre378ac652009-09-18 16:14:22 +0100972
973/* --------------------------------------------------------------------
Nicolas Ferre789b23b2009-06-26 15:36:58 +0100974 * LCD Controller
975 * -------------------------------------------------------------------- */
976
977#if defined(CONFIG_FB_ATMEL) || defined(CONFIG_FB_ATMEL_MODULE)
978static u64 lcdc_dmamask = DMA_BIT_MASK(32);
979static struct atmel_lcdfb_info lcdc_data;
980
981static struct resource lcdc_resources[] = {
982 [0] = {
983 .start = AT91SAM9G45_LCDC_BASE,
984 .end = AT91SAM9G45_LCDC_BASE + SZ_4K - 1,
985 .flags = IORESOURCE_MEM,
986 },
987 [1] = {
988 .start = AT91SAM9G45_ID_LCDC,
989 .end = AT91SAM9G45_ID_LCDC,
990 .flags = IORESOURCE_IRQ,
991 },
992};
993
994static struct platform_device at91_lcdc_device = {
995 .name = "atmel_lcdfb",
996 .id = 0,
997 .dev = {
998 .dma_mask = &lcdc_dmamask,
999 .coherent_dma_mask = DMA_BIT_MASK(32),
1000 .platform_data = &lcdc_data,
1001 },
1002 .resource = lcdc_resources,
1003 .num_resources = ARRAY_SIZE(lcdc_resources),
1004};
1005
1006void __init at91_add_device_lcdc(struct atmel_lcdfb_info *data)
1007{
1008 if (!data)
1009 return;
1010
1011 at91_set_A_periph(AT91_PIN_PE0, 0); /* LCDDPWR */
1012
1013 at91_set_A_periph(AT91_PIN_PE2, 0); /* LCDCC */
1014 at91_set_A_periph(AT91_PIN_PE3, 0); /* LCDVSYNC */
1015 at91_set_A_periph(AT91_PIN_PE4, 0); /* LCDHSYNC */
1016 at91_set_A_periph(AT91_PIN_PE5, 0); /* LCDDOTCK */
1017 at91_set_A_periph(AT91_PIN_PE6, 0); /* LCDDEN */
1018 at91_set_A_periph(AT91_PIN_PE7, 0); /* LCDD0 */
1019 at91_set_A_periph(AT91_PIN_PE8, 0); /* LCDD1 */
1020 at91_set_A_periph(AT91_PIN_PE9, 0); /* LCDD2 */
1021 at91_set_A_periph(AT91_PIN_PE10, 0); /* LCDD3 */
1022 at91_set_A_periph(AT91_PIN_PE11, 0); /* LCDD4 */
1023 at91_set_A_periph(AT91_PIN_PE12, 0); /* LCDD5 */
1024 at91_set_A_periph(AT91_PIN_PE13, 0); /* LCDD6 */
1025 at91_set_A_periph(AT91_PIN_PE14, 0); /* LCDD7 */
1026 at91_set_A_periph(AT91_PIN_PE15, 0); /* LCDD8 */
1027 at91_set_A_periph(AT91_PIN_PE16, 0); /* LCDD9 */
1028 at91_set_A_periph(AT91_PIN_PE17, 0); /* LCDD10 */
1029 at91_set_A_periph(AT91_PIN_PE18, 0); /* LCDD11 */
1030 at91_set_A_periph(AT91_PIN_PE19, 0); /* LCDD12 */
1031 at91_set_A_periph(AT91_PIN_PE20, 0); /* LCDD13 */
1032 at91_set_A_periph(AT91_PIN_PE21, 0); /* LCDD14 */
1033 at91_set_A_periph(AT91_PIN_PE22, 0); /* LCDD15 */
1034 at91_set_A_periph(AT91_PIN_PE23, 0); /* LCDD16 */
1035 at91_set_A_periph(AT91_PIN_PE24, 0); /* LCDD17 */
1036 at91_set_A_periph(AT91_PIN_PE25, 0); /* LCDD18 */
1037 at91_set_A_periph(AT91_PIN_PE26, 0); /* LCDD19 */
1038 at91_set_A_periph(AT91_PIN_PE27, 0); /* LCDD20 */
1039 at91_set_A_periph(AT91_PIN_PE28, 0); /* LCDD21 */
1040 at91_set_A_periph(AT91_PIN_PE29, 0); /* LCDD22 */
1041 at91_set_A_periph(AT91_PIN_PE30, 0); /* LCDD23 */
1042
1043 lcdc_data = *data;
1044 platform_device_register(&at91_lcdc_device);
1045}
1046#else
1047void __init at91_add_device_lcdc(struct atmel_lcdfb_info *data) {}
1048#endif
1049
1050
1051/* --------------------------------------------------------------------
1052 * Timer/Counter block
1053 * -------------------------------------------------------------------- */
1054
1055#ifdef CONFIG_ATMEL_TCLIB
1056static struct resource tcb0_resources[] = {
1057 [0] = {
1058 .start = AT91SAM9G45_BASE_TCB0,
Nicolas Ferre29831292012-01-18 16:56:36 +01001059 .end = AT91SAM9G45_BASE_TCB0 + SZ_256 - 1,
Nicolas Ferre789b23b2009-06-26 15:36:58 +01001060 .flags = IORESOURCE_MEM,
1061 },
1062 [1] = {
1063 .start = AT91SAM9G45_ID_TCB,
1064 .end = AT91SAM9G45_ID_TCB,
1065 .flags = IORESOURCE_IRQ,
1066 },
1067};
1068
1069static struct platform_device at91sam9g45_tcb0_device = {
1070 .name = "atmel_tcb",
1071 .id = 0,
1072 .resource = tcb0_resources,
1073 .num_resources = ARRAY_SIZE(tcb0_resources),
1074};
1075
1076/* TCB1 begins with TC3 */
1077static struct resource tcb1_resources[] = {
1078 [0] = {
1079 .start = AT91SAM9G45_BASE_TCB1,
Nicolas Ferre29831292012-01-18 16:56:36 +01001080 .end = AT91SAM9G45_BASE_TCB1 + SZ_256 - 1,
Nicolas Ferre789b23b2009-06-26 15:36:58 +01001081 .flags = IORESOURCE_MEM,
1082 },
1083 [1] = {
1084 .start = AT91SAM9G45_ID_TCB,
1085 .end = AT91SAM9G45_ID_TCB,
1086 .flags = IORESOURCE_IRQ,
1087 },
1088};
1089
1090static struct platform_device at91sam9g45_tcb1_device = {
1091 .name = "atmel_tcb",
1092 .id = 1,
1093 .resource = tcb1_resources,
1094 .num_resources = ARRAY_SIZE(tcb1_resources),
1095};
1096
Nicolas Ferre3a61a5d2012-01-19 10:13:40 +01001097#if defined(CONFIG_OF)
1098static struct of_device_id tcb_ids[] = {
1099 { .compatible = "atmel,at91rm9200-tcb" },
1100 { /*sentinel*/ }
1101};
1102#endif
1103
Nicolas Ferre789b23b2009-06-26 15:36:58 +01001104static void __init at91_add_device_tc(void)
1105{
Nicolas Ferre3a61a5d2012-01-19 10:13:40 +01001106#if defined(CONFIG_OF)
1107 struct device_node *np;
1108
1109 np = of_find_matching_node(NULL, tcb_ids);
1110 if (np) {
1111 of_node_put(np);
1112 return;
1113 }
1114#endif
1115
Nicolas Ferre789b23b2009-06-26 15:36:58 +01001116 platform_device_register(&at91sam9g45_tcb0_device);
Nicolas Ferre789b23b2009-06-26 15:36:58 +01001117 platform_device_register(&at91sam9g45_tcb1_device);
1118}
1119#else
1120static void __init at91_add_device_tc(void) { }
1121#endif
1122
1123
1124/* --------------------------------------------------------------------
1125 * RTC
1126 * -------------------------------------------------------------------- */
1127
1128#if defined(CONFIG_RTC_DRV_AT91RM9200) || defined(CONFIG_RTC_DRV_AT91RM9200_MODULE)
Jean-Christophe PLAGNIOL-VILLARDd28bdfc2011-11-14 14:24:53 +08001129static struct resource rtc_resources[] = {
1130 [0] = {
1131 .start = AT91SAM9G45_BASE_RTC,
1132 .end = AT91SAM9G45_BASE_RTC + SZ_256 - 1,
1133 .flags = IORESOURCE_MEM,
1134 },
1135 [1] = {
1136 .start = AT91_ID_SYS,
1137 .end = AT91_ID_SYS,
1138 .flags = IORESOURCE_IRQ,
1139 },
1140};
1141
Nicolas Ferre789b23b2009-06-26 15:36:58 +01001142static struct platform_device at91sam9g45_rtc_device = {
1143 .name = "at91_rtc",
1144 .id = -1,
Jean-Christophe PLAGNIOL-VILLARDd28bdfc2011-11-14 14:24:53 +08001145 .resource = rtc_resources,
1146 .num_resources = ARRAY_SIZE(rtc_resources),
Nicolas Ferre789b23b2009-06-26 15:36:58 +01001147};
1148
1149static void __init at91_add_device_rtc(void)
1150{
1151 platform_device_register(&at91sam9g45_rtc_device);
1152}
1153#else
1154static void __init at91_add_device_rtc(void) {}
1155#endif
1156
1157
1158/* --------------------------------------------------------------------
Nicolas Ferre985f37f2009-11-19 09:32:52 -08001159 * Touchscreen
1160 * -------------------------------------------------------------------- */
1161
1162#if defined(CONFIG_TOUCHSCREEN_ATMEL_TSADCC) || defined(CONFIG_TOUCHSCREEN_ATMEL_TSADCC_MODULE)
1163static u64 tsadcc_dmamask = DMA_BIT_MASK(32);
1164static struct at91_tsadcc_data tsadcc_data;
1165
1166static struct resource tsadcc_resources[] = {
1167 [0] = {
1168 .start = AT91SAM9G45_BASE_TSC,
1169 .end = AT91SAM9G45_BASE_TSC + SZ_16K - 1,
1170 .flags = IORESOURCE_MEM,
1171 },
1172 [1] = {
1173 .start = AT91SAM9G45_ID_TSC,
1174 .end = AT91SAM9G45_ID_TSC,
1175 .flags = IORESOURCE_IRQ,
1176 }
1177};
1178
1179static struct platform_device at91sam9g45_tsadcc_device = {
1180 .name = "atmel_tsadcc",
1181 .id = -1,
1182 .dev = {
1183 .dma_mask = &tsadcc_dmamask,
1184 .coherent_dma_mask = DMA_BIT_MASK(32),
1185 .platform_data = &tsadcc_data,
1186 },
1187 .resource = tsadcc_resources,
1188 .num_resources = ARRAY_SIZE(tsadcc_resources),
1189};
1190
1191void __init at91_add_device_tsadcc(struct at91_tsadcc_data *data)
1192{
1193 if (!data)
1194 return;
1195
1196 at91_set_gpio_input(AT91_PIN_PD20, 0); /* AD0_XR */
1197 at91_set_gpio_input(AT91_PIN_PD21, 0); /* AD1_XL */
1198 at91_set_gpio_input(AT91_PIN_PD22, 0); /* AD2_YT */
1199 at91_set_gpio_input(AT91_PIN_PD23, 0); /* AD3_TB */
1200
1201 tsadcc_data = *data;
1202 platform_device_register(&at91sam9g45_tsadcc_device);
1203}
1204#else
1205void __init at91_add_device_tsadcc(struct at91_tsadcc_data *data) {}
1206#endif
1207
1208
1209/* --------------------------------------------------------------------
Nicolas Ferre789b23b2009-06-26 15:36:58 +01001210 * RTT
1211 * -------------------------------------------------------------------- */
1212
1213static struct resource rtt_resources[] = {
1214 {
Jean-Christophe PLAGNIOL-VILLARDeab5fd62011-09-18 10:12:00 +08001215 .start = AT91SAM9G45_BASE_RTT,
1216 .end = AT91SAM9G45_BASE_RTT + SZ_16 - 1,
Nicolas Ferre789b23b2009-06-26 15:36:58 +01001217 .flags = IORESOURCE_MEM,
Jean-Christophe PLAGNIOL-VILLARDb3af8b42012-02-15 21:24:46 +08001218 }, {
1219 .flags = IORESOURCE_MEM,
Nicolas Ferre789b23b2009-06-26 15:36:58 +01001220 }
1221};
1222
1223static struct platform_device at91sam9g45_rtt_device = {
1224 .name = "at91_rtt",
1225 .id = 0,
1226 .resource = rtt_resources,
Nicolas Ferre789b23b2009-06-26 15:36:58 +01001227};
1228
Jean-Christophe PLAGNIOL-VILLARD205056a2012-02-15 20:51:37 +08001229#if IS_ENABLED(CONFIG_RTC_DRV_AT91SAM9)
1230static void __init at91_add_device_rtt_rtc(void)
1231{
1232 at91sam9g45_rtt_device.name = "rtc-at91sam9";
Jean-Christophe PLAGNIOL-VILLARDb3af8b42012-02-15 21:24:46 +08001233 /*
1234 * The second resource is needed:
1235 * GPBR will serve as the storage for RTC time offset
1236 */
1237 at91sam9g45_rtt_device.num_resources = 2;
1238 rtt_resources[1].start = AT91SAM9G45_BASE_GPBR +
1239 4 * CONFIG_RTC_DRV_AT91SAM9_GPBR;
1240 rtt_resources[1].end = rtt_resources[1].start + 3;
Jean-Christophe PLAGNIOL-VILLARD205056a2012-02-15 20:51:37 +08001241}
1242#else
Jean-Christophe PLAGNIOL-VILLARDb3af8b42012-02-15 21:24:46 +08001243static void __init at91_add_device_rtt_rtc(void)
1244{
1245 /* Only one resource is needed: RTT not used as RTC */
1246 at91sam9g45_rtt_device.num_resources = 1;
1247}
Jean-Christophe PLAGNIOL-VILLARD205056a2012-02-15 20:51:37 +08001248#endif
1249
Nicolas Ferre789b23b2009-06-26 15:36:58 +01001250static void __init at91_add_device_rtt(void)
1251{
Jean-Christophe PLAGNIOL-VILLARD205056a2012-02-15 20:51:37 +08001252 at91_add_device_rtt_rtc();
Nicolas Ferre789b23b2009-06-26 15:36:58 +01001253 platform_device_register(&at91sam9g45_rtt_device);
1254}
1255
1256
1257/* --------------------------------------------------------------------
Peter Korsgaard237a62a2011-10-06 17:41:33 +02001258 * TRNG
1259 * -------------------------------------------------------------------- */
1260
1261#if defined(CONFIG_HW_RANDOM_ATMEL) || defined(CONFIG_HW_RANDOM_ATMEL_MODULE)
1262static struct resource trng_resources[] = {
1263 {
1264 .start = AT91SAM9G45_BASE_TRNG,
1265 .end = AT91SAM9G45_BASE_TRNG + SZ_16K - 1,
1266 .flags = IORESOURCE_MEM,
1267 },
1268};
1269
1270static struct platform_device at91sam9g45_trng_device = {
1271 .name = "atmel-trng",
1272 .id = -1,
1273 .resource = trng_resources,
1274 .num_resources = ARRAY_SIZE(trng_resources),
1275};
1276
1277static void __init at91_add_device_trng(void)
1278{
1279 platform_device_register(&at91sam9g45_trng_device);
1280}
1281#else
1282static void __init at91_add_device_trng(void) {}
1283#endif
1284
1285/* --------------------------------------------------------------------
Nicolas Ferre789b23b2009-06-26 15:36:58 +01001286 * Watchdog
1287 * -------------------------------------------------------------------- */
1288
Yegor Yefremov47263742009-10-20 08:39:41 +01001289#if defined(CONFIG_AT91SAM9X_WATCHDOG) || defined(CONFIG_AT91SAM9X_WATCHDOG_MODULE)
Jean-Christophe PLAGNIOL-VILLARDc1c30a22011-11-02 01:43:31 +08001290static struct resource wdt_resources[] = {
1291 {
1292 .start = AT91SAM9G45_BASE_WDT,
1293 .end = AT91SAM9G45_BASE_WDT + SZ_16 - 1,
1294 .flags = IORESOURCE_MEM,
1295 }
1296};
1297
Nicolas Ferre789b23b2009-06-26 15:36:58 +01001298static struct platform_device at91sam9g45_wdt_device = {
1299 .name = "at91_wdt",
1300 .id = -1,
Jean-Christophe PLAGNIOL-VILLARDc1c30a22011-11-02 01:43:31 +08001301 .resource = wdt_resources,
1302 .num_resources = ARRAY_SIZE(wdt_resources),
Nicolas Ferre789b23b2009-06-26 15:36:58 +01001303};
1304
1305static void __init at91_add_device_watchdog(void)
1306{
1307 platform_device_register(&at91sam9g45_wdt_device);
1308}
1309#else
1310static void __init at91_add_device_watchdog(void) {}
1311#endif
1312
1313
1314/* --------------------------------------------------------------------
1315 * PWM
1316 * --------------------------------------------------------------------*/
1317
1318#if defined(CONFIG_ATMEL_PWM) || defined(CONFIG_ATMEL_PWM_MODULE)
1319static u32 pwm_mask;
1320
1321static struct resource pwm_resources[] = {
1322 [0] = {
1323 .start = AT91SAM9G45_BASE_PWMC,
1324 .end = AT91SAM9G45_BASE_PWMC + SZ_16K - 1,
1325 .flags = IORESOURCE_MEM,
1326 },
1327 [1] = {
1328 .start = AT91SAM9G45_ID_PWMC,
1329 .end = AT91SAM9G45_ID_PWMC,
1330 .flags = IORESOURCE_IRQ,
1331 },
1332};
1333
1334static struct platform_device at91sam9g45_pwm0_device = {
1335 .name = "atmel_pwm",
1336 .id = -1,
1337 .dev = {
1338 .platform_data = &pwm_mask,
1339 },
1340 .resource = pwm_resources,
1341 .num_resources = ARRAY_SIZE(pwm_resources),
1342};
1343
1344void __init at91_add_device_pwm(u32 mask)
1345{
1346 if (mask & (1 << AT91_PWM0))
1347 at91_set_B_periph(AT91_PIN_PD24, 1); /* enable PWM0 */
1348
1349 if (mask & (1 << AT91_PWM1))
1350 at91_set_B_periph(AT91_PIN_PD31, 1); /* enable PWM1 */
1351
1352 if (mask & (1 << AT91_PWM2))
1353 at91_set_B_periph(AT91_PIN_PD26, 1); /* enable PWM2 */
1354
1355 if (mask & (1 << AT91_PWM3))
1356 at91_set_B_periph(AT91_PIN_PD0, 1); /* enable PWM3 */
1357
1358 pwm_mask = mask;
1359
1360 platform_device_register(&at91sam9g45_pwm0_device);
1361}
1362#else
1363void __init at91_add_device_pwm(u32 mask) {}
1364#endif
1365
1366
1367/* --------------------------------------------------------------------
1368 * SSC -- Synchronous Serial Controller
1369 * -------------------------------------------------------------------- */
1370
1371#if defined(CONFIG_ATMEL_SSC) || defined(CONFIG_ATMEL_SSC_MODULE)
1372static u64 ssc0_dmamask = DMA_BIT_MASK(32);
1373
1374static struct resource ssc0_resources[] = {
1375 [0] = {
1376 .start = AT91SAM9G45_BASE_SSC0,
1377 .end = AT91SAM9G45_BASE_SSC0 + SZ_16K - 1,
1378 .flags = IORESOURCE_MEM,
1379 },
1380 [1] = {
1381 .start = AT91SAM9G45_ID_SSC0,
1382 .end = AT91SAM9G45_ID_SSC0,
1383 .flags = IORESOURCE_IRQ,
1384 },
1385};
1386
1387static struct platform_device at91sam9g45_ssc0_device = {
1388 .name = "ssc",
1389 .id = 0,
1390 .dev = {
1391 .dma_mask = &ssc0_dmamask,
1392 .coherent_dma_mask = DMA_BIT_MASK(32),
1393 },
1394 .resource = ssc0_resources,
1395 .num_resources = ARRAY_SIZE(ssc0_resources),
1396};
1397
1398static inline void configure_ssc0_pins(unsigned pins)
1399{
1400 if (pins & ATMEL_SSC_TF)
1401 at91_set_A_periph(AT91_PIN_PD1, 1);
1402 if (pins & ATMEL_SSC_TK)
1403 at91_set_A_periph(AT91_PIN_PD0, 1);
1404 if (pins & ATMEL_SSC_TD)
1405 at91_set_A_periph(AT91_PIN_PD2, 1);
1406 if (pins & ATMEL_SSC_RD)
1407 at91_set_A_periph(AT91_PIN_PD3, 1);
1408 if (pins & ATMEL_SSC_RK)
1409 at91_set_A_periph(AT91_PIN_PD4, 1);
1410 if (pins & ATMEL_SSC_RF)
1411 at91_set_A_periph(AT91_PIN_PD5, 1);
1412}
1413
1414static u64 ssc1_dmamask = DMA_BIT_MASK(32);
1415
1416static struct resource ssc1_resources[] = {
1417 [0] = {
1418 .start = AT91SAM9G45_BASE_SSC1,
1419 .end = AT91SAM9G45_BASE_SSC1 + SZ_16K - 1,
1420 .flags = IORESOURCE_MEM,
1421 },
1422 [1] = {
1423 .start = AT91SAM9G45_ID_SSC1,
1424 .end = AT91SAM9G45_ID_SSC1,
1425 .flags = IORESOURCE_IRQ,
1426 },
1427};
1428
1429static struct platform_device at91sam9g45_ssc1_device = {
1430 .name = "ssc",
1431 .id = 1,
1432 .dev = {
1433 .dma_mask = &ssc1_dmamask,
1434 .coherent_dma_mask = DMA_BIT_MASK(32),
1435 },
1436 .resource = ssc1_resources,
1437 .num_resources = ARRAY_SIZE(ssc1_resources),
1438};
1439
1440static inline void configure_ssc1_pins(unsigned pins)
1441{
1442 if (pins & ATMEL_SSC_TF)
1443 at91_set_A_periph(AT91_PIN_PD14, 1);
1444 if (pins & ATMEL_SSC_TK)
1445 at91_set_A_periph(AT91_PIN_PD12, 1);
1446 if (pins & ATMEL_SSC_TD)
1447 at91_set_A_periph(AT91_PIN_PD10, 1);
1448 if (pins & ATMEL_SSC_RD)
1449 at91_set_A_periph(AT91_PIN_PD11, 1);
1450 if (pins & ATMEL_SSC_RK)
1451 at91_set_A_periph(AT91_PIN_PD13, 1);
1452 if (pins & ATMEL_SSC_RF)
1453 at91_set_A_periph(AT91_PIN_PD15, 1);
1454}
1455
1456/*
1457 * SSC controllers are accessed through library code, instead of any
1458 * kind of all-singing/all-dancing driver. For example one could be
1459 * used by a particular I2S audio codec's driver, while another one
1460 * on the same system might be used by a custom data capture driver.
1461 */
1462void __init at91_add_device_ssc(unsigned id, unsigned pins)
1463{
1464 struct platform_device *pdev;
1465
1466 /*
1467 * NOTE: caller is responsible for passing information matching
1468 * "pins" to whatever will be using each particular controller.
1469 */
1470 switch (id) {
1471 case AT91SAM9G45_ID_SSC0:
1472 pdev = &at91sam9g45_ssc0_device;
1473 configure_ssc0_pins(pins);
Nicolas Ferre789b23b2009-06-26 15:36:58 +01001474 break;
1475 case AT91SAM9G45_ID_SSC1:
1476 pdev = &at91sam9g45_ssc1_device;
1477 configure_ssc1_pins(pins);
Nicolas Ferre789b23b2009-06-26 15:36:58 +01001478 break;
1479 default:
1480 return;
1481 }
1482
1483 platform_device_register(pdev);
1484}
1485
1486#else
1487void __init at91_add_device_ssc(unsigned id, unsigned pins) {}
1488#endif
1489
1490
1491/* --------------------------------------------------------------------
1492 * UART
1493 * -------------------------------------------------------------------- */
1494
1495#if defined(CONFIG_SERIAL_ATMEL)
1496static struct resource dbgu_resources[] = {
1497 [0] = {
Jean-Christophe PLAGNIOL-VILLARD13079a72011-11-02 01:43:31 +08001498 .start = AT91SAM9G45_BASE_DBGU,
1499 .end = AT91SAM9G45_BASE_DBGU + SZ_512 - 1,
Nicolas Ferre789b23b2009-06-26 15:36:58 +01001500 .flags = IORESOURCE_MEM,
1501 },
1502 [1] = {
1503 .start = AT91_ID_SYS,
1504 .end = AT91_ID_SYS,
1505 .flags = IORESOURCE_IRQ,
1506 },
1507};
1508
1509static struct atmel_uart_data dbgu_data = {
1510 .use_dma_tx = 0,
1511 .use_dma_rx = 0,
Nicolas Ferre789b23b2009-06-26 15:36:58 +01001512};
1513
1514static u64 dbgu_dmamask = DMA_BIT_MASK(32);
1515
1516static struct platform_device at91sam9g45_dbgu_device = {
1517 .name = "atmel_usart",
1518 .id = 0,
1519 .dev = {
1520 .dma_mask = &dbgu_dmamask,
1521 .coherent_dma_mask = DMA_BIT_MASK(32),
1522 .platform_data = &dbgu_data,
1523 },
1524 .resource = dbgu_resources,
1525 .num_resources = ARRAY_SIZE(dbgu_resources),
1526};
1527
1528static inline void configure_dbgu_pins(void)
1529{
1530 at91_set_A_periph(AT91_PIN_PB12, 0); /* DRXD */
1531 at91_set_A_periph(AT91_PIN_PB13, 1); /* DTXD */
1532}
1533
1534static struct resource uart0_resources[] = {
1535 [0] = {
1536 .start = AT91SAM9G45_BASE_US0,
1537 .end = AT91SAM9G45_BASE_US0 + SZ_16K - 1,
1538 .flags = IORESOURCE_MEM,
1539 },
1540 [1] = {
1541 .start = AT91SAM9G45_ID_US0,
1542 .end = AT91SAM9G45_ID_US0,
1543 .flags = IORESOURCE_IRQ,
1544 },
1545};
1546
1547static struct atmel_uart_data uart0_data = {
1548 .use_dma_tx = 1,
1549 .use_dma_rx = 1,
1550};
1551
1552static u64 uart0_dmamask = DMA_BIT_MASK(32);
1553
1554static struct platform_device at91sam9g45_uart0_device = {
1555 .name = "atmel_usart",
1556 .id = 1,
1557 .dev = {
1558 .dma_mask = &uart0_dmamask,
1559 .coherent_dma_mask = DMA_BIT_MASK(32),
1560 .platform_data = &uart0_data,
1561 },
1562 .resource = uart0_resources,
1563 .num_resources = ARRAY_SIZE(uart0_resources),
1564};
1565
1566static inline void configure_usart0_pins(unsigned pins)
1567{
1568 at91_set_A_periph(AT91_PIN_PB19, 1); /* TXD0 */
1569 at91_set_A_periph(AT91_PIN_PB18, 0); /* RXD0 */
1570
1571 if (pins & ATMEL_UART_RTS)
1572 at91_set_B_periph(AT91_PIN_PB17, 0); /* RTS0 */
1573 if (pins & ATMEL_UART_CTS)
1574 at91_set_B_periph(AT91_PIN_PB15, 0); /* CTS0 */
1575}
1576
1577static struct resource uart1_resources[] = {
1578 [0] = {
1579 .start = AT91SAM9G45_BASE_US1,
1580 .end = AT91SAM9G45_BASE_US1 + SZ_16K - 1,
1581 .flags = IORESOURCE_MEM,
1582 },
1583 [1] = {
1584 .start = AT91SAM9G45_ID_US1,
1585 .end = AT91SAM9G45_ID_US1,
1586 .flags = IORESOURCE_IRQ,
1587 },
1588};
1589
1590static struct atmel_uart_data uart1_data = {
1591 .use_dma_tx = 1,
1592 .use_dma_rx = 1,
1593};
1594
1595static u64 uart1_dmamask = DMA_BIT_MASK(32);
1596
1597static struct platform_device at91sam9g45_uart1_device = {
1598 .name = "atmel_usart",
1599 .id = 2,
1600 .dev = {
1601 .dma_mask = &uart1_dmamask,
1602 .coherent_dma_mask = DMA_BIT_MASK(32),
1603 .platform_data = &uart1_data,
1604 },
1605 .resource = uart1_resources,
1606 .num_resources = ARRAY_SIZE(uart1_resources),
1607};
1608
1609static inline void configure_usart1_pins(unsigned pins)
1610{
1611 at91_set_A_periph(AT91_PIN_PB4, 1); /* TXD1 */
1612 at91_set_A_periph(AT91_PIN_PB5, 0); /* RXD1 */
1613
1614 if (pins & ATMEL_UART_RTS)
1615 at91_set_A_periph(AT91_PIN_PD16, 0); /* RTS1 */
1616 if (pins & ATMEL_UART_CTS)
1617 at91_set_A_periph(AT91_PIN_PD17, 0); /* CTS1 */
1618}
1619
1620static struct resource uart2_resources[] = {
1621 [0] = {
1622 .start = AT91SAM9G45_BASE_US2,
1623 .end = AT91SAM9G45_BASE_US2 + SZ_16K - 1,
1624 .flags = IORESOURCE_MEM,
1625 },
1626 [1] = {
1627 .start = AT91SAM9G45_ID_US2,
1628 .end = AT91SAM9G45_ID_US2,
1629 .flags = IORESOURCE_IRQ,
1630 },
1631};
1632
1633static struct atmel_uart_data uart2_data = {
1634 .use_dma_tx = 1,
1635 .use_dma_rx = 1,
1636};
1637
1638static u64 uart2_dmamask = DMA_BIT_MASK(32);
1639
1640static struct platform_device at91sam9g45_uart2_device = {
1641 .name = "atmel_usart",
1642 .id = 3,
1643 .dev = {
1644 .dma_mask = &uart2_dmamask,
1645 .coherent_dma_mask = DMA_BIT_MASK(32),
1646 .platform_data = &uart2_data,
1647 },
1648 .resource = uart2_resources,
1649 .num_resources = ARRAY_SIZE(uart2_resources),
1650};
1651
1652static inline void configure_usart2_pins(unsigned pins)
1653{
1654 at91_set_A_periph(AT91_PIN_PB6, 1); /* TXD2 */
1655 at91_set_A_periph(AT91_PIN_PB7, 0); /* RXD2 */
1656
1657 if (pins & ATMEL_UART_RTS)
1658 at91_set_B_periph(AT91_PIN_PC9, 0); /* RTS2 */
1659 if (pins & ATMEL_UART_CTS)
1660 at91_set_B_periph(AT91_PIN_PC11, 0); /* CTS2 */
1661}
1662
1663static struct resource uart3_resources[] = {
1664 [0] = {
1665 .start = AT91SAM9G45_BASE_US3,
1666 .end = AT91SAM9G45_BASE_US3 + SZ_16K - 1,
1667 .flags = IORESOURCE_MEM,
1668 },
1669 [1] = {
1670 .start = AT91SAM9G45_ID_US3,
1671 .end = AT91SAM9G45_ID_US3,
1672 .flags = IORESOURCE_IRQ,
1673 },
1674};
1675
1676static struct atmel_uart_data uart3_data = {
1677 .use_dma_tx = 1,
1678 .use_dma_rx = 1,
1679};
1680
1681static u64 uart3_dmamask = DMA_BIT_MASK(32);
1682
1683static struct platform_device at91sam9g45_uart3_device = {
1684 .name = "atmel_usart",
1685 .id = 4,
1686 .dev = {
1687 .dma_mask = &uart3_dmamask,
1688 .coherent_dma_mask = DMA_BIT_MASK(32),
1689 .platform_data = &uart3_data,
1690 },
1691 .resource = uart3_resources,
1692 .num_resources = ARRAY_SIZE(uart3_resources),
1693};
1694
1695static inline void configure_usart3_pins(unsigned pins)
1696{
1697 at91_set_A_periph(AT91_PIN_PB8, 1); /* TXD3 */
1698 at91_set_A_periph(AT91_PIN_PB9, 0); /* RXD3 */
1699
1700 if (pins & ATMEL_UART_RTS)
1701 at91_set_B_periph(AT91_PIN_PA23, 0); /* RTS3 */
1702 if (pins & ATMEL_UART_CTS)
1703 at91_set_B_periph(AT91_PIN_PA24, 0); /* CTS3 */
1704}
1705
1706static struct platform_device *__initdata at91_uarts[ATMEL_MAX_UART]; /* the UARTs to use */
Nicolas Ferre789b23b2009-06-26 15:36:58 +01001707
1708void __init at91_register_uart(unsigned id, unsigned portnr, unsigned pins)
1709{
1710 struct platform_device *pdev;
Jean-Christophe PLAGNIOL-VILLARD2b348e22011-04-10 14:10:05 +08001711 struct atmel_uart_data *pdata;
Nicolas Ferre789b23b2009-06-26 15:36:58 +01001712
1713 switch (id) {
1714 case 0: /* DBGU */
1715 pdev = &at91sam9g45_dbgu_device;
1716 configure_dbgu_pins();
Nicolas Ferre789b23b2009-06-26 15:36:58 +01001717 break;
1718 case AT91SAM9G45_ID_US0:
1719 pdev = &at91sam9g45_uart0_device;
1720 configure_usart0_pins(pins);
Nicolas Ferre789b23b2009-06-26 15:36:58 +01001721 break;
1722 case AT91SAM9G45_ID_US1:
1723 pdev = &at91sam9g45_uart1_device;
1724 configure_usart1_pins(pins);
Nicolas Ferre789b23b2009-06-26 15:36:58 +01001725 break;
1726 case AT91SAM9G45_ID_US2:
1727 pdev = &at91sam9g45_uart2_device;
1728 configure_usart2_pins(pins);
Nicolas Ferre789b23b2009-06-26 15:36:58 +01001729 break;
1730 case AT91SAM9G45_ID_US3:
1731 pdev = &at91sam9g45_uart3_device;
1732 configure_usart3_pins(pins);
Nicolas Ferre789b23b2009-06-26 15:36:58 +01001733 break;
1734 default:
1735 return;
1736 }
Jean-Christophe PLAGNIOL-VILLARD2b348e22011-04-10 14:10:05 +08001737 pdata = pdev->dev.platform_data;
1738 pdata->num = portnr; /* update to mapped ID */
Nicolas Ferre789b23b2009-06-26 15:36:58 +01001739
1740 if (portnr < ATMEL_MAX_UART)
1741 at91_uarts[portnr] = pdev;
1742}
1743
1744void __init at91_set_serial_console(unsigned portnr)
1745{
Jean-Christophe PLAGNIOL-VILLARDbd602992011-02-02 07:27:07 +01001746 if (portnr < ATMEL_MAX_UART) {
Nicolas Ferre789b23b2009-06-26 15:36:58 +01001747 atmel_default_console_device = at91_uarts[portnr];
Jean-Christophe PLAGNIOL-VILLARD5c1f9662011-06-21 11:24:33 +08001748 at91sam9g45_set_console_clock(at91_uarts[portnr]->id);
Jean-Christophe PLAGNIOL-VILLARDbd602992011-02-02 07:27:07 +01001749 }
Nicolas Ferre789b23b2009-06-26 15:36:58 +01001750}
1751
1752void __init at91_add_device_serial(void)
1753{
1754 int i;
1755
1756 for (i = 0; i < ATMEL_MAX_UART; i++) {
1757 if (at91_uarts[i])
1758 platform_device_register(at91_uarts[i]);
1759 }
1760
1761 if (!atmel_default_console_device)
1762 printk(KERN_INFO "AT91: No default serial console defined.\n");
1763}
1764#else
1765void __init at91_register_uart(unsigned id, unsigned portnr, unsigned pins) {}
1766void __init at91_set_serial_console(unsigned portnr) {}
1767void __init at91_add_device_serial(void) {}
1768#endif
1769
1770
1771/* -------------------------------------------------------------------- */
1772/*
1773 * These devices are always present and don't need any board-specific
1774 * setup.
1775 */
1776static int __init at91_add_standard_devices(void)
1777{
Nicolas Ferre40262b22009-07-24 11:43:01 +01001778 at91_add_device_hdmac();
Nicolas Ferre789b23b2009-06-26 15:36:58 +01001779 at91_add_device_rtc();
1780 at91_add_device_rtt();
Peter Korsgaard237a62a2011-10-06 17:41:33 +02001781 at91_add_device_trng();
Nicolas Ferre789b23b2009-06-26 15:36:58 +01001782 at91_add_device_watchdog();
1783 at91_add_device_tc();
1784 return 0;
1785}
1786
1787arch_initcall(at91_add_standard_devices);