Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-or-later
0002 /*
0003  * HTC Herald board configuration
0004  * Copyright (C) 2009 Cory Maccarrone <darkstar6262@gmail.com>
0005  * Copyright (C) 2009 Wing Linux
0006  *
0007  * Based on the board-htcwizard.c file from the linwizard project:
0008  * Copyright (C) 2006 Unai Uribarri
0009  * Copyright (C) 2008 linwizard.sourceforge.net
0010  */
0011 #include <linux/kernel.h>
0012 #include <linux/init.h>
0013 #include <linux/platform_device.h>
0014 #include <linux/input.h>
0015 #include <linux/delay.h>
0016 #include <linux/gpio.h>
0017 #include <linux/gpio_keys.h>
0018 #include <linux/i2c.h>
0019 #include <linux/platform_data/i2c-gpio.h>
0020 #include <linux/htcpld.h>
0021 #include <linux/leds.h>
0022 #include <linux/spi/spi.h>
0023 #include <linux/spi/ads7846.h>
0024 #include <linux/omapfb.h>
0025 #include <linux/platform_data/keypad-omap.h>
0026 #include <linux/soc/ti/omap1-io.h>
0027 
0028 #include <asm/mach-types.h>
0029 #include <asm/mach/arch.h>
0030 
0031 #include "hardware.h"
0032 #include "omap7xx.h"
0033 #include "mmc.h"
0034 #include "irqs.h"
0035 #include "usb.h"
0036 #include "common.h"
0037 
0038 /* LCD register definition */
0039 #define       OMAP_LCDC_CONTROL               (0xfffec000 + 0x00)
0040 #define       OMAP_LCDC_STATUS                (0xfffec000 + 0x10)
0041 #define       OMAP_DMA_LCD_CCR                (0xfffee300 + 0xc2)
0042 #define       OMAP_DMA_LCD_CTRL               (0xfffee300 + 0xc4)
0043 #define       OMAP_LCDC_CTRL_LCD_EN           (1 << 0)
0044 #define       OMAP_LCDC_STAT_DONE             (1 << 0)
0045 
0046 /* GPIO definitions for the power button and keyboard slide switch */
0047 #define HTCHERALD_GPIO_POWER 139
0048 #define HTCHERALD_GPIO_SLIDE 174
0049 #define HTCHERALD_GIRQ_BTNS 141
0050 
0051 /* GPIO definitions for the touchscreen */
0052 #define HTCHERALD_GPIO_TS 76
0053 
0054 /* HTCPLD definitions */
0055 
0056 /*
0057  * CPLD Logic
0058  *
0059  * Chip 3 - 0x03
0060  *
0061  * Function            7 6 5 4  3 2 1 0
0062  * ------------------------------------
0063  * DPAD light          x x x x  x x x 1
0064  * SoundDev            x x x x  1 x x x
0065  * Screen white        1 x x x  x x x x
0066  * MMC power on        x x x x  x 1 x x
0067  * Happy times (n)     0 x x x  x 1 x x
0068  *
0069  * Chip 4 - 0x04
0070  *
0071  * Function            7 6 5 4  3 2 1 0
0072  * ------------------------------------
0073  * Keyboard light      x x x x  x x x 1
0074  * LCD Bright (4)      x x x x  x 1 1 x
0075  * LCD Bright (3)      x x x x  x 0 1 x
0076  * LCD Bright (2)      x x x x  x 1 0 x
0077  * LCD Bright (1)      x x x x  x 0 0 x
0078  * LCD Off             x x x x  0 x x x
0079  * LCD image (fb)      1 x x x  x x x x
0080  * LCD image (white)   0 x x x  x x x x
0081  * Caps lock LED       x x 1 x  x x x x
0082  *
0083  * Chip 5 - 0x05
0084  *
0085  * Function            7 6 5 4  3 2 1 0
0086  * ------------------------------------
0087  * Red (solid)         x x x x  x 1 x x
0088  * Red (flash)         x x x x  x x 1 x
0089  * Green (GSM flash)   x x x x  1 x x x
0090  * Green (GSM solid)   x x x 1  x x x x
0091  * Green (wifi flash)  x x 1 x  x x x x
0092  * Blue (bt flash)     x 1 x x  x x x x
0093  * DPAD Int Enable     1 x x x  x x x 0
0094  *
0095  * (Combinations of the above can be made for different colors.)
0096  * The direction pad interrupt enable must be set each time the
0097  * interrupt is handled.
0098  *
0099  * Chip 6 - 0x06
0100  *
0101  * Function            7 6 5 4  3 2 1 0
0102  * ------------------------------------
0103  * Vibrator            x x x x  1 x x x
0104  * Alt LED             x x x 1  x x x x
0105  * Screen white        1 x x x  x x x x
0106  * Screen white        x x 1 x  x x x x
0107  * Screen white        x 0 x x  x x x x
0108  * Enable kbd dpad     x x x x  x x 0 x
0109  * Happy Times         0 1 0 x  x x 0 x
0110  */
0111 
0112 /*
0113  * HTCPLD GPIO lines start 16 after OMAP_MAX_GPIO_LINES to account
0114  * for the 16 MPUIO lines.
0115  */
0116 #define HTCPLD_GPIO_START_OFFSET    (OMAP_MAX_GPIO_LINES + 16)
0117 #define HTCPLD_IRQ(chip, offset)    (OMAP_IRQ_END + 8 * (chip) + (offset))
0118 #define HTCPLD_BASE(chip, offset)   \
0119     (HTCPLD_GPIO_START_OFFSET + 8 * (chip) + (offset))
0120 
0121 #define HTCPLD_GPIO_LED_DPAD        HTCPLD_BASE(0, 0)
0122 #define HTCPLD_GPIO_LED_KBD     HTCPLD_BASE(1, 0)
0123 #define HTCPLD_GPIO_LED_CAPS        HTCPLD_BASE(1, 5)
0124 #define HTCPLD_GPIO_LED_RED_FLASH   HTCPLD_BASE(2, 1)
0125 #define HTCPLD_GPIO_LED_RED_SOLID   HTCPLD_BASE(2, 2)
0126 #define HTCPLD_GPIO_LED_GREEN_FLASH HTCPLD_BASE(2, 3)
0127 #define HTCPLD_GPIO_LED_GREEN_SOLID HTCPLD_BASE(2, 4)
0128 #define HTCPLD_GPIO_LED_WIFI        HTCPLD_BASE(2, 5)
0129 #define HTCPLD_GPIO_LED_BT      HTCPLD_BASE(2, 6)
0130 #define HTCPLD_GPIO_LED_VIBRATE     HTCPLD_BASE(3, 3)
0131 #define HTCPLD_GPIO_LED_ALT     HTCPLD_BASE(3, 4)
0132 
0133 #define HTCPLD_GPIO_RIGHT_KBD       HTCPLD_BASE(6, 7)
0134 #define HTCPLD_GPIO_UP_KBD      HTCPLD_BASE(6, 6)
0135 #define HTCPLD_GPIO_LEFT_KBD        HTCPLD_BASE(6, 5)
0136 #define HTCPLD_GPIO_DOWN_KBD        HTCPLD_BASE(6, 4)
0137 
0138 #define HTCPLD_GPIO_RIGHT_DPAD      HTCPLD_BASE(7, 7)
0139 #define HTCPLD_GPIO_UP_DPAD     HTCPLD_BASE(7, 6)
0140 #define HTCPLD_GPIO_LEFT_DPAD       HTCPLD_BASE(7, 5)
0141 #define HTCPLD_GPIO_DOWN_DPAD       HTCPLD_BASE(7, 4)
0142 #define HTCPLD_GPIO_ENTER_DPAD      HTCPLD_BASE(7, 3)
0143 
0144 /*
0145  * The htcpld chip requires a gpio write to a specific line
0146  * to re-enable interrupts after one has occurred.
0147  */
0148 #define HTCPLD_GPIO_INT_RESET_HI    HTCPLD_BASE(2, 7)
0149 #define HTCPLD_GPIO_INT_RESET_LO    HTCPLD_BASE(2, 0)
0150 
0151 /* Chip 5 */
0152 #define HTCPLD_IRQ_RIGHT_KBD        HTCPLD_IRQ(0, 7)
0153 #define HTCPLD_IRQ_UP_KBD       HTCPLD_IRQ(0, 6)
0154 #define HTCPLD_IRQ_LEFT_KBD     HTCPLD_IRQ(0, 5)
0155 #define HTCPLD_IRQ_DOWN_KBD     HTCPLD_IRQ(0, 4)
0156 
0157 /* Chip 6 */
0158 #define HTCPLD_IRQ_RIGHT_DPAD       HTCPLD_IRQ(1, 7)
0159 #define HTCPLD_IRQ_UP_DPAD      HTCPLD_IRQ(1, 6)
0160 #define HTCPLD_IRQ_LEFT_DPAD        HTCPLD_IRQ(1, 5)
0161 #define HTCPLD_IRQ_DOWN_DPAD        HTCPLD_IRQ(1, 4)
0162 #define HTCPLD_IRQ_ENTER_DPAD       HTCPLD_IRQ(1, 3)
0163 
0164 /* Keyboard definition */
0165 
0166 static const unsigned int htc_herald_keymap[] = {
0167     KEY(0, 0, KEY_RECORD), /* Mail button */
0168     KEY(1, 0, KEY_CAMERA), /* Camera */
0169     KEY(2, 0, KEY_PHONE), /* Send key */
0170     KEY(3, 0, KEY_VOLUMEUP), /* Volume up */
0171     KEY(4, 0, KEY_F2),  /* Right bar (landscape) */
0172     KEY(5, 0, KEY_MAIL), /* Win key (portrait) */
0173     KEY(6, 0, KEY_DIRECTORY), /* Right bar (portrait) */
0174     KEY(0, 1, KEY_LEFTCTRL), /* Windows key */
0175     KEY(1, 1, KEY_COMMA),
0176     KEY(2, 1, KEY_M),
0177     KEY(3, 1, KEY_K),
0178     KEY(4, 1, KEY_SLASH), /* OK key */
0179     KEY(5, 1, KEY_I),
0180     KEY(6, 1, KEY_U),
0181     KEY(0, 2, KEY_LEFTALT),
0182     KEY(1, 2, KEY_TAB),
0183     KEY(2, 2, KEY_N),
0184     KEY(3, 2, KEY_J),
0185     KEY(4, 2, KEY_ENTER),
0186     KEY(5, 2, KEY_H),
0187     KEY(6, 2, KEY_Y),
0188     KEY(0, 3, KEY_SPACE),
0189     KEY(1, 3, KEY_L),
0190     KEY(2, 3, KEY_B),
0191     KEY(3, 3, KEY_V),
0192     KEY(4, 3, KEY_BACKSPACE),
0193     KEY(5, 3, KEY_G),
0194     KEY(6, 3, KEY_T),
0195     KEY(0, 4, KEY_CAPSLOCK), /* Shift */
0196     KEY(1, 4, KEY_C),
0197     KEY(2, 4, KEY_F),
0198     KEY(3, 4, KEY_R),
0199     KEY(4, 4, KEY_O),
0200     KEY(5, 4, KEY_E),
0201     KEY(6, 4, KEY_D),
0202     KEY(0, 5, KEY_X),
0203     KEY(1, 5, KEY_Z),
0204     KEY(2, 5, KEY_S),
0205     KEY(3, 5, KEY_W),
0206     KEY(4, 5, KEY_P),
0207     KEY(5, 5, KEY_Q),
0208     KEY(6, 5, KEY_A),
0209     KEY(0, 6, KEY_CONNECT), /* Voice button */
0210     KEY(2, 6, KEY_CANCEL), /* End key */
0211     KEY(3, 6, KEY_VOLUMEDOWN), /* Volume down */
0212     KEY(4, 6, KEY_F1), /* Left bar (landscape) */
0213     KEY(5, 6, KEY_WWW), /* OK button (portrait) */
0214     KEY(6, 6, KEY_CALENDAR), /* Left bar (portrait) */
0215 };
0216 
0217 static const struct matrix_keymap_data htc_herald_keymap_data = {
0218     .keymap     = htc_herald_keymap,
0219     .keymap_size    = ARRAY_SIZE(htc_herald_keymap),
0220 };
0221 
0222 static struct omap_kp_platform_data htcherald_kp_data = {
0223     .rows   = 7,
0224     .cols   = 7,
0225     .delay = 20,
0226     .rep = true,
0227     .keymap_data = &htc_herald_keymap_data,
0228 };
0229 
0230 static struct resource kp_resources[] = {
0231     [0] = {
0232         .start  = INT_7XX_MPUIO_KEYPAD,
0233         .end    = INT_7XX_MPUIO_KEYPAD,
0234         .flags  = IORESOURCE_IRQ,
0235     },
0236 };
0237 
0238 static struct platform_device kp_device = {
0239     .name       = "omap-keypad",
0240     .id     = -1,
0241     .dev        = {
0242         .platform_data = &htcherald_kp_data,
0243     },
0244     .num_resources  = ARRAY_SIZE(kp_resources),
0245     .resource   = kp_resources,
0246 };
0247 
0248 /* GPIO buttons for keyboard slide and power button */
0249 static struct gpio_keys_button herald_gpio_keys_table[] = {
0250     {BTN_0,  HTCHERALD_GPIO_POWER, 1, "POWER", EV_KEY, 1, 20},
0251     {SW_LID, HTCHERALD_GPIO_SLIDE, 0, "SLIDE", EV_SW,  1, 20},
0252 
0253     {KEY_LEFT,  HTCPLD_GPIO_LEFT_KBD,  1, "LEFT",  EV_KEY, 1, 20},
0254     {KEY_RIGHT, HTCPLD_GPIO_RIGHT_KBD, 1, "RIGHT", EV_KEY, 1, 20},
0255     {KEY_UP,    HTCPLD_GPIO_UP_KBD,    1, "UP",    EV_KEY, 1, 20},
0256     {KEY_DOWN,  HTCPLD_GPIO_DOWN_KBD,  1, "DOWN",  EV_KEY, 1, 20},
0257 
0258     {KEY_LEFT,  HTCPLD_GPIO_LEFT_DPAD,   1, "DLEFT",  EV_KEY, 1, 20},
0259     {KEY_RIGHT, HTCPLD_GPIO_RIGHT_DPAD,  1, "DRIGHT", EV_KEY, 1, 20},
0260     {KEY_UP,    HTCPLD_GPIO_UP_DPAD,     1, "DUP",    EV_KEY, 1, 20},
0261     {KEY_DOWN,  HTCPLD_GPIO_DOWN_DPAD,   1, "DDOWN",  EV_KEY, 1, 20},
0262     {KEY_ENTER, HTCPLD_GPIO_ENTER_DPAD,  1, "DENTER", EV_KEY, 1, 20},
0263 };
0264 
0265 static struct gpio_keys_platform_data herald_gpio_keys_data = {
0266     .buttons    = herald_gpio_keys_table,
0267     .nbuttons   = ARRAY_SIZE(herald_gpio_keys_table),
0268     .rep        = true,
0269 };
0270 
0271 static struct platform_device herald_gpiokeys_device = {
0272     .name      = "gpio-keys",
0273     .id     = -1,
0274     .dev = {
0275         .platform_data = &herald_gpio_keys_data,
0276     },
0277 };
0278 
0279 /* LEDs for the Herald.  These connect to the HTCPLD GPIO device. */
0280 static const struct gpio_led gpio_leds[] = {
0281     {"dpad",        NULL, HTCPLD_GPIO_LED_DPAD,        0, 0, LEDS_GPIO_DEFSTATE_OFF},
0282     {"kbd",         NULL, HTCPLD_GPIO_LED_KBD,         0, 0, LEDS_GPIO_DEFSTATE_OFF},
0283     {"vibrate",     NULL, HTCPLD_GPIO_LED_VIBRATE,     0, 0, LEDS_GPIO_DEFSTATE_OFF},
0284     {"green_solid", NULL, HTCPLD_GPIO_LED_GREEN_SOLID, 0, 0, LEDS_GPIO_DEFSTATE_OFF},
0285     {"green_flash", NULL, HTCPLD_GPIO_LED_GREEN_FLASH, 0, 0, LEDS_GPIO_DEFSTATE_OFF},
0286     {"red_solid",   "mmc0", HTCPLD_GPIO_LED_RED_SOLID, 0, 0, LEDS_GPIO_DEFSTATE_OFF},
0287     {"red_flash",   NULL, HTCPLD_GPIO_LED_RED_FLASH,   0, 0, LEDS_GPIO_DEFSTATE_OFF},
0288     {"wifi",        NULL, HTCPLD_GPIO_LED_WIFI,        0, 0, LEDS_GPIO_DEFSTATE_OFF},
0289     {"bt",          NULL, HTCPLD_GPIO_LED_BT,          0, 0, LEDS_GPIO_DEFSTATE_OFF},
0290     {"caps",        NULL, HTCPLD_GPIO_LED_CAPS,        0, 0, LEDS_GPIO_DEFSTATE_OFF},
0291     {"alt",         NULL, HTCPLD_GPIO_LED_ALT,         0, 0, LEDS_GPIO_DEFSTATE_OFF},
0292 };
0293 
0294 static struct gpio_led_platform_data gpio_leds_data = {
0295     .leds       = gpio_leds,
0296     .num_leds   = ARRAY_SIZE(gpio_leds),
0297 };
0298 
0299 static struct platform_device gpio_leds_device = {
0300     .name       = "leds-gpio",
0301     .id     = 0,
0302     .dev    = {
0303         .platform_data  = &gpio_leds_data,
0304     },
0305 };
0306 
0307 /* HTC PLD chips */
0308 
0309 static struct resource htcpld_resources[] = {
0310     [0] = {
0311         .flags  = IORESOURCE_IRQ,
0312     },
0313 };
0314 
0315 static struct htcpld_chip_platform_data htcpld_chips[] = {
0316     [0] = {
0317         .addr       = 0x03,
0318         .reset      = 0x04,
0319         .num_gpios  = 8,
0320         .gpio_out_base  = HTCPLD_BASE(0, 0),
0321         .gpio_in_base   = HTCPLD_BASE(4, 0),
0322     },
0323     [1] = {
0324         .addr       = 0x04,
0325         .reset      = 0x8e,
0326         .num_gpios  = 8,
0327         .gpio_out_base  = HTCPLD_BASE(1, 0),
0328         .gpio_in_base   = HTCPLD_BASE(5, 0),
0329     },
0330     [2] = {
0331         .addr       = 0x05,
0332         .reset      = 0x80,
0333         .num_gpios  = 8,
0334         .gpio_out_base  = HTCPLD_BASE(2, 0),
0335         .gpio_in_base   = HTCPLD_BASE(6, 0),
0336         .irq_base   = HTCPLD_IRQ(0, 0),
0337         .num_irqs   = 8,
0338     },
0339     [3] = {
0340         .addr       = 0x06,
0341         .reset      = 0x40,
0342         .num_gpios  = 8,
0343         .gpio_out_base  = HTCPLD_BASE(3, 0),
0344         .gpio_in_base   = HTCPLD_BASE(7, 0),
0345         .irq_base   = HTCPLD_IRQ(1, 0),
0346         .num_irqs   = 8,
0347     },
0348 };
0349 
0350 static struct htcpld_core_platform_data htcpld_pfdata = {
0351     .int_reset_gpio_hi = HTCPLD_GPIO_INT_RESET_HI,
0352     .int_reset_gpio_lo = HTCPLD_GPIO_INT_RESET_LO,
0353     .i2c_adapter_id    = 1,
0354 
0355     .chip          = htcpld_chips,
0356     .num_chip      = ARRAY_SIZE(htcpld_chips),
0357 };
0358 
0359 static struct platform_device htcpld_device = {
0360     .name       = "i2c-htcpld",
0361     .id     = -1,
0362     .resource   = htcpld_resources,
0363     .num_resources  = ARRAY_SIZE(htcpld_resources),
0364     .dev    = {
0365         .platform_data  = &htcpld_pfdata,
0366     },
0367 };
0368 
0369 /* USB Device */
0370 static struct omap_usb_config htcherald_usb_config __initdata = {
0371     .otg = 0,
0372     .register_host = 0,
0373     .register_dev  = 1,
0374     .hmc_mode = 4,
0375     .pins[0] = 2,
0376 };
0377 
0378 /* LCD Device resources */
0379 static const struct omap_lcd_config htcherald_lcd_config __initconst = {
0380     .ctrl_name  = "internal",
0381 };
0382 
0383 static struct platform_device lcd_device = {
0384     .name           = "lcd_htcherald",
0385     .id             = -1,
0386 };
0387 
0388 /* MMC Card */
0389 #if IS_ENABLED(CONFIG_MMC_OMAP)
0390 static struct omap_mmc_platform_data htc_mmc1_data = {
0391     .nr_slots                       = 1,
0392     .switch_slot                    = NULL,
0393     .slots[0]       = {
0394         .ocr_mask               = MMC_VDD_32_33 | MMC_VDD_33_34,
0395         .name                   = "mmcblk",
0396         .nomux                  = 1,
0397         .wires                  = 4,
0398         .switch_pin             = -1,
0399     },
0400 };
0401 
0402 static struct omap_mmc_platform_data *htc_mmc_data[1];
0403 #endif
0404 
0405 
0406 /* Platform devices for the Herald */
0407 static struct platform_device *devices[] __initdata = {
0408     &kp_device,
0409     &lcd_device,
0410     &htcpld_device,
0411     &gpio_leds_device,
0412     &herald_gpiokeys_device,
0413 };
0414 
0415 /*
0416  * Touchscreen
0417  */
0418 static const struct ads7846_platform_data htcherald_ts_platform_data = {
0419     .model          = 7846,
0420     .keep_vref_on       = 1,
0421     .x_plate_ohms       = 496,
0422     .gpio_pendown       = HTCHERALD_GPIO_TS,
0423     .pressure_max       = 10000,
0424     .pressure_min       = 5000,
0425     .x_min          = 528,
0426     .x_max          = 3760,
0427     .y_min          = 624,
0428     .y_max          = 3760,
0429 };
0430 
0431 static struct spi_board_info __initdata htcherald_spi_board_info[] = {
0432     {
0433         .modalias       = "ads7846",
0434         .platform_data      = &htcherald_ts_platform_data,
0435         .max_speed_hz       = 2500000,
0436         .bus_num        = 2,
0437         .chip_select        = 1,
0438     }
0439 };
0440 
0441 /*
0442  * Init functions from here on
0443  */
0444 
0445 static void __init htcherald_lcd_init(void)
0446 {
0447     u32 reg;
0448     unsigned int tries = 200;
0449 
0450     /* disable controller if active */
0451     reg = omap_readl(OMAP_LCDC_CONTROL);
0452     if (reg & OMAP_LCDC_CTRL_LCD_EN) {
0453         reg &= ~OMAP_LCDC_CTRL_LCD_EN;
0454         omap_writel(reg, OMAP_LCDC_CONTROL);
0455 
0456         /* wait for end of frame */
0457         while (!(omap_readl(OMAP_LCDC_STATUS) & OMAP_LCDC_STAT_DONE)) {
0458             tries--;
0459             if (!tries)
0460                 break;
0461         }
0462         if (!tries)
0463             pr_err("Timeout waiting for end of frame -- LCD may not be available\n");
0464 
0465         /* turn off DMA */
0466         reg = omap_readw(OMAP_DMA_LCD_CCR);
0467         reg &= ~(1 << 7);
0468         omap_writew(reg, OMAP_DMA_LCD_CCR);
0469 
0470         reg = omap_readw(OMAP_DMA_LCD_CTRL);
0471         reg &= ~(1 << 8);
0472         omap_writew(reg, OMAP_DMA_LCD_CTRL);
0473     }
0474 }
0475 
0476 static void __init htcherald_map_io(void)
0477 {
0478     omap7xx_map_io();
0479 
0480     /*
0481      * The LCD panel must be disabled and DMA turned off here, as doing
0482      * it later causes the LCD never to reinitialize.
0483      */
0484     htcherald_lcd_init();
0485 
0486     printk(KERN_INFO "htcherald_map_io done.\n");
0487 }
0488 
0489 static void __init htcherald_disable_watchdog(void)
0490 {
0491     /* Disable watchdog if running */
0492     if (omap_readl(OMAP_WDT_TIMER_MODE) & 0x8000) {
0493         /*
0494          * disable a potentially running watchdog timer before
0495          * it kills us.
0496          */
0497         printk(KERN_WARNING "OMAP850 Watchdog seems to be activated, disabling it for now.\n");
0498         omap_writel(0xF5, OMAP_WDT_TIMER_MODE);
0499         omap_writel(0xA0, OMAP_WDT_TIMER_MODE);
0500     }
0501 }
0502 
0503 #define HTCHERALD_GPIO_USB_EN1 33
0504 #define HTCHERALD_GPIO_USB_EN2 73
0505 #define HTCHERALD_GPIO_USB_DM  35
0506 #define HTCHERALD_GPIO_USB_DP  36
0507 
0508 static void __init htcherald_usb_enable(void)
0509 {
0510     unsigned int tries = 20;
0511     unsigned int value = 0;
0512 
0513     /* Request the GPIOs we need to control here */
0514     if (gpio_request(HTCHERALD_GPIO_USB_EN1, "herald_usb") < 0)
0515         goto err1;
0516 
0517     if (gpio_request(HTCHERALD_GPIO_USB_EN2, "herald_usb") < 0)
0518         goto err2;
0519 
0520     if (gpio_request(HTCHERALD_GPIO_USB_DM, "herald_usb") < 0)
0521         goto err3;
0522 
0523     if (gpio_request(HTCHERALD_GPIO_USB_DP, "herald_usb") < 0)
0524         goto err4;
0525 
0526     /* force USB_EN GPIO to 0 */
0527     do {
0528         /* output low */
0529         gpio_direction_output(HTCHERALD_GPIO_USB_EN1, 0);
0530     } while ((value = gpio_get_value(HTCHERALD_GPIO_USB_EN1)) == 1 &&
0531             --tries);
0532 
0533     if (value == 1)
0534         printk(KERN_WARNING "Unable to reset USB, trying to continue\n");
0535 
0536     gpio_direction_output(HTCHERALD_GPIO_USB_EN2, 0); /* output low */
0537     gpio_direction_input(HTCHERALD_GPIO_USB_DM); /* input */
0538     gpio_direction_input(HTCHERALD_GPIO_USB_DP); /* input */
0539 
0540     goto done;
0541 
0542 err4:
0543     gpio_free(HTCHERALD_GPIO_USB_DM);
0544 err3:
0545     gpio_free(HTCHERALD_GPIO_USB_EN2);
0546 err2:
0547     gpio_free(HTCHERALD_GPIO_USB_EN1);
0548 err1:
0549     printk(KERN_ERR "Unabled to request GPIO for USB\n");
0550 done:
0551     printk(KERN_INFO "USB setup complete.\n");
0552 }
0553 
0554 static void __init htcherald_init(void)
0555 {
0556     printk(KERN_INFO "HTC Herald init.\n");
0557 
0558     /* Do board initialization before we register all the devices */
0559     htcpld_resources[0].start = gpio_to_irq(HTCHERALD_GIRQ_BTNS);
0560     htcpld_resources[0].end = gpio_to_irq(HTCHERALD_GIRQ_BTNS);
0561     platform_add_devices(devices, ARRAY_SIZE(devices));
0562 
0563     htcherald_disable_watchdog();
0564 
0565     htcherald_usb_enable();
0566     omap1_usb_init(&htcherald_usb_config);
0567 
0568     htcherald_spi_board_info[0].irq = gpio_to_irq(HTCHERALD_GPIO_TS);
0569     spi_register_board_info(htcherald_spi_board_info,
0570         ARRAY_SIZE(htcherald_spi_board_info));
0571 
0572     omap_register_i2c_bus(1, 100, NULL, 0);
0573 
0574 #if IS_ENABLED(CONFIG_MMC_OMAP)
0575     htc_mmc_data[0] = &htc_mmc1_data;
0576     omap1_init_mmc(htc_mmc_data, 1);
0577 #endif
0578 
0579     omapfb_set_lcd_config(&htcherald_lcd_config);
0580 }
0581 
0582 MACHINE_START(HERALD, "HTC Herald")
0583     /* Maintainer: Cory Maccarrone <darkstar6262@gmail.com> */
0584     /* Maintainer: wing-linux.sourceforge.net */
0585     .atag_offset    = 0x100,
0586     .map_io         = htcherald_map_io,
0587     .init_early     = omap1_init_early,
0588     .init_irq       = omap1_init_irq,
0589     .handle_irq = omap1_handle_irq,
0590     .init_machine   = htcherald_init,
0591     .init_late  = omap1_init_late,
0592     .init_time  = omap1_timer_init,
0593     .restart    = omap1_restart,
0594 MACHINE_END