blob: ddf210ab8d123a0c5a73e31cdb35717af89fa17d [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++) {
136 if (data->overcurrent_pin[i])
137 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
790 if (devices[i].bus_num == 0)
791 enable_spi0 = 1;
792 else
793 enable_spi1 = 1;
794
795 /* enable chip-select pin */
796 at91_set_gpio_output(cs_pin, 1);
797
798 /* pass chip-select pin to driver */
799 devices[i].controller_data = (void *) cs_pin;
800 }
801
802 spi_register_board_info(devices, nr_devices);
803
804 /* Configure SPI bus(es) */
805 if (enable_spi0) {
806 at91_set_A_periph(AT91_PIN_PB0, 0); /* SPI0_MISO */
807 at91_set_A_periph(AT91_PIN_PB1, 0); /* SPI0_MOSI */
808 at91_set_A_periph(AT91_PIN_PB2, 0); /* SPI0_SPCK */
809
Nicolas Ferre789b23b2009-06-26 15:36:58 +0100810 platform_device_register(&at91sam9g45_spi0_device);
811 }
812 if (enable_spi1) {
813 at91_set_A_periph(AT91_PIN_PB14, 0); /* SPI1_MISO */
814 at91_set_A_periph(AT91_PIN_PB15, 0); /* SPI1_MOSI */
815 at91_set_A_periph(AT91_PIN_PB16, 0); /* SPI1_SPCK */
816
Nicolas Ferre789b23b2009-06-26 15:36:58 +0100817 platform_device_register(&at91sam9g45_spi1_device);
818 }
819}
820#else
821void __init at91_add_device_spi(struct spi_board_info *devices, int nr_devices) {}
822#endif
823
824
825/* --------------------------------------------------------------------
Nicolas Ferre378ac652009-09-18 16:14:22 +0100826 * AC97
827 * -------------------------------------------------------------------- */
828
829#if defined(CONFIG_SND_ATMEL_AC97C) || defined(CONFIG_SND_ATMEL_AC97C_MODULE)
830static u64 ac97_dmamask = DMA_BIT_MASK(32);
831static struct ac97c_platform_data ac97_data;
832
833static struct resource ac97_resources[] = {
834 [0] = {
835 .start = AT91SAM9G45_BASE_AC97C,
836 .end = AT91SAM9G45_BASE_AC97C + SZ_16K - 1,
837 .flags = IORESOURCE_MEM,
838 },
839 [1] = {
840 .start = AT91SAM9G45_ID_AC97C,
841 .end = AT91SAM9G45_ID_AC97C,
842 .flags = IORESOURCE_IRQ,
843 },
844};
845
846static struct platform_device at91sam9g45_ac97_device = {
847 .name = "atmel_ac97c",
848 .id = 0,
849 .dev = {
850 .dma_mask = &ac97_dmamask,
851 .coherent_dma_mask = DMA_BIT_MASK(32),
852 .platform_data = &ac97_data,
853 },
854 .resource = ac97_resources,
855 .num_resources = ARRAY_SIZE(ac97_resources),
856};
857
858void __init at91_add_device_ac97(struct ac97c_platform_data *data)
859{
860 if (!data)
861 return;
862
863 at91_set_A_periph(AT91_PIN_PD8, 0); /* AC97FS */
864 at91_set_A_periph(AT91_PIN_PD9, 0); /* AC97CK */
865 at91_set_A_periph(AT91_PIN_PD7, 0); /* AC97TX */
866 at91_set_A_periph(AT91_PIN_PD6, 0); /* AC97RX */
867
868 /* reset */
Jean-Christophe PLAGNIOL-VILLARDcc9f9ae2011-09-19 15:28:25 +0800869 if (gpio_is_valid(data->reset_pin))
Nicolas Ferre378ac652009-09-18 16:14:22 +0100870 at91_set_gpio_output(data->reset_pin, 0);
871
872 ac97_data = *data;
873 platform_device_register(&at91sam9g45_ac97_device);
874}
875#else
876void __init at91_add_device_ac97(struct ac97c_platform_data *data) {}
877#endif
878
Josh Wu343754f2011-10-22 15:17:40 +0800879/* --------------------------------------------------------------------
880 * Image Sensor Interface
881 * -------------------------------------------------------------------- */
882#if defined(CONFIG_VIDEO_ATMEL_ISI) || defined(CONFIG_VIDEO_ATMEL_ISI_MODULE)
883static u64 isi_dmamask = DMA_BIT_MASK(32);
884static struct isi_platform_data isi_data;
885
886struct resource isi_resources[] = {
887 [0] = {
888 .start = AT91SAM9G45_BASE_ISI,
889 .end = AT91SAM9G45_BASE_ISI + SZ_16K - 1,
890 .flags = IORESOURCE_MEM,
891 },
892 [1] = {
893 .start = AT91SAM9G45_ID_ISI,
894 .end = AT91SAM9G45_ID_ISI,
895 .flags = IORESOURCE_IRQ,
896 },
897};
898
899static struct platform_device at91sam9g45_isi_device = {
900 .name = "atmel_isi",
901 .id = 0,
902 .dev = {
903 .dma_mask = &isi_dmamask,
904 .coherent_dma_mask = DMA_BIT_MASK(32),
905 .platform_data = &isi_data,
906 },
907 .resource = isi_resources,
908 .num_resources = ARRAY_SIZE(isi_resources),
909};
910
911static struct clk_lookup isi_mck_lookups[] = {
912 CLKDEV_CON_DEV_ID("isi_mck", "atmel_isi.0", NULL),
913};
914
915void __init at91_add_device_isi(struct isi_platform_data *data,
916 bool use_pck_as_mck)
917{
918 struct clk *pck;
919 struct clk *parent;
920
921 if (!data)
922 return;
923 isi_data = *data;
924
925 at91_set_A_periph(AT91_PIN_PB20, 0); /* ISI_D0 */
926 at91_set_A_periph(AT91_PIN_PB21, 0); /* ISI_D1 */
927 at91_set_A_periph(AT91_PIN_PB22, 0); /* ISI_D2 */
928 at91_set_A_periph(AT91_PIN_PB23, 0); /* ISI_D3 */
929 at91_set_A_periph(AT91_PIN_PB24, 0); /* ISI_D4 */
930 at91_set_A_periph(AT91_PIN_PB25, 0); /* ISI_D5 */
931 at91_set_A_periph(AT91_PIN_PB26, 0); /* ISI_D6 */
932 at91_set_A_periph(AT91_PIN_PB27, 0); /* ISI_D7 */
933 at91_set_A_periph(AT91_PIN_PB28, 0); /* ISI_PCK */
934 at91_set_A_periph(AT91_PIN_PB30, 0); /* ISI_HSYNC */
935 at91_set_A_periph(AT91_PIN_PB29, 0); /* ISI_VSYNC */
936 at91_set_B_periph(AT91_PIN_PB8, 0); /* ISI_PD8 */
937 at91_set_B_periph(AT91_PIN_PB9, 0); /* ISI_PD9 */
938 at91_set_B_periph(AT91_PIN_PB10, 0); /* ISI_PD10 */
939 at91_set_B_periph(AT91_PIN_PB11, 0); /* ISI_PD11 */
940
941 platform_device_register(&at91sam9g45_isi_device);
942
943 if (use_pck_as_mck) {
944 at91_set_B_periph(AT91_PIN_PB31, 0); /* ISI_MCK (PCK1) */
945
946 pck = clk_get(NULL, "pck1");
947 parent = clk_get(NULL, "plla");
948
949 BUG_ON(IS_ERR(pck) || IS_ERR(parent));
950
951 if (clk_set_parent(pck, parent)) {
952 pr_err("Failed to set PCK's parent\n");
953 } else {
954 /* Register PCK as ISI_MCK */
955 isi_mck_lookups[0].clk = pck;
956 clkdev_add_table(isi_mck_lookups,
957 ARRAY_SIZE(isi_mck_lookups));
958 }
959
960 clk_put(pck);
961 clk_put(parent);
962 }
963}
964#else
965void __init at91_add_device_isi(struct isi_platform_data *data,
966 bool use_pck_as_mck) {}
967#endif
968
Nicolas Ferre378ac652009-09-18 16:14:22 +0100969
970/* --------------------------------------------------------------------
Nicolas Ferre789b23b2009-06-26 15:36:58 +0100971 * LCD Controller
972 * -------------------------------------------------------------------- */
973
974#if defined(CONFIG_FB_ATMEL) || defined(CONFIG_FB_ATMEL_MODULE)
975static u64 lcdc_dmamask = DMA_BIT_MASK(32);
976static struct atmel_lcdfb_info lcdc_data;
977
978static struct resource lcdc_resources[] = {
979 [0] = {
980 .start = AT91SAM9G45_LCDC_BASE,
981 .end = AT91SAM9G45_LCDC_BASE + SZ_4K - 1,
982 .flags = IORESOURCE_MEM,
983 },
984 [1] = {
985 .start = AT91SAM9G45_ID_LCDC,
986 .end = AT91SAM9G45_ID_LCDC,
987 .flags = IORESOURCE_IRQ,
988 },
989};
990
991static struct platform_device at91_lcdc_device = {
992 .name = "atmel_lcdfb",
993 .id = 0,
994 .dev = {
995 .dma_mask = &lcdc_dmamask,
996 .coherent_dma_mask = DMA_BIT_MASK(32),
997 .platform_data = &lcdc_data,
998 },
999 .resource = lcdc_resources,
1000 .num_resources = ARRAY_SIZE(lcdc_resources),
1001};
1002
1003void __init at91_add_device_lcdc(struct atmel_lcdfb_info *data)
1004{
1005 if (!data)
1006 return;
1007
1008 at91_set_A_periph(AT91_PIN_PE0, 0); /* LCDDPWR */
1009
1010 at91_set_A_periph(AT91_PIN_PE2, 0); /* LCDCC */
1011 at91_set_A_periph(AT91_PIN_PE3, 0); /* LCDVSYNC */
1012 at91_set_A_periph(AT91_PIN_PE4, 0); /* LCDHSYNC */
1013 at91_set_A_periph(AT91_PIN_PE5, 0); /* LCDDOTCK */
1014 at91_set_A_periph(AT91_PIN_PE6, 0); /* LCDDEN */
1015 at91_set_A_periph(AT91_PIN_PE7, 0); /* LCDD0 */
1016 at91_set_A_periph(AT91_PIN_PE8, 0); /* LCDD1 */
1017 at91_set_A_periph(AT91_PIN_PE9, 0); /* LCDD2 */
1018 at91_set_A_periph(AT91_PIN_PE10, 0); /* LCDD3 */
1019 at91_set_A_periph(AT91_PIN_PE11, 0); /* LCDD4 */
1020 at91_set_A_periph(AT91_PIN_PE12, 0); /* LCDD5 */
1021 at91_set_A_periph(AT91_PIN_PE13, 0); /* LCDD6 */
1022 at91_set_A_periph(AT91_PIN_PE14, 0); /* LCDD7 */
1023 at91_set_A_periph(AT91_PIN_PE15, 0); /* LCDD8 */
1024 at91_set_A_periph(AT91_PIN_PE16, 0); /* LCDD9 */
1025 at91_set_A_periph(AT91_PIN_PE17, 0); /* LCDD10 */
1026 at91_set_A_periph(AT91_PIN_PE18, 0); /* LCDD11 */
1027 at91_set_A_periph(AT91_PIN_PE19, 0); /* LCDD12 */
1028 at91_set_A_periph(AT91_PIN_PE20, 0); /* LCDD13 */
1029 at91_set_A_periph(AT91_PIN_PE21, 0); /* LCDD14 */
1030 at91_set_A_periph(AT91_PIN_PE22, 0); /* LCDD15 */
1031 at91_set_A_periph(AT91_PIN_PE23, 0); /* LCDD16 */
1032 at91_set_A_periph(AT91_PIN_PE24, 0); /* LCDD17 */
1033 at91_set_A_periph(AT91_PIN_PE25, 0); /* LCDD18 */
1034 at91_set_A_periph(AT91_PIN_PE26, 0); /* LCDD19 */
1035 at91_set_A_periph(AT91_PIN_PE27, 0); /* LCDD20 */
1036 at91_set_A_periph(AT91_PIN_PE28, 0); /* LCDD21 */
1037 at91_set_A_periph(AT91_PIN_PE29, 0); /* LCDD22 */
1038 at91_set_A_periph(AT91_PIN_PE30, 0); /* LCDD23 */
1039
1040 lcdc_data = *data;
1041 platform_device_register(&at91_lcdc_device);
1042}
1043#else
1044void __init at91_add_device_lcdc(struct atmel_lcdfb_info *data) {}
1045#endif
1046
1047
1048/* --------------------------------------------------------------------
1049 * Timer/Counter block
1050 * -------------------------------------------------------------------- */
1051
1052#ifdef CONFIG_ATMEL_TCLIB
1053static struct resource tcb0_resources[] = {
1054 [0] = {
1055 .start = AT91SAM9G45_BASE_TCB0,
Nicolas Ferre29831292012-01-18 16:56:36 +01001056 .end = AT91SAM9G45_BASE_TCB0 + SZ_256 - 1,
Nicolas Ferre789b23b2009-06-26 15:36:58 +01001057 .flags = IORESOURCE_MEM,
1058 },
1059 [1] = {
1060 .start = AT91SAM9G45_ID_TCB,
1061 .end = AT91SAM9G45_ID_TCB,
1062 .flags = IORESOURCE_IRQ,
1063 },
1064};
1065
1066static struct platform_device at91sam9g45_tcb0_device = {
1067 .name = "atmel_tcb",
1068 .id = 0,
1069 .resource = tcb0_resources,
1070 .num_resources = ARRAY_SIZE(tcb0_resources),
1071};
1072
1073/* TCB1 begins with TC3 */
1074static struct resource tcb1_resources[] = {
1075 [0] = {
1076 .start = AT91SAM9G45_BASE_TCB1,
Nicolas Ferre29831292012-01-18 16:56:36 +01001077 .end = AT91SAM9G45_BASE_TCB1 + SZ_256 - 1,
Nicolas Ferre789b23b2009-06-26 15:36:58 +01001078 .flags = IORESOURCE_MEM,
1079 },
1080 [1] = {
1081 .start = AT91SAM9G45_ID_TCB,
1082 .end = AT91SAM9G45_ID_TCB,
1083 .flags = IORESOURCE_IRQ,
1084 },
1085};
1086
1087static struct platform_device at91sam9g45_tcb1_device = {
1088 .name = "atmel_tcb",
1089 .id = 1,
1090 .resource = tcb1_resources,
1091 .num_resources = ARRAY_SIZE(tcb1_resources),
1092};
1093
Nicolas Ferre3a61a5d2012-01-19 10:13:40 +01001094#if defined(CONFIG_OF)
1095static struct of_device_id tcb_ids[] = {
1096 { .compatible = "atmel,at91rm9200-tcb" },
1097 { /*sentinel*/ }
1098};
1099#endif
1100
Nicolas Ferre789b23b2009-06-26 15:36:58 +01001101static void __init at91_add_device_tc(void)
1102{
Nicolas Ferre3a61a5d2012-01-19 10:13:40 +01001103#if defined(CONFIG_OF)
1104 struct device_node *np;
1105
1106 np = of_find_matching_node(NULL, tcb_ids);
1107 if (np) {
1108 of_node_put(np);
1109 return;
1110 }
1111#endif
1112
Nicolas Ferre789b23b2009-06-26 15:36:58 +01001113 platform_device_register(&at91sam9g45_tcb0_device);
Nicolas Ferre789b23b2009-06-26 15:36:58 +01001114 platform_device_register(&at91sam9g45_tcb1_device);
1115}
1116#else
1117static void __init at91_add_device_tc(void) { }
1118#endif
1119
1120
1121/* --------------------------------------------------------------------
1122 * RTC
1123 * -------------------------------------------------------------------- */
1124
1125#if defined(CONFIG_RTC_DRV_AT91RM9200) || defined(CONFIG_RTC_DRV_AT91RM9200_MODULE)
Jean-Christophe PLAGNIOL-VILLARDd28bdfc2011-11-14 14:24:53 +08001126static struct resource rtc_resources[] = {
1127 [0] = {
1128 .start = AT91SAM9G45_BASE_RTC,
1129 .end = AT91SAM9G45_BASE_RTC + SZ_256 - 1,
1130 .flags = IORESOURCE_MEM,
1131 },
1132 [1] = {
1133 .start = AT91_ID_SYS,
1134 .end = AT91_ID_SYS,
1135 .flags = IORESOURCE_IRQ,
1136 },
1137};
1138
Nicolas Ferre789b23b2009-06-26 15:36:58 +01001139static struct platform_device at91sam9g45_rtc_device = {
1140 .name = "at91_rtc",
1141 .id = -1,
Jean-Christophe PLAGNIOL-VILLARDd28bdfc2011-11-14 14:24:53 +08001142 .resource = rtc_resources,
1143 .num_resources = ARRAY_SIZE(rtc_resources),
Nicolas Ferre789b23b2009-06-26 15:36:58 +01001144};
1145
1146static void __init at91_add_device_rtc(void)
1147{
1148 platform_device_register(&at91sam9g45_rtc_device);
1149}
1150#else
1151static void __init at91_add_device_rtc(void) {}
1152#endif
1153
1154
1155/* --------------------------------------------------------------------
Nicolas Ferre985f37f2009-11-19 09:32:52 -08001156 * Touchscreen
1157 * -------------------------------------------------------------------- */
1158
1159#if defined(CONFIG_TOUCHSCREEN_ATMEL_TSADCC) || defined(CONFIG_TOUCHSCREEN_ATMEL_TSADCC_MODULE)
1160static u64 tsadcc_dmamask = DMA_BIT_MASK(32);
1161static struct at91_tsadcc_data tsadcc_data;
1162
1163static struct resource tsadcc_resources[] = {
1164 [0] = {
1165 .start = AT91SAM9G45_BASE_TSC,
1166 .end = AT91SAM9G45_BASE_TSC + SZ_16K - 1,
1167 .flags = IORESOURCE_MEM,
1168 },
1169 [1] = {
1170 .start = AT91SAM9G45_ID_TSC,
1171 .end = AT91SAM9G45_ID_TSC,
1172 .flags = IORESOURCE_IRQ,
1173 }
1174};
1175
1176static struct platform_device at91sam9g45_tsadcc_device = {
1177 .name = "atmel_tsadcc",
1178 .id = -1,
1179 .dev = {
1180 .dma_mask = &tsadcc_dmamask,
1181 .coherent_dma_mask = DMA_BIT_MASK(32),
1182 .platform_data = &tsadcc_data,
1183 },
1184 .resource = tsadcc_resources,
1185 .num_resources = ARRAY_SIZE(tsadcc_resources),
1186};
1187
1188void __init at91_add_device_tsadcc(struct at91_tsadcc_data *data)
1189{
1190 if (!data)
1191 return;
1192
1193 at91_set_gpio_input(AT91_PIN_PD20, 0); /* AD0_XR */
1194 at91_set_gpio_input(AT91_PIN_PD21, 0); /* AD1_XL */
1195 at91_set_gpio_input(AT91_PIN_PD22, 0); /* AD2_YT */
1196 at91_set_gpio_input(AT91_PIN_PD23, 0); /* AD3_TB */
1197
1198 tsadcc_data = *data;
1199 platform_device_register(&at91sam9g45_tsadcc_device);
1200}
1201#else
1202void __init at91_add_device_tsadcc(struct at91_tsadcc_data *data) {}
1203#endif
1204
1205
1206/* --------------------------------------------------------------------
Nicolas Ferre789b23b2009-06-26 15:36:58 +01001207 * RTT
1208 * -------------------------------------------------------------------- */
1209
1210static struct resource rtt_resources[] = {
1211 {
Jean-Christophe PLAGNIOL-VILLARDeab5fd62011-09-18 10:12:00 +08001212 .start = AT91SAM9G45_BASE_RTT,
1213 .end = AT91SAM9G45_BASE_RTT + SZ_16 - 1,
Nicolas Ferre789b23b2009-06-26 15:36:58 +01001214 .flags = IORESOURCE_MEM,
Jean-Christophe PLAGNIOL-VILLARDb3af8b42012-02-15 21:24:46 +08001215 }, {
1216 .flags = IORESOURCE_MEM,
Nicolas Ferre789b23b2009-06-26 15:36:58 +01001217 }
1218};
1219
1220static struct platform_device at91sam9g45_rtt_device = {
1221 .name = "at91_rtt",
1222 .id = 0,
1223 .resource = rtt_resources,
Nicolas Ferre789b23b2009-06-26 15:36:58 +01001224};
1225
Jean-Christophe PLAGNIOL-VILLARD205056a2012-02-15 20:51:37 +08001226#if IS_ENABLED(CONFIG_RTC_DRV_AT91SAM9)
1227static void __init at91_add_device_rtt_rtc(void)
1228{
1229 at91sam9g45_rtt_device.name = "rtc-at91sam9";
Jean-Christophe PLAGNIOL-VILLARDb3af8b42012-02-15 21:24:46 +08001230 /*
1231 * The second resource is needed:
1232 * GPBR will serve as the storage for RTC time offset
1233 */
1234 at91sam9g45_rtt_device.num_resources = 2;
1235 rtt_resources[1].start = AT91SAM9G45_BASE_GPBR +
1236 4 * CONFIG_RTC_DRV_AT91SAM9_GPBR;
1237 rtt_resources[1].end = rtt_resources[1].start + 3;
Jean-Christophe PLAGNIOL-VILLARD205056a2012-02-15 20:51:37 +08001238}
1239#else
Jean-Christophe PLAGNIOL-VILLARDb3af8b42012-02-15 21:24:46 +08001240static void __init at91_add_device_rtt_rtc(void)
1241{
1242 /* Only one resource is needed: RTT not used as RTC */
1243 at91sam9g45_rtt_device.num_resources = 1;
1244}
Jean-Christophe PLAGNIOL-VILLARD205056a2012-02-15 20:51:37 +08001245#endif
1246
Nicolas Ferre789b23b2009-06-26 15:36:58 +01001247static void __init at91_add_device_rtt(void)
1248{
Jean-Christophe PLAGNIOL-VILLARD205056a2012-02-15 20:51:37 +08001249 at91_add_device_rtt_rtc();
Nicolas Ferre789b23b2009-06-26 15:36:58 +01001250 platform_device_register(&at91sam9g45_rtt_device);
1251}
1252
1253
1254/* --------------------------------------------------------------------
Peter Korsgaard237a62a2011-10-06 17:41:33 +02001255 * TRNG
1256 * -------------------------------------------------------------------- */
1257
1258#if defined(CONFIG_HW_RANDOM_ATMEL) || defined(CONFIG_HW_RANDOM_ATMEL_MODULE)
1259static struct resource trng_resources[] = {
1260 {
1261 .start = AT91SAM9G45_BASE_TRNG,
1262 .end = AT91SAM9G45_BASE_TRNG + SZ_16K - 1,
1263 .flags = IORESOURCE_MEM,
1264 },
1265};
1266
1267static struct platform_device at91sam9g45_trng_device = {
1268 .name = "atmel-trng",
1269 .id = -1,
1270 .resource = trng_resources,
1271 .num_resources = ARRAY_SIZE(trng_resources),
1272};
1273
1274static void __init at91_add_device_trng(void)
1275{
1276 platform_device_register(&at91sam9g45_trng_device);
1277}
1278#else
1279static void __init at91_add_device_trng(void) {}
1280#endif
1281
1282/* --------------------------------------------------------------------
Nicolas Ferre789b23b2009-06-26 15:36:58 +01001283 * Watchdog
1284 * -------------------------------------------------------------------- */
1285
Yegor Yefremov47263742009-10-20 08:39:41 +01001286#if defined(CONFIG_AT91SAM9X_WATCHDOG) || defined(CONFIG_AT91SAM9X_WATCHDOG_MODULE)
Jean-Christophe PLAGNIOL-VILLARDc1c30a22011-11-02 01:43:31 +08001287static struct resource wdt_resources[] = {
1288 {
1289 .start = AT91SAM9G45_BASE_WDT,
1290 .end = AT91SAM9G45_BASE_WDT + SZ_16 - 1,
1291 .flags = IORESOURCE_MEM,
1292 }
1293};
1294
Nicolas Ferre789b23b2009-06-26 15:36:58 +01001295static struct platform_device at91sam9g45_wdt_device = {
1296 .name = "at91_wdt",
1297 .id = -1,
Jean-Christophe PLAGNIOL-VILLARDc1c30a22011-11-02 01:43:31 +08001298 .resource = wdt_resources,
1299 .num_resources = ARRAY_SIZE(wdt_resources),
Nicolas Ferre789b23b2009-06-26 15:36:58 +01001300};
1301
1302static void __init at91_add_device_watchdog(void)
1303{
1304 platform_device_register(&at91sam9g45_wdt_device);
1305}
1306#else
1307static void __init at91_add_device_watchdog(void) {}
1308#endif
1309
1310
1311/* --------------------------------------------------------------------
1312 * PWM
1313 * --------------------------------------------------------------------*/
1314
1315#if defined(CONFIG_ATMEL_PWM) || defined(CONFIG_ATMEL_PWM_MODULE)
1316static u32 pwm_mask;
1317
1318static struct resource pwm_resources[] = {
1319 [0] = {
1320 .start = AT91SAM9G45_BASE_PWMC,
1321 .end = AT91SAM9G45_BASE_PWMC + SZ_16K - 1,
1322 .flags = IORESOURCE_MEM,
1323 },
1324 [1] = {
1325 .start = AT91SAM9G45_ID_PWMC,
1326 .end = AT91SAM9G45_ID_PWMC,
1327 .flags = IORESOURCE_IRQ,
1328 },
1329};
1330
1331static struct platform_device at91sam9g45_pwm0_device = {
1332 .name = "atmel_pwm",
1333 .id = -1,
1334 .dev = {
1335 .platform_data = &pwm_mask,
1336 },
1337 .resource = pwm_resources,
1338 .num_resources = ARRAY_SIZE(pwm_resources),
1339};
1340
1341void __init at91_add_device_pwm(u32 mask)
1342{
1343 if (mask & (1 << AT91_PWM0))
1344 at91_set_B_periph(AT91_PIN_PD24, 1); /* enable PWM0 */
1345
1346 if (mask & (1 << AT91_PWM1))
1347 at91_set_B_periph(AT91_PIN_PD31, 1); /* enable PWM1 */
1348
1349 if (mask & (1 << AT91_PWM2))
1350 at91_set_B_periph(AT91_PIN_PD26, 1); /* enable PWM2 */
1351
1352 if (mask & (1 << AT91_PWM3))
1353 at91_set_B_periph(AT91_PIN_PD0, 1); /* enable PWM3 */
1354
1355 pwm_mask = mask;
1356
1357 platform_device_register(&at91sam9g45_pwm0_device);
1358}
1359#else
1360void __init at91_add_device_pwm(u32 mask) {}
1361#endif
1362
1363
1364/* --------------------------------------------------------------------
1365 * SSC -- Synchronous Serial Controller
1366 * -------------------------------------------------------------------- */
1367
1368#if defined(CONFIG_ATMEL_SSC) || defined(CONFIG_ATMEL_SSC_MODULE)
1369static u64 ssc0_dmamask = DMA_BIT_MASK(32);
1370
1371static struct resource ssc0_resources[] = {
1372 [0] = {
1373 .start = AT91SAM9G45_BASE_SSC0,
1374 .end = AT91SAM9G45_BASE_SSC0 + SZ_16K - 1,
1375 .flags = IORESOURCE_MEM,
1376 },
1377 [1] = {
1378 .start = AT91SAM9G45_ID_SSC0,
1379 .end = AT91SAM9G45_ID_SSC0,
1380 .flags = IORESOURCE_IRQ,
1381 },
1382};
1383
1384static struct platform_device at91sam9g45_ssc0_device = {
1385 .name = "ssc",
1386 .id = 0,
1387 .dev = {
1388 .dma_mask = &ssc0_dmamask,
1389 .coherent_dma_mask = DMA_BIT_MASK(32),
1390 },
1391 .resource = ssc0_resources,
1392 .num_resources = ARRAY_SIZE(ssc0_resources),
1393};
1394
1395static inline void configure_ssc0_pins(unsigned pins)
1396{
1397 if (pins & ATMEL_SSC_TF)
1398 at91_set_A_periph(AT91_PIN_PD1, 1);
1399 if (pins & ATMEL_SSC_TK)
1400 at91_set_A_periph(AT91_PIN_PD0, 1);
1401 if (pins & ATMEL_SSC_TD)
1402 at91_set_A_periph(AT91_PIN_PD2, 1);
1403 if (pins & ATMEL_SSC_RD)
1404 at91_set_A_periph(AT91_PIN_PD3, 1);
1405 if (pins & ATMEL_SSC_RK)
1406 at91_set_A_periph(AT91_PIN_PD4, 1);
1407 if (pins & ATMEL_SSC_RF)
1408 at91_set_A_periph(AT91_PIN_PD5, 1);
1409}
1410
1411static u64 ssc1_dmamask = DMA_BIT_MASK(32);
1412
1413static struct resource ssc1_resources[] = {
1414 [0] = {
1415 .start = AT91SAM9G45_BASE_SSC1,
1416 .end = AT91SAM9G45_BASE_SSC1 + SZ_16K - 1,
1417 .flags = IORESOURCE_MEM,
1418 },
1419 [1] = {
1420 .start = AT91SAM9G45_ID_SSC1,
1421 .end = AT91SAM9G45_ID_SSC1,
1422 .flags = IORESOURCE_IRQ,
1423 },
1424};
1425
1426static struct platform_device at91sam9g45_ssc1_device = {
1427 .name = "ssc",
1428 .id = 1,
1429 .dev = {
1430 .dma_mask = &ssc1_dmamask,
1431 .coherent_dma_mask = DMA_BIT_MASK(32),
1432 },
1433 .resource = ssc1_resources,
1434 .num_resources = ARRAY_SIZE(ssc1_resources),
1435};
1436
1437static inline void configure_ssc1_pins(unsigned pins)
1438{
1439 if (pins & ATMEL_SSC_TF)
1440 at91_set_A_periph(AT91_PIN_PD14, 1);
1441 if (pins & ATMEL_SSC_TK)
1442 at91_set_A_periph(AT91_PIN_PD12, 1);
1443 if (pins & ATMEL_SSC_TD)
1444 at91_set_A_periph(AT91_PIN_PD10, 1);
1445 if (pins & ATMEL_SSC_RD)
1446 at91_set_A_periph(AT91_PIN_PD11, 1);
1447 if (pins & ATMEL_SSC_RK)
1448 at91_set_A_periph(AT91_PIN_PD13, 1);
1449 if (pins & ATMEL_SSC_RF)
1450 at91_set_A_periph(AT91_PIN_PD15, 1);
1451}
1452
1453/*
1454 * SSC controllers are accessed through library code, instead of any
1455 * kind of all-singing/all-dancing driver. For example one could be
1456 * used by a particular I2S audio codec's driver, while another one
1457 * on the same system might be used by a custom data capture driver.
1458 */
1459void __init at91_add_device_ssc(unsigned id, unsigned pins)
1460{
1461 struct platform_device *pdev;
1462
1463 /*
1464 * NOTE: caller is responsible for passing information matching
1465 * "pins" to whatever will be using each particular controller.
1466 */
1467 switch (id) {
1468 case AT91SAM9G45_ID_SSC0:
1469 pdev = &at91sam9g45_ssc0_device;
1470 configure_ssc0_pins(pins);
Nicolas Ferre789b23b2009-06-26 15:36:58 +01001471 break;
1472 case AT91SAM9G45_ID_SSC1:
1473 pdev = &at91sam9g45_ssc1_device;
1474 configure_ssc1_pins(pins);
Nicolas Ferre789b23b2009-06-26 15:36:58 +01001475 break;
1476 default:
1477 return;
1478 }
1479
1480 platform_device_register(pdev);
1481}
1482
1483#else
1484void __init at91_add_device_ssc(unsigned id, unsigned pins) {}
1485#endif
1486
1487
1488/* --------------------------------------------------------------------
1489 * UART
1490 * -------------------------------------------------------------------- */
1491
1492#if defined(CONFIG_SERIAL_ATMEL)
1493static struct resource dbgu_resources[] = {
1494 [0] = {
Jean-Christophe PLAGNIOL-VILLARD13079a72011-11-02 01:43:31 +08001495 .start = AT91SAM9G45_BASE_DBGU,
1496 .end = AT91SAM9G45_BASE_DBGU + SZ_512 - 1,
Nicolas Ferre789b23b2009-06-26 15:36:58 +01001497 .flags = IORESOURCE_MEM,
1498 },
1499 [1] = {
1500 .start = AT91_ID_SYS,
1501 .end = AT91_ID_SYS,
1502 .flags = IORESOURCE_IRQ,
1503 },
1504};
1505
1506static struct atmel_uart_data dbgu_data = {
1507 .use_dma_tx = 0,
1508 .use_dma_rx = 0,
Nicolas Ferre789b23b2009-06-26 15:36:58 +01001509};
1510
1511static u64 dbgu_dmamask = DMA_BIT_MASK(32);
1512
1513static struct platform_device at91sam9g45_dbgu_device = {
1514 .name = "atmel_usart",
1515 .id = 0,
1516 .dev = {
1517 .dma_mask = &dbgu_dmamask,
1518 .coherent_dma_mask = DMA_BIT_MASK(32),
1519 .platform_data = &dbgu_data,
1520 },
1521 .resource = dbgu_resources,
1522 .num_resources = ARRAY_SIZE(dbgu_resources),
1523};
1524
1525static inline void configure_dbgu_pins(void)
1526{
1527 at91_set_A_periph(AT91_PIN_PB12, 0); /* DRXD */
1528 at91_set_A_periph(AT91_PIN_PB13, 1); /* DTXD */
1529}
1530
1531static struct resource uart0_resources[] = {
1532 [0] = {
1533 .start = AT91SAM9G45_BASE_US0,
1534 .end = AT91SAM9G45_BASE_US0 + SZ_16K - 1,
1535 .flags = IORESOURCE_MEM,
1536 },
1537 [1] = {
1538 .start = AT91SAM9G45_ID_US0,
1539 .end = AT91SAM9G45_ID_US0,
1540 .flags = IORESOURCE_IRQ,
1541 },
1542};
1543
1544static struct atmel_uart_data uart0_data = {
1545 .use_dma_tx = 1,
1546 .use_dma_rx = 1,
1547};
1548
1549static u64 uart0_dmamask = DMA_BIT_MASK(32);
1550
1551static struct platform_device at91sam9g45_uart0_device = {
1552 .name = "atmel_usart",
1553 .id = 1,
1554 .dev = {
1555 .dma_mask = &uart0_dmamask,
1556 .coherent_dma_mask = DMA_BIT_MASK(32),
1557 .platform_data = &uart0_data,
1558 },
1559 .resource = uart0_resources,
1560 .num_resources = ARRAY_SIZE(uart0_resources),
1561};
1562
1563static inline void configure_usart0_pins(unsigned pins)
1564{
1565 at91_set_A_periph(AT91_PIN_PB19, 1); /* TXD0 */
1566 at91_set_A_periph(AT91_PIN_PB18, 0); /* RXD0 */
1567
1568 if (pins & ATMEL_UART_RTS)
1569 at91_set_B_periph(AT91_PIN_PB17, 0); /* RTS0 */
1570 if (pins & ATMEL_UART_CTS)
1571 at91_set_B_periph(AT91_PIN_PB15, 0); /* CTS0 */
1572}
1573
1574static struct resource uart1_resources[] = {
1575 [0] = {
1576 .start = AT91SAM9G45_BASE_US1,
1577 .end = AT91SAM9G45_BASE_US1 + SZ_16K - 1,
1578 .flags = IORESOURCE_MEM,
1579 },
1580 [1] = {
1581 .start = AT91SAM9G45_ID_US1,
1582 .end = AT91SAM9G45_ID_US1,
1583 .flags = IORESOURCE_IRQ,
1584 },
1585};
1586
1587static struct atmel_uart_data uart1_data = {
1588 .use_dma_tx = 1,
1589 .use_dma_rx = 1,
1590};
1591
1592static u64 uart1_dmamask = DMA_BIT_MASK(32);
1593
1594static struct platform_device at91sam9g45_uart1_device = {
1595 .name = "atmel_usart",
1596 .id = 2,
1597 .dev = {
1598 .dma_mask = &uart1_dmamask,
1599 .coherent_dma_mask = DMA_BIT_MASK(32),
1600 .platform_data = &uart1_data,
1601 },
1602 .resource = uart1_resources,
1603 .num_resources = ARRAY_SIZE(uart1_resources),
1604};
1605
1606static inline void configure_usart1_pins(unsigned pins)
1607{
1608 at91_set_A_periph(AT91_PIN_PB4, 1); /* TXD1 */
1609 at91_set_A_periph(AT91_PIN_PB5, 0); /* RXD1 */
1610
1611 if (pins & ATMEL_UART_RTS)
1612 at91_set_A_periph(AT91_PIN_PD16, 0); /* RTS1 */
1613 if (pins & ATMEL_UART_CTS)
1614 at91_set_A_periph(AT91_PIN_PD17, 0); /* CTS1 */
1615}
1616
1617static struct resource uart2_resources[] = {
1618 [0] = {
1619 .start = AT91SAM9G45_BASE_US2,
1620 .end = AT91SAM9G45_BASE_US2 + SZ_16K - 1,
1621 .flags = IORESOURCE_MEM,
1622 },
1623 [1] = {
1624 .start = AT91SAM9G45_ID_US2,
1625 .end = AT91SAM9G45_ID_US2,
1626 .flags = IORESOURCE_IRQ,
1627 },
1628};
1629
1630static struct atmel_uart_data uart2_data = {
1631 .use_dma_tx = 1,
1632 .use_dma_rx = 1,
1633};
1634
1635static u64 uart2_dmamask = DMA_BIT_MASK(32);
1636
1637static struct platform_device at91sam9g45_uart2_device = {
1638 .name = "atmel_usart",
1639 .id = 3,
1640 .dev = {
1641 .dma_mask = &uart2_dmamask,
1642 .coherent_dma_mask = DMA_BIT_MASK(32),
1643 .platform_data = &uart2_data,
1644 },
1645 .resource = uart2_resources,
1646 .num_resources = ARRAY_SIZE(uart2_resources),
1647};
1648
1649static inline void configure_usart2_pins(unsigned pins)
1650{
1651 at91_set_A_periph(AT91_PIN_PB6, 1); /* TXD2 */
1652 at91_set_A_periph(AT91_PIN_PB7, 0); /* RXD2 */
1653
1654 if (pins & ATMEL_UART_RTS)
1655 at91_set_B_periph(AT91_PIN_PC9, 0); /* RTS2 */
1656 if (pins & ATMEL_UART_CTS)
1657 at91_set_B_periph(AT91_PIN_PC11, 0); /* CTS2 */
1658}
1659
1660static struct resource uart3_resources[] = {
1661 [0] = {
1662 .start = AT91SAM9G45_BASE_US3,
1663 .end = AT91SAM9G45_BASE_US3 + SZ_16K - 1,
1664 .flags = IORESOURCE_MEM,
1665 },
1666 [1] = {
1667 .start = AT91SAM9G45_ID_US3,
1668 .end = AT91SAM9G45_ID_US3,
1669 .flags = IORESOURCE_IRQ,
1670 },
1671};
1672
1673static struct atmel_uart_data uart3_data = {
1674 .use_dma_tx = 1,
1675 .use_dma_rx = 1,
1676};
1677
1678static u64 uart3_dmamask = DMA_BIT_MASK(32);
1679
1680static struct platform_device at91sam9g45_uart3_device = {
1681 .name = "atmel_usart",
1682 .id = 4,
1683 .dev = {
1684 .dma_mask = &uart3_dmamask,
1685 .coherent_dma_mask = DMA_BIT_MASK(32),
1686 .platform_data = &uart3_data,
1687 },
1688 .resource = uart3_resources,
1689 .num_resources = ARRAY_SIZE(uart3_resources),
1690};
1691
1692static inline void configure_usart3_pins(unsigned pins)
1693{
1694 at91_set_A_periph(AT91_PIN_PB8, 1); /* TXD3 */
1695 at91_set_A_periph(AT91_PIN_PB9, 0); /* RXD3 */
1696
1697 if (pins & ATMEL_UART_RTS)
1698 at91_set_B_periph(AT91_PIN_PA23, 0); /* RTS3 */
1699 if (pins & ATMEL_UART_CTS)
1700 at91_set_B_periph(AT91_PIN_PA24, 0); /* CTS3 */
1701}
1702
1703static struct platform_device *__initdata at91_uarts[ATMEL_MAX_UART]; /* the UARTs to use */
Nicolas Ferre789b23b2009-06-26 15:36:58 +01001704
1705void __init at91_register_uart(unsigned id, unsigned portnr, unsigned pins)
1706{
1707 struct platform_device *pdev;
Jean-Christophe PLAGNIOL-VILLARD2b348e22011-04-10 14:10:05 +08001708 struct atmel_uart_data *pdata;
Nicolas Ferre789b23b2009-06-26 15:36:58 +01001709
1710 switch (id) {
1711 case 0: /* DBGU */
1712 pdev = &at91sam9g45_dbgu_device;
1713 configure_dbgu_pins();
Nicolas Ferre789b23b2009-06-26 15:36:58 +01001714 break;
1715 case AT91SAM9G45_ID_US0:
1716 pdev = &at91sam9g45_uart0_device;
1717 configure_usart0_pins(pins);
Nicolas Ferre789b23b2009-06-26 15:36:58 +01001718 break;
1719 case AT91SAM9G45_ID_US1:
1720 pdev = &at91sam9g45_uart1_device;
1721 configure_usart1_pins(pins);
Nicolas Ferre789b23b2009-06-26 15:36:58 +01001722 break;
1723 case AT91SAM9G45_ID_US2:
1724 pdev = &at91sam9g45_uart2_device;
1725 configure_usart2_pins(pins);
Nicolas Ferre789b23b2009-06-26 15:36:58 +01001726 break;
1727 case AT91SAM9G45_ID_US3:
1728 pdev = &at91sam9g45_uart3_device;
1729 configure_usart3_pins(pins);
Nicolas Ferre789b23b2009-06-26 15:36:58 +01001730 break;
1731 default:
1732 return;
1733 }
Jean-Christophe PLAGNIOL-VILLARD2b348e22011-04-10 14:10:05 +08001734 pdata = pdev->dev.platform_data;
1735 pdata->num = portnr; /* update to mapped ID */
Nicolas Ferre789b23b2009-06-26 15:36:58 +01001736
1737 if (portnr < ATMEL_MAX_UART)
1738 at91_uarts[portnr] = pdev;
1739}
1740
1741void __init at91_set_serial_console(unsigned portnr)
1742{
Jean-Christophe PLAGNIOL-VILLARDbd602992011-02-02 07:27:07 +01001743 if (portnr < ATMEL_MAX_UART) {
Nicolas Ferre789b23b2009-06-26 15:36:58 +01001744 atmel_default_console_device = at91_uarts[portnr];
Jean-Christophe PLAGNIOL-VILLARD5c1f9662011-06-21 11:24:33 +08001745 at91sam9g45_set_console_clock(at91_uarts[portnr]->id);
Jean-Christophe PLAGNIOL-VILLARDbd602992011-02-02 07:27:07 +01001746 }
Nicolas Ferre789b23b2009-06-26 15:36:58 +01001747}
1748
1749void __init at91_add_device_serial(void)
1750{
1751 int i;
1752
1753 for (i = 0; i < ATMEL_MAX_UART; i++) {
1754 if (at91_uarts[i])
1755 platform_device_register(at91_uarts[i]);
1756 }
1757
1758 if (!atmel_default_console_device)
1759 printk(KERN_INFO "AT91: No default serial console defined.\n");
1760}
1761#else
1762void __init at91_register_uart(unsigned id, unsigned portnr, unsigned pins) {}
1763void __init at91_set_serial_console(unsigned portnr) {}
1764void __init at91_add_device_serial(void) {}
1765#endif
1766
1767
1768/* -------------------------------------------------------------------- */
1769/*
1770 * These devices are always present and don't need any board-specific
1771 * setup.
1772 */
1773static int __init at91_add_standard_devices(void)
1774{
Nicolas Ferre40262b22009-07-24 11:43:01 +01001775 at91_add_device_hdmac();
Nicolas Ferre789b23b2009-06-26 15:36:58 +01001776 at91_add_device_rtc();
1777 at91_add_device_rtt();
Peter Korsgaard237a62a2011-10-06 17:41:33 +02001778 at91_add_device_trng();
Nicolas Ferre789b23b2009-06-26 15:36:58 +01001779 at91_add_device_watchdog();
1780 at91_add_device_tc();
1781 return 0;
1782}
1783
1784arch_initcall(at91_add_standard_devices);