/* callback for battery check * return : bool * true - battery detected, false battery NOT detected */ bool sec_bat_check_callback(struct sec_battery_info *battery) { struct power_supply *psy; union power_supply_propval value; pr_info("%s: battery->pdata->bat_irq_gpio(%d)\n", __func__, battery->pdata->bat_irq_gpio); psy = get_power_supply_by_name(("sec-charger")); if (!psy) { pr_err("%s: Fail to get psy (%s)\n", __func__, "sec-charger"); value.intval = 1; } else { if (battery->pdata->bat_irq_gpio > 0) { value.intval = !gpio_get_value(battery->pdata->bat_irq_gpio); pr_info("%s: Battery status(%d)\n", __func__, value.intval); if (value.intval == 0) { return value.intval; } #if defined(CONFIG_MACH_HLTEATT) || defined(CONFIG_MACH_HLTESPR) || \ defined(CONFIG_MACH_HLTEVZW) || defined(CONFIG_MACH_HLTETMO) || \ defined(CONFIG_MACH_HLTEUSC) { int data, ret; struct qpnp_vadc_result result; struct qpnp_pin_cfg adc_param = { .mode = 4, .ain_route = 3, .src_sel = 0, .master_en =1, }; struct qpnp_pin_cfg int_param = { .mode = 0, .vin_sel = 2, .src_sel = 0, .master_en =1, }; ret = qpnp_pin_config(battery->pdata->bat_irq_gpio, &adc_param); if (ret < 0) pr_info("%s: qpnp config error: %d\n", __func__, ret); /* check the adc from vf pin */ qpnp_vadc_read(NULL, P_MUX8_1_3, &result); data = ((int)result.physical) / 1000; pr_info("%s: (%dmV) is connected.\n", __func__, data); if(data < SHORT_BATTERY_STANDARD) { pr_info("%s: Short Battery(%dmV) is connected.\n", __func__, data); value.intval = 0; } ret = qpnp_pin_config(battery->pdata->bat_irq_gpio, &int_param); if (ret < 0) pr_info("%s: qpnp config error int: %d\n", __func__, ret); } #endif } else { int ret; ret = psy->get_property(psy, POWER_SUPPLY_PROP_PRESENT, &(value)); if (ret < 0) { pr_err("%s: Fail to sec-charger get_property (%d=>%d)\n", __func__, POWER_SUPPLY_PROP_PRESENT, ret); value.intval = 1; } } } return value.intval; }
static void sii8240_charger_mhl_cb(bool otg_enable, int charger) { struct sii8240_platform_data *pdata = g_pdata; union power_supply_propval value; int i, ret = 0; struct power_supply *psy; pdata->charging_type = POWER_SUPPLY_TYPE_MISC; ret = sii8240_muic_get_charging_type(); if (ret < 0) { pr_info("%s: It's not mhl cable type!\n", __func__); return; } pr_info("%s: otg_enable : %d, charger: %d\n", __func__, otg_enable, charger); if (charger == 0x00) { pr_info("%s() TA charger 500mA\n", __func__); pdata->charging_type = POWER_SUPPLY_TYPE_MHL_500; } else if (charger == 0x01) { pr_info("%s() TA charger 900mA\n", __func__); pdata->charging_type = POWER_SUPPLY_TYPE_MHL_900; } else if (charger == 0x02) { pr_info("%s() TA charger 1500mA\n", __func__); pdata->charging_type = POWER_SUPPLY_TYPE_MHL_1500; } else if (charger == 0x03) { pr_info("%s() USB charger\n", __func__); pdata->charging_type = POWER_SUPPLY_TYPE_MHL_USB; } else pdata->charging_type = POWER_SUPPLY_TYPE_BATTERY; if (otg_enable) { if (!sii8240_vbus_present()) { #ifdef CONFIG_SAMSUNG_LPM_MODE if (!poweroff_charging) { #else { #endif if (pdata->muic_otg_set) pdata->muic_otg_set(true); pdata->charging_type = POWER_SUPPLY_TYPE_OTG; } } } else { if (pdata->muic_otg_set) pdata->muic_otg_set(false); } for (i = 0; i < 10; i++) { psy = power_supply_get_by_name("battery"); if (psy) break; } if (i == 10) { pr_err("[ERROR] %s: fail to get battery ps\n", __func__); return; } value.intval = pdata->charging_type; ret = psy->set_property(psy, POWER_SUPPLY_PROP_ONLINE, &value); if (ret) { pr_err("[ERROR] %s: fail to set power_suppy ONLINE property(%d)\n", __func__, ret); return; } } static void of_sii8240_gpio_init(void) { struct sii8240_platform_data *pdata = g_pdata; if (pdata->gpio_mhl_en > 0) { if (gpio_request(pdata->gpio_mhl_en, "mhl_en")) { pr_err("[ERROR] %s: unable to request gpio_mhl_en [%d]\n", __func__, pdata->gpio_mhl_en); return; } if (gpio_direction_output(pdata->gpio_mhl_en, 0)) { pr_err("[ERROR] %s: unable to gpio_mhl_en low[%d]\n", __func__, pdata->gpio_mhl_en); return; } } if (pdata->gpio_mhl_reset > 0) { if (gpio_request(pdata->gpio_mhl_reset, "mhl_reset")) { pr_err("[ERROR] %s: unable to request gpio_mhl_reset [%d]\n", __func__, pdata->gpio_mhl_reset); return; } if (gpio_direction_output(pdata->gpio_mhl_reset, 0)) { pr_err("[ERROR] %s: unable to gpio_mhl_reset low[%d]\n", __func__, pdata->gpio_mhl_reset); return; } } if (pdata->drm_workaround) msm_gpiomux_install(msm_hdmi_ddc_configs, ARRAY_SIZE(msm_hdmi_ddc_configs)); /* if(pdata->gpio_barcode_emul) { ice_gpiox_get(FPGA_GPIO_MHL_EN); ice_gpiox_get(FPGA_GPIO_MHL_RST); }*/ } static void of_sii8240_gpio_config(enum mhl_sleep_state sleep_status) { struct sii8240_platform_data *pdata = g_pdata; int ret; pr_info("%s() %s - reset_pin_type(%d), en_pin_type(%d)\n", __func__, sleep_status ? "resume" : "suspend", pdata->gpio_mhl_reset_type, pdata->gpio_mhl_en_type); if (pdata->gpio_barcode_emul) { gpio_tlmm_config(GPIO_CFG(pdata->gpio_mhl_reset, 0, GPIO_CFG_OUTPUT, GPIO_CFG_PULL_DOWN, GPIO_CFG_2MA), 1); gpio_tlmm_config(GPIO_CFG(pdata->gpio_mhl_en, 0, GPIO_CFG_INPUT, GPIO_CFG_PULL_DOWN, GPIO_CFG_2MA), 1); return; } if (sleep_status == MHL_SUSPEND_STATE) { if (pdata->gpio_mhl_reset) { switch (pdata->gpio_mhl_reset_type) { case MHL_GPIO_AP_GPIO: gpio_tlmm_config(GPIO_CFG(pdata->gpio_mhl_reset, 0, GPIO_CFG_INPUT, GPIO_CFG_NO_PULL, GPIO_CFG_2MA), 1); break; case MHL_GPIO_PM_GPIO: ret = qpnp_pin_config(pdata->gpio_mhl_reset, &MHL_PIN_PM_GPIO_MHL_RESET_SLEEP); if (unlikely(ret < 0)) pr_err("[ERROR] %s() set gpio_mhl_reset\n", __func__); break; case MHL_GPIO_PM_MPP: ret = qpnp_pin_config(pdata->gpio_mhl_reset, &MHL_PIN_PM_MPP_SLEEP); if (unlikely(ret < 0)) pr_err("[ERROR] %s() set gpio_mhl_reset\n", __func__); break; default: pr_err("[ERROR] %s() unknown gpio_mhl_reset's type\n", __func__); break; } } else { pr_err("[ERROR] %s() gpio_mhl_reset is NULL\n", __func__); } if (pdata->gpio_mhl_en) { switch (pdata->gpio_mhl_en_type) { case MHL_GPIO_AP_GPIO: gpio_tlmm_config(GPIO_CFG(pdata->gpio_mhl_en, 0, GPIO_CFG_INPUT, GPIO_CFG_NO_PULL, GPIO_CFG_2MA), 1); break; case MHL_GPIO_PM_GPIO: ret = qpnp_pin_config(pdata->gpio_mhl_en, &MHL_PIN_PM_GPIO_MHL_EN_SLEEP); if (unlikely(ret < 0)) pr_err("[ERROR] %s() set gpio_mhl_en\n", __func__); break; case MHL_GPIO_PM_MPP: ret = qpnp_pin_config(pdata->gpio_mhl_en, &MHL_PIN_PM_MPP_SLEEP); if (unlikely(ret < 0)) pr_err("[ERROR] %s() set gpio_mhl_en\n", __func__); break; default: pr_err("[ERROR] %s() unknown gpio_mhl_en's type\n", __func__); break; } } else { pr_err("[ERROR] %s() gpio_mhl_en is NULL\n", __func__); } /* suspend */ } else if (sleep_status == MHL_RESUME_STATE) { if (pdata->gpio_mhl_reset) { switch (pdata->gpio_mhl_reset_type) { case MHL_GPIO_AP_GPIO: gpio_tlmm_config(GPIO_CFG(pdata->gpio_mhl_reset, 0, GPIO_CFG_OUTPUT, GPIO_CFG_NO_PULL, GPIO_CFG_2MA), 1); break; case MHL_GPIO_PM_GPIO: ret = qpnp_pin_config(pdata->gpio_mhl_reset, &MHL_PIN_PM_GPIO_WAKE); if (unlikely(ret < 0)) pr_err("[ERROR] %s() set gpio_mhl_reset\n", __func__); break; case MHL_GPIO_PM_MPP: ret = qpnp_pin_config(pdata->gpio_mhl_reset, &MHL_PIN_PM_MPP_WAKE); if (unlikely(ret < 0)) pr_err("[ERROR] %s() set gpio_mhl_reset\n", __func__); break; default: pr_err("[ERROR] %s() unknown gpio_mhl_reset's type\n", __func__); break; } } else { pr_err("[ERROR] %s() gpio_mhl_reset is NULL\n", __func__); } if (pdata->gpio_mhl_en) { switch (pdata->gpio_mhl_en_type) { case MHL_GPIO_AP_GPIO: gpio_tlmm_config(GPIO_CFG(pdata->gpio_mhl_en, 0, GPIO_CFG_OUTPUT, GPIO_CFG_NO_PULL, GPIO_CFG_2MA), 1); break; case MHL_GPIO_PM_GPIO: ret = qpnp_pin_config(pdata->gpio_mhl_en, &MHL_PIN_PM_GPIO_WAKE); if (unlikely(ret < 0)) pr_err("[ERROR] %s() set gpio_mhl_en\n", __func__); break; case MHL_GPIO_PM_MPP: ret = qpnp_pin_config(pdata->gpio_mhl_en, &MHL_PIN_PM_MPP_WAKE); if (unlikely(ret < 0)) pr_err("[ERROR] %s() set gpio_mhl_en\n", __func__); break; default: pr_err("[ERROR] %s() unknown gpio_mhl_en's type\n", __func__); break; } } else { pr_err("[ERROR] %s() gpio_mhl_en is NULL\n", __func__); } } } static void of_sii8240_hw_onoff(bool onoff) { int ret; struct sii8240_platform_data *pdata = g_pdata; pr_info("%s: Onoff: %d\n", __func__, onoff); if (onoff) { /* if(pdata->gpio_barcode_emul) ice_gpiox_set(FPGA_GPIO_MHL_EN, onoff); */ if (pdata->gpio_mhl_en > 0) gpio_set_value_cansleep(pdata->gpio_mhl_en, onoff); if (pdata->vcc_1p2v) { ret = regulator_set_voltage(pdata->vcc_1p2v, 1200000, 1200000); if (unlikely(ret < 0)) { pr_err("[ERROR] regulator vcc_1p2v set_vtg failed rc\n"); return; } ret = regulator_enable(pdata->vcc_1p2v); if (unlikely(ret < 0)) { pr_err("[ERROR] regulator vcc_1p2v enable failed rc\n"); return; } } if (pdata->vcc_1p8v) { ret = regulator_set_voltage(pdata->vcc_1p8v, 1800000, 1800000); if (unlikely(ret < 0)) { pr_err("[ERROR] regulator vcc 1p8v set_vtg failed rc\n"); goto err_regulator_1p8v; } ret = regulator_enable(pdata->vcc_1p8v); if (unlikely(ret < 0)) { pr_err("[ERROR] regulator vcc 1p8v enable failed rc\n"); goto err_regulator_1p8v; } } if (pdata->vcc_3p3v) { ret = regulator_set_voltage(pdata->vcc_3p3v, 3300000, 3300000); if (unlikely(ret < 0)) { pr_err("[ERROR] regulator vcc_3p3v set_vtg failed rc\n"); goto err_regulator_3p3v; } ret = regulator_enable(pdata->vcc_3p3v); if (unlikely(ret < 0)) { pr_err("[ERROR] regulator vcc_3p3v enable failed rc\n"); goto err_regulator_3p3v; } } } else { /* if(pdata->gpio_barcode_emul) ice_gpiox_set(FPGA_GPIO_MHL_EN, onoff); */ if (pdata->gpio_mhl_en > 0) gpio_set_value_cansleep(pdata->gpio_mhl_en, onoff); if (pdata->vcc_1p2v) { ret = regulator_disable(pdata->vcc_1p2v); if (unlikely(ret < 0)) { pr_err("[ERROR] regulator vcc_1p2v disable failed rc\n"); return; } } if (pdata->vcc_1p8v) { ret = regulator_disable(pdata->vcc_1p8v); if (unlikely(ret < 0)) { pr_err("[ERROR] regulator vcc_1p8v disable failed rc\n"); return; } } if (pdata->vcc_3p3v) { ret = regulator_disable(pdata->vcc_3p3v); if (unlikely(ret < 0)) { pr_err("[ERROR] regulator vcc_3pv3 disable failed rc\n"); return; } } usleep_range(10000, 20000); if (pdata->gpio_mhl_reset > 0) gpio_set_value_cansleep(pdata->gpio_mhl_reset, 0); } return; err_regulator_3p3v: if (pdata->vcc_1p8v) regulator_disable(pdata->vcc_1p8v); err_regulator_1p8v: if (pdata->vcc_1p2v) regulator_disable(pdata->vcc_1p2v); }