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