Full support for Ginger Console
[linux-ginger.git] / arch / arm / mach-omap2 / board-ginger.c
blobd0b4e591a0ceab5899fa1adbe9a7e09cac2e1b81
1 /*
2 * board-ginger - TimLL Devkit8000-based Ginger Console
4 * Copyright (C) 2009 Kim Botherway
5 * Copyright (C) 2010 Thomas Weber
7 * Modified from mach-omap2/board-omap3beagle.c
9 * Initial code: Syed Mohammed Khasim
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License version 2 as
13 * published by the Free Software Foundation.
16 #include <linux/kernel.h>
17 #include <linux/init.h>
18 #include <linux/platform_device.h>
19 #include <linux/delay.h>
20 #include <linux/err.h>
21 #include <linux/clk.h>
22 #include <linux/io.h>
23 #include <linux/leds.h>
24 #include <linux/gpio.h>
25 #include <linux/input.h>
26 #include <linux/gpio_keys.h>
28 #include <linux/mtd/mtd.h>
29 #include <linux/mtd/partitions.h>
30 #include <linux/mtd/nand.h>
32 #include <linux/regulator/machine.h>
33 #include <linux/i2c/twl4030.h>
35 #include <mach/hardware.h>
36 #include <asm/mach-types.h>
37 #include <asm/mach/arch.h>
38 #include <asm/mach/map.h>
39 #include <asm/mach/flash.h>
41 #include <plat/board.h>
42 #include <plat/common.h>
43 #include <plat/gpmc.h>
44 #include <plat/nand.h>
45 #include <plat/usb.h>
46 #include <plat/timer-gp.h>
47 #include <plat/display.h>
49 #include <plat/mcspi.h>
50 #include <linux/input/matrix_keypad.h>
51 #include <linux/spi/spi.h>
52 #include <linux/spi/ads7846.h>
53 #include <linux/usb/otg.h>
54 #include <linux/dm9000.h>
55 #include <linux/interrupt.h>
57 #include "sdram-micron-mt46h32m32lf-6.h"
58 #include "mmc-twl4030.h"
59 #include "pm.h"
60 #include "omap3-opp.h"
62 #include <plat/mux.h>
63 #include <plat/mmc.h>
65 #define GPMC_CS0_BASE 0x60
66 #define GPMC_CS_SIZE 0x30
68 #define NAND_BLOCK_SIZE SZ_128K
70 #define OMAP_DM9000_GPIO_IRQ 25
71 #define OMAP3_EVM_TS_GPIO 27
73 static struct mtd_partition ginger_nand_partitions[] = {
74 /* All the partition sizes are listed in terms of NAND block size */
76 .name = "X-Loader",
77 .offset = 0,
78 .size = 4 * NAND_BLOCK_SIZE,
79 .mask_flags = MTD_WRITEABLE, /* force read-only */
82 .name = "U-Boot",
83 .offset = MTDPART_OFS_APPEND, /* Offset = 0x80000 */
84 .size = 15 * NAND_BLOCK_SIZE,
85 .mask_flags = MTD_WRITEABLE, /* force read-only */
88 .name = "U-Boot Env",
89 .offset = MTDPART_OFS_APPEND, /* Offset = 0x260000 */
90 .size = 1 * NAND_BLOCK_SIZE,
93 .name = "Kernel",
94 .offset = MTDPART_OFS_APPEND, /* Offset = 0x280000 */
95 .size = 32 * NAND_BLOCK_SIZE,
98 .name = "File System",
99 .offset = MTDPART_OFS_APPEND, /* Offset = 0x680000 */
100 .size = MTDPART_SIZ_FULL,
104 static struct omap_nand_platform_data ginger_nand_data = {
105 .options = NAND_BUSWIDTH_16,
106 .parts = ginger_nand_partitions,
107 .nr_parts = ARRAY_SIZE(ginger_nand_partitions),
108 .dma_channel = -1, /* disable DMA in OMAP NAND driver */
109 .nand_setup = NULL,
110 .dev_ready = NULL,
113 static struct resource ginger_nand_resource = {
114 .flags = IORESOURCE_MEM,
117 static struct platform_device ginger_nand_device = {
118 .name = "omap2-nand",
119 .id = -1,
120 .dev = {
121 .platform_data = &ginger_nand_data,
123 .num_resources = 1,
124 .resource = &ginger_nand_resource,
127 static struct twl4030_hsmmc_info mmc[] = {
129 .mmc = 1,
130 .wires = 8,
131 .gpio_wp = 29,
133 {} /* Terminator */
135 static struct omap_board_config_kernel ginger_config[] __initdata = {
138 // static int ginger_panel_enable_lcd(struct omap_dss_device *dssdev)
139 // {
140 // twl_i2c_write_u8(TWL4030_MODULE_GPIO, 0x80, REG_GPIODATADIR1);
141 // twl_i2c_write_u8(TWL4030_MODULE_LED, 0x0, 0x0);
143 // return 0;
144 // }
146 // static void ginger_panel_disable_lcd(struct omap_dss_device *dssdev)
147 // {
148 // }
149 static int ginger_panel_enable_lcd(struct omap_dss_device *dssdev)
151 twl4030_i2c_write_u8(TWL4030_MODULE_GPIO, 0x80, REG_GPIODATAOUT1);
152 twl4030_i2c_write_u8(TWL4030_MODULE_LED, 0x0, 0x0);
153 return 0;
155 static void ginger_panel_disable_lcd(struct omap_dss_device *dssdev)
157 twl4030_i2c_write_u8(TWL4030_MODULE_GPIO, 0x80, REG_GPIODATAOUT1);
158 twl4030_i2c_write_u8(TWL4030_MODULE_LED, 0x0, 0x0);
160 static int ginger_panel_enable_dvi(struct omap_dss_device *dssdev)
162 return 0;
165 static void ginger_panel_disable_dvi(struct omap_dss_device *dssdev)
169 static int ginger_panel_enable_tv(struct omap_dss_device *dssdev)
172 return 0;
175 static void ginger_panel_disable_tv(struct omap_dss_device *dssdev)
180 static struct regulator_consumer_supply ginger_vmmc1_supply = {
181 .supply = "vmmc",
184 static struct regulator_consumer_supply ginger_vsim_supply = {
185 .supply = "vmmc_aux",
188 static struct regulator_consumer_supply ginger_vio_supplies[] = {
189 REGULATOR_SUPPLY("vcc", "spi2.0"),
193 static struct omap_dss_device ginger_lcd_device = {
194 .name = "lcd",
195 .driver_name = "ginger_panel",
196 .type = OMAP_DISPLAY_TYPE_DPI,
197 .phy.dpi.data_lines = 24,
198 .platform_enable = ginger_panel_enable_lcd,
199 .platform_disable = ginger_panel_disable_lcd,
201 static struct omap_dss_device ginger_dvi_device = {
202 .name = "dvi",
203 .driver_name = "generic_panel",
204 .type = OMAP_DISPLAY_TYPE_DPI,
205 .phy.dpi.data_lines = 24,
206 .platform_enable = ginger_panel_enable_dvi,
207 .platform_disable = ginger_panel_disable_dvi,
210 static struct omap_dss_device ginger_tv_device = {
211 .name = "tv",
212 .driver_name = "venc",
213 .type = OMAP_DISPLAY_TYPE_VENC,
214 .phy.venc.type = OMAP_DSS_VENC_TYPE_SVIDEO,
215 .platform_enable = ginger_panel_enable_tv,
216 .platform_disable = ginger_panel_disable_tv,
220 static struct omap_dss_device *ginger_dss_devices[] = {
221 &ginger_lcd_device,
222 &ginger_dvi_device,
223 &ginger_tv_device,
226 static struct omap_dss_board_info ginger_dss_data = {
227 .num_devices = ARRAY_SIZE(ginger_dss_devices),
228 .devices = ginger_dss_devices,
229 .default_device = &ginger_lcd_device,
232 static struct platform_device ginger_dss_device = {
233 .name = "omapdss",
234 .id = -1,
235 .dev = {
236 .platform_data = &ginger_dss_data,
240 static struct regulator_consumer_supply ginger_vdda_dac_supply = {
241 .supply = "vdda_dac",
242 .dev = &ginger_dss_device.dev,
245 static int board_keymap[] = {
246 KEY(0, 0, KEY_1),
247 KEY(1, 0, KEY_2),
248 KEY(2, 0, KEY_3),
249 KEY(0, 1, KEY_4),
250 KEY(1, 1, KEY_5),
251 KEY(2, 1, KEY_6),
252 KEY(3, 1, KEY_F5),
253 KEY(0, 2, KEY_7),
254 KEY(1, 2, KEY_8),
255 KEY(2, 2, KEY_9),
256 KEY(3, 2, KEY_F6),
257 KEY(0, 3, KEY_F7),
258 KEY(1, 3, KEY_0),
259 KEY(2, 3, KEY_F8),
260 PERSISTENT_KEY(4, 5),
261 KEY(4, 4, KEY_VOLUMEUP),
262 KEY(5, 5, KEY_VOLUMEDOWN),
266 static struct matrix_keymap_data board_map_data = {
267 .keymap = board_keymap,
268 .keymap_size = ARRAY_SIZE(board_keymap),
271 static struct twl4030_keypad_data ginger_kp_data = {
272 .keymap_data = &board_map_data,
273 .rows = 6,
274 .cols = 6,
275 .rep = 1,
278 static struct gpio_led gpio_leds[];
280 static int ginger_twl_gpio_setup(struct device *dev,
281 unsigned gpio, unsigned ngpio)
283 omap_cfg_reg(AH8_34XX_GPIO29);
284 /* gpio + 0 is "mmc0_cd" (input/IRQ) */
285 mmc[0].gpio_cd = gpio + 0;
286 twl4030_mmc_init(mmc);
288 /* link regulators to MMC adapters */
289 ginger_vmmc1_supply.dev = mmc[0].dev;
290 ginger_vsim_supply.dev = mmc[0].dev;
292 /* REVISIT: need ehci-omap hooks for external VBUS
293 * power switch and overcurrent detect
296 gpio_request(gpio + 1, "EHCI_nOC");
297 gpio_direction_input(gpio + 1);
299 /* TWL4030_GPIO_MAX + 0 == ledA, EHCI nEN_USB_PWR (out, active low) */
300 gpio_request(gpio + TWL4030_GPIO_MAX, "nEN_USB_PWR");
301 gpio_direction_output(gpio + TWL4030_GPIO_MAX, 1);
303 /* TWL4030_GPIO_MAX + 1 == ledB, PMU_STAT (out, active low LED) */
304 gpio_leds[2].gpio = gpio + TWL4030_GPIO_MAX + 1;
306 return 0;
309 static struct twl4030_gpio_platform_data ginger_gpio_data = {
310 .gpio_base = OMAP_MAX_GPIO_LINES,
311 .irq_base = TWL4030_GPIO_IRQ_BASE,
312 .irq_end = TWL4030_GPIO_IRQ_END,
313 .use_leds = true,
314 .pullups = BIT(1),
315 .pulldowns = BIT(2) | BIT(6) | BIT(7) | BIT(8) | BIT(13)
316 | BIT(15) | BIT(16) | BIT(17),
317 .setup = ginger_twl_gpio_setup,
320 static struct regulator_consumer_supply ginger_vpll1_supplies[] = {
322 .supply = "vdvi",
323 .dev = &ginger_lcd_device.dev,
326 .supply = "vdss_dsi",
327 .dev = &ginger_dss_device.dev,
331 /* VMMC1 for MMC1 pins CMD, CLK, DAT0..DAT3 (20 mA, plus card == max 220 mA) */
332 static struct regulator_init_data ginger_vmmc1 = {
333 .constraints = {
334 .min_uV = 1850000,
335 .max_uV = 3150000,
336 .valid_modes_mask = REGULATOR_MODE_NORMAL
337 | REGULATOR_MODE_STANDBY,
338 .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE
339 | REGULATOR_CHANGE_MODE
340 | REGULATOR_CHANGE_STATUS,
342 .num_consumer_supplies = 1,
343 .consumer_supplies = &ginger_vmmc1_supply,
346 /* VSIM for MMC1 pins DAT4..DAT7 (2 mA, plus card == max 50 mA) */
347 static struct regulator_init_data ginger_vsim = {
348 .constraints = {
349 .min_uV = 1800000,
350 .max_uV = 3000000,
351 .valid_modes_mask = REGULATOR_MODE_NORMAL
352 | REGULATOR_MODE_STANDBY,
353 .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE
354 | REGULATOR_CHANGE_MODE
355 | REGULATOR_CHANGE_STATUS,
357 .num_consumer_supplies = 1,
358 .consumer_supplies = &ginger_vsim_supply,
361 /* VDAC for DSS driving S-Video (8 mA unloaded, max 65 mA) */
362 static struct regulator_init_data ginger_vdac = {
363 .constraints = {
364 .min_uV = 1800000,
365 .max_uV = 1800000,
366 .valid_modes_mask = REGULATOR_MODE_NORMAL
367 | REGULATOR_MODE_STANDBY,
368 .valid_ops_mask = REGULATOR_CHANGE_MODE
369 | REGULATOR_CHANGE_STATUS,
371 .num_consumer_supplies = 1,
372 .consumer_supplies = &ginger_vdda_dac_supply,
375 /* VPLL2 for digital video outputs */
376 static struct regulator_init_data ginger_vpll1 = {
377 .constraints = {
378 .name = "VDVI",
379 .min_uV = 1800000,
380 .max_uV = 1800000,
381 .valid_modes_mask = REGULATOR_MODE_NORMAL
382 | REGULATOR_MODE_STANDBY,
383 .valid_ops_mask = REGULATOR_CHANGE_MODE
384 | REGULATOR_CHANGE_STATUS,
386 .num_consumer_supplies = ARRAY_SIZE(ginger_vpll1_supplies),
387 .consumer_supplies = ginger_vpll1_supplies,
390 /* VAUX4 for ads7846 and nubs */
391 static struct regulator_init_data ginger_vio = {
392 .constraints = {
393 .min_uV = 1800000,
394 .max_uV = 1800000,
395 .apply_uV = true,
396 .valid_modes_mask = REGULATOR_MODE_NORMAL
397 | REGULATOR_MODE_STANDBY,
398 .valid_ops_mask = REGULATOR_CHANGE_MODE
399 | REGULATOR_CHANGE_STATUS,
401 .num_consumer_supplies = ARRAY_SIZE(ginger_vio_supplies),
402 .consumer_supplies = ginger_vio_supplies,
406 static struct twl4030_usb_data ginger_usb_data = {
407 .usb_mode = T2_USB_MODE_ULPI,
410 static struct twl4030_platform_data ginger_twldata = {
411 .irq_base = TWL4030_IRQ_BASE,
412 .irq_end = TWL4030_IRQ_END,
414 /* platform_data for children goes here */
415 .usb = &ginger_usb_data,
416 .gpio = &ginger_gpio_data,
417 .vmmc1 = &ginger_vmmc1,
418 .vsim = &ginger_vsim,
419 .vdac = &ginger_vdac,
420 .vpll1 = &ginger_vpll1,
421 .keypad = &ginger_kp_data,
424 static struct i2c_board_info __initdata ginger_i2c_boardinfo[] = {
426 I2C_BOARD_INFO("twl4030", 0x48),
427 .flags = I2C_CLIENT_WAKE,
428 .irq = INT_34XX_SYS_NIRQ,
429 .platform_data = &ginger_twldata,
433 static int __init ginger_i2c_init(void)
435 omap_register_i2c_bus(1, 2600, ginger_i2c_boardinfo,
436 ARRAY_SIZE(ginger_i2c_boardinfo));
437 /* Bus 3 is attached to the DVI port where devices like the pico DLP
438 * projector don't work reliably with 400kHz */
439 omap_register_i2c_bus(3, 400, NULL, 0);
440 return 0;
443 static struct gpio_led gpio_leds[] = {
445 .name = "led1",
446 .default_trigger = "heartbeat",
447 .gpio = 186,
448 .active_low = true,
451 .name = "led2",
452 .default_trigger = "mmc0",
453 .gpio = 163,
454 .active_low = true,
457 .name = "ledB",
458 .default_trigger = "none",
459 .gpio = 153,
460 .active_low = true,
463 .name = "led3",
464 .default_trigger = "none",
465 .gpio = 164,
466 .active_low = true,
470 static struct gpio_led_platform_data gpio_led_info = {
471 .leds = gpio_leds,
472 .num_leds = ARRAY_SIZE(gpio_leds),
475 static struct platform_device leds_gpio = {
476 .name = "leds-gpio",
477 .id = -1,
478 .dev = {
479 .platform_data = &gpio_led_info,
483 static struct gpio_keys_button gpio_buttons[] = {
485 .code = BTN_EXTRA,
486 .gpio = 26,
487 .desc = "user",
488 .wakeup = 1,
492 static struct gpio_keys_platform_data gpio_key_info = {
493 .buttons = gpio_buttons,
494 .nbuttons = ARRAY_SIZE(gpio_buttons),
497 static struct platform_device keys_gpio = {
498 .name = "gpio-keys",
499 .id = -1,
500 .dev = {
501 .platform_data = &gpio_key_info,
507 #define OMAP_DM9000_BASE 0x2c000000
509 static struct resource omap_dm9000_resources[] = {
510 [0] = {
511 .start = OMAP_DM9000_BASE,
512 .end = (OMAP_DM9000_BASE + 0x4 - 1),
513 .flags = IORESOURCE_MEM,
515 [1] = {
516 .start = (OMAP_DM9000_BASE + 0x400),
517 .end = (OMAP_DM9000_BASE + 0x400 + 0x4 - 1),
518 .flags = IORESOURCE_MEM,
520 [2] = {
521 .start = OMAP_GPIO_IRQ(OMAP_DM9000_GPIO_IRQ),
522 .flags = IORESOURCE_IRQ | IRQF_TRIGGER_LOW,
526 static struct dm9000_plat_data omap_dm9000_platdata = {
527 .flags = DM9000_PLATF_16BITONLY,
530 static struct platform_device omap_dm9000_dev = {
531 .name = "dm9000",
532 .id = -1,
533 .num_resources = ARRAY_SIZE(omap_dm9000_resources),
534 .resource = omap_dm9000_resources,
535 .dev = {
536 .platform_data = &omap_dm9000_platdata,
540 static void __init omap_dm9000_init(void)
542 if (gpio_request(OMAP_DM9000_GPIO_IRQ, "dm9000 irq") < 0) {
543 printk(KERN_ERR "Failed to request GPIO%d for dm9000 IRQ\n",
544 OMAP_DM9000_GPIO_IRQ);
545 return;
548 gpio_direction_input(OMAP_DM9000_GPIO_IRQ);
551 static void __init ginger_init_irq(void)
553 omap_board_config = ginger_config;
554 omap_board_config_size = ARRAY_SIZE(ginger_config);
556 omap2_init_common_hw(mt46h32m32lf6_sdrc_params, mt46h32m32lf6_sdrc_params,
557 omap3_mpu_rate_table,omap3_dsp_rate_table, omap3_l3_rate_table);
559 omap_init_irq();
560 #ifdef CONFIG_OMAP_32K_TIMER
561 omap2_gp_clockevent_set_gptimer(12);
562 #endif
563 omap_gpio_init();
564 omap_dm9000_init();
567 static struct platform_device *ginger_devices[] __initdata = {
568 &ginger_dss_device,
569 &leds_gpio,
570 &keys_gpio,
571 &omap_dm9000_dev,
574 static void __init ginger_flash_init(void)
576 u8 cs = 0;
577 u8 nandcs = GPMC_CS_NUM + 1;
579 u32 gpmc_base_add = OMAP34XX_GPMC_VIRT;
581 /* find out the chip-select on which NAND exists */
582 while (cs < GPMC_CS_NUM) {
583 u32 ret = 0;
584 ret = gpmc_cs_read_reg(cs, GPMC_CS_CONFIG1);
586 if ((ret & 0xC00) == 0x800) {
587 printk(KERN_INFO "Found NAND on CS%d\n", cs);
588 if (nandcs > GPMC_CS_NUM)
589 nandcs = cs;
591 cs++;
594 if (nandcs > GPMC_CS_NUM) {
595 printk(KERN_INFO "NAND: Unable to find configuration "
596 "in GPMC\n ");
597 return;
600 if (nandcs < GPMC_CS_NUM) {
601 ginger_nand_data.cs = nandcs;
602 ginger_nand_data.gpmc_cs_baseaddr = (void *)
603 (gpmc_base_add + GPMC_CS0_BASE + nandcs * GPMC_CS_SIZE);
604 ginger_nand_data.gpmc_baseaddr = (void *)
605 (gpmc_base_add);
607 printk(KERN_INFO "Registering NAND on CS%d\n", nandcs);
608 if (platform_device_register(&ginger_nand_device) < 0)
609 printk(KERN_ERR "Unable to register NAND device\n");
613 static struct ehci_hcd_omap_platform_data ehci_pdata __initconst = {
615 .port_mode[0] = EHCI_HCD_OMAP_MODE_PHY,
616 .port_mode[1] = EHCI_HCD_OMAP_MODE_PHY,
617 .port_mode[2] = EHCI_HCD_OMAP_MODE_UNKNOWN,
619 .phy_reset = true,
620 .reset_gpio_port[0] = -EINVAL,
621 .reset_gpio_port[1] = 147,
622 .reset_gpio_port[2] = -EINVAL
625 ////// TOUCH
626 static void ads7846_dev_init(void)
628 if (gpio_request(OMAP3_EVM_TS_GPIO, "ADS7846 pendown") < 0)
629 printk(KERN_ERR "can't get ads7846 pen down GPIO\n");
631 gpio_direction_input(OMAP3_EVM_TS_GPIO);
633 omap_set_gpio_debounce(OMAP3_EVM_TS_GPIO, 1);
634 omap_set_gpio_debounce_time(OMAP3_EVM_TS_GPIO, 0xa);
637 static int ads7846_get_pendown_state(void)
639 return !gpio_get_value(OMAP3_EVM_TS_GPIO);
642 struct ads7846_platform_data ads7846_config = {
643 .x_max = 0x0fff,
644 .y_max = 0x0fff,
645 // .x_plate_ohms = 180,
646 // .pressure_max = 255,
647 .debounce_max = 10,
648 .debounce_tol = 5,
649 .debounce_rep = 1,
650 .get_pendown_state = ads7846_get_pendown_state,
651 .keep_vref_on = 1,
652 .settle_delay_usecs = 150,
655 static struct omap2_mcspi_device_config ads7846_mcspi_config = {
656 .turbo_mode = 0,
657 .single_channel = 1, /* 0: slave, 1: master */
660 struct spi_board_info omap3evm_spi_board_info[] = {
661 [0] = {
662 .modalias = "ads7846",
663 .bus_num = 2,
664 .chip_select = 0,
665 .max_speed_hz = 1500000,
666 .controller_data = &ads7846_mcspi_config,
667 .irq = OMAP_GPIO_IRQ(OMAP3_EVM_TS_GPIO),
668 .platform_data = &ads7846_config,
673 static void __init ginger_init(void)
675 ginger_i2c_init();
676 platform_add_devices(ginger_devices,
677 ARRAY_SIZE(ginger_devices));
678 omap_board_config = ginger_config;
679 omap_board_config_size = ARRAY_SIZE(ginger_config);
681 spi_register_board_info(omap3evm_spi_board_info,
682 ARRAY_SIZE(omap3evm_spi_board_info));
683 omap_serial_init();
687 omap_cfg_reg(J25_34XX_GPIO170);
688 gpio_request(170, "DVI_nPD");
689 /* REVISIT leave DVI powered down until it's needed ... */
690 gpio_direction_output(170, true);
692 usb_musb_init();
693 usb_ehci_init(&ehci_pdata);
695 ads7846_dev_init();
696 ginger_flash_init();
698 /* Ensure SDRC pins are mux'd for self-refresh */
699 omap_cfg_reg(H16_34XX_SDRC_CKE0);
700 omap_cfg_reg(H17_34XX_SDRC_CKE1);
703 static void __init ginger_map_io(void)
705 omap2_set_globals_343x();
706 omap2_map_common_io();
709 MACHINE_START(GINGER, "GDi Ginger Console")
710 .phys_io = 0x48000000,
711 .io_pg_offst = ((0xd8000000) >> 18) & 0xfffc,
712 .boot_params = 0x80000100,
713 .map_io = ginger_map_io,
714 .init_irq = ginger_init_irq,
715 .init_machine = ginger_init,
716 .timer = &omap_timer,
717 MACHINE_END