/* Copyright (c) 2009-2013, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and * only version 2 as published by the Free Software Foundation. * * 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. * */ #include #include #include #include #include #include #include #include #ifdef CONFIG_SPI_QSD #include #endif #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 #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "devices.h" #include "timer.h" #ifdef CONFIG_USB_G_ANDROID #include #include #endif #include "pm.h" #include "pm-boot.h" #include "spm.h" #include "acpuclock.h" #include "clock.h" #include #include #include #include #include #include "smd_private.h" #include #include "board-msm7x30-regulator.h" #include "pm.h" #define MSM_PMEM_SF_SIZE 0x1700000 #ifdef CONFIG_FB_MSM_TRIPLE_BUFFER #define MSM_FB_PRIM_BUF_SIZE (864 * 480 * 4 * 3) /* 4bpp * 3 Pages */ #else #define MSM_FB_PRIM_BUF_SIZE (864 * 480 * 4 * 2) /* 4bpp * 2 Pages */ #endif /* * Reserve space for double buffered full screen * res V4L2 video overlay - i.e. 1280x720x1.5x2 */ #define MSM_V4L2_VIDEO_OVERLAY_BUF_SIZE 2764800 #ifdef CONFIG_FB_MSM_HDMI_ADV7520_PANEL #define MSM_FB_EXT_BUF_SIZE (1280 * 720 * 2 * 1) /* 2 bpp x 1 page */ #else #define MSM_FB_EXT_BUF_SIZE 0 #endif #ifdef CONFIG_FB_MSM_OVERLAY0_WRITEBACK /* width x height x 3 bpp x 2 frame buffer */ #define MSM_FB_OVERLAY0_WRITEBACK_SIZE roundup((864 * 480 * 3 * 2), 4096) #else #define MSM_FB_OVERLAY0_WRITEBACK_SIZE 0 #endif #define MSM_FB_SIZE roundup(MSM_FB_PRIM_BUF_SIZE + MSM_FB_EXT_BUF_SIZE, 4096) #define MSM_PMEM_ADSP_SIZE 0x1E00000 #define MSM_FLUID_PMEM_ADSP_SIZE 0x2800000 #define PMEM_KERNEL_EBI0_SIZE 0x600000 #define MSM_PMEM_AUDIO_SIZE 0x200000 #ifdef CONFIG_ION_MSM static struct platform_device ion_dev; #define MSM_ION_AUDIO_SIZE (MSM_PMEM_AUDIO_SIZE + PMEM_KERNEL_EBI0_SIZE) #define MSM_ION_SF_SIZE MSM_PMEM_SF_SIZE #define MSM_ION_HEAP_NUM 4 #endif #define PMIC_GPIO_INT 27 #define PMIC_VREG_WLAN_LEVEL 2900 #define PMIC_GPIO_SD_DET 36 #define PMIC_GPIO_SDC4_EN_N 17 /* PMIC GPIO Number 18 */ #define PMIC_GPIO_HDMI_5V_EN_V3 32 /* PMIC GPIO for V3 H/W */ #define PMIC_GPIO_HDMI_5V_EN_V2 39 /* PMIC GPIO for V2 H/W */ #define ADV7520_I2C_ADDR 0x39 #define FPGA_SDCC_STATUS 0x8E0001A8 #define FPGA_OPTNAV_GPIO_ADDR 0x8E000026 #define OPTNAV_I2C_SLAVE_ADDR (0xB0 >> 1) #define OPTNAV_IRQ 20 #define OPTNAV_CHIP_SELECT 19 #define PMIC_GPIO_SDC4_PWR_EN_N 24 /* PMIC GPIO Number 25 */ /* Macros assume PMIC GPIOs start at 0 */ #define PM8058_GPIO_PM_TO_SYS(pm_gpio) (pm_gpio + NR_GPIO_IRQS) #define PM8058_GPIO_SYS_TO_PM(sys_gpio) (sys_gpio - NR_GPIO_IRQS) #define PM8058_MPP_BASE PM8058_GPIO_PM_TO_SYS(PM8058_GPIOS) #define PM8058_MPP_PM_TO_SYS(pm_gpio) (pm_gpio + PM8058_MPP_BASE) #define PMIC_GPIO_FLASH_BOOST_ENABLE 15 /* PMIC GPIO Number 16 */ #define PMIC_GPIO_HAP_ENABLE 16 /* PMIC GPIO Number 17 */ #define PMIC_GPIO_WLAN_EXT_POR 22 /* PMIC GPIO NUMBER 23 */ #define BMA150_GPIO_INT 1 #define HAP_LVL_SHFT_MSM_GPIO 24 #define PMIC_GPIO_QUICKVX_CLK 37 /* PMIC GPIO 38 */ #define PM_FLIP_MPP 5 /* PMIC MPP 06 */ #define DDR1_BANK_BASE 0X20000000 #define DDR2_BANK_BASE 0X40000000 static unsigned int phys_add = DDR2_BANK_BASE; unsigned long ebi1_phys_offset = DDR2_BANK_BASE; EXPORT_SYMBOL(ebi1_phys_offset); struct pm8xxx_gpio_init_info { unsigned gpio; struct pm_gpio config; }; static int pm8058_gpios_init(void) { int rc; struct pm8xxx_gpio_init_info sdc4_en = { PM8058_GPIO_PM_TO_SYS(PMIC_GPIO_SDC4_EN_N), { .direction = PM_GPIO_DIR_OUT, .pull = PM_GPIO_PULL_NO, .vin_sel = PM8058_GPIO_VIN_L5, .function = PM_GPIO_FUNC_NORMAL, .inv_int_pol = 0, .out_strength = PM_GPIO_STRENGTH_LOW, .output_value = 0, }, }; struct pm8xxx_gpio_init_info sdc4_pwr_en = { PM8058_GPIO_PM_TO_SYS(PMIC_GPIO_SDC4_PWR_EN_N), { .direction = PM_GPIO_DIR_OUT, .pull = PM_GPIO_PULL_NO, .vin_sel = PM8058_GPIO_VIN_L5, .function = PM_GPIO_FUNC_NORMAL, .inv_int_pol = 0, .out_strength = PM_GPIO_STRENGTH_LOW, .output_value = 0, }, }; struct pm8xxx_gpio_init_info haptics_enable = { PM8058_GPIO_PM_TO_SYS(PMIC_GPIO_HAP_ENABLE), { .direction = PM_GPIO_DIR_OUT, .pull = PM_GPIO_PULL_NO, .out_strength = PM_GPIO_STRENGTH_HIGH, .function = PM_GPIO_FUNC_NORMAL, .inv_int_pol = 0, .vin_sel = 2, .output_buffer = PM_GPIO_OUT_BUF_CMOS, .output_value = 0, }, }; struct pm8xxx_gpio_init_info hdmi_5V_en = { PM8058_GPIO_PM_TO_SYS(PMIC_GPIO_HDMI_5V_EN_V3), { .direction = PM_GPIO_DIR_OUT, .pull = PM_GPIO_PULL_NO, .vin_sel = PM8058_GPIO_VIN_VPH, .function = PM_GPIO_FUNC_NORMAL, .out_strength = PM_GPIO_STRENGTH_LOW, .output_value = 0, }, }; struct pm8xxx_gpio_init_info flash_boost_enable = { PM8058_GPIO_PM_TO_SYS(PMIC_GPIO_FLASH_BOOST_ENABLE), { .direction = PM_GPIO_DIR_OUT, .output_buffer = PM_GPIO_OUT_BUF_CMOS, .output_value = 0, .pull = PM_GPIO_PULL_NO, .vin_sel = PM8058_GPIO_VIN_S3, .out_strength = PM_GPIO_STRENGTH_HIGH, .function = PM_GPIO_FUNC_2, }, }; struct pm8xxx_gpio_init_info gpio23 = { PM8058_GPIO_PM_TO_SYS(PMIC_GPIO_WLAN_EXT_POR), { .direction = PM_GPIO_DIR_OUT, .output_buffer = PM_GPIO_OUT_BUF_CMOS, .output_value = 0, .pull = PM_GPIO_PULL_NO, .vin_sel = 2, .out_strength = PM_GPIO_STRENGTH_LOW, .function = PM_GPIO_FUNC_NORMAL, } }; struct pm8xxx_gpio_init_info sdcc_det = { PM8058_GPIO_PM_TO_SYS(PMIC_GPIO_SD_DET - 1), { .direction = PM_GPIO_DIR_IN, .pull = PM_GPIO_PULL_UP_1P5, .vin_sel = 2, .function = PM_GPIO_FUNC_NORMAL, .inv_int_pol = 0, }, }; if (machine_is_msm7x30_fluid()) sdcc_det.config.inv_int_pol = 1; rc = pm8xxx_gpio_config(sdcc_det.gpio, &sdcc_det.config); if (rc) { pr_err("%s PMIC_GPIO_SD_DET config failed\n", __func__); return rc; } if (machine_is_msm8x55_svlte_surf() || machine_is_msm8x55_svlte_ffa() || machine_is_msm7x30_fluid()) hdmi_5V_en.gpio = PMIC_GPIO_HDMI_5V_EN_V2; else hdmi_5V_en.gpio = PMIC_GPIO_HDMI_5V_EN_V3; hdmi_5V_en.gpio = PM8058_GPIO_PM_TO_SYS(hdmi_5V_en.gpio); rc = pm8xxx_gpio_config(hdmi_5V_en.gpio, &hdmi_5V_en.config); if (rc) { pr_err("%s PMIC_GPIO_HDMI_5V_EN config failed\n", __func__); return rc; } /* Deassert GPIO#23 (source for Ext_POR on WLAN-Volans) */ rc = pm8xxx_gpio_config(gpio23.gpio, &gpio23.config); if (rc) { pr_err("%s PMIC_GPIO_WLAN_EXT_POR config failed\n", __func__); return rc; } if (machine_is_msm7x30_fluid()) { /* Haptics gpio */ rc = pm8xxx_gpio_config(haptics_enable.gpio, &haptics_enable.config); if (rc) { pr_err("%s: PMIC GPIO %d write failed\n", __func__, haptics_enable.gpio); return rc; } /* Flash boost gpio */ rc = pm8xxx_gpio_config(flash_boost_enable.gpio, &flash_boost_enable.config); if (rc) { pr_err("%s: PMIC GPIO %d write failed\n", __func__, flash_boost_enable.gpio); return rc; } /* SCD4 gpio */ rc = pm8xxx_gpio_config(sdc4_en.gpio, &sdc4_en.config); if (rc) { pr_err("%s PMIC_GPIO_SDC4_EN_N config failed\n", __func__); return rc; } rc = gpio_request(sdc4_en.gpio, "sdc4_en"); if (rc) { pr_err("%s PMIC_GPIO_SDC4_EN_N gpio_request failed\n", __func__); return rc; } gpio_set_value_cansleep(sdc4_en.gpio, 0); } /* FFA -> gpio_25 controls vdd of sdcc4 */ else { /* SCD4 gpio_25 */ rc = pm8xxx_gpio_config(sdc4_pwr_en.gpio, &sdc4_pwr_en.config); if (rc) { pr_err("%s PMIC_GPIO_SDC4_PWR_EN_N config failed: %d\n", __func__, rc); return rc; } rc = gpio_request(sdc4_pwr_en.gpio, "sdc4_pwr_en"); if (rc) { pr_err("PMIC_GPIO_SDC4_PWR_EN_N gpio_req failed: %d\n", rc); return rc; } } return 0; } /* Regulator API support */ #ifdef CONFIG_MSM_PROC_COMM_REGULATOR static struct platform_device msm_proccomm_regulator_dev = { .name = PROCCOMM_REGULATOR_DEV_NAME, .id = -1, .dev = { .platform_data = &msm7x30_proccomm_regulator_data } }; #endif /*virtual key support */ static ssize_t tma300_vkeys_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf) { return sprintf(buf, __stringify(EV_KEY) ":" __stringify(KEY_BACK) ":50:842:80:100" ":" __stringify(EV_KEY) ":" __stringify(KEY_MENU) ":170:842:80:100" ":" __stringify(EV_KEY) ":" __stringify(KEY_HOME) ":290:842:80:100" ":" __stringify(EV_KEY) ":" __stringify(KEY_SEARCH) ":410:842:80:100" "\n"); } static struct kobj_attribute tma300_vkeys_attr = { .attr = { .mode = S_IRUGO, }, .show = &tma300_vkeys_show, }; static struct attribute *tma300_properties_attrs[] = { &tma300_vkeys_attr.attr, NULL }; static struct attribute_group tma300_properties_attr_group = { .attrs = tma300_properties_attrs, }; static struct kobject *properties_kobj; static struct regulator_bulk_data cyttsp_regs[] = { { .supply = "ldo8", .min_uV = 1800000, .max_uV = 1800000 }, { .supply = "ldo15", .min_uV = 3050000, .max_uV = 3100000 }, }; #define CYTTSP_TS_GPIO_IRQ 150 static int cyttsp_platform_init(struct i2c_client *client) { int rc = -EINVAL; rc = regulator_bulk_get(NULL, ARRAY_SIZE(cyttsp_regs), cyttsp_regs); if (rc) { pr_err("%s: could not get regulators: %d\n", __func__, rc); goto out; } rc = regulator_bulk_set_voltage(ARRAY_SIZE(cyttsp_regs), cyttsp_regs); if (rc) { pr_err("%s: could not set regulator voltages: %d\n", __func__, rc); goto regs_free; } rc = regulator_bulk_enable(ARRAY_SIZE(cyttsp_regs), cyttsp_regs); if (rc) { pr_err("%s: could not enable regulators: %d\n", __func__, rc); goto regs_free; } /* check this device active by reading first byte/register */ rc = i2c_smbus_read_byte_data(client, 0x01); if (rc < 0) { pr_err("%s: i2c sanity check failed\n", __func__); goto regs_disable; } rc = gpio_tlmm_config(GPIO_CFG(CYTTSP_TS_GPIO_IRQ, 0, GPIO_CFG_INPUT, GPIO_CFG_PULL_UP, GPIO_CFG_6MA), GPIO_CFG_ENABLE); if (rc) { pr_err("%s: Could not configure gpio %d\n", __func__, CYTTSP_TS_GPIO_IRQ); goto regs_disable; } /* virtual keys */ tma300_vkeys_attr.attr.name = "virtualkeys.cyttsp-i2c"; properties_kobj = kobject_create_and_add("board_properties", NULL); if (properties_kobj) rc = sysfs_create_group(properties_kobj, &tma300_properties_attr_group); if (!properties_kobj || rc) pr_err("%s: failed to create board_properties\n", __func__); return CY_OK; regs_disable: regulator_bulk_disable(ARRAY_SIZE(cyttsp_regs), cyttsp_regs); regs_free: regulator_bulk_free(ARRAY_SIZE(cyttsp_regs), cyttsp_regs); out: return rc; } /* TODO: Put the regulator to LPM / HPM in suspend/resume*/ static int cyttsp_platform_suspend(struct i2c_client *client) { msleep(20); return CY_OK; } static int cyttsp_platform_resume(struct i2c_client *client) { /* add any special code to strobe a wakeup pin or chip reset */ mdelay(10); return CY_OK; } static struct cyttsp_platform_data cyttsp_data = { .fw_fname = "cyttsp_7630_fluid.hex", .panel_maxx = 479, .panel_maxy = 799, .disp_maxx = 469, .disp_maxy = 799, .disp_minx = 10, .disp_miny = 0, .flags = 0, .gen = CY_GEN3, /* or */ .use_st = CY_USE_ST, .use_mt = CY_USE_MT, .use_hndshk = CY_SEND_HNDSHK, .use_trk_id = CY_USE_TRACKING_ID, .use_sleep = CY_USE_DEEP_SLEEP_SEL | CY_USE_LOW_POWER_SEL, .use_gestures = CY_USE_GESTURES, /* activate up to 4 groups * and set active distance */ .gest_set = CY_GEST_GRP1 | CY_GEST_GRP2 | CY_GEST_GRP3 | CY_GEST_GRP4 | CY_ACT_DIST, /* change act_intrvl to customize the Active power state * scanning/processing refresh interval for Operating mode */ .act_intrvl = CY_ACT_INTRVL_DFLT, /* change tch_tmout to customize the touch timeout for the * Active power state for Operating mode */ .tch_tmout = CY_TCH_TMOUT_DFLT, /* change lp_intrvl to customize the Low Power power state * scanning/processing refresh interval for Operating mode */ .lp_intrvl = CY_LP_INTRVL_DFLT, .resume = cyttsp_platform_resume, .suspend = cyttsp_platform_suspend, .init = cyttsp_platform_init, .sleep_gpio = -1, .resout_gpio = -1, .irq_gpio = CYTTSP_TS_GPIO_IRQ, .correct_fw_ver = 2, }; static int pm8058_pwm_config(struct pwm_device *pwm, int ch, int on) { struct pm_gpio pwm_gpio_config = { .direction = PM_GPIO_DIR_OUT, .output_buffer = PM_GPIO_OUT_BUF_CMOS, .output_value = 0, .pull = PM_GPIO_PULL_NO, .vin_sel = PM8058_GPIO_VIN_S3, .out_strength = PM_GPIO_STRENGTH_HIGH, .function = PM_GPIO_FUNC_2, }; int rc = -EINVAL; int id, mode, max_mA; id = mode = max_mA = 0; switch (ch) { case 0: case 1: case 2: if (on) { id = 24 + ch; rc = pm8xxx_gpio_config(PM8058_GPIO_PM_TO_SYS(id - 1), &pwm_gpio_config); if (rc) pr_err("%s: pm8xxx_gpio_config(%d): rc=%d\n", __func__, id, rc); } break; case 3: id = PM_PWM_LED_KPD; mode = PM_PWM_CONF_DTEST3; max_mA = 200; break; case 4: id = PM_PWM_LED_0; mode = PM_PWM_CONF_PWM1; max_mA = 40; break; case 5: id = PM_PWM_LED_2; mode = PM_PWM_CONF_PWM2; max_mA = 40; break; case 6: id = PM_PWM_LED_FLASH; mode = PM_PWM_CONF_DTEST3; max_mA = 200; break; default: break; } if (ch >= 3 && ch <= 6) { if (!on) { mode = PM_PWM_CONF_NONE; max_mA = 0; } rc = pm8058_pwm_config_led(pwm, id, mode, max_mA); if (rc) pr_err("%s: pm8058_pwm_config_led(ch=%d): rc=%d\n", __func__, ch, rc); } return rc; } static int pm8058_pwm_enable(struct pwm_device *pwm, int ch, int on) { int rc; switch (ch) { case 7: rc = pm8058_pwm_set_dtest(pwm, on); if (rc) pr_err("%s: pwm_set_dtest(%d): rc=%d\n", __func__, on, rc); break; default: rc = -EINVAL; break; } return rc; } static const unsigned int fluid_keymap[] = { KEY(0, 0, KEY_7), KEY(0, 1, KEY_ENTER), KEY(0, 2, KEY_UP), /* drop (0,3) as it always shows up in pair with(0,2) */ KEY(0, 4, KEY_DOWN), KEY(1, 0, KEY_CAMERA_SNAPSHOT), KEY(1, 1, KEY_SELECT), KEY(1, 2, KEY_1), KEY(1, 3, KEY_VOLUMEUP), KEY(1, 4, KEY_VOLUMEDOWN), }; static const unsigned int surf_keymap[] = { KEY(0, 0, KEY_7), KEY(0, 1, KEY_DOWN), KEY(0, 2, KEY_UP), KEY(0, 3, KEY_RIGHT), KEY(0, 4, KEY_ENTER), KEY(0, 5, KEY_L), KEY(0, 6, KEY_BACK), KEY(0, 7, KEY_M), KEY(1, 0, KEY_LEFT), KEY(1, 1, KEY_SEND), KEY(1, 2, KEY_1), KEY(1, 3, KEY_4), KEY(1, 4, KEY_CLEAR), KEY(1, 5, KEY_MSDOS), KEY(1, 6, KEY_SPACE), KEY(1, 7, KEY_COMMA), KEY(2, 0, KEY_6), KEY(2, 1, KEY_5), KEY(2, 2, KEY_8), KEY(2, 3, KEY_3), KEY(2, 4, KEY_NUMERIC_STAR), KEY(2, 5, KEY_UP), KEY(2, 6, KEY_DOWN), /* SYN */ KEY(2, 7, KEY_LEFTSHIFT), KEY(3, 0, KEY_9), KEY(3, 1, KEY_NUMERIC_POUND), KEY(3, 2, KEY_0), KEY(3, 3, KEY_2), KEY(3, 4, KEY_SLEEP), KEY(3, 5, KEY_F1), KEY(3, 6, KEY_F2), KEY(3, 7, KEY_F3), KEY(4, 0, KEY_BACK), KEY(4, 1, KEY_HOME), KEY(4, 2, KEY_MENU), KEY(4, 3, KEY_VOLUMEUP), KEY(4, 4, KEY_VOLUMEDOWN), KEY(4, 5, KEY_F4), KEY(4, 6, KEY_F5), KEY(4, 7, KEY_F6), KEY(5, 0, KEY_R), KEY(5, 1, KEY_T), KEY(5, 2, KEY_Y), KEY(5, 3, KEY_LEFTALT), KEY(5, 4, KEY_KPENTER), KEY(5, 5, KEY_Q), KEY(5, 6, KEY_W), KEY(5, 7, KEY_E), KEY(6, 0, KEY_F), KEY(6, 1, KEY_G), KEY(6, 2, KEY_H), KEY(6, 3, KEY_CAPSLOCK), KEY(6, 4, KEY_PAGEUP), KEY(6, 5, KEY_A), KEY(6, 6, KEY_S), KEY(6, 7, KEY_D), KEY(7, 0, KEY_V), KEY(7, 1, KEY_B), KEY(7, 2, KEY_N), KEY(7, 3, KEY_MENU), /* REVISIT - SYM */ KEY(7, 4, KEY_PAGEDOWN), KEY(7, 5, KEY_Z), KEY(7, 6, KEY_X), KEY(7, 7, KEY_C), KEY(8, 0, KEY_P), KEY(8, 1, KEY_J), KEY(8, 2, KEY_K), KEY(8, 3, KEY_INSERT), KEY(8, 4, KEY_LINEFEED), KEY(8, 5, KEY_U), KEY(8, 6, KEY_I), KEY(8, 7, KEY_O), KEY(9, 0, KEY_4), KEY(9, 1, KEY_5), KEY(9, 2, KEY_6), KEY(9, 3, KEY_7), KEY(9, 4, KEY_8), KEY(9, 5, KEY_1), KEY(9, 6, KEY_2), KEY(9, 7, KEY_3), KEY(10, 0, KEY_F7), KEY(10, 1, KEY_F8), KEY(10, 2, KEY_F9), KEY(10, 3, KEY_F10), KEY(10, 4, KEY_FN), KEY(10, 5, KEY_9), KEY(10, 6, KEY_0), KEY(10, 7, KEY_DOT), KEY(11, 0, KEY_LEFTCTRL), KEY(11, 1, KEY_F11), /* START */ KEY(11, 2, KEY_ENTER), KEY(11, 3, KEY_SEARCH), KEY(11, 4, KEY_DELETE), KEY(11, 5, KEY_RIGHT), KEY(11, 6, KEY_LEFT), KEY(11, 7, KEY_RIGHTSHIFT), }; static struct matrix_keymap_data surf_keymap_data = { .keymap_size = ARRAY_SIZE(surf_keymap), .keymap = surf_keymap, }; static struct pm8xxx_keypad_platform_data surf_keypad_data = { .input_name = "surf_keypad", .input_phys_device = "surf_keypad/input0", .num_rows = 12, .num_cols = 8, .rows_gpio_start = PM8058_GPIO_PM_TO_SYS(8), .cols_gpio_start = PM8058_GPIO_PM_TO_SYS(0), .debounce_ms = 15, .scan_delay_ms = 32, .row_hold_ns = 91500, .wakeup = 1, .keymap_data = &surf_keymap_data, }; static struct matrix_keymap_data fluid_keymap_data = { .keymap_size = ARRAY_SIZE(fluid_keymap), .keymap = fluid_keymap, }; static struct pm8xxx_keypad_platform_data fluid_keypad_data = { .input_name = "fluid-keypad", .input_phys_device = "fluid-keypad/input0", .num_rows = 5, .num_cols = 5, .rows_gpio_start = PM8058_GPIO_PM_TO_SYS(8), .cols_gpio_start = PM8058_GPIO_PM_TO_SYS(0), .debounce_ms = 15, .scan_delay_ms = 32, .row_hold_ns = 91500, .wakeup = 1, .keymap_data = &fluid_keymap_data, }; static struct pm8058_pwm_pdata pm8058_pwm_data = { .config = pm8058_pwm_config, .enable = pm8058_pwm_enable, }; static struct pmic8058_led pmic8058_ffa_leds[] = { [0] = { .name = "keyboard-backlight", .max_brightness = 15, .id = PMIC8058_ID_LED_KB_LIGHT, }, }; static struct pmic8058_leds_platform_data pm8058_ffa_leds_data = { .num_leds = ARRAY_SIZE(pmic8058_ffa_leds), .leds = pmic8058_ffa_leds, }; static struct pmic8058_led pmic8058_surf_leds[] = { [0] = { .name = "keyboard-backlight", .max_brightness = 15, .id = PMIC8058_ID_LED_KB_LIGHT, }, [1] = { .name = "voice:red", .max_brightness = 20, .id = PMIC8058_ID_LED_0, }, [2] = { .name = "wlan:green", .max_brightness = 20, .id = PMIC8058_ID_LED_2, }, }; static struct pmic8058_leds_platform_data pm8058_surf_leds_data = { .num_leds = ARRAY_SIZE(pmic8058_surf_leds), .leds = pmic8058_surf_leds, }; static struct pmic8058_led pmic8058_fluid_leds[] = { [0] = { .name = "keyboard-backlight", .max_brightness = 15, .id = PMIC8058_ID_LED_KB_LIGHT, }, [1] = { .name = "flash:led_0", .max_brightness = 15, .id = PMIC8058_ID_FLASH_LED_0, }, [2] = { .name = "flash:led_1", .max_brightness = 15, .id = PMIC8058_ID_FLASH_LED_1, }, }; static struct pmic8058_leds_platform_data pm8058_fluid_leds_data = { .num_leds = ARRAY_SIZE(pmic8058_fluid_leds), .leds = pmic8058_fluid_leds, }; static struct pm8xxx_irq_platform_data pm8xxx_irq_pdata = { .irq_base = PMIC8058_IRQ_BASE, .devirq = MSM_GPIO_TO_INT(PMIC_GPIO_INT), .irq_trigger_flag = IRQF_TRIGGER_LOW, }; static struct pm8xxx_gpio_platform_data pm8xxx_gpio_pdata = { .gpio_base = PM8058_GPIO_PM_TO_SYS(0), }; static struct pm8xxx_mpp_platform_data pm8xxx_mpp_pdata = { .mpp_base = PM8058_MPP_PM_TO_SYS(0), }; static struct pm8058_platform_data pm8058_7x30_data = { .irq_pdata = &pm8xxx_irq_pdata, .gpio_pdata = &pm8xxx_gpio_pdata, .mpp_pdata = &pm8xxx_mpp_pdata, .pwm_pdata = &pm8058_pwm_data, }; #ifdef CONFIG_MSM_SSBI static struct msm_ssbi_platform_data msm7x30_ssbi_pm8058_pdata = { .rsl_id = "D:PMIC_SSBI", .controller_type = MSM_SBI_CTRL_SSBI2, .slave = { .name = "pm8058-core", .platform_data = &pm8058_7x30_data, }, }; #endif static struct i2c_board_info cy8info[] __initdata = { { I2C_BOARD_INFO(CY_I2C_NAME, 0x24), .platform_data = &cyttsp_data, #ifndef CY_USE_TIMER .irq = MSM_GPIO_TO_INT(CYTTSP_TS_GPIO_IRQ), #endif /* CY_USE_TIMER */ }, }; #ifdef CONFIG_MSM_CAMERA_V4L2 static struct msm_camera_device_platform_data msm_camera_csi_device_data[] = { { .csiphy_core = 0, .csid_core = 0, .is_vpe = 1, .ioclk = { .vfe_clk_rate = 153600000, }, }, { .csiphy_core = 0, .csid_core = 0, .is_vpe = 1, .ioclk = { .vfe_clk_rate = 153600000, }, }, }; static struct camera_vreg_t msm_7x30_back_cam_vreg[] = { {"gp2", REG_LDO, 2600000, 2600000, -1}, {"lvsw1", REG_VS, 0, 0, 0}, }; static uint32_t camera_off_gpio_table[] = { /* parallel CAMERA interfaces */ /* RST */ GPIO_CFG(0, 0, GPIO_CFG_OUTPUT, GPIO_CFG_PULL_DOWN, GPIO_CFG_2MA), /* DAT2 */ GPIO_CFG(2, 0, GPIO_CFG_INPUT, GPIO_CFG_PULL_DOWN, GPIO_CFG_2MA), /* DAT3 */ GPIO_CFG(3, 0, GPIO_CFG_INPUT, GPIO_CFG_PULL_DOWN, GPIO_CFG_2MA), /* DAT4 */ GPIO_CFG(4, 0, GPIO_CFG_INPUT, GPIO_CFG_PULL_DOWN, GPIO_CFG_2MA), /* DAT5 */ GPIO_CFG(5, 0, GPIO_CFG_INPUT, GPIO_CFG_PULL_DOWN, GPIO_CFG_2MA), /* DAT6 */ GPIO_CFG(6, 0, GPIO_CFG_INPUT, GPIO_CFG_PULL_DOWN, GPIO_CFG_2MA), /* DAT7 */ GPIO_CFG(7, 0, GPIO_CFG_INPUT, GPIO_CFG_PULL_DOWN, GPIO_CFG_2MA), /* DAT8 */ GPIO_CFG(8, 0, GPIO_CFG_INPUT, GPIO_CFG_PULL_DOWN, GPIO_CFG_2MA), /* DAT9 */ GPIO_CFG(9, 0, GPIO_CFG_INPUT, GPIO_CFG_PULL_DOWN, GPIO_CFG_2MA), /* DAT10 */ GPIO_CFG(10, 0, GPIO_CFG_INPUT, GPIO_CFG_PULL_DOWN, GPIO_CFG_2MA), /* DAT11 */ GPIO_CFG(11, 0, GPIO_CFG_INPUT, GPIO_CFG_PULL_DOWN, GPIO_CFG_2MA), /* PCLK */ GPIO_CFG(12, 0, GPIO_CFG_INPUT, GPIO_CFG_PULL_DOWN, GPIO_CFG_2MA), /* HSYNC_IN */ GPIO_CFG(13, 0, GPIO_CFG_INPUT, GPIO_CFG_PULL_DOWN, GPIO_CFG_2MA), /* VSYNC_IN */ GPIO_CFG(14, 0, GPIO_CFG_INPUT, GPIO_CFG_PULL_DOWN, GPIO_CFG_2MA), /* MCLK */ GPIO_CFG(15, 0, GPIO_CFG_OUTPUT, GPIO_CFG_NO_PULL, GPIO_CFG_2MA), }; static uint32_t camera_on_gpio_table[] = { /* parallel CAMERA interfaces */ /* RST */ GPIO_CFG(0, 0, GPIO_CFG_OUTPUT, GPIO_CFG_PULL_DOWN, GPIO_CFG_2MA), /* DAT2 */ GPIO_CFG(2, 1, GPIO_CFG_INPUT, GPIO_CFG_PULL_DOWN, GPIO_CFG_2MA), /* DAT3 */ GPIO_CFG(3, 1, GPIO_CFG_INPUT, GPIO_CFG_PULL_DOWN, GPIO_CFG_2MA), /* DAT4 */ GPIO_CFG(4, 1, GPIO_CFG_INPUT, GPIO_CFG_PULL_DOWN, GPIO_CFG_2MA), /* DAT5 */ GPIO_CFG(5, 1, GPIO_CFG_INPUT, GPIO_CFG_PULL_DOWN, GPIO_CFG_2MA), /* DAT6 */ GPIO_CFG(6, 1, GPIO_CFG_INPUT, GPIO_CFG_PULL_DOWN, GPIO_CFG_2MA), /* DAT7 */ GPIO_CFG(7, 1, GPIO_CFG_INPUT, GPIO_CFG_PULL_DOWN, GPIO_CFG_2MA), /* DAT8 */ GPIO_CFG(8, 1, GPIO_CFG_INPUT, GPIO_CFG_PULL_DOWN, GPIO_CFG_2MA), /* DAT9 */ GPIO_CFG(9, 1, GPIO_CFG_INPUT, GPIO_CFG_PULL_DOWN, GPIO_CFG_2MA), /* DAT10 */ GPIO_CFG(10, 1, GPIO_CFG_INPUT, GPIO_CFG_PULL_DOWN, GPIO_CFG_2MA), /* DAT11 */ GPIO_CFG(11, 1, GPIO_CFG_INPUT, GPIO_CFG_PULL_DOWN, GPIO_CFG_2MA), /* PCLK */ GPIO_CFG(12, 1, GPIO_CFG_INPUT, GPIO_CFG_PULL_DOWN, GPIO_CFG_2MA), /* HSYNC_IN */ GPIO_CFG(13, 1, GPIO_CFG_INPUT, GPIO_CFG_PULL_DOWN, GPIO_CFG_2MA), /* VSYNC_IN */ GPIO_CFG(14, 1, GPIO_CFG_INPUT, GPIO_CFG_PULL_DOWN, GPIO_CFG_2MA), /* MCLK */ GPIO_CFG(15, 1, GPIO_CFG_OUTPUT, GPIO_CFG_NO_PULL, GPIO_CFG_2MA), }; static struct gpio msm7x30_back_cam_gpio[] = { {0, GPIOF_DIR_OUT, "CAM_RESET"}, }; static struct msm_gpio_set_tbl msm7x30_back_cam_gpio_set_tbl[] = { {0, GPIOF_OUT_INIT_LOW, 1000}, {0, GPIOF_OUT_INIT_HIGH, 4000}, }; static struct msm_camera_gpio_conf msm_7x30_back_cam_gpio_conf = { .cam_gpio_req_tbl = msm7x30_back_cam_gpio, .cam_gpio_req_tbl_size = ARRAY_SIZE(msm7x30_back_cam_gpio), .cam_gpio_set_tbl = msm7x30_back_cam_gpio_set_tbl, .cam_gpio_set_tbl_size = ARRAY_SIZE(msm7x30_back_cam_gpio_set_tbl), .camera_off_table = camera_off_gpio_table, .camera_off_table_size = ARRAY_SIZE(camera_off_gpio_table), .camera_on_table = camera_on_gpio_table, .camera_on_table_size = ARRAY_SIZE(camera_on_gpio_table), .gpio_no_mux = 1, }; static struct msm_camera_sensor_flash_data flash_vx6953 = { .flash_type = MSM_CAMERA_FLASH_NONE, }; static struct msm_camera_sensor_platform_info sensor_board_info_vx6953 = { .mount_angle = 0, .cam_vreg = msm_7x30_back_cam_vreg, .num_vreg = ARRAY_SIZE(msm_7x30_back_cam_vreg), .gpio_conf = &msm_7x30_back_cam_gpio_conf, }; static struct msm_camera_sensor_info msm_camera_sensor_vx6953_data = { .sensor_name = "vx6953", .pdata = &msm_camera_csi_device_data[0], .flash_data = &flash_vx6953, .sensor_platform_info = &sensor_board_info_vx6953, .csi_if = 1, .camera_type = BACK_CAMERA_2D, }; static struct platform_device msm_camera_server = { .name = "msm_cam_server", .id = 0, }; void __init msm7x30_init_cam(void) { platform_device_register(&msm_camera_server); platform_device_register(&msm_device_csic0); platform_device_register(&msm_device_vfe); platform_device_register(&msm_device_vpe); } #ifdef CONFIG_I2C static struct i2c_board_info msm_camera_boardinfo[] = { { I2C_BOARD_INFO("vx6953", 0x20), .platform_data = &msm_camera_sensor_vx6953_data, }, }; #endif #else static struct i2c_board_info msm_camera_boardinfo[] __initdata = { #ifdef CONFIG_MT9D112 { I2C_BOARD_INFO("mt9d112", 0x78 >> 1), }, #endif #ifdef CONFIG_WEBCAM_OV9726 { I2C_BOARD_INFO("ov9726", 0x10), }, #endif #ifdef CONFIG_S5K3E2FX { I2C_BOARD_INFO("s5k3e2fx", 0x20 >> 1), }, #endif #ifdef CONFIG_MT9P012 { I2C_BOARD_INFO("mt9p012", 0x6C >> 1), }, #endif #ifdef CONFIG_VX6953 { I2C_BOARD_INFO("vx6953", 0x20), }, #endif #ifdef CONFIG_MT9E013 { I2C_BOARD_INFO("mt9e013", 0x6C >> 2), }, #endif #ifdef CONFIG_SN12M0PZ { I2C_BOARD_INFO("sn12m0pz", 0x34 >> 1), }, #endif #if defined(CONFIG_MT9T013) || defined(CONFIG_SENSORS_MT9T013) { I2C_BOARD_INFO("mt9t013", 0x6C), }, #endif }; #ifdef CONFIG_MSM_CAMERA #define CAM_STNDBY 143 static uint32_t camera_off_vcm_gpio_table[] = { GPIO_CFG(1, 0, GPIO_CFG_OUTPUT, GPIO_CFG_PULL_DOWN, GPIO_CFG_2MA), /* VCM */ }; static uint32_t camera_off_gpio_table[] = { /* parallel CAMERA interfaces */ /* RST */ GPIO_CFG(0, 0, GPIO_CFG_OUTPUT, GPIO_CFG_PULL_DOWN, GPIO_CFG_2MA), /* DAT2 */ GPIO_CFG(2, 0, GPIO_CFG_INPUT, GPIO_CFG_PULL_DOWN, GPIO_CFG_2MA), /* DAT3 */ GPIO_CFG(3, 0, GPIO_CFG_INPUT, GPIO_CFG_PULL_DOWN, GPIO_CFG_2MA), /* DAT4 */ GPIO_CFG(4, 0, GPIO_CFG_INPUT, GPIO_CFG_PULL_DOWN, GPIO_CFG_2MA), /* DAT5 */ GPIO_CFG(5, 0, GPIO_CFG_INPUT, GPIO_CFG_PULL_DOWN, GPIO_CFG_2MA), /* DAT6 */ GPIO_CFG(6, 0, GPIO_CFG_INPUT, GPIO_CFG_PULL_DOWN, GPIO_CFG_2MA), /* DAT7 */ GPIO_CFG(7, 0, GPIO_CFG_INPUT, GPIO_CFG_PULL_DOWN, GPIO_CFG_2MA), /* DAT8 */ GPIO_CFG(8, 0, GPIO_CFG_INPUT, GPIO_CFG_PULL_DOWN, GPIO_CFG_2MA), /* DAT9 */ GPIO_CFG(9, 0, GPIO_CFG_INPUT, GPIO_CFG_PULL_DOWN, GPIO_CFG_2MA), /* DAT10 */ GPIO_CFG(10, 0, GPIO_CFG_INPUT, GPIO_CFG_PULL_DOWN, GPIO_CFG_2MA), /* DAT11 */ GPIO_CFG(11, 0, GPIO_CFG_INPUT, GPIO_CFG_PULL_DOWN, GPIO_CFG_2MA), /* PCLK */ GPIO_CFG(12, 0, GPIO_CFG_INPUT, GPIO_CFG_PULL_DOWN, GPIO_CFG_2MA), /* HSYNC_IN */ GPIO_CFG(13, 0, GPIO_CFG_INPUT, GPIO_CFG_PULL_DOWN, GPIO_CFG_2MA), /* VSYNC_IN */ GPIO_CFG(14, 0, GPIO_CFG_INPUT, GPIO_CFG_PULL_DOWN, GPIO_CFG_2MA), /* MCLK */ GPIO_CFG(15, 0, GPIO_CFG_OUTPUT, GPIO_CFG_NO_PULL, GPIO_CFG_2MA), }; static uint32_t camera_on_vcm_gpio_table[] = { GPIO_CFG(1, 0, GPIO_CFG_OUTPUT, GPIO_CFG_PULL_UP, GPIO_CFG_2MA), /* VCM */ }; static uint32_t camera_on_gpio_table[] = { /* parallel CAMERA interfaces */ /* RST */ GPIO_CFG(0, 0, GPIO_CFG_OUTPUT, GPIO_CFG_PULL_DOWN, GPIO_CFG_2MA), /* DAT2 */ GPIO_CFG(2, 1, GPIO_CFG_INPUT, GPIO_CFG_PULL_DOWN, GPIO_CFG_2MA), /* DAT3 */ GPIO_CFG(3, 1, GPIO_CFG_INPUT, GPIO_CFG_PULL_DOWN, GPIO_CFG_2MA), /* DAT4 */ GPIO_CFG(4, 1, GPIO_CFG_INPUT, GPIO_CFG_PULL_DOWN, GPIO_CFG_2MA), /* DAT5 */ GPIO_CFG(5, 1, GPIO_CFG_INPUT, GPIO_CFG_PULL_DOWN, GPIO_CFG_2MA), /* DAT6 */ GPIO_CFG(6, 1, GPIO_CFG_INPUT, GPIO_CFG_PULL_DOWN, GPIO_CFG_2MA), /* DAT7 */ GPIO_CFG(7, 1, GPIO_CFG_INPUT, GPIO_CFG_PULL_DOWN, GPIO_CFG_2MA), /* DAT8 */ GPIO_CFG(8, 1, GPIO_CFG_INPUT, GPIO_CFG_PULL_DOWN, GPIO_CFG_2MA), /* DAT9 */ GPIO_CFG(9, 1, GPIO_CFG_INPUT, GPIO_CFG_PULL_DOWN, GPIO_CFG_2MA), /* DAT10 */ GPIO_CFG(10, 1, GPIO_CFG_INPUT, GPIO_CFG_PULL_DOWN, GPIO_CFG_2MA), /* DAT11 */ GPIO_CFG(11, 1, GPIO_CFG_INPUT, GPIO_CFG_PULL_DOWN, GPIO_CFG_2MA), /* PCLK */ GPIO_CFG(12, 1, GPIO_CFG_INPUT, GPIO_CFG_PULL_DOWN, GPIO_CFG_2MA), /* HSYNC_IN */ GPIO_CFG(13, 1, GPIO_CFG_INPUT, GPIO_CFG_PULL_DOWN, GPIO_CFG_2MA), /* VSYNC_IN */ GPIO_CFG(14, 1, GPIO_CFG_INPUT, GPIO_CFG_PULL_DOWN, GPIO_CFG_2MA), /* MCLK */ GPIO_CFG(15, 1, GPIO_CFG_OUTPUT, GPIO_CFG_NO_PULL, GPIO_CFG_2MA), }; static uint32_t camera_off_gpio_fluid_table[] = { /* FLUID: CAM_VGA_RST_N */ GPIO_CFG(31, 0, GPIO_CFG_OUTPUT, GPIO_CFG_PULL_DOWN, GPIO_CFG_2MA), /* FLUID: CAMIF_STANDBY */ GPIO_CFG(CAM_STNDBY, 0, GPIO_CFG_OUTPUT, GPIO_CFG_NO_PULL, GPIO_CFG_2MA) }; static uint32_t camera_on_gpio_fluid_table[] = { /* FLUID: CAM_VGA_RST_N */ GPIO_CFG(31, 0, GPIO_CFG_OUTPUT, GPIO_CFG_PULL_DOWN, GPIO_CFG_2MA), /* FLUID: CAMIF_STANDBY */ GPIO_CFG(CAM_STNDBY, 0, GPIO_CFG_OUTPUT, GPIO_CFG_NO_PULL, GPIO_CFG_2MA) }; static void config_gpio_table(uint32_t *table, int len) { int n, rc; for (n = 0; n < len; n++) { rc = gpio_tlmm_config(table[n], GPIO_CFG_ENABLE); if (rc) { pr_err("%s: gpio_tlmm_config(%#x)=%d\n", __func__, table[n], rc); break; } } } static int config_camera_on_gpios(void) { config_gpio_table(camera_on_gpio_table, ARRAY_SIZE(camera_on_gpio_table)); if (adie_get_detected_codec_type() != TIMPANI_ID) /* GPIO1 is shared also used in Timpani RF card so only configure it for non-Timpani RF card */ config_gpio_table(camera_on_vcm_gpio_table, ARRAY_SIZE(camera_on_vcm_gpio_table)); if (machine_is_msm7x30_fluid()) { config_gpio_table(camera_on_gpio_fluid_table, ARRAY_SIZE(camera_on_gpio_fluid_table)); /* FLUID: turn on 5V booster */ gpio_set_value( PM8058_GPIO_PM_TO_SYS(PMIC_GPIO_FLASH_BOOST_ENABLE), 1); /* FLUID: drive high to put secondary sensor to STANDBY */ gpio_set_value(CAM_STNDBY, 1); } return 0; } static void config_camera_off_gpios(void) { config_gpio_table(camera_off_gpio_table, ARRAY_SIZE(camera_off_gpio_table)); if (adie_get_detected_codec_type() != TIMPANI_ID) /* GPIO1 is shared also used in Timpani RF card so only configure it for non-Timpani RF card */ config_gpio_table(camera_off_vcm_gpio_table, ARRAY_SIZE(camera_off_vcm_gpio_table)); if (machine_is_msm7x30_fluid()) { config_gpio_table(camera_off_gpio_fluid_table, ARRAY_SIZE(camera_off_gpio_fluid_table)); /* FLUID: turn off 5V booster */ gpio_set_value( PM8058_GPIO_PM_TO_SYS(PMIC_GPIO_FLASH_BOOST_ENABLE), 0); } } struct resource msm_camera_resources[] = { { .start = 0xA6000000, .end = 0xA6000000 + SZ_1M - 1, .flags = IORESOURCE_MEM, }, { .start = INT_VFE, .end = INT_VFE, .flags = IORESOURCE_IRQ, }, { .flags = IORESOURCE_DMA, } }; struct msm_camera_device_platform_data msm_camera_device_data = { .camera_gpio_on = config_camera_on_gpios, .camera_gpio_off = config_camera_off_gpios, .ioext.camifpadphy = 0xAB000000, .ioext.camifpadsz = 0x00000400, .ioext.csiphy = 0xA6100000, .ioext.csisz = 0x00000400, .ioext.csiirq = INT_CSI, .ioclk.mclk_clk_rate = 24000000, .ioclk.vfe_clk_rate = 147456000, }; static struct msm_camera_sensor_flash_src msm_flash_src_pwm = { .flash_sr_type = MSM_CAMERA_FLASH_SRC_PWM, ._fsrc.pwm_src.freq = 1000, ._fsrc.pwm_src.max_load = 300, ._fsrc.pwm_src.low_load = 30, ._fsrc.pwm_src.high_load = 100, ._fsrc.pwm_src.channel = 7, }; #ifdef CONFIG_MT9D112 static struct msm_camera_sensor_flash_data flash_mt9d112 = { .flash_type = MSM_CAMERA_FLASH_LED, .flash_src = &msm_flash_src_pwm }; static struct msm_camera_sensor_info msm_camera_sensor_mt9d112_data = { .sensor_name = "mt9d112", .sensor_reset = 0, .sensor_pwd = 85, .vcm_pwd = 1, .vcm_enable = 0, .pdata = &msm_camera_device_data, .resource = msm_camera_resources, .num_resources = ARRAY_SIZE(msm_camera_resources), .flash_data = &flash_mt9d112, .csi_if = 0 }; static struct platform_device msm_camera_sensor_mt9d112 = { .name = "msm_camera_mt9d112", .dev = { .platform_data = &msm_camera_sensor_mt9d112_data, }, }; #endif #ifdef CONFIG_WEBCAM_OV9726 static struct msm_camera_sensor_platform_info ov9726_sensor_7630_info = { .mount_angle = 90 }; static struct msm_camera_sensor_flash_data flash_ov9726 = { .flash_type = MSM_CAMERA_FLASH_LED, .flash_src = &msm_flash_src_pwm }; static struct msm_camera_sensor_info msm_camera_sensor_ov9726_data = { .sensor_name = "ov9726", .sensor_reset = 0, .sensor_pwd = 85, .vcm_pwd = 1, .vcm_enable = 0, .pdata = &msm_camera_device_data, .resource = msm_camera_resources, .num_resources = ARRAY_SIZE(msm_camera_resources), .flash_data = &flash_ov9726, .sensor_platform_info = &ov9726_sensor_7630_info, .csi_if = 1 }; struct platform_device msm_camera_sensor_ov9726 = { .name = "msm_camera_ov9726", .dev = { .platform_data = &msm_camera_sensor_ov9726_data, }, }; #endif #ifdef CONFIG_S5K3E2FX static struct msm_camera_sensor_flash_data flash_s5k3e2fx = { .flash_type = MSM_CAMERA_FLASH_LED, .flash_src = &msm_flash_src_pwm, }; static struct msm_camera_sensor_info msm_camera_sensor_s5k3e2fx_data = { .sensor_name = "s5k3e2fx", .sensor_reset = 0, .sensor_pwd = 85, .vcm_pwd = 1, .vcm_enable = 0, .pdata = &msm_camera_device_data, .resource = msm_camera_resources, .num_resources = ARRAY_SIZE(msm_camera_resources), .flash_data = &flash_s5k3e2fx, .csi_if = 0 }; static struct platform_device msm_camera_sensor_s5k3e2fx = { .name = "msm_camera_s5k3e2fx", .dev = { .platform_data = &msm_camera_sensor_s5k3e2fx_data, }, }; #endif #ifdef CONFIG_MT9P012 static struct msm_camera_sensor_flash_data flash_mt9p012 = { .flash_type = MSM_CAMERA_FLASH_LED, .flash_src = &msm_flash_src_pwm }; static struct msm_camera_sensor_info msm_camera_sensor_mt9p012_data = { .sensor_name = "mt9p012", .sensor_reset = 0, .sensor_pwd = 85, .vcm_pwd = 1, .vcm_enable = 1, .pdata = &msm_camera_device_data, .resource = msm_camera_resources, .num_resources = ARRAY_SIZE(msm_camera_resources), .flash_data = &flash_mt9p012, .csi_if = 0 }; static struct platform_device msm_camera_sensor_mt9p012 = { .name = "msm_camera_mt9p012", .dev = { .platform_data = &msm_camera_sensor_mt9p012_data, }, }; #endif #ifdef CONFIG_MT9E013 static struct msm_camera_sensor_platform_info mt9e013_sensor_7630_info = { .mount_angle = 0 }; static struct msm_camera_sensor_flash_data flash_mt9e013 = { .flash_type = MSM_CAMERA_FLASH_LED, .flash_src = &msm_flash_src_pwm }; static struct msm_camera_sensor_info msm_camera_sensor_mt9e013_data = { .sensor_name = "mt9e013", .sensor_reset = 0, .sensor_pwd = 85, .vcm_pwd = 1, .vcm_enable = 1, .pdata = &msm_camera_device_data, .resource = msm_camera_resources, .num_resources = ARRAY_SIZE(msm_camera_resources), .flash_data = &flash_mt9e013, .sensor_platform_info = &mt9e013_sensor_7630_info, .csi_if = 1 }; static struct platform_device msm_camera_sensor_mt9e013 = { .name = "msm_camera_mt9e013", .dev = { .platform_data = &msm_camera_sensor_mt9e013_data, }, }; #endif #ifdef CONFIG_VX6953 static struct msm_camera_sensor_platform_info vx6953_sensor_7630_info = { .mount_angle = 0 }; static struct msm_camera_sensor_flash_data flash_vx6953 = { .flash_type = MSM_CAMERA_FLASH_LED, .flash_src = &msm_flash_src_pwm }; static struct msm_camera_sensor_info msm_camera_sensor_vx6953_data = { .sensor_name = "vx6953", .sensor_reset = 0, .sensor_pwd = 85, .vcm_pwd = 1, .vcm_enable = 0, .pdata = &msm_camera_device_data, .resource = msm_camera_resources, .num_resources = ARRAY_SIZE(msm_camera_resources), .sensor_platform_info = &vx6953_sensor_7630_info, .flash_data = &flash_vx6953, .csi_if = 1 }; static struct platform_device msm_camera_sensor_vx6953 = { .name = "msm_camera_vx6953", .dev = { .platform_data = &msm_camera_sensor_vx6953_data, }, }; #endif #ifdef CONFIG_SN12M0PZ static struct msm_camera_sensor_flash_src msm_flash_src_current_driver = { .flash_sr_type = MSM_CAMERA_FLASH_SRC_CURRENT_DRIVER, ._fsrc.current_driver_src.low_current = 210, ._fsrc.current_driver_src.high_current = 700, ._fsrc.current_driver_src.driver_channel = &pm8058_fluid_leds_data, }; static struct msm_camera_sensor_flash_data flash_sn12m0pz = { .flash_type = MSM_CAMERA_FLASH_LED, .flash_src = &msm_flash_src_current_driver }; static struct msm_camera_sensor_info msm_camera_sensor_sn12m0pz_data = { .sensor_name = "sn12m0pz", .sensor_reset = 0, .sensor_pwd = 85, .vcm_pwd = 1, .vcm_enable = 1, .pdata = &msm_camera_device_data, .flash_data = &flash_sn12m0pz, .resource = msm_camera_resources, .num_resources = ARRAY_SIZE(msm_camera_resources), .csi_if = 0 }; static struct platform_device msm_camera_sensor_sn12m0pz = { .name = "msm_camera_sn12m0pz", .dev = { .platform_data = &msm_camera_sensor_sn12m0pz_data, }, }; #endif #ifdef CONFIG_MT9T013 static struct msm_camera_sensor_flash_data flash_mt9t013 = { .flash_type = MSM_CAMERA_FLASH_LED, .flash_src = &msm_flash_src_pwm }; static struct msm_camera_sensor_info msm_camera_sensor_mt9t013_data = { .sensor_name = "mt9t013", .sensor_reset = 0, .sensor_pwd = 85, .vcm_pwd = 1, .vcm_enable = 0, .pdata = &msm_camera_device_data, .resource = msm_camera_resources, .num_resources = ARRAY_SIZE(msm_camera_resources), .flash_data = &flash_mt9t013, .csi_if = 1 }; static struct platform_device msm_camera_sensor_mt9t013 = { .name = "msm_camera_mt9t013", .dev = { .platform_data = &msm_camera_sensor_mt9t013_data, }, }; #endif #ifdef CONFIG_MSM_VPE static struct resource msm_vpe_resources[] = { { .start = 0xAD200000, .end = 0xAD200000 + SZ_1M - 1, .flags = IORESOURCE_MEM, }, { .start = INT_VPE, .end = INT_VPE, .flags = IORESOURCE_IRQ, }, }; static struct platform_device msm_vpe_device = { .name = "msm_vpe", .id = 0, .num_resources = ARRAY_SIZE(msm_vpe_resources), .resource = msm_vpe_resources, }; #endif #endif /*CONFIG_MSM_CAMERA*/ #endif #ifdef CONFIG_MSM_GEMINI static struct resource msm_gemini_resources[] = { { .start = 0xA3A00000, .end = 0xA3A00000 + 0x0150 - 1, .flags = IORESOURCE_MEM, }, { .start = INT_JPEG, .end = INT_JPEG, .flags = IORESOURCE_IRQ, }, }; static struct platform_device msm_gemini_device = { .name = "msm_gemini", .resource = msm_gemini_resources, .num_resources = ARRAY_SIZE(msm_gemini_resources), }; #endif #ifdef CONFIG_MSM7KV2_AUDIO static uint32_t audio_pamp_gpio_config = GPIO_CFG(82, 0, GPIO_CFG_OUTPUT, GPIO_CFG_NO_PULL, GPIO_CFG_2MA); static uint32_t audio_fluid_icodec_tx_config = GPIO_CFG(85, 0, GPIO_CFG_OUTPUT, GPIO_CFG_NO_PULL, GPIO_CFG_2MA); static int __init snddev_poweramp_gpio_init(void) { int rc; pr_info("snddev_poweramp_gpio_init \n"); rc = gpio_tlmm_config(audio_pamp_gpio_config, GPIO_CFG_ENABLE); if (rc) { printk(KERN_ERR "%s: gpio_tlmm_config(%#x)=%d\n", __func__, audio_pamp_gpio_config, rc); } return rc; } void msm_snddev_tx_route_config(void) { int rc; pr_debug("%s()\n", __func__); if (machine_is_msm7x30_fluid()) { rc = gpio_tlmm_config(audio_fluid_icodec_tx_config, GPIO_CFG_ENABLE); if (rc) { printk(KERN_ERR "%s: gpio_tlmm_config(%#x)=%d\n", __func__, audio_fluid_icodec_tx_config, rc); } else gpio_set_value(85, 0); } } void msm_snddev_tx_route_deconfig(void) { int rc; pr_debug("%s()\n", __func__); if (machine_is_msm7x30_fluid()) { rc = gpio_tlmm_config(audio_fluid_icodec_tx_config, GPIO_CFG_DISABLE); if (rc) { printk(KERN_ERR "%s: gpio_tlmm_config(%#x)=%d\n", __func__, audio_fluid_icodec_tx_config, rc); } } } void msm_snddev_poweramp_on(void) { gpio_set_value(82, 1); /* enable spkr poweramp */ pr_info("%s: power on amplifier\n", __func__); } void msm_snddev_poweramp_off(void) { gpio_set_value(82, 0); /* disable spkr poweramp */ pr_info("%s: power off amplifier\n", __func__); } static struct regulator_bulk_data snddev_regs[] = { { .supply = "gp4", .min_uV = 2600000, .max_uV = 2600000 }, { .supply = "ncp", .min_uV = 1800000, .max_uV = 1800000 }, }; static int __init snddev_hsed_voltage_init(void) { int rc; rc = regulator_bulk_get(NULL, ARRAY_SIZE(snddev_regs), snddev_regs); if (rc) { pr_err("%s: could not get regulators: %d\n", __func__, rc); goto out; } rc = regulator_bulk_set_voltage(ARRAY_SIZE(snddev_regs), snddev_regs); if (rc) { pr_err("%s: could not set regulator voltages: %d\n", __func__, rc); goto regs_free; } return 0; regs_free: regulator_bulk_free(ARRAY_SIZE(snddev_regs), snddev_regs); out: return rc; } void msm_snddev_hsed_voltage_on(void) { int rc = regulator_bulk_enable(ARRAY_SIZE(snddev_regs), snddev_regs); if (rc) pr_err("%s: could not enable regulators: %d\n", __func__, rc); } void msm_snddev_hsed_voltage_off(void) { int rc = regulator_bulk_disable(ARRAY_SIZE(snddev_regs), snddev_regs); if (rc) { pr_err("%s: could not disable regulators: %d\n", __func__, rc); } } static unsigned aux_pcm_gpio_on[] = { GPIO_CFG(138, 1, GPIO_CFG_OUTPUT, GPIO_CFG_NO_PULL, GPIO_CFG_2MA), /* PCM_DOUT */ GPIO_CFG(139, 1, GPIO_CFG_INPUT, GPIO_CFG_NO_PULL, GPIO_CFG_2MA), /* PCM_DIN */ GPIO_CFG(140, 1, GPIO_CFG_OUTPUT, GPIO_CFG_NO_PULL, GPIO_CFG_2MA), /* PCM_SYNC */ GPIO_CFG(141, 1, GPIO_CFG_OUTPUT, GPIO_CFG_NO_PULL, GPIO_CFG_2MA), /* PCM_CLK */ }; static int __init aux_pcm_gpio_init(void) { int pin, rc; pr_info("aux_pcm_gpio_init \n"); for (pin = 0; pin < ARRAY_SIZE(aux_pcm_gpio_on); pin++) { rc = gpio_tlmm_config(aux_pcm_gpio_on[pin], GPIO_CFG_ENABLE); if (rc) { printk(KERN_ERR "%s: gpio_tlmm_config(%#x)=%d\n", __func__, aux_pcm_gpio_on[pin], rc); } } return rc; } static struct msm_gpio mi2s_clk_gpios[] = { { GPIO_CFG(145, 1, GPIO_CFG_OUTPUT, GPIO_CFG_NO_PULL, GPIO_CFG_2MA), "MI2S_SCLK"}, { GPIO_CFG(144, 1, GPIO_CFG_OUTPUT, GPIO_CFG_NO_PULL, GPIO_CFG_2MA), "MI2S_WS"}, { GPIO_CFG(120, 1, GPIO_CFG_OUTPUT, GPIO_CFG_NO_PULL, GPIO_CFG_2MA), "MI2S_MCLK_A"}, }; static struct msm_gpio mi2s_rx_data_lines_gpios[] = { { GPIO_CFG(121, 1, GPIO_CFG_OUTPUT, GPIO_CFG_NO_PULL, GPIO_CFG_2MA), "MI2S_DATA_SD0_A"}, { GPIO_CFG(122, 1, GPIO_CFG_OUTPUT, GPIO_CFG_NO_PULL, GPIO_CFG_2MA), "MI2S_DATA_SD1_A"}, { GPIO_CFG(123, 1, GPIO_CFG_OUTPUT, GPIO_CFG_NO_PULL, GPIO_CFG_2MA), "MI2S_DATA_SD2_A"}, { GPIO_CFG(146, 1, GPIO_CFG_OUTPUT, GPIO_CFG_NO_PULL, GPIO_CFG_2MA), "MI2S_DATA_SD3"}, }; static struct msm_gpio mi2s_tx_data_lines_gpios[] = { { GPIO_CFG(146, 1, GPIO_CFG_INPUT, GPIO_CFG_NO_PULL, GPIO_CFG_2MA), "MI2S_DATA_SD3"}, }; int mi2s_config_clk_gpio(void) { int rc = 0; rc = msm_gpios_request_enable(mi2s_clk_gpios, ARRAY_SIZE(mi2s_clk_gpios)); if (rc) { pr_err("%s: enable mi2s clk gpios failed\n", __func__); return rc; } return 0; } int mi2s_unconfig_data_gpio(u32 direction, u8 sd_line_mask) { int i, rc = 0; sd_line_mask &= MI2S_SD_LINE_MASK; switch (direction) { case DIR_TX: msm_gpios_disable_free(mi2s_tx_data_lines_gpios, 1); break; case DIR_RX: i = 0; while (sd_line_mask) { if (sd_line_mask & 0x1) msm_gpios_disable_free( mi2s_rx_data_lines_gpios + i , 1); sd_line_mask = sd_line_mask >> 1; i++; } break; default: pr_err("%s: Invaild direction direction = %u\n", __func__, direction); rc = -EINVAL; break; } return rc; } int mi2s_config_data_gpio(u32 direction, u8 sd_line_mask) { int i , rc = 0; u8 sd_config_done_mask = 0; sd_line_mask &= MI2S_SD_LINE_MASK; switch (direction) { case DIR_TX: if ((sd_line_mask & MI2S_SD_0) || (sd_line_mask & MI2S_SD_1) || (sd_line_mask & MI2S_SD_2) || !(sd_line_mask & MI2S_SD_3)) { pr_err("%s: can not use SD0 or SD1 or SD2 for TX" ".only can use SD3. sd_line_mask = 0x%x\n", __func__ , sd_line_mask); rc = -EINVAL; } else { rc = msm_gpios_request_enable(mi2s_tx_data_lines_gpios, 1); if (rc) pr_err("%s: enable mi2s gpios for TX failed\n", __func__); } break; case DIR_RX: i = 0; while (sd_line_mask && (rc == 0)) { if (sd_line_mask & 0x1) { rc = msm_gpios_request_enable( mi2s_rx_data_lines_gpios + i , 1); if (rc) { pr_err("%s: enable mi2s gpios for" "RX failed. SD line = %s\n", __func__, (mi2s_rx_data_lines_gpios + i)->label); mi2s_unconfig_data_gpio(DIR_RX, sd_config_done_mask); } else sd_config_done_mask |= (1 << i); } sd_line_mask = sd_line_mask >> 1; i++; } break; default: pr_err("%s: Invaild direction direction = %u\n", __func__, direction); rc = -EINVAL; break; } return rc; } int mi2s_unconfig_clk_gpio(void) { msm_gpios_disable_free(mi2s_clk_gpios, ARRAY_SIZE(mi2s_clk_gpios)); return 0; } #endif /* CONFIG_MSM7KV2_AUDIO */ static int __init buses_init(void) { if (gpio_tlmm_config(GPIO_CFG(PMIC_GPIO_INT, 1, GPIO_CFG_INPUT, GPIO_CFG_NO_PULL, GPIO_CFG_2MA), GPIO_CFG_ENABLE)) pr_err("%s: gpio_tlmm_config (gpio=%d) failed\n", __func__, PMIC_GPIO_INT); if (machine_is_msm8x60_fluid()) pm8058_7x30_data.keypad_pdata = &fluid_keypad_data; else pm8058_7x30_data.keypad_pdata = &surf_keypad_data; return 0; } #define TIMPANI_RESET_GPIO 1 struct bahama_config_register{ u8 reg; u8 value; u8 mask; }; enum version{ VER_1_0, VER_2_0, VER_UNSUPPORTED = 0xFF }; static struct regulator *vreg_marimba_1; static struct regulator *vreg_marimba_2; static struct regulator *vreg_bahama; static struct msm_gpio timpani_reset_gpio_cfg[] = { { GPIO_CFG(TIMPANI_RESET_GPIO, 0, GPIO_CFG_OUTPUT, GPIO_CFG_NO_PULL, GPIO_CFG_2MA), "timpani_reset"} }; static u8 read_bahama_ver(void) { int rc; struct marimba config = { .mod_id = SLAVE_ID_BAHAMA }; u8 bahama_version; rc = marimba_read_bit_mask(&config, 0x00, &bahama_version, 1, 0x1F); if (rc < 0) { printk(KERN_ERR "%s: version read failed: %d\n", __func__, rc); return rc; } else { printk(KERN_INFO "%s: version read got: 0x%x\n", __func__, bahama_version); } switch (bahama_version) { case 0x08: /* varient of bahama v1 */ case 0x10: case 0x00: return VER_1_0; case 0x09: /* variant of bahama v2 */ return VER_2_0; default: return VER_UNSUPPORTED; } } static int config_timpani_reset(void) { int rc; rc = msm_gpios_request_enable(timpani_reset_gpio_cfg, ARRAY_SIZE(timpani_reset_gpio_cfg)); if (rc < 0) { printk(KERN_ERR "%s: msm_gpios_request_enable failed (%d)\n", __func__, rc); } return rc; } static unsigned int msm_timpani_setup_power(void) { int rc; rc = config_timpani_reset(); if (rc < 0) goto out; rc = regulator_enable(vreg_marimba_1); if (rc) { pr_err("%s: regulator_enable failed (%d)\n", __func__, rc); goto out; } rc = regulator_enable(vreg_marimba_2); if (rc) { pr_err("%s: regulator_enable failed (%d)\n", __func__, rc); goto disable_marimba_1; } rc = gpio_direction_output(TIMPANI_RESET_GPIO, 1); if (rc < 0) { pr_err("%s: gpio_direction_output failed (%d)\n", __func__, rc); msm_gpios_free(timpani_reset_gpio_cfg, ARRAY_SIZE(timpani_reset_gpio_cfg)); goto disable_marimba_2; } return 0; disable_marimba_2: regulator_disable(vreg_marimba_2); disable_marimba_1: regulator_disable(vreg_marimba_1); out: return rc; }; static void msm_timpani_shutdown_power(void) { int rc; rc = regulator_disable(vreg_marimba_2); if (rc) pr_err("%s: regulator_disable failed (%d)\n", __func__, rc); rc = regulator_disable(vreg_marimba_1); if (rc) pr_err("%s: regulator_disable failed (%d)\n", __func__, rc); rc = gpio_direction_output(TIMPANI_RESET_GPIO, 0); if (rc < 0) pr_err("%s: gpio_direction_output failed (%d)\n", __func__, rc); msm_gpios_free(timpani_reset_gpio_cfg, ARRAY_SIZE(timpani_reset_gpio_cfg)); }; static unsigned int msm_bahama_core_config(int type) { int rc = 0; if (type == BAHAMA_ID) { int i; struct marimba config = { .mod_id = SLAVE_ID_BAHAMA }; const struct bahama_config_register v20_init[] = { /* reg, value, mask */ { 0xF4, 0x84, 0xFF }, /* AREG */ { 0xF0, 0x04, 0xFF } /* DREG */ }; if (read_bahama_ver() == VER_2_0) { for (i = 0; i < ARRAY_SIZE(v20_init); i++) { u8 value = v20_init[i].value; rc = marimba_write_bit_mask(&config, v20_init[i].reg, &value, sizeof(v20_init[i].value), v20_init[i].mask); if (rc < 0) { printk(KERN_ERR "%s: reg %d write failed: %d\n", __func__, v20_init[i].reg, rc); return rc; } printk(KERN_INFO "%s: reg 0x%02x value 0x%02x" " mask 0x%02x\n", __func__, v20_init[i].reg, v20_init[i].value, v20_init[i].mask); } } } printk(KERN_INFO "core type: %d\n", type); return rc; } static unsigned int msm_bahama_setup_power(void) { int rc = regulator_enable(vreg_bahama); if (rc) pr_err("%s: regulator_enable failed (%d)\n", __func__, rc); return rc; }; static unsigned int msm_bahama_shutdown_power(int value) { int rc = 0; if (value != BAHAMA_ID) { rc = regulator_disable(vreg_bahama); if (rc) pr_err("%s: regulator_disable failed (%d)\n", __func__, rc); } return rc; }; static struct msm_gpio marimba_svlte_config_clock[] = { { GPIO_CFG(34, 0, GPIO_CFG_OUTPUT, GPIO_CFG_NO_PULL, GPIO_CFG_2MA), "MARIMBA_SVLTE_CLOCK_ENABLE" }, }; static unsigned int msm_marimba_gpio_config_svlte(int gpio_cfg_marimba) { if (machine_is_msm8x55_svlte_surf() || machine_is_msm8x55_svlte_ffa()) { if (gpio_cfg_marimba) gpio_set_value(GPIO_PIN (marimba_svlte_config_clock->gpio_cfg), 1); else gpio_set_value(GPIO_PIN (marimba_svlte_config_clock->gpio_cfg), 0); } return 0; }; static unsigned int msm_marimba_setup_power(void) { int rc; rc = regulator_enable(vreg_marimba_1); if (rc) { pr_err("%s: regulator_enable failed (%d)\n", __func__, rc); goto out; } rc = regulator_enable(vreg_marimba_2); if (rc) { pr_err("%s: regulator_enable failed (%d)\n", __func__, rc); goto disable_marimba_1; } if (machine_is_msm8x55_svlte_surf() || machine_is_msm8x55_svlte_ffa()) { rc = msm_gpios_request_enable(marimba_svlte_config_clock, ARRAY_SIZE(marimba_svlte_config_clock)); if (rc < 0) { pr_err("%s: msm_gpios_request_enable failed (%d)\n", __func__, rc); goto disable_marimba_2; } rc = gpio_direction_output(GPIO_PIN (marimba_svlte_config_clock->gpio_cfg), 0); if (rc < 0) { pr_err("%s: gpio_direction_output failed (%d)\n", __func__, rc); goto disable_marimba_2; } } return 0; disable_marimba_2: regulator_disable(vreg_marimba_2); disable_marimba_1: regulator_disable(vreg_marimba_1); out: return rc; }; static void msm_marimba_shutdown_power(void) { int rc; rc = regulator_disable(vreg_marimba_2); if (rc) pr_err("%s: regulator_disable failed (%d)\n", __func__, rc); rc = regulator_disable(vreg_marimba_1); if (rc) pr_err("%s: regulator_disable failed (%d)\n", __func__, rc); }; static int bahama_present(void) { int id; switch (id = adie_get_detected_connectivity_type()) { case BAHAMA_ID: return 1; case MARIMBA_ID: return 0; case TIMPANI_ID: default: printk(KERN_ERR "%s: unexpected adie connectivity type: %d\n", __func__, id); return -ENODEV; } } struct regulator *fm_regulator; static int fm_radio_setup(struct marimba_fm_platform_data *pdata) { int rc, voltage; uint32_t irqcfg; const char *id = "FMPW"; int bahama_not_marimba = bahama_present(); if (bahama_not_marimba < 0) { pr_warn("%s: bahama_present: %d\n", __func__, bahama_not_marimba); rc = -ENODEV; goto out; } if (bahama_not_marimba) { fm_regulator = regulator_get(NULL, "s3"); voltage = 1800000; } else { fm_regulator = regulator_get(NULL, "s2"); voltage = 1300000; } if (IS_ERR(fm_regulator)) { rc = PTR_ERR(fm_regulator); pr_err("%s: regulator_get failed (%d)\n", __func__, rc); goto out; } rc = regulator_set_voltage(fm_regulator, voltage, voltage); if (rc) { pr_err("%s: regulator_set_voltage failed (%d)\n", __func__, rc); goto regulator_free; } rc = regulator_enable(fm_regulator); if (rc) { pr_err("%s: regulator_enable failed (%d)\n", __func__, rc); goto regulator_free; } rc = pmapp_clock_vote(id, PMAPP_CLOCK_ID_DO, PMAPP_CLOCK_VOTE_ON); if (rc < 0) { pr_err("%s: clock vote failed (%d)\n", __func__, rc); goto regulator_disable; } /*Request the Clock Using GPIO34/AP2MDM_MRMBCK_EN in case of svlte*/ if (machine_is_msm8x55_svlte_surf() || machine_is_msm8x55_svlte_ffa()) { rc = marimba_gpio_config(1); if (rc < 0) { pr_err("%s: clock enable for svlte : %d\n", __func__, rc); goto clock_devote; } } irqcfg = GPIO_CFG(147, 0, GPIO_CFG_INPUT, GPIO_CFG_NO_PULL, GPIO_CFG_2MA); rc = gpio_tlmm_config(irqcfg, GPIO_CFG_ENABLE); if (rc) { pr_err("%s: gpio_tlmm_config(%#x)=%d\n", __func__, irqcfg, rc); rc = -EIO; goto gpio_deconfig; } return 0; gpio_deconfig: if (machine_is_msm8x55_svlte_surf() || machine_is_msm8x55_svlte_ffa()) marimba_gpio_config(0); clock_devote: pmapp_clock_vote(id, PMAPP_CLOCK_ID_DO, PMAPP_CLOCK_VOTE_OFF); regulator_disable: regulator_disable(fm_regulator); regulator_free: regulator_put(fm_regulator); fm_regulator = NULL; out: return rc; }; static void fm_radio_shutdown(struct marimba_fm_platform_data *pdata) { int rc; const char *id = "FMPW"; uint32_t irqcfg = GPIO_CFG(147, 0, GPIO_CFG_INPUT, GPIO_CFG_PULL_UP, GPIO_CFG_2MA); int bahama_not_marimba = bahama_present(); if (bahama_not_marimba == -1) { pr_warn("%s: bahama_present: %d\n", __func__, bahama_not_marimba); return; } rc = gpio_tlmm_config(irqcfg, GPIO_CFG_ENABLE); if (rc) { pr_err("%s: gpio_tlmm_config(%#x)=%d\n", __func__, irqcfg, rc); } if (!IS_ERR_OR_NULL(fm_regulator)) { rc = regulator_disable(fm_regulator); if (rc) pr_err("%s: return val: %d\n", __func__, rc); regulator_put(fm_regulator); fm_regulator = NULL; } rc = pmapp_clock_vote(id, PMAPP_CLOCK_ID_DO, PMAPP_CLOCK_VOTE_OFF); if (rc < 0) pr_err("%s: clock_vote return val: %d\n", __func__, rc); /*Disable the Clock Using GPIO34/AP2MDM_MRMBCK_EN in case of svlte*/ if (machine_is_msm8x55_svlte_surf() || machine_is_msm8x55_svlte_ffa()) { rc = marimba_gpio_config(0); if (rc < 0) pr_err("%s: clock disable for svlte : %d\n", __func__, rc); } } static struct marimba_fm_platform_data marimba_fm_pdata = { .fm_setup = fm_radio_setup, .fm_shutdown = fm_radio_shutdown, .irq = MSM_GPIO_TO_INT(147), .vreg_s2 = NULL, .vreg_xo_out = NULL, .is_fm_soc_i2s_master = false, .config_i2s_gpio = NULL, }; /* Slave id address for FM/CDC/QMEMBIST * Values can be programmed using Marimba slave id 0 * should there be a conflict with other I2C devices * */ #define MARIMBA_SLAVE_ID_FM_ADDR 0x2A #define MARIMBA_SLAVE_ID_CDC_ADDR 0x77 #define MARIMBA_SLAVE_ID_QMEMBIST_ADDR 0X66 #define BAHAMA_SLAVE_ID_FM_ADDR 0x2A #define BAHAMA_SLAVE_ID_QMEMBIST_ADDR 0x7B static const char *tsadc_id = "MADC"; static struct regulator_bulk_data regs_tsadc_marimba[] = { { .supply = "gp12", .min_uV = 2200000, .max_uV = 2200000 }, { .supply = "s2", .min_uV = 1300000, .max_uV = 1300000 }, }; static struct regulator_bulk_data regs_tsadc_timpani[] = { { .supply = "s3", .min_uV = 1800000, .max_uV = 1800000 }, { .supply = "gp12", .min_uV = 2200000, .max_uV = 2200000 }, { .supply = "gp16", .min_uV = 1200000, .max_uV = 1200000 }, }; static struct regulator_bulk_data *regs_tsadc; static int regs_tsadc_count; static int marimba_tsadc_power(int vreg_on) { int rc = 0; int tsadc_adie_type = adie_get_detected_codec_type(); switch (tsadc_adie_type) { case TIMPANI_ID: rc = pmapp_clock_vote(tsadc_id, PMAPP_CLOCK_ID_D1, vreg_on ? PMAPP_CLOCK_VOTE_ON : PMAPP_CLOCK_VOTE_OFF); if (rc) { pr_err("%s: unable to %svote for d1 clk\n", __func__, vreg_on ? "" : "de-"); goto D1_vote_fail; } /* fall through */ case MARIMBA_ID: rc = pmapp_clock_vote(tsadc_id, PMAPP_CLOCK_ID_DO, vreg_on ? PMAPP_CLOCK_VOTE_ON : PMAPP_CLOCK_VOTE_OFF); if (rc) { pr_err("%s: unable to %svote for d1 clk\n", __func__, vreg_on ? "" : "de-"); goto D0_vote_fail; } WARN_ON(regs_tsadc_count == 0); rc = vreg_on ? regulator_bulk_enable(regs_tsadc_count, regs_tsadc) : regulator_bulk_disable(regs_tsadc_count, regs_tsadc); if (rc) { pr_err("%s: regulator %sable failed: %d\n", __func__, vreg_on ? "en" : "dis", rc); goto regulator_switch_fail; } break; default: pr_err("%s:Adie %d not supported\n", __func__, tsadc_adie_type); return -ENODEV; } msleep(5); /* ensure power is stable */ return 0; regulator_switch_fail: pmapp_clock_vote(tsadc_id, PMAPP_CLOCK_ID_DO, vreg_on ? PMAPP_CLOCK_VOTE_OFF : PMAPP_CLOCK_VOTE_ON); D0_vote_fail: if (tsadc_adie_type == TIMPANI_ID) pmapp_clock_vote(tsadc_id, PMAPP_CLOCK_ID_D1, vreg_on ? PMAPP_CLOCK_VOTE_OFF : PMAPP_CLOCK_VOTE_ON); D1_vote_fail: return rc; } static int marimba_tsadc_init(void) { int rc = 0; int tsadc_adie_type = adie_get_detected_codec_type(); switch (tsadc_adie_type) { case MARIMBA_ID: regs_tsadc = regs_tsadc_marimba; regs_tsadc_count = ARRAY_SIZE(regs_tsadc_marimba); break; case TIMPANI_ID: regs_tsadc = regs_tsadc_timpani; regs_tsadc_count = ARRAY_SIZE(regs_tsadc_timpani); break; default: pr_err("%s:Adie %d not supported\n", __func__, tsadc_adie_type); rc = -ENODEV; goto out; } rc = regulator_bulk_get(NULL, regs_tsadc_count, regs_tsadc); if (rc) { pr_err("%s: could not get regulators: %d\n", __func__, rc); goto out; } rc = regulator_bulk_set_voltage(regs_tsadc_count, regs_tsadc); if (rc) { pr_err("%s: could not set regulator voltages: %d\n", __func__, rc); goto vreg_free; } return 0; vreg_free: regulator_bulk_free(regs_tsadc_count, regs_tsadc); out: regs_tsadc = NULL; regs_tsadc_count = 0; return rc; } static int marimba_tsadc_exit(void) { regulator_bulk_free(regs_tsadc_count, regs_tsadc); regs_tsadc_count = 0; regs_tsadc = NULL; return 0; } static struct msm_ts_platform_data msm_ts_data = { .min_x = 284, .max_x = 3801, .min_y = 155, .max_y = 3929, .min_press = 0, .max_press = 255, .inv_x = 4096, .inv_y = 4096, .can_wakeup = false, }; static struct marimba_tsadc_platform_data marimba_tsadc_pdata = { .marimba_tsadc_power = marimba_tsadc_power, .init = marimba_tsadc_init, .exit = marimba_tsadc_exit, .tsadc_prechg_en = true, .can_wakeup = false, .setup = { .pen_irq_en = true, .tsadc_en = true, }, .params2 = { .input_clk_khz = 2400, .sample_prd = TSADC_CLK_3, }, .params3 = { .prechg_time_nsecs = 6400, .stable_time_nsecs = 6400, .tsadc_test_mode = 0, }, .tssc_data = &msm_ts_data, }; static struct regulator_bulk_data codec_regs[] = { { .supply = "s4", .min_uV = 2200000, .max_uV = 2200000 }, }; static int __init msm_marimba_codec_init(void) { int rc = regulator_bulk_get(NULL, ARRAY_SIZE(codec_regs), codec_regs); if (rc) { pr_err("%s: could not get regulators: %d\n", __func__, rc); goto out; } rc = regulator_bulk_set_voltage(ARRAY_SIZE(codec_regs), codec_regs); if (rc) { pr_err("%s: could not set regulator voltages: %d\n", __func__, rc); goto reg_free; } return rc; reg_free: regulator_bulk_free(ARRAY_SIZE(codec_regs), codec_regs); out: return rc; } static int msm_marimba_codec_power(int vreg_on) { int rc = vreg_on ? regulator_bulk_enable(ARRAY_SIZE(codec_regs), codec_regs) : regulator_bulk_disable(ARRAY_SIZE(codec_regs), codec_regs); if (rc) { pr_err("%s: could not %sable regulators: %d", __func__, vreg_on ? "en" : "dis", rc); return rc; } return 0; } static struct marimba_codec_platform_data mariba_codec_pdata = { .marimba_codec_power = msm_marimba_codec_power, #ifdef CONFIG_MARIMBA_CODEC .snddev_profile_init = msm_snddev_init, #endif }; static struct marimba_platform_data marimba_pdata = { .slave_id[MARIMBA_SLAVE_ID_FM] = MARIMBA_SLAVE_ID_FM_ADDR, .slave_id[MARIMBA_SLAVE_ID_CDC] = MARIMBA_SLAVE_ID_CDC_ADDR, .slave_id[MARIMBA_SLAVE_ID_QMEMBIST] = MARIMBA_SLAVE_ID_QMEMBIST_ADDR, .slave_id[SLAVE_ID_BAHAMA_FM] = BAHAMA_SLAVE_ID_FM_ADDR, .slave_id[SLAVE_ID_BAHAMA_QMEMBIST] = BAHAMA_SLAVE_ID_QMEMBIST_ADDR, .marimba_setup = msm_marimba_setup_power, .marimba_shutdown = msm_marimba_shutdown_power, .bahama_setup = msm_bahama_setup_power, .bahama_shutdown = msm_bahama_shutdown_power, .marimba_gpio_config = msm_marimba_gpio_config_svlte, .bahama_core_config = msm_bahama_core_config, .fm = &marimba_fm_pdata, .codec = &mariba_codec_pdata, .tsadc_ssbi_adap = MARIMBA_SSBI_ADAP, }; static void __init msm7x30_init_marimba(void) { int rc; struct regulator_bulk_data regs[] = { { .supply = "s3", .min_uV = 1800000, .max_uV = 1800000 }, { .supply = "gp16", .min_uV = 1200000, .max_uV = 1200000 }, { .supply = "usb2", .min_uV = 1800000, .max_uV = 1800000 }, }; rc = msm_marimba_codec_init(); if (rc) { pr_err("%s: msm_marimba_codec_init failed (%d)\n", __func__, rc); return; } rc = regulator_bulk_get(NULL, ARRAY_SIZE(regs), regs); if (rc) { pr_err("%s: could not get regulators: %d\n", __func__, rc); return; } rc = regulator_bulk_set_voltage(ARRAY_SIZE(regs), regs); if (rc) { pr_err("%s: could not set voltages: %d\n", __func__, rc); regulator_bulk_free(ARRAY_SIZE(regs), regs); return; } vreg_marimba_1 = regs[0].consumer; vreg_marimba_2 = regs[1].consumer; vreg_bahama = regs[2].consumer; } static struct marimba_codec_platform_data timpani_codec_pdata = { .marimba_codec_power = msm_marimba_codec_power, #ifdef CONFIG_TIMPANI_CODEC .snddev_profile_init = msm_snddev_init_timpani, #endif }; static struct marimba_platform_data timpani_pdata = { .slave_id[MARIMBA_SLAVE_ID_CDC] = MARIMBA_SLAVE_ID_CDC_ADDR, .slave_id[MARIMBA_SLAVE_ID_QMEMBIST] = MARIMBA_SLAVE_ID_QMEMBIST_ADDR, .marimba_setup = msm_timpani_setup_power, .marimba_shutdown = msm_timpani_shutdown_power, .codec = &timpani_codec_pdata, .tsadc = &marimba_tsadc_pdata, .tsadc_ssbi_adap = MARIMBA_SSBI_ADAP, }; #define TIMPANI_I2C_SLAVE_ADDR 0xD static struct i2c_board_info msm_i2c_gsbi7_timpani_info[] = { { I2C_BOARD_INFO("timpani", TIMPANI_I2C_SLAVE_ADDR), .platform_data = &timpani_pdata, }, }; #ifdef CONFIG_MSM7KV2_AUDIO static struct resource msm_aictl_resources[] = { { .name = "aictl", .start = 0xa5000100, .end = 0xa5000100, .flags = IORESOURCE_MEM, } }; static struct resource msm_mi2s_resources[] = { { .name = "hdmi", .start = 0xac900000, .end = 0xac900038, .flags = IORESOURCE_MEM, }, { .name = "codec_rx", .start = 0xac940040, .end = 0xac940078, .flags = IORESOURCE_MEM, }, { .name = "codec_tx", .start = 0xac980080, .end = 0xac9800B8, .flags = IORESOURCE_MEM, } }; static struct msm_lpa_platform_data lpa_pdata = { .obuf_hlb_size = 0x2BFF8, .dsp_proc_id = 0, .app_proc_id = 2, .nosb_config = { .llb_min_addr = 0, .llb_max_addr = 0x3ff8, .sb_min_addr = 0, .sb_max_addr = 0, }, .sb_config = { .llb_min_addr = 0, .llb_max_addr = 0x37f8, .sb_min_addr = 0x3800, .sb_max_addr = 0x3ff8, } }; static struct resource msm_lpa_resources[] = { { .name = "lpa", .start = 0xa5000000, .end = 0xa50000a0, .flags = IORESOURCE_MEM, } }; static struct resource msm_aux_pcm_resources[] = { { .name = "aux_codec_reg_addr", .start = 0xac9c00c0, .end = 0xac9c00c8, .flags = IORESOURCE_MEM, }, { .name = "aux_pcm_dout", .start = 138, .end = 138, .flags = IORESOURCE_IO, }, { .name = "aux_pcm_din", .start = 139, .end = 139, .flags = IORESOURCE_IO, }, { .name = "aux_pcm_syncout", .start = 140, .end = 140, .flags = IORESOURCE_IO, }, { .name = "aux_pcm_clkin_a", .start = 141, .end = 141, .flags = IORESOURCE_IO, }, }; static struct platform_device msm_aux_pcm_device = { .name = "msm_aux_pcm", .id = 0, .num_resources = ARRAY_SIZE(msm_aux_pcm_resources), .resource = msm_aux_pcm_resources, }; struct platform_device msm_aictl_device = { .name = "audio_interct", .id = 0, .num_resources = ARRAY_SIZE(msm_aictl_resources), .resource = msm_aictl_resources, }; struct platform_device msm_mi2s_device = { .name = "mi2s", .id = 0, .num_resources = ARRAY_SIZE(msm_mi2s_resources), .resource = msm_mi2s_resources, }; struct platform_device msm_lpa_device = { .name = "lpa", .id = 0, .num_resources = ARRAY_SIZE(msm_lpa_resources), .resource = msm_lpa_resources, .dev = { .platform_data = &lpa_pdata, }, }; #endif /* CONFIG_MSM7KV2_AUDIO */ #define DEC0_FORMAT ((1<> 12; qsd_spi_resources[4].start = DMOV_USB_CHAN; qsd_spi_resources[4].end = DMOV_TSIF_CHAN; switch (spi_mux) { case (1): qsd_spi_resources[5].start = DMOV_HSUART1_RX_CRCI; qsd_spi_resources[5].end = DMOV_HSUART1_TX_CRCI; break; case (2): qsd_spi_resources[5].start = DMOV_HSUART2_RX_CRCI; qsd_spi_resources[5].end = DMOV_HSUART2_TX_CRCI; break; case (3): qsd_spi_resources[5].start = DMOV_CE_OUT_CRCI; qsd_spi_resources[5].end = DMOV_CE_IN_CRCI; break; default: ret = -ENOENT; } iounmap(ct_adm_base); return ret; } static struct platform_device qsd_device_spi = { .name = "spi_qsd", .id = 0, .num_resources = ARRAY_SIZE(qsd_spi_resources), .resource = qsd_spi_resources, }; #ifdef CONFIG_SPI_QSD static struct spi_board_info lcdc_sharp_spi_board_info[] __initdata = { { .modalias = "lcdc_sharp_ls038y7dx01", .mode = SPI_MODE_1, .bus_num = 0, .chip_select = 0, .max_speed_hz = 26331429, } }; static struct spi_board_info lcdc_toshiba_spi_board_info[] __initdata = { { .modalias = "lcdc_toshiba_ltm030dd40", .mode = SPI_MODE_3|SPI_CS_HIGH, .bus_num = 0, .chip_select = 0, .max_speed_hz = 9963243, } }; #endif static struct msm_gpio qsd_spi_gpio_config_data[] = { { GPIO_CFG(45, 1, GPIO_CFG_INPUT, GPIO_CFG_NO_PULL, GPIO_CFG_2MA), "spi_clk" }, { GPIO_CFG(46, 1, GPIO_CFG_INPUT, GPIO_CFG_NO_PULL, GPIO_CFG_2MA), "spi_cs0" }, { GPIO_CFG(47, 1, GPIO_CFG_INPUT, GPIO_CFG_NO_PULL, GPIO_CFG_8MA), "spi_mosi" }, { GPIO_CFG(48, 1, GPIO_CFG_INPUT, GPIO_CFG_NO_PULL, GPIO_CFG_2MA), "spi_miso" }, }; static int msm_qsd_spi_gpio_config(void) { return msm_gpios_request_enable(qsd_spi_gpio_config_data, ARRAY_SIZE(qsd_spi_gpio_config_data)); } static void msm_qsd_spi_gpio_release(void) { msm_gpios_disable_free(qsd_spi_gpio_config_data, ARRAY_SIZE(qsd_spi_gpio_config_data)); } static struct msm_spi_platform_data qsd_spi_pdata = { .max_clock_speed = 26331429, .gpio_config = msm_qsd_spi_gpio_config, .gpio_release = msm_qsd_spi_gpio_release, .dma_config = msm_qsd_spi_dma_config, }; static void __init msm_qsd_spi_init(void) { qsd_device_spi.dev.platform_data = &qsd_spi_pdata; } #ifdef CONFIG_USB_EHCI_MSM_72K static void msm_hsusb_vbus_power(unsigned phy_info, int on) { int rc; static int vbus_is_on; struct pm8xxx_gpio_init_info usb_vbus = { PM8058_GPIO_PM_TO_SYS(36), { .direction = PM_GPIO_DIR_OUT, .pull = PM_GPIO_PULL_NO, .output_buffer = PM_GPIO_OUT_BUF_CMOS, .output_value = 1, .vin_sel = 2, .out_strength = PM_GPIO_STRENGTH_MED, .function = PM_GPIO_FUNC_NORMAL, .inv_int_pol = 0, }, }; /* If VBUS is already on (or off), do nothing. */ if (unlikely(on == vbus_is_on)) return; if (on) { rc = pm8xxx_gpio_config(usb_vbus.gpio, &usb_vbus.config); if (rc) { pr_err("%s PMIC GPIO 36 write failed\n", __func__); return; } } else { gpio_set_value_cansleep(PM8058_GPIO_PM_TO_SYS(36), 0); } vbus_is_on = on; } static struct msm_usb_host_platform_data msm_usb_host_pdata = { .phy_info = (USB_PHY_INTEGRATED | USB_PHY_MODEL_45NM), .vbus_power = msm_hsusb_vbus_power, .power_budget = 180, }; #endif #ifdef CONFIG_USB_MSM_OTG_72K static int hsusb_rpc_connect(int connect) { if (connect) return msm_hsusb_rpc_connect(); else return msm_hsusb_rpc_close(); } #endif #ifdef CONFIG_USB_MSM_OTG_72K static struct regulator *vreg_3p3; static int msm_hsusb_ldo_init(int init) { uint32_t version = 0; int def_vol = 3400000; version = socinfo_get_version(); if (SOCINFO_VERSION_MAJOR(version) >= 2 && SOCINFO_VERSION_MINOR(version) >= 1) { def_vol = 3075000; pr_debug("%s: default voltage:%d\n", __func__, def_vol); } if (init) { vreg_3p3 = regulator_get(NULL, "usb"); if (IS_ERR(vreg_3p3)) return PTR_ERR(vreg_3p3); regulator_set_voltage(vreg_3p3, def_vol, def_vol); } else regulator_put(vreg_3p3); return 0; } static int msm_hsusb_ldo_enable(int enable) { static int ldo_status; if (!vreg_3p3 || IS_ERR(vreg_3p3)) return -ENODEV; if (ldo_status == enable) return 0; ldo_status = enable; if (enable) return regulator_enable(vreg_3p3); else return regulator_disable(vreg_3p3); } static int msm_hsusb_ldo_set_voltage(int mV) { static int cur_voltage; if (!vreg_3p3 || IS_ERR(vreg_3p3)) return -ENODEV; if (cur_voltage == mV) return 0; cur_voltage = mV; pr_debug("%s: (%d)\n", __func__, mV); return regulator_set_voltage(vreg_3p3, mV*1000, mV*1000); } #endif #ifndef CONFIG_USB_EHCI_MSM_72K static int msm_hsusb_pmic_notif_init(void (*callback)(int online), int init); #endif static struct msm_otg_platform_data msm_otg_pdata = { .rpc_connect = hsusb_rpc_connect, #ifndef CONFIG_USB_EHCI_MSM_72K .pmic_vbus_notif_init = msm_hsusb_pmic_notif_init, #else .vbus_power = msm_hsusb_vbus_power, #endif .pemp_level = PRE_EMPHASIS_WITH_20_PERCENT, .cdr_autoreset = CDR_AUTO_RESET_DISABLE, .drv_ampl = HS_DRV_AMPLITUDE_DEFAULT, .se1_gating = SE1_GATING_DISABLE, .chg_vbus_draw = hsusb_chg_vbus_draw, .chg_connected = hsusb_chg_connected, .chg_init = hsusb_chg_init, .ldo_enable = msm_hsusb_ldo_enable, .ldo_init = msm_hsusb_ldo_init, .ldo_set_voltage = msm_hsusb_ldo_set_voltage, }; #ifdef CONFIG_USB_GADGET static struct msm_hsusb_gadget_platform_data msm_gadget_pdata = { .is_phy_status_timer_on = 1, }; #endif #ifndef CONFIG_USB_EHCI_MSM_72K typedef void (*notify_vbus_state) (int); notify_vbus_state notify_vbus_state_func_ptr; int vbus_on_irq; static irqreturn_t pmic_vbus_on_irq(int irq, void *data) { pr_info("%s: vbus notification from pmic\n", __func__); (*notify_vbus_state_func_ptr) (1); return IRQ_HANDLED; } static int msm_hsusb_pmic_notif_init(void (*callback)(int online), int init) { int ret; if (init) { if (!callback) return -ENODEV; notify_vbus_state_func_ptr = callback; vbus_on_irq = platform_get_irq_byname(&msm_device_otg, "vbus_on"); if (vbus_on_irq <= 0) { pr_err("%s: unable to get vbus on irq\n", __func__); return -ENODEV; } ret = request_any_context_irq(vbus_on_irq, pmic_vbus_on_irq, IRQF_TRIGGER_RISING, "msm_otg_vbus_on", NULL); if (ret < 0) { pr_info("%s: request_irq for vbus_on" "interrupt failed\n", __func__); return ret; } msm_otg_pdata.pmic_vbus_irq = vbus_on_irq; return 0; } else { free_irq(vbus_on_irq, 0); notify_vbus_state_func_ptr = NULL; return 0; } } #endif #ifndef CONFIG_SPI_QSD static int lcdc_gpio_array_num[] = { 45, /* spi_clk */ 46, /* spi_cs */ 47, /* spi_mosi */ 48, /* spi_miso */ }; static struct msm_gpio lcdc_gpio_config_data[] = { { GPIO_CFG(45, 0, GPIO_CFG_OUTPUT, GPIO_CFG_NO_PULL, GPIO_CFG_2MA), "spi_clk" }, { GPIO_CFG(46, 0, GPIO_CFG_OUTPUT, GPIO_CFG_NO_PULL, GPIO_CFG_2MA), "spi_cs0" }, { GPIO_CFG(47, 0, GPIO_CFG_OUTPUT, GPIO_CFG_NO_PULL, GPIO_CFG_2MA), "spi_mosi" }, { GPIO_CFG(48, 0, GPIO_CFG_INPUT, GPIO_CFG_NO_PULL, GPIO_CFG_2MA), "spi_miso" }, }; static void lcdc_config_gpios(int enable) { if (enable) { msm_gpios_request_enable(lcdc_gpio_config_data, ARRAY_SIZE( lcdc_gpio_config_data)); } else msm_gpios_disable_free(lcdc_gpio_config_data, ARRAY_SIZE( lcdc_gpio_config_data)); } #endif static struct msm_panel_common_pdata lcdc_sharp_panel_data = { #ifndef CONFIG_SPI_QSD .panel_config_gpio = lcdc_config_gpios, .gpio_num = lcdc_gpio_array_num, #endif .gpio = 2, /* LPG PMIC_GPIO26 channel number */ }; static struct platform_device lcdc_sharp_panel_device = { .name = "lcdc_sharp_wvga", .id = 0, .dev = { .platform_data = &lcdc_sharp_panel_data, } }; static struct msm_gpio dtv_panel_irq_gpios[] = { { GPIO_CFG(18, 0, GPIO_CFG_INPUT, GPIO_CFG_NO_PULL, GPIO_CFG_4MA), "hdmi_int" }, }; static struct msm_gpio dtv_panel_gpios[] = { { GPIO_CFG(120, 1, GPIO_CFG_OUTPUT, GPIO_CFG_NO_PULL, GPIO_CFG_4MA), "wca_mclk" }, { GPIO_CFG(121, 1, GPIO_CFG_OUTPUT, GPIO_CFG_NO_PULL, GPIO_CFG_4MA), "wca_sd0" }, { GPIO_CFG(122, 1, GPIO_CFG_OUTPUT, GPIO_CFG_NO_PULL, GPIO_CFG_4MA), "wca_sd1" }, { GPIO_CFG(123, 1, GPIO_CFG_OUTPUT, GPIO_CFG_NO_PULL, GPIO_CFG_4MA), "wca_sd2" }, { GPIO_CFG(124, 1, GPIO_CFG_OUTPUT, GPIO_CFG_NO_PULL, GPIO_CFG_8MA), "dtv_pclk" }, { GPIO_CFG(125, 1, GPIO_CFG_OUTPUT, GPIO_CFG_NO_PULL, GPIO_CFG_4MA), "dtv_en" }, { GPIO_CFG(126, 1, GPIO_CFG_OUTPUT, GPIO_CFG_NO_PULL, GPIO_CFG_4MA), "dtv_vsync" }, { GPIO_CFG(127, 1, GPIO_CFG_OUTPUT, GPIO_CFG_NO_PULL, GPIO_CFG_4MA), "dtv_hsync" }, { GPIO_CFG(128, 1, GPIO_CFG_OUTPUT, GPIO_CFG_NO_PULL, GPIO_CFG_4MA), "dtv_data0" }, { GPIO_CFG(129, 1, GPIO_CFG_OUTPUT, GPIO_CFG_NO_PULL, GPIO_CFG_4MA), "dtv_data1" }, { GPIO_CFG(130, 1, GPIO_CFG_OUTPUT, GPIO_CFG_NO_PULL, GPIO_CFG_4MA), "dtv_data2" }, { GPIO_CFG(131, 1, GPIO_CFG_OUTPUT, GPIO_CFG_NO_PULL, GPIO_CFG_4MA), "dtv_data3" }, { GPIO_CFG(132, 1, GPIO_CFG_OUTPUT, GPIO_CFG_NO_PULL, GPIO_CFG_4MA), "dtv_data4" }, { GPIO_CFG(160, 1, GPIO_CFG_OUTPUT, GPIO_CFG_NO_PULL, GPIO_CFG_4MA), "dtv_data5" }, { GPIO_CFG(161, 1, GPIO_CFG_OUTPUT, GPIO_CFG_NO_PULL, GPIO_CFG_4MA), "dtv_data6" }, { GPIO_CFG(162, 1, GPIO_CFG_OUTPUT, GPIO_CFG_NO_PULL, GPIO_CFG_4MA), "dtv_data7" }, { GPIO_CFG(163, 1, GPIO_CFG_OUTPUT, GPIO_CFG_NO_PULL, GPIO_CFG_4MA), "dtv_data8" }, { GPIO_CFG(164, 1, GPIO_CFG_OUTPUT, GPIO_CFG_NO_PULL, GPIO_CFG_4MA), "dtv_data9" }, { GPIO_CFG(165, 1, GPIO_CFG_OUTPUT, GPIO_CFG_NO_PULL, GPIO_CFG_4MA), "dtv_dat10" }, { GPIO_CFG(166, 1, GPIO_CFG_OUTPUT, GPIO_CFG_NO_PULL, GPIO_CFG_4MA), "dtv_dat11" }, { GPIO_CFG(167, 1, GPIO_CFG_OUTPUT, GPIO_CFG_NO_PULL, GPIO_CFG_4MA), "dtv_dat12" }, { GPIO_CFG(168, 1, GPIO_CFG_OUTPUT, GPIO_CFG_NO_PULL, GPIO_CFG_4MA), "dtv_dat13" }, { GPIO_CFG(169, 1, GPIO_CFG_OUTPUT, GPIO_CFG_NO_PULL, GPIO_CFG_4MA), "dtv_dat14" }, { GPIO_CFG(170, 1, GPIO_CFG_OUTPUT, GPIO_CFG_NO_PULL, GPIO_CFG_4MA), "dtv_dat15" }, { GPIO_CFG(171, 1, GPIO_CFG_OUTPUT, GPIO_CFG_NO_PULL, GPIO_CFG_4MA), "dtv_dat16" }, { GPIO_CFG(172, 1, GPIO_CFG_OUTPUT, GPIO_CFG_NO_PULL, GPIO_CFG_4MA), "dtv_dat17" }, { GPIO_CFG(173, 1, GPIO_CFG_OUTPUT, GPIO_CFG_NO_PULL, GPIO_CFG_4MA), "dtv_dat18" }, { GPIO_CFG(174, 1, GPIO_CFG_OUTPUT, GPIO_CFG_NO_PULL, GPIO_CFG_4MA), "dtv_dat19" }, { GPIO_CFG(175, 1, GPIO_CFG_OUTPUT, GPIO_CFG_NO_PULL, GPIO_CFG_4MA), "dtv_dat20" }, { GPIO_CFG(176, 1, GPIO_CFG_OUTPUT, GPIO_CFG_NO_PULL, GPIO_CFG_4MA), "dtv_dat21" }, { GPIO_CFG(177, 1, GPIO_CFG_OUTPUT, GPIO_CFG_NO_PULL, GPIO_CFG_4MA), "dtv_dat22" }, { GPIO_CFG(178, 1, GPIO_CFG_OUTPUT, GPIO_CFG_NO_PULL, GPIO_CFG_4MA), "dtv_dat23" }, }; #ifdef HDMI_RESET static unsigned dtv_reset_gpio = GPIO_CFG(37, 0, GPIO_CFG_OUTPUT, GPIO_CFG_NO_PULL, GPIO_CFG_2MA); #endif static struct regulator_bulk_data hdmi_core_regs[] = { { .supply = "ldo8", .min_uV = 1800000, .max_uV = 1800000 }, }; static struct regulator_bulk_data hdmi_comm_regs[] = { { .supply = "ldo8", .min_uV = 1800000, .max_uV = 1800000 }, { .supply = "ldo10", .min_uV = 2600000, .max_uV = 2600000 }, }; static struct regulator_bulk_data hdmi_cec_regs[] = { { .supply = "ldo17", .min_uV = 2600000, .max_uV = 2600000 }, }; static int __init hdmi_init_regs(void) { int rc; rc = regulator_bulk_get(NULL, ARRAY_SIZE(hdmi_core_regs), hdmi_core_regs); if (rc) { pr_err("%s: could not get %s regulators: %d\n", __func__, "core", rc); goto out; } rc = regulator_bulk_set_voltage(ARRAY_SIZE(hdmi_core_regs), hdmi_core_regs); if (rc) { pr_err("%s: could not set %s voltages: %d\n", __func__, "core", rc); goto free_core; } rc = regulator_bulk_get(NULL, ARRAY_SIZE(hdmi_comm_regs), hdmi_comm_regs); if (rc) { pr_err("%s: could not get %s regulators: %d\n", __func__, "comm", rc); goto free_core; } rc = regulator_bulk_set_voltage(ARRAY_SIZE(hdmi_comm_regs), hdmi_comm_regs); if (rc) { pr_err("%s: could not set %s voltages: %d\n", __func__, "comm", rc); goto free_comm; } rc = regulator_bulk_get(NULL, ARRAY_SIZE(hdmi_cec_regs), hdmi_cec_regs); if (rc) { pr_err("%s: could not get %s regulators: %d\n", __func__, "cec", rc); goto free_comm; } rc = regulator_bulk_set_voltage(ARRAY_SIZE(hdmi_cec_regs), hdmi_cec_regs); if (rc) { pr_err("%s: could not set %s voltages: %d\n", __func__, "cec", rc); goto free_cec; } return 0; free_cec: regulator_bulk_free(ARRAY_SIZE(hdmi_cec_regs), hdmi_cec_regs); free_comm: regulator_bulk_free(ARRAY_SIZE(hdmi_comm_regs), hdmi_comm_regs); free_core: regulator_bulk_free(ARRAY_SIZE(hdmi_core_regs), hdmi_core_regs); out: return rc; } static int hdmi_init_irq(void) { int rc = msm_gpios_enable(dtv_panel_irq_gpios, ARRAY_SIZE(dtv_panel_irq_gpios)); if (rc < 0) { pr_err("%s: gpio enable failed: %d\n", __func__, rc); return rc; } pr_info("%s\n", __func__); return 0; } static int hdmi_enable_5v(int on) { int pmic_gpio_hdmi_5v_en ; if (machine_is_msm8x55_svlte_surf() || machine_is_msm8x55_svlte_ffa() || machine_is_msm7x30_fluid()) pmic_gpio_hdmi_5v_en = PMIC_GPIO_HDMI_5V_EN_V2 ; else pmic_gpio_hdmi_5v_en = PMIC_GPIO_HDMI_5V_EN_V3 ; pr_info("%s: %d\n", __func__, on); if (on) { int rc; rc = gpio_request(PM8058_GPIO_PM_TO_SYS(pmic_gpio_hdmi_5v_en), "hdmi_5V_en"); if (rc) { pr_err("%s PMIC_GPIO_HDMI_5V_EN gpio_request failed\n", __func__); return rc; } gpio_set_value_cansleep( PM8058_GPIO_PM_TO_SYS(pmic_gpio_hdmi_5v_en), 1); } else { gpio_set_value_cansleep( PM8058_GPIO_PM_TO_SYS(pmic_gpio_hdmi_5v_en), 0); gpio_free(PM8058_GPIO_PM_TO_SYS(pmic_gpio_hdmi_5v_en)); } return 0; } static int hdmi_comm_power(int on, int show) { if (show) pr_info("%s: i2c comm: %d \n", __func__, on); return on ? regulator_bulk_enable(ARRAY_SIZE(hdmi_comm_regs), hdmi_comm_regs) : regulator_bulk_disable(ARRAY_SIZE(hdmi_comm_regs), hdmi_comm_regs); } static int hdmi_core_power(int on, int show) { if (show) pr_info("%s: %d \n", __func__, on); return on ? regulator_bulk_enable(ARRAY_SIZE(hdmi_core_regs), hdmi_core_regs) : regulator_bulk_disable(ARRAY_SIZE(hdmi_core_regs), hdmi_core_regs); } static int hdmi_cec_power(int on) { pr_info("%s: %d \n", __func__, on); return on ? regulator_bulk_enable(ARRAY_SIZE(hdmi_cec_regs), hdmi_cec_regs) : regulator_bulk_disable(ARRAY_SIZE(hdmi_cec_regs), hdmi_cec_regs); } #if defined(CONFIG_FB_MSM_HDMI_ADV7520_PANEL) || defined(CONFIG_BOSCH_BMA150) /* there is an i2c address conflict between adv7520 and bma150 sensor after * power up on fluid. As a solution, the default address of adv7520's packet * memory is changed as soon as possible */ static int __init fluid_i2c_address_fixup(void) { unsigned char wBuff[16]; unsigned char rBuff[16]; struct i2c_msg msgs[3]; int res; int rc = -EINVAL; struct i2c_adapter *adapter; if (machine_is_msm7x30_fluid()) { adapter = i2c_get_adapter(0); if (!adapter) { pr_err("%s: invalid i2c adapter\n", __func__); return PTR_ERR(adapter); } /* turn on LDO8 */ rc = hdmi_core_power(1, 0); if (rc) { pr_err("%s: could not enable hdmi core regs: %d", __func__, rc); goto adapter_put; } /* change packet memory address to 0x74 */ wBuff[0] = 0x45; wBuff[1] = 0x74; msgs[0].addr = ADV7520_I2C_ADDR; msgs[0].flags = 0; msgs[0].buf = (unsigned char *) wBuff; msgs[0].len = 2; res = i2c_transfer(adapter, msgs, 1); if (res != 1) { pr_err("%s: error writing adv7520\n", __func__); goto ldo8_disable; } /* powerdown adv7520 using bit 6 */ /* i2c read first */ wBuff[0] = 0x41; msgs[0].addr = ADV7520_I2C_ADDR; msgs[0].flags = 0; msgs[0].buf = (unsigned char *) wBuff; msgs[0].len = 1; msgs[1].addr = ADV7520_I2C_ADDR; msgs[1].flags = I2C_M_RD; msgs[1].buf = rBuff; msgs[1].len = 1; res = i2c_transfer(adapter, msgs, 2); if (res != 2) { pr_err("%s: error reading adv7520\n", __func__); goto ldo8_disable; } /* i2c write back */ wBuff[0] = 0x41; wBuff[1] = rBuff[0] | 0x40; msgs[0].addr = ADV7520_I2C_ADDR; msgs[0].flags = 0; msgs[0].buf = (unsigned char *) wBuff; msgs[0].len = 2; res = i2c_transfer(adapter, msgs, 1); if (res != 1) { pr_err("%s: error writing adv7520\n", __func__); goto ldo8_disable; } /* for successful fixup, we release the i2c adapter */ /* but leave ldo8 on so that the adv7520 is not repowered */ i2c_put_adapter(adapter); pr_info("%s: fluid i2c address conflict resolved\n", __func__); } return 0; ldo8_disable: hdmi_core_power(0, 0); adapter_put: i2c_put_adapter(adapter); return rc; } fs_initcall_sync(fluid_i2c_address_fixup); #endif static bool hdmi_check_hdcp_hw_support(void) { if (machine_is_msm7x30_fluid()) return false; else return true; } static int dtv_panel_power(int on) { int flag_on = !!on; static int dtv_power_save_on; int rc; if (dtv_power_save_on == flag_on) return 0; dtv_power_save_on = flag_on; pr_info("%s: %d\n", __func__, on); #ifdef HDMI_RESET if (on) { /* reset Toshiba WeGA chip -- toggle reset pin -- gpio_180 */ rc = gpio_tlmm_config(dtv_reset_gpio, GPIO_CFG_ENABLE); if (rc) { pr_err("%s: gpio_tlmm_config(%#x)=%d\n", __func__, dtv_reset_gpio, rc); return rc; } /* bring reset line low to hold reset*/ gpio_set_value(37, 0); } #endif if (on) { rc = msm_gpios_enable(dtv_panel_gpios, ARRAY_SIZE(dtv_panel_gpios)); if (rc < 0) { printk(KERN_ERR "%s: gpio enable failed: %d\n", __func__, rc); return rc; } } else { rc = msm_gpios_disable(dtv_panel_gpios, ARRAY_SIZE(dtv_panel_gpios)); if (rc < 0) { printk(KERN_ERR "%s: gpio disable failed: %d\n", __func__, rc); return rc; } } mdelay(5); /* ensure power is stable */ #ifdef HDMI_RESET if (on) { gpio_set_value(37, 1); /* bring reset line high */ mdelay(10); /* 10 msec before IO can be accessed */ } #endif return rc; } static struct lcdc_platform_data dtv_pdata = { .lcdc_power_save = dtv_panel_power, }; static struct msm_serial_hs_platform_data msm_uart_dm1_pdata = { .inject_rx_on_wakeup = 1, .rx_to_inject = 0xFD, }; static struct resource msm_fb_resources[] = { { .flags = IORESOURCE_DMA, } }; #ifdef CONFIG_MSM_V4L2_VIDEO_OVERLAY_DEVICE static struct resource msm_v4l2_video_overlay_resources[] = { { .flags = IORESOURCE_DMA, } }; #endif static int msm_fb_detect_panel(const char *name) { if (machine_is_msm7x30_fluid()) { if (!strcmp(name, "lcdc_sharp_wvga_pt")) return 0; } else { if (!strncmp(name, "mddi_toshiba_wvga_pt", 20)) return -EPERM; else if (!strncmp(name, "lcdc_toshiba_wvga_pt", 20)) return 0; else if (!strcmp(name, "mddi_orise")) return -EPERM; else if (!strcmp(name, "mddi_quickvx")) return -EPERM; } return -ENODEV; } static struct msm_fb_platform_data msm_fb_pdata = { .detect_client = msm_fb_detect_panel, .mddi_prescan = 1, }; static struct platform_device msm_fb_device = { .name = "msm_fb", .id = 0, .num_resources = ARRAY_SIZE(msm_fb_resources), .resource = msm_fb_resources, .dev = { .platform_data = &msm_fb_pdata, } }; #ifdef CONFIG_MSM_V4L2_VIDEO_OVERLAY_DEVICE static struct platform_device msm_v4l2_video_overlay_device = { .name = "msm_v4l2_overlay_pd", .id = 0, .num_resources = ARRAY_SIZE(msm_v4l2_video_overlay_resources), .resource = msm_v4l2_video_overlay_resources, }; #endif static struct platform_device msm_migrate_pages_device = { .name = "msm_migrate_pages", .id = -1, }; #if defined(CONFIG_CRYPTO_DEV_QCRYPTO) || \ defined(CONFIG_CRYPTO_DEV_QCRYPTO_MODULE) || \ defined(CONFIG_CRYPTO_DEV_QCEDEV) || \ defined(CONFIG_CRYPTO_DEV_QCEDEV_MODULE) #define QCE_SIZE 0x10000 #define QCE_0_BASE 0xA8400000 #define QCE_HW_KEY_SUPPORT 1 #define QCE_SHA_HMAC_SUPPORT 0 #define QCE_SHARE_CE_RESOURCE 0 #define QCE_CE_SHARED 0 static struct resource qcrypto_resources[] = { [0] = { .start = QCE_0_BASE, .end = QCE_0_BASE + QCE_SIZE - 1, .flags = IORESOURCE_MEM, }, [1] = { .name = "crypto_channels", .start = DMOV_CE_IN_CHAN, .end = DMOV_CE_OUT_CHAN, .flags = IORESOURCE_DMA, }, [2] = { .name = "crypto_crci_in", .start = DMOV_CE_IN_CRCI, .end = DMOV_CE_IN_CRCI, .flags = IORESOURCE_DMA, }, [3] = { .name = "crypto_crci_out", .start = DMOV_CE_OUT_CRCI, .end = DMOV_CE_OUT_CRCI, .flags = IORESOURCE_DMA, }, [4] = { .name = "crypto_crci_hash", .start = DMOV_CE_HASH_CRCI, .end = DMOV_CE_HASH_CRCI, .flags = IORESOURCE_DMA, }, }; static struct resource qcedev_resources[] = { [0] = { .start = QCE_0_BASE, .end = QCE_0_BASE + QCE_SIZE - 1, .flags = IORESOURCE_MEM, }, [1] = { .name = "crypto_channels", .start = DMOV_CE_IN_CHAN, .end = DMOV_CE_OUT_CHAN, .flags = IORESOURCE_DMA, }, [2] = { .name = "crypto_crci_in", .start = DMOV_CE_IN_CRCI, .end = DMOV_CE_IN_CRCI, .flags = IORESOURCE_DMA, }, [3] = { .name = "crypto_crci_out", .start = DMOV_CE_OUT_CRCI, .end = DMOV_CE_OUT_CRCI, .flags = IORESOURCE_DMA, }, [4] = { .name = "crypto_crci_hash", .start = DMOV_CE_HASH_CRCI, .end = DMOV_CE_HASH_CRCI, .flags = IORESOURCE_DMA, }, }; #endif #if defined(CONFIG_CRYPTO_DEV_QCRYPTO) || \ defined(CONFIG_CRYPTO_DEV_QCRYPTO_MODULE) static struct msm_ce_hw_support qcrypto_ce_hw_suppport = { .ce_shared = QCE_CE_SHARED, .shared_ce_resource = QCE_SHARE_CE_RESOURCE, .hw_key_support = QCE_HW_KEY_SUPPORT, .sha_hmac = QCE_SHA_HMAC_SUPPORT, /* Bus Scaling declaration*/ .bus_scale_table = NULL, }; static struct platform_device qcrypto_device = { .name = "qcrypto", .id = 0, .num_resources = ARRAY_SIZE(qcrypto_resources), .resource = qcrypto_resources, .dev = { .coherent_dma_mask = DMA_BIT_MASK(32), .platform_data = &qcrypto_ce_hw_suppport, }, }; #endif #if defined(CONFIG_CRYPTO_DEV_QCEDEV) || \ defined(CONFIG_CRYPTO_DEV_QCEDEV_MODULE) static struct msm_ce_hw_support qcedev_ce_hw_suppport = { .ce_shared = QCE_CE_SHARED, .shared_ce_resource = QCE_SHARE_CE_RESOURCE, .hw_key_support = QCE_HW_KEY_SUPPORT, .sha_hmac = QCE_SHA_HMAC_SUPPORT, /* Bus Scaling declaration*/ .bus_scale_table = NULL, }; static struct platform_device qcedev_device = { .name = "qce", .id = 0, .num_resources = ARRAY_SIZE(qcedev_resources), .resource = qcedev_resources, .dev = { .coherent_dma_mask = DMA_BIT_MASK(32), .platform_data = &qcedev_ce_hw_suppport, }, }; #endif static int mddi_toshiba_pmic_bl(int level) { int ret = -EPERM; ret = pmic_set_led_intensity(LED_LCD, level); if (ret) printk(KERN_WARNING "%s: can't set lcd backlight!\n", __func__); return ret; } static struct msm_panel_common_pdata mddi_toshiba_pdata = { .pmic_backlight = mddi_toshiba_pmic_bl, }; static struct platform_device mddi_toshiba_device = { .name = "mddi_toshiba", .id = 0, .dev = { .platform_data = &mddi_toshiba_pdata, } }; static unsigned wega_reset_gpio = GPIO_CFG(180, 0, GPIO_CFG_OUTPUT, GPIO_CFG_NO_PULL, GPIO_CFG_2MA); static struct msm_gpio fluid_vee_reset_gpio[] = { { GPIO_CFG(20, 0, GPIO_CFG_OUTPUT, GPIO_CFG_NO_PULL, GPIO_CFG_2MA), "vee_reset" }, }; static unsigned char quickvx_mddi_client = 1, other_mddi_client = 1; static unsigned char quickvx_ldo_enabled; static unsigned quickvx_vlp_gpio = GPIO_CFG(97, 0, GPIO_CFG_OUTPUT, GPIO_CFG_NO_PULL, GPIO_CFG_2MA); static struct pm8xxx_gpio_init_info pmic_quickvx_clk_gpio = { PM8058_GPIO_PM_TO_SYS(PMIC_GPIO_QUICKVX_CLK), { .direction = PM_GPIO_DIR_OUT, .output_buffer = PM_GPIO_OUT_BUF_CMOS, .output_value = 1, .pull = PM_GPIO_PULL_NO, .vin_sel = PM8058_GPIO_VIN_S3, .out_strength = PM_GPIO_STRENGTH_HIGH, .function = PM_GPIO_FUNC_2, }, }; static struct regulator *mddi_ldo20; static struct regulator *mddi_ldo12; static struct regulator *mddi_ldo16; static struct regulator *mddi_ldo6; static struct regulator *mddi_lcd; static int display_common_init(void) { struct regulator_bulk_data regs[5] = { { .supply = "ldo20", /* voltage set in display_common_power */}, { .supply = "ldo12", .min_uV = 1800000, .max_uV = 1800000 }, { .supply = "ldo6", .min_uV = 3075000, .max_uV = 3400000 }, { .supply = "ldo16", .min_uV = 2600000, .max_uV = 2600000 }, { .supply = NULL, /* mddi_lcd, initialized below */ }, }; int rc = 0; if (machine_is_msm7x30_fluid()) { /* lcd: LDO8 @1.8V */ regs[4].supply = "ldo8"; regs[4].min_uV = 1800000; regs[4].max_uV = 1800000; } else { /* lcd: LDO15 @3.1V */ regs[4].supply = "ldo15"; regs[4].min_uV = 3100000; regs[4].max_uV = 3100000; } rc = regulator_bulk_get(NULL, ARRAY_SIZE(regs), regs); if (rc) { pr_err("%s: regulator_bulk_get failed: %d\n", __func__, rc); goto bail; } rc = regulator_bulk_set_voltage(ARRAY_SIZE(regs), regs); if (rc) { pr_err("%s: regulator_bulk_set_voltage failed: %d\n", __func__, rc); goto put_regs; } mddi_ldo20 = regs[0].consumer; mddi_ldo12 = regs[1].consumer; mddi_ldo6 = regs[2].consumer; mddi_ldo16 = regs[3].consumer; mddi_lcd = regs[4].consumer; return rc; put_regs: regulator_bulk_free(ARRAY_SIZE(regs), regs); bail: return rc; } static int display_common_power(int on) { int rc = 0, flag_on = !!on; static int display_common_power_save_on; static bool display_regs_initialized; if (display_common_power_save_on == flag_on) return 0; display_common_power_save_on = flag_on; if (unlikely(!display_regs_initialized)) { rc = display_common_init(); if (rc) { pr_err("%s: regulator init failed: %d\n", __func__, rc); return rc; } display_regs_initialized = true; } if (on) { /* reset Toshiba WeGA chip -- toggle reset pin -- gpio_180 */ rc = gpio_tlmm_config(wega_reset_gpio, GPIO_CFG_ENABLE); if (rc) { pr_err("%s: gpio_tlmm_config(%#x)=%d\n", __func__, wega_reset_gpio, rc); return rc; } /* bring reset line low to hold reset*/ gpio_set_value(180, 0); if (quickvx_mddi_client) { /* QuickVX chip -- VLP pin -- gpio 97 */ rc = gpio_tlmm_config(quickvx_vlp_gpio, GPIO_CFG_ENABLE); if (rc) { pr_err("%s: gpio_tlmm_config(%#x)=%d\n", __func__, quickvx_vlp_gpio, rc); return rc; } /* bring QuickVX VLP line low */ gpio_set_value(97, 0); rc = pm8xxx_gpio_config(pmic_quickvx_clk_gpio.gpio, &pmic_quickvx_clk_gpio.config); if (rc) { pr_err("%s: pm8xxx_gpio_config(%#x)=%d\n", __func__, pmic_quickvx_clk_gpio.gpio, rc); return rc; } gpio_set_value_cansleep(PM8058_GPIO_PM_TO_SYS( PMIC_GPIO_QUICKVX_CLK), 0); } } if (quickvx_mddi_client) rc = regulator_set_voltage(mddi_ldo20, 1500000, 1800000); else rc = regulator_set_voltage(mddi_ldo20, 1500000, 1500000); if (rc) { pr_err("%s: could not set voltage for ldo20: %d\n", __func__, rc); return rc; } if (on) { rc = regulator_enable(mddi_ldo20); if (rc) { pr_err("%s: LDO20 regulator enable failed (%d)\n", __func__, rc); return rc; } rc = regulator_enable(mddi_ldo12); if (rc) { pr_err("%s: LDO12 regulator enable failed (%d)\n", __func__, rc); return rc; } if (other_mddi_client) { rc = regulator_enable(mddi_ldo16); if (rc) { pr_err("%s: LDO16 regulator enable failed (%d)\n", __func__, rc); return rc; } } if (quickvx_ldo_enabled) { /* Disable LDO6 during display ON */ rc = regulator_disable(mddi_ldo6); if (rc) { pr_err("%s: LDO6 regulator disable failed (%d)\n", __func__, rc); return rc; } quickvx_ldo_enabled = 0; } rc = regulator_enable(mddi_lcd); if (rc) { pr_err("%s: LCD regulator enable failed (%d)\n", __func__, rc); return rc; } mdelay(5); /* ensure power is stable */ if (machine_is_msm7x30_fluid()) { rc = msm_gpios_request_enable(fluid_vee_reset_gpio, ARRAY_SIZE(fluid_vee_reset_gpio)); if (rc) pr_err("%s gpio_request_enable failed rc=%d\n", __func__, rc); else { /* assert vee reset_n */ gpio_set_value(20, 1); gpio_set_value(20, 0); mdelay(1); gpio_set_value(20, 1); } } gpio_set_value(180, 1); /* bring reset line high */ mdelay(10); /* 10 msec before IO can be accessed */ if (quickvx_mddi_client) { gpio_set_value(97, 1); msleep(2); gpio_set_value_cansleep(PM8058_GPIO_PM_TO_SYS( PMIC_GPIO_QUICKVX_CLK), 1); msleep(2); } rc = pmapp_display_clock_config(1); if (rc) { pr_err("%s pmapp_display_clock_config rc=%d\n", __func__, rc); return rc; } } else { rc = regulator_disable(mddi_ldo20); if (rc) { pr_err("%s: LDO20 regulator disable failed (%d)\n", __func__, rc); return rc; } if (other_mddi_client) { rc = regulator_disable(mddi_ldo16); if (rc) { pr_err("%s: LDO16 regulator disable failed (%d)\n", __func__, rc); return rc; } } if (quickvx_mddi_client && !quickvx_ldo_enabled) { /* Enable LDO6 during display OFF for Quicklogic chip to sleep with data retention */ rc = regulator_enable(mddi_ldo6); if (rc) { pr_err("%s: LDO6 regulator enable failed (%d)\n", __func__, rc); return rc; } quickvx_ldo_enabled = 1; } gpio_set_value(180, 0); /* bring reset line low */ if (quickvx_mddi_client) { gpio_set_value(97, 0); gpio_set_value_cansleep(PM8058_GPIO_PM_TO_SYS( PMIC_GPIO_QUICKVX_CLK), 0); } rc = regulator_disable(mddi_lcd); if (rc) { pr_err("%s: LCD regulator disable failed (%d)\n", __func__, rc); return rc; } mdelay(5); /* ensure power is stable */ rc = regulator_disable(mddi_ldo12); if (rc) { pr_err("%s: LDO12 regulator disable failed (%d)\n", __func__, rc); return rc; } if (machine_is_msm7x30_fluid()) { msm_gpios_disable_free(fluid_vee_reset_gpio, ARRAY_SIZE(fluid_vee_reset_gpio)); } rc = pmapp_display_clock_config(0); if (rc) { pr_err("%s pmapp_display_clock_config rc=%d\n", __func__, rc); return rc; } } return rc; } static int msm_fb_mddi_sel_clk(u32 *clk_rate) { *clk_rate *= 2; return 0; } static int msm_fb_mddi_client_power(u32 client_id) { int rc; printk(KERN_NOTICE "\n client_id = 0x%x", client_id); /* Check if it is Quicklogic client */ if (client_id == 0xc5835800) { printk(KERN_NOTICE "\n Quicklogic MDDI client"); other_mddi_client = 0; if (IS_ERR(mddi_ldo16)) { rc = PTR_ERR(mddi_ldo16); pr_err("%s: gp10 vreg get failed (%d)\n", __func__, rc); return rc; } rc = regulator_disable(mddi_ldo16); if (rc) { pr_err("%s: LDO16 vreg enable failed (%d)\n", __func__, rc); return rc; } } else { printk(KERN_NOTICE "\n Non-Quicklogic MDDI client"); quickvx_mddi_client = 0; gpio_set_value(97, 0); gpio_set_value_cansleep(PM8058_GPIO_PM_TO_SYS( PMIC_GPIO_QUICKVX_CLK), 0); } return 0; } static struct mddi_platform_data mddi_pdata = { .mddi_power_save = display_common_power, .mddi_sel_clk = msm_fb_mddi_sel_clk, .mddi_client_power = msm_fb_mddi_client_power, }; static struct msm_panel_common_pdata mdp_pdata = { .hw_revision_addr = 0xac001270, .gpio = 30, .mdp_max_clk = 192000000, .mdp_rev = MDP_REV_40, .mem_hid = MEMTYPE_EBI0, }; static int lcd_panel_spi_gpio_num[] = { 45, /* spi_clk */ 46, /* spi_cs */ 47, /* spi_mosi */ 48, /* spi_miso */ }; static struct msm_gpio lcd_panel_gpios[] = { /* Workaround, since HDMI_INT is using the same GPIO line (18), and is used as * input. if there is a hardware revision; we should reassign this GPIO to a * new open line; and removing it will just ensure that this will be missed in * the future. { GPIO_CFG(18, 1, GPIO_CFG_OUTPUT, GPIO_CFG_NO_PULL, GPIO_CFG_2MA), "lcdc_grn0" }, */ { GPIO_CFG(19, 1, GPIO_CFG_OUTPUT, GPIO_CFG_NO_PULL, GPIO_CFG_2MA), "lcdc_grn1" }, { GPIO_CFG(20, 1, GPIO_CFG_OUTPUT, GPIO_CFG_NO_PULL, GPIO_CFG_2MA), "lcdc_blu0" }, { GPIO_CFG(21, 1, GPIO_CFG_OUTPUT, GPIO_CFG_NO_PULL, GPIO_CFG_2MA), "lcdc_blu1" }, { GPIO_CFG(22, 1, GPIO_CFG_OUTPUT, GPIO_CFG_NO_PULL, GPIO_CFG_2MA), "lcdc_blu2" }, { GPIO_CFG(23, 1, GPIO_CFG_OUTPUT, GPIO_CFG_NO_PULL, GPIO_CFG_2MA), "lcdc_red0" }, { GPIO_CFG(24, 1, GPIO_CFG_OUTPUT, GPIO_CFG_NO_PULL, GPIO_CFG_2MA), "lcdc_red1" }, { GPIO_CFG(25, 1, GPIO_CFG_OUTPUT, GPIO_CFG_NO_PULL, GPIO_CFG_2MA), "lcdc_red2" }, #ifndef CONFIG_SPI_QSD { GPIO_CFG(45, 0, GPIO_CFG_OUTPUT, GPIO_CFG_NO_PULL, GPIO_CFG_2MA), "spi_clk" }, { GPIO_CFG(46, 0, GPIO_CFG_OUTPUT, GPIO_CFG_NO_PULL, GPIO_CFG_2MA), "spi_cs0" }, { GPIO_CFG(47, 0, GPIO_CFG_OUTPUT, GPIO_CFG_NO_PULL, GPIO_CFG_2MA), "spi_mosi" }, { GPIO_CFG(48, 0, GPIO_CFG_INPUT, GPIO_CFG_NO_PULL, GPIO_CFG_2MA), "spi_miso" }, #endif { GPIO_CFG(90, 1, GPIO_CFG_OUTPUT, GPIO_CFG_NO_PULL, GPIO_CFG_2MA), "lcdc_pclk" }, { GPIO_CFG(91, 1, GPIO_CFG_OUTPUT, GPIO_CFG_NO_PULL, GPIO_CFG_2MA), "lcdc_en" }, { GPIO_CFG(92, 1, GPIO_CFG_OUTPUT, GPIO_CFG_NO_PULL, GPIO_CFG_2MA), "lcdc_vsync" }, { GPIO_CFG(93, 1, GPIO_CFG_OUTPUT, GPIO_CFG_NO_PULL, GPIO_CFG_2MA), "lcdc_hsync" }, { GPIO_CFG(94, 1, GPIO_CFG_OUTPUT, GPIO_CFG_NO_PULL, GPIO_CFG_2MA), "lcdc_grn2" }, { GPIO_CFG(95, 1, GPIO_CFG_OUTPUT, GPIO_CFG_NO_PULL, GPIO_CFG_2MA), "lcdc_grn3" }, { GPIO_CFG(96, 1, GPIO_CFG_OUTPUT, GPIO_CFG_NO_PULL, GPIO_CFG_2MA), "lcdc_grn4" }, { GPIO_CFG(97, 1, GPIO_CFG_OUTPUT, GPIO_CFG_NO_PULL, GPIO_CFG_2MA), "lcdc_grn5" }, { GPIO_CFG(98, 1, GPIO_CFG_OUTPUT, GPIO_CFG_NO_PULL, GPIO_CFG_2MA), "lcdc_grn6" }, { GPIO_CFG(99, 1, GPIO_CFG_OUTPUT, GPIO_CFG_NO_PULL, GPIO_CFG_2MA), "lcdc_grn7" }, { GPIO_CFG(100, 1, GPIO_CFG_OUTPUT, GPIO_CFG_NO_PULL, GPIO_CFG_2MA), "lcdc_blu3" }, { GPIO_CFG(101, 1, GPIO_CFG_OUTPUT, GPIO_CFG_NO_PULL, GPIO_CFG_2MA), "lcdc_blu4" }, { GPIO_CFG(102, 1, GPIO_CFG_OUTPUT, GPIO_CFG_NO_PULL, GPIO_CFG_2MA), "lcdc_blu5" }, { GPIO_CFG(103, 1, GPIO_CFG_OUTPUT, GPIO_CFG_NO_PULL, GPIO_CFG_2MA), "lcdc_blu6" }, { GPIO_CFG(104, 1, GPIO_CFG_OUTPUT, GPIO_CFG_NO_PULL, GPIO_CFG_2MA), "lcdc_blu7" }, { GPIO_CFG(105, 1, GPIO_CFG_OUTPUT, GPIO_CFG_NO_PULL, GPIO_CFG_2MA), "lcdc_red3" }, { GPIO_CFG(106, 1, GPIO_CFG_OUTPUT, GPIO_CFG_NO_PULL, GPIO_CFG_2MA), "lcdc_red4" }, { GPIO_CFG(107, 1, GPIO_CFG_OUTPUT, GPIO_CFG_NO_PULL, GPIO_CFG_2MA), "lcdc_red5" }, { GPIO_CFG(108, 1, GPIO_CFG_OUTPUT, GPIO_CFG_NO_PULL, GPIO_CFG_2MA), "lcdc_red6" }, { GPIO_CFG(109, 1, GPIO_CFG_OUTPUT, GPIO_CFG_NO_PULL, GPIO_CFG_2MA), "lcdc_red7" }, }; static struct msm_gpio lcd_sharp_panel_gpios[] = { { GPIO_CFG(22, 1, GPIO_CFG_OUTPUT, GPIO_CFG_NO_PULL, GPIO_CFG_2MA), "lcdc_blu2" }, { GPIO_CFG(25, 1, GPIO_CFG_OUTPUT, GPIO_CFG_NO_PULL, GPIO_CFG_2MA), "lcdc_red2" }, { GPIO_CFG(90, 1, GPIO_CFG_OUTPUT, GPIO_CFG_NO_PULL, GPIO_CFG_2MA), "lcdc_pclk" }, { GPIO_CFG(91, 1, GPIO_CFG_OUTPUT, GPIO_CFG_NO_PULL, GPIO_CFG_2MA), "lcdc_en" }, { GPIO_CFG(92, 1, GPIO_CFG_OUTPUT, GPIO_CFG_NO_PULL, GPIO_CFG_2MA), "lcdc_vsync" }, { GPIO_CFG(93, 1, GPIO_CFG_OUTPUT, GPIO_CFG_NO_PULL, GPIO_CFG_2MA), "lcdc_hsync" }, { GPIO_CFG(94, 1, GPIO_CFG_OUTPUT, GPIO_CFG_NO_PULL, GPIO_CFG_2MA), "lcdc_grn2" }, { GPIO_CFG(95, 1, GPIO_CFG_OUTPUT, GPIO_CFG_NO_PULL, GPIO_CFG_2MA), "lcdc_grn3" }, { GPIO_CFG(96, 1, GPIO_CFG_OUTPUT, GPIO_CFG_NO_PULL, GPIO_CFG_2MA), "lcdc_grn4" }, { GPIO_CFG(97, 1, GPIO_CFG_OUTPUT, GPIO_CFG_NO_PULL, GPIO_CFG_2MA), "lcdc_grn5" }, { GPIO_CFG(98, 1, GPIO_CFG_OUTPUT, GPIO_CFG_NO_PULL, GPIO_CFG_2MA), "lcdc_grn6" }, { GPIO_CFG(99, 1, GPIO_CFG_OUTPUT, GPIO_CFG_NO_PULL, GPIO_CFG_2MA), "lcdc_grn7" }, { GPIO_CFG(100, 1, GPIO_CFG_OUTPUT, GPIO_CFG_NO_PULL, GPIO_CFG_2MA), "lcdc_blu3" }, { GPIO_CFG(101, 1, GPIO_CFG_OUTPUT, GPIO_CFG_NO_PULL, GPIO_CFG_2MA), "lcdc_blu4" }, { GPIO_CFG(102, 1, GPIO_CFG_OUTPUT, GPIO_CFG_NO_PULL, GPIO_CFG_2MA), "lcdc_blu5" }, { GPIO_CFG(103, 1, GPIO_CFG_OUTPUT, GPIO_CFG_NO_PULL, GPIO_CFG_2MA), "lcdc_blu6" }, { GPIO_CFG(104, 1, GPIO_CFG_OUTPUT, GPIO_CFG_NO_PULL, GPIO_CFG_2MA), "lcdc_blu7" }, { GPIO_CFG(105, 1, GPIO_CFG_OUTPUT, GPIO_CFG_NO_PULL, GPIO_CFG_2MA), "lcdc_red3" }, { GPIO_CFG(106, 1, GPIO_CFG_OUTPUT, GPIO_CFG_NO_PULL, GPIO_CFG_2MA), "lcdc_red4" }, { GPIO_CFG(107, 1, GPIO_CFG_OUTPUT, GPIO_CFG_NO_PULL, GPIO_CFG_2MA), "lcdc_red5" }, { GPIO_CFG(108, 1, GPIO_CFG_OUTPUT, GPIO_CFG_NO_PULL, GPIO_CFG_2MA), "lcdc_red6" }, { GPIO_CFG(109, 1, GPIO_CFG_OUTPUT, GPIO_CFG_NO_PULL, GPIO_CFG_2MA), "lcdc_red7" }, }; static int lcdc_toshiba_panel_power(int on) { int rc, i; struct msm_gpio *gp; rc = display_common_power(on); if (rc < 0) { printk(KERN_ERR "%s display_common_power failed: %d\n", __func__, rc); return rc; } if (on) { rc = msm_gpios_enable(lcd_panel_gpios, ARRAY_SIZE(lcd_panel_gpios)); if (rc < 0) { printk(KERN_ERR "%s: gpio enable failed: %d\n", __func__, rc); } } else { /* off */ gp = lcd_panel_gpios; for (i = 0; i < ARRAY_SIZE(lcd_panel_gpios); i++) { /* ouput low */ gpio_set_value(GPIO_PIN(gp->gpio_cfg), 0); gp++; } } return rc; } static int lcdc_sharp_panel_power(int on) { int rc, i; struct msm_gpio *gp; rc = display_common_power(on); if (rc < 0) { printk(KERN_ERR "%s display_common_power failed: %d\n", __func__, rc); return rc; } if (on) { rc = msm_gpios_enable(lcd_sharp_panel_gpios, ARRAY_SIZE(lcd_sharp_panel_gpios)); if (rc < 0) { printk(KERN_ERR "%s: gpio enable failed: %d\n", __func__, rc); } } else { /* off */ gp = lcd_sharp_panel_gpios; for (i = 0; i < ARRAY_SIZE(lcd_sharp_panel_gpios); i++) { /* ouput low */ gpio_set_value(GPIO_PIN(gp->gpio_cfg), 0); gp++; } } return rc; } static int lcdc_panel_power(int on) { int flag_on = !!on; static int lcdc_power_save_on, lcdc_power_initialized; if (lcdc_power_save_on == flag_on) return 0; lcdc_power_save_on = flag_on; if (unlikely(!lcdc_power_initialized)) { quickvx_mddi_client = 0; display_common_init(); lcdc_power_initialized = 1; } if (machine_is_msm7x30_fluid()) return lcdc_sharp_panel_power(on); else return lcdc_toshiba_panel_power(on); } static struct lcdc_platform_data lcdc_pdata = { .lcdc_power_save = lcdc_panel_power, }; static struct regulator *atv_s4, *atv_ldo9; static int __init atv_dac_power_init(void) { int rc; struct regulator_bulk_data regs[] = { { .supply = "smps4", .min_uV = 2200000, .max_uV = 2200000 }, { .supply = "ldo9", .min_uV = 2050000, .max_uV = 2050000 }, }; rc = regulator_bulk_get(NULL, ARRAY_SIZE(regs), regs); if (rc) { pr_err("%s: could not get regulators: %d\n", __func__, rc); goto bail; } rc = regulator_bulk_set_voltage(ARRAY_SIZE(regs), regs); if (rc) { pr_err("%s: could not set voltages: %d\n", __func__, rc); goto reg_free; } atv_s4 = regs[0].consumer; atv_ldo9 = regs[1].consumer; reg_free: regulator_bulk_free(ARRAY_SIZE(regs), regs); bail: return rc; } static int atv_dac_power(int on) { int rc = 0; if (on) { rc = regulator_enable(atv_s4); if (rc) { pr_err("%s: s4 vreg enable failed (%d)\n", __func__, rc); return rc; } rc = regulator_enable(atv_ldo9); if (rc) { pr_err("%s: ldo9 vreg enable failed (%d)\n", __func__, rc); return rc; } } else { rc = regulator_disable(atv_ldo9); if (rc) { pr_err("%s: ldo9 vreg disable failed (%d)\n", __func__, rc); return rc; } rc = regulator_disable(atv_s4); if (rc) { pr_err("%s: s4 vreg disable failed (%d)\n", __func__, rc); return rc; } } return rc; } static struct tvenc_platform_data atv_pdata = { .poll = 1, .pm_vid_en = atv_dac_power, }; static void __init msm_fb_add_devices(void) { msm_fb_register_device("mdp", &mdp_pdata); msm_fb_register_device("pmdh", &mddi_pdata); msm_fb_register_device("lcdc", &lcdc_pdata); msm_fb_register_device("dtv", &dtv_pdata); msm_fb_register_device("tvenc", &atv_pdata); #ifdef CONFIG_FB_MSM_TVOUT msm_fb_register_device("tvout_device", NULL); #endif } static struct msm_panel_common_pdata lcdc_toshiba_panel_data = { .gpio_num = lcd_panel_spi_gpio_num, }; static struct platform_device lcdc_toshiba_panel_device = { .name = "lcdc_toshiba_wvga", .id = 0, .dev = { .platform_data = &lcdc_toshiba_panel_data, } }; #if defined(CONFIG_MARIMBA_CORE) && \ (defined(CONFIG_MSM_BT_POWER) || defined(CONFIG_MSM_BT_POWER_MODULE)) static struct platform_device msm_bt_power_device = { .name = "bt_power", .id = -1 }; enum { BT_RFR, BT_CTS, BT_RX, BT_TX, }; static struct msm_gpio bt_config_power_on[] = { { GPIO_CFG(134, 1, GPIO_CFG_OUTPUT, GPIO_CFG_NO_PULL, GPIO_CFG_2MA), "UART1DM_RFR" }, { GPIO_CFG(135, 1, GPIO_CFG_INPUT, GPIO_CFG_NO_PULL, GPIO_CFG_2MA), "UART1DM_CTS" }, { GPIO_CFG(136, 1, GPIO_CFG_INPUT, GPIO_CFG_NO_PULL, GPIO_CFG_2MA), "UART1DM_Rx" }, { GPIO_CFG(137, 1, GPIO_CFG_OUTPUT, GPIO_CFG_NO_PULL, GPIO_CFG_2MA), "UART1DM_Tx" } }; static struct msm_gpio bt_config_power_off[] = { { GPIO_CFG(134, 0, GPIO_CFG_INPUT, GPIO_CFG_PULL_DOWN, GPIO_CFG_2MA), "UART1DM_RFR" }, { GPIO_CFG(135, 0, GPIO_CFG_INPUT, GPIO_CFG_PULL_DOWN, GPIO_CFG_2MA), "UART1DM_CTS" }, { GPIO_CFG(136, 0, GPIO_CFG_INPUT, GPIO_CFG_PULL_DOWN, GPIO_CFG_2MA), "UART1DM_Rx" }, { GPIO_CFG(137, 0, GPIO_CFG_INPUT, GPIO_CFG_PULL_DOWN, GPIO_CFG_2MA), "UART1DM_Tx" } }; static u8 bahama_version; static struct regulator_bulk_data regs_bt_marimba[] = { { .supply = "smps3", .min_uV = 1800000, .max_uV = 1800000 }, { .supply = "smps2", .min_uV = 1300000, .max_uV = 1300000 }, { .supply = "ldo24", .min_uV = 1200000, .max_uV = 1200000 }, { .supply = "ldo13", .min_uV = 2900000, .max_uV = 3050000 }, }; static struct regulator_bulk_data regs_bt_bahama_v1[] = { { .supply = "smps3", .min_uV = 1800000, .max_uV = 1800000 }, { .supply = "ldo7", .min_uV = 1800000, .max_uV = 1800000 }, { .supply = "smps2", .min_uV = 1300000, .max_uV = 1300000 }, { .supply = "ldo13", .min_uV = 2900000, .max_uV = 3050000 }, }; static struct regulator_bulk_data regs_bt_bahama_v2[] = { { .supply = "smps3", .min_uV = 1800000, .max_uV = 1800000 }, { .supply = "ldo7", .min_uV = 1800000, .max_uV = 1800000 }, { .supply = "ldo13", .min_uV = 2900000, .max_uV = 3050000 }, }; static struct regulator_bulk_data *regs_bt; static int regs_bt_count; static int marimba_bt(int on) { int rc; int i; struct marimba config = { .mod_id = MARIMBA_SLAVE_ID_MARIMBA }; struct marimba_config_register { u8 reg; u8 value; u8 mask; }; struct marimba_variant_register { const size_t size; const struct marimba_config_register *set; }; const struct marimba_config_register *p; u8 version; const struct marimba_config_register v10_bt_on[] = { { 0xE5, 0x0B, 0x0F }, { 0x05, 0x02, 0x07 }, { 0x06, 0x88, 0xFF }, { 0xE7, 0x21, 0x21 }, { 0xE3, 0x38, 0xFF }, { 0xE4, 0x06, 0xFF }, }; const struct marimba_config_register v10_bt_off[] = { { 0xE5, 0x0B, 0x0F }, { 0x05, 0x08, 0x0F }, { 0x06, 0x88, 0xFF }, { 0xE7, 0x00, 0x21 }, { 0xE3, 0x00, 0xFF }, { 0xE4, 0x00, 0xFF }, }; const struct marimba_config_register v201_bt_on[] = { { 0x05, 0x08, 0x07 }, { 0x06, 0x88, 0xFF }, { 0xE7, 0x21, 0x21 }, { 0xE3, 0x38, 0xFF }, { 0xE4, 0x06, 0xFF }, }; const struct marimba_config_register v201_bt_off[] = { { 0x05, 0x08, 0x07 }, { 0x06, 0x88, 0xFF }, { 0xE7, 0x00, 0x21 }, { 0xE3, 0x00, 0xFF }, { 0xE4, 0x00, 0xFF }, }; const struct marimba_config_register v210_bt_on[] = { { 0xE9, 0x01, 0x01 }, { 0x06, 0x88, 0xFF }, { 0xE7, 0x21, 0x21 }, { 0xE3, 0x38, 0xFF }, { 0xE4, 0x06, 0xFF }, }; const struct marimba_config_register v210_bt_off[] = { { 0x06, 0x88, 0xFF }, { 0xE7, 0x00, 0x21 }, { 0xE9, 0x00, 0x01 }, { 0xE3, 0x00, 0xFF }, { 0xE4, 0x00, 0xFF }, }; const struct marimba_variant_register bt_marimba[2][4] = { { { ARRAY_SIZE(v10_bt_off), v10_bt_off }, { 0, NULL }, { ARRAY_SIZE(v201_bt_off), v201_bt_off }, { ARRAY_SIZE(v210_bt_off), v210_bt_off } }, { { ARRAY_SIZE(v10_bt_on), v10_bt_on }, { 0, NULL }, { ARRAY_SIZE(v201_bt_on), v201_bt_on }, { ARRAY_SIZE(v210_bt_on), v210_bt_on } } }; on = on ? 1 : 0; rc = marimba_read_bit_mask(&config, 0x11, &version, 1, 0x1F); if (rc < 0) { printk(KERN_ERR "%s: version read failed: %d\n", __func__, rc); return rc; } if ((version >= ARRAY_SIZE(bt_marimba[on])) || (bt_marimba[on][version].size == 0)) { printk(KERN_ERR "%s: unsupported version\n", __func__); return -EIO; } p = bt_marimba[on][version].set; printk(KERN_INFO "%s: found version %d\n", __func__, version); for (i = 0; i < bt_marimba[on][version].size; i++) { u8 value = (p+i)->value; rc = marimba_write_bit_mask(&config, (p+i)->reg, &value, sizeof((p+i)->value), (p+i)->mask); if (rc < 0) { printk(KERN_ERR "%s: reg %d write failed: %d\n", __func__, (p+i)->reg, rc); return rc; } printk(KERN_INFO "%s: reg 0x%02x value 0x%02x mask 0x%02x\n", __func__, (p+i)->reg, value, (p+i)->mask); } return 0; } static int bahama_bt(int on) { int rc; int i; struct marimba config = { .mod_id = SLAVE_ID_BAHAMA }; struct bahama_variant_register { const size_t size; const struct bahama_config_register *set; }; const struct bahama_config_register *p; const struct bahama_config_register v10_bt_on[] = { { 0xE9, 0x00, 0xFF }, { 0xF4, 0x80, 0xFF }, { 0xF0, 0x06, 0xFF }, { 0xE4, 0x00, 0xFF }, { 0xE5, 0x00, 0x0F }, #ifdef CONFIG_WLAN { 0xE6, 0x38, 0x7F }, { 0xE7, 0x06, 0xFF }, #endif { 0x11, 0x13, 0xFF }, { 0xE9, 0x21, 0xFF }, { 0x01, 0x0C, 0x1F }, { 0x01, 0x08, 0x1F }, }; const struct bahama_config_register v20_bt_on_fm_off[] = { { 0x11, 0x0C, 0xFF }, { 0x13, 0x01, 0xFF }, { 0xF4, 0x80, 0xFF }, { 0xF0, 0x00, 0xFF }, { 0xE9, 0x00, 0xFF }, #ifdef CONFIG_WLAN { 0x81, 0x00, 0xFF }, { 0x82, 0x00, 0xFF }, { 0xE6, 0x38, 0x7F }, { 0xE7, 0x06, 0xFF }, #endif { 0xE9, 0x21, 0xFF } }; const struct bahama_config_register v20_bt_on_fm_on[] = { { 0x11, 0x0C, 0xFF }, { 0x13, 0x01, 0xFF }, { 0xF4, 0x86, 0xFF }, { 0xF0, 0x06, 0xFF }, { 0xE9, 0x00, 0xFF }, #ifdef CONFIG_WLAN { 0x81, 0x00, 0xFF }, { 0x82, 0x00, 0xFF }, { 0xE6, 0x38, 0x7F }, { 0xE7, 0x06, 0xFF }, #endif { 0xE9, 0x21, 0xFF } }; const struct bahama_config_register v10_bt_off[] = { { 0xE9, 0x00, 0xFF }, }; const struct bahama_config_register v20_bt_off_fm_off[] = { { 0xF4, 0x84, 0xFF }, { 0xF0, 0x04, 0xFF }, { 0xE9, 0x00, 0xFF } }; const struct bahama_config_register v20_bt_off_fm_on[] = { { 0xF4, 0x86, 0xFF }, { 0xF0, 0x06, 0xFF }, { 0xE9, 0x00, 0xFF } }; const struct bahama_variant_register bt_bahama[2][3] = { { { ARRAY_SIZE(v10_bt_off), v10_bt_off }, { ARRAY_SIZE(v20_bt_off_fm_off), v20_bt_off_fm_off }, { ARRAY_SIZE(v20_bt_off_fm_on), v20_bt_off_fm_on } }, { { ARRAY_SIZE(v10_bt_on), v10_bt_on }, { ARRAY_SIZE(v20_bt_on_fm_off), v20_bt_on_fm_off }, { ARRAY_SIZE(v20_bt_on_fm_on), v20_bt_on_fm_on } } }; u8 offset = 0; /* index into bahama configs */ on = on ? 1 : 0; if (bahama_version == VER_2_0) { if (marimba_get_fm_status(&config)) offset = 0x01; } p = bt_bahama[on][bahama_version + offset].set; dev_info(&msm_bt_power_device.dev, "%s: found version %d\n", __func__, bahama_version); for (i = 0; i < bt_bahama[on][bahama_version + offset].size; i++) { u8 value = (p+i)->value; rc = marimba_write_bit_mask(&config, (p+i)->reg, &value, sizeof((p+i)->value), (p+i)->mask); if (rc < 0) { dev_err(&msm_bt_power_device.dev, "%s: reg %d write failed: %d\n", __func__, (p+i)->reg, rc); return rc; } dev_info(&msm_bt_power_device.dev, "%s: reg 0x%02x write value 0x%02x mask 0x%02x\n", __func__, (p+i)->reg, value, (p+i)->mask); } /* Update BT status */ if (on) marimba_set_bt_status(&config, true); else marimba_set_bt_status(&config, false); return 0; } static int bluetooth_regs_init(int bahama_not_marimba) { int rc = 0; struct device *const dev = &msm_bt_power_device.dev; if (bahama_not_marimba) { bahama_version = read_bahama_ver(); switch (bahama_version) { case VER_1_0: regs_bt = regs_bt_bahama_v1; regs_bt_count = ARRAY_SIZE(regs_bt_bahama_v1); break; case VER_2_0: regs_bt = regs_bt_bahama_v2; regs_bt_count = ARRAY_SIZE(regs_bt_bahama_v2); break; case VER_UNSUPPORTED: default: dev_err(dev, "%s: i2c failure or unsupported version: %d\n", __func__, bahama_version); rc = -EIO; goto out; } } else { regs_bt = regs_bt_marimba; regs_bt_count = ARRAY_SIZE(regs_bt_marimba); } rc = regulator_bulk_get(&msm_bt_power_device.dev, regs_bt_count, regs_bt); if (rc) { dev_err(dev, "%s: could not get regulators: %d\n", __func__, rc); goto out; } rc = regulator_bulk_set_voltage(regs_bt_count, regs_bt); if (rc) { dev_err(dev, "%s: could not set voltages: %d\n", __func__, rc); goto reg_free; } return 0; reg_free: regulator_bulk_free(regs_bt_count, regs_bt); out: regs_bt_count = 0; regs_bt = NULL; return rc; } static int bluetooth_power(int on) { int rc; const char *id = "BTPW"; int bahama_not_marimba = bahama_present(); if (bahama_not_marimba < 0) { printk(KERN_WARNING "%s: bahama_present: %d\n", __func__, bahama_not_marimba); return -ENODEV; } if (unlikely(regs_bt_count == 0)) { rc = bluetooth_regs_init(bahama_not_marimba); if (rc) return rc; } if (on) { rc = regulator_bulk_enable(regs_bt_count, regs_bt); if (rc) return rc; rc = pmapp_clock_vote(id, PMAPP_CLOCK_ID_DO, PMAPP_CLOCK_VOTE_ON); if (rc < 0) return -EIO; if (machine_is_msm8x55_svlte_surf() || machine_is_msm8x55_svlte_ffa()) { rc = marimba_gpio_config(1); if (rc < 0) return -EIO; } rc = (bahama_not_marimba ? bahama_bt(on) : marimba_bt(on)); if (rc < 0) return -EIO; msleep(10); rc = pmapp_clock_vote(id, PMAPP_CLOCK_ID_DO, PMAPP_CLOCK_VOTE_PIN_CTRL); if (rc < 0) return -EIO; if (machine_is_msm8x55_svlte_surf() || machine_is_msm8x55_svlte_ffa()) { rc = marimba_gpio_config(0); if (rc < 0) return -EIO; } rc = msm_gpios_enable(bt_config_power_on, ARRAY_SIZE(bt_config_power_on)); if (rc < 0) return rc; } else { rc = msm_gpios_enable(bt_config_power_off, ARRAY_SIZE(bt_config_power_off)); if (rc < 0) return rc; /* check for initial RFKILL block (power off) */ if (platform_get_drvdata(&msm_bt_power_device) == NULL) goto out; rc = (bahama_not_marimba ? bahama_bt(on) : marimba_bt(on)); if (rc < 0) return -EIO; rc = pmapp_clock_vote(id, PMAPP_CLOCK_ID_DO, PMAPP_CLOCK_VOTE_OFF); if (rc < 0) return -EIO; rc = regulator_bulk_disable(regs_bt_count, regs_bt); if (rc) return rc; } out: printk(KERN_DEBUG "Bluetooth power switch: %d\n", on); return 0; } static void __init bt_power_init(void) { msm_bt_power_device.dev.platform_data = &bluetooth_power; } #else #define bt_power_init(x) do {} while (0) #endif static struct msm_psy_batt_pdata msm_psy_batt_data = { .voltage_min_design = 2800, .voltage_max_design = 4300, .avail_chg_sources = AC_CHG | USB_CHG , .batt_technology = POWER_SUPPLY_TECHNOLOGY_LION, }; static struct platform_device msm_batt_device = { .name = "msm-battery", .id = -1, .dev.platform_data = &msm_psy_batt_data, }; static char *msm_adc_fluid_device_names[] = { "LTC_ADC1", "LTC_ADC2", "LTC_ADC3", }; static char *msm_adc_surf_device_names[] = { "XO_ADC", }; static struct msm_adc_platform_data msm_adc_pdata; static struct platform_device msm_adc_device = { .name = "msm_adc", .id = -1, .dev = { .platform_data = &msm_adc_pdata, }, }; #ifdef CONFIG_MSM_SDIO_AL static struct msm_gpio mdm2ap_status = { GPIO_CFG(77, 0, GPIO_CFG_INPUT, GPIO_CFG_NO_PULL, GPIO_CFG_2MA), "mdm2ap_status" }; static int configure_mdm2ap_status(int on) { if (on) return msm_gpios_request_enable(&mdm2ap_status, 1); else { msm_gpios_disable_free(&mdm2ap_status, 1); return 0; } } static int get_mdm2ap_status(void) { return gpio_get_value(GPIO_PIN(mdm2ap_status.gpio_cfg)); } static struct sdio_al_platform_data sdio_al_pdata = { .config_mdm2ap_status = configure_mdm2ap_status, .get_mdm2ap_status = get_mdm2ap_status, .allow_sdioc_version_major_2 = 1, .peer_sdioc_version_minor = 0x0001, .peer_sdioc_version_major = 0x0003, .peer_sdioc_boot_version_minor = 0x0001, .peer_sdioc_boot_version_major = 0x0003, }; struct platform_device msm_device_sdio_al = { .name = "msm_sdio_al", .id = -1, .dev = { .platform_data = &sdio_al_pdata, }, }; #endif /* CONFIG_MSM_SDIO_AL */ static struct platform_device *devices[] __initdata = { #if defined(CONFIG_SERIAL_MSM) || defined(CONFIG_MSM_SERIAL_DEBUGGER) &msm_device_uart2, #endif #ifdef CONFIG_MSM_PROC_COMM_REGULATOR &msm_proccomm_regulator_dev, #endif &asoc_msm_pcm, &asoc_msm_dai0, &asoc_msm_dai1, #if defined (CONFIG_SND_MSM_MVS_DAI_SOC) &asoc_msm_mvs, &asoc_mvs_dai0, &asoc_mvs_dai1, #endif &msm_device_smd, &msm_device_dmov, &smc91x_device, &smsc911x_device, &msm_device_nand, #ifdef CONFIG_USB_MSM_OTG_72K &msm_device_otg, #ifdef CONFIG_USB_GADGET &msm_device_gadget_peripheral, #endif #endif #ifdef CONFIG_USB_G_ANDROID &android_usb_device, #endif &qsd_device_spi, #ifdef CONFIG_MSM_SSBI &msm_device_ssbi_pmic1, #endif #ifdef CONFIG_I2C_SSBI &msm_device_ssbi7, #endif &msm_fb_device, #ifdef CONFIG_MSM_V4L2_VIDEO_OVERLAY_DEVICE &msm_v4l2_video_overlay_device, #endif &msm_migrate_pages_device, &mddi_toshiba_device, &lcdc_toshiba_panel_device, #ifdef CONFIG_MSM_ROTATOR &msm_rotator_device, #endif &lcdc_sharp_panel_device, &msm_device_i2c, &msm_device_i2c_2, &msm_device_uart_dm1, &hs_device, #ifdef CONFIG_MSM7KV2_AUDIO &msm_aictl_device, &msm_mi2s_device, &msm_lpa_device, &msm_aux_pcm_device, #endif &msm_device_adspdec, &qup_device_i2c, #if defined(CONFIG_MARIMBA_CORE) && \ (defined(CONFIG_MSM_BT_POWER) || defined(CONFIG_MSM_BT_POWER_MODULE)) &msm_bt_power_device, #endif &msm_kgsl_3d0, &msm_kgsl_2d0, #ifndef CONFIG_MSM_CAMERA_V4L2 #ifdef CONFIG_MT9T013 &msm_camera_sensor_mt9t013, #endif #ifdef CONFIG_MT9D112 &msm_camera_sensor_mt9d112, #endif #ifdef CONFIG_WEBCAM_OV9726 &msm_camera_sensor_ov9726, #endif #ifdef CONFIG_S5K3E2FX &msm_camera_sensor_s5k3e2fx, #endif #ifdef CONFIG_MT9P012 &msm_camera_sensor_mt9p012, #endif #ifdef CONFIG_MT9E013 &msm_camera_sensor_mt9e013, #endif #ifdef CONFIG_VX6953 &msm_camera_sensor_vx6953, #endif #ifdef CONFIG_SN12M0PZ &msm_camera_sensor_sn12m0pz, #endif #endif &msm_device_vidc_720p, #ifdef CONFIG_MSM_GEMINI &msm_gemini_device, #endif #ifndef CONFIG_MSM_CAMERA_V4L2 #ifdef CONFIG_MSM_VPE &msm_vpe_device, #endif #endif #if defined(CONFIG_TSIF) || defined(CONFIG_TSIF_MODULE) &msm_device_tsif, #endif #ifdef CONFIG_MSM_SDIO_AL &msm_device_sdio_al, #endif #if defined(CONFIG_CRYPTO_DEV_QCRYPTO) || \ defined(CONFIG_CRYPTO_DEV_QCRYPTO_MODULE) &qcrypto_device, #endif #if defined(CONFIG_CRYPTO_DEV_QCEDEV) || \ defined(CONFIG_CRYPTO_DEV_QCEDEV_MODULE) &qcedev_device, #endif &msm_batt_device, &msm_adc_device, &msm_ebi0_thermal, &msm_ebi1_thermal, &msm_adsp_device, #ifdef CONFIG_ION_MSM &ion_dev, #endif }; static struct msm_gpio msm_i2c_gpios_hw[] = { { GPIO_CFG(70, 1, GPIO_CFG_INPUT, GPIO_CFG_NO_PULL, GPIO_CFG_16MA), "i2c_scl" }, { GPIO_CFG(71, 1, GPIO_CFG_INPUT, GPIO_CFG_NO_PULL, GPIO_CFG_16MA), "i2c_sda" }, }; static struct msm_gpio msm_i2c_gpios_io[] = { { GPIO_CFG(70, 0, GPIO_CFG_OUTPUT, GPIO_CFG_NO_PULL, GPIO_CFG_16MA), "i2c_scl" }, { GPIO_CFG(71, 0, GPIO_CFG_OUTPUT, GPIO_CFG_NO_PULL, GPIO_CFG_16MA), "i2c_sda" }, }; static struct msm_gpio qup_i2c_gpios_io[] = { { GPIO_CFG(16, 0, GPIO_CFG_OUTPUT, GPIO_CFG_NO_PULL, GPIO_CFG_16MA), "qup_scl" }, { GPIO_CFG(17, 0, GPIO_CFG_OUTPUT, GPIO_CFG_NO_PULL, GPIO_CFG_16MA), "qup_sda" }, }; static struct msm_gpio qup_i2c_gpios_hw[] = { { GPIO_CFG(16, 2, GPIO_CFG_INPUT, GPIO_CFG_NO_PULL, GPIO_CFG_16MA), "qup_scl" }, { GPIO_CFG(17, 2, GPIO_CFG_INPUT, GPIO_CFG_NO_PULL, GPIO_CFG_16MA), "qup_sda" }, }; static void msm_i2c_gpio_config(int adap_id, int config_type) { struct msm_gpio *msm_i2c_table; /* Each adapter gets 2 lines from the table */ if (adap_id > 0) return; if (config_type) msm_i2c_table = &msm_i2c_gpios_hw[adap_id*2]; else msm_i2c_table = &msm_i2c_gpios_io[adap_id*2]; msm_gpios_enable(msm_i2c_table, 2); } /*This needs to be enabled only for OEMS*/ #ifndef CONFIG_QUP_EXCLUSIVE_TO_CAMERA static struct regulator *qup_vreg; #endif static void qup_i2c_gpio_config(int adap_id, int config_type) { int rc = 0; struct msm_gpio *qup_i2c_table; /* Each adapter gets 2 lines from the table */ if (adap_id != 4) return; if (config_type) qup_i2c_table = qup_i2c_gpios_hw; else qup_i2c_table = qup_i2c_gpios_io; rc = msm_gpios_enable(qup_i2c_table, 2); if (rc < 0) printk(KERN_ERR "QUP GPIO enable failed: %d\n", rc); /*This needs to be enabled only for OEMS*/ #ifndef CONFIG_QUP_EXCLUSIVE_TO_CAMERA if (!IS_ERR_OR_NULL(qup_vreg)) { rc = regulator_enable(qup_vreg); if (rc) { pr_err("%s: regulator_enable failed: %d\n", __func__, rc); } } #endif } static struct msm_i2c_platform_data msm_i2c_pdata = { .clk_freq = 100000, .pri_clk = 70, .pri_dat = 71, .rmutex = 1, .rsl_id = "D:I2C02000021", .msm_i2c_config_gpio = msm_i2c_gpio_config, }; static void __init msm_device_i2c_init(void) { if (msm_gpios_request(msm_i2c_gpios_hw, ARRAY_SIZE(msm_i2c_gpios_hw))) pr_err("failed to request I2C gpios\n"); msm_device_i2c.dev.platform_data = &msm_i2c_pdata; } static struct msm_i2c_platform_data msm_i2c_2_pdata = { .clk_freq = 100000, .rmutex = 1, .rsl_id = "D:I2C02000022", .msm_i2c_config_gpio = msm_i2c_gpio_config, }; static void __init msm_device_i2c_2_init(void) { msm_device_i2c_2.dev.platform_data = &msm_i2c_2_pdata; } static struct msm_i2c_platform_data qup_i2c_pdata = { .clk_freq = 384000, .msm_i2c_config_gpio = qup_i2c_gpio_config, }; static void __init qup_device_i2c_init(void) { if (msm_gpios_request(qup_i2c_gpios_hw, ARRAY_SIZE(qup_i2c_gpios_hw))) pr_err("failed to request I2C gpios\n"); qup_device_i2c.dev.platform_data = &qup_i2c_pdata; /*This needs to be enabled only for OEMS*/ #ifndef CONFIG_QUP_EXCLUSIVE_TO_CAMERA qup_vreg = regulator_get(&qup_device_i2c.dev, "lvsw1"); if (IS_ERR(qup_vreg)) { dev_err(&qup_device_i2c.dev, "%s: regulator_get failed: %ld\n", __func__, PTR_ERR(qup_vreg)); } #endif } #ifdef CONFIG_I2C_SSBI static struct msm_i2c_ssbi_platform_data msm_i2c_ssbi7_pdata = { .rsl_id = "D:CODEC_SSBI", .controller_type = MSM_SBI_CTRL_SSBI, }; #endif static void __init msm7x30_init_irq(void) { msm_init_irq(); } static struct msm_gpio msm_nand_ebi2_cfg_data[] = { {GPIO_CFG(86, 1, GPIO_CFG_OUTPUT, GPIO_CFG_PULL_UP, GPIO_CFG_8MA), "ebi2_cs1"}, {GPIO_CFG(115, 2, GPIO_CFG_OUTPUT, GPIO_CFG_PULL_UP, GPIO_CFG_8MA), "ebi2_busy1"}, }; #if (defined(CONFIG_MMC_MSM_SDC1_SUPPORT)\ || defined(CONFIG_MMC_MSM_SDC2_SUPPORT)\ || defined(CONFIG_MMC_MSM_SDC3_SUPPORT)\ || defined(CONFIG_MMC_MSM_SDC4_SUPPORT)) struct sdcc_gpio { struct msm_gpio *cfg_data; uint32_t size; struct msm_gpio *sleep_cfg_data; }; #if defined(CONFIG_MMC_MSM_SDC1_SUPPORT) static struct msm_gpio sdc1_lvlshft_cfg_data[] = { {GPIO_CFG(35, 1, GPIO_CFG_OUTPUT, GPIO_CFG_PULL_UP, GPIO_CFG_16MA), "sdc1_lvlshft"}, }; #endif static struct msm_gpio sdc1_cfg_data[] = { {GPIO_CFG(38, 1, GPIO_CFG_OUTPUT, GPIO_CFG_NO_PULL, GPIO_CFG_16MA), "sdc1_clk"}, {GPIO_CFG(39, 1, GPIO_CFG_OUTPUT, GPIO_CFG_PULL_UP, GPIO_CFG_8MA), "sdc1_cmd"}, {GPIO_CFG(40, 1, GPIO_CFG_OUTPUT, GPIO_CFG_PULL_UP, GPIO_CFG_8MA), "sdc1_dat_3"}, {GPIO_CFG(41, 1, GPIO_CFG_OUTPUT, GPIO_CFG_PULL_UP, GPIO_CFG_8MA), "sdc1_dat_2"}, {GPIO_CFG(42, 1, GPIO_CFG_OUTPUT, GPIO_CFG_PULL_UP, GPIO_CFG_8MA), "sdc1_dat_1"}, {GPIO_CFG(43, 1, GPIO_CFG_OUTPUT, GPIO_CFG_PULL_UP, GPIO_CFG_8MA), "sdc1_dat_0"}, }; static struct msm_gpio sdc2_cfg_data[] = { {GPIO_CFG(64, 1, GPIO_CFG_OUTPUT, GPIO_CFG_NO_PULL, GPIO_CFG_16MA), "sdc2_clk"}, {GPIO_CFG(65, 1, GPIO_CFG_OUTPUT, GPIO_CFG_PULL_UP, GPIO_CFG_8MA), "sdc2_cmd"}, {GPIO_CFG(66, 1, GPIO_CFG_OUTPUT, GPIO_CFG_PULL_UP, GPIO_CFG_8MA), "sdc2_dat_3"}, {GPIO_CFG(67, 1, GPIO_CFG_OUTPUT, GPIO_CFG_PULL_UP, GPIO_CFG_8MA), "sdc2_dat_2"}, {GPIO_CFG(68, 1, GPIO_CFG_OUTPUT, GPIO_CFG_PULL_UP, GPIO_CFG_8MA), "sdc2_dat_1"}, {GPIO_CFG(69, 1, GPIO_CFG_OUTPUT, GPIO_CFG_PULL_UP, GPIO_CFG_8MA), "sdc2_dat_0"}, #ifdef CONFIG_MMC_MSM_SDC2_8_BIT_SUPPORT {GPIO_CFG(115, 1, GPIO_CFG_OUTPUT, GPIO_CFG_PULL_UP, GPIO_CFG_8MA), "sdc2_dat_4"}, {GPIO_CFG(114, 1, GPIO_CFG_OUTPUT, GPIO_CFG_PULL_UP, GPIO_CFG_8MA), "sdc2_dat_5"}, {GPIO_CFG(113, 1, GPIO_CFG_OUTPUT, GPIO_CFG_PULL_UP, GPIO_CFG_8MA), "sdc2_dat_6"}, {GPIO_CFG(112, 1, GPIO_CFG_OUTPUT, GPIO_CFG_PULL_UP, GPIO_CFG_8MA), "sdc2_dat_7"}, #endif }; static struct msm_gpio sdc3_cfg_data[] = { {GPIO_CFG(110, 1, GPIO_CFG_OUTPUT, GPIO_CFG_NO_PULL, GPIO_CFG_16MA), "sdc3_clk"}, {GPIO_CFG(111, 1, GPIO_CFG_OUTPUT, GPIO_CFG_PULL_UP, GPIO_CFG_8MA), "sdc3_cmd"}, {GPIO_CFG(116, 1, GPIO_CFG_OUTPUT, GPIO_CFG_PULL_UP, GPIO_CFG_8MA), "sdc3_dat_3"}, {GPIO_CFG(117, 1, GPIO_CFG_OUTPUT, GPIO_CFG_PULL_UP, GPIO_CFG_8MA), "sdc3_dat_2"}, {GPIO_CFG(118, 1, GPIO_CFG_OUTPUT, GPIO_CFG_PULL_UP, GPIO_CFG_8MA), "sdc3_dat_1"}, {GPIO_CFG(119, 1, GPIO_CFG_OUTPUT, GPIO_CFG_PULL_UP, GPIO_CFG_8MA), "sdc3_dat_0"}, }; static struct msm_gpio sdc3_sleep_cfg_data[] = { {GPIO_CFG(110, 0, GPIO_CFG_OUTPUT, GPIO_CFG_NO_PULL, GPIO_CFG_2MA), "sdc3_clk"}, {GPIO_CFG(111, 0, GPIO_CFG_OUTPUT, GPIO_CFG_NO_PULL, GPIO_CFG_2MA), "sdc3_cmd"}, {GPIO_CFG(116, 0, GPIO_CFG_OUTPUT, GPIO_CFG_NO_PULL, GPIO_CFG_2MA), "sdc3_dat_3"}, {GPIO_CFG(117, 0, GPIO_CFG_OUTPUT, GPIO_CFG_NO_PULL, GPIO_CFG_2MA), "sdc3_dat_2"}, {GPIO_CFG(118, 0, GPIO_CFG_OUTPUT, GPIO_CFG_NO_PULL, GPIO_CFG_2MA), "sdc3_dat_1"}, {GPIO_CFG(119, 0, GPIO_CFG_OUTPUT, GPIO_CFG_NO_PULL, GPIO_CFG_2MA), "sdc3_dat_0"}, }; static struct msm_gpio sdc4_cfg_data[] = { {GPIO_CFG(58, 1, GPIO_CFG_OUTPUT, GPIO_CFG_NO_PULL, GPIO_CFG_16MA), "sdc4_clk"}, {GPIO_CFG(59, 1, GPIO_CFG_OUTPUT, GPIO_CFG_PULL_UP, GPIO_CFG_8MA), "sdc4_cmd"}, {GPIO_CFG(60, 1, GPIO_CFG_OUTPUT, GPIO_CFG_PULL_UP, GPIO_CFG_8MA), "sdc4_dat_3"}, {GPIO_CFG(61, 1, GPIO_CFG_OUTPUT, GPIO_CFG_PULL_UP, GPIO_CFG_8MA), "sdc4_dat_2"}, {GPIO_CFG(62, 1, GPIO_CFG_OUTPUT, GPIO_CFG_PULL_UP, GPIO_CFG_8MA), "sdc4_dat_1"}, {GPIO_CFG(63, 1, GPIO_CFG_OUTPUT, GPIO_CFG_PULL_UP, GPIO_CFG_8MA), "sdc4_dat_0"}, }; static struct sdcc_gpio sdcc_cfg_data[] = { { .cfg_data = sdc1_cfg_data, .size = ARRAY_SIZE(sdc1_cfg_data), .sleep_cfg_data = NULL, }, { .cfg_data = sdc2_cfg_data, .size = ARRAY_SIZE(sdc2_cfg_data), .sleep_cfg_data = NULL, }, { .cfg_data = sdc3_cfg_data, .size = ARRAY_SIZE(sdc3_cfg_data), .sleep_cfg_data = sdc3_sleep_cfg_data, }, { .cfg_data = sdc4_cfg_data, .size = ARRAY_SIZE(sdc4_cfg_data), .sleep_cfg_data = NULL, }, }; static struct regulator *sdcc_vreg_data[ARRAY_SIZE(sdcc_cfg_data)]; static unsigned long vreg_sts, gpio_sts; static uint32_t msm_sdcc_setup_gpio(int dev_id, unsigned int enable) { int rc = 0; struct sdcc_gpio *curr; curr = &sdcc_cfg_data[dev_id - 1]; if (!(test_bit(dev_id, &gpio_sts)^enable)) return rc; if (enable) { set_bit(dev_id, &gpio_sts); rc = msm_gpios_request_enable(curr->cfg_data, curr->size); if (rc) printk(KERN_ERR "%s: Failed to turn on GPIOs for slot %d\n", __func__, dev_id); } else { clear_bit(dev_id, &gpio_sts); if (curr->sleep_cfg_data) { msm_gpios_enable(curr->sleep_cfg_data, curr->size); msm_gpios_free(curr->sleep_cfg_data, curr->size); } else { msm_gpios_disable_free(curr->cfg_data, curr->size); } } return rc; } static uint32_t msm_sdcc_setup_vreg(int dev_id, unsigned int enable) { int rc = 0; struct regulator *curr = sdcc_vreg_data[dev_id - 1]; static int enabled_once[] = {0, 0, 0, 0}; if (test_bit(dev_id, &vreg_sts) == enable) return rc; if (dev_id == 4) { if (enable) { pr_debug("Enable Vdd dev_%d\n", dev_id); gpio_set_value_cansleep( PM8058_GPIO_PM_TO_SYS(PMIC_GPIO_SDC4_PWR_EN_N), 0); set_bit(dev_id, &vreg_sts); } else { pr_debug("Disable Vdd dev_%d\n", dev_id); gpio_set_value_cansleep( PM8058_GPIO_PM_TO_SYS(PMIC_GPIO_SDC4_PWR_EN_N), 1); clear_bit(dev_id, &vreg_sts); } } if (!enable || enabled_once[dev_id - 1]) return 0; if (!curr) return -ENODEV; if (IS_ERR(curr)) return PTR_ERR(curr); if (enable) { set_bit(dev_id, &vreg_sts); rc = regulator_enable(curr); if (rc) pr_err("%s: could not enable regulator: %d\n", __func__, rc); enabled_once[dev_id - 1] = 1; } else { clear_bit(dev_id, &vreg_sts); rc = regulator_disable(curr); if (rc) pr_err("%s: could not disable regulator: %d\n", __func__, rc); } return rc; } static uint32_t msm_sdcc_setup_power(struct device *dv, unsigned int vdd) { int rc = 0; struct platform_device *pdev; pdev = container_of(dv, struct platform_device, dev); rc = msm_sdcc_setup_gpio(pdev->id, (vdd ? 1 : 0)); if (rc) goto out; if (pdev->id == 4) /* S3 is always ON and cannot be disabled */ rc = msm_sdcc_setup_vreg(pdev->id, (vdd ? 1 : 0)); out: return rc; } #if defined(CONFIG_MMC_MSM_SDC1_SUPPORT) && \ defined(CONFIG_CSDIO_VENDOR_ID) && \ defined(CONFIG_CSDIO_DEVICE_ID) && \ (CONFIG_CSDIO_VENDOR_ID == 0x70 && CONFIG_CSDIO_DEVICE_ID == 0x1117) #define MBP_ON 1 #define MBP_OFF 0 #define MBP_RESET_N \ GPIO_CFG(44, 0, GPIO_CFG_OUTPUT, GPIO_CFG_NO_PULL, GPIO_CFG_8MA) #define MBP_INT0 \ GPIO_CFG(46, 0, GPIO_CFG_INPUT, GPIO_CFG_PULL_UP, GPIO_CFG_8MA) #define MBP_MODE_CTRL_0 \ GPIO_CFG(35, 0, GPIO_CFG_OUTPUT, GPIO_CFG_NO_PULL, GPIO_CFG_2MA) #define MBP_MODE_CTRL_1 \ GPIO_CFG(36, 0, GPIO_CFG_OUTPUT, GPIO_CFG_NO_PULL, GPIO_CFG_2MA) #define MBP_MODE_CTRL_2 \ GPIO_CFG(34, 0, GPIO_CFG_OUTPUT, GPIO_CFG_NO_PULL, GPIO_CFG_2MA) #define TSIF_EN \ GPIO_CFG(35, 1, GPIO_CFG_INPUT, GPIO_CFG_PULL_DOWN, GPIO_CFG_2MA) #define TSIF_DATA \ GPIO_CFG(36, 1, GPIO_CFG_INPUT, GPIO_CFG_PULL_DOWN, GPIO_CFG_2MA) #define TSIF_CLK \ GPIO_CFG(34, 1, GPIO_CFG_INPUT, GPIO_CFG_PULL_DOWN, GPIO_CFG_2MA) static struct msm_gpio mbp_cfg_data[] = { {GPIO_CFG(44, 0, GPIO_CFG_OUTPUT, GPIO_CFG_NO_PULL, GPIO_CFG_16MA), "mbp_reset"}, {GPIO_CFG(85, 0, GPIO_CFG_OUTPUT, GPIO_CFG_NO_PULL, GPIO_CFG_16MA), "mbp_io_voltage"}, }; static int mbp_config_gpios_pre_init(int enable) { int rc = 0; if (enable) { rc = msm_gpios_request_enable(mbp_cfg_data, ARRAY_SIZE(mbp_cfg_data)); if (rc) { printk(KERN_ERR "%s: Failed to turnon GPIOs for mbp chip(%d)\n", __func__, rc); } } else msm_gpios_disable_free(mbp_cfg_data, ARRAY_SIZE(mbp_cfg_data)); return rc; } static struct regulator_bulk_data mbp_regs_io[2]; static struct regulator_bulk_data mbp_regs_rf[2]; static struct regulator_bulk_data mbp_regs_adc[1]; static struct regulator_bulk_data mbp_regs_core[1]; static int mbp_init_regs(struct device *dev) { struct regulator_bulk_data regs[] = { /* Analog and I/O regs */ { .supply = "gp4", .min_uV = 2600000, .max_uV = 2600000 }, { .supply = "s3", .min_uV = 1800000, .max_uV = 1800000 }, /* RF regs */ { .supply = "s2", .min_uV = 1300000, .max_uV = 1300000 }, { .supply = "rf", .min_uV = 2600000, .max_uV = 2600000 }, /* ADC regs */ { .supply = "s4", .min_uV = 2200000, .max_uV = 2200000 }, /* Core regs */ { .supply = "gp16", .min_uV = 1200000, .max_uV = 1200000 }, }; struct regulator_bulk_data *regptr = regs; int rc; rc = regulator_bulk_get(dev, ARRAY_SIZE(regs), regs); if (rc) { dev_err(dev, "%s: could not get regulators: %d\n", __func__, rc); goto out; } rc = regulator_bulk_set_voltage(ARRAY_SIZE(regs), regs); if (rc) { dev_err(dev, "%s: could not set voltages: %d\n", __func__, rc); goto reg_free; } memcpy(mbp_regs_io, regptr, sizeof(mbp_regs_io)); regptr += ARRAY_SIZE(mbp_regs_io); memcpy(mbp_regs_rf, regptr, sizeof(mbp_regs_rf)); regptr += ARRAY_SIZE(mbp_regs_rf); memcpy(mbp_regs_adc, regptr, sizeof(mbp_regs_adc)); regptr += ARRAY_SIZE(mbp_regs_adc); memcpy(mbp_regs_core, regptr, sizeof(mbp_regs_core)); return 0; reg_free: regulator_bulk_free(ARRAY_SIZE(regs), regs); out: return rc; } static int mbp_setup_rf_vregs(int state) { return state ? regulator_bulk_enable(ARRAY_SIZE(mbp_regs_rf), mbp_regs_rf) : regulator_bulk_disable(ARRAY_SIZE(mbp_regs_rf), mbp_regs_rf); } static int mbp_setup_vregs(int state) { return state ? regulator_bulk_enable(ARRAY_SIZE(mbp_regs_io), mbp_regs_io) : regulator_bulk_disable(ARRAY_SIZE(mbp_regs_io), mbp_regs_io); } static int mbp_set_tcxo_en(int enable) { int rc; const char *id = "UBMC"; struct vreg *vreg_analog = NULL; rc = pmapp_clock_vote(id, PMAPP_CLOCK_ID_A1, enable ? PMAPP_CLOCK_VOTE_ON : PMAPP_CLOCK_VOTE_OFF); if (rc < 0) { printk(KERN_ERR "%s: unable to %svote for a1 clk\n", __func__, enable ? "" : "de-"); return -EIO; } return rc; } static void mbp_set_freeze_io(int state) { if (state) gpio_set_value(85, 0); else gpio_set_value(85, 1); } static int mbp_set_core_voltage_en(int enable) { static bool is_enabled; int rc = 0; if (enable && !is_enabled) { rc = regulator_bulk_enable(ARRAY_SIZE(mbp_regs_core), mbp_regs_core); if (rc) { pr_err("%s: could not enable regulators: %d\n", __func__, rc); } else { is_enabled = true; } } return rc; } static void mbp_set_reset(int state) { if (state) gpio_set_value(GPIO_PIN(MBP_RESET_N), 0); else gpio_set_value(GPIO_PIN(MBP_RESET_N), 1); } static int mbp_config_interface_mode(int state) { if (state) { gpio_tlmm_config(MBP_MODE_CTRL_0, GPIO_CFG_ENABLE); gpio_tlmm_config(MBP_MODE_CTRL_1, GPIO_CFG_ENABLE); gpio_tlmm_config(MBP_MODE_CTRL_2, GPIO_CFG_ENABLE); gpio_set_value(GPIO_PIN(MBP_MODE_CTRL_0), 0); gpio_set_value(GPIO_PIN(MBP_MODE_CTRL_1), 1); gpio_set_value(GPIO_PIN(MBP_MODE_CTRL_2), 0); } else { gpio_tlmm_config(MBP_MODE_CTRL_0, GPIO_CFG_DISABLE); gpio_tlmm_config(MBP_MODE_CTRL_1, GPIO_CFG_DISABLE); gpio_tlmm_config(MBP_MODE_CTRL_2, GPIO_CFG_DISABLE); } return 0; } static int mbp_setup_adc_vregs(int state) { return state ? regulator_bulk_enable(ARRAY_SIZE(mbp_regs_adc), mbp_regs_adc) : regulator_bulk_disable(ARRAY_SIZE(mbp_regs_adc), mbp_regs_adc); } static int mbp_power_up(void) { int rc; rc = mbp_config_gpios_pre_init(MBP_ON); if (rc) goto exit; pr_debug("%s: mbp_config_gpios_pre_init() done\n", __func__); rc = mbp_setup_vregs(MBP_ON); if (rc) goto exit; pr_debug("%s: gp4 (2.6) and s3 (1.8) done\n", __func__); rc = mbp_set_tcxo_en(MBP_ON); if (rc) goto exit; pr_debug("%s: tcxo clock done\n", __func__); mbp_set_freeze_io(MBP_OFF); pr_debug("%s: set gpio 85 to 1 done\n", __func__); udelay(100); mbp_set_reset(MBP_ON); udelay(300); rc = mbp_config_interface_mode(MBP_ON); if (rc) goto exit; pr_debug("%s: mbp_config_interface_mode() done\n", __func__); udelay(100 + mbp_set_core_voltage_en(MBP_ON)); pr_debug("%s: power gp16 1.2V done\n", __func__); mbp_set_freeze_io(MBP_ON); pr_debug("%s: set gpio 85 to 0 done\n", __func__); udelay(100); rc = mbp_setup_rf_vregs(MBP_ON); if (rc) goto exit; pr_debug("%s: s2 1.3V and rf 2.6V done\n", __func__); rc = mbp_setup_adc_vregs(MBP_ON); if (rc) goto exit; pr_debug("%s: s4 2.2V done\n", __func__); udelay(200); mbp_set_reset(MBP_OFF); pr_debug("%s: close gpio 44 done\n", __func__); msleep(20); exit: return rc; } static int mbp_power_down(void) { int rc; mbp_set_reset(MBP_ON); pr_debug("%s: mbp_set_reset(MBP_ON) done\n", __func__); udelay(100); rc = mbp_setup_adc_vregs(MBP_OFF); if (rc) goto exit; pr_debug("%s: vreg_disable(vreg_adc) done\n", __func__); udelay(5); rc = mbp_setup_rf_vregs(MBP_OFF); if (rc) goto exit; pr_debug("%s: mbp_setup_rf_vregs(MBP_OFF) done\n", __func__); udelay(5); mbp_set_freeze_io(MBP_OFF); pr_debug("%s: mbp_set_freeze_io(MBP_OFF) done\n", __func__); udelay(100); rc = mbp_set_core_voltage_en(MBP_OFF); if (rc) goto exit; pr_debug("%s: mbp_set_core_voltage_en(MBP_OFF) done\n", __func__); rc = mbp_set_tcxo_en(MBP_OFF); if (rc) goto exit; pr_debug("%s: mbp_set_tcxo_en(MBP_OFF) done\n", __func__); rc = mbp_setup_vregs(MBP_OFF); if (rc) goto exit; pr_debug("%s: mbp_setup_vregs(MBP_OFF) done\n", __func__); rc = mbp_config_gpios_pre_init(MBP_OFF); if (rc) goto exit; exit: return rc; } static void (*mbp_status_notify_cb)(int card_present, void *dev_id); static void *mbp_status_notify_cb_devid; static int mbp_power_status; static int mbp_power_init_done; static uint32_t mbp_setup_power(struct device *dv, unsigned int power_status) { int rc = 0; struct platform_device *pdev; pdev = container_of(dv, struct platform_device, dev); if (power_status == mbp_power_status) goto exit; if (power_status) { pr_debug("turn on power of mbp slot"); rc = mbp_power_up(); mbp_power_status = 1; } else { pr_debug("turn off power of mbp slot"); rc = mbp_power_down(); mbp_power_status = 0; } exit: return rc; }; int mbp_register_status_notify(void (*callback)(int, void *), void *dev_id) { mbp_status_notify_cb = callback; mbp_status_notify_cb_devid = dev_id; return 0; } static unsigned int mbp_status(struct device *dev) { return mbp_power_status; } static uint32_t msm_sdcc_setup_power_mbp(struct device *dv, unsigned int vdd) { struct platform_device *pdev; uint32_t rc = 0; pdev = container_of(dv, struct platform_device, dev); rc = msm_sdcc_setup_power(dv, vdd); if (rc) { pr_err("%s: Failed to setup power (%d)\n", __func__, rc); goto out; } if (!mbp_power_init_done) { rc = mbp_init_regs(dv); if (rc) { dev_err(dv, "%s: regulator init failed: %d\n", __func__, rc); goto out; } mbp_setup_power(dv, 1); mbp_setup_power(dv, 0); mbp_power_init_done = 1; } if (vdd >= 0x8000) { rc = mbp_setup_power(dv, (0x8000 == vdd) ? 0 : 1); if (rc) { pr_err("%s: Failed to config mbp chip power (%d)\n", __func__, rc); goto out; } if (mbp_status_notify_cb) { mbp_status_notify_cb(mbp_power_status, mbp_status_notify_cb_devid); } } out: /* should return 0 only */ return 0; } #endif #endif #ifdef CONFIG_MMC_MSM_SDC4_SUPPORT static unsigned int msm7x30_sdcc_slot_status(struct device *dev) { return (unsigned int) gpio_get_value_cansleep( PM8058_GPIO_PM_TO_SYS(PMIC_GPIO_SD_DET - 1)); } static int msm_sdcc_get_wpswitch(struct device *dv) { void __iomem *wp_addr = 0; uint32_t ret = 0; struct platform_device *pdev; if (!(machine_is_msm7x30_surf())) return -1; pdev = container_of(dv, struct platform_device, dev); wp_addr = ioremap(FPGA_SDCC_STATUS, 4); if (!wp_addr) { pr_err("%s: Could not remap %x\n", __func__, FPGA_SDCC_STATUS); return -ENOMEM; } ret = (((readl(wp_addr) >> 4) >> (pdev->id-1)) & 0x01); pr_info("%s: WP Status for Slot %d = 0x%x \n", __func__, pdev->id, ret); iounmap(wp_addr); return ret; } #endif #if defined(CONFIG_MMC_MSM_SDC1_SUPPORT) #if defined(CONFIG_CSDIO_VENDOR_ID) && \ defined(CONFIG_CSDIO_DEVICE_ID) && \ (CONFIG_CSDIO_VENDOR_ID == 0x70 && CONFIG_CSDIO_DEVICE_ID == 0x1117) static struct mmc_platform_data msm7x30_sdc1_data = { .ocr_mask = MMC_VDD_165_195 | MMC_VDD_27_28 | MMC_VDD_28_29, .translate_vdd = msm_sdcc_setup_power_mbp, .mmc_bus_width = MMC_CAP_4_BIT_DATA, .status = mbp_status, .register_status_notify = mbp_register_status_notify, .msmsdcc_fmin = 144000, .msmsdcc_fmid = 24576000, .msmsdcc_fmax = 24576000, .nonremovable = 0, }; #else static struct mmc_platform_data msm7x30_sdc1_data = { .ocr_mask = MMC_VDD_165_195, .translate_vdd = msm_sdcc_setup_power, .mmc_bus_width = MMC_CAP_4_BIT_DATA, .msmsdcc_fmin = 144000, .msmsdcc_fmid = 24576000, .msmsdcc_fmax = 49152000, .nonremovable = 0, }; #endif #endif #ifdef CONFIG_MMC_MSM_SDC2_SUPPORT static struct mmc_platform_data msm7x30_sdc2_data = { .ocr_mask = MMC_VDD_165_195 | MMC_VDD_27_28, .translate_vdd = msm_sdcc_setup_power, #ifdef CONFIG_MMC_MSM_SDC2_8_BIT_SUPPORT .mmc_bus_width = MMC_CAP_8_BIT_DATA, #else .mmc_bus_width = MMC_CAP_4_BIT_DATA, #endif .msmsdcc_fmin = 144000, .msmsdcc_fmid = 24576000, .msmsdcc_fmax = 49152000, .nonremovable = 1, }; #endif #ifdef CONFIG_MMC_MSM_SDC3_SUPPORT static struct mmc_platform_data msm7x30_sdc3_data = { .ocr_mask = MMC_VDD_27_28 | MMC_VDD_28_29, .translate_vdd = msm_sdcc_setup_power, .mmc_bus_width = MMC_CAP_4_BIT_DATA, .sdiowakeup_irq = MSM_GPIO_TO_INT(118), .msmsdcc_fmin = 144000, .msmsdcc_fmid = 24576000, .msmsdcc_fmax = 49152000, .nonremovable = 0, }; #endif #ifdef CONFIG_MMC_MSM_SDC4_SUPPORT static struct mmc_platform_data msm7x30_sdc4_data = { .ocr_mask = MMC_VDD_27_28 | MMC_VDD_28_29, .translate_vdd = msm_sdcc_setup_power, .mmc_bus_width = MMC_CAP_4_BIT_DATA, .status = msm7x30_sdcc_slot_status, .status_irq = PM8058_GPIO_IRQ(PMIC8058_IRQ_BASE, PMIC_GPIO_SD_DET - 1), .irq_flags = IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING, .wpswitch = msm_sdcc_get_wpswitch, .msmsdcc_fmin = 144000, .msmsdcc_fmid = 24576000, .msmsdcc_fmax = 49152000, .nonremovable = 0, }; #endif #ifdef CONFIG_MMC_MSM_SDC1_SUPPORT static int msm_sdc1_lvlshft_enable(void) { static struct regulator *ldo5; int rc; /* Enable LDO5, an input to the FET that powers slot 1 */ ldo5 = regulator_get(NULL, "ldo5"); if (IS_ERR(ldo5)) { rc = PTR_ERR(ldo5); pr_err("%s: could not get ldo5: %d\n", __func__, rc); goto out; } rc = regulator_set_voltage(ldo5, 2850000, 2850000); if (rc) { pr_err("%s: could not set ldo5 voltage: %d\n", __func__, rc); goto ldo5_free; } rc = regulator_enable(ldo5); if (rc) { pr_err("%s: could not enable ldo5: %d\n", __func__, rc); goto ldo5_free; } /* Enable GPIO 35, to turn on the FET that powers slot 1 */ rc = msm_gpios_request_enable(sdc1_lvlshft_cfg_data, ARRAY_SIZE(sdc1_lvlshft_cfg_data)); if (rc) printk(KERN_ERR "%s: Failed to enable GPIO 35\n", __func__); rc = gpio_direction_output(GPIO_PIN(sdc1_lvlshft_cfg_data[0].gpio_cfg), 1); if (rc) printk(KERN_ERR "%s: Failed to turn on GPIO 35\n", __func__); return 0; ldo5_free: regulator_put(ldo5); out: ldo5 = NULL; return rc; } #endif static int mmc_regulator_init(int sdcc_no, const char *supply, int uV) { int rc; BUG_ON(sdcc_no < 1 || sdcc_no > 4); sdcc_no--; sdcc_vreg_data[sdcc_no] = regulator_get(NULL, supply); if (IS_ERR(sdcc_vreg_data[sdcc_no])) { rc = PTR_ERR(sdcc_vreg_data[sdcc_no]); pr_err("%s: could not get regulator \"%s\": %d\n", __func__, supply, rc); goto out; } rc = regulator_set_voltage(sdcc_vreg_data[sdcc_no], uV, uV); if (rc) { pr_err("%s: could not set voltage for \"%s\" to %d uV: %d\n", __func__, supply, uV, rc); goto reg_free; } return rc; reg_free: regulator_put(sdcc_vreg_data[sdcc_no]); out: sdcc_vreg_data[sdcc_no] = NULL; return rc; } static void __init msm7x30_init_mmc(void) { #ifdef CONFIG_MMC_MSM_SDC1_SUPPORT if (mmc_regulator_init(1, "s3", 1800000)) goto out1; if (machine_is_msm7x30_fluid()) { msm7x30_sdc1_data.ocr_mask = MMC_VDD_27_28 | MMC_VDD_28_29; if (msm_sdc1_lvlshft_enable()) { pr_err("%s: could not enable level shift\n"); goto out1; } } msm_add_sdcc(1, &msm7x30_sdc1_data); out1: #endif #ifdef CONFIG_MMC_MSM_SDC2_SUPPORT if (mmc_regulator_init(2, "s3", 1800000)) goto out2; if (machine_is_msm8x55_svlte_surf()) msm7x30_sdc2_data.msmsdcc_fmax = 24576000; if (machine_is_msm8x55_svlte_surf() || machine_is_msm8x55_svlte_ffa()) { msm7x30_sdc2_data.sdiowakeup_irq = MSM_GPIO_TO_INT(68); msm7x30_sdc2_data.is_sdio_al_client = 1; } msm_add_sdcc(2, &msm7x30_sdc2_data); out2: #endif #ifdef CONFIG_MMC_MSM_SDC3_SUPPORT if (mmc_regulator_init(3, "s3", 1800000)) goto out3; msm_sdcc_setup_gpio(3, 1); msm_add_sdcc(3, &msm7x30_sdc3_data); out3: #endif #ifdef CONFIG_MMC_MSM_SDC4_SUPPORT if (mmc_regulator_init(4, "mmc", 2850000)) return; msm_add_sdcc(4, &msm7x30_sdc4_data); #endif } static void __init msm7x30_init_nand(void) { char *build_id; struct flash_platform_data *plat_data; build_id = socinfo_get_build_id(); if (build_id == NULL) { pr_err("%s: Build ID not available from socinfo\n", __func__); return; } if (build_id[8] == 'C' && !msm_gpios_request_enable(msm_nand_ebi2_cfg_data, ARRAY_SIZE(msm_nand_ebi2_cfg_data))) { plat_data = msm_device_nand.dev.platform_data; plat_data->interleave = 1; printk(KERN_INFO "%s: Interleave mode Build ID found\n", __func__); } } #ifdef CONFIG_SERIAL_MSM_CONSOLE static struct msm_gpio uart2_config_data[] = { { GPIO_CFG(49, 2, GPIO_CFG_OUTPUT, GPIO_CFG_PULL_DOWN, GPIO_CFG_2MA), "UART2_RFR"}, { GPIO_CFG(50, 2, GPIO_CFG_INPUT, GPIO_CFG_PULL_DOWN, GPIO_CFG_2MA), "UART2_CTS"}, { GPIO_CFG(51, 2, GPIO_CFG_INPUT, GPIO_CFG_PULL_DOWN, GPIO_CFG_2MA), "UART2_Rx"}, { GPIO_CFG(52, 2, GPIO_CFG_OUTPUT, GPIO_CFG_PULL_DOWN, GPIO_CFG_2MA), "UART2_Tx"}, }; static void msm7x30_init_uart2(void) { msm_gpios_request_enable(uart2_config_data, ARRAY_SIZE(uart2_config_data)); } #endif /* TSIF begin */ #if defined(CONFIG_TSIF) || defined(CONFIG_TSIF_MODULE) #define TSIF_B_SYNC GPIO_CFG(37, 1, GPIO_CFG_INPUT, GPIO_CFG_PULL_DOWN, GPIO_CFG_2MA) #define TSIF_B_DATA GPIO_CFG(36, 1, GPIO_CFG_INPUT, GPIO_CFG_PULL_DOWN, GPIO_CFG_2MA) #define TSIF_B_EN GPIO_CFG(35, 1, GPIO_CFG_INPUT, GPIO_CFG_PULL_DOWN, GPIO_CFG_2MA) #define TSIF_B_CLK GPIO_CFG(34, 1, GPIO_CFG_INPUT, GPIO_CFG_PULL_DOWN, GPIO_CFG_2MA) static const struct msm_gpio tsif_gpios[] = { { .gpio_cfg = TSIF_B_CLK, .label = "tsif_clk", }, { .gpio_cfg = TSIF_B_EN, .label = "tsif_en", }, { .gpio_cfg = TSIF_B_DATA, .label = "tsif_data", }, { .gpio_cfg = TSIF_B_SYNC, .label = "tsif_sync", }, }; static struct msm_tsif_platform_data tsif_platform_data = { .num_gpios = ARRAY_SIZE(tsif_gpios), .gpios = tsif_gpios, .tsif_pclk = "iface_clk", .tsif_ref_clk = "ref_clk", }; #endif /* defined(CONFIG_TSIF) || defined(CONFIG_TSIF_MODULE) */ /* TSIF end */ static void __init pmic8058_leds_init(void) { if (machine_is_msm7x30_surf()) pm8058_7x30_data.leds_pdata = &pm8058_surf_leds_data; else if (!machine_is_msm7x30_fluid()) pm8058_7x30_data.leds_pdata = &pm8058_ffa_leds_data; else if (machine_is_msm7x30_fluid()) pm8058_7x30_data.leds_pdata = &pm8058_fluid_leds_data; } static struct msm_spm_platform_data msm_spm_data __initdata = { .reg_base_addr = MSM_SAW0_BASE, .reg_init_values[MSM_SPM_REG_SAW_CFG] = 0x05, .reg_init_values[MSM_SPM_REG_SAW_SPM_CTL] = 0x18, .reg_init_values[MSM_SPM_REG_SAW_SPM_SLP_TMR_DLY] = 0x00006666, .reg_init_values[MSM_SPM_REG_SAW_SPM_WAKE_TMR_DLY] = 0xFF000666, .reg_init_values[MSM_SPM_REG_SAW_SLP_CLK_EN] = 0x01, .reg_init_values[MSM_SPM_REG_SAW_SLP_HSFS_PRECLMP_EN] = 0x03, .reg_init_values[MSM_SPM_REG_SAW_SLP_HSFS_POSTCLMP_EN] = 0x00, .reg_init_values[MSM_SPM_REG_SAW_SLP_CLMP_EN] = 0x01, .reg_init_values[MSM_SPM_REG_SAW_SLP_RST_EN] = 0x00, .reg_init_values[MSM_SPM_REG_SAW_SPM_MPM_CFG] = 0x00, .awake_vlevel = 0xF2, .retention_vlevel = 0xE0, .collapse_vlevel = 0x72, .retention_mid_vlevel = 0xE0, .collapse_mid_vlevel = 0xE0, .vctl_timeout_us = 50, }; #if defined(CONFIG_TOUCHSCREEN_TSC2007) || \ defined(CONFIG_TOUCHSCREEN_TSC2007_MODULE) #define TSC2007_TS_PEN_INT 20 static struct msm_gpio tsc2007_config_data[] = { { GPIO_CFG(TSC2007_TS_PEN_INT, 0, GPIO_CFG_INPUT, GPIO_CFG_NO_PULL, GPIO_CFG_2MA), "tsc2007_irq" }, }; static struct regulator_bulk_data tsc2007_regs[] = { { .supply = "s3", .min_uV = 1800000, .max_uV = 1800000 }, { .supply = "s2", .min_uV = 1300000, .max_uV = 1300000 }, }; static int tsc2007_init(void) { int rc; rc = regulator_bulk_get(NULL, ARRAY_SIZE(tsc2007_regs), tsc2007_regs); if (rc) { pr_err("%s: could not get regulators: %d\n", __func__, rc); goto out; } rc = regulator_bulk_set_voltage(ARRAY_SIZE(tsc2007_regs), tsc2007_regs); if (rc) { pr_err("%s: could not set voltages: %d\n", __func__, rc); goto reg_free; } rc = regulator_bulk_enable(ARRAY_SIZE(tsc2007_regs), tsc2007_regs); if (rc) { pr_err("%s: could not enable regulators: %d\n", __func__, rc); goto reg_free; } rc = msm_gpios_request_enable(tsc2007_config_data, ARRAY_SIZE(tsc2007_config_data)); if (rc) { pr_err("%s: Unable to request gpios\n", __func__); goto reg_disable; } return 0; reg_disable: regulator_bulk_disable(ARRAY_SIZE(tsc2007_regs), tsc2007_regs); reg_free: regulator_bulk_free(ARRAY_SIZE(tsc2007_regs), tsc2007_regs); out: return rc; } static int tsc2007_get_pendown_state(void) { int rc; rc = gpio_get_value(TSC2007_TS_PEN_INT); if (rc < 0) { pr_err("%s: MSM GPIO %d read failed\n", __func__, TSC2007_TS_PEN_INT); return rc; } return (rc == 0 ? 1 : 0); } static void tsc2007_exit(void) { regulator_bulk_disable(ARRAY_SIZE(tsc2007_regs), tsc2007_regs); regulator_bulk_free(ARRAY_SIZE(tsc2007_regs), tsc2007_regs); msm_gpios_disable_free(tsc2007_config_data, ARRAY_SIZE(tsc2007_config_data)); } static int tsc2007_power_shutdown(bool enable) { int rc; rc = (enable == false) ? regulator_bulk_enable(ARRAY_SIZE(tsc2007_regs), tsc2007_regs) : regulator_bulk_disable(ARRAY_SIZE(tsc2007_regs), tsc2007_regs); if (rc) { pr_err("%s: could not %sable regulators: %d\n", __func__, enable ? "dis" : "en", rc); return rc; } if (enable == false) msleep(20); return 0; } static struct tsc2007_platform_data tsc2007_ts_data = { .model = 2007, .x_plate_ohms = 300, .min_x = 210, .max_x = 3832, .min_y = 150, .max_y = 3936, .irq_flags = IRQF_TRIGGER_LOW, .init_platform_hw = tsc2007_init, .exit_platform_hw = tsc2007_exit, .power_shutdown = tsc2007_power_shutdown, .invert_x = true, .invert_y = true, /* REVISIT: Temporary fix for reversed pressure */ .invert_z1 = true, .invert_z2 = true, .get_pendown_state = tsc2007_get_pendown_state, }; static struct i2c_board_info tsc_i2c_board_info[] = { { I2C_BOARD_INFO("tsc2007", 0x48), .irq = MSM_GPIO_TO_INT(TSC2007_TS_PEN_INT), .platform_data = &tsc2007_ts_data, }, }; #endif static struct regulator_bulk_data regs_isa1200[] = { { .supply = "gp7", .min_uV = 1800000, .max_uV = 1800000 }, { .supply = "gp10", .min_uV = 2600000, .max_uV = 2600000 }, }; static int isa1200_power(int vreg_on) { int rc = 0; rc = vreg_on ? regulator_bulk_enable(ARRAY_SIZE(regs_isa1200), regs_isa1200) : regulator_bulk_disable(ARRAY_SIZE(regs_isa1200), regs_isa1200); if (rc) { pr_err("%s: could not %sable regulators: %d\n", __func__, vreg_on ? "en" : "dis", rc); goto out; } /* vote for DO buffer */ rc = pmapp_clock_vote("VIBR", PMAPP_CLOCK_ID_DO, vreg_on ? PMAPP_CLOCK_VOTE_ON : PMAPP_CLOCK_VOTE_OFF); if (rc) { pr_err("%s: unable to %svote for d0 clk\n", __func__, vreg_on ? "" : "de-"); goto vreg_fail; } return 0; vreg_fail: if (vreg_on) regulator_bulk_disable(ARRAY_SIZE(regs_isa1200), regs_isa1200); else regulator_bulk_enable(ARRAY_SIZE(regs_isa1200), regs_isa1200); out: return rc; } static int isa1200_dev_setup(bool enable) { int rc; if (enable == true) { rc = regulator_bulk_get(NULL, ARRAY_SIZE(regs_isa1200), regs_isa1200); if (rc) { pr_err("%s: could not get regulators: %d\n", __func__, rc); goto out; } rc = regulator_bulk_set_voltage(ARRAY_SIZE(regs_isa1200), regs_isa1200); if (rc) { pr_err("%s: could not set voltages: %d\n", __func__, rc); goto reg_free; } rc = gpio_tlmm_config(GPIO_CFG(HAP_LVL_SHFT_MSM_GPIO, 0, GPIO_CFG_OUTPUT, GPIO_CFG_NO_PULL, GPIO_CFG_2MA), GPIO_CFG_ENABLE); if (rc) { pr_err("%s: Could not configure gpio %d\n", __func__, HAP_LVL_SHFT_MSM_GPIO); goto reg_free; } rc = gpio_request(HAP_LVL_SHFT_MSM_GPIO, "haptics_shft_lvl_oe"); if (rc) { pr_err("%s: unable to request gpio %d (%d)\n", __func__, HAP_LVL_SHFT_MSM_GPIO, rc); goto reg_free; } gpio_set_value(HAP_LVL_SHFT_MSM_GPIO, 1); } else { regulator_bulk_free(ARRAY_SIZE(regs_isa1200), regs_isa1200); gpio_free(HAP_LVL_SHFT_MSM_GPIO); } return 0; reg_free: regulator_bulk_free(ARRAY_SIZE(regs_isa1200), regs_isa1200); out: return rc; } static struct isa1200_platform_data isa1200_1_pdata = { .name = "vibrator", .power_on = isa1200_power, .dev_setup = isa1200_dev_setup, .pwm_ch_id = 1, /*channel id*/ /*gpio to enable haptic*/ .hap_en_gpio = PM8058_GPIO_PM_TO_SYS(PMIC_GPIO_HAP_ENABLE), .hap_len_gpio = -1, .max_timeout = 15000, .mode_ctrl = PWM_GEN_MODE, .pwm_fd = { .pwm_div = 256, }, .is_erm = false, .smart_en = true, .ext_clk_en = true, .chip_en = 1, }; static struct i2c_board_info msm_isa1200_board_info[] = { { I2C_BOARD_INFO("isa1200_1", 0x90>>1), .platform_data = &isa1200_1_pdata, }, }; static int kp_flip_mpp_config(void) { struct pm8xxx_mpp_config_data kp_flip_mpp = { .type = PM8XXX_MPP_TYPE_D_INPUT, .level = PM8018_MPP_DIG_LEVEL_S3, .control = PM8XXX_MPP_DIN_TO_INT, }; return pm8xxx_mpp_config(PM8058_MPP_PM_TO_SYS(PM_FLIP_MPP), &kp_flip_mpp); } static struct flip_switch_pdata flip_switch_data = { .name = "kp_flip_switch", .flip_gpio = PM8058_GPIO_PM_TO_SYS(PM8058_GPIOS) + PM_FLIP_MPP, .left_key = KEY_OPEN, .right_key = KEY_CLOSE, .active_low = 0, .wakeup = 1, .flip_mpp_config = kp_flip_mpp_config, }; static struct platform_device flip_switch_device = { .name = "kp_flip_switch", .id = -1, .dev = { .platform_data = &flip_switch_data, } }; static struct regulator_bulk_data regs_tma300[] = { { .supply = "gp6", .min_uV = 3050000, .max_uV = 3100000 }, { .supply = "gp7", .min_uV = 1800000, .max_uV = 1800000 }, }; static int tma300_power(int vreg_on) { int rc; rc = vreg_on ? regulator_bulk_enable(ARRAY_SIZE(regs_tma300), regs_tma300) : regulator_bulk_disable(ARRAY_SIZE(regs_tma300), regs_tma300); if (rc) pr_err("%s: could not %sable regulators: %d\n", __func__, vreg_on ? "en" : "dis", rc); return rc; } #define TS_GPIO_IRQ 150 static int tma300_dev_setup(bool enable) { int rc; if (enable) { rc = regulator_bulk_get(NULL, ARRAY_SIZE(regs_tma300), regs_tma300); if (rc) { pr_err("%s: could not get regulators: %d\n", __func__, rc); goto out; } rc = regulator_bulk_set_voltage(ARRAY_SIZE(regs_tma300), regs_tma300); if (rc) { pr_err("%s: could not set voltages: %d\n", __func__, rc); goto reg_free; } /* enable interrupt gpio */ rc = gpio_tlmm_config(GPIO_CFG(TS_GPIO_IRQ, 0, GPIO_CFG_INPUT, GPIO_CFG_PULL_UP, GPIO_CFG_6MA), GPIO_CFG_ENABLE); if (rc) { pr_err("%s: Could not configure gpio %d\n", __func__, TS_GPIO_IRQ); goto reg_free; } /* virtual keys */ tma300_vkeys_attr.attr.name = "virtualkeys.msm_tma300_ts"; properties_kobj = kobject_create_and_add("board_properties", NULL); if (!properties_kobj) { pr_err("%s: failed to create a kobject " "for board_properties\n", __func__); rc = -ENOMEM; goto reg_free; } rc = sysfs_create_group(properties_kobj, &tma300_properties_attr_group); if (rc) { pr_err("%s: failed to create a sysfs entry %s\n", __func__, tma300_vkeys_attr.attr.name); goto kobj_free; } } else { regulator_bulk_free(ARRAY_SIZE(regs_tma300), regs_tma300); /* destroy virtual keys */ if (properties_kobj) { sysfs_remove_group(properties_kobj, &tma300_properties_attr_group); kobject_put(properties_kobj); } } return 0; kobj_free: kobject_put(properties_kobj); properties_kobj = NULL; reg_free: regulator_bulk_free(ARRAY_SIZE(regs_tma300), regs_tma300); out: return rc; } static struct cy8c_ts_platform_data cy8ctma300_pdata = { .power_on = tma300_power, .dev_setup = tma300_dev_setup, .ts_name = "msm_tma300_ts", .dis_min_x = 0, .dis_max_x = 479, .dis_min_y = 0, .dis_max_y = 799, .res_x = 479, .res_y = 1009, .min_tid = 1, .max_tid = 255, .min_touch = 0, .max_touch = 255, .min_width = 0, .max_width = 255, .invert_y = 1, .nfingers = 4, .irq_gpio = TS_GPIO_IRQ, .resout_gpio = -1, }; static struct i2c_board_info cy8ctma300_board_info[] = { { I2C_BOARD_INFO("cy8ctma300", 0x2), .platform_data = &cy8ctma300_pdata, } }; static void __init msm7x30_init(void) { int rc; unsigned smem_size; uint32_t usb_hub_gpio_cfg_value = GPIO_CFG(56, 0, GPIO_CFG_OUTPUT, GPIO_CFG_NO_PULL, GPIO_CFG_2MA); uint32_t soc_version = 0; soc_version = socinfo_get_version(); msm_clock_init(&msm7x30_clock_init_data); #ifdef CONFIG_SERIAL_MSM_CONSOLE msm7x30_init_uart2(); #endif msm_spm_init(&msm_spm_data, 1); platform_device_register(&msm7x30_device_acpuclk); if (machine_is_msm7x30_surf() || machine_is_msm7x30_fluid()) msm7x30_cfg_smsc911x(); #ifdef CONFIG_USB_MSM_OTG_72K if (SOCINFO_VERSION_MAJOR(soc_version) >= 2 && SOCINFO_VERSION_MINOR(soc_version) >= 1) { pr_debug("%s: SOC Version:2.(1 or more)\n", __func__); msm_otg_pdata.ldo_set_voltage = 0; } msm_device_otg.dev.platform_data = &msm_otg_pdata; #ifdef CONFIG_USB_GADGET msm_otg_pdata.swfi_latency = msm_pm_data [MSM_PM_SLEEP_MODE_RAMP_DOWN_AND_WAIT_FOR_INTERRUPT].latency; msm_device_gadget_peripheral.dev.platform_data = &msm_gadget_pdata; #endif #endif msm_uart_dm1_pdata.wakeup_irq = gpio_to_irq(136); msm_device_uart_dm1.dev.platform_data = &msm_uart_dm1_pdata; #if defined(CONFIG_TSIF) || defined(CONFIG_TSIF_MODULE) msm_device_tsif.dev.platform_data = &tsif_platform_data; #endif if (machine_is_msm7x30_fluid()) { msm_adc_pdata.dev_names = msm_adc_fluid_device_names; msm_adc_pdata.num_adc = ARRAY_SIZE(msm_adc_fluid_device_names); } else { msm_adc_pdata.dev_names = msm_adc_surf_device_names; msm_adc_pdata.num_adc = ARRAY_SIZE(msm_adc_surf_device_names); } pmic8058_leds_init(); buses_init(); #ifdef CONFIG_MSM_SSBI msm_device_ssbi_pmic1.dev.platform_data = &msm7x30_ssbi_pm8058_pdata; #endif platform_add_devices(msm_footswitch_devices, msm_num_footswitch_devices); platform_add_devices(devices, ARRAY_SIZE(devices)); #ifdef CONFIG_USB_EHCI_MSM_72K msm_add_host(0, &msm_usb_host_pdata); #endif #ifdef CONFIG_MSM_CAMERA_V4L2 msm7x30_init_cam(); #endif msm7x30_init_mmc(); msm7x30_init_nand(); msm_qsd_spi_init(); #ifdef CONFIG_SPI_QSD if (machine_is_msm7x30_fluid()) spi_register_board_info(lcdc_sharp_spi_board_info, ARRAY_SIZE(lcdc_sharp_spi_board_info)); else spi_register_board_info(lcdc_toshiba_spi_board_info, ARRAY_SIZE(lcdc_toshiba_spi_board_info)); #endif atv_dac_power_init(); sensors_ldo_init(); hdmi_init_regs(); msm_fb_add_devices(); msm_pm_set_platform_data(msm_pm_data, ARRAY_SIZE(msm_pm_data)); BUG_ON(msm_pm_boot_init(&msm_pm_boot_pdata)); msm_pm_register_irqs(); msm_device_i2c_init(); msm_device_i2c_2_init(); qup_device_i2c_init(); msm7x30_init_marimba(); #ifdef CONFIG_MSM7KV2_AUDIO snddev_poweramp_gpio_init(); snddev_hsed_voltage_init(); aux_pcm_gpio_init(); #endif i2c_register_board_info(0, msm_i2c_board_info, ARRAY_SIZE(msm_i2c_board_info)); if (!machine_is_msm8x55_svlte_ffa() && !machine_is_msm7x30_fluid()) marimba_pdata.tsadc = &marimba_tsadc_pdata; if (machine_is_msm7x30_fluid()) i2c_register_board_info(0, cy8info, ARRAY_SIZE(cy8info)); #ifdef CONFIG_BOSCH_BMA150 if (machine_is_msm7x30_fluid()) i2c_register_board_info(0, bma150_board_info, ARRAY_SIZE(bma150_board_info)); #endif i2c_register_board_info(2, msm_marimba_board_info, ARRAY_SIZE(msm_marimba_board_info)); i2c_register_board_info(2, msm_i2c_gsbi7_timpani_info, ARRAY_SIZE(msm_i2c_gsbi7_timpani_info)); i2c_register_board_info(4 /* QUP ID */, msm_camera_boardinfo, ARRAY_SIZE(msm_camera_boardinfo)); bt_power_init(); #ifdef CONFIG_I2C_SSBI msm_device_ssbi7.dev.platform_data = &msm_i2c_ssbi7_pdata; #endif if (machine_is_msm7x30_fluid()) i2c_register_board_info(0, msm_isa1200_board_info, ARRAY_SIZE(msm_isa1200_board_info)); #if defined(CONFIG_TOUCHSCREEN_TSC2007) || \ defined(CONFIG_TOUCHSCREEN_TSC2007_MODULE) if (machine_is_msm8x55_svlte_ffa()) i2c_register_board_info(2, tsc_i2c_board_info, ARRAY_SIZE(tsc_i2c_board_info)); #endif if (machine_is_msm7x30_surf()) platform_device_register(&flip_switch_device); pm8058_gpios_init(); if (machine_is_msm7x30_fluid()) { /* Initialize platform data for fluid v2 hardware */ if (SOCINFO_VERSION_MAJOR( socinfo_get_platform_version()) == 2) { cy8ctma300_pdata.res_y = 920; cy8ctma300_pdata.invert_y = 0; } i2c_register_board_info(0, cy8ctma300_board_info, ARRAY_SIZE(cy8ctma300_board_info)); } if (machine_is_msm8x55_svlte_surf() || machine_is_msm8x55_svlte_ffa()) { rc = gpio_tlmm_config(usb_hub_gpio_cfg_value, GPIO_CFG_ENABLE); if (rc) pr_err("%s: gpio_tlmm_config(%#x)=%d\n", __func__, usb_hub_gpio_cfg_value, rc); } boot_reason = *(unsigned int *) (smem_get_entry(SMEM_POWER_ON_STATUS_INFO, &smem_size)); printk(KERN_NOTICE "Boot Reason = 0x%02x\n", boot_reason); } static unsigned pmem_sf_size = MSM_PMEM_SF_SIZE; static int __init pmem_sf_size_setup(char *p) { pmem_sf_size = memparse(p, NULL); return 0; } early_param("pmem_sf_size", pmem_sf_size_setup); static unsigned fb_size; static int __init fb_size_setup(char *p) { fb_size = memparse(p, NULL); return 0; } early_param("fb_size", fb_size_setup); static unsigned pmem_adsp_size = MSM_PMEM_ADSP_SIZE; static int __init pmem_adsp_size_setup(char *p) { pmem_adsp_size = memparse(p, NULL); return 0; } early_param("pmem_adsp_size", pmem_adsp_size_setup); static unsigned fluid_pmem_adsp_size = MSM_FLUID_PMEM_ADSP_SIZE; static int __init fluid_pmem_adsp_size_setup(char *p) { fluid_pmem_adsp_size = memparse(p, NULL); return 0; } early_param("fluid_pmem_adsp_size", fluid_pmem_adsp_size_setup); static unsigned pmem_audio_size = MSM_PMEM_AUDIO_SIZE; static int __init pmem_audio_size_setup(char *p) { pmem_audio_size = memparse(p, NULL); return 0; } early_param("pmem_audio_size", pmem_audio_size_setup); static unsigned pmem_kernel_ebi0_size = PMEM_KERNEL_EBI0_SIZE; static int __init pmem_kernel_ebi0_size_setup(char *p) { pmem_kernel_ebi0_size = memparse(p, NULL); return 0; } early_param("pmem_kernel_ebi0_size", pmem_kernel_ebi0_size_setup); #ifdef CONFIG_ION_MSM #ifdef CONFIG_MSM_MULTIMEDIA_USE_ION static struct ion_co_heap_pdata co_ion_pdata = { .adjacent_mem_id = INVALID_HEAP_ID, .align = PAGE_SIZE, }; #endif /** * These heaps are listed in the order they will be allocated. * Don't swap the order unless you know what you are doing! */ struct ion_platform_heap msm7x30_heaps[] = { { .id = ION_SYSTEM_HEAP_ID, .type = ION_HEAP_TYPE_SYSTEM, .name = ION_VMALLOC_HEAP_NAME, }, #ifdef CONFIG_MSM_MULTIMEDIA_USE_ION /* PMEM_ADSP = CAMERA */ { .id = ION_CAMERA_HEAP_ID, .type = ION_HEAP_TYPE_CARVEOUT, .name = ION_CAMERA_HEAP_NAME, .memory_type = ION_EBI_TYPE, .extra_data = (void *)&co_ion_pdata, }, /* PMEM_AUDIO */ { .id = ION_AUDIO_HEAP_ID, .type = ION_HEAP_TYPE_CARVEOUT, .name = ION_AUDIO_HEAP_NAME, .memory_type = ION_EBI_TYPE, .extra_data = (void *)&co_ion_pdata, }, /* PMEM_MDP = SF */ { .id = ION_SF_HEAP_ID, .type = ION_HEAP_TYPE_CARVEOUT, .name = ION_SF_HEAP_NAME, .memory_type = ION_EBI_TYPE, .extra_data = (void *)&co_ion_pdata, }, #endif }; static struct ion_platform_data ion_pdata = { .nr = MSM_ION_HEAP_NUM, .heaps = msm7x30_heaps, }; static struct platform_device ion_dev = { .name = "ion-msm", .id = 1, .dev = { .platform_data = &ion_pdata }, }; #endif static struct memtype_reserve msm7x30_reserve_table[] __initdata = { [MEMTYPE_SMI] = { }, [MEMTYPE_EBI0] = { .flags = MEMTYPE_FLAGS_1M_ALIGN, }, [MEMTYPE_EBI1] = { .flags = MEMTYPE_FLAGS_1M_ALIGN, }, }; unsigned long size; unsigned long msm_ion_camera_size; static void fix_sizes(void) { if machine_is_msm7x30_fluid() size = fluid_pmem_adsp_size; else size = pmem_adsp_size; #ifdef CONFIG_ION_MSM msm_ion_camera_size = size; #endif } static void __init reserve_mdp_memory(void) { mdp_pdata.ov0_wb_size = MSM_FB_OVERLAY0_WRITEBACK_SIZE; msm7x30_reserve_table[mdp_pdata.mem_hid].size += mdp_pdata.ov0_wb_size; } static void __init size_ion_devices(void) { #ifdef CONFIG_MSM_MULTIMEDIA_USE_ION ion_pdata.heaps[1].size = msm_ion_camera_size; ion_pdata.heaps[2].size = MSM_ION_AUDIO_SIZE; ion_pdata.heaps[3].size = MSM_ION_SF_SIZE; #endif } static void __init reserve_ion_memory(void) { #if defined(CONFIG_ION_MSM) && defined(CONFIG_MSM_MULTIMEDIA_USE_ION) msm7x30_reserve_table[MEMTYPE_EBI0].size += msm_ion_camera_size; msm7x30_reserve_table[MEMTYPE_EBI0].size += MSM_ION_AUDIO_SIZE; msm7x30_reserve_table[MEMTYPE_EBI0].size += MSM_ION_SF_SIZE; #endif } static void __init msm7x30_calculate_reserve_sizes(void) { fix_sizes(); reserve_mdp_memory(); size_ion_devices(); reserve_ion_memory(); } static int msm7x30_paddr_to_memtype(unsigned int paddr) { if (paddr < phys_add) return MEMTYPE_EBI0; if (paddr >= phys_add && paddr < 0x80000000) return MEMTYPE_EBI1; return MEMTYPE_NONE; } static struct reserve_info msm7x30_reserve_info __initdata = { .memtype_reserve_table = msm7x30_reserve_table, .calculate_reserve_sizes = msm7x30_calculate_reserve_sizes, .paddr_to_memtype = msm7x30_paddr_to_memtype, }; static void __init msm7x30_reserve(void) { reserve_info = &msm7x30_reserve_info; msm_reserve(); } static void __init msm7x30_allocate_memory_regions(void) { void *addr; unsigned long size; size = fb_size ? : MSM_FB_SIZE; addr = alloc_bootmem_align(size, 0x1000); msm_fb_resources[0].start = __pa(addr); msm_fb_resources[0].end = msm_fb_resources[0].start + size - 1; pr_info("allocating %lu bytes at %p (%lx physical) for fb\n", size, addr, __pa(addr)); #ifdef CONFIG_MSM_V4L2_VIDEO_OVERLAY_DEVICE size = MSM_V4L2_VIDEO_OVERLAY_BUF_SIZE; addr = alloc_bootmem_align(size, 0x1000); msm_v4l2_video_overlay_resources[0].start = __pa(addr); msm_v4l2_video_overlay_resources[0].end = msm_v4l2_video_overlay_resources[0].start + size - 1; pr_debug("allocating %lu bytes at %p (%lx physical) for v4l2\n", size, addr, __pa(addr)); #endif } static void __init msm7x30_map_io(void) { msm_shared_ram_phys = 0x00100000; msm_map_msm7x30_io(); if (socinfo_init() < 0) pr_err("socinfo_init() failed!\n"); } static void __init msm7x30_init_early(void) { msm7x30_allocate_memory_regions(); } static void __init msm7x30_fixup(struct tag *tags, char **cmdline, struct meminfo *mi) { for (; tags->hdr.size; tags = tag_next(tags)) { if (tags->hdr.tag == ATAG_MEM && tags->u.mem.start == DDR1_BANK_BASE) { ebi1_phys_offset = DDR1_BANK_BASE; phys_add = DDR1_BANK_BASE; break; } } } MACHINE_START(MSM7X30_SURF, "QCT MSM7X30 SURF") .atag_offset = 0x100, .map_io = msm7x30_map_io, .reserve = msm7x30_reserve, .init_irq = msm7x30_init_irq, .init_machine = msm7x30_init, .timer = &msm_timer, .init_early = msm7x30_init_early, .handle_irq = vic_handle_irq, .fixup = msm7x30_fixup, MACHINE_END MACHINE_START(MSM7X30_FFA, "QCT MSM7X30 FFA") .atag_offset = 0x100, .map_io = msm7x30_map_io, .reserve = msm7x30_reserve, .init_irq = msm7x30_init_irq, .init_machine = msm7x30_init, .timer = &msm_timer, .init_early = msm7x30_init_early, .handle_irq = vic_handle_irq, .fixup = msm7x30_fixup, MACHINE_END MACHINE_START(MSM7X30_FLUID, "QCT MSM7X30 FLUID") .atag_offset = 0x100, .map_io = msm7x30_map_io, .reserve = msm7x30_reserve, .init_irq = msm7x30_init_irq, .init_machine = msm7x30_init, .timer = &msm_timer, .init_early = msm7x30_init_early, .handle_irq = vic_handle_irq, .fixup = msm7x30_fixup, MACHINE_END MACHINE_START(MSM8X55_SURF, "QCT MSM8X55 SURF") .atag_offset = 0x100, .map_io = msm7x30_map_io, .reserve = msm7x30_reserve, .init_irq = msm7x30_init_irq, .init_machine = msm7x30_init, .timer = &msm_timer, .init_early = msm7x30_init_early, .handle_irq = vic_handle_irq, .fixup = msm7x30_fixup, MACHINE_END MACHINE_START(MSM8X55_FFA, "QCT MSM8X55 FFA") .atag_offset = 0x100, .map_io = msm7x30_map_io, .reserve = msm7x30_reserve, .init_irq = msm7x30_init_irq, .init_machine = msm7x30_init, .timer = &msm_timer, .init_early = msm7x30_init_early, .handle_irq = vic_handle_irq, .fixup = msm7x30_fixup, MACHINE_END MACHINE_START(MSM8X55_SVLTE_SURF, "QCT MSM8X55 SVLTE SURF") .atag_offset = 0x100, .map_io = msm7x30_map_io, .reserve = msm7x30_reserve, .init_irq = msm7x30_init_irq, .init_machine = msm7x30_init, .timer = &msm_timer, .init_early = msm7x30_init_early, .handle_irq = vic_handle_irq, .fixup = msm7x30_fixup, MACHINE_END MACHINE_START(MSM8X55_SVLTE_FFA, "QCT MSM8X55 SVLTE FFA") .atag_offset = 0x100, .map_io = msm7x30_map_io, .reserve = msm7x30_reserve, .init_irq = msm7x30_init_irq, .init_machine = msm7x30_init, .timer = &msm_timer, .init_early = msm7x30_init_early, .handle_irq = vic_handle_irq, .fixup = msm7x30_fixup, MACHINE_END