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); }
static void sii8240_charger_mhl_cb(bool otg_enable, int plim) { union power_supply_propval value; int i, ret = 0; struct power_supply *psy; int current_cable_type = POWER_SUPPLY_TYPE_MISC; int sub_type = ONLINE_SUB_TYPE_MHL; int power_type = ONLINE_POWER_TYPE_UNKNOWN; int muic_cable_type = max77803_muic_get_charging_type(); pr_info("%s: muic cable_type = %d\n", __func__, muic_cable_type); switch (muic_cable_type) { case CABLE_TYPE_SMARTDOCK_MUIC: case CABLE_TYPE_SMARTDOCK_TA_MUIC: case CABLE_TYPE_SMARTDOCK_USB_MUIC: return; default: break; } pr_info("sii8240:otg_enable=%d, plim=%d\n", otg_enable, plim); if (plim == 0x00) { pr_info("TA charger 500mA\n"); power_type = ONLINE_POWER_TYPE_MHL_500; } else if (plim == 0x01) { pr_info("TA charger 900mA\n"); power_type = ONLINE_POWER_TYPE_MHL_900; } else if (plim == 0x02) { pr_info("TA charger 1500mA\n"); power_type = ONLINE_POWER_TYPE_MHL_1500; } else if (plim == 0x03) { pr_info("USB charger\n"); power_type = ONLINE_POWER_TYPE_USB; } else current_cable_type = POWER_SUPPLY_TYPE_BATTERY; if (muic_cable_type == CABLE_TYPE_MMDOCK_MUIC) { if (otg_enable == true || plim == 0x03 || plim == 0x00) { pr_info("sii8240: MMDOCK: charger_mhl_cb do nothing\n"); return; } else if (current_cable_type != POWER_SUPPLY_TYPE_BATTERY) { current_cable_type = POWER_SUPPLY_TYPE_MDOCK_TA; power_type = ONLINE_POWER_TYPE_UNKNOWN; sub_type = ONLINE_SUB_TYPE_UNKNOWN; pr_info("sii8240: MMDOCK: POWER_SUPPLY_TYPE_MDOCK_TA\n"); } } if (otg_enable) { if(!sii8240_vbus_present()) { if (!lpcharge) { otg_control(true); current_cable_type = POWER_SUPPLY_TYPE_BATTERY; power_type = ONLINE_POWER_TYPE_UNKNOWN; } } } else otg_control(false); for (i = 0; i < 10; i++) { psy = power_supply_get_by_name("battery"); if (psy) break; } if (i == 10) { pr_err("%s: fail to get battery ps\n", __func__); return; } value.intval = current_cable_type<<ONLINE_TYPE_MAIN_SHIFT | sub_type<<ONLINE_TYPE_SUB_SHIFT | power_type<<ONLINE_TYPE_PWR_SHIFT; ret = psy->set_property(psy, POWER_SUPPLY_PROP_ONLINE, &value); if (ret) { pr_err("%s: fail to set power_suppy ONLINE property(%d)\n", __func__, ret); } }