/* 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;
}
Esempio n. 2
0
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);
}