blob: d298fb7cb210379a771ee52c98b05260a378769c [file] [log] [blame]
Andrew Victor2b3b3512008-01-24 15:10:39 +01001/*
2 * arch/arm/mach-at91/at91cap9_devices.c
3 *
4 * Copyright (C) 2007 Stelian Pop <stelian.pop@leadtechdesign.com>
5 * Copyright (C) 2007 Lead Tech Design <www.leadtechdesign.com>
6 * Copyright (C) 2007 Atmel Corporation.
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 */
14#include <asm/mach/arch.h>
15#include <asm/mach/map.h>
Stelian Pop7be90a62008-10-22 13:52:08 +010016#include <asm/mach/irq.h>
Andrew Victor2b3b3512008-01-24 15:10:39 +010017
18#include <linux/dma-mapping.h>
Russell King2f8163b2011-07-26 10:53:52 +010019#include <linux/gpio.h>
Andrew Victor2b3b3512008-01-24 15:10:39 +010020#include <linux/platform_device.h>
Andrew Victor11aadac2008-04-15 21:16:38 +010021#include <linux/i2c-gpio.h>
Andrew Victor2b3b3512008-01-24 15:10:39 +010022
23#include <video/atmel_lcdc.h>
24
Russell Kinga09e64f2008-08-05 16:14:15 +010025#include <mach/board.h>
Stelian Pop7be90a62008-10-22 13:52:08 +010026#include <mach/cpu.h>
Russell Kinga09e64f2008-08-05 16:14:15 +010027#include <mach/at91cap9.h>
28#include <mach/at91cap9_matrix.h>
29#include <mach/at91sam9_smc.h>
Andrew Victor2b3b3512008-01-24 15:10:39 +010030
31#include "generic.h"
32
33
34/* --------------------------------------------------------------------
35 * USB Host
36 * -------------------------------------------------------------------- */
37
38#if defined(CONFIG_USB_OHCI_HCD) || defined(CONFIG_USB_OHCI_HCD_MODULE)
39static u64 ohci_dmamask = DMA_BIT_MASK(32);
40static struct at91_usbh_data usbh_data;
41
42static struct resource usbh_resources[] = {
43 [0] = {
44 .start = AT91CAP9_UHP_BASE,
45 .end = AT91CAP9_UHP_BASE + SZ_1M - 1,
46 .flags = IORESOURCE_MEM,
47 },
48 [1] = {
49 .start = AT91CAP9_ID_UHP,
50 .end = AT91CAP9_ID_UHP,
51 .flags = IORESOURCE_IRQ,
52 },
53};
54
55static struct platform_device at91_usbh_device = {
56 .name = "at91_ohci",
57 .id = -1,
58 .dev = {
59 .dma_mask = &ohci_dmamask,
60 .coherent_dma_mask = DMA_BIT_MASK(32),
61 .platform_data = &usbh_data,
62 },
63 .resource = usbh_resources,
64 .num_resources = ARRAY_SIZE(usbh_resources),
65};
66
67void __init at91_add_device_usbh(struct at91_usbh_data *data)
68{
69 int i;
70
71 if (!data)
72 return;
73
Stelian Pop7be90a62008-10-22 13:52:08 +010074 if (cpu_is_at91cap9_revB())
Thomas Gleixner6845664a2011-03-24 13:25:22 +010075 irq_set_irq_type(AT91CAP9_ID_UHP, IRQ_TYPE_LEVEL_HIGH);
Stelian Pop7be90a62008-10-22 13:52:08 +010076
Andrew Victor2b3b3512008-01-24 15:10:39 +010077 /* Enable VBus control for UHP ports */
78 for (i = 0; i < data->ports; i++) {
Jean-Christophe PLAGNIOL-VILLARDcc9f9ae2011-09-19 15:28:25 +080079 if (gpio_is_valid(data->vbus_pin[i]))
Andrew Victor2b3b3512008-01-24 15:10:39 +010080 at91_set_gpio_output(data->vbus_pin[i], 0);
81 }
82
Thomas Petazzoni1fcaea72011-07-13 11:29:18 +020083 /* Enable overcurrent notification */
84 for (i = 0; i < data->ports; i++) {
85 if (data->overcurrent_pin[i])
86 at91_set_gpio_input(data->overcurrent_pin[i], 1);
87 }
88
Andrew Victor2b3b3512008-01-24 15:10:39 +010089 usbh_data = *data;
90 platform_device_register(&at91_usbh_device);
91}
92#else
93void __init at91_add_device_usbh(struct at91_usbh_data *data) {}
94#endif
95
96
97/* --------------------------------------------------------------------
Stelian Pop7c8cf662008-04-05 21:15:25 +010098 * USB HS Device (Gadget)
99 * -------------------------------------------------------------------- */
100
Jochen Friedrichdd0b3822011-10-25 20:51:06 +0200101#if defined(CONFIG_USB_ATMEL_USBA) || defined(CONFIG_USB_ATMEL_USBA_MODULE)
Stelian Pop7c8cf662008-04-05 21:15:25 +0100102
103static struct resource usba_udc_resources[] = {
104 [0] = {
105 .start = AT91CAP9_UDPHS_FIFO,
106 .end = AT91CAP9_UDPHS_FIFO + SZ_512K - 1,
107 .flags = IORESOURCE_MEM,
108 },
109 [1] = {
110 .start = AT91CAP9_BASE_UDPHS,
111 .end = AT91CAP9_BASE_UDPHS + SZ_1K - 1,
112 .flags = IORESOURCE_MEM,
113 },
114 [2] = {
115 .start = AT91CAP9_ID_UDPHS,
116 .end = AT91CAP9_ID_UDPHS,
117 .flags = IORESOURCE_IRQ,
118 },
119};
120
121#define EP(nam, idx, maxpkt, maxbk, dma, isoc) \
122 [idx] = { \
123 .name = nam, \
124 .index = idx, \
125 .fifo_size = maxpkt, \
126 .nr_banks = maxbk, \
127 .can_dma = dma, \
128 .can_isoc = isoc, \
129 }
130
131static struct usba_ep_data usba_udc_ep[] = {
132 EP("ep0", 0, 64, 1, 0, 0),
133 EP("ep1", 1, 1024, 3, 1, 1),
134 EP("ep2", 2, 1024, 3, 1, 1),
135 EP("ep3", 3, 1024, 2, 1, 1),
136 EP("ep4", 4, 1024, 2, 1, 1),
137 EP("ep5", 5, 1024, 2, 1, 0),
138 EP("ep6", 6, 1024, 2, 1, 0),
139 EP("ep7", 7, 1024, 2, 0, 0),
140};
141
142#undef EP
143
144/*
145 * pdata doesn't have room for any endpoints, so we need to
146 * append room for the ones we need right after it.
147 */
148static struct {
149 struct usba_platform_data pdata;
150 struct usba_ep_data ep[8];
151} usba_udc_data;
152
153static struct platform_device at91_usba_udc_device = {
154 .name = "atmel_usba_udc",
155 .id = -1,
156 .dev = {
157 .platform_data = &usba_udc_data.pdata,
158 },
159 .resource = usba_udc_resources,
160 .num_resources = ARRAY_SIZE(usba_udc_resources),
161};
162
163void __init at91_add_device_usba(struct usba_platform_data *data)
164{
Stelian Pop7be90a62008-10-22 13:52:08 +0100165 if (cpu_is_at91cap9_revB()) {
Thomas Gleixner6845664a2011-03-24 13:25:22 +0100166 irq_set_irq_type(AT91CAP9_ID_UDPHS, IRQ_TYPE_LEVEL_HIGH);
Stelian Pop7be90a62008-10-22 13:52:08 +0100167 at91_sys_write(AT91_MATRIX_UDPHS, AT91_MATRIX_SELECT_UDPHS |
168 AT91_MATRIX_UDPHS_BYPASS_LOCK);
169 }
170 else
171 at91_sys_write(AT91_MATRIX_UDPHS, AT91_MATRIX_SELECT_UDPHS);
Stelian Pop7c8cf662008-04-05 21:15:25 +0100172
173 /*
174 * Invalid pins are 0 on AT91, but the usba driver is shared
175 * with AVR32, which use negative values instead. Once/if
176 * gpio_is_valid() is ported to AT91, revisit this code.
177 */
178 usba_udc_data.pdata.vbus_pin = -EINVAL;
179 usba_udc_data.pdata.num_ep = ARRAY_SIZE(usba_udc_ep);
Justin P. Mattock6eab04a2011-04-08 19:49:08 -0700180 memcpy(usba_udc_data.ep, usba_udc_ep, sizeof(usba_udc_ep));
Stelian Pop7c8cf662008-04-05 21:15:25 +0100181
Jean-Christophe PLAGNIOL-VILLARDcc9f9ae2011-09-19 15:28:25 +0800182 if (data && gpio_is_valid(data->vbus_pin)) {
Stelian Pop7c8cf662008-04-05 21:15:25 +0100183 at91_set_gpio_input(data->vbus_pin, 0);
184 at91_set_deglitch(data->vbus_pin, 1);
185 usba_udc_data.pdata.vbus_pin = data->vbus_pin;
186 }
187
188 /* Pullup pin is handled internally by USB device peripheral */
189
Stelian Pop7c8cf662008-04-05 21:15:25 +0100190 platform_device_register(&at91_usba_udc_device);
191}
192#else
193void __init at91_add_device_usba(struct usba_platform_data *data) {}
194#endif
195
196
197/* --------------------------------------------------------------------
Andrew Victor2b3b3512008-01-24 15:10:39 +0100198 * Ethernet
199 * -------------------------------------------------------------------- */
200
201#if defined(CONFIG_MACB) || defined(CONFIG_MACB_MODULE)
202static u64 eth_dmamask = DMA_BIT_MASK(32);
Jamie Iles84e0cdb2011-03-08 20:17:06 +0000203static struct macb_platform_data eth_data;
Andrew Victor2b3b3512008-01-24 15:10:39 +0100204
205static struct resource eth_resources[] = {
206 [0] = {
207 .start = AT91CAP9_BASE_EMAC,
208 .end = AT91CAP9_BASE_EMAC + SZ_16K - 1,
209 .flags = IORESOURCE_MEM,
210 },
211 [1] = {
212 .start = AT91CAP9_ID_EMAC,
213 .end = AT91CAP9_ID_EMAC,
214 .flags = IORESOURCE_IRQ,
215 },
216};
217
218static struct platform_device at91cap9_eth_device = {
219 .name = "macb",
220 .id = -1,
221 .dev = {
222 .dma_mask = &eth_dmamask,
223 .coherent_dma_mask = DMA_BIT_MASK(32),
224 .platform_data = &eth_data,
225 },
226 .resource = eth_resources,
227 .num_resources = ARRAY_SIZE(eth_resources),
228};
229
Jamie Iles84e0cdb2011-03-08 20:17:06 +0000230void __init at91_add_device_eth(struct macb_platform_data *data)
Andrew Victor2b3b3512008-01-24 15:10:39 +0100231{
232 if (!data)
233 return;
234
Jean-Christophe PLAGNIOL-VILLARDcc9f9ae2011-09-19 15:28:25 +0800235 if (gpio_is_valid(data->phy_irq_pin)) {
Andrew Victor2b3b3512008-01-24 15:10:39 +0100236 at91_set_gpio_input(data->phy_irq_pin, 0);
237 at91_set_deglitch(data->phy_irq_pin, 1);
238 }
239
240 /* Pins used for MII and RMII */
241 at91_set_A_periph(AT91_PIN_PB21, 0); /* ETXCK_EREFCK */
242 at91_set_A_periph(AT91_PIN_PB22, 0); /* ERXDV */
243 at91_set_A_periph(AT91_PIN_PB25, 0); /* ERX0 */
244 at91_set_A_periph(AT91_PIN_PB26, 0); /* ERX1 */
245 at91_set_A_periph(AT91_PIN_PB27, 0); /* ERXER */
246 at91_set_A_periph(AT91_PIN_PB28, 0); /* ETXEN */
247 at91_set_A_periph(AT91_PIN_PB23, 0); /* ETX0 */
248 at91_set_A_periph(AT91_PIN_PB24, 0); /* ETX1 */
249 at91_set_A_periph(AT91_PIN_PB30, 0); /* EMDIO */
250 at91_set_A_periph(AT91_PIN_PB29, 0); /* EMDC */
251
252 if (!data->is_rmii) {
253 at91_set_B_periph(AT91_PIN_PC25, 0); /* ECRS */
254 at91_set_B_periph(AT91_PIN_PC26, 0); /* ECOL */
255 at91_set_B_periph(AT91_PIN_PC22, 0); /* ERX2 */
256 at91_set_B_periph(AT91_PIN_PC23, 0); /* ERX3 */
257 at91_set_B_periph(AT91_PIN_PC27, 0); /* ERXCK */
258 at91_set_B_periph(AT91_PIN_PC20, 0); /* ETX2 */
259 at91_set_B_periph(AT91_PIN_PC21, 0); /* ETX3 */
260 at91_set_B_periph(AT91_PIN_PC24, 0); /* ETXER */
261 }
262
263 eth_data = *data;
264 platform_device_register(&at91cap9_eth_device);
265}
266#else
Jamie Iles84e0cdb2011-03-08 20:17:06 +0000267void __init at91_add_device_eth(struct macb_platform_data *data) {}
Andrew Victor2b3b3512008-01-24 15:10:39 +0100268#endif
269
270
271/* --------------------------------------------------------------------
272 * MMC / SD
273 * -------------------------------------------------------------------- */
274
275#if defined(CONFIG_MMC_AT91) || defined(CONFIG_MMC_AT91_MODULE)
276static u64 mmc_dmamask = DMA_BIT_MASK(32);
277static struct at91_mmc_data mmc0_data, mmc1_data;
278
279static struct resource mmc0_resources[] = {
280 [0] = {
281 .start = AT91CAP9_BASE_MCI0,
282 .end = AT91CAP9_BASE_MCI0 + SZ_16K - 1,
283 .flags = IORESOURCE_MEM,
284 },
285 [1] = {
286 .start = AT91CAP9_ID_MCI0,
287 .end = AT91CAP9_ID_MCI0,
288 .flags = IORESOURCE_IRQ,
289 },
290};
291
292static struct platform_device at91cap9_mmc0_device = {
293 .name = "at91_mci",
294 .id = 0,
295 .dev = {
296 .dma_mask = &mmc_dmamask,
297 .coherent_dma_mask = DMA_BIT_MASK(32),
298 .platform_data = &mmc0_data,
299 },
300 .resource = mmc0_resources,
301 .num_resources = ARRAY_SIZE(mmc0_resources),
302};
303
304static struct resource mmc1_resources[] = {
305 [0] = {
306 .start = AT91CAP9_BASE_MCI1,
307 .end = AT91CAP9_BASE_MCI1 + SZ_16K - 1,
308 .flags = IORESOURCE_MEM,
309 },
310 [1] = {
311 .start = AT91CAP9_ID_MCI1,
312 .end = AT91CAP9_ID_MCI1,
313 .flags = IORESOURCE_IRQ,
314 },
315};
316
317static struct platform_device at91cap9_mmc1_device = {
318 .name = "at91_mci",
319 .id = 1,
320 .dev = {
321 .dma_mask = &mmc_dmamask,
322 .coherent_dma_mask = DMA_BIT_MASK(32),
323 .platform_data = &mmc1_data,
324 },
325 .resource = mmc1_resources,
326 .num_resources = ARRAY_SIZE(mmc1_resources),
327};
328
329void __init at91_add_device_mmc(short mmc_id, struct at91_mmc_data *data)
330{
331 if (!data)
332 return;
333
334 /* input/irq */
Jean-Christophe PLAGNIOL-VILLARDcc9f9ae2011-09-19 15:28:25 +0800335 if (gpio_is_valid(data->det_pin)) {
Andrew Victor2b3b3512008-01-24 15:10:39 +0100336 at91_set_gpio_input(data->det_pin, 1);
337 at91_set_deglitch(data->det_pin, 1);
338 }
Jean-Christophe PLAGNIOL-VILLARDcc9f9ae2011-09-19 15:28:25 +0800339 if (gpio_is_valid(data->wp_pin))
Andrew Victor2b3b3512008-01-24 15:10:39 +0100340 at91_set_gpio_input(data->wp_pin, 1);
Jean-Christophe PLAGNIOL-VILLARDcc9f9ae2011-09-19 15:28:25 +0800341 if (gpio_is_valid(data->vcc_pin))
Andrew Victor2b3b3512008-01-24 15:10:39 +0100342 at91_set_gpio_output(data->vcc_pin, 0);
343
344 if (mmc_id == 0) { /* MCI0 */
345 /* CLK */
346 at91_set_A_periph(AT91_PIN_PA2, 0);
347
348 /* CMD */
349 at91_set_A_periph(AT91_PIN_PA1, 1);
350
351 /* DAT0, maybe DAT1..DAT3 */
352 at91_set_A_periph(AT91_PIN_PA0, 1);
353 if (data->wire4) {
354 at91_set_A_periph(AT91_PIN_PA3, 1);
355 at91_set_A_periph(AT91_PIN_PA4, 1);
356 at91_set_A_periph(AT91_PIN_PA5, 1);
357 }
358
359 mmc0_data = *data;
Andrew Victor2b3b3512008-01-24 15:10:39 +0100360 platform_device_register(&at91cap9_mmc0_device);
361 } else { /* MCI1 */
362 /* CLK */
363 at91_set_A_periph(AT91_PIN_PA16, 0);
364
365 /* CMD */
366 at91_set_A_periph(AT91_PIN_PA17, 1);
367
368 /* DAT0, maybe DAT1..DAT3 */
369 at91_set_A_periph(AT91_PIN_PA18, 1);
370 if (data->wire4) {
371 at91_set_A_periph(AT91_PIN_PA19, 1);
372 at91_set_A_periph(AT91_PIN_PA20, 1);
373 at91_set_A_periph(AT91_PIN_PA21, 1);
374 }
375
376 mmc1_data = *data;
Andrew Victor2b3b3512008-01-24 15:10:39 +0100377 platform_device_register(&at91cap9_mmc1_device);
378 }
379}
380#else
381void __init at91_add_device_mmc(short mmc_id, struct at91_mmc_data *data) {}
382#endif
383
384
385/* --------------------------------------------------------------------
386 * NAND / SmartMedia
387 * -------------------------------------------------------------------- */
388
Pieter du Preezf6ed6f72008-08-01 10:06:40 +0100389#if defined(CONFIG_MTD_NAND_ATMEL) || defined(CONFIG_MTD_NAND_ATMEL_MODULE)
HÃ¥vard Skinnemoen3c3796c2008-06-06 18:04:53 +0200390static struct atmel_nand_data nand_data;
Andrew Victor2b3b3512008-01-24 15:10:39 +0100391
392#define NAND_BASE AT91_CHIPSELECT_3
393
394static struct resource nand_resources[] = {
Andrew Victord7a24152008-04-02 21:44:44 +0100395 [0] = {
Andrew Victor2b3b3512008-01-24 15:10:39 +0100396 .start = NAND_BASE,
397 .end = NAND_BASE + SZ_256M - 1,
398 .flags = IORESOURCE_MEM,
Andrew Victord7a24152008-04-02 21:44:44 +0100399 },
400 [1] = {
Jean-Christophe PLAGNIOL-VILLARDd28edd12011-09-18 09:31:56 +0800401 .start = AT91CAP9_BASE_ECC,
402 .end = AT91CAP9_BASE_ECC + SZ_512 - 1,
Andrew Victord7a24152008-04-02 21:44:44 +0100403 .flags = IORESOURCE_MEM,
Andrew Victor2b3b3512008-01-24 15:10:39 +0100404 }
405};
406
407static struct platform_device at91cap9_nand_device = {
HÃ¥vard Skinnemoen3c3796c2008-06-06 18:04:53 +0200408 .name = "atmel_nand",
Andrew Victor2b3b3512008-01-24 15:10:39 +0100409 .id = -1,
410 .dev = {
411 .platform_data = &nand_data,
412 },
413 .resource = nand_resources,
414 .num_resources = ARRAY_SIZE(nand_resources),
415};
416
HÃ¥vard Skinnemoen3c3796c2008-06-06 18:04:53 +0200417void __init at91_add_device_nand(struct atmel_nand_data *data)
Andrew Victor2b3b3512008-01-24 15:10:39 +0100418{
Andrew Victor461d3b42008-10-06 20:01:00 +0100419 unsigned long csa;
Andrew Victor2b3b3512008-01-24 15:10:39 +0100420
421 if (!data)
422 return;
423
424 csa = at91_sys_read(AT91_MATRIX_EBICSA);
Andrew Victor461d3b42008-10-06 20:01:00 +0100425 at91_sys_write(AT91_MATRIX_EBICSA, csa | AT91_MATRIX_EBI_CS3A_SMC_SMARTMEDIA);
Andrew Victor2b3b3512008-01-24 15:10:39 +0100426
427 /* enable pin */
Jean-Christophe PLAGNIOL-VILLARDcc9f9ae2011-09-19 15:28:25 +0800428 if (gpio_is_valid(data->enable_pin))
Andrew Victor2b3b3512008-01-24 15:10:39 +0100429 at91_set_gpio_output(data->enable_pin, 1);
430
431 /* ready/busy pin */
Jean-Christophe PLAGNIOL-VILLARDcc9f9ae2011-09-19 15:28:25 +0800432 if (gpio_is_valid(data->rdy_pin))
Andrew Victor2b3b3512008-01-24 15:10:39 +0100433 at91_set_gpio_input(data->rdy_pin, 1);
434
435 /* card detect pin */
Jean-Christophe PLAGNIOL-VILLARDcc9f9ae2011-09-19 15:28:25 +0800436 if (gpio_is_valid(data->det_pin))
Andrew Victor2b3b3512008-01-24 15:10:39 +0100437 at91_set_gpio_input(data->det_pin, 1);
438
439 nand_data = *data;
440 platform_device_register(&at91cap9_nand_device);
441}
442#else
HÃ¥vard Skinnemoen3c3796c2008-06-06 18:04:53 +0200443void __init at91_add_device_nand(struct atmel_nand_data *data) {}
Andrew Victor2b3b3512008-01-24 15:10:39 +0100444#endif
445
Andrew Victor11aadac2008-04-15 21:16:38 +0100446
Andrew Victor2b3b3512008-01-24 15:10:39 +0100447/* --------------------------------------------------------------------
448 * TWI (i2c)
449 * -------------------------------------------------------------------- */
450
451/*
452 * Prefer the GPIO code since the TWI controller isn't robust
453 * (gets overruns and underruns under load) and can only issue
454 * repeated STARTs in one scenario (the driver doesn't yet handle them).
455 */
456#if defined(CONFIG_I2C_GPIO) || defined(CONFIG_I2C_GPIO_MODULE)
457
458static struct i2c_gpio_platform_data pdata = {
459 .sda_pin = AT91_PIN_PB4,
460 .sda_is_open_drain = 1,
461 .scl_pin = AT91_PIN_PB5,
462 .scl_is_open_drain = 1,
463 .udelay = 2, /* ~100 kHz */
464};
465
466static struct platform_device at91cap9_twi_device = {
467 .name = "i2c-gpio",
468 .id = -1,
469 .dev.platform_data = &pdata,
470};
471
472void __init at91_add_device_i2c(struct i2c_board_info *devices, int nr_devices)
473{
474 at91_set_GPIO_periph(AT91_PIN_PB4, 1); /* TWD (SDA) */
475 at91_set_multi_drive(AT91_PIN_PB4, 1);
476
477 at91_set_GPIO_periph(AT91_PIN_PB5, 1); /* TWCK (SCL) */
478 at91_set_multi_drive(AT91_PIN_PB5, 1);
479
480 i2c_register_board_info(0, devices, nr_devices);
481 platform_device_register(&at91cap9_twi_device);
482}
483
484#elif defined(CONFIG_I2C_AT91) || defined(CONFIG_I2C_AT91_MODULE)
485
486static struct resource twi_resources[] = {
487 [0] = {
488 .start = AT91CAP9_BASE_TWI,
489 .end = AT91CAP9_BASE_TWI + SZ_16K - 1,
490 .flags = IORESOURCE_MEM,
491 },
492 [1] = {
493 .start = AT91CAP9_ID_TWI,
494 .end = AT91CAP9_ID_TWI,
495 .flags = IORESOURCE_IRQ,
496 },
497};
498
499static struct platform_device at91cap9_twi_device = {
500 .name = "at91_i2c",
501 .id = -1,
502 .resource = twi_resources,
503 .num_resources = ARRAY_SIZE(twi_resources),
504};
505
506void __init at91_add_device_i2c(struct i2c_board_info *devices, int nr_devices)
507{
508 /* pins used for TWI interface */
509 at91_set_B_periph(AT91_PIN_PB4, 0); /* TWD */
510 at91_set_multi_drive(AT91_PIN_PB4, 1);
511
512 at91_set_B_periph(AT91_PIN_PB5, 0); /* TWCK */
513 at91_set_multi_drive(AT91_PIN_PB5, 1);
514
515 i2c_register_board_info(0, devices, nr_devices);
516 platform_device_register(&at91cap9_twi_device);
517}
518#else
519void __init at91_add_device_i2c(struct i2c_board_info *devices, int nr_devices) {}
520#endif
521
522/* --------------------------------------------------------------------
523 * SPI
524 * -------------------------------------------------------------------- */
525
526#if defined(CONFIG_SPI_ATMEL) || defined(CONFIG_SPI_ATMEL_MODULE)
527static u64 spi_dmamask = DMA_BIT_MASK(32);
528
529static struct resource spi0_resources[] = {
530 [0] = {
531 .start = AT91CAP9_BASE_SPI0,
532 .end = AT91CAP9_BASE_SPI0 + SZ_16K - 1,
533 .flags = IORESOURCE_MEM,
534 },
535 [1] = {
536 .start = AT91CAP9_ID_SPI0,
537 .end = AT91CAP9_ID_SPI0,
538 .flags = IORESOURCE_IRQ,
539 },
540};
541
542static struct platform_device at91cap9_spi0_device = {
543 .name = "atmel_spi",
544 .id = 0,
545 .dev = {
546 .dma_mask = &spi_dmamask,
547 .coherent_dma_mask = DMA_BIT_MASK(32),
548 },
549 .resource = spi0_resources,
550 .num_resources = ARRAY_SIZE(spi0_resources),
551};
552
553static const unsigned spi0_standard_cs[4] = { AT91_PIN_PA5, AT91_PIN_PA3, AT91_PIN_PD0, AT91_PIN_PD1 };
554
555static struct resource spi1_resources[] = {
556 [0] = {
557 .start = AT91CAP9_BASE_SPI1,
558 .end = AT91CAP9_BASE_SPI1 + SZ_16K - 1,
559 .flags = IORESOURCE_MEM,
560 },
561 [1] = {
562 .start = AT91CAP9_ID_SPI1,
563 .end = AT91CAP9_ID_SPI1,
564 .flags = IORESOURCE_IRQ,
565 },
566};
567
568static struct platform_device at91cap9_spi1_device = {
569 .name = "atmel_spi",
570 .id = 1,
571 .dev = {
572 .dma_mask = &spi_dmamask,
573 .coherent_dma_mask = DMA_BIT_MASK(32),
574 },
575 .resource = spi1_resources,
576 .num_resources = ARRAY_SIZE(spi1_resources),
577};
578
579static const unsigned spi1_standard_cs[4] = { AT91_PIN_PB15, AT91_PIN_PB16, AT91_PIN_PB17, AT91_PIN_PB18 };
580
581void __init at91_add_device_spi(struct spi_board_info *devices, int nr_devices)
582{
583 int i;
584 unsigned long cs_pin;
585 short enable_spi0 = 0;
586 short enable_spi1 = 0;
587
588 /* Choose SPI chip-selects */
589 for (i = 0; i < nr_devices; i++) {
590 if (devices[i].controller_data)
591 cs_pin = (unsigned long) devices[i].controller_data;
592 else if (devices[i].bus_num == 0)
593 cs_pin = spi0_standard_cs[devices[i].chip_select];
594 else
595 cs_pin = spi1_standard_cs[devices[i].chip_select];
596
597 if (devices[i].bus_num == 0)
598 enable_spi0 = 1;
599 else
600 enable_spi1 = 1;
601
602 /* enable chip-select pin */
603 at91_set_gpio_output(cs_pin, 1);
604
605 /* pass chip-select pin to driver */
606 devices[i].controller_data = (void *) cs_pin;
607 }
608
609 spi_register_board_info(devices, nr_devices);
610
611 /* Configure SPI bus(es) */
612 if (enable_spi0) {
613 at91_set_B_periph(AT91_PIN_PA0, 0); /* SPI0_MISO */
614 at91_set_B_periph(AT91_PIN_PA1, 0); /* SPI0_MOSI */
615 at91_set_B_periph(AT91_PIN_PA2, 0); /* SPI0_SPCK */
616
Andrew Victor2b3b3512008-01-24 15:10:39 +0100617 platform_device_register(&at91cap9_spi0_device);
618 }
619 if (enable_spi1) {
620 at91_set_A_periph(AT91_PIN_PB12, 0); /* SPI1_MISO */
621 at91_set_A_periph(AT91_PIN_PB13, 0); /* SPI1_MOSI */
622 at91_set_A_periph(AT91_PIN_PB14, 0); /* SPI1_SPCK */
623
Andrew Victor2b3b3512008-01-24 15:10:39 +0100624 platform_device_register(&at91cap9_spi1_device);
625 }
626}
627#else
628void __init at91_add_device_spi(struct spi_board_info *devices, int nr_devices) {}
629#endif
630
631
632/* --------------------------------------------------------------------
Andrew Victore5f40bf2008-04-02 21:58:00 +0100633 * Timer/Counter block
634 * -------------------------------------------------------------------- */
635
636#ifdef CONFIG_ATMEL_TCLIB
637
638static struct resource tcb_resources[] = {
639 [0] = {
640 .start = AT91CAP9_BASE_TCB0,
641 .end = AT91CAP9_BASE_TCB0 + SZ_16K - 1,
642 .flags = IORESOURCE_MEM,
643 },
644 [1] = {
645 .start = AT91CAP9_ID_TCB,
646 .end = AT91CAP9_ID_TCB,
647 .flags = IORESOURCE_IRQ,
648 },
649};
650
651static struct platform_device at91cap9_tcb_device = {
652 .name = "atmel_tcb",
653 .id = 0,
654 .resource = tcb_resources,
655 .num_resources = ARRAY_SIZE(tcb_resources),
656};
657
658static void __init at91_add_device_tc(void)
659{
Andrew Victore5f40bf2008-04-02 21:58:00 +0100660 platform_device_register(&at91cap9_tcb_device);
661}
662#else
663static void __init at91_add_device_tc(void) { }
664#endif
665
666
667/* --------------------------------------------------------------------
Andrew Victor2b3b3512008-01-24 15:10:39 +0100668 * RTT
669 * -------------------------------------------------------------------- */
670
Andrew Victor4fd92122008-04-02 21:55:19 +0100671static struct resource rtt_resources[] = {
672 {
Jean-Christophe PLAGNIOL-VILLARDeab5fd62011-09-18 10:12:00 +0800673 .start = AT91CAP9_BASE_RTT,
674 .end = AT91CAP9_BASE_RTT + SZ_16 - 1,
Andrew Victor4fd92122008-04-02 21:55:19 +0100675 .flags = IORESOURCE_MEM,
676 }
677};
678
Andrew Victor2b3b3512008-01-24 15:10:39 +0100679static struct platform_device at91cap9_rtt_device = {
680 .name = "at91_rtt",
Andrew Victor4fd92122008-04-02 21:55:19 +0100681 .id = 0,
682 .resource = rtt_resources,
683 .num_resources = ARRAY_SIZE(rtt_resources),
Andrew Victor2b3b3512008-01-24 15:10:39 +0100684};
685
686static void __init at91_add_device_rtt(void)
687{
688 platform_device_register(&at91cap9_rtt_device);
689}
690
691
692/* --------------------------------------------------------------------
693 * Watchdog
694 * -------------------------------------------------------------------- */
695
Andrew Victor2af29b72009-02-11 21:23:10 +0100696#if defined(CONFIG_AT91SAM9X_WATCHDOG) || defined(CONFIG_AT91SAM9X_WATCHDOG_MODULE)
Jean-Christophe PLAGNIOL-VILLARDc1c30a22011-11-02 01:43:31 +0800697static struct resource wdt_resources[] = {
698 {
699 .start = AT91CAP9_BASE_WDT,
700 .end = AT91CAP9_BASE_WDT + SZ_16 - 1,
701 .flags = IORESOURCE_MEM,
702 }
703};
704
Andrew Victor2b3b3512008-01-24 15:10:39 +0100705static struct platform_device at91cap9_wdt_device = {
706 .name = "at91_wdt",
707 .id = -1,
Jean-Christophe PLAGNIOL-VILLARDc1c30a22011-11-02 01:43:31 +0800708 .resource = wdt_resources,
709 .num_resources = ARRAY_SIZE(wdt_resources),
Andrew Victor2b3b3512008-01-24 15:10:39 +0100710};
711
712static void __init at91_add_device_watchdog(void)
713{
714 platform_device_register(&at91cap9_wdt_device);
715}
716#else
717static void __init at91_add_device_watchdog(void) {}
718#endif
719
720
721/* --------------------------------------------------------------------
Andrew Victorbb1ad682008-09-18 19:42:37 +0100722 * PWM
723 * --------------------------------------------------------------------*/
724
725#if defined(CONFIG_ATMEL_PWM)
726static u32 pwm_mask;
727
728static struct resource pwm_resources[] = {
729 [0] = {
730 .start = AT91CAP9_BASE_PWMC,
731 .end = AT91CAP9_BASE_PWMC + SZ_16K - 1,
732 .flags = IORESOURCE_MEM,
733 },
734 [1] = {
735 .start = AT91CAP9_ID_PWMC,
736 .end = AT91CAP9_ID_PWMC,
737 .flags = IORESOURCE_IRQ,
738 },
739};
740
741static struct platform_device at91cap9_pwm0_device = {
742 .name = "atmel_pwm",
743 .id = -1,
744 .dev = {
745 .platform_data = &pwm_mask,
746 },
747 .resource = pwm_resources,
748 .num_resources = ARRAY_SIZE(pwm_resources),
749};
750
751void __init at91_add_device_pwm(u32 mask)
752{
753 if (mask & (1 << AT91_PWM0))
754 at91_set_A_periph(AT91_PIN_PB19, 1); /* enable PWM0 */
755
756 if (mask & (1 << AT91_PWM1))
757 at91_set_B_periph(AT91_PIN_PB8, 1); /* enable PWM1 */
758
759 if (mask & (1 << AT91_PWM2))
760 at91_set_B_periph(AT91_PIN_PC29, 1); /* enable PWM2 */
761
762 if (mask & (1 << AT91_PWM3))
763 at91_set_B_periph(AT91_PIN_PA11, 1); /* enable PWM3 */
764
765 pwm_mask = mask;
766
767 platform_device_register(&at91cap9_pwm0_device);
768}
769#else
770void __init at91_add_device_pwm(u32 mask) {}
771#endif
772
773
774
775/* --------------------------------------------------------------------
Andrew Victor2b3b3512008-01-24 15:10:39 +0100776 * AC97
777 * -------------------------------------------------------------------- */
778
Andrew Victor9173a8e2009-09-22 10:47:50 +0100779#if defined(CONFIG_SND_ATMEL_AC97C) || defined(CONFIG_SND_ATMEL_AC97C_MODULE)
Andrew Victor2b3b3512008-01-24 15:10:39 +0100780static u64 ac97_dmamask = DMA_BIT_MASK(32);
Andrew Victor9173a8e2009-09-22 10:47:50 +0100781static struct ac97c_platform_data ac97_data;
Andrew Victor2b3b3512008-01-24 15:10:39 +0100782
783static struct resource ac97_resources[] = {
784 [0] = {
785 .start = AT91CAP9_BASE_AC97C,
786 .end = AT91CAP9_BASE_AC97C + SZ_16K - 1,
787 .flags = IORESOURCE_MEM,
788 },
789 [1] = {
790 .start = AT91CAP9_ID_AC97C,
791 .end = AT91CAP9_ID_AC97C,
792 .flags = IORESOURCE_IRQ,
793 },
794};
795
796static struct platform_device at91cap9_ac97_device = {
Andrew Victor9173a8e2009-09-22 10:47:50 +0100797 .name = "atmel_ac97c",
Andrew Victor2b3b3512008-01-24 15:10:39 +0100798 .id = 1,
799 .dev = {
800 .dma_mask = &ac97_dmamask,
801 .coherent_dma_mask = DMA_BIT_MASK(32),
802 .platform_data = &ac97_data,
803 },
804 .resource = ac97_resources,
805 .num_resources = ARRAY_SIZE(ac97_resources),
806};
807
Andrew Victor9173a8e2009-09-22 10:47:50 +0100808void __init at91_add_device_ac97(struct ac97c_platform_data *data)
Andrew Victor2b3b3512008-01-24 15:10:39 +0100809{
810 if (!data)
811 return;
812
813 at91_set_A_periph(AT91_PIN_PA6, 0); /* AC97FS */
814 at91_set_A_periph(AT91_PIN_PA7, 0); /* AC97CK */
815 at91_set_A_periph(AT91_PIN_PA8, 0); /* AC97TX */
816 at91_set_A_periph(AT91_PIN_PA9, 0); /* AC97RX */
817
818 /* reset */
Jean-Christophe PLAGNIOL-VILLARDcc9f9ae2011-09-19 15:28:25 +0800819 if (gpio_is_valid(data->reset_pin))
Andrew Victor2b3b3512008-01-24 15:10:39 +0100820 at91_set_gpio_output(data->reset_pin, 0);
821
822 ac97_data = *data;
823 platform_device_register(&at91cap9_ac97_device);
824}
825#else
Andrew Victor9173a8e2009-09-22 10:47:50 +0100826void __init at91_add_device_ac97(struct ac97c_platform_data *data) {}
Andrew Victor2b3b3512008-01-24 15:10:39 +0100827#endif
828
829
830/* --------------------------------------------------------------------
831 * LCD Controller
832 * -------------------------------------------------------------------- */
833
834#if defined(CONFIG_FB_ATMEL) || defined(CONFIG_FB_ATMEL_MODULE)
835static u64 lcdc_dmamask = DMA_BIT_MASK(32);
836static struct atmel_lcdfb_info lcdc_data;
837
838static struct resource lcdc_resources[] = {
839 [0] = {
840 .start = AT91CAP9_LCDC_BASE,
841 .end = AT91CAP9_LCDC_BASE + SZ_4K - 1,
842 .flags = IORESOURCE_MEM,
843 },
844 [1] = {
845 .start = AT91CAP9_ID_LCDC,
846 .end = AT91CAP9_ID_LCDC,
847 .flags = IORESOURCE_IRQ,
848 },
849};
850
851static struct platform_device at91_lcdc_device = {
852 .name = "atmel_lcdfb",
853 .id = 0,
854 .dev = {
855 .dma_mask = &lcdc_dmamask,
856 .coherent_dma_mask = DMA_BIT_MASK(32),
857 .platform_data = &lcdc_data,
858 },
859 .resource = lcdc_resources,
860 .num_resources = ARRAY_SIZE(lcdc_resources),
861};
862
863void __init at91_add_device_lcdc(struct atmel_lcdfb_info *data)
864{
865 if (!data)
866 return;
867
Stelian Pop7be90a62008-10-22 13:52:08 +0100868 if (cpu_is_at91cap9_revB())
Thomas Gleixner6845664a2011-03-24 13:25:22 +0100869 irq_set_irq_type(AT91CAP9_ID_LCDC, IRQ_TYPE_LEVEL_HIGH);
Stelian Pop7be90a62008-10-22 13:52:08 +0100870
Andrew Victor2b3b3512008-01-24 15:10:39 +0100871 at91_set_A_periph(AT91_PIN_PC1, 0); /* LCDHSYNC */
872 at91_set_A_periph(AT91_PIN_PC2, 0); /* LCDDOTCK */
873 at91_set_A_periph(AT91_PIN_PC3, 0); /* LCDDEN */
874 at91_set_B_periph(AT91_PIN_PB9, 0); /* LCDCC */
875 at91_set_A_periph(AT91_PIN_PC6, 0); /* LCDD2 */
876 at91_set_A_periph(AT91_PIN_PC7, 0); /* LCDD3 */
877 at91_set_A_periph(AT91_PIN_PC8, 0); /* LCDD4 */
878 at91_set_A_periph(AT91_PIN_PC9, 0); /* LCDD5 */
879 at91_set_A_periph(AT91_PIN_PC10, 0); /* LCDD6 */
880 at91_set_A_periph(AT91_PIN_PC11, 0); /* LCDD7 */
881 at91_set_A_periph(AT91_PIN_PC14, 0); /* LCDD10 */
882 at91_set_A_periph(AT91_PIN_PC15, 0); /* LCDD11 */
883 at91_set_A_periph(AT91_PIN_PC16, 0); /* LCDD12 */
884 at91_set_A_periph(AT91_PIN_PC17, 0); /* LCDD13 */
885 at91_set_A_periph(AT91_PIN_PC18, 0); /* LCDD14 */
886 at91_set_A_periph(AT91_PIN_PC19, 0); /* LCDD15 */
887 at91_set_A_periph(AT91_PIN_PC22, 0); /* LCDD18 */
888 at91_set_A_periph(AT91_PIN_PC23, 0); /* LCDD19 */
889 at91_set_A_periph(AT91_PIN_PC24, 0); /* LCDD20 */
890 at91_set_A_periph(AT91_PIN_PC25, 0); /* LCDD21 */
891 at91_set_A_periph(AT91_PIN_PC26, 0); /* LCDD22 */
892 at91_set_A_periph(AT91_PIN_PC27, 0); /* LCDD23 */
893
894 lcdc_data = *data;
895 platform_device_register(&at91_lcdc_device);
896}
897#else
898void __init at91_add_device_lcdc(struct atmel_lcdfb_info *data) {}
899#endif
900
901
902/* --------------------------------------------------------------------
903 * SSC -- Synchronous Serial Controller
904 * -------------------------------------------------------------------- */
905
906#if defined(CONFIG_ATMEL_SSC) || defined(CONFIG_ATMEL_SSC_MODULE)
907static u64 ssc0_dmamask = DMA_BIT_MASK(32);
908
909static struct resource ssc0_resources[] = {
910 [0] = {
911 .start = AT91CAP9_BASE_SSC0,
912 .end = AT91CAP9_BASE_SSC0 + SZ_16K - 1,
913 .flags = IORESOURCE_MEM,
914 },
915 [1] = {
916 .start = AT91CAP9_ID_SSC0,
917 .end = AT91CAP9_ID_SSC0,
918 .flags = IORESOURCE_IRQ,
919 },
920};
921
922static struct platform_device at91cap9_ssc0_device = {
923 .name = "ssc",
924 .id = 0,
925 .dev = {
926 .dma_mask = &ssc0_dmamask,
927 .coherent_dma_mask = DMA_BIT_MASK(32),
928 },
929 .resource = ssc0_resources,
930 .num_resources = ARRAY_SIZE(ssc0_resources),
931};
932
933static inline void configure_ssc0_pins(unsigned pins)
934{
935 if (pins & ATMEL_SSC_TF)
936 at91_set_A_periph(AT91_PIN_PB0, 1);
937 if (pins & ATMEL_SSC_TK)
938 at91_set_A_periph(AT91_PIN_PB1, 1);
939 if (pins & ATMEL_SSC_TD)
940 at91_set_A_periph(AT91_PIN_PB2, 1);
941 if (pins & ATMEL_SSC_RD)
942 at91_set_A_periph(AT91_PIN_PB3, 1);
943 if (pins & ATMEL_SSC_RK)
944 at91_set_A_periph(AT91_PIN_PB4, 1);
945 if (pins & ATMEL_SSC_RF)
946 at91_set_A_periph(AT91_PIN_PB5, 1);
947}
948
949static u64 ssc1_dmamask = DMA_BIT_MASK(32);
950
951static struct resource ssc1_resources[] = {
952 [0] = {
953 .start = AT91CAP9_BASE_SSC1,
954 .end = AT91CAP9_BASE_SSC1 + SZ_16K - 1,
955 .flags = IORESOURCE_MEM,
956 },
957 [1] = {
958 .start = AT91CAP9_ID_SSC1,
959 .end = AT91CAP9_ID_SSC1,
960 .flags = IORESOURCE_IRQ,
961 },
962};
963
964static struct platform_device at91cap9_ssc1_device = {
965 .name = "ssc",
966 .id = 1,
967 .dev = {
968 .dma_mask = &ssc1_dmamask,
969 .coherent_dma_mask = DMA_BIT_MASK(32),
970 },
971 .resource = ssc1_resources,
972 .num_resources = ARRAY_SIZE(ssc1_resources),
973};
974
975static inline void configure_ssc1_pins(unsigned pins)
976{
977 if (pins & ATMEL_SSC_TF)
978 at91_set_A_periph(AT91_PIN_PB6, 1);
979 if (pins & ATMEL_SSC_TK)
980 at91_set_A_periph(AT91_PIN_PB7, 1);
981 if (pins & ATMEL_SSC_TD)
982 at91_set_A_periph(AT91_PIN_PB8, 1);
983 if (pins & ATMEL_SSC_RD)
984 at91_set_A_periph(AT91_PIN_PB9, 1);
985 if (pins & ATMEL_SSC_RK)
986 at91_set_A_periph(AT91_PIN_PB10, 1);
987 if (pins & ATMEL_SSC_RF)
988 at91_set_A_periph(AT91_PIN_PB11, 1);
989}
990
991/*
992 * SSC controllers are accessed through library code, instead of any
993 * kind of all-singing/all-dancing driver. For example one could be
994 * used by a particular I2S audio codec's driver, while another one
995 * on the same system might be used by a custom data capture driver.
996 */
997void __init at91_add_device_ssc(unsigned id, unsigned pins)
998{
999 struct platform_device *pdev;
1000
1001 /*
1002 * NOTE: caller is responsible for passing information matching
1003 * "pins" to whatever will be using each particular controller.
1004 */
1005 switch (id) {
1006 case AT91CAP9_ID_SSC0:
1007 pdev = &at91cap9_ssc0_device;
1008 configure_ssc0_pins(pins);
Andrew Victor2b3b3512008-01-24 15:10:39 +01001009 break;
1010 case AT91CAP9_ID_SSC1:
1011 pdev = &at91cap9_ssc1_device;
1012 configure_ssc1_pins(pins);
Andrew Victor2b3b3512008-01-24 15:10:39 +01001013 break;
1014 default:
1015 return;
1016 }
1017
1018 platform_device_register(pdev);
1019}
1020
1021#else
1022void __init at91_add_device_ssc(unsigned id, unsigned pins) {}
1023#endif
1024
1025
1026/* --------------------------------------------------------------------
1027 * UART
1028 * -------------------------------------------------------------------- */
1029
1030#if defined(CONFIG_SERIAL_ATMEL)
1031static struct resource dbgu_resources[] = {
1032 [0] = {
Jean-Christophe PLAGNIOL-VILLARD13079a72011-11-02 01:43:31 +08001033 .start = AT91CAP9_BASE_DBGU,
1034 .end = AT91CAP9_BASE_DBGU + SZ_512 - 1,
Andrew Victor2b3b3512008-01-24 15:10:39 +01001035 .flags = IORESOURCE_MEM,
1036 },
1037 [1] = {
1038 .start = AT91_ID_SYS,
1039 .end = AT91_ID_SYS,
1040 .flags = IORESOURCE_IRQ,
1041 },
1042};
1043
1044static struct atmel_uart_data dbgu_data = {
1045 .use_dma_tx = 0,
1046 .use_dma_rx = 0, /* DBGU not capable of receive DMA */
Andrew Victor2b3b3512008-01-24 15:10:39 +01001047};
1048
1049static u64 dbgu_dmamask = DMA_BIT_MASK(32);
1050
1051static struct platform_device at91cap9_dbgu_device = {
1052 .name = "atmel_usart",
1053 .id = 0,
1054 .dev = {
1055 .dma_mask = &dbgu_dmamask,
1056 .coherent_dma_mask = DMA_BIT_MASK(32),
1057 .platform_data = &dbgu_data,
1058 },
1059 .resource = dbgu_resources,
1060 .num_resources = ARRAY_SIZE(dbgu_resources),
1061};
1062
1063static inline void configure_dbgu_pins(void)
1064{
1065 at91_set_A_periph(AT91_PIN_PC30, 0); /* DRXD */
1066 at91_set_A_periph(AT91_PIN_PC31, 1); /* DTXD */
1067}
1068
1069static struct resource uart0_resources[] = {
1070 [0] = {
1071 .start = AT91CAP9_BASE_US0,
1072 .end = AT91CAP9_BASE_US0 + SZ_16K - 1,
1073 .flags = IORESOURCE_MEM,
1074 },
1075 [1] = {
1076 .start = AT91CAP9_ID_US0,
1077 .end = AT91CAP9_ID_US0,
1078 .flags = IORESOURCE_IRQ,
1079 },
1080};
1081
1082static struct atmel_uart_data uart0_data = {
1083 .use_dma_tx = 1,
1084 .use_dma_rx = 1,
1085};
1086
1087static u64 uart0_dmamask = DMA_BIT_MASK(32);
1088
1089static struct platform_device at91cap9_uart0_device = {
1090 .name = "atmel_usart",
1091 .id = 1,
1092 .dev = {
1093 .dma_mask = &uart0_dmamask,
1094 .coherent_dma_mask = DMA_BIT_MASK(32),
1095 .platform_data = &uart0_data,
1096 },
1097 .resource = uart0_resources,
1098 .num_resources = ARRAY_SIZE(uart0_resources),
1099};
1100
1101static inline void configure_usart0_pins(unsigned pins)
1102{
1103 at91_set_A_periph(AT91_PIN_PA22, 1); /* TXD0 */
1104 at91_set_A_periph(AT91_PIN_PA23, 0); /* RXD0 */
1105
1106 if (pins & ATMEL_UART_RTS)
1107 at91_set_A_periph(AT91_PIN_PA24, 0); /* RTS0 */
1108 if (pins & ATMEL_UART_CTS)
1109 at91_set_A_periph(AT91_PIN_PA25, 0); /* CTS0 */
1110}
1111
1112static struct resource uart1_resources[] = {
1113 [0] = {
1114 .start = AT91CAP9_BASE_US1,
1115 .end = AT91CAP9_BASE_US1 + SZ_16K - 1,
1116 .flags = IORESOURCE_MEM,
1117 },
1118 [1] = {
1119 .start = AT91CAP9_ID_US1,
1120 .end = AT91CAP9_ID_US1,
1121 .flags = IORESOURCE_IRQ,
1122 },
1123};
1124
1125static struct atmel_uart_data uart1_data = {
1126 .use_dma_tx = 1,
1127 .use_dma_rx = 1,
1128};
1129
1130static u64 uart1_dmamask = DMA_BIT_MASK(32);
1131
1132static struct platform_device at91cap9_uart1_device = {
1133 .name = "atmel_usart",
1134 .id = 2,
1135 .dev = {
1136 .dma_mask = &uart1_dmamask,
1137 .coherent_dma_mask = DMA_BIT_MASK(32),
1138 .platform_data = &uart1_data,
1139 },
1140 .resource = uart1_resources,
1141 .num_resources = ARRAY_SIZE(uart1_resources),
1142};
1143
1144static inline void configure_usart1_pins(unsigned pins)
1145{
1146 at91_set_A_periph(AT91_PIN_PD0, 1); /* TXD1 */
1147 at91_set_A_periph(AT91_PIN_PD1, 0); /* RXD1 */
1148
1149 if (pins & ATMEL_UART_RTS)
1150 at91_set_B_periph(AT91_PIN_PD7, 0); /* RTS1 */
1151 if (pins & ATMEL_UART_CTS)
1152 at91_set_B_periph(AT91_PIN_PD8, 0); /* CTS1 */
1153}
1154
1155static struct resource uart2_resources[] = {
1156 [0] = {
1157 .start = AT91CAP9_BASE_US2,
1158 .end = AT91CAP9_BASE_US2 + SZ_16K - 1,
1159 .flags = IORESOURCE_MEM,
1160 },
1161 [1] = {
1162 .start = AT91CAP9_ID_US2,
1163 .end = AT91CAP9_ID_US2,
1164 .flags = IORESOURCE_IRQ,
1165 },
1166};
1167
1168static struct atmel_uart_data uart2_data = {
1169 .use_dma_tx = 1,
1170 .use_dma_rx = 1,
1171};
1172
1173static u64 uart2_dmamask = DMA_BIT_MASK(32);
1174
1175static struct platform_device at91cap9_uart2_device = {
1176 .name = "atmel_usart",
1177 .id = 3,
1178 .dev = {
1179 .dma_mask = &uart2_dmamask,
1180 .coherent_dma_mask = DMA_BIT_MASK(32),
1181 .platform_data = &uart2_data,
1182 },
1183 .resource = uart2_resources,
1184 .num_resources = ARRAY_SIZE(uart2_resources),
1185};
1186
1187static inline void configure_usart2_pins(unsigned pins)
1188{
1189 at91_set_A_periph(AT91_PIN_PD2, 1); /* TXD2 */
1190 at91_set_A_periph(AT91_PIN_PD3, 0); /* RXD2 */
1191
1192 if (pins & ATMEL_UART_RTS)
1193 at91_set_B_periph(AT91_PIN_PD5, 0); /* RTS2 */
1194 if (pins & ATMEL_UART_CTS)
1195 at91_set_B_periph(AT91_PIN_PD6, 0); /* CTS2 */
1196}
1197
Andrew Victor11aadac2008-04-15 21:16:38 +01001198static struct platform_device *__initdata at91_uarts[ATMEL_MAX_UART]; /* the UARTs to use */
Andrew Victor2b3b3512008-01-24 15:10:39 +01001199struct platform_device *atmel_default_console_device; /* the serial console device */
1200
1201void __init at91_register_uart(unsigned id, unsigned portnr, unsigned pins)
1202{
1203 struct platform_device *pdev;
Jean-Christophe PLAGNIOL-VILLARD2b348e22011-04-10 14:10:05 +08001204 struct atmel_uart_data *pdata;
Andrew Victor2b3b3512008-01-24 15:10:39 +01001205
1206 switch (id) {
1207 case 0: /* DBGU */
1208 pdev = &at91cap9_dbgu_device;
1209 configure_dbgu_pins();
Andrew Victor2b3b3512008-01-24 15:10:39 +01001210 break;
1211 case AT91CAP9_ID_US0:
1212 pdev = &at91cap9_uart0_device;
1213 configure_usart0_pins(pins);
Andrew Victor2b3b3512008-01-24 15:10:39 +01001214 break;
1215 case AT91CAP9_ID_US1:
1216 pdev = &at91cap9_uart1_device;
1217 configure_usart1_pins(pins);
Andrew Victor2b3b3512008-01-24 15:10:39 +01001218 break;
1219 case AT91CAP9_ID_US2:
1220 pdev = &at91cap9_uart2_device;
1221 configure_usart2_pins(pins);
Andrew Victor2b3b3512008-01-24 15:10:39 +01001222 break;
1223 default:
1224 return;
1225 }
Jean-Christophe PLAGNIOL-VILLARD2b348e22011-04-10 14:10:05 +08001226 pdata = pdev->dev.platform_data;
1227 pdata->num = portnr; /* update to mapped ID */
Andrew Victor2b3b3512008-01-24 15:10:39 +01001228
1229 if (portnr < ATMEL_MAX_UART)
1230 at91_uarts[portnr] = pdev;
1231}
1232
1233void __init at91_set_serial_console(unsigned portnr)
1234{
Jean-Christophe PLAGNIOL-VILLARDbd602992011-02-02 07:27:07 +01001235 if (portnr < ATMEL_MAX_UART) {
Andrew Victor2b3b3512008-01-24 15:10:39 +01001236 atmel_default_console_device = at91_uarts[portnr];
Jean-Christophe PLAGNIOL-VILLARD5c1f9662011-06-21 11:24:33 +08001237 at91cap9_set_console_clock(at91_uarts[portnr]->id);
Jean-Christophe PLAGNIOL-VILLARDbd602992011-02-02 07:27:07 +01001238 }
Andrew Victor2b3b3512008-01-24 15:10:39 +01001239}
1240
1241void __init at91_add_device_serial(void)
1242{
1243 int i;
1244
1245 for (i = 0; i < ATMEL_MAX_UART; i++) {
1246 if (at91_uarts[i])
1247 platform_device_register(at91_uarts[i]);
1248 }
Andrew Victor11aadac2008-04-15 21:16:38 +01001249
1250 if (!atmel_default_console_device)
1251 printk(KERN_INFO "AT91: No default serial console defined.\n");
Andrew Victor2b3b3512008-01-24 15:10:39 +01001252}
1253#else
1254void __init at91_register_uart(unsigned id, unsigned portnr, unsigned pins) {}
1255void __init at91_set_serial_console(unsigned portnr) {}
1256void __init at91_add_device_serial(void) {}
1257#endif
1258
1259
1260/* -------------------------------------------------------------------- */
1261/*
1262 * These devices are always present and don't need any board-specific
1263 * setup.
1264 */
1265static int __init at91_add_standard_devices(void)
1266{
1267 at91_add_device_rtt();
1268 at91_add_device_watchdog();
Andrew Victore5f40bf2008-04-02 21:58:00 +01001269 at91_add_device_tc();
Andrew Victor2b3b3512008-01-24 15:10:39 +01001270 return 0;
1271}
1272
1273arch_initcall(at91_add_standard_devices);