/* * HTC Herald board configuration * Copyright (C) 2009 Cory Maccarrone * Copyright (C) 2009 Wing Linux * * Based on the board-htcwizard.c file from the linwizard project: * Copyright (C) 2006 Unai Uribarri * Copyright (C) 2008 linwizard.sourceforge.net * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation; either version 2 of the * License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA * 02110-1301, USA. * */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include /* LCD register definition */ #define OMAP_LCDC_CONTROL (0xfffec000 + 0x00) #define OMAP_LCDC_STATUS (0xfffec000 + 0x10) #define OMAP_DMA_LCD_CCR (0xfffee300 + 0xc2) #define OMAP_DMA_LCD_CTRL (0xfffee300 + 0xc4) #define OMAP_LCDC_CTRL_LCD_EN (1 << 0) #define OMAP_LCDC_STAT_DONE (1 << 0) static struct omap_lcd_config htcherald_lcd_config __initdata = { .ctrl_name = "internal", }; static struct omap_board_config_kernel htcherald_config[] __initdata = { { OMAP_TAG_LCD, &htcherald_lcd_config }, }; /* Keyboard definition */ static int htc_herald_keymap[] = { KEY(0, 0, KEY_RECORD), /* Mail button */ KEY(0, 1, KEY_CAMERA), /* Camera */ KEY(0, 2, KEY_PHONE), /* Send key */ KEY(0, 3, KEY_VOLUMEUP), /* Volume up */ KEY(0, 4, KEY_F2), /* Right bar (landscape) */ KEY(0, 5, KEY_MAIL), /* Win key (portrait) */ KEY(0, 6, KEY_DIRECTORY), /* Right bar (protrait) */ KEY(1, 0, KEY_LEFTCTRL), /* Windows key */ KEY(1, 1, KEY_COMMA), KEY(1, 2, KEY_M), KEY(1, 3, KEY_K), KEY(1, 4, KEY_SLASH), /* OK key */ KEY(1, 5, KEY_I), KEY(1, 6, KEY_U), KEY(2, 0, KEY_LEFTALT), KEY(2, 1, KEY_TAB), KEY(2, 2, KEY_N), KEY(2, 3, KEY_J), KEY(2, 4, KEY_ENTER), KEY(2, 5, KEY_H), KEY(2, 6, KEY_Y), KEY(3, 0, KEY_SPACE), KEY(3, 1, KEY_L), KEY(3, 2, KEY_B), KEY(3, 3, KEY_V), KEY(3, 4, KEY_BACKSPACE), KEY(3, 5, KEY_G), KEY(3, 6, KEY_T), KEY(4, 0, KEY_CAPSLOCK), /* Shift */ KEY(4, 1, KEY_C), KEY(4, 2, KEY_F), KEY(4, 3, KEY_R), KEY(4, 4, KEY_O), KEY(4, 5, KEY_E), KEY(4, 6, KEY_D), KEY(5, 0, KEY_X), KEY(5, 1, KEY_Z), KEY(5, 2, KEY_S), KEY(5, 3, KEY_W), KEY(5, 4, KEY_P), KEY(5, 5, KEY_Q), KEY(5, 6, KEY_A), KEY(6, 0, KEY_CONNECT), /* Voice button */ KEY(6, 2, KEY_CANCEL), /* End key */ KEY(6, 3, KEY_VOLUMEDOWN), /* Volume down */ KEY(6, 4, KEY_F1), /* Left bar (landscape) */ KEY(6, 5, KEY_WWW), /* OK button (portrait) */ KEY(6, 6, KEY_CALENDAR), /* Left bar (portrait) */ 0 }; struct omap_kp_platform_data htcherald_kp_data = { .rows = 7, .cols = 7, .delay = 20, .rep = 1, .keymap = htc_herald_keymap, }; static struct resource kp_resources[] = { [0] = { .start = INT_7XX_MPUIO_KEYPAD, .end = INT_7XX_MPUIO_KEYPAD, .flags = IORESOURCE_IRQ, }, }; static struct platform_device kp_device = { .name = "omap-keypad", .id = -1, .dev = { .platform_data = &htcherald_kp_data, }, .num_resources = ARRAY_SIZE(kp_resources), .resource = kp_resources, }; /* USB Device */ static struct omap_usb_config htcherald_usb_config __initdata = { .otg = 0, .register_host = 0, .register_dev = 1, .hmc_mode = 4, .pins[0] = 2, }; /* LCD Device resources */ static struct platform_device lcd_device = { .name = "lcd_htcherald", .id = -1, }; static struct platform_device *devices[] __initdata = { &kp_device, &lcd_device, }; /* * Init functions from here on */ static void __init htcherald_lcd_init(void) { u32 reg; unsigned int tries = 200; /* disable controller if active */ reg = omap_readl(OMAP_LCDC_CONTROL); if (reg & OMAP_LCDC_CTRL_LCD_EN) { reg &= ~OMAP_LCDC_CTRL_LCD_EN; omap_writel(reg, OMAP_LCDC_CONTROL); /* wait for end of frame */ while (!(omap_readl(OMAP_LCDC_STATUS) & OMAP_LCDC_STAT_DONE)) { tries--; if (!tries) break; } if (!tries) printk(KERN_WARNING "Timeout waiting for end of frame " "-- LCD may not be available\n"); /* turn off DMA */ reg = omap_readw(OMAP_DMA_LCD_CCR); reg &= ~(1 << 7); omap_writew(reg, OMAP_DMA_LCD_CCR); reg = omap_readw(OMAP_DMA_LCD_CTRL); reg &= ~(1 << 8); omap_writew(reg, OMAP_DMA_LCD_CTRL); } } static void __init htcherald_map_io(void) { omap1_map_common_io(); /* * The LCD panel must be disabled and DMA turned off here, as doing * it later causes the LCD never to reinitialize. */ htcherald_lcd_init(); printk(KERN_INFO "htcherald_map_io done.\n"); } static void __init htcherald_disable_watchdog(void) { /* Disable watchdog if running */ if (omap_readl(OMAP_WDT_TIMER_MODE) & 0x8000) { /* * disable a potentially running watchdog timer before * it kills us. */ printk(KERN_WARNING "OMAP850 Watchdog seems to be activated, disabling it for now.\n"); omap_writel(0xF5, OMAP_WDT_TIMER_MODE); omap_writel(0xA0, OMAP_WDT_TIMER_MODE); } } #define HTCHERALD_GPIO_USB_EN1 33 #define HTCHERALD_GPIO_USB_EN2 73 #define HTCHERALD_GPIO_USB_DM 35 #define HTCHERALD_GPIO_USB_DP 36 static void __init htcherald_usb_enable(void) { unsigned int tries = 20; unsigned int value = 0; /* Request the GPIOs we need to control here */ if (gpio_request(HTCHERALD_GPIO_USB_EN1, "herald_usb") < 0) goto err1; if (gpio_request(HTCHERALD_GPIO_USB_EN2, "herald_usb") < 0) goto err2; if (gpio_request(HTCHERALD_GPIO_USB_DM, "herald_usb") < 0) goto err3; if (gpio_request(HTCHERALD_GPIO_USB_DP, "herald_usb") < 0) goto err4; /* force USB_EN GPIO to 0 */ do { /* output low */ gpio_direction_output(HTCHERALD_GPIO_USB_EN1, 0); } while ((value = gpio_get_value(HTCHERALD_GPIO_USB_EN1)) == 1 && --tries); if (value == 1) printk(KERN_WARNING "Unable to reset USB, trying to continue\n"); gpio_direction_output(HTCHERALD_GPIO_USB_EN2, 0); /* output low */ gpio_direction_input(HTCHERALD_GPIO_USB_DM); /* input */ gpio_direction_input(HTCHERALD_GPIO_USB_DP); /* input */ goto done; err4: gpio_free(HTCHERALD_GPIO_USB_DM); err3: gpio_free(HTCHERALD_GPIO_USB_EN2); err2: gpio_free(HTCHERALD_GPIO_USB_EN1); err1: printk(KERN_ERR "Unabled to request GPIO for USB\n"); done: printk(KERN_INFO "USB setup complete.\n"); } static void __init htcherald_init(void) { printk(KERN_INFO "HTC Herald init.\n"); omap_gpio_init(); omap_board_config = htcherald_config; omap_board_config_size = ARRAY_SIZE(htcherald_config); platform_add_devices(devices, ARRAY_SIZE(devices)); htcherald_disable_watchdog(); htcherald_usb_enable(); omap_usb_init(&htcherald_usb_config); } static void __init htcherald_init_irq(void) { printk(KERN_INFO "htcherald_init_irq.\n"); omap1_init_common_hw(); omap_init_irq(); } MACHINE_START(HERALD, "HTC Herald") /* Maintainer: Cory Maccarrone */ /* Maintainer: wing-linux.sourceforge.net */ .phys_io = 0xfff00000, .io_pg_offst = ((0xfef00000) >> 18) & 0xfffc, .boot_params = 0x10000100, .map_io = htcherald_map_io, .init_irq = htcherald_init_irq, .init_machine = htcherald_init, .timer = &omap_timer, MACHINE_END