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