ARM: gpio: convert includes of mach/gpio.h and asm/gpio.h to linux/gpio.h
[deliverable/linux.git] / arch / arm / mach-at91 / at91cap9_devices.c
CommitLineData
2b3b3516
AV
1/*
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>
7be90a6b 16#include <asm/mach/irq.h>
2b3b3516
AV
17
18#include <linux/dma-mapping.h>
2f8163ba 19#include <linux/gpio.h>
2b3b3516 20#include <linux/platform_device.h>
11aadac4 21#include <linux/i2c-gpio.h>
2b3b3516
AV
22
23#include <video/atmel_lcdc.h>
24
a09e64fb 25#include <mach/board.h>
7be90a6b 26#include <mach/cpu.h>
a09e64fb
RK
27#include <mach/at91cap9.h>
28#include <mach/at91cap9_matrix.h>
29#include <mach/at91sam9_smc.h>
2b3b3516
AV
30
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
7be90a6b 74 if (cpu_is_at91cap9_revB())
6845664a 75 irq_set_irq_type(AT91CAP9_ID_UHP, IRQ_TYPE_LEVEL_HIGH);
7be90a6b 76
2b3b3516
AV
77 /* Enable VBus control for UHP ports */
78 for (i = 0; i < data->ports; i++) {
79 if (data->vbus_pin[i])
80 at91_set_gpio_output(data->vbus_pin[i], 0);
81 }
82
83 usbh_data = *data;
84 platform_device_register(&at91_usbh_device);
85}
86#else
87void __init at91_add_device_usbh(struct at91_usbh_data *data) {}
88#endif
89
90
7c8cf665
SP
91/* --------------------------------------------------------------------
92 * USB HS Device (Gadget)
93 * -------------------------------------------------------------------- */
94
95#if defined(CONFIG_USB_GADGET_ATMEL_USBA) || defined(CONFIG_USB_GADGET_ATMEL_USBA_MODULE)
96
97static struct resource usba_udc_resources[] = {
98 [0] = {
99 .start = AT91CAP9_UDPHS_FIFO,
100 .end = AT91CAP9_UDPHS_FIFO + SZ_512K - 1,
101 .flags = IORESOURCE_MEM,
102 },
103 [1] = {
104 .start = AT91CAP9_BASE_UDPHS,
105 .end = AT91CAP9_BASE_UDPHS + SZ_1K - 1,
106 .flags = IORESOURCE_MEM,
107 },
108 [2] = {
109 .start = AT91CAP9_ID_UDPHS,
110 .end = AT91CAP9_ID_UDPHS,
111 .flags = IORESOURCE_IRQ,
112 },
113};
114
115#define EP(nam, idx, maxpkt, maxbk, dma, isoc) \
116 [idx] = { \
117 .name = nam, \
118 .index = idx, \
119 .fifo_size = maxpkt, \
120 .nr_banks = maxbk, \
121 .can_dma = dma, \
122 .can_isoc = isoc, \
123 }
124
125static struct usba_ep_data usba_udc_ep[] = {
126 EP("ep0", 0, 64, 1, 0, 0),
127 EP("ep1", 1, 1024, 3, 1, 1),
128 EP("ep2", 2, 1024, 3, 1, 1),
129 EP("ep3", 3, 1024, 2, 1, 1),
130 EP("ep4", 4, 1024, 2, 1, 1),
131 EP("ep5", 5, 1024, 2, 1, 0),
132 EP("ep6", 6, 1024, 2, 1, 0),
133 EP("ep7", 7, 1024, 2, 0, 0),
134};
135
136#undef EP
137
138/*
139 * pdata doesn't have room for any endpoints, so we need to
140 * append room for the ones we need right after it.
141 */
142static struct {
143 struct usba_platform_data pdata;
144 struct usba_ep_data ep[8];
145} usba_udc_data;
146
147static struct platform_device at91_usba_udc_device = {
148 .name = "atmel_usba_udc",
149 .id = -1,
150 .dev = {
151 .platform_data = &usba_udc_data.pdata,
152 },
153 .resource = usba_udc_resources,
154 .num_resources = ARRAY_SIZE(usba_udc_resources),
155};
156
157void __init at91_add_device_usba(struct usba_platform_data *data)
158{
7be90a6b 159 if (cpu_is_at91cap9_revB()) {
6845664a 160 irq_set_irq_type(AT91CAP9_ID_UDPHS, IRQ_TYPE_LEVEL_HIGH);
7be90a6b
SP
161 at91_sys_write(AT91_MATRIX_UDPHS, AT91_MATRIX_SELECT_UDPHS |
162 AT91_MATRIX_UDPHS_BYPASS_LOCK);
163 }
164 else
165 at91_sys_write(AT91_MATRIX_UDPHS, AT91_MATRIX_SELECT_UDPHS);
7c8cf665
SP
166
167 /*
168 * Invalid pins are 0 on AT91, but the usba driver is shared
169 * with AVR32, which use negative values instead. Once/if
170 * gpio_is_valid() is ported to AT91, revisit this code.
171 */
172 usba_udc_data.pdata.vbus_pin = -EINVAL;
173 usba_udc_data.pdata.num_ep = ARRAY_SIZE(usba_udc_ep);
6eab04a8 174 memcpy(usba_udc_data.ep, usba_udc_ep, sizeof(usba_udc_ep));
7c8cf665
SP
175
176 if (data && data->vbus_pin > 0) {
177 at91_set_gpio_input(data->vbus_pin, 0);
178 at91_set_deglitch(data->vbus_pin, 1);
179 usba_udc_data.pdata.vbus_pin = data->vbus_pin;
180 }
181
182 /* Pullup pin is handled internally by USB device peripheral */
183
7c8cf665
SP
184 platform_device_register(&at91_usba_udc_device);
185}
186#else
187void __init at91_add_device_usba(struct usba_platform_data *data) {}
188#endif
189
190
2b3b3516
AV
191/* --------------------------------------------------------------------
192 * Ethernet
193 * -------------------------------------------------------------------- */
194
195#if defined(CONFIG_MACB) || defined(CONFIG_MACB_MODULE)
196static u64 eth_dmamask = DMA_BIT_MASK(32);
197static struct at91_eth_data eth_data;
198
199static struct resource eth_resources[] = {
200 [0] = {
201 .start = AT91CAP9_BASE_EMAC,
202 .end = AT91CAP9_BASE_EMAC + SZ_16K - 1,
203 .flags = IORESOURCE_MEM,
204 },
205 [1] = {
206 .start = AT91CAP9_ID_EMAC,
207 .end = AT91CAP9_ID_EMAC,
208 .flags = IORESOURCE_IRQ,
209 },
210};
211
212static struct platform_device at91cap9_eth_device = {
213 .name = "macb",
214 .id = -1,
215 .dev = {
216 .dma_mask = &eth_dmamask,
217 .coherent_dma_mask = DMA_BIT_MASK(32),
218 .platform_data = &eth_data,
219 },
220 .resource = eth_resources,
221 .num_resources = ARRAY_SIZE(eth_resources),
222};
223
224void __init at91_add_device_eth(struct at91_eth_data *data)
225{
226 if (!data)
227 return;
228
229 if (data->phy_irq_pin) {
230 at91_set_gpio_input(data->phy_irq_pin, 0);
231 at91_set_deglitch(data->phy_irq_pin, 1);
232 }
233
234 /* Pins used for MII and RMII */
235 at91_set_A_periph(AT91_PIN_PB21, 0); /* ETXCK_EREFCK */
236 at91_set_A_periph(AT91_PIN_PB22, 0); /* ERXDV */
237 at91_set_A_periph(AT91_PIN_PB25, 0); /* ERX0 */
238 at91_set_A_periph(AT91_PIN_PB26, 0); /* ERX1 */
239 at91_set_A_periph(AT91_PIN_PB27, 0); /* ERXER */
240 at91_set_A_periph(AT91_PIN_PB28, 0); /* ETXEN */
241 at91_set_A_periph(AT91_PIN_PB23, 0); /* ETX0 */
242 at91_set_A_periph(AT91_PIN_PB24, 0); /* ETX1 */
243 at91_set_A_periph(AT91_PIN_PB30, 0); /* EMDIO */
244 at91_set_A_periph(AT91_PIN_PB29, 0); /* EMDC */
245
246 if (!data->is_rmii) {
247 at91_set_B_periph(AT91_PIN_PC25, 0); /* ECRS */
248 at91_set_B_periph(AT91_PIN_PC26, 0); /* ECOL */
249 at91_set_B_periph(AT91_PIN_PC22, 0); /* ERX2 */
250 at91_set_B_periph(AT91_PIN_PC23, 0); /* ERX3 */
251 at91_set_B_periph(AT91_PIN_PC27, 0); /* ERXCK */
252 at91_set_B_periph(AT91_PIN_PC20, 0); /* ETX2 */
253 at91_set_B_periph(AT91_PIN_PC21, 0); /* ETX3 */
254 at91_set_B_periph(AT91_PIN_PC24, 0); /* ETXER */
255 }
256
257 eth_data = *data;
258 platform_device_register(&at91cap9_eth_device);
259}
260#else
261void __init at91_add_device_eth(struct at91_eth_data *data) {}
262#endif
263
264
265/* --------------------------------------------------------------------
266 * MMC / SD
267 * -------------------------------------------------------------------- */
268
269#if defined(CONFIG_MMC_AT91) || defined(CONFIG_MMC_AT91_MODULE)
270static u64 mmc_dmamask = DMA_BIT_MASK(32);
271static struct at91_mmc_data mmc0_data, mmc1_data;
272
273static struct resource mmc0_resources[] = {
274 [0] = {
275 .start = AT91CAP9_BASE_MCI0,
276 .end = AT91CAP9_BASE_MCI0 + SZ_16K - 1,
277 .flags = IORESOURCE_MEM,
278 },
279 [1] = {
280 .start = AT91CAP9_ID_MCI0,
281 .end = AT91CAP9_ID_MCI0,
282 .flags = IORESOURCE_IRQ,
283 },
284};
285
286static struct platform_device at91cap9_mmc0_device = {
287 .name = "at91_mci",
288 .id = 0,
289 .dev = {
290 .dma_mask = &mmc_dmamask,
291 .coherent_dma_mask = DMA_BIT_MASK(32),
292 .platform_data = &mmc0_data,
293 },
294 .resource = mmc0_resources,
295 .num_resources = ARRAY_SIZE(mmc0_resources),
296};
297
298static struct resource mmc1_resources[] = {
299 [0] = {
300 .start = AT91CAP9_BASE_MCI1,
301 .end = AT91CAP9_BASE_MCI1 + SZ_16K - 1,
302 .flags = IORESOURCE_MEM,
303 },
304 [1] = {
305 .start = AT91CAP9_ID_MCI1,
306 .end = AT91CAP9_ID_MCI1,
307 .flags = IORESOURCE_IRQ,
308 },
309};
310
311static struct platform_device at91cap9_mmc1_device = {
312 .name = "at91_mci",
313 .id = 1,
314 .dev = {
315 .dma_mask = &mmc_dmamask,
316 .coherent_dma_mask = DMA_BIT_MASK(32),
317 .platform_data = &mmc1_data,
318 },
319 .resource = mmc1_resources,
320 .num_resources = ARRAY_SIZE(mmc1_resources),
321};
322
323void __init at91_add_device_mmc(short mmc_id, struct at91_mmc_data *data)
324{
325 if (!data)
326 return;
327
328 /* input/irq */
329 if (data->det_pin) {
330 at91_set_gpio_input(data->det_pin, 1);
331 at91_set_deglitch(data->det_pin, 1);
332 }
333 if (data->wp_pin)
334 at91_set_gpio_input(data->wp_pin, 1);
335 if (data->vcc_pin)
336 at91_set_gpio_output(data->vcc_pin, 0);
337
338 if (mmc_id == 0) { /* MCI0 */
339 /* CLK */
340 at91_set_A_periph(AT91_PIN_PA2, 0);
341
342 /* CMD */
343 at91_set_A_periph(AT91_PIN_PA1, 1);
344
345 /* DAT0, maybe DAT1..DAT3 */
346 at91_set_A_periph(AT91_PIN_PA0, 1);
347 if (data->wire4) {
348 at91_set_A_periph(AT91_PIN_PA3, 1);
349 at91_set_A_periph(AT91_PIN_PA4, 1);
350 at91_set_A_periph(AT91_PIN_PA5, 1);
351 }
352
353 mmc0_data = *data;
2b3b3516
AV
354 platform_device_register(&at91cap9_mmc0_device);
355 } else { /* MCI1 */
356 /* CLK */
357 at91_set_A_periph(AT91_PIN_PA16, 0);
358
359 /* CMD */
360 at91_set_A_periph(AT91_PIN_PA17, 1);
361
362 /* DAT0, maybe DAT1..DAT3 */
363 at91_set_A_periph(AT91_PIN_PA18, 1);
364 if (data->wire4) {
365 at91_set_A_periph(AT91_PIN_PA19, 1);
366 at91_set_A_periph(AT91_PIN_PA20, 1);
367 at91_set_A_periph(AT91_PIN_PA21, 1);
368 }
369
370 mmc1_data = *data;
2b3b3516
AV
371 platform_device_register(&at91cap9_mmc1_device);
372 }
373}
374#else
375void __init at91_add_device_mmc(short mmc_id, struct at91_mmc_data *data) {}
376#endif
377
378
379/* --------------------------------------------------------------------
380 * NAND / SmartMedia
381 * -------------------------------------------------------------------- */
382
f6ed6f78 383#if defined(CONFIG_MTD_NAND_ATMEL) || defined(CONFIG_MTD_NAND_ATMEL_MODULE)
3c3796cc 384static struct atmel_nand_data nand_data;
2b3b3516
AV
385
386#define NAND_BASE AT91_CHIPSELECT_3
387
388static struct resource nand_resources[] = {
d7a2415f 389 [0] = {
2b3b3516
AV
390 .start = NAND_BASE,
391 .end = NAND_BASE + SZ_256M - 1,
392 .flags = IORESOURCE_MEM,
d7a2415f
AV
393 },
394 [1] = {
395 .start = AT91_BASE_SYS + AT91_ECC,
396 .end = AT91_BASE_SYS + AT91_ECC + SZ_512 - 1,
397 .flags = IORESOURCE_MEM,
2b3b3516
AV
398 }
399};
400
401static struct platform_device at91cap9_nand_device = {
3c3796cc 402 .name = "atmel_nand",
2b3b3516
AV
403 .id = -1,
404 .dev = {
405 .platform_data = &nand_data,
406 },
407 .resource = nand_resources,
408 .num_resources = ARRAY_SIZE(nand_resources),
409};
410
3c3796cc 411void __init at91_add_device_nand(struct atmel_nand_data *data)
2b3b3516 412{
461d3b4d 413 unsigned long csa;
2b3b3516
AV
414
415 if (!data)
416 return;
417
418 csa = at91_sys_read(AT91_MATRIX_EBICSA);
461d3b4d 419 at91_sys_write(AT91_MATRIX_EBICSA, csa | AT91_MATRIX_EBI_CS3A_SMC_SMARTMEDIA);
2b3b3516
AV
420
421 /* enable pin */
422 if (data->enable_pin)
423 at91_set_gpio_output(data->enable_pin, 1);
424
425 /* ready/busy pin */
426 if (data->rdy_pin)
427 at91_set_gpio_input(data->rdy_pin, 1);
428
429 /* card detect pin */
430 if (data->det_pin)
431 at91_set_gpio_input(data->det_pin, 1);
432
433 nand_data = *data;
434 platform_device_register(&at91cap9_nand_device);
435}
436#else
3c3796cc 437void __init at91_add_device_nand(struct atmel_nand_data *data) {}
2b3b3516
AV
438#endif
439
11aadac4 440
2b3b3516
AV
441/* --------------------------------------------------------------------
442 * TWI (i2c)
443 * -------------------------------------------------------------------- */
444
445/*
446 * Prefer the GPIO code since the TWI controller isn't robust
447 * (gets overruns and underruns under load) and can only issue
448 * repeated STARTs in one scenario (the driver doesn't yet handle them).
449 */
450#if defined(CONFIG_I2C_GPIO) || defined(CONFIG_I2C_GPIO_MODULE)
451
452static struct i2c_gpio_platform_data pdata = {
453 .sda_pin = AT91_PIN_PB4,
454 .sda_is_open_drain = 1,
455 .scl_pin = AT91_PIN_PB5,
456 .scl_is_open_drain = 1,
457 .udelay = 2, /* ~100 kHz */
458};
459
460static struct platform_device at91cap9_twi_device = {
461 .name = "i2c-gpio",
462 .id = -1,
463 .dev.platform_data = &pdata,
464};
465
466void __init at91_add_device_i2c(struct i2c_board_info *devices, int nr_devices)
467{
468 at91_set_GPIO_periph(AT91_PIN_PB4, 1); /* TWD (SDA) */
469 at91_set_multi_drive(AT91_PIN_PB4, 1);
470
471 at91_set_GPIO_periph(AT91_PIN_PB5, 1); /* TWCK (SCL) */
472 at91_set_multi_drive(AT91_PIN_PB5, 1);
473
474 i2c_register_board_info(0, devices, nr_devices);
475 platform_device_register(&at91cap9_twi_device);
476}
477
478#elif defined(CONFIG_I2C_AT91) || defined(CONFIG_I2C_AT91_MODULE)
479
480static struct resource twi_resources[] = {
481 [0] = {
482 .start = AT91CAP9_BASE_TWI,
483 .end = AT91CAP9_BASE_TWI + SZ_16K - 1,
484 .flags = IORESOURCE_MEM,
485 },
486 [1] = {
487 .start = AT91CAP9_ID_TWI,
488 .end = AT91CAP9_ID_TWI,
489 .flags = IORESOURCE_IRQ,
490 },
491};
492
493static struct platform_device at91cap9_twi_device = {
494 .name = "at91_i2c",
495 .id = -1,
496 .resource = twi_resources,
497 .num_resources = ARRAY_SIZE(twi_resources),
498};
499
500void __init at91_add_device_i2c(struct i2c_board_info *devices, int nr_devices)
501{
502 /* pins used for TWI interface */
503 at91_set_B_periph(AT91_PIN_PB4, 0); /* TWD */
504 at91_set_multi_drive(AT91_PIN_PB4, 1);
505
506 at91_set_B_periph(AT91_PIN_PB5, 0); /* TWCK */
507 at91_set_multi_drive(AT91_PIN_PB5, 1);
508
509 i2c_register_board_info(0, devices, nr_devices);
510 platform_device_register(&at91cap9_twi_device);
511}
512#else
513void __init at91_add_device_i2c(struct i2c_board_info *devices, int nr_devices) {}
514#endif
515
516/* --------------------------------------------------------------------
517 * SPI
518 * -------------------------------------------------------------------- */
519
520#if defined(CONFIG_SPI_ATMEL) || defined(CONFIG_SPI_ATMEL_MODULE)
521static u64 spi_dmamask = DMA_BIT_MASK(32);
522
523static struct resource spi0_resources[] = {
524 [0] = {
525 .start = AT91CAP9_BASE_SPI0,
526 .end = AT91CAP9_BASE_SPI0 + SZ_16K - 1,
527 .flags = IORESOURCE_MEM,
528 },
529 [1] = {
530 .start = AT91CAP9_ID_SPI0,
531 .end = AT91CAP9_ID_SPI0,
532 .flags = IORESOURCE_IRQ,
533 },
534};
535
536static struct platform_device at91cap9_spi0_device = {
537 .name = "atmel_spi",
538 .id = 0,
539 .dev = {
540 .dma_mask = &spi_dmamask,
541 .coherent_dma_mask = DMA_BIT_MASK(32),
542 },
543 .resource = spi0_resources,
544 .num_resources = ARRAY_SIZE(spi0_resources),
545};
546
547static const unsigned spi0_standard_cs[4] = { AT91_PIN_PA5, AT91_PIN_PA3, AT91_PIN_PD0, AT91_PIN_PD1 };
548
549static struct resource spi1_resources[] = {
550 [0] = {
551 .start = AT91CAP9_BASE_SPI1,
552 .end = AT91CAP9_BASE_SPI1 + SZ_16K - 1,
553 .flags = IORESOURCE_MEM,
554 },
555 [1] = {
556 .start = AT91CAP9_ID_SPI1,
557 .end = AT91CAP9_ID_SPI1,
558 .flags = IORESOURCE_IRQ,
559 },
560};
561
562static struct platform_device at91cap9_spi1_device = {
563 .name = "atmel_spi",
564 .id = 1,
565 .dev = {
566 .dma_mask = &spi_dmamask,
567 .coherent_dma_mask = DMA_BIT_MASK(32),
568 },
569 .resource = spi1_resources,
570 .num_resources = ARRAY_SIZE(spi1_resources),
571};
572
573static const unsigned spi1_standard_cs[4] = { AT91_PIN_PB15, AT91_PIN_PB16, AT91_PIN_PB17, AT91_PIN_PB18 };
574
575void __init at91_add_device_spi(struct spi_board_info *devices, int nr_devices)
576{
577 int i;
578 unsigned long cs_pin;
579 short enable_spi0 = 0;
580 short enable_spi1 = 0;
581
582 /* Choose SPI chip-selects */
583 for (i = 0; i < nr_devices; i++) {
584 if (devices[i].controller_data)
585 cs_pin = (unsigned long) devices[i].controller_data;
586 else if (devices[i].bus_num == 0)
587 cs_pin = spi0_standard_cs[devices[i].chip_select];
588 else
589 cs_pin = spi1_standard_cs[devices[i].chip_select];
590
591 if (devices[i].bus_num == 0)
592 enable_spi0 = 1;
593 else
594 enable_spi1 = 1;
595
596 /* enable chip-select pin */
597 at91_set_gpio_output(cs_pin, 1);
598
599 /* pass chip-select pin to driver */
600 devices[i].controller_data = (void *) cs_pin;
601 }
602
603 spi_register_board_info(devices, nr_devices);
604
605 /* Configure SPI bus(es) */
606 if (enable_spi0) {
607 at91_set_B_periph(AT91_PIN_PA0, 0); /* SPI0_MISO */
608 at91_set_B_periph(AT91_PIN_PA1, 0); /* SPI0_MOSI */
609 at91_set_B_periph(AT91_PIN_PA2, 0); /* SPI0_SPCK */
610
2b3b3516
AV
611 platform_device_register(&at91cap9_spi0_device);
612 }
613 if (enable_spi1) {
614 at91_set_A_periph(AT91_PIN_PB12, 0); /* SPI1_MISO */
615 at91_set_A_periph(AT91_PIN_PB13, 0); /* SPI1_MOSI */
616 at91_set_A_periph(AT91_PIN_PB14, 0); /* SPI1_SPCK */
617
2b3b3516
AV
618 platform_device_register(&at91cap9_spi1_device);
619 }
620}
621#else
622void __init at91_add_device_spi(struct spi_board_info *devices, int nr_devices) {}
623#endif
624
625
e5f40bfa
AV
626/* --------------------------------------------------------------------
627 * Timer/Counter block
628 * -------------------------------------------------------------------- */
629
630#ifdef CONFIG_ATMEL_TCLIB
631
632static struct resource tcb_resources[] = {
633 [0] = {
634 .start = AT91CAP9_BASE_TCB0,
635 .end = AT91CAP9_BASE_TCB0 + SZ_16K - 1,
636 .flags = IORESOURCE_MEM,
637 },
638 [1] = {
639 .start = AT91CAP9_ID_TCB,
640 .end = AT91CAP9_ID_TCB,
641 .flags = IORESOURCE_IRQ,
642 },
643};
644
645static struct platform_device at91cap9_tcb_device = {
646 .name = "atmel_tcb",
647 .id = 0,
648 .resource = tcb_resources,
649 .num_resources = ARRAY_SIZE(tcb_resources),
650};
651
652static void __init at91_add_device_tc(void)
653{
e5f40bfa
AV
654 platform_device_register(&at91cap9_tcb_device);
655}
656#else
657static void __init at91_add_device_tc(void) { }
658#endif
659
660
2b3b3516
AV
661/* --------------------------------------------------------------------
662 * RTT
663 * -------------------------------------------------------------------- */
664
4fd9212c
AV
665static struct resource rtt_resources[] = {
666 {
667 .start = AT91_BASE_SYS + AT91_RTT,
668 .end = AT91_BASE_SYS + AT91_RTT + SZ_16 - 1,
669 .flags = IORESOURCE_MEM,
670 }
671};
672
2b3b3516
AV
673static struct platform_device at91cap9_rtt_device = {
674 .name = "at91_rtt",
4fd9212c
AV
675 .id = 0,
676 .resource = rtt_resources,
677 .num_resources = ARRAY_SIZE(rtt_resources),
2b3b3516
AV
678};
679
680static void __init at91_add_device_rtt(void)
681{
682 platform_device_register(&at91cap9_rtt_device);
683}
684
685
686/* --------------------------------------------------------------------
687 * Watchdog
688 * -------------------------------------------------------------------- */
689
2af29b78 690#if defined(CONFIG_AT91SAM9X_WATCHDOG) || defined(CONFIG_AT91SAM9X_WATCHDOG_MODULE)
2b3b3516
AV
691static struct platform_device at91cap9_wdt_device = {
692 .name = "at91_wdt",
693 .id = -1,
694 .num_resources = 0,
695};
696
697static void __init at91_add_device_watchdog(void)
698{
699 platform_device_register(&at91cap9_wdt_device);
700}
701#else
702static void __init at91_add_device_watchdog(void) {}
703#endif
704
705
bb1ad68b
AV
706/* --------------------------------------------------------------------
707 * PWM
708 * --------------------------------------------------------------------*/
709
710#if defined(CONFIG_ATMEL_PWM)
711static u32 pwm_mask;
712
713static struct resource pwm_resources[] = {
714 [0] = {
715 .start = AT91CAP9_BASE_PWMC,
716 .end = AT91CAP9_BASE_PWMC + SZ_16K - 1,
717 .flags = IORESOURCE_MEM,
718 },
719 [1] = {
720 .start = AT91CAP9_ID_PWMC,
721 .end = AT91CAP9_ID_PWMC,
722 .flags = IORESOURCE_IRQ,
723 },
724};
725
726static struct platform_device at91cap9_pwm0_device = {
727 .name = "atmel_pwm",
728 .id = -1,
729 .dev = {
730 .platform_data = &pwm_mask,
731 },
732 .resource = pwm_resources,
733 .num_resources = ARRAY_SIZE(pwm_resources),
734};
735
736void __init at91_add_device_pwm(u32 mask)
737{
738 if (mask & (1 << AT91_PWM0))
739 at91_set_A_periph(AT91_PIN_PB19, 1); /* enable PWM0 */
740
741 if (mask & (1 << AT91_PWM1))
742 at91_set_B_periph(AT91_PIN_PB8, 1); /* enable PWM1 */
743
744 if (mask & (1 << AT91_PWM2))
745 at91_set_B_periph(AT91_PIN_PC29, 1); /* enable PWM2 */
746
747 if (mask & (1 << AT91_PWM3))
748 at91_set_B_periph(AT91_PIN_PA11, 1); /* enable PWM3 */
749
750 pwm_mask = mask;
751
752 platform_device_register(&at91cap9_pwm0_device);
753}
754#else
755void __init at91_add_device_pwm(u32 mask) {}
756#endif
757
758
759
2b3b3516
AV
760/* --------------------------------------------------------------------
761 * AC97
762 * -------------------------------------------------------------------- */
763
9173a8ef 764#if defined(CONFIG_SND_ATMEL_AC97C) || defined(CONFIG_SND_ATMEL_AC97C_MODULE)
2b3b3516 765static u64 ac97_dmamask = DMA_BIT_MASK(32);
9173a8ef 766static struct ac97c_platform_data ac97_data;
2b3b3516
AV
767
768static struct resource ac97_resources[] = {
769 [0] = {
770 .start = AT91CAP9_BASE_AC97C,
771 .end = AT91CAP9_BASE_AC97C + SZ_16K - 1,
772 .flags = IORESOURCE_MEM,
773 },
774 [1] = {
775 .start = AT91CAP9_ID_AC97C,
776 .end = AT91CAP9_ID_AC97C,
777 .flags = IORESOURCE_IRQ,
778 },
779};
780
781static struct platform_device at91cap9_ac97_device = {
9173a8ef 782 .name = "atmel_ac97c",
2b3b3516
AV
783 .id = 1,
784 .dev = {
785 .dma_mask = &ac97_dmamask,
786 .coherent_dma_mask = DMA_BIT_MASK(32),
787 .platform_data = &ac97_data,
788 },
789 .resource = ac97_resources,
790 .num_resources = ARRAY_SIZE(ac97_resources),
791};
792
9173a8ef 793void __init at91_add_device_ac97(struct ac97c_platform_data *data)
2b3b3516
AV
794{
795 if (!data)
796 return;
797
798 at91_set_A_periph(AT91_PIN_PA6, 0); /* AC97FS */
799 at91_set_A_periph(AT91_PIN_PA7, 0); /* AC97CK */
800 at91_set_A_periph(AT91_PIN_PA8, 0); /* AC97TX */
801 at91_set_A_periph(AT91_PIN_PA9, 0); /* AC97RX */
802
803 /* reset */
804 if (data->reset_pin)
805 at91_set_gpio_output(data->reset_pin, 0);
806
807 ac97_data = *data;
808 platform_device_register(&at91cap9_ac97_device);
809}
810#else
9173a8ef 811void __init at91_add_device_ac97(struct ac97c_platform_data *data) {}
2b3b3516
AV
812#endif
813
814
815/* --------------------------------------------------------------------
816 * LCD Controller
817 * -------------------------------------------------------------------- */
818
819#if defined(CONFIG_FB_ATMEL) || defined(CONFIG_FB_ATMEL_MODULE)
820static u64 lcdc_dmamask = DMA_BIT_MASK(32);
821static struct atmel_lcdfb_info lcdc_data;
822
823static struct resource lcdc_resources[] = {
824 [0] = {
825 .start = AT91CAP9_LCDC_BASE,
826 .end = AT91CAP9_LCDC_BASE + SZ_4K - 1,
827 .flags = IORESOURCE_MEM,
828 },
829 [1] = {
830 .start = AT91CAP9_ID_LCDC,
831 .end = AT91CAP9_ID_LCDC,
832 .flags = IORESOURCE_IRQ,
833 },
834};
835
836static struct platform_device at91_lcdc_device = {
837 .name = "atmel_lcdfb",
838 .id = 0,
839 .dev = {
840 .dma_mask = &lcdc_dmamask,
841 .coherent_dma_mask = DMA_BIT_MASK(32),
842 .platform_data = &lcdc_data,
843 },
844 .resource = lcdc_resources,
845 .num_resources = ARRAY_SIZE(lcdc_resources),
846};
847
848void __init at91_add_device_lcdc(struct atmel_lcdfb_info *data)
849{
850 if (!data)
851 return;
852
7be90a6b 853 if (cpu_is_at91cap9_revB())
6845664a 854 irq_set_irq_type(AT91CAP9_ID_LCDC, IRQ_TYPE_LEVEL_HIGH);
7be90a6b 855
2b3b3516
AV
856 at91_set_A_periph(AT91_PIN_PC1, 0); /* LCDHSYNC */
857 at91_set_A_periph(AT91_PIN_PC2, 0); /* LCDDOTCK */
858 at91_set_A_periph(AT91_PIN_PC3, 0); /* LCDDEN */
859 at91_set_B_periph(AT91_PIN_PB9, 0); /* LCDCC */
860 at91_set_A_periph(AT91_PIN_PC6, 0); /* LCDD2 */
861 at91_set_A_periph(AT91_PIN_PC7, 0); /* LCDD3 */
862 at91_set_A_periph(AT91_PIN_PC8, 0); /* LCDD4 */
863 at91_set_A_periph(AT91_PIN_PC9, 0); /* LCDD5 */
864 at91_set_A_periph(AT91_PIN_PC10, 0); /* LCDD6 */
865 at91_set_A_periph(AT91_PIN_PC11, 0); /* LCDD7 */
866 at91_set_A_periph(AT91_PIN_PC14, 0); /* LCDD10 */
867 at91_set_A_periph(AT91_PIN_PC15, 0); /* LCDD11 */
868 at91_set_A_periph(AT91_PIN_PC16, 0); /* LCDD12 */
869 at91_set_A_periph(AT91_PIN_PC17, 0); /* LCDD13 */
870 at91_set_A_periph(AT91_PIN_PC18, 0); /* LCDD14 */
871 at91_set_A_periph(AT91_PIN_PC19, 0); /* LCDD15 */
872 at91_set_A_periph(AT91_PIN_PC22, 0); /* LCDD18 */
873 at91_set_A_periph(AT91_PIN_PC23, 0); /* LCDD19 */
874 at91_set_A_periph(AT91_PIN_PC24, 0); /* LCDD20 */
875 at91_set_A_periph(AT91_PIN_PC25, 0); /* LCDD21 */
876 at91_set_A_periph(AT91_PIN_PC26, 0); /* LCDD22 */
877 at91_set_A_periph(AT91_PIN_PC27, 0); /* LCDD23 */
878
879 lcdc_data = *data;
880 platform_device_register(&at91_lcdc_device);
881}
882#else
883void __init at91_add_device_lcdc(struct atmel_lcdfb_info *data) {}
884#endif
885
886
887/* --------------------------------------------------------------------
888 * SSC -- Synchronous Serial Controller
889 * -------------------------------------------------------------------- */
890
891#if defined(CONFIG_ATMEL_SSC) || defined(CONFIG_ATMEL_SSC_MODULE)
892static u64 ssc0_dmamask = DMA_BIT_MASK(32);
893
894static struct resource ssc0_resources[] = {
895 [0] = {
896 .start = AT91CAP9_BASE_SSC0,
897 .end = AT91CAP9_BASE_SSC0 + SZ_16K - 1,
898 .flags = IORESOURCE_MEM,
899 },
900 [1] = {
901 .start = AT91CAP9_ID_SSC0,
902 .end = AT91CAP9_ID_SSC0,
903 .flags = IORESOURCE_IRQ,
904 },
905};
906
907static struct platform_device at91cap9_ssc0_device = {
908 .name = "ssc",
909 .id = 0,
910 .dev = {
911 .dma_mask = &ssc0_dmamask,
912 .coherent_dma_mask = DMA_BIT_MASK(32),
913 },
914 .resource = ssc0_resources,
915 .num_resources = ARRAY_SIZE(ssc0_resources),
916};
917
918static inline void configure_ssc0_pins(unsigned pins)
919{
920 if (pins & ATMEL_SSC_TF)
921 at91_set_A_periph(AT91_PIN_PB0, 1);
922 if (pins & ATMEL_SSC_TK)
923 at91_set_A_periph(AT91_PIN_PB1, 1);
924 if (pins & ATMEL_SSC_TD)
925 at91_set_A_periph(AT91_PIN_PB2, 1);
926 if (pins & ATMEL_SSC_RD)
927 at91_set_A_periph(AT91_PIN_PB3, 1);
928 if (pins & ATMEL_SSC_RK)
929 at91_set_A_periph(AT91_PIN_PB4, 1);
930 if (pins & ATMEL_SSC_RF)
931 at91_set_A_periph(AT91_PIN_PB5, 1);
932}
933
934static u64 ssc1_dmamask = DMA_BIT_MASK(32);
935
936static struct resource ssc1_resources[] = {
937 [0] = {
938 .start = AT91CAP9_BASE_SSC1,
939 .end = AT91CAP9_BASE_SSC1 + SZ_16K - 1,
940 .flags = IORESOURCE_MEM,
941 },
942 [1] = {
943 .start = AT91CAP9_ID_SSC1,
944 .end = AT91CAP9_ID_SSC1,
945 .flags = IORESOURCE_IRQ,
946 },
947};
948
949static struct platform_device at91cap9_ssc1_device = {
950 .name = "ssc",
951 .id = 1,
952 .dev = {
953 .dma_mask = &ssc1_dmamask,
954 .coherent_dma_mask = DMA_BIT_MASK(32),
955 },
956 .resource = ssc1_resources,
957 .num_resources = ARRAY_SIZE(ssc1_resources),
958};
959
960static inline void configure_ssc1_pins(unsigned pins)
961{
962 if (pins & ATMEL_SSC_TF)
963 at91_set_A_periph(AT91_PIN_PB6, 1);
964 if (pins & ATMEL_SSC_TK)
965 at91_set_A_periph(AT91_PIN_PB7, 1);
966 if (pins & ATMEL_SSC_TD)
967 at91_set_A_periph(AT91_PIN_PB8, 1);
968 if (pins & ATMEL_SSC_RD)
969 at91_set_A_periph(AT91_PIN_PB9, 1);
970 if (pins & ATMEL_SSC_RK)
971 at91_set_A_periph(AT91_PIN_PB10, 1);
972 if (pins & ATMEL_SSC_RF)
973 at91_set_A_periph(AT91_PIN_PB11, 1);
974}
975
976/*
977 * SSC controllers are accessed through library code, instead of any
978 * kind of all-singing/all-dancing driver. For example one could be
979 * used by a particular I2S audio codec's driver, while another one
980 * on the same system might be used by a custom data capture driver.
981 */
982void __init at91_add_device_ssc(unsigned id, unsigned pins)
983{
984 struct platform_device *pdev;
985
986 /*
987 * NOTE: caller is responsible for passing information matching
988 * "pins" to whatever will be using each particular controller.
989 */
990 switch (id) {
991 case AT91CAP9_ID_SSC0:
992 pdev = &at91cap9_ssc0_device;
993 configure_ssc0_pins(pins);
2b3b3516
AV
994 break;
995 case AT91CAP9_ID_SSC1:
996 pdev = &at91cap9_ssc1_device;
997 configure_ssc1_pins(pins);
2b3b3516
AV
998 break;
999 default:
1000 return;
1001 }
1002
1003 platform_device_register(pdev);
1004}
1005
1006#else
1007void __init at91_add_device_ssc(unsigned id, unsigned pins) {}
1008#endif
1009
1010
1011/* --------------------------------------------------------------------
1012 * UART
1013 * -------------------------------------------------------------------- */
1014
1015#if defined(CONFIG_SERIAL_ATMEL)
1016static struct resource dbgu_resources[] = {
1017 [0] = {
1018 .start = AT91_VA_BASE_SYS + AT91_DBGU,
1019 .end = AT91_VA_BASE_SYS + AT91_DBGU + SZ_512 - 1,
1020 .flags = IORESOURCE_MEM,
1021 },
1022 [1] = {
1023 .start = AT91_ID_SYS,
1024 .end = AT91_ID_SYS,
1025 .flags = IORESOURCE_IRQ,
1026 },
1027};
1028
1029static struct atmel_uart_data dbgu_data = {
1030 .use_dma_tx = 0,
1031 .use_dma_rx = 0, /* DBGU not capable of receive DMA */
1032 .regs = (void __iomem *)(AT91_VA_BASE_SYS + AT91_DBGU),
1033};
1034
1035static u64 dbgu_dmamask = DMA_BIT_MASK(32);
1036
1037static struct platform_device at91cap9_dbgu_device = {
1038 .name = "atmel_usart",
1039 .id = 0,
1040 .dev = {
1041 .dma_mask = &dbgu_dmamask,
1042 .coherent_dma_mask = DMA_BIT_MASK(32),
1043 .platform_data = &dbgu_data,
1044 },
1045 .resource = dbgu_resources,
1046 .num_resources = ARRAY_SIZE(dbgu_resources),
1047};
1048
1049static inline void configure_dbgu_pins(void)
1050{
1051 at91_set_A_periph(AT91_PIN_PC30, 0); /* DRXD */
1052 at91_set_A_periph(AT91_PIN_PC31, 1); /* DTXD */
1053}
1054
1055static struct resource uart0_resources[] = {
1056 [0] = {
1057 .start = AT91CAP9_BASE_US0,
1058 .end = AT91CAP9_BASE_US0 + SZ_16K - 1,
1059 .flags = IORESOURCE_MEM,
1060 },
1061 [1] = {
1062 .start = AT91CAP9_ID_US0,
1063 .end = AT91CAP9_ID_US0,
1064 .flags = IORESOURCE_IRQ,
1065 },
1066};
1067
1068static struct atmel_uart_data uart0_data = {
1069 .use_dma_tx = 1,
1070 .use_dma_rx = 1,
1071};
1072
1073static u64 uart0_dmamask = DMA_BIT_MASK(32);
1074
1075static struct platform_device at91cap9_uart0_device = {
1076 .name = "atmel_usart",
1077 .id = 1,
1078 .dev = {
1079 .dma_mask = &uart0_dmamask,
1080 .coherent_dma_mask = DMA_BIT_MASK(32),
1081 .platform_data = &uart0_data,
1082 },
1083 .resource = uart0_resources,
1084 .num_resources = ARRAY_SIZE(uart0_resources),
1085};
1086
1087static inline void configure_usart0_pins(unsigned pins)
1088{
1089 at91_set_A_periph(AT91_PIN_PA22, 1); /* TXD0 */
1090 at91_set_A_periph(AT91_PIN_PA23, 0); /* RXD0 */
1091
1092 if (pins & ATMEL_UART_RTS)
1093 at91_set_A_periph(AT91_PIN_PA24, 0); /* RTS0 */
1094 if (pins & ATMEL_UART_CTS)
1095 at91_set_A_periph(AT91_PIN_PA25, 0); /* CTS0 */
1096}
1097
1098static struct resource uart1_resources[] = {
1099 [0] = {
1100 .start = AT91CAP9_BASE_US1,
1101 .end = AT91CAP9_BASE_US1 + SZ_16K - 1,
1102 .flags = IORESOURCE_MEM,
1103 },
1104 [1] = {
1105 .start = AT91CAP9_ID_US1,
1106 .end = AT91CAP9_ID_US1,
1107 .flags = IORESOURCE_IRQ,
1108 },
1109};
1110
1111static struct atmel_uart_data uart1_data = {
1112 .use_dma_tx = 1,
1113 .use_dma_rx = 1,
1114};
1115
1116static u64 uart1_dmamask = DMA_BIT_MASK(32);
1117
1118static struct platform_device at91cap9_uart1_device = {
1119 .name = "atmel_usart",
1120 .id = 2,
1121 .dev = {
1122 .dma_mask = &uart1_dmamask,
1123 .coherent_dma_mask = DMA_BIT_MASK(32),
1124 .platform_data = &uart1_data,
1125 },
1126 .resource = uart1_resources,
1127 .num_resources = ARRAY_SIZE(uart1_resources),
1128};
1129
1130static inline void configure_usart1_pins(unsigned pins)
1131{
1132 at91_set_A_periph(AT91_PIN_PD0, 1); /* TXD1 */
1133 at91_set_A_periph(AT91_PIN_PD1, 0); /* RXD1 */
1134
1135 if (pins & ATMEL_UART_RTS)
1136 at91_set_B_periph(AT91_PIN_PD7, 0); /* RTS1 */
1137 if (pins & ATMEL_UART_CTS)
1138 at91_set_B_periph(AT91_PIN_PD8, 0); /* CTS1 */
1139}
1140
1141static struct resource uart2_resources[] = {
1142 [0] = {
1143 .start = AT91CAP9_BASE_US2,
1144 .end = AT91CAP9_BASE_US2 + SZ_16K - 1,
1145 .flags = IORESOURCE_MEM,
1146 },
1147 [1] = {
1148 .start = AT91CAP9_ID_US2,
1149 .end = AT91CAP9_ID_US2,
1150 .flags = IORESOURCE_IRQ,
1151 },
1152};
1153
1154static struct atmel_uart_data uart2_data = {
1155 .use_dma_tx = 1,
1156 .use_dma_rx = 1,
1157};
1158
1159static u64 uart2_dmamask = DMA_BIT_MASK(32);
1160
1161static struct platform_device at91cap9_uart2_device = {
1162 .name = "atmel_usart",
1163 .id = 3,
1164 .dev = {
1165 .dma_mask = &uart2_dmamask,
1166 .coherent_dma_mask = DMA_BIT_MASK(32),
1167 .platform_data = &uart2_data,
1168 },
1169 .resource = uart2_resources,
1170 .num_resources = ARRAY_SIZE(uart2_resources),
1171};
1172
1173static inline void configure_usart2_pins(unsigned pins)
1174{
1175 at91_set_A_periph(AT91_PIN_PD2, 1); /* TXD2 */
1176 at91_set_A_periph(AT91_PIN_PD3, 0); /* RXD2 */
1177
1178 if (pins & ATMEL_UART_RTS)
1179 at91_set_B_periph(AT91_PIN_PD5, 0); /* RTS2 */
1180 if (pins & ATMEL_UART_CTS)
1181 at91_set_B_periph(AT91_PIN_PD6, 0); /* CTS2 */
1182}
1183
11aadac4 1184static struct platform_device *__initdata at91_uarts[ATMEL_MAX_UART]; /* the UARTs to use */
2b3b3516
AV
1185struct platform_device *atmel_default_console_device; /* the serial console device */
1186
1187void __init at91_register_uart(unsigned id, unsigned portnr, unsigned pins)
1188{
1189 struct platform_device *pdev;
2b348e2f 1190 struct atmel_uart_data *pdata;
2b3b3516
AV
1191
1192 switch (id) {
1193 case 0: /* DBGU */
1194 pdev = &at91cap9_dbgu_device;
1195 configure_dbgu_pins();
2b3b3516
AV
1196 break;
1197 case AT91CAP9_ID_US0:
1198 pdev = &at91cap9_uart0_device;
1199 configure_usart0_pins(pins);
2b3b3516
AV
1200 break;
1201 case AT91CAP9_ID_US1:
1202 pdev = &at91cap9_uart1_device;
1203 configure_usart1_pins(pins);
2b3b3516
AV
1204 break;
1205 case AT91CAP9_ID_US2:
1206 pdev = &at91cap9_uart2_device;
1207 configure_usart2_pins(pins);
2b3b3516
AV
1208 break;
1209 default:
1210 return;
1211 }
2b348e2f
JCPV
1212 pdata = pdev->dev.platform_data;
1213 pdata->num = portnr; /* update to mapped ID */
2b3b3516
AV
1214
1215 if (portnr < ATMEL_MAX_UART)
1216 at91_uarts[portnr] = pdev;
1217}
1218
1219void __init at91_set_serial_console(unsigned portnr)
1220{
bd602995 1221 if (portnr < ATMEL_MAX_UART) {
2b3b3516 1222 atmel_default_console_device = at91_uarts[portnr];
5c1f9668 1223 at91cap9_set_console_clock(at91_uarts[portnr]->id);
bd602995 1224 }
2b3b3516
AV
1225}
1226
1227void __init at91_add_device_serial(void)
1228{
1229 int i;
1230
1231 for (i = 0; i < ATMEL_MAX_UART; i++) {
1232 if (at91_uarts[i])
1233 platform_device_register(at91_uarts[i]);
1234 }
11aadac4
AV
1235
1236 if (!atmel_default_console_device)
1237 printk(KERN_INFO "AT91: No default serial console defined.\n");
2b3b3516
AV
1238}
1239#else
1240void __init at91_register_uart(unsigned id, unsigned portnr, unsigned pins) {}
1241void __init at91_set_serial_console(unsigned portnr) {}
1242void __init at91_add_device_serial(void) {}
1243#endif
1244
1245
1246/* -------------------------------------------------------------------- */
1247/*
1248 * These devices are always present and don't need any board-specific
1249 * setup.
1250 */
1251static int __init at91_add_standard_devices(void)
1252{
1253 at91_add_device_rtt();
1254 at91_add_device_watchdog();
e5f40bfa 1255 at91_add_device_tc();
2b3b3516
AV
1256 return 0;
1257}
1258
1259arch_initcall(at91_add_standard_devices);
This page took 0.301155 seconds and 5 git commands to generate.