--- zzzz-none-000/linux-3.10.107/arch/arm/mach-msm/board-msm7x30.c 2017-06-27 09:49:32.000000000 +0000 +++ vr9-7490-729/linux-3.10.107/arch/arm/mach-msm/board-msm7x30.c 2021-11-10 11:53:52.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (c) 2009-2010, Code Aurora Forum. All rights reserved. +/* Copyright (c) 2009-2012, 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 @@ -9,114 +9,5938 @@ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. */ -#include + #include #include #include #include +#include #include +#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 +#include #include +#include + #include "devices.h" -#include "gpiomux.h" -#include "proc_comm.h" -#include "common.h" - -static void __init msm7x30_fixup(struct tag *tag, char **cmdline, - struct meminfo *mi) -{ - for (; tag->hdr.size; tag = tag_next(tag)) - if (tag->hdr.tag == ATAG_MEM && tag->u.mem.start == 0x200000) { - tag->u.mem.start = 0; - tag->u.mem.size += SZ_2M; +#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 + +#define MSM_FB_EXT_BUF_SIZE 0 + +#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; } -static void __init msm7x30_reserve(void) +/* 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) { - memblock_remove(0x0, SZ_2M); + 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 int hsusb_phy_init_seq[] = { - 0x30, 0x32, /* Enable and set Pre-Emphasis Depth to 20% */ - 0x02, 0x36, /* Disable CDR Auto Reset feature */ - -1 +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, +}; + + +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_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 + + + +#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 = { - .phy_init_seq = hsusb_phy_init_seq, - .mode = USB_PERIPHERAL, - .otg_control = OTG_PHY_CONTROL, + .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, }; -struct msm_gpiomux_config msm_gpiomux_configs[GPIOMUX_NGPIOS] = { -#ifdef CONFIG_SERIAL_MSM_CONSOLE - [49] = { /* UART2 RFR */ - .suspended = GPIOMUX_DRV_2MA | GPIOMUX_PULL_DOWN | - GPIOMUX_FUNC_2 | GPIOMUX_VALID, - }, - [50] = { /* UART2 CTS */ - .suspended = GPIOMUX_DRV_2MA | GPIOMUX_PULL_DOWN | - GPIOMUX_FUNC_2 | GPIOMUX_VALID, - }, - [51] = { /* UART2 RX */ - .suspended = GPIOMUX_DRV_2MA | GPIOMUX_PULL_DOWN | - GPIOMUX_FUNC_2 | GPIOMUX_VALID, - }, - [52] = { /* UART2 TX */ - .suspended = GPIOMUX_DRV_2MA | GPIOMUX_PULL_DOWN | - GPIOMUX_FUNC_2 | GPIOMUX_VALID, +#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 + +static struct android_pmem_platform_data android_pmem_pdata = { + .name = "pmem", + .allocator_type = PMEM_ALLOCATORTYPE_ALLORNOTHING, + .cached = 1, + .memory_type = MEMTYPE_EBI0, +}; + +static struct platform_device android_pmem_device = { + .name = "android_pmem", + .id = 0, + .dev = { .platform_data = &android_pmem_pdata }, +}; + +#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_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, + } +}; + + +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, + } +}; + + +static struct platform_device msm_migrate_pages_device = { + .name = "msm_migrate_pages", + .id = -1, +}; + +static struct android_pmem_platform_data android_pmem_adsp_pdata = { + .name = "pmem_adsp", + .allocator_type = PMEM_ALLOCATORTYPE_BITMAP, + .cached = 0, + .memory_type = MEMTYPE_EBI0, +}; + +static struct android_pmem_platform_data android_pmem_audio_pdata = { + .name = "pmem_audio", + .allocator_type = PMEM_ALLOCATORTYPE_BITMAP, + .cached = 0, + .memory_type = MEMTYPE_EBI0, +}; + +static struct platform_device android_pmem_adsp_device = { + .name = "android_pmem", + .id = 2, + .dev = { .platform_data = &android_pmem_adsp_pdata }, +}; + +static struct platform_device android_pmem_audio_device = { + .name = "android_pmem", + .id = 4, + .dev = { .platform_data = &android_pmem_audio_pdata }, +}; + +#if \ + defined(CONFIG_CRYPTO_DEV_QCRYPTO_MODULE) || \ + \ + 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_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_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); +} + +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, + } +}; + +#define bt_power_init(x) do {} while (0) + +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, + }, +}; + + static struct platform_device *devices[] __initdata = { - &msm_device_gpio_7x30, -#if defined(CONFIG_SERIAL_MSM) || defined(CONFIG_MSM_SERIAL_DEBUGGER) - &msm_device_uart2, +#if defined(CONFIG_SERIAL_MSM) + &msm_device_uart2, +#endif +#ifdef CONFIG_MSM_PROC_COMM_REGULATOR + &msm_proccomm_regulator_dev, #endif + &asoc_msm_pcm, + &asoc_msm_dai0, + &asoc_msm_dai1, &msm_device_smd, - &msm_device_otg, - &msm_device_hsusb, - &msm_device_hsusb_host, + &msm_device_dmov, + &smc91x_device, + &smsc911x_device, + &msm_device_nand, +#ifdef CONFIG_USB_G_ANDROID + &android_usb_device, +#endif + &qsd_device_spi, + + &android_pmem_device, + &msm_fb_device, + &msm_migrate_pages_device, + &mddi_toshiba_device, + &lcdc_toshiba_panel_device, + &lcdc_sharp_panel_device, + &android_pmem_adsp_device, + &android_pmem_audio_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, + &msm_kgsl_3d0, + &msm_kgsl_2d0, +#if defined(CONFIG_TSIF) || defined(CONFIG_TSIF_MODULE) + &msm_device_tsif, +#endif + +#if \ + defined(CONFIG_CRYPTO_DEV_QCRYPTO_MODULE) + &qcrypto_device, +#endif + +#if \ + 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 +} + + 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) { - msm_device_otg.dev.platform_data = &msm_otg_pdata; - msm_device_hsusb.dev.parent = &msm_device_otg.dev; - msm_device_hsusb_host.dev.parent = &msm_device_otg.dev; + 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(); + + 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(); + + + 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 + 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)); + + bt_power_init(); + 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_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; + +static void fix_sizes(void) +{ + if machine_is_msm7x30_fluid() + size = fluid_pmem_adsp_size; + else + size = pmem_adsp_size; +} + +static void __init size_pmem_devices(void) +{ +} + + +static void __init reserve_pmem_memory(void) +{ +} + +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 = 0; + 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_AUDIO_SIZE; + msm7x30_reserve_table[MEMTYPE_EBI0].size += MSM_ION_SF_SIZE; +#endif +} + +static void __init msm7x30_calculate_reserve_sizes(void) +{ + fix_sizes(); + size_pmem_devices(); + reserve_pmem_memory(); + 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)); + } static void __init msm7x30_map_io(void) { + msm_shared_ram_phys = 0x00100000; msm_map_msm7x30_io(); - msm_clock_init(msm_clocks_7x30, msm_num_clocks_7x30); + if (socinfo_init() < 0) + printk(KERN_ERR "%s: socinfo_init() failed!\n", + __func__); +} + +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; + } + } } static void __init msm7x30_init_late(void) @@ -126,33 +5950,85 @@ MACHINE_START(MSM7X30_SURF, "QCT MSM7X30 SURF") .atag_offset = 0x100, - .fixup = msm7x30_fixup, - .reserve = msm7x30_reserve, .map_io = msm7x30_map_io, + .reserve = msm7x30_reserve, .init_irq = msm7x30_init_irq, .init_machine = msm7x30_init, .init_late = msm7x30_init_late, - .init_time = msm7x30_timer_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, .init_late = msm7x30_init_late, - .init_time = msm7x30_timer_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") +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, .init_late = msm7x30_init_late, - .init_time = msm7x30_timer_init, + .timer = &msm_timer, + .init_early = msm7x30_init_early, + .handle_irq = vic_handle_irq, + .fixup = msm7x30_fixup, MACHINE_END