Path: blob/master/arch/arm/mach-omap1/board-htcherald.c
10817 views
/*1* HTC Herald board configuration2* Copyright (C) 2009 Cory Maccarrone <[email protected]>3* Copyright (C) 2009 Wing Linux4*5* Based on the board-htcwizard.c file from the linwizard project:6* Copyright (C) 2006 Unai Uribarri7* Copyright (C) 2008 linwizard.sourceforge.net8*9* This program is free software; you can redistribute it and/or10* modify it under the terms of the GNU General Public License as11* published by the Free Software Foundation; either version 2 of the12* License, or (at your option) any later version.13*14* This program is distributed in the hope that it will be useful, but15* WITHOUT ANY WARRANTY; without even the implied warranty of16* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU17* General Public License for more details.18*19* You should have received a copy of the GNU General Public License20* along with this program; if not, write to the Free Software21* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA22* 02110-1301, USA.23*24*/2526#include <linux/kernel.h>27#include <linux/init.h>28#include <linux/platform_device.h>29#include <linux/input.h>30#include <linux/io.h>31#include <linux/gpio.h>32#include <linux/gpio_keys.h>33#include <linux/i2c.h>34#include <linux/i2c-gpio.h>35#include <linux/htcpld.h>36#include <linux/leds.h>37#include <linux/spi/spi.h>38#include <linux/spi/ads7846.h>3940#include <asm/mach-types.h>41#include <asm/mach/arch.h>4243#include <plat/omap7xx.h>44#include <plat/common.h>45#include <plat/board.h>46#include <plat/keypad.h>47#include <plat/usb.h>48#include <plat/mmc.h>4950#include <mach/irqs.h>5152#include <linux/delay.h>5354/* LCD register definition */55#define OMAP_LCDC_CONTROL (0xfffec000 + 0x00)56#define OMAP_LCDC_STATUS (0xfffec000 + 0x10)57#define OMAP_DMA_LCD_CCR (0xfffee300 + 0xc2)58#define OMAP_DMA_LCD_CTRL (0xfffee300 + 0xc4)59#define OMAP_LCDC_CTRL_LCD_EN (1 << 0)60#define OMAP_LCDC_STAT_DONE (1 << 0)6162/* GPIO definitions for the power button and keyboard slide switch */63#define HTCHERALD_GPIO_POWER 13964#define HTCHERALD_GPIO_SLIDE 17465#define HTCHERALD_GIRQ_BTNS 1416667/* GPIO definitions for the touchscreen */68#define HTCHERALD_GPIO_TS 766970/* HTCPLD definitions */7172/*73* CPLD Logic74*75* Chip 3 - 0x0376*77* Function 7 6 5 4 3 2 1 078* ------------------------------------79* DPAD light x x x x x x x 180* SoundDev x x x x 1 x x x81* Screen white 1 x x x x x x x82* MMC power on x x x x x 1 x x83* Happy times (n) 0 x x x x 1 x x84*85* Chip 4 - 0x0486*87* Function 7 6 5 4 3 2 1 088* ------------------------------------89* Keyboard light x x x x x x x 190* LCD Bright (4) x x x x x 1 1 x91* LCD Bright (3) x x x x x 0 1 x92* LCD Bright (2) x x x x x 1 0 x93* LCD Bright (1) x x x x x 0 0 x94* LCD Off x x x x 0 x x x95* LCD image (fb) 1 x x x x x x x96* LCD image (white) 0 x x x x x x x97* Caps lock LED x x 1 x x x x x98*99* Chip 5 - 0x05100*101* Function 7 6 5 4 3 2 1 0102* ------------------------------------103* Red (solid) x x x x x 1 x x104* Red (flash) x x x x x x 1 x105* Green (GSM flash) x x x x 1 x x x106* Green (GSM solid) x x x 1 x x x x107* Green (wifi flash) x x 1 x x x x x108* Blue (bt flash) x 1 x x x x x x109* DPAD Int Enable 1 x x x x x x 0110*111* (Combinations of the above can be made for different colors.)112* The direction pad interrupt enable must be set each time the113* interrupt is handled.114*115* Chip 6 - 0x06116*117* Function 7 6 5 4 3 2 1 0118* ------------------------------------119* Vibrator x x x x 1 x x x120* Alt LED x x x 1 x x x x121* Screen white 1 x x x x x x x122* Screen white x x 1 x x x x x123* Screen white x 0 x x x x x x124* Enable kbd dpad x x x x x x 0 x125* Happy Times 0 1 0 x x x 0 x126*/127128/*129* HTCPLD GPIO lines start 16 after OMAP_MAX_GPIO_LINES to account130* for the 16 MPUIO lines.131*/132#define HTCPLD_GPIO_START_OFFSET (OMAP_MAX_GPIO_LINES + 16)133#define HTCPLD_IRQ(chip, offset) (OMAP_IRQ_END + 8 * (chip) + (offset))134#define HTCPLD_BASE(chip, offset) \135(HTCPLD_GPIO_START_OFFSET + 8 * (chip) + (offset))136137#define HTCPLD_GPIO_LED_DPAD HTCPLD_BASE(0, 0)138#define HTCPLD_GPIO_LED_KBD HTCPLD_BASE(1, 0)139#define HTCPLD_GPIO_LED_CAPS HTCPLD_BASE(1, 5)140#define HTCPLD_GPIO_LED_RED_FLASH HTCPLD_BASE(2, 1)141#define HTCPLD_GPIO_LED_RED_SOLID HTCPLD_BASE(2, 2)142#define HTCPLD_GPIO_LED_GREEN_FLASH HTCPLD_BASE(2, 3)143#define HTCPLD_GPIO_LED_GREEN_SOLID HTCPLD_BASE(2, 4)144#define HTCPLD_GPIO_LED_WIFI HTCPLD_BASE(2, 5)145#define HTCPLD_GPIO_LED_BT HTCPLD_BASE(2, 6)146#define HTCPLD_GPIO_LED_VIBRATE HTCPLD_BASE(3, 3)147#define HTCPLD_GPIO_LED_ALT HTCPLD_BASE(3, 4)148149#define HTCPLD_GPIO_RIGHT_KBD HTCPLD_BASE(6, 7)150#define HTCPLD_GPIO_UP_KBD HTCPLD_BASE(6, 6)151#define HTCPLD_GPIO_LEFT_KBD HTCPLD_BASE(6, 5)152#define HTCPLD_GPIO_DOWN_KBD HTCPLD_BASE(6, 4)153154#define HTCPLD_GPIO_RIGHT_DPAD HTCPLD_BASE(7, 7)155#define HTCPLD_GPIO_UP_DPAD HTCPLD_BASE(7, 6)156#define HTCPLD_GPIO_LEFT_DPAD HTCPLD_BASE(7, 5)157#define HTCPLD_GPIO_DOWN_DPAD HTCPLD_BASE(7, 4)158#define HTCPLD_GPIO_ENTER_DPAD HTCPLD_BASE(7, 3)159160/*161* The htcpld chip requires a gpio write to a specific line162* to re-enable interrupts after one has occurred.163*/164#define HTCPLD_GPIO_INT_RESET_HI HTCPLD_BASE(2, 7)165#define HTCPLD_GPIO_INT_RESET_LO HTCPLD_BASE(2, 0)166167/* Chip 5 */168#define HTCPLD_IRQ_RIGHT_KBD HTCPLD_IRQ(0, 7)169#define HTCPLD_IRQ_UP_KBD HTCPLD_IRQ(0, 6)170#define HTCPLD_IRQ_LEFT_KBD HTCPLD_IRQ(0, 5)171#define HTCPLD_IRQ_DOWN_KBD HTCPLD_IRQ(0, 4)172173/* Chip 6 */174#define HTCPLD_IRQ_RIGHT_DPAD HTCPLD_IRQ(1, 7)175#define HTCPLD_IRQ_UP_DPAD HTCPLD_IRQ(1, 6)176#define HTCPLD_IRQ_LEFT_DPAD HTCPLD_IRQ(1, 5)177#define HTCPLD_IRQ_DOWN_DPAD HTCPLD_IRQ(1, 4)178#define HTCPLD_IRQ_ENTER_DPAD HTCPLD_IRQ(1, 3)179180/* Keyboard definition */181182static const unsigned int htc_herald_keymap[] = {183KEY(0, 0, KEY_RECORD), /* Mail button */184KEY(1, 0, KEY_CAMERA), /* Camera */185KEY(2, 0, KEY_PHONE), /* Send key */186KEY(3, 0, KEY_VOLUMEUP), /* Volume up */187KEY(4, 0, KEY_F2), /* Right bar (landscape) */188KEY(5, 0, KEY_MAIL), /* Win key (portrait) */189KEY(6, 0, KEY_DIRECTORY), /* Right bar (protrait) */190KEY(0, 1, KEY_LEFTCTRL), /* Windows key */191KEY(1, 1, KEY_COMMA),192KEY(2, 1, KEY_M),193KEY(3, 1, KEY_K),194KEY(4, 1, KEY_SLASH), /* OK key */195KEY(5, 1, KEY_I),196KEY(6, 1, KEY_U),197KEY(0, 2, KEY_LEFTALT),198KEY(1, 2, KEY_TAB),199KEY(2, 2, KEY_N),200KEY(3, 2, KEY_J),201KEY(4, 2, KEY_ENTER),202KEY(5, 2, KEY_H),203KEY(6, 2, KEY_Y),204KEY(0, 3, KEY_SPACE),205KEY(1, 3, KEY_L),206KEY(2, 3, KEY_B),207KEY(3, 3, KEY_V),208KEY(4, 3, KEY_BACKSPACE),209KEY(5, 3, KEY_G),210KEY(6, 3, KEY_T),211KEY(0, 4, KEY_CAPSLOCK), /* Shift */212KEY(1, 4, KEY_C),213KEY(2, 4, KEY_F),214KEY(3, 4, KEY_R),215KEY(4, 4, KEY_O),216KEY(5, 4, KEY_E),217KEY(6, 4, KEY_D),218KEY(0, 5, KEY_X),219KEY(1, 5, KEY_Z),220KEY(2, 5, KEY_S),221KEY(3, 5, KEY_W),222KEY(4, 5, KEY_P),223KEY(5, 5, KEY_Q),224KEY(6, 5, KEY_A),225KEY(0, 6, KEY_CONNECT), /* Voice button */226KEY(2, 6, KEY_CANCEL), /* End key */227KEY(3, 6, KEY_VOLUMEDOWN), /* Volume down */228KEY(4, 6, KEY_F1), /* Left bar (landscape) */229KEY(5, 6, KEY_WWW), /* OK button (portrait) */230KEY(6, 6, KEY_CALENDAR), /* Left bar (portrait) */231};232233static const struct matrix_keymap_data htc_herald_keymap_data = {234.keymap = htc_herald_keymap,235.keymap_size = ARRAY_SIZE(htc_herald_keymap),236};237238static struct omap_kp_platform_data htcherald_kp_data = {239.rows = 7,240.cols = 7,241.delay = 20,242.rep = true,243.keymap_data = &htc_herald_keymap_data,244};245246static struct resource kp_resources[] = {247[0] = {248.start = INT_7XX_MPUIO_KEYPAD,249.end = INT_7XX_MPUIO_KEYPAD,250.flags = IORESOURCE_IRQ,251},252};253254static struct platform_device kp_device = {255.name = "omap-keypad",256.id = -1,257.dev = {258.platform_data = &htcherald_kp_data,259},260.num_resources = ARRAY_SIZE(kp_resources),261.resource = kp_resources,262};263264/* GPIO buttons for keyboard slide and power button */265static struct gpio_keys_button herald_gpio_keys_table[] = {266{BTN_0, HTCHERALD_GPIO_POWER, 1, "POWER", EV_KEY, 1, 20},267{SW_LID, HTCHERALD_GPIO_SLIDE, 0, "SLIDE", EV_SW, 1, 20},268269{KEY_LEFT, HTCPLD_GPIO_LEFT_KBD, 1, "LEFT", EV_KEY, 1, 20},270{KEY_RIGHT, HTCPLD_GPIO_RIGHT_KBD, 1, "RIGHT", EV_KEY, 1, 20},271{KEY_UP, HTCPLD_GPIO_UP_KBD, 1, "UP", EV_KEY, 1, 20},272{KEY_DOWN, HTCPLD_GPIO_DOWN_KBD, 1, "DOWN", EV_KEY, 1, 20},273274{KEY_LEFT, HTCPLD_GPIO_LEFT_DPAD, 1, "DLEFT", EV_KEY, 1, 20},275{KEY_RIGHT, HTCPLD_GPIO_RIGHT_DPAD, 1, "DRIGHT", EV_KEY, 1, 20},276{KEY_UP, HTCPLD_GPIO_UP_DPAD, 1, "DUP", EV_KEY, 1, 20},277{KEY_DOWN, HTCPLD_GPIO_DOWN_DPAD, 1, "DDOWN", EV_KEY, 1, 20},278{KEY_ENTER, HTCPLD_GPIO_ENTER_DPAD, 1, "DENTER", EV_KEY, 1, 20},279};280281static struct gpio_keys_platform_data herald_gpio_keys_data = {282.buttons = herald_gpio_keys_table,283.nbuttons = ARRAY_SIZE(herald_gpio_keys_table),284.rep = true,285};286287static struct platform_device herald_gpiokeys_device = {288.name = "gpio-keys",289.id = -1,290.dev = {291.platform_data = &herald_gpio_keys_data,292},293};294295/* LEDs for the Herald. These connect to the HTCPLD GPIO device. */296static struct gpio_led gpio_leds[] = {297{"dpad", NULL, HTCPLD_GPIO_LED_DPAD, 0, 0, LEDS_GPIO_DEFSTATE_OFF},298{"kbd", NULL, HTCPLD_GPIO_LED_KBD, 0, 0, LEDS_GPIO_DEFSTATE_OFF},299{"vibrate", NULL, HTCPLD_GPIO_LED_VIBRATE, 0, 0, LEDS_GPIO_DEFSTATE_OFF},300{"green_solid", NULL, HTCPLD_GPIO_LED_GREEN_SOLID, 0, 0, LEDS_GPIO_DEFSTATE_OFF},301{"green_flash", NULL, HTCPLD_GPIO_LED_GREEN_FLASH, 0, 0, LEDS_GPIO_DEFSTATE_OFF},302{"red_solid", "mmc0", HTCPLD_GPIO_LED_RED_SOLID, 0, 0, LEDS_GPIO_DEFSTATE_OFF},303{"red_flash", NULL, HTCPLD_GPIO_LED_RED_FLASH, 0, 0, LEDS_GPIO_DEFSTATE_OFF},304{"wifi", NULL, HTCPLD_GPIO_LED_WIFI, 0, 0, LEDS_GPIO_DEFSTATE_OFF},305{"bt", NULL, HTCPLD_GPIO_LED_BT, 0, 0, LEDS_GPIO_DEFSTATE_OFF},306{"caps", NULL, HTCPLD_GPIO_LED_CAPS, 0, 0, LEDS_GPIO_DEFSTATE_OFF},307{"alt", NULL, HTCPLD_GPIO_LED_ALT, 0, 0, LEDS_GPIO_DEFSTATE_OFF},308};309310static struct gpio_led_platform_data gpio_leds_data = {311.leds = gpio_leds,312.num_leds = ARRAY_SIZE(gpio_leds),313};314315static struct platform_device gpio_leds_device = {316.name = "leds-gpio",317.id = 0,318.dev = {319.platform_data = &gpio_leds_data,320},321};322323/* HTC PLD chips */324325static struct resource htcpld_resources[] = {326[0] = {327.start = OMAP_GPIO_IRQ(HTCHERALD_GIRQ_BTNS),328.end = OMAP_GPIO_IRQ(HTCHERALD_GIRQ_BTNS),329.flags = IORESOURCE_IRQ,330},331};332333static struct htcpld_chip_platform_data htcpld_chips[] = {334[0] = {335.addr = 0x03,336.reset = 0x04,337.num_gpios = 8,338.gpio_out_base = HTCPLD_BASE(0, 0),339.gpio_in_base = HTCPLD_BASE(4, 0),340},341[1] = {342.addr = 0x04,343.reset = 0x8e,344.num_gpios = 8,345.gpio_out_base = HTCPLD_BASE(1, 0),346.gpio_in_base = HTCPLD_BASE(5, 0),347},348[2] = {349.addr = 0x05,350.reset = 0x80,351.num_gpios = 8,352.gpio_out_base = HTCPLD_BASE(2, 0),353.gpio_in_base = HTCPLD_BASE(6, 0),354.irq_base = HTCPLD_IRQ(0, 0),355.num_irqs = 8,356},357[3] = {358.addr = 0x06,359.reset = 0x40,360.num_gpios = 8,361.gpio_out_base = HTCPLD_BASE(3, 0),362.gpio_in_base = HTCPLD_BASE(7, 0),363.irq_base = HTCPLD_IRQ(1, 0),364.num_irqs = 8,365},366};367368static struct htcpld_core_platform_data htcpld_pfdata = {369.int_reset_gpio_hi = HTCPLD_GPIO_INT_RESET_HI,370.int_reset_gpio_lo = HTCPLD_GPIO_INT_RESET_LO,371.i2c_adapter_id = 1,372373.chip = htcpld_chips,374.num_chip = ARRAY_SIZE(htcpld_chips),375};376377static struct platform_device htcpld_device = {378.name = "i2c-htcpld",379.id = -1,380.resource = htcpld_resources,381.num_resources = ARRAY_SIZE(htcpld_resources),382.dev = {383.platform_data = &htcpld_pfdata,384},385};386387/* USB Device */388static struct omap_usb_config htcherald_usb_config __initdata = {389.otg = 0,390.register_host = 0,391.register_dev = 1,392.hmc_mode = 4,393.pins[0] = 2,394};395396/* LCD Device resources */397static struct omap_lcd_config htcherald_lcd_config __initdata = {398.ctrl_name = "internal",399};400401static struct omap_board_config_kernel htcherald_config[] __initdata = {402{ OMAP_TAG_LCD, &htcherald_lcd_config },403};404405static struct platform_device lcd_device = {406.name = "lcd_htcherald",407.id = -1,408};409410/* MMC Card */411#if defined(CONFIG_MMC_OMAP) || defined(CONFIG_MMC_OMAP_MODULE)412static struct omap_mmc_platform_data htc_mmc1_data = {413.nr_slots = 1,414.switch_slot = NULL,415.slots[0] = {416.ocr_mask = MMC_VDD_32_33 | MMC_VDD_33_34,417.name = "mmcblk",418.nomux = 1,419.wires = 4,420.switch_pin = -1,421},422};423424static struct omap_mmc_platform_data *htc_mmc_data[1];425#endif426427428/* Platform devices for the Herald */429static struct platform_device *devices[] __initdata = {430&kp_device,431&lcd_device,432&htcpld_device,433&gpio_leds_device,434&herald_gpiokeys_device,435};436437/*438* Touchscreen439*/440static const struct ads7846_platform_data htcherald_ts_platform_data = {441.model = 7846,442.keep_vref_on = 1,443.x_plate_ohms = 496,444.gpio_pendown = HTCHERALD_GPIO_TS,445.pressure_max = 10000,446.pressure_min = 5000,447.x_min = 528,448.x_max = 3760,449.y_min = 624,450.y_max = 3760,451};452453static struct spi_board_info __initdata htcherald_spi_board_info[] = {454{455.modalias = "ads7846",456.platform_data = &htcherald_ts_platform_data,457.irq = OMAP_GPIO_IRQ(HTCHERALD_GPIO_TS),458.max_speed_hz = 2500000,459.bus_num = 2,460.chip_select = 1,461}462};463464/*465* Init functions from here on466*/467468static void __init htcherald_lcd_init(void)469{470u32 reg;471unsigned int tries = 200;472473/* disable controller if active */474reg = omap_readl(OMAP_LCDC_CONTROL);475if (reg & OMAP_LCDC_CTRL_LCD_EN) {476reg &= ~OMAP_LCDC_CTRL_LCD_EN;477omap_writel(reg, OMAP_LCDC_CONTROL);478479/* wait for end of frame */480while (!(omap_readl(OMAP_LCDC_STATUS) & OMAP_LCDC_STAT_DONE)) {481tries--;482if (!tries)483break;484}485if (!tries)486printk(KERN_WARNING "Timeout waiting for end of frame "487"-- LCD may not be available\n");488489/* turn off DMA */490reg = omap_readw(OMAP_DMA_LCD_CCR);491reg &= ~(1 << 7);492omap_writew(reg, OMAP_DMA_LCD_CCR);493494reg = omap_readw(OMAP_DMA_LCD_CTRL);495reg &= ~(1 << 8);496omap_writew(reg, OMAP_DMA_LCD_CTRL);497}498}499500static void __init htcherald_map_io(void)501{502omap1_map_common_io();503504/*505* The LCD panel must be disabled and DMA turned off here, as doing506* it later causes the LCD never to reinitialize.507*/508htcherald_lcd_init();509510printk(KERN_INFO "htcherald_map_io done.\n");511}512513static void __init htcherald_disable_watchdog(void)514{515/* Disable watchdog if running */516if (omap_readl(OMAP_WDT_TIMER_MODE) & 0x8000) {517/*518* disable a potentially running watchdog timer before519* it kills us.520*/521printk(KERN_WARNING "OMAP850 Watchdog seems to be activated, disabling it for now.\n");522omap_writel(0xF5, OMAP_WDT_TIMER_MODE);523omap_writel(0xA0, OMAP_WDT_TIMER_MODE);524}525}526527#define HTCHERALD_GPIO_USB_EN1 33528#define HTCHERALD_GPIO_USB_EN2 73529#define HTCHERALD_GPIO_USB_DM 35530#define HTCHERALD_GPIO_USB_DP 36531532static void __init htcherald_usb_enable(void)533{534unsigned int tries = 20;535unsigned int value = 0;536537/* Request the GPIOs we need to control here */538if (gpio_request(HTCHERALD_GPIO_USB_EN1, "herald_usb") < 0)539goto err1;540541if (gpio_request(HTCHERALD_GPIO_USB_EN2, "herald_usb") < 0)542goto err2;543544if (gpio_request(HTCHERALD_GPIO_USB_DM, "herald_usb") < 0)545goto err3;546547if (gpio_request(HTCHERALD_GPIO_USB_DP, "herald_usb") < 0)548goto err4;549550/* force USB_EN GPIO to 0 */551do {552/* output low */553gpio_direction_output(HTCHERALD_GPIO_USB_EN1, 0);554} while ((value = gpio_get_value(HTCHERALD_GPIO_USB_EN1)) == 1 &&555--tries);556557if (value == 1)558printk(KERN_WARNING "Unable to reset USB, trying to continue\n");559560gpio_direction_output(HTCHERALD_GPIO_USB_EN2, 0); /* output low */561gpio_direction_input(HTCHERALD_GPIO_USB_DM); /* input */562gpio_direction_input(HTCHERALD_GPIO_USB_DP); /* input */563564goto done;565566err4:567gpio_free(HTCHERALD_GPIO_USB_DM);568err3:569gpio_free(HTCHERALD_GPIO_USB_EN2);570err2:571gpio_free(HTCHERALD_GPIO_USB_EN1);572err1:573printk(KERN_ERR "Unabled to request GPIO for USB\n");574done:575printk(KERN_INFO "USB setup complete.\n");576}577578static void __init htcherald_init(void)579{580printk(KERN_INFO "HTC Herald init.\n");581582/* Do board initialization before we register all the devices */583omap_board_config = htcherald_config;584omap_board_config_size = ARRAY_SIZE(htcherald_config);585platform_add_devices(devices, ARRAY_SIZE(devices));586587htcherald_disable_watchdog();588589htcherald_usb_enable();590omap1_usb_init(&htcherald_usb_config);591592spi_register_board_info(htcherald_spi_board_info,593ARRAY_SIZE(htcherald_spi_board_info));594595omap_register_i2c_bus(1, 100, NULL, 0);596597#if defined(CONFIG_MMC_OMAP) || defined(CONFIG_MMC_OMAP_MODULE)598htc_mmc_data[0] = &htc_mmc1_data;599omap1_init_mmc(htc_mmc_data, 1);600#endif601}602603static void __init htcherald_init_irq(void)604{605printk(KERN_INFO "htcherald_init_irq.\n");606omap1_init_common_hw();607omap_init_irq();608}609610MACHINE_START(HERALD, "HTC Herald")611/* Maintainer: Cory Maccarrone <[email protected]> */612/* Maintainer: wing-linux.sourceforge.net */613.boot_params = 0x10000100,614.map_io = htcherald_map_io,615.reserve = omap_reserve,616.init_irq = htcherald_init_irq,617.init_machine = htcherald_init,618.timer = &omap_timer,619MACHINE_END620621622