/* * arch/arm/mach-tegra/board-cardhu.c * * Copyright (c) 2011, NVIDIA Corporation. * * 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 #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "board.h" #include "clock.h" #include "board-cardhu.h" #include "devices.h" #include "gpio-names.h" #include "fuse.h" #include "pm.h" #include "baseband-xmm-power.h" /* !!!TODO: Change for cardhu (Taken from Ventana) */ static struct tegra_utmip_config utmi_phy_config[] = { [0] = { .hssync_start_delay = 0, .idle_wait_delay = 17, .elastic_limit = 16, .term_range_adj = 6, .xcvr_setup = 15, .xcvr_setup_offset = 0, .xcvr_use_fuses = 1, .xcvr_lsfslew = 2, .xcvr_lsrslew = 2, }, [1] = { .hssync_start_delay = 0, .idle_wait_delay = 17, .elastic_limit = 16, .term_range_adj = 6, .xcvr_setup = 15, .xcvr_setup_offset = 0, .xcvr_use_fuses = 1, .xcvr_lsfslew = 2, .xcvr_lsrslew = 2, }, [2] = { .hssync_start_delay = 0, .idle_wait_delay = 17, .elastic_limit = 16, .term_range_adj = 6, .xcvr_setup = 8, .xcvr_setup_offset = 0, .xcvr_use_fuses = 1, .xcvr_lsfslew = 2, .xcvr_lsrslew = 2, }, }; #ifdef CONFIG_BCM4329_RFKILL static struct resource cardhu_bcm4329_rfkill_resources[] = { { .name = "bcm4329_nshutdown_gpio", .start = TEGRA_GPIO_PU0, .end = TEGRA_GPIO_PU0, .flags = IORESOURCE_IO, }, }; static struct platform_device cardhu_bcm4329_rfkill_device = { .name = "bcm4329_rfkill", .id = -1, .num_resources = ARRAY_SIZE(cardhu_bcm4329_rfkill_resources), .resource = cardhu_bcm4329_rfkill_resources, }; static noinline void __init cardhu_bt_rfkill(void) { platform_device_register(&cardhu_bcm4329_rfkill_device); return; } #else static inline void cardhu_bt_rfkill(void) { } #endif #ifdef CONFIG_BT_BLUESLEEP static noinline void __init tegra_setup_bluesleep(void) { struct platform_device *pdev = NULL; struct resource *res; pdev = platform_device_alloc("bluesleep", 0); if (!pdev) { pr_err("unable to allocate platform device for bluesleep"); return; } res = kzalloc(sizeof(struct resource) * 3, GFP_KERNEL); if (!res) { pr_err("unable to allocate resource for bluesleep\n"); goto err_free_dev; } res[0].name = "gpio_host_wake"; res[0].start = TEGRA_GPIO_PU6; res[0].end = TEGRA_GPIO_PU6; res[0].flags = IORESOURCE_IO; res[1].name = "gpio_ext_wake"; res[1].start = TEGRA_GPIO_PU1; res[1].end = TEGRA_GPIO_PU1; res[1].flags = IORESOURCE_IO; res[2].name = "host_wake"; res[2].start = gpio_to_irq(TEGRA_GPIO_PU6); res[2].end = gpio_to_irq(TEGRA_GPIO_PU6); res[2].flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHEDGE ; if (platform_device_add_resources(pdev, res, 3)) { pr_err("unable to add resources to bluesleep device\n"); goto err_free_res; } if (platform_device_add(pdev)) { pr_err("unable to add bluesleep device\n"); goto err_free_res; } tegra_gpio_enable(TEGRA_GPIO_PU6); tegra_gpio_enable(TEGRA_GPIO_PU1); return; err_free_res: kfree(res); err_free_dev: platform_device_put(pdev); return; } #else static inline void tegra_setup_bluesleep(void) { } #endif static __initdata struct tegra_clk_init_table cardhu_clk_init_table[] = { /* name parent rate enabled */ { "pll_m", NULL, 0, false}, { "hda", "pll_p", 108000000, false}, { "hda2codec_2x","pll_p", 48000000, false}, { "pwm", "pll_p", 3187500, false}, { "blink", "clk_32k", 32768, true}, { "i2s1", "pll_a_out0", 0, false}, { "i2s3", "pll_a_out0", 0, false}, { "spdif_out", "pll_a_out0", 0, false}, { "d_audio", "pll_a_out0", 0, false}, { "dam0", "pll_a_out0", 0, false}, { "dam1", "pll_a_out0", 0, false}, { "dam2", "pll_a_out0", 0, false}, { "vi_sensor", "pll_p", 150000000, false}, { "i2c1", "pll_p", 3200000, false}, { "i2c2", "pll_p", 3200000, false}, { "i2c3", "pll_p", 3200000, false}, { "i2c4", "pll_p", 3200000, false}, { "i2c5", "pll_p", 3200000, false}, { NULL, NULL, 0, 0}, }; static struct tegra_i2c_platform_data cardhu_i2c1_platform_data = { .adapter_nr = 0, .bus_count = 1, .bus_clk_rate = { 100000, 0 }, .scl_gpio = {TEGRA_GPIO_PC4, 0}, .sda_gpio = {TEGRA_GPIO_PC5, 0}, .arb_recovery = arb_lost_recovery, }; static struct tegra_i2c_platform_data cardhu_i2c2_platform_data = { .adapter_nr = 1, .bus_count = 1, .bus_clk_rate = { 100000, 0 }, .is_clkon_always = true, .scl_gpio = {TEGRA_GPIO_PT5, 0}, .sda_gpio = {TEGRA_GPIO_PT6, 0}, .arb_recovery = arb_lost_recovery, }; static struct tegra_i2c_platform_data cardhu_i2c3_platform_data = { .adapter_nr = 2, .bus_count = 1, .bus_clk_rate = { 100000, 0 }, .scl_gpio = {TEGRA_GPIO_PBB1, 0}, .sda_gpio = {TEGRA_GPIO_PBB2, 0}, .arb_recovery = arb_lost_recovery, }; static struct tegra_i2c_platform_data cardhu_i2c4_platform_data = { .adapter_nr = 3, .bus_count = 1, .bus_clk_rate = { 100000, 0 }, .scl_gpio = {TEGRA_GPIO_PV4, 0}, .sda_gpio = {TEGRA_GPIO_PV5, 0}, .arb_recovery = arb_lost_recovery, }; static struct tegra_i2c_platform_data cardhu_i2c5_platform_data = { .adapter_nr = 4, .bus_count = 1, .bus_clk_rate = { 400000, 0 }, .scl_gpio = {TEGRA_GPIO_PZ6, 0}, .sda_gpio = {TEGRA_GPIO_PZ7, 0}, .arb_recovery = arb_lost_recovery, }; #if 0 struct tegra_wired_jack_conf audio_wr_jack_conf = { .hp_det_n = TEGRA_GPIO_PW2, .en_mic_ext = TEGRA_GPIO_PX1, .en_mic_int = TEGRA_GPIO_PX0, }; #endif static struct wm8903_platform_data cardhu_wm8903_pdata = { .irq_active_low = 0, .micdet_cfg = 0, .micdet_delay = 100, .gpio_base = CARDHU_GPIO_WM8903(0), .gpio_cfg = { (WM8903_GPn_FN_DMIC_LR_CLK_OUTPUT << WM8903_GP1_FN_SHIFT), (WM8903_GPn_FN_DMIC_LR_CLK_OUTPUT << WM8903_GP2_FN_SHIFT) | WM8903_GP2_DIR, 0, WM8903_GPIO_NO_CONFIG, WM8903_GPIO_NO_CONFIG, }, }; static struct i2c_board_info __initdata wm8903_board_info = { I2C_BOARD_INFO("wm8903", 0x1a), .platform_data = &cardhu_wm8903_pdata, .irq = TEGRA_GPIO_TO_IRQ(TEGRA_GPIO_CDC_IRQ), }; static void cardhu_i2c_init(void) { tegra_i2c_device1.dev.platform_data = &cardhu_i2c1_platform_data; tegra_i2c_device2.dev.platform_data = &cardhu_i2c2_platform_data; tegra_i2c_device3.dev.platform_data = &cardhu_i2c3_platform_data; tegra_i2c_device4.dev.platform_data = &cardhu_i2c4_platform_data; tegra_i2c_device5.dev.platform_data = &cardhu_i2c5_platform_data; platform_device_register(&tegra_i2c_device5); platform_device_register(&tegra_i2c_device4); platform_device_register(&tegra_i2c_device3); platform_device_register(&tegra_i2c_device2); platform_device_register(&tegra_i2c_device1); i2c_register_board_info(4, &wm8903_board_info, 1); } static struct platform_device *cardhu_uart_devices[] __initdata = { &tegra_uarta_device, &tegra_uartb_device, &tegra_uartc_device, &tegra_uartd_device, &tegra_uarte_device, }; static struct uart_clk_parent uart_parent_clk[] = { [0] = {.name = "clk_m"}, [1] = {.name = "pll_p"}, [2] = {.name = "pll_m"}, }; static struct tegra_uart_platform_data cardhu_uart_pdata; static void __init uart_debug_init(void) { struct board_info board_info; int debug_port_id; tegra_get_board_info(&board_info); debug_port_id = get_tegra_uart_debug_port_id(); if (debug_port_id < 0) { debug_port_id = 0; /* UARTB is debug port * for SLT - E1186/E1187/PM269 * for E1256/E1257 */ if (((board_info.sku & SKU_SLT_ULPI_SUPPORT) && ((board_info.board_id == BOARD_E1186) || (board_info.board_id == BOARD_E1187) || (board_info.board_id == BOARD_PM269))) || (board_info.board_id == BOARD_E1256) || (board_info.board_id == BOARD_E1257)) debug_port_id = 1; } switch (debug_port_id) { case 0: /* UARTA is the debug port. */ pr_info("Selecting UARTA as the debug console\n"); cardhu_uart_devices[0] = &debug_uarta_device; debug_uart_clk = clk_get_sys("serial8250.0", "uarta"); debug_uart_port_base = ((struct plat_serial8250_port *)( debug_uarta_device.dev.platform_data))->mapbase; break; case 1: /* UARTB is the debug port. */ pr_info("Selecting UARTB as the debug console\n"); cardhu_uart_devices[1] = &debug_uartb_device; debug_uart_clk = clk_get_sys("serial8250.0", "uartb"); debug_uart_port_base = ((struct plat_serial8250_port *)( debug_uartb_device.dev.platform_data))->mapbase; break; case 2: /* UARTC is the debug port. */ pr_info("Selecting UARTC as the debug console\n"); cardhu_uart_devices[2] = &debug_uartc_device; debug_uart_clk = clk_get_sys("serial8250.0", "uartc"); debug_uart_port_base = ((struct plat_serial8250_port *)( debug_uartc_device.dev.platform_data))->mapbase; break; case 3: /* UARTD is the debug port. */ pr_info("Selecting UARTD as the debug console\n"); cardhu_uart_devices[3] = &debug_uartd_device; debug_uart_clk = clk_get_sys("serial8250.0", "uartd"); debug_uart_port_base = ((struct plat_serial8250_port *)( debug_uartd_device.dev.platform_data))->mapbase; break; case 4: /* UARTE is the debug port. */ pr_info("Selecting UARTE as the debug console\n"); cardhu_uart_devices[4] = &debug_uarte_device; debug_uart_clk = clk_get_sys("serial8250.0", "uarte"); debug_uart_port_base = ((struct plat_serial8250_port *)( debug_uarte_device.dev.platform_data))->mapbase; break; default: pr_info("The debug console id %d is invalid, Assuming UARTA", debug_port_id); cardhu_uart_devices[0] = &debug_uarta_device; debug_uart_clk = clk_get_sys("serial8250.0", "uarta"); debug_uart_port_base = ((struct plat_serial8250_port *)( debug_uarta_device.dev.platform_data))->mapbase; break; } return; } static void __init cardhu_uart_init(void) { struct clk *c; int i; for (i = 0; i < ARRAY_SIZE(uart_parent_clk); ++i) { c = tegra_get_clock_by_name(uart_parent_clk[i].name); if (IS_ERR_OR_NULL(c)) { pr_err("Not able to get the clock for %s\n", uart_parent_clk[i].name); continue; } uart_parent_clk[i].parent_clk = c; uart_parent_clk[i].fixed_clk_rate = clk_get_rate(c); } cardhu_uart_pdata.parent_clk_list = uart_parent_clk; cardhu_uart_pdata.parent_clk_count = ARRAY_SIZE(uart_parent_clk); tegra_uarta_device.dev.platform_data = &cardhu_uart_pdata; tegra_uartb_device.dev.platform_data = &cardhu_uart_pdata; tegra_uartc_device.dev.platform_data = &cardhu_uart_pdata; tegra_uartd_device.dev.platform_data = &cardhu_uart_pdata; tegra_uarte_device.dev.platform_data = &cardhu_uart_pdata; /* Register low speed only if it is selected */ if (!is_tegra_debug_uartport_hs()) { uart_debug_init(); /* Clock enable for the debug channel */ if (!IS_ERR_OR_NULL(debug_uart_clk)) { pr_info("The debug console clock name is %s\n", debug_uart_clk->name); c = tegra_get_clock_by_name("pll_p"); if (IS_ERR_OR_NULL(c)) pr_err("Not getting the parent clock pll_p\n"); else clk_set_parent(debug_uart_clk, c); clk_enable(debug_uart_clk); clk_set_rate(debug_uart_clk, clk_get_rate(c)); } else { pr_err("Not getting the clock %s for debug console\n", debug_uart_clk->name); } } platform_add_devices(cardhu_uart_devices, ARRAY_SIZE(cardhu_uart_devices)); } static struct platform_device tegra_camera = { .name = "tegra_camera", .id = -1, }; static struct platform_device *cardhu_spi_devices[] __initdata = { &tegra_spi_device4, }; struct spi_clk_parent spi_parent_clk[] = { [0] = {.name = "pll_p"}, [1] = {.name = "pll_m"}, [2] = {.name = "clk_m"}, }; static struct tegra_spi_platform_data cardhu_spi_pdata = { .is_dma_based = true, .max_dma_buffer = (16 * 1024), .is_clkon_always = false, .max_rate = 100000000, }; static void __init cardhu_spi_init(void) { int i; struct clk *c; struct board_info board_info; tegra_get_board_info(&board_info); for (i = 0; i < ARRAY_SIZE(spi_parent_clk); ++i) { c = tegra_get_clock_by_name(spi_parent_clk[i].name); if (IS_ERR_OR_NULL(c)) { pr_err("Not able to get the clock for %s\n", spi_parent_clk[i].name); continue; } spi_parent_clk[i].parent_clk = c; spi_parent_clk[i].fixed_clk_rate = clk_get_rate(c); } cardhu_spi_pdata.parent_clk_list = spi_parent_clk; cardhu_spi_pdata.parent_clk_count = ARRAY_SIZE(spi_parent_clk); tegra_spi_device4.dev.platform_data = &cardhu_spi_pdata; platform_add_devices(cardhu_spi_devices, ARRAY_SIZE(cardhu_spi_devices)); if (board_info.board_id == BOARD_E1198) { tegra_spi_device2.dev.platform_data = &cardhu_spi_pdata; platform_device_register(&tegra_spi_device2); } } static struct resource tegra_rtc_resources[] = { [0] = { .start = TEGRA_RTC_BASE, .end = TEGRA_RTC_BASE + TEGRA_RTC_SIZE - 1, .flags = IORESOURCE_MEM, }, [1] = { .start = INT_RTC, .end = INT_RTC, .flags = IORESOURCE_IRQ, }, }; static struct platform_device tegra_rtc_device = { .name = "tegra_rtc", .id = -1, .resource = tegra_rtc_resources, .num_resources = ARRAY_SIZE(tegra_rtc_resources), }; static struct tegra_wm8903_platform_data cardhu_audio_pdata = { .gpio_spkr_en = TEGRA_GPIO_SPKR_EN, .gpio_hp_det = TEGRA_GPIO_HP_DET, .gpio_hp_mute = -1, .gpio_int_mic_en = -1, .gpio_ext_mic_en = -1, }; static struct platform_device cardhu_audio_device = { .name = "tegra-snd-wm8903", .id = 0, .dev = { .platform_data = &cardhu_audio_pdata, }, }; static struct platform_device *cardhu_devices[] __initdata = { &tegra_pmu_device, &tegra_rtc_device, &tegra_udc_device, #if defined(CONFIG_SND_HDA_TEGRA) &tegra_hda_device, #endif #if defined(CONFIG_TEGRA_IOVMM_SMMU) &tegra_smmu_device, #endif &tegra_wdt_device, #if defined(CONFIG_TEGRA_AVP) &tegra_avp_device, #endif &tegra_camera, #if defined(CONFIG_CRYPTO_DEV_TEGRA_SE) &tegra_se_device, #endif &tegra_ahub_device, &tegra_dam_device0, &tegra_dam_device1, &tegra_dam_device2, &tegra_i2s_device1, &tegra_i2s_device3, &tegra_spdif_device, &spdif_dit_device, &bluetooth_dit_device, &tegra_pcm_device, &cardhu_audio_device, #if defined(CONFIG_CRYPTO_DEV_TEGRA_AES) &tegra_aes_device, #endif }; #define MXT_CONFIG_CRC 0xD62DE8 static const u8 config[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x32, 0x0A, 0x00, 0x14, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x8B, 0x00, 0x00, 0x1B, 0x2A, 0x00, 0x20, 0x3C, 0x04, 0x05, 0x00, 0x02, 0x01, 0x00, 0x0A, 0x0A, 0x0A, 0x0A, 0xFF, 0x02, 0x55, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x64, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, 0x05, 0x0A, 0x15, 0x1E, 0x00, 0x00, 0x04, 0xFF, 0x03, 0x3F, 0x64, 0x64, 0x01, 0x0A, 0x14, 0x28, 0x4B, 0x00, 0x02, 0x00, 0x64, 0x00, 0x19, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x10, 0x3C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; #define MXT_CONFIG_CRC_SKU2000 0xA24D9A static const u8 config_sku2000[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x32, 0x0A, 0x00, 0x14, 0x14, 0x19, 0x00, 0x00, 0x00, 0x00, 0x00, 0x8B, 0x00, 0x00, 0x1B, 0x2A, 0x00, 0x20, 0x3A, 0x04, 0x05, 0x00, //23=thr 2 di 0x04, 0x04, 0x41, 0x0A, 0x0A, 0x0A, 0x0A, 0xFF, 0x02, 0x55, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x00, //0A=limit 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, 0x05, 0x0A, 0x15, 0x1E, 0x00, 0x00, 0x04, 0x00, 0x03, 0x3F, 0x64, 0x64, 0x01, 0x0A, 0x14, 0x28, 0x4B, 0x00, 0x02, 0x00, 0x64, 0x00, 0x19, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x10, 0x3C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; static struct mxt_platform_data atmel_mxt_info = { .x_line = 27, .y_line = 42, .x_size = 768, .y_size = 1366, .blen = 0x20, .threshold = 0x3C, .voltage = 3300000, /* 3.3V */ .orient = 5, .config = config, .config_length = 157, .config_crc = MXT_CONFIG_CRC, .irqflags = IRQF_TRIGGER_FALLING, /* .read_chg = &read_chg, */ .read_chg = NULL, }; static struct i2c_board_info __initdata atmel_i2c_info[] = { { I2C_BOARD_INFO("atmel_mxt_ts", 0x5A), .irq = TEGRA_GPIO_TO_IRQ(TEGRA_GPIO_PH4), .platform_data = &atmel_mxt_info, } }; static int __init cardhu_touch_init(void) { struct board_info BoardInfo; tegra_gpio_enable(TEGRA_GPIO_PH4); tegra_gpio_enable(TEGRA_GPIO_PH6); gpio_request(TEGRA_GPIO_PH4, "atmel-irq"); gpio_direction_input(TEGRA_GPIO_PH4); gpio_request(TEGRA_GPIO_PH6, "atmel-reset"); gpio_direction_output(TEGRA_GPIO_PH6, 0); msleep(1); gpio_set_value(TEGRA_GPIO_PH6, 1); msleep(100); tegra_get_board_info(&BoardInfo); if ((BoardInfo.sku & SKU_TOUCH_MASK) == SKU_TOUCH_2000) { atmel_mxt_info.config = config_sku2000; atmel_mxt_info.config_crc = MXT_CONFIG_CRC_SKU2000; } i2c_register_board_info(1, atmel_i2c_info, 1); return 0; } static struct tegra_uhsic_config uhsic_phy_config = { .enable_gpio = EN_HSIC_GPIO, .reset_gpio = -1, .sync_start_delay = 9, .idle_wait_delay = 17, .term_range_adj = 0, .elastic_underrun_limit = 16, .elastic_overrun_limit = 16, }; static struct tegra_ehci_platform_data tegra_ehci_uhsic_pdata = { .phy_type = TEGRA_USB_PHY_TYPE_HSIC, .phy_config = &uhsic_phy_config, .operating_mode = TEGRA_USB_HOST, .power_down_on_bus_suspend = 1, }; static struct tegra_ehci_platform_data tegra_ehci_pdata[] = { [0] = { .phy_config = &utmi_phy_config[0], .operating_mode = TEGRA_USB_HOST, .power_down_on_bus_suspend = 1, }, [1] = { .phy_config = &utmi_phy_config[1], .operating_mode = TEGRA_USB_HOST, .power_down_on_bus_suspend = 1, }, [2] = { .phy_config = &utmi_phy_config[2], .operating_mode = TEGRA_USB_HOST, .power_down_on_bus_suspend = 1, .hotplug = 1, }, }; static struct tegra_otg_platform_data tegra_otg_pdata = { .ehci_device = &tegra_ehci1_device, .ehci_pdata = &tegra_ehci_pdata[0], }; #ifdef CONFIG_USB_SUPPORT static struct usb_phy_plat_data tegra_usb_phy_pdata[] = { [0] = { .instance = 0, .vbus_gpio = -1, .vbus_reg_supply = "vdd_vbus_micro_usb", }, [1] = { .instance = 1, .vbus_gpio = -1, }, [2] = { .instance = 2, .vbus_gpio = -1, .vbus_reg_supply = "vdd_vbus_typea_usb", }, }; static void cardhu_usb_init(void) { struct board_info bi; tegra_get_board_info(&bi); tegra_usb_phy_init(tegra_usb_phy_pdata, ARRAY_SIZE(tegra_usb_phy_pdata)); tegra_otg_device.dev.platform_data = &tegra_otg_pdata; platform_device_register(&tegra_otg_device); if (bi.board_id == BOARD_PM267) { uhsic_phy_config.reset_gpio = PM267_SMSC4640_HSIC_HUB_RESET_GPIO; tegra_ehci2_device.dev.platform_data = &tegra_ehci_uhsic_pdata; platform_device_register(&tegra_ehci2_device); } else if (bi.board_id == BOARD_E1256) { tegra_ehci2_device.dev.platform_data = &tegra_ehci_uhsic_pdata; platform_device_register(&tegra_ehci2_device); } else if (bi.board_id == BOARD_E1186) { tegra_ehci2_device.dev.platform_data = &tegra_ehci_uhsic_pdata; /* baseband registration happens in baseband-xmm-power */ } else { tegra_ehci2_device.dev.platform_data = &tegra_ehci_pdata[1]; platform_device_register(&tegra_ehci2_device); } tegra_ehci3_device.dev.platform_data = &tegra_ehci_pdata[2]; platform_device_register(&tegra_ehci3_device); } #else static void cardhu_usb_init(void) { } #endif static void cardhu_gps_init(void) { tegra_gpio_enable(TEGRA_GPIO_PU2); tegra_gpio_enable(TEGRA_GPIO_PU3); } static struct baseband_power_platform_data tegra_baseband_power_data = { .baseband_type = BASEBAND_XMM, .modem = { .xmm = { .bb_rst = XMM_GPIO_BB_RST, .bb_on = XMM_GPIO_BB_ON, .ipc_bb_wake = XMM_GPIO_IPC_BB_WAKE, .ipc_ap_wake = XMM_GPIO_IPC_AP_WAKE, .ipc_hsic_active = XMM_GPIO_IPC_HSIC_ACTIVE, .ipc_hsic_sus_req = XMM_GPIO_IPC_HSIC_SUS_REQ, .hsic_device = &tegra_ehci2_device, }, }, }; static struct platform_device tegra_baseband_power_device = { .name = "baseband_xmm_power", .id = -1, .dev = { .platform_data = &tegra_baseband_power_data, }, }; static struct platform_device tegra_baseband_power2_device = { .name = "baseband_xmm_power2", .id = -1, .dev = { .platform_data = &tegra_baseband_power_data, }, }; static void cardhu_modem_init(void) { struct board_info board_info; int w_disable_gpio, ret; tegra_get_board_info(&board_info); switch (board_info.board_id) { case BOARD_E1291: case BOARD_E1198: if (((board_info.board_id == BOARD_E1291) && (board_info.fab < BOARD_FAB_A03)) || ((board_info.board_id == BOARD_E1198) && (board_info.fab < BOARD_FAB_A02))) { w_disable_gpio = TEGRA_GPIO_PH5; } else { w_disable_gpio = TEGRA_GPIO_PDD5; } tegra_gpio_enable(w_disable_gpio); ret = gpio_request(w_disable_gpio, "w_disable_gpio"); if (ret < 0) pr_err("%s: gpio_request failed for gpio %d\n", __func__, w_disable_gpio); else gpio_direction_input(w_disable_gpio); /* E1291-A04 & E1198:A02: Set PERST signal to high */ if (((board_info.board_id == BOARD_E1291) && (board_info.fab >= BOARD_FAB_A04)) || ((board_info.board_id == BOARD_E1198) && (board_info.fab >= BOARD_FAB_A02))) { ret = gpio_request(TEGRA_GPIO_PH7, "modem_perst"); if (ret < 0) { pr_err("%s(): Error in allocating gpio " "TEGRA_GPIO_PH7\n", __func__); break; } gpio_direction_output(TEGRA_GPIO_PH7, 1); tegra_gpio_enable(TEGRA_GPIO_PH7); } break; case BOARD_E1186: tegra_gpio_enable( tegra_baseband_power_data.modem.xmm.bb_rst); tegra_gpio_enable( tegra_baseband_power_data.modem.xmm.bb_on); tegra_gpio_enable( tegra_baseband_power_data.modem.xmm.ipc_bb_wake); tegra_gpio_enable( tegra_baseband_power_data.modem.xmm.ipc_ap_wake); tegra_gpio_enable( tegra_baseband_power_data.modem.xmm.ipc_hsic_active); tegra_gpio_enable( tegra_baseband_power_data.modem.xmm.ipc_hsic_sus_req); platform_device_register(&tegra_baseband_power_device); platform_device_register(&tegra_baseband_power2_device); break; default: break; } } #ifdef CONFIG_SATA_AHCI_TEGRA static void cardhu_sata_init(void) { platform_device_register(&tegra_sata_device); } #else static void cardhu_sata_init(void) { } #endif static void __init tegra_cardhu_init(void) { tegra_clk_init_from_table(cardhu_clk_init_table); cardhu_pinmux_init(); cardhu_i2c_init(); cardhu_spi_init(); cardhu_usb_init(); #ifdef CONFIG_TEGRA_EDP_LIMITS cardhu_edp_init(); #endif cardhu_uart_init(); cardhu_tsensor_init(); platform_add_devices(cardhu_devices, ARRAY_SIZE(cardhu_devices)); cardhu_sdhci_init(); cardhu_regulator_init(); cardhu_gpio_switch_regulator_init(); cardhu_suspend_init(); cardhu_power_off_init(); cardhu_touch_init(); cardhu_gps_init(); cardhu_modem_init(); cardhu_kbc_init(); cardhu_scroll_init(); cardhu_keys_init(); cardhu_panel_init(); cardhu_pmon_init(); cardhu_sensors_init(); cardhu_bt_rfkill(); tegra_setup_bluesleep(); cardhu_sata_init(); //audio_wired_jack_init(); cardhu_pins_state_init(); cardhu_emc_init(); tegra_release_bootloader_fb(); } static void __init tegra_cardhu_reserve(void) { #if defined(CONFIG_NVMAP_CONVERT_CARVEOUT_TO_IOVMM) /* support 1920X1200 with 24bpp */ tegra_reserve(0, SZ_8M + SZ_1M, SZ_8M + SZ_1M); #else tegra_reserve(SZ_128M, SZ_8M, SZ_8M); #endif } MACHINE_START(CARDHU, "cardhu") .boot_params = 0x80000100, .map_io = tegra_map_common_io, .reserve = tegra_cardhu_reserve, .init_early = tegra_init_early, .init_irq = tegra_init_irq, .timer = &tegra_timer, .init_machine = tegra_cardhu_init, MACHINE_END