blob: a517c7f7af92b4536d718a01e3f2afd957f2521d [file] [log] [blame]
Nicolas Ferre789b23b2009-06-26 15:36:58 +01001/*
2 * Board-specific setup code for the AT91SAM9M10G45 Evaluation Kit family
3 *
4 * Covers: * AT91SAM9G45-EKES board
5 * * AT91SAM9M10G45-EK board
6 *
7 * Copyright (C) 2009 Atmel Corporation.
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
13 *
14 */
15
16#include <linux/types.h>
Russell King2f8163b2011-07-26 10:53:52 +010017#include <linux/gpio.h>
Nicolas Ferre789b23b2009-06-26 15:36:58 +010018#include <linux/init.h>
19#include <linux/mm.h>
20#include <linux/module.h>
21#include <linux/platform_device.h>
22#include <linux/spi/spi.h>
23#include <linux/fb.h>
24#include <linux/gpio_keys.h>
25#include <linux/input.h>
26#include <linux/leds.h>
Nicolas Ferre75305d72010-10-22 18:27:48 +020027#include <linux/atmel-mci.h>
Josh Wu343754f2011-10-22 15:17:40 +080028#include <linux/delay.h>
Alexandre Bellonic545dcd2014-05-29 01:20:05 +020029#include <linux/pwm.h>
30#include <linux/leds_pwm.h>
Nicolas Ferre789b23b2009-06-26 15:36:58 +010031
Maxime Ripard4a5920e2012-05-11 15:35:35 +020032#include <linux/platform_data/at91_adc.h>
33
Nicolas Ferre75305d72010-10-22 18:27:48 +020034#include <mach/hardware.h>
Nicolas Ferre789b23b2009-06-26 15:36:58 +010035#include <video/atmel_lcdc.h>
Josh Wu343754f2011-10-22 15:17:40 +080036#include <media/soc_camera.h>
37#include <media/atmel-isi.h>
Nicolas Ferre789b23b2009-06-26 15:36:58 +010038
39#include <asm/setup.h>
40#include <asm/mach-types.h>
41#include <asm/irq.h>
42
43#include <asm/mach/arch.h>
44#include <asm/mach/map.h>
45#include <asm/mach/irq.h>
46
Nicolas Ferre789b23b2009-06-26 15:36:58 +010047#include <mach/at91sam9_smc.h>
Jean-Christophe PLAGNIOL-VILLARD76b2ab72011-04-14 00:34:03 +080048#include <mach/system_rev.h>
Nicolas Ferre789b23b2009-06-26 15:36:58 +010049
Jean-Christophe PLAGNIOL-VILLARDa510b9b2012-10-30 06:41:28 +080050#include "at91_aic.h"
Jean-Christophe PLAGNIOL-VILLARD43d2f532012-10-30 05:14:17 +080051#include "board.h"
Nicolas Ferre789b23b2009-06-26 15:36:58 +010052#include "sam9_smc.h"
53#include "generic.h"
Linus Walleijcf2e9332014-03-27 14:18:51 +010054#include "gpio.h"
Nicolas Ferre789b23b2009-06-26 15:36:58 +010055
56
Jean-Christophe PLAGNIOL-VILLARD1b021a32011-04-28 20:19:32 +080057static void __init ek_init_early(void)
Nicolas Ferre789b23b2009-06-26 15:36:58 +010058{
59 /* Initialize processor: 12.000 MHz crystal */
Jean-Christophe PLAGNIOL-VILLARD21d08b92011-04-23 15:28:34 +080060 at91_initialize(12000000);
Nicolas Ferre789b23b2009-06-26 15:36:58 +010061}
62
Nicolas Ferre789b23b2009-06-26 15:36:58 +010063/*
64 * USB HS Host port (common to OHCI & EHCI)
65 */
66static struct at91_usbh_data __initdata ek_usbh_hs_data = {
67 .ports = 2,
68 .vbus_pin = {AT91_PIN_PD1, AT91_PIN_PD3},
Nicolas Ferrecca03552012-03-28 11:56:28 +020069 .vbus_pin_active_low = {1, 1},
Jean-Christophe PLAGNIOL-VILLARD63b4c292011-11-25 01:51:06 +080070 .overcurrent_pin= {-EINVAL, -EINVAL},
Nicolas Ferre789b23b2009-06-26 15:36:58 +010071};
72
73
74/*
75 * USB HS Device port
76 */
77static struct usba_platform_data __initdata ek_usba_udc_data = {
78 .vbus_pin = AT91_PIN_PB19,
79};
80
81
82/*
83 * SPI devices.
84 */
85static struct spi_board_info ek_spi_devices[] = {
86 { /* DataFlash chip */
87 .modalias = "mtd_dataflash",
88 .chip_select = 0,
89 .max_speed_hz = 15 * 1000 * 1000,
90 .bus_num = 0,
91 },
92};
93
94
95/*
Nicolas Ferre75305d72010-10-22 18:27:48 +020096 * MCI (SD/MMC)
97 */
98static struct mci_platform_data __initdata mci0_data = {
99 .slot[0] = {
100 .bus_width = 4,
101 .detect_pin = AT91_PIN_PD10,
Jean-Christophe PLAGNIOL-VILLARD63b4c292011-11-25 01:51:06 +0800102 .wp_pin = -EINVAL,
Nicolas Ferre75305d72010-10-22 18:27:48 +0200103 },
104};
105
106static struct mci_platform_data __initdata mci1_data = {
107 .slot[0] = {
108 .bus_width = 4,
109 .detect_pin = AT91_PIN_PD11,
110 .wp_pin = AT91_PIN_PD29,
111 },
112};
113
114
115/*
Nicolas Ferre789b23b2009-06-26 15:36:58 +0100116 * MACB Ethernet device
117 */
Jamie Iles84e0cdb2011-03-08 20:17:06 +0000118static struct macb_platform_data __initdata ek_macb_data = {
Nicolas Ferre789b23b2009-06-26 15:36:58 +0100119 .phy_irq_pin = AT91_PIN_PD5,
120 .is_rmii = 1,
121};
122
123
124/*
125 * NAND flash
126 */
127static struct mtd_partition __initdata ek_nand_partition[] = {
128 {
129 .name = "Partition 1",
130 .offset = 0,
131 .size = SZ_64M,
132 },
133 {
134 .name = "Partition 2",
135 .offset = MTDPART_OFS_NXTBLK,
136 .size = MTDPART_SIZ_FULL,
137 },
138};
139
Nicolas Ferre789b23b2009-06-26 15:36:58 +0100140/* det_pin is not connected */
141static struct atmel_nand_data __initdata ek_nand_data = {
142 .ale = 21,
143 .cle = 22,
144 .rdy_pin = AT91_PIN_PC8,
145 .enable_pin = AT91_PIN_PC14,
Jean-Christophe PLAGNIOL-VILLARD63b4c292011-11-25 01:51:06 +0800146 .det_pin = -EINVAL,
Jean-Christophe PLAGNIOL-VILLARDbf4289c2011-12-29 14:43:24 +0800147 .ecc_mode = NAND_ECC_SOFT,
Jean-Christophe PLAGNIOL-VILLARD98619dc2011-12-29 15:05:50 +0800148 .on_flash_bbt = 1,
Dmitry Eremin-Solenikov1754aab2011-05-29 17:49:22 +0400149 .parts = ek_nand_partition,
150 .num_parts = ARRAY_SIZE(ek_nand_partition),
Nicolas Ferre789b23b2009-06-26 15:36:58 +0100151};
152
153static struct sam9_smc_config __initdata ek_nand_smc_config = {
154 .ncs_read_setup = 0,
155 .nrd_setup = 2,
156 .ncs_write_setup = 0,
157 .nwe_setup = 2,
158
159 .ncs_read_pulse = 4,
160 .nrd_pulse = 4,
161 .ncs_write_pulse = 4,
162 .nwe_pulse = 4,
163
164 .read_cycle = 7,
165 .write_cycle = 7,
166
167 .mode = AT91_SMC_READMODE | AT91_SMC_WRITEMODE | AT91_SMC_EXNWMODE_DISABLE,
168 .tdf_cycles = 3,
169};
170
171static void __init ek_add_device_nand(void)
172{
Nicolas Ferre64393b32011-07-01 12:25:24 +0200173 ek_nand_data.bus_width_16 = board_have_nand_16bit();
Nicolas Ferre789b23b2009-06-26 15:36:58 +0100174 /* setup bus-width (8 or 16) */
175 if (ek_nand_data.bus_width_16)
176 ek_nand_smc_config.mode |= AT91_SMC_DBW_16;
177 else
178 ek_nand_smc_config.mode |= AT91_SMC_DBW_8;
179
180 /* configure chip-select 3 (NAND) */
Jean-Christophe PLAGNIOL-VILLARDfaee0cc2011-10-14 01:37:09 +0800181 sam9_smc_configure(0, 3, &ek_nand_smc_config);
Nicolas Ferre789b23b2009-06-26 15:36:58 +0100182
183 at91_add_device_nand(&ek_nand_data);
184}
185
186
187/*
Josh Wu343754f2011-10-22 15:17:40 +0800188 * ISI
189 */
190static struct isi_platform_data __initdata isi_data = {
191 .frate = ISI_CFG1_FRATE_CAPTURE_ALL,
192 /* to use codec and preview path simultaneously */
193 .full_mode = 1,
194 .data_width_flags = ISI_DATAWIDTH_8 | ISI_DATAWIDTH_10,
195 /* ISI_MCK is provided by programmable clock or external clock */
196 .mck_hz = 25000000,
197};
198
199
200/*
201 * soc-camera OV2640
202 */
203#if defined(CONFIG_SOC_CAMERA_OV2640) || \
204 defined(CONFIG_SOC_CAMERA_OV2640_MODULE)
205static unsigned long isi_camera_query_bus_param(struct soc_camera_link *link)
206{
207 /* ISI board for ek using default 8-bits connection */
208 return SOCAM_DATAWIDTH_8;
209}
210
211static int i2c_camera_power(struct device *dev, int on)
212{
213 /* enable or disable the camera */
214 pr_debug("%s: %s the camera\n", __func__, on ? "ENABLE" : "DISABLE");
215 at91_set_gpio_output(AT91_PIN_PD13, !on);
216
217 if (!on)
218 goto out;
219
220 /* If enabled, give a reset impulse */
221 at91_set_gpio_output(AT91_PIN_PD12, 0);
222 msleep(20);
223 at91_set_gpio_output(AT91_PIN_PD12, 1);
224 msleep(100);
225
226out:
227 return 0;
228}
229
230static struct i2c_board_info i2c_camera = {
231 I2C_BOARD_INFO("ov2640", 0x30),
232};
233
234static struct soc_camera_link iclink_ov2640 = {
235 .bus_id = 0,
236 .board_info = &i2c_camera,
237 .i2c_adapter_id = 0,
238 .power = i2c_camera_power,
239 .query_bus_param = isi_camera_query_bus_param,
240};
241
242static struct platform_device isi_ov2640 = {
243 .name = "soc-camera-pdrv",
244 .id = 0,
245 .dev = {
246 .platform_data = &iclink_ov2640,
247 },
248};
249#endif
250
251
252/*
Nicolas Ferre789b23b2009-06-26 15:36:58 +0100253 * LCD Controller
254 */
255#if defined(CONFIG_FB_ATMEL) || defined(CONFIG_FB_ATMEL_MODULE)
256static struct fb_videomode at91_tft_vga_modes[] = {
257 {
258 .name = "LG",
259 .refresh = 60,
260 .xres = 480, .yres = 272,
261 .pixclock = KHZ2PICOS(9000),
262
263 .left_margin = 1, .right_margin = 1,
264 .upper_margin = 40, .lower_margin = 1,
265 .hsync_len = 45, .vsync_len = 1,
266
267 .sync = 0,
268 .vmode = FB_VMODE_NONINTERLACED,
269 },
270};
271
272static struct fb_monspecs at91fb_default_monspecs = {
273 .manufacturer = "LG",
274 .monitor = "LB043WQ1",
275
276 .modedb = at91_tft_vga_modes,
277 .modedb_len = ARRAY_SIZE(at91_tft_vga_modes),
278 .hfmin = 15000,
279 .hfmax = 17640,
280 .vfmin = 57,
281 .vfmax = 67,
282};
283
284#define AT91SAM9G45_DEFAULT_LCDCON2 (ATMEL_LCDC_MEMOR_LITTLE \
285 | ATMEL_LCDC_DISTYPE_TFT \
286 | ATMEL_LCDC_CLKMOD_ALWAYSACTIVE)
287
288/* Driver datas */
Jean-Christophe PLAGNIOL-VILLARD8af2c282013-03-28 22:53:42 +0800289static struct atmel_lcdfb_pdata __initdata ek_lcdc_data = {
Nicolas Ferre789b23b2009-06-26 15:36:58 +0100290 .lcdcon_is_backlight = true,
291 .default_bpp = 32,
292 .default_dmacon = ATMEL_LCDC_DMAEN,
293 .default_lcdcon2 = AT91SAM9G45_DEFAULT_LCDCON2,
294 .default_monspecs = &at91fb_default_monspecs,
295 .guard_time = 9,
296 .lcd_wiring_mode = ATMEL_LCDC_WIRING_RGB,
297};
298
299#else
Jean-Christophe PLAGNIOL-VILLARD8af2c282013-03-28 22:53:42 +0800300static struct atmel_lcdfb_pdata __initdata ek_lcdc_data;
Nicolas Ferre789b23b2009-06-26 15:36:58 +0100301#endif
302
303
304/*
Alexandre Belloni9d971622014-04-15 12:28:05 +0200305 * ADCs and touchscreen
Maxime Ripard4a5920e2012-05-11 15:35:35 +0200306 */
307static struct at91_adc_data ek_adc_data = {
308 .channels_used = BIT(0) | BIT(1) | BIT(2) | BIT(3) | BIT(4) | BIT(5) | BIT(6) | BIT(7),
309 .use_external_triggers = true,
310 .vref = 3300,
Alexandre Bellonicab91592014-04-15 12:28:00 +0200311 .touchscreen_type = ATMEL_ADC_TOUCHSCREEN_4WIRE,
Maxime Ripard4a5920e2012-05-11 15:35:35 +0200312};
Nicolas Ferre985f37f2009-11-19 09:32:52 -0800313
314/*
Nicolas Ferre789b23b2009-06-26 15:36:58 +0100315 * GPIO Buttons
316 */
317#if defined(CONFIG_KEYBOARD_GPIO) || defined(CONFIG_KEYBOARD_GPIO_MODULE)
318static struct gpio_keys_button ek_buttons[] = {
319 { /* BP1, "leftclic" */
320 .code = BTN_LEFT,
321 .gpio = AT91_PIN_PB6,
322 .active_low = 1,
323 .desc = "left_click",
324 .wakeup = 1,
325 },
326 { /* BP2, "rightclic" */
327 .code = BTN_RIGHT,
328 .gpio = AT91_PIN_PB7,
329 .active_low = 1,
330 .desc = "right_click",
331 .wakeup = 1,
332 },
333 /* BP3, "joystick" */
334 {
335 .code = KEY_LEFT,
336 .gpio = AT91_PIN_PB14,
337 .active_low = 1,
338 .desc = "Joystick Left",
339 },
340 {
341 .code = KEY_RIGHT,
342 .gpio = AT91_PIN_PB15,
343 .active_low = 1,
344 .desc = "Joystick Right",
345 },
346 {
347 .code = KEY_UP,
348 .gpio = AT91_PIN_PB16,
349 .active_low = 1,
350 .desc = "Joystick Up",
351 },
352 {
353 .code = KEY_DOWN,
354 .gpio = AT91_PIN_PB17,
355 .active_low = 1,
356 .desc = "Joystick Down",
357 },
358 {
359 .code = KEY_ENTER,
360 .gpio = AT91_PIN_PB18,
361 .active_low = 1,
362 .desc = "Joystick Press",
363 },
364};
365
366static struct gpio_keys_platform_data ek_button_data = {
367 .buttons = ek_buttons,
368 .nbuttons = ARRAY_SIZE(ek_buttons),
369};
370
371static struct platform_device ek_button_device = {
372 .name = "gpio-keys",
373 .id = -1,
374 .num_resources = 0,
375 .dev = {
376 .platform_data = &ek_button_data,
377 }
378};
379
380static void __init ek_add_device_buttons(void)
381{
382 int i;
383
384 for (i = 0; i < ARRAY_SIZE(ek_buttons); i++) {
385 at91_set_GPIO_periph(ek_buttons[i].gpio, 1);
386 at91_set_deglitch(ek_buttons[i].gpio, 1);
387 }
388
389 platform_device_register(&ek_button_device);
390}
391#else
392static void __init ek_add_device_buttons(void) {}
393#endif
394
395
396/*
Nicolas Ferre378ac652009-09-18 16:14:22 +0100397 * AC97
398 * reset_pin is not connected: NRST
399 */
400static struct ac97c_platform_data ek_ac97_data = {
Jean-Christophe PLAGNIOL-VILLARD63b4c292011-11-25 01:51:06 +0800401 .reset_pin = -EINVAL,
Nicolas Ferre378ac652009-09-18 16:14:22 +0100402};
403
404
405/*
Nicolas Ferre789b23b2009-06-26 15:36:58 +0100406 * LEDs ... these could all be PWM-driven, for variable brightness
407 */
408static struct gpio_led ek_leds[] = {
409 { /* "top" led, red, powerled */
410 .name = "d8",
411 .gpio = AT91_PIN_PD30,
412 .default_trigger = "heartbeat",
413 },
414 { /* "left" led, green, userled2, pwm3 */
415 .name = "d6",
416 .gpio = AT91_PIN_PD0,
417 .active_low = 1,
418 .default_trigger = "nand-disk",
419 },
Alexandre Bellonic545dcd2014-05-29 01:20:05 +0200420#if !IS_ENABLED(CONFIG_LEDS_PWM)
Nicolas Ferre789b23b2009-06-26 15:36:58 +0100421 { /* "right" led, green, userled1, pwm1 */
422 .name = "d7",
423 .gpio = AT91_PIN_PD31,
424 .active_low = 1,
425 .default_trigger = "mmc0",
426 },
427#endif
428};
429
430
431/*
432 * PWM Leds
433 */
Alexandre Bellonic545dcd2014-05-29 01:20:05 +0200434static struct pwm_lookup pwm_lookup[] = {
435 PWM_LOOKUP("at91sam9rl-pwm", 1, "leds_pwm", "d7",
436 5000, PWM_POLARITY_INVERSED),
Nicolas Ferre789b23b2009-06-26 15:36:58 +0100437};
438
Alexandre Bellonic545dcd2014-05-29 01:20:05 +0200439#if IS_ENABLED(CONFIG_LEDS_PWM)
440static struct led_pwm pwm_leds[] = {
441 { /* "right" led, green, userled1, pwm1 */
442 .name = "d7",
443 .max_brightness = 255,
444 },
445};
446
447static struct led_pwm_platform_data pwm_data = {
448 .num_leds = ARRAY_SIZE(pwm_leds),
449 .leds = pwm_leds,
450};
451
452static struct platform_device leds_pwm = {
453 .name = "leds_pwm",
454 .id = -1,
455 .dev = {
456 .platform_data = &pwm_data,
457 },
458};
459#endif
460
Josh Wu343754f2011-10-22 15:17:40 +0800461static struct platform_device *devices[] __initdata = {
462#if defined(CONFIG_SOC_CAMERA_OV2640) || \
463 defined(CONFIG_SOC_CAMERA_OV2640_MODULE)
464 &isi_ov2640,
465#endif
Alexandre Bellonic545dcd2014-05-29 01:20:05 +0200466#if IS_ENABLED(CONFIG_LEDS_PWM)
467 &leds_pwm,
468#endif
Josh Wu343754f2011-10-22 15:17:40 +0800469};
Nicolas Ferre789b23b2009-06-26 15:36:58 +0100470
471static void __init ek_board_init(void)
472{
Maxime Riparde76265c2014-07-03 11:55:33 +0200473 at91_register_devices();
474
Nicolas Ferre789b23b2009-06-26 15:36:58 +0100475 /* Serial */
Jean-Christophe PLAGNIOL-VILLARD71b149b2012-04-05 14:14:28 +0800476 /* DGBU on ttyS0. (Rx & Tx only) */
477 at91_register_uart(0, 0, 0);
478
479 /* USART0 not connected on the -EK board */
480 /* USART1 on ttyS2. (Rx, Tx, RTS, CTS) */
481 at91_register_uart(AT91SAM9G45_ID_US1, 2, ATMEL_UART_CTS | ATMEL_UART_RTS);
Nicolas Ferre789b23b2009-06-26 15:36:58 +0100482 at91_add_device_serial();
483 /* USB HS Host */
484 at91_add_device_usbh_ohci(&ek_usbh_hs_data);
Nicolas Ferref51f78c2009-09-25 12:11:32 +0100485 at91_add_device_usbh_ehci(&ek_usbh_hs_data);
Nicolas Ferre789b23b2009-06-26 15:36:58 +0100486 /* USB HS Device */
487 at91_add_device_usba(&ek_usba_udc_data);
488 /* SPI */
489 at91_add_device_spi(ek_spi_devices, ARRAY_SIZE(ek_spi_devices));
Nicolas Ferre75305d72010-10-22 18:27:48 +0200490 /* MMC */
491 at91_add_device_mci(0, &mci0_data);
492 at91_add_device_mci(1, &mci1_data);
Nicolas Ferre789b23b2009-06-26 15:36:58 +0100493 /* Ethernet */
494 at91_add_device_eth(&ek_macb_data);
495 /* NAND */
496 ek_add_device_nand();
497 /* I2C */
498 at91_add_device_i2c(0, NULL, 0);
Josh Wu343754f2011-10-22 15:17:40 +0800499 /* ISI, using programmable clock as ISI_MCK */
500 at91_add_device_isi(&isi_data, true);
Nicolas Ferre789b23b2009-06-26 15:36:58 +0100501 /* LCD Controller */
502 at91_add_device_lcdc(&ek_lcdc_data);
Alexandre Belloni9d971622014-04-15 12:28:05 +0200503 /* ADC and touchscreen */
Maxime Ripard4a5920e2012-05-11 15:35:35 +0200504 at91_add_device_adc(&ek_adc_data);
Nicolas Ferre789b23b2009-06-26 15:36:58 +0100505 /* Push Buttons */
506 ek_add_device_buttons();
Nicolas Ferre378ac652009-09-18 16:14:22 +0100507 /* AC97 */
508 at91_add_device_ac97(&ek_ac97_data);
Nicolas Ferre789b23b2009-06-26 15:36:58 +0100509 /* LEDs */
510 at91_gpio_leds(ek_leds, ARRAY_SIZE(ek_leds));
Alexandre Bellonic545dcd2014-05-29 01:20:05 +0200511 pwm_add_table(pwm_lookup, ARRAY_SIZE(pwm_lookup));
512#if IS_ENABLED(CONFIG_LEDS_PWM)
513 at91_add_device_pwm(1 << AT91_PWM1);
514#endif
Josh Wu343754f2011-10-22 15:17:40 +0800515 /* Other platform devices */
516 platform_add_devices(devices, ARRAY_SIZE(devices));
Nicolas Ferre789b23b2009-06-26 15:36:58 +0100517}
518
Jean-Christophe PLAGNIOL-VILLARD67dd8992010-09-22 07:55:59 +0200519MACHINE_START(AT91SAM9M10G45EK, "Atmel AT91SAM9M10G45-EK")
Nicolas Ferre789b23b2009-06-26 15:36:58 +0100520 /* Maintainer: Atmel */
Maxime Ripard0f391f12014-07-01 11:33:25 +0200521 .init_time = at91_init_time,
Jean-Christophe PLAGNIOL-VILLARD21d08b92011-04-23 15:28:34 +0800522 .map_io = at91_map_io,
Ludovic Desroches3e135462012-06-11 15:38:03 +0200523 .handle_irq = at91_aic_handle_irq,
Jean-Christophe PLAGNIOL-VILLARD1b021a32011-04-28 20:19:32 +0800524 .init_early = ek_init_early,
Jean-Christophe PLAGNIOL-VILLARD92100c12011-04-23 15:28:34 +0800525 .init_irq = at91_init_irq_default,
Nicolas Ferre789b23b2009-06-26 15:36:58 +0100526 .init_machine = ek_board_init,
527MACHINE_END