static int sec_bat_adc_ap_read(void)
{
	int data = -1;
	int rc = -1;
	struct qpnp_vadc_result results;

	switch (current_chip_vendor)
	{
	case VENDOR_LSI :
		break;
	case VENDOR_QCOM :
#if defined(CONFIG_ARCH_MSM8974PRO)
			rc = qpnp_vadc_read(adc_client, LR_MUX5_PU1_AMUX_THM2, &results);
#else
			rc = qpnp_vadc_read(NULL, LR_MUX5_PU2_AMUX_THM2, &results);
#endif
			if (rc) {
				pr_err("%s: Unable to read batt temperature rc=%d\n",
					__func__, rc);
				return 0;
			}
			pr_err("%s: adc %d\n",
				__func__, results.adc_code);
			data = results.adc_code;
			break;
	default :
		break;
	}

	pr_info("%s: [%d] data = %d\n", __func__, current_chip_vendor, data);

	return data;
}
static int sec_bat_adc_ap_read(struct sec_battery_info *battery, int channel)
{
	struct qpnp_vadc_result results;
	int rc = -1;
	int data = -1;

	switch (channel)
	{
	case SEC_BAT_ADC_CHANNEL_TEMP :
		rc = qpnp_vadc_read(NULL, temp_channel, &results);
		if (rc) {
			pr_err("%s: Unable to read batt temperature rc=%d\n",
				__func__, rc);
			return 0;
		}
		data = results.adc_code;
		break;
	case SEC_BAT_ADC_CHANNEL_TEMP_AMBIENT:
		data = 33000;
		break;
	case SEC_BAT_ADC_CHANNEL_BAT_CHECK :
		qpnp_vadc_read(NULL, P_MUX8_1_3, &results);
		data = ((int)results.physical) / 1000;
		break;
	default :
		break;
	}

	pr_debug("%s: data(%d)\n", __func__, data);

	return data;
}
static int sec_bat_adc_ap_read(struct sec_battery_info *battery, int channel)
{
	struct qpnp_vadc_result results;
	int rc = -1;
	int data = -1;

	switch (channel)
	{
	case SEC_BAT_ADC_CHANNEL_TEMP:
		rc = qpnp_vadc_read(adc_client, LR_MUX1_BATT_THERM, &results);
		if (rc) {
			pr_err("%s: Unable to read batt temperature rc=%d\n",
					__func__, rc);
			return 0;
		}
		data = results.adc_code;
		break;
	case SEC_BAT_ADC_CHANNEL_TEMP_AMBIENT:
		data = 33000;
		break;
	case SEC_BAT_ADC_CHANNEL_BAT_CHECK:
		rc = qpnp_vadc_read(adc_client, LR_MUX2_BAT_ID, &results);
		if (rc) {
			pr_err("%s: Unable to read BATT_ID ADC rc=%d\n",
					__func__, rc);
			return 0;
		}
		pr_debug("BAT_ID physical= %lld, raw = 0x%x\n", results.physical, results.adc_code);
		data = results.physical;
		break;
	case SEC_BAT_ADC_CHANNEL_INBAT_VOLTAGE:
		rc = qpnp_vadc_read(adc_client, VBAT_SNS, &results);
		if (rc) {
			pr_err("%s: Unable to read VBAT_SNS ADC rc=%d\n",
					__func__, rc);
			return 0;
		}
		data = ((int)results.physical)/1000;
		break;
	case SEC_BAT_ADC_CHANNEL_DISCHARGING_CHECK:
		/** Battery Thermister ADC is used for self_discharge IC ADC in GT5*/
                rc = qpnp_vadc_read(adc_client, LR_MUX1_BATT_THERM, &results);
                if (rc) {
                        pr_err("%s: Unable to read discharging_check ADC rc=%d\n",
                                        __func__, rc);
                        return 0;
                }
                data = results.adc_code;
                break;
	case SEC_BAT_ADC_CHANNEL_DISCHARGING_NTC:
		return 0;
		break;
	default :
		break;
	}

	return data;
}
void sec_bat_check_batt_id(struct sec_battery_info *battery)
{
#if defined(CONFIG_SENSORS_QPNP_ADC_VOLTAGE)
#if defined(CONFIG_FUELGAUGE_MAX17050)
	int rc, data = -1;
	struct qpnp_vadc_result results;

#if defined(CONFIG_MACH_PICASSO) || defined(CONFIG_MACH_LT03) || defined(CONFIG_MACH_VIENNA)
	rc = qpnp_vadc_read(NULL, LR_MUX9_PU2_AMUX_THM5, &results);
#else
	rc = qpnp_vadc_read(NULL, LR_MUX5_PU2_AMUX_THM2, &results);
#endif
	if (rc) {
		pr_err("%s: Unable to read batt id rc=%d\n",
				__func__, rc);
		return;
	}
	data = results.adc_code;

	pr_info("%s: batt_id_adc = (%d)\n", __func__, data);

#if defined(CONFIG_MACH_PICASSO) || defined(CONFIG_MACH_LT03)
	/* SDI: 28000, BYD: 29000, ATL: 31000 */
	if (data > 31000) { /* ATL */
		battery->pdata->vendor = "ATL ATL";
		samsung_battery_data[0].Capacity = 0x4074;
		samsung_battery_data[0].type_str = "ATL";
	} else if (data > 29000) { /* BYD */
		battery->pdata->vendor = "BYD BYD";
		samsung_battery_data[0].Capacity = 0x4010;
		samsung_battery_data[0].type_str = "BYD";
	}
#else
	/* SDI: 28500, ATL: 31000 */
	if (data > 31000) {
		battery->pdata->vendor = "ATL ATL";
#if defined(CONFIG_MACH_MONDRIAN)
		samsung_battery_data[0].Capacity = 0x2614; /* Mondrian : 4874mAh */
#else
		samsung_battery_data[0].Capacity = 0x4958; /* Vienna */
#endif
		samsung_battery_data[0].type_str = "ATL";
	}
#endif

	pr_err("%s: batt_type(%s), batt_id(%d), cap(0x%x), type(%s)\n",
			__func__, battery->pdata->vendor, data,
			samsung_battery_data[0].Capacity, samsung_battery_data[0].type_str);
#endif
#endif
}
Exemple #5
0
static int sec_bat_adc_ap_read(unsigned int channel)
{
#if defined(CONFIG_SENSORS_QPNP_ADC_VOLTAGE)
	int rc = -1, data =  -1;
	struct qpnp_vadc_result results;

	switch (channel) {
	case SEC_BAT_ADC_CHANNEL_TEMP:
		rc = qpnp_vadc_read(LR_MUX5_PU2_AMUX_THM2, &results);
		if (rc) {
			pr_err("%s: Unable to read batt temperature rc=%d\n",
				__func__, rc);
			return 0;
		}
		data = results.adc_code;
		break;
	case SEC_BAT_ADC_CHANNEL_TEMP_AMBIENT:
		data = 33000;
		break;
	case SEC_BAT_ADC_CHANNEL_BAT_CHECK:
		break;
	default:
		break;
	}

	return data;
#else
	return 33000;
#endif
}
static int32_t qpnp_check_pmic_temp(void)
{
	struct qpnp_iadc_drv *iadc = qpnp_iadc;
	struct qpnp_vadc_result result_pmic_therm;
	int64_t die_temp_offset;
	int rc = 0;

	rc = qpnp_vadc_read(DIE_TEMP, &result_pmic_therm);
	if (rc < 0)
		return rc;

	die_temp_offset = result_pmic_therm.physical -
			iadc->die_temp;
	if (die_temp_offset < 0)
		die_temp_offset = -die_temp_offset;

	if (die_temp_offset > QPNP_IADC_DIE_TEMP_CALIB_OFFSET) {
		iadc->die_temp =
			result_pmic_therm.physical;
		rc = qpnp_iadc_calibrate_for_trim();
		if (rc)
			pr_err("periodic IADC calibration failed\n");
	}

	return rc;
}
static int32_t qpnp_check_pmic_temp(struct qpnp_iadc_chip *iadc)
{
    struct qpnp_vadc_result result_pmic_therm;
    int64_t die_temp_offset;
    int rc = 0;

    rc = qpnp_vadc_read(iadc->vadc_dev, DIE_TEMP, &result_pmic_therm);
    if (rc < 0)
        return rc;

    die_temp_offset = result_pmic_therm.physical -
                      iadc->die_temp;
    if (die_temp_offset < 0)
        die_temp_offset = -die_temp_offset;

    if (die_temp_offset > QPNP_IADC_DIE_TEMP_CALIB_OFFSET) {
        iadc->die_temp = result_pmic_therm.physical;
        if (!iadc->skip_auto_calibrations) {
            rc = qpnp_iadc_calibrate_for_trim(iadc, true);
            if (rc)
                pr_err("IADC calibration failed rc = %d\n", rc);
        }
    }

    return rc;
}
static void button_pressed(struct work_struct *work)
{
	struct delayed_work *dwork = container_of(work, struct delayed_work, work);
	struct hsd_info *hi = container_of(dwork, struct hsd_info, work_for_key_pressed);
	struct qpnp_vadc_result result;
	int acc_read_value = 0;
	int i, rc;
	struct ear_3button_info_table *table;
	int table_size = ARRAY_SIZE(max1462x_ear_3button_type_data);

	if (hi->gpio_get_value_func(hi->gpio_detect) || (atomic_read(&hi->is_3_pole_or_not))) {
		HSD_ERR("button_pressed but 4 pole ear jack is plugged out already! just ignore the event.\n");
		return;
	}

	rc = qpnp_vadc_read(switch_vadc, P_MUX6_1_1, &result);

	if (rc < 0) {
		if (rc == -ETIMEDOUT) {
			pr_err("[DEBUG] button_pressed : adc read timeout \n");
		} else {
			pr_err("button_pressed: adc read error - %d\n", rc);
		}
	}
	acc_read_value = (int)result.physical;
	pr_info("%s: acc_read_value - %d\n", __func__, acc_read_value);

	for (i = 0; i < table_size; i++) {
		table = &max1462x_ear_3button_type_data[i];
		/*                                  
                                                              
   */
		if ((acc_read_value <= table->PERMISS_REANGE_MAX) &&
				(acc_read_value >= table->PERMISS_REANGE_MIN)) {
			HSD_DBG("button_pressed \n");
			atomic_set(&hi->btn_state, 1);
			switch (table->ADC_HEADSET_BUTTON) {
			case  KEY_MEDIA:
				input_report_key(hi->input, KEY_MEDIA, 1);
				pr_info("%s: KEY_MEDIA \n", __func__);
				break;
			case KEY_VOLUMEUP:
				input_report_key(hi->input, KEY_VOLUMEUP, 1);
				pr_info("%s: KEY_VOLUMEUP \n", __func__);
				break;
			case KEY_VOLUMEDOWN:
				input_report_key(hi->input, KEY_VOLUMEDOWN, 1);
				pr_info("%s: KEY_VOLUMDOWN \n", __func__);
				break;
			default:
				break;
			}
			table->PRESS_OR_NOT = 1;
			input_sync(hi->input);
			break;
		}
	}
	return;
}
static int sec_bat_adc_ap_read(struct sec_battery_info *battery, int channel)
{
  struct qpnp_vadc_result results;
  int rc = -1;
  int data = -1;

  switch (channel)
  {
  case SEC_BAT_ADC_CHANNEL_TEMP :
    rc = qpnp_vadc_read(NULL, temp_channel, &results);
    if (rc) {
      pr_err("%s: Unable to read batt temperature rc=%d\n",
        __func__, rc);
      return 0;
    }
    data = results.adc_code;
    break;
  case SEC_BAT_ADC_CHANNEL_TEMP_AMBIENT:
    data = 33000;
    break;
  case SEC_BAT_ADC_CHANNEL_BAT_CHECK:
    rc = qpnp_vadc_read(NULL, LR_MUX2_BAT_ID, &results);
    if (rc) {
      pr_err("%s: Unable to read BATT_ID ADC rc=%d\n",
        __func__, rc);
      return 0;
    }
    pr_debug("BAT_ID physical= %lld, raw = 0x%x\n", results.physical, results.adc_code);
    data = results.physical;
    break;
  case SEC_BAT_ADC_CHANNEL_INBAT_VOLTAGE:
	rc = qpnp_vadc_read(NULL, VBAT_SNS, &results);
	if (rc) {
		pr_err("%s: Unable to read VBAT_SNS ADC rc=%d\n",
			__func__, rc);
		return 0;
    }
	data = ((int)results.physical)/1000;
	break;
  default :
    break;
  }

  return data;
}
Exemple #10
0
static int bq24192_get_prop_input_voltage(struct bq24192_chip *chip)
{
	int rc = 0;
	struct qpnp_vadc_result results;

	rc = qpnp_vadc_read(USBIN, &results);
	if (rc) {
		pr_err("Unable to read vbus rc=%d\n", rc);
		return UNINIT_VBUS_UV;
	}

	return (int)results.physical;
}
static int qpnp_tm_update_temp(struct qpnp_tm_chip *chip)
{
	struct qpnp_vadc_result adc_result;
	int rc;

	rc = qpnp_vadc_read(chip->adc_channel, &adc_result);
	if (!rc)
		chip->temperature = adc_result.physical;
	else
		dev_err(&chip->spmi_dev->dev, "%s: qpnp_vadc_read(%d) failed, rc=%d\n",
			__func__, chip->adc_channel, rc);

	return rc;
}
static int get_cp_thm2_value(struct ssp_data *data)
{
	int err = 0;
	struct qpnp_vadc_result results;
	mutex_lock(&data->cp_temp_adc_lock);
	err = qpnp_vadc_read(ssp_vadc, LR_MUX8_PU1_AMUX_THM4, &results);
	mutex_unlock(&data->cp_temp_adc_lock);
	if (err) {
		pr_err("%s : error reading chn %d, rc = %d\n",
			__func__, LR_MUX8_PU2_AMUX_THM4, err);
		return err;
	}
	return results.adc_code;
}
static int convert_adc_to_temp2(struct ssp_data *data, unsigned int adc)
{
	int err = 0;
	struct qpnp_vadc_result results;
	mutex_lock(&data->cp_temp_adc_lock);
	err = qpnp_vadc_read(ssp_vadc, LR_MUX8_PU1_AMUX_THM4, &results);
	mutex_unlock(&data->cp_temp_adc_lock);
	if (err) {
		pr_err("%s : error reading chn %d, rc = %d\n",
			__func__, LR_MUX8_PU2_AMUX_THM4, err);
		return err;
	}

	return results.physical * 10;
}
//ASUS_BSP Eason A90_EVB porting ---
int64_t read_battery_id(void)
{
	int rc=-1;
	struct qpnp_vadc_result result;

	rc = qpnp_vadc_read(asus_vadc, LR_MUX2_BAT_ID, &result);
	if (rc) {
		printk("[BAT][GAU][A66]error reading batt id channel = %d, rc = %d\n",
					LR_MUX2_BAT_ID, rc);
		return rc;
	}

	g_BatteryID_value = result.physical;
	return result.physical;
	
	
}
void sec_bat_check_batt_id(struct sec_battery_info *battery)
{
#if defined(CONFIG_SENSORS_QPNP_ADC_VOLTAGE)
	int rc, data =  -1;
	struct qpnp_vadc_result results;

	rc = qpnp_vadc_read(NULL, LR_MUX2_BAT_ID, &results);
	if (rc) {
		pr_err("%s: Unable to read batt id rc=%d\n",
				__func__, rc);
		return;
	}
	data = results.adc_code;

	pr_info("%s: batt_id_adc = (%d)\n", __func__, data);
#endif
}
static int sec_therm_get_adc_data(struct sec_therm_info *info)
{
	int rc = 0;
	int adc_max = 0;
	int adc_min = 0;
	int adc_total = 0;
	int i, adc_data;

	struct qpnp_vadc_result results;

	for (i = 0; i < ADC_SAMPLING_CNT; i++) {

		rc = qpnp_vadc_read(NULL, MSM_THERM_CH , &results);

		if (rc) {
			pr_err("error reading AMUX %d, rc = %d\n",
						MSM_THERM_CH, rc);
			goto err;
		}
		adc_data = results.adc_code;

		if (i == 0) {
			pr_debug("reading MSM_THERM_CH [rc = %d] [adc_code = %d]\n",
									rc,results.adc_code);
		}

		if (i != 0) {
			if (adc_data > adc_max)
				adc_max = adc_data;
			else if (adc_data < adc_min)
				adc_min = adc_data;
		} else {
			adc_max = adc_data;
			adc_min = adc_data;
		}

		adc_total += adc_data;
	}

	return (adc_total - adc_max - adc_min) / (ADC_SAMPLING_CNT - 2);

err:
	return rc;

}
static int64_t htc_8974_get_usbid_adc(void)
{
#if 0
	struct qpnp_vadc_result result;
	int err = 0, adc = 0;
	err = qpnp_vadc_read(LR_MUX10_USB_ID_LV, &result);
	if (err < 0) {
		pr_info("[CABLE] %s: get adc fail, err %d\n", __func__, err);
		return err;
	}
	adc = result.physical;
	adc /= 1000;
	pr_info("[CABLE] chan=%d, adc_code=%d, measurement=%lld, \
			physical=%lld translate voltage %d\n", result.chan, result.adc_code,
			result.measurement, result.physical, adc);
	return adc;
#endif
	return htc_qpnp_adc_get_usbid_adc();
}
static int sec_therm_get_adc_data_flash_led(struct sec_therm_info *info)
{
	int rc = 0;
	int adc_max = 0;
	int adc_min = 0;
	int adc_total = 0;
	int i, adc_data;

	struct qpnp_vadc_result results;

	for (i = 0; i < ADC_SAMPLING_CNT; i++) {

		rc = qpnp_vadc_read(NULL, LR_MUX9_PU2_AMUX_THM5, &results);

		if (rc) {
			pr_err("error reading AMUX %d, rc = %d\n",
						LR_MUX9_PU2_AMUX_THM5, rc);
			goto err;
		}
		adc_data = results.adc_code;

		pr_err("reading LR_MUX9_PU2_AMUX_THM5 [rc = %d] [adc_code = %d]\n",
									rc,results.adc_code);
		if (i != 0) {
			if (adc_data > adc_max)
				adc_max = adc_data;
			else if (adc_data < adc_min)
				adc_min = adc_data;
		} else {
			adc_max = adc_data;
			adc_min = adc_data;
		}

		adc_total += adc_data;
	}

	return (adc_total - adc_max - adc_min) / (ADC_SAMPLING_CNT - 2);

err:
	return rc;

}
static int max14688_read_mic_impedence (struct device *dev)
{
	struct qpnp_vadc_result result;
	int acc_read_value = 0;

	int rc;

	rc = qpnp_vadc_read(input_vadc, P_MUX2_1_1, &result);
	if (rc < 0) {
		if (rc == -ETIMEDOUT) {
			pr_err("[DEBUG] button_pressed : adc read timeout \n");
		} else {
			pr_err("button_pressed: adc read error - %d\n", rc);
		}
	}

	acc_read_value = (int)result.physical;
	log_dbg("%s[adc value =  %d]\n", __func__, acc_read_value);

	return acc_read_value;
}
static int qpnp_get_battery_temp(int *temp)
{
	int ret = 0;
	struct qpnp_vadc_result results;

	if (qpnp_vadc_is_ready()) {
		*temp = DEFAULT_TEMP;
		return 0;
	}

	ret = qpnp_vadc_read(LR_MUX1_BATT_THERM, &results);
	if (ret) {
		pr_err("%s: Unable to read batt temp\n", __func__);
		*temp = DEFAULT_TEMP;
		return ret;
	}

	*temp = (int)results.physical;

	return 0;
}
int32_t qpnp_check_pmic_temp(void)
{
	struct qpnp_iadc_drv *iadc = qpnp_iadc;
	struct qpnp_vadc_result result_pmic_therm;
	int rc;

	rc = qpnp_vadc_read(DIE_TEMP, &result_pmic_therm);
	if (rc < 0)
		return rc;

	if (((uint64_t) (result_pmic_therm.physical -
				iadc->die_temp_calib_offset))
			> QPNP_IADC_DIE_TEMP_CALIB_OFFSET) {
		mutex_lock(&iadc->adc->adc_lock);

		rc = qpnp_iadc_calibrate_for_trim();
		if (rc)
			pr_err("periodic IADC calibration failed\n");

		mutex_unlock(&iadc->adc->adc_lock);
	}

	return 0;
}
Exemple #22
0
lcd_maker_id get_panel_maker_id(void)
{
    struct qpnp_vadc_result result;
    lcd_maker_id maker_id = LCD_MAKER_MAX;
    int rc;
    int acc_read_value = 0;

	rc = qpnp_vadc_read(P_MUX5_1_1, &result);

	if (rc < 0) {
		if (rc == -ETIMEDOUT) {
		   acc_read_value = 0;
		}
		pr_err("%s : adc read "
					 "error - %d\n", __func__, rc);
	}
	acc_read_value = (int)result.physical / 1000;
	pr_debug("%s: acc_read_value - %d\n", __func__,
					 (int)result.physical);

    maker_id = get_lcd_maker_by_voltage(acc_read_value);

	return maker_id;
}
/* 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 int max1462x_hsd_probe(struct platform_device *pdev)
{
	struct max1462x_platform_data *pdata = pdev->dev.platform_data;
	struct max1462x_hsd_info *hi;
	struct qpnp_vadc_result result;
	int acc_read_value = 0;
	int i;
	int adc_read_count = 3;
	int ret = 0;

	pr_debug("%s\n", __func__);

	if (pdev->dev.of_node) {
		pdata = devm_kzalloc(&pdev->dev,
				sizeof(struct max1462x_platform_data),
				GFP_KERNEL);
		if (!pdata) {
			pr_err("%s: Failed to allocate memory\n", __func__);
			return -ENOMEM;
		}
		pdev->dev.platform_data = pdata;
		max1462x_parse_dt(&pdev->dev, pdata);
	} else {
		pdata = pdev->dev.platform_data;
		if (!pdata) {
			pr_err("%s: No pdata\n", __func__);
			return -ENODEV;
		}
	}

	local_max1462x_workqueue = create_workqueue("max1462x");
	if (!local_max1462x_workqueue) {
		pr_err("%s: Failed to create_workqueue\n", __func__);
		return -ENOMEM;
	}

	wake_lock_init(&ear_hook_wake_lock, WAKE_LOCK_SUSPEND, "ear_hook");

	hi = kzalloc(sizeof(struct max1462x_hsd_info), GFP_KERNEL);
	if (!hi) {
		pr_err("%s: Failed to allloate memory for device info\n",
				__func__);
		ret = -ENOMEM;
		goto err_kzalloc;
	}

	hi->key_code = pdata->key_code;

	platform_set_drvdata(pdev, hi);

	atomic_set(&hi->btn_state, 0);
	atomic_set(&hi->is_3_pole_or_not, 1);

	hi->gpio_mic_en = pdata->gpio_mic_en;
	hi->gpio_detect = pdata->gpio_detect;
	hi->gpio_key = pdata->gpio_key;

	hi->latency_for_key = msecs_to_jiffies(50); /* convert ms to jiffies */
	mutex_init(&hi->mutex_lock);
	INIT_WORK(&hi->work, max1462x_detect_work);
	INIT_DELAYED_WORK(&hi->work_for_key_pressed, max1462x_button_pressed);
	INIT_DELAYED_WORK(&hi->work_for_key_released, max1462x_button_released);

	/* init gpio_mic_en & set default value */
	ret = gpio_request_one(hi->gpio_mic_en, GPIOF_OUT_INIT_HIGH,
			"gpio_mic_en");
	if (ret < 0) {
		pr_err("%s: Failed to configure gpio%d(gpio_mic_en)n",
			__func__, hi->gpio_mic_en);
		goto err_gpio_mic_en;
	}
	pr_debug("gpio_get_value_cansleep(hi->gpio_mic_en)=%d\n",
		gpio_get_value_cansleep(hi->gpio_mic_en));

	/* init gpio_detect */
	ret = gpio_request_one(hi->gpio_detect, GPIOF_IN, "gpio_detect");
	if (ret < 0) {
		pr_err("%s: Failed to configure gpio%d(gpio_det)\n",
			__func__, hi->gpio_detect);
		goto err_gpio_detect;
	}

	/* init gpio_key */
	ret = gpio_request_one(hi->gpio_key, GPIOF_IN, "gpio_key");
	if (ret < 0) {
		pr_err("%s: Failed to configure gpio%d(gpio_key)\n",
			__func__, hi->gpio_key);
		goto err_gpio_key;
	}

	ret = gpio_to_irq(hi->gpio_detect);
	if (ret < 0) {
		pr_err("%s: Failed to get interrupt number\n", __func__);
		goto err_irq_detect;
	}
	hi->irq_detect = ret;
	pr_debug("%s: hi->irq_detect = %d\n", __func__, hi->irq_detect);

	ret = request_threaded_irq(hi->irq_detect, NULL,
				max1462x_earjack_det_irq_handler,
				IRQF_TRIGGER_RISING|IRQF_TRIGGER_FALLING,
				pdev->name, hi);
	if (ret < 0) {
		pr_err("%s: failed to request button irq\n", __func__);
		goto err_irq_detect_request;
	}

	ret = enable_irq_wake(hi->irq_detect);
	if (ret < 0) {
		pr_err("%s: Failed to set gpio_detect interrupt wake\n",
			__func__);
		goto err_irq_detect_wake;
	}

	/* initialize irq of gpio_key */
	ret = gpio_to_irq(hi->gpio_key);
	if (ret < 0) {
		pr_err("%s: Failed to get interrupt number\n", __func__);
		goto err_irq_key;
	}
	hi->irq_key = ret;
	pr_debug("%s: hi->irq_key = %d\n", __func__, hi->irq_key);

	ret = request_threaded_irq(hi->irq_key, NULL,
			max1462x_button_irq_handler,
			IRQF_TRIGGER_RISING|IRQF_TRIGGER_FALLING,
			pdev->name, hi);
	if (ret < 0) {
		pr_err("%s: failed to request button irq\n", __func__);
		goto err_irq_key_request;
	}

        disable_irq(hi->irq_key);
        atomic_set(&hi->irq_key_enabled, false);

        /* initialize switch device */
	hi->sdev.name = pdata->switch_name;
	hi->sdev.print_state = max1462x_hsd_print_state;
	hi->sdev.print_name = max1462x_hsd_print_name;

	ret = switch_dev_register(&hi->sdev);
	if (ret < 0) {
		pr_err("%s: Failed to register switch device\n", __func__);
		goto err_switch_dev_register;
	}

	/* initialize input device */
	hi->input = input_allocate_device();
	if (!hi->input) {
		pr_err("%s: Failed to allocate input device\n", __func__);
		ret = -ENOMEM;
		goto err_input_allocate_device;
	}

	hi->input->name = pdata->keypad_name;
	hi->input->id.vendor    = 0x0001;
	hi->input->id.product   = 1;
	hi->input->id.version   = 1;

	/* headset tx noise */
	for (i = 0; i < adc_read_count; i++) {
		ret = qpnp_vadc_read(ADC_PORT_NUM, &result);
		if (ret < 0) {
			if (ret == -ETIMEDOUT)
				pr_warn("%s: warning: adc read timeout \n",
						__func__);
			else
				pr_warn("%s: warning: adc read error - %d\n",
						__func__, ret);
		} else {
			acc_read_value = (int)result.physical;
			pr_info("%s: acc_read_value - %d\n", __func__,
				acc_read_value);
			break;
		}
	}

	set_bit(EV_SYN, hi->input->evbit);
	set_bit(EV_KEY, hi->input->evbit);
	set_bit(EV_SW, hi->input->evbit);
	set_bit(hi->key_code, hi->input->keybit);
	set_bit(SW_HEADPHONE_INSERT, hi->input->swbit);
	set_bit(SW_MICROPHONE_INSERT, hi->input->swbit);

	input_set_capability(hi->input, EV_KEY, KEY_MEDIA);
	input_set_capability(hi->input, EV_KEY, KEY_VOLUMEUP);
	input_set_capability(hi->input, EV_KEY, KEY_VOLUMEDOWN);
	input_set_capability(hi->input, EV_SW, SW_HEADPHONE_INSERT);
	input_set_capability(hi->input, EV_SW, SW_MICROPHONE_INSERT);

	ret = input_register_device(hi->input);
	if (ret < 0) {
		pr_err("%s: Failed to register input device\n", __func__);
		goto err_input_register_device;
	}

	/* to detect in initialization with eacjack insertion */
	if (!(gpio_get_value(hi->gpio_detect)))
		queue_work(local_max1462x_workqueue, &(hi->work));

	return ret;

err_input_register_device:
	input_free_device(hi->input);
err_input_allocate_device:
	switch_dev_unregister(&hi->sdev);
err_switch_dev_register:
        free_irq(hi->irq_key, hi);
err_irq_key_request:
err_irq_key:
err_irq_detect_wake:
	free_irq(hi->irq_detect, hi);
err_irq_detect_request:
err_irq_detect:
	gpio_free(hi->gpio_key);
err_gpio_key:
	gpio_free(hi->gpio_detect);
err_gpio_detect:
	gpio_free(hi->gpio_mic_en);
err_gpio_mic_en:
	mutex_destroy(&hi->mutex_lock);
	kfree(hi);
err_kzalloc:
	destroy_workqueue(local_max1462x_workqueue);
	local_max1462x_workqueue = NULL;
	return ret;
}
Exemple #25
0
static int lge_hsd_probe(struct platform_device *pdev)
{
	int ret = 0;
	struct max1462x_platform_data *pdata = pdev->dev.platform_data;


	struct hsd_info *hi;

	HSD_DBG("lge_hsd_probe\n");

	hi = kzalloc(sizeof(struct hsd_info), GFP_KERNEL);

	if ( hi == NULL) {
		HSD_ERR("Failed to allloate headset per device info\n");
		return -ENOMEM;
	}

	if(pdev->dev.of_node){
		pdata = devm_kzalloc(&pdev->dev,sizeof(struct max1462x_platform_data),GFP_KERNEL);
		if(!pdata){
			HSD_ERR("Failed to allocate memory\n");
			return -ENOMEM;
		}
		pdev->dev.platform_data = pdata;

		max1462x_parse_dt(&pdev->dev,pdata);
	} else {
		pdata = devm_kzalloc(&pdev->dev,sizeof(struct max1462x_platform_data),GFP_KERNEL);
		if(!pdata){
			HSD_ERR("Failed to allocate memory\n");
			return -ENOMEM;
		}
		else
			pdata = pdev->dev.platform_data;
	}
	hi->key_code = pdata->key_code;

	platform_set_drvdata(pdev, hi);

	atomic_set(&hi->btn_state, 0);
	atomic_set(&hi->is_3_pole_or_not, 1);
	atomic_set(&hi->irq_key_enabled, FALSE);

	hi->gpio_mic_en = pdata->gpio_mic_en;
	hi->gpio_detect = pdata->gpio_detect;
	hi->gpio_key = pdata->gpio_key;
	hi->gpio_set_value_func = pdata->gpio_set_value_func;
	hi->gpio_get_value_func = pdata->gpio_get_value_func;

	hi->latency_for_key = msecs_to_jiffies(50); /* convert milli to jiffies */
	mutex_init(&hi->mutex_lock);
	INIT_WORK(&hi->work, detect_work);
	INIT_DELAYED_WORK(&hi->work_for_key_pressed, button_pressed);
	INIT_DELAYED_WORK(&hi->work_for_key_released, button_released);

	ret = gpio_request(hi->gpio_mic_en, "gpio_mic_en");
	if (ret < 0) {
		HSD_ERR("Failed to configure gpio%d (gpio_mic_en) gpio_request\n", hi->gpio_mic_en);
		goto error_02;
	}

	ret = gpio_direction_output(hi->gpio_mic_en, 0);
	if (ret < 0) {
		HSD_ERR("Failed to configure gpio%d (gpio_mic_en) gpio_direction_input\n", hi->gpio_mic_en);
		goto error_02;
	}
	HSD_DBG("gpio_get_value_cansleep(hi->gpio_mic_en) = %d\n", gpio_get_value_cansleep(hi->gpio_mic_en));

	/* init gpio_detect */
	ret = gpio_request(hi->gpio_detect, "gpio_detect");
	if (ret < 0) {
		HSD_ERR("Failed to configure gpio%d (gpio_det) gpio_request\n", hi->gpio_detect);
		goto error_03;
	}

	ret = gpio_direction_input(hi->gpio_detect);
	if (ret < 0) {
		HSD_ERR("Failed to configure gpio%d (gpio_det) gpio_direction_input\n", hi->gpio_detect);
		goto error_03;
	}

	/*init gpio_key */
	ret = gpio_request(hi->gpio_key, "gpio_key");
	if (ret < 0) {
		HSD_ERR("Failed to configure gpio%d (gpio_key) gpio_request\n", hi->gpio_key);
		goto error_04;
	}

	ret = gpio_direction_input(hi->gpio_key);
	if (ret < 0) {
		HSD_ERR("Failed to configure gpio%d (gpio_key) gpio_direction_input\n", hi->gpio_key);
		goto error_04;
	}


	/* initialize irq of gpio_key */
	hi->irq_key = gpio_to_irq(hi->gpio_key);

	HSD_DBG("hi->irq_key = %d\n", hi->irq_key);

	if (hi->irq_key < 0) {
		HSD_ERR("Failed to get interrupt number\n");
		ret = hi->irq_key;
		goto error_06;
	}
	ret = request_threaded_irq(hi->irq_key, NULL, button_irq_handler,
			IRQF_TRIGGER_RISING|IRQF_TRIGGER_FALLING, pdev->name, hi);
	if (ret) {
		HSD_ERR("failed to request button irq\n");
		goto error_06;
	}

	ret = irq_set_irq_wake(hi->irq_key, 1);
	if (ret < 0) {
		HSD_ERR("Failed to set irq_key interrupt wake\n");
		goto error_06;
	}
	enable_irq(hi->irq_key);

	hi->irq_detect = gpio_to_irq(hi->gpio_detect);
	HSD_DBG("hi->irq_detect = %d\n", hi->irq_detect);

	if (hi->irq_detect < 0) {
		HSD_ERR("Failed to get interrupt number\n");
		ret = hi->irq_detect;
		goto error_07;
	}
	ret = request_threaded_irq(hi->irq_detect, NULL, earjack_det_irq_handler,
			IRQF_TRIGGER_RISING|IRQF_TRIGGER_FALLING, pdev->name, hi);

	if (ret) {
		HSD_ERR("failed to request button irq\n");
		goto error_07;
	}

	ret = irq_set_irq_wake(hi->irq_detect, 1);
	if (ret < 0) {
		HSD_ERR("Failed to set gpio_detect interrupt wake\n");
		goto error_07;
	}
	/* initialize switch device */
	hi->sdev.name = pdata->switch_name;
	hi->sdev.print_state = lge_hsd_print_state;
	hi->sdev.print_name = lge_hsd_print_name;

	ret = switch_dev_register(&hi->sdev);
	if (ret < 0) {
		HSD_ERR("Failed to register switch device\n");
		goto error_08;
	}

	/* initialize input device */
	hi->input = input_allocate_device();
	if (!hi->input) {
		HSD_ERR("Failed to allocate input device\n");
		ret = -ENOMEM;
		goto error_09;
	}

	hi->input->name = pdata->keypad_name;

	hi->input->id.vendor    = 0x0001;
	hi->input->id.product   = 1;
	hi->input->id.version   = 1;

	/* headset tx noise */
	{
		struct qpnp_vadc_result result;
		int acc_read_value = 0;
		int i, rc;
		int count = 3;

		for (i = 0; i < count; i++)
		{
			rc = qpnp_vadc_read(P_MUX6_1_1,&result);

			if (rc < 0)
			{
				if (rc == -ETIMEDOUT) {
					pr_err("[DEBUG]adc read timeout \n");
				} else {
					pr_err("[DEBUG]adc read error - %d\n", rc);
				}
			}
			else
			{
				acc_read_value = (int)result.physical;
				pr_info("%s: acc_read_value - %d\n", __func__, (int)result.physical);
				break;
			}
		}
	}

	set_bit(EV_SYN, hi->input->evbit);
	set_bit(EV_KEY, hi->input->evbit);
	set_bit(EV_SW, hi->input->evbit);
	set_bit(hi->key_code, hi->input->keybit);
	set_bit(SW_HEADPHONE_INSERT, hi->input->swbit);
	set_bit(SW_MICROPHONE_INSERT, hi->input->swbit);
	input_set_capability(hi->input, EV_KEY, KEY_MEDIA);
	input_set_capability(hi->input, EV_KEY, KEY_VOLUMEUP);
	input_set_capability(hi->input, EV_KEY, KEY_VOLUMEDOWN);
	ret = input_register_device(hi->input);
	if (ret) {
		HSD_ERR("Failed to register input device\n");
		goto error_09;
	}

	if (!(hi->gpio_get_value_func(hi->gpio_detect)))

#ifdef CONFIG_MAX1462X_USE_LOCAL_WORK_QUEUE
		/* to detect in initialization with eacjack insertion */
		queue_work(local_max1462x_workqueue, &(hi->work));
#else
	/* to detect in initialization with eacjack insertion */
	schedule_work(&(hi->work));
#endif
	return ret;

error_09:
	input_free_device(hi->input);
error_08:
	switch_dev_unregister(&hi->sdev);
error_07:
	free_irq(hi->irq_detect, 0);
error_06:
	free_irq(hi->irq_key, 0);
error_04:
	gpio_free(hi->gpio_key);
error_03:
	gpio_free(hi->gpio_detect);
error_02:
	gpio_free(hi->gpio_mic_en);
	kfree(hi);
	return ret;
}
static int sec_therm_get_adc_data(struct sec_therm_info *info)
{
	int rc = 0;
	int adc_max = 0;
	int adc_min = 0;
	int adc_total = 0;
	int i, adc_data;

#if defined (CONFIG_ARCH_MSM8226)

	struct qpnp_vadc_result results;

	for (i = 0; i < ADC_SAMPLING_CNT; i++) {

	rc = qpnp_vadc_read(therm_vadc_dev, P_MUX2_1_1, &results);

	if (rc) {
			pr_err("error reading AMUX %d, rc = %d\n", P_MUX2_1_1, rc);
			goto err;
	}

	adc_data = results.adc_code;
	//pr_err("########## reading P_MUX2_1_1 [rc = %d] [adc_code = %d]\n", rc, results.adc_code);
#else
	struct pm8xxx_adc_chan_result result;
#if defined (CONFIG_MACH_LT02)
	int system_rev = msm8930_get_board_rev();
#endif

	for (i = 0; i < ADC_SAMPLING_CNT; i++) {
#if defined (CONFIG_MACH_LT02)
		if (system_rev >= 2)
			rc = pm8xxx_adc_mpp_config_read(PM8XXX_AMUX_MPP_3,
						ADC_MPP_1_AMUX6, &result);
		else
			rc = pm8xxx_adc_mpp_config_read(PM8XXX_AMUX_MPP_4,
						ADC_MPP_1_AMUX6, &result);
#else
		rc = pm8xxx_adc_mpp_config_read(PM8XXX_AMUX_MPP_4,
						ADC_MPP_1_AMUX6, &result);
#endif
		if (rc) {
			pr_err("error reading mpp %d, rc = %d\n",
						PM8XXX_AMUX_MPP_4, rc);
			goto err;
		}
		adc_data = (int)result.measurement;
		pr_err("reading PM8XXX_AMUX_MPP_4 [rc = %d] [measurement = %lld]\n", rc,result.measurement);
#endif
		if (i != 0) {
			if (adc_data > adc_max)
				adc_max = adc_data;
			else if (adc_data < adc_min)
				adc_min = adc_data;
		} else {
			adc_max = adc_data;
			adc_min = adc_data;
		}

		adc_total += adc_data;
	}

	return (adc_total - adc_max - adc_min) / (ADC_SAMPLING_CNT - 2);

err:
	return rc;

}

static int convert_adc_to_temper(struct sec_therm_info *info, unsigned int adc)
{
	int low = 0;
	int high = 0;
	int mid = 0;
	int temp = 0;
	int temp2 = 0;

	if (!info->pdata->adc_table || !info->pdata->adc_arr_size) {
		/* using fake temp */
		return 300;
	}

	high = info->pdata->adc_arr_size - 1;

	if (info->pdata->adc_table[low].adc >= adc) {
		temp = info->pdata->adc_table[low].temperature;
		goto convert_adc_to_temp_goto;
	} else if (info->pdata->adc_table[high].adc <= adc) {
		temp = info->pdata->adc_table[high].temperature;
		goto convert_adc_to_temp_goto;
	}

	while (low <= high) {
		mid = (low + high) / 2;
		if (info->pdata->adc_table[mid].adc > adc) {
			high = mid - 1;
		} else if (info->pdata->adc_table[mid].adc < adc) {
			low = mid + 1;
		} else {
			temp = info->pdata->adc_table[mid].temperature;
			goto convert_adc_to_temp_goto;
		}
	}

	temp = info->pdata->adc_table[high].temperature;

	temp2 = (info->pdata->adc_table[low].temperature -
			info->pdata->adc_table[high].temperature) *
			(adc - info->pdata->adc_table[high].adc);

	temp += temp2 /
		(info->pdata->adc_table[low].adc -
			info->pdata->adc_table[high].adc);

convert_adc_to_temp_goto:

	return temp;
}
static void msm_thermal_main(struct work_struct *work)
{
	struct qpnp_vadc_result result;
	enum thermal_state old_throttle;
	int64_t temp;
	int ret;

	ret = qpnp_vadc_read(t_conf->vadc_dev, t_conf->adc_chan, &result);
	if (ret) {
		pr_err("Unable to read ADC channel\n");
		goto reschedule;
	}

	temp = result.physical;
	old_throttle = t_pol->cpu_throttle;

	/* Low trip point */
	if ((temp >= t_conf->trip_low_degC) &&
		(temp < t_conf->trip_mid_degC) &&
		(t_pol->cpu_throttle == UNTHROTTLE)) {
		t_pol->throttle_freq = t_conf->freq_low_KHz;
		t_pol->cpu_throttle = LOW_THROTTLE;
	/* Low clear point */
	} else if ((temp <= t_conf->reset_low_degC) &&
		(t_pol->cpu_throttle > UNTHROTTLE)) {
		t_pol->cpu_throttle = UNTHROTTLE;
	/* Mid trip point */
	} else if ((temp >= t_conf->trip_mid_degC) &&
		(temp < t_conf->trip_high_degC) &&
		(t_pol->cpu_throttle < MID_THROTTLE)) {
		t_pol->throttle_freq = t_conf->freq_mid_KHz;
		t_pol->cpu_throttle = MID_THROTTLE;
	/* Mid clear point */
	} else if ((temp < t_conf->reset_mid_degC) &&
		(t_pol->cpu_throttle > LOW_THROTTLE)) {
		t_pol->throttle_freq = t_conf->freq_low_KHz;
		t_pol->cpu_throttle = LOW_THROTTLE;
	/* High trip point */
	} else if ((temp >= t_conf->trip_high_degC) &&
		(t_pol->cpu_throttle < HIGH_THROTTLE)) {
		t_pol->throttle_freq = t_conf->freq_high_KHz;
		t_pol->cpu_throttle = HIGH_THROTTLE;
	/* High clear point */
	} else if ((temp < t_conf->reset_high_degC) &&
		(t_pol->cpu_throttle > MID_THROTTLE)) {
		t_pol->throttle_freq = t_conf->freq_mid_KHz;
		t_pol->cpu_throttle = MID_THROTTLE;
	}

	/* Thermal state changed */
	if (t_pol->cpu_throttle != old_throttle) {
		if (t_pol->cpu_throttle)
			pr_warn("Setting CPU to %uKHz! temp: %lluC\n",
						t_pol->throttle_freq, temp);
		else
			pr_warn("CPU unthrottled! temp: %lluC\n", temp);
		/* Immediately enforce new thermal policy on online CPUs */
		update_online_cpu_policy();
	}

reschedule:
	queue_delayed_work(thermal_wq, &thermal_work,
				msecs_to_jiffies(t_conf->sampling_ms));
}
static long tcmd_misc_ioctl( struct file *file,
                             unsigned int cmd, unsigned long arg)
{
#ifdef CONFIG_TCMD
    void __user *argp = (void __user *)arg;
    int gpio_enum = -1, irq = -1, gpio_state = -1, rc = 0;

    pr_info("tcmd_misc_ioctl is called");

    switch(cmd)
    {
    case TCMD_IOCTL_SET_REG:
    case TCMD_IOCTL_GET_REG:
    {
        tcmd_reg_arg reg_arg;
        struct regulator *reg_p;
        printk("TCMD_IOCTL_SET_REG or GET");
        if (copy_from_user(&reg_arg, argp, sizeof(tcmd_reg_arg)))
            return -EFAULT;

        reg_p = regulator_get(NULL,reg_arg.name );

        if (IS_ERR(reg_p))
        {
            printk("%s: VREG reg_p get failed\n", __func__);
            reg_p  = NULL;
            return -EFAULT;
        }


        if(cmd == TCMD_IOCTL_GET_REG ) {
            printk("cmd == TCMD_IOCTL_GET_REG ");
            if(TCMD_REG_GET_VOLTAGE  == reg_arg.cmd)
            {   printk("cmd == TCMD_REG_GET_VOLTAGE  ");
                reg_arg.param = regulator_get_voltage(reg_p);
            } else if(TCMD_REG_GET_POWER_MODE  == reg_arg.cmd)
            {
                reg_arg.param = regulator_get_mode(reg_p);
            }
            if(copy_to_user((tcmd_reg_arg  *)argp, &reg_arg, sizeof(tcmd_reg_arg )))
                return -EFAULT;

        }
        else {
            switch(reg_arg.cmd)
            {
            case TCMD_REG_ENABLE :
                printk("TCMD_REGULATOR_ENABLE\n");
                rc = regulator_enable(reg_p);
                if (rc) {
                    pr_info( " regulator_enable failed:%d\n", rc);
                    return rc;
                }
                break;
            case     TCMD_REG_DISABLE:
                printk("TCMD_REGULATOR_DISABLE\n");
                rc = regulator_disable(reg_p);
                if (rc) {
                    pr_info( " regulator_disable failed:%d\n", rc);
                    return rc;
                }
                break;
            case    TCMD_REG_SET_VOLTAGE :
                pr_info("TCMD_REG_SET_VOLTAGE, reg_arg.param= %d\n",reg_arg.param);
                rc = regulator_set_voltage(reg_p, reg_arg.param, reg_arg.param);
                if (rc) {
                    pr_info( " regulator_set_voltage failed:%d\n", rc);
                    return rc;
                }
                break;
            case    TCMD_REG_SET_POWER_MODE :
                pr_info("TCMD_REG_SET_POWER_MODE, reg_arg.param= %d\n",reg_arg.param);
                rc = regulator_set_mode(reg_p, reg_arg.param);
                if (rc) {
                    pr_info( " regulator_set_mode failed:%d\n", rc);
                    return rc;
                }
                break;
            default:
                return -EINVAL;
                break;
            }

        }
        break;
    }
    case TCMD_IOCTL_CHARGER:
    {

        unsigned char charger_enable;
        pr_info("cmd == TCMD_IOCTL_CHARGER");

        if (copy_from_user(&charger_enable, argp, sizeof(unsigned char )))
            return -EFAULT;

        switch(charger_enable)
        {
        case 0:
            rc = qpnp_disable_source_current(true);
            if (rc)
            {
                printk("TCMD :tcmd_driver : qpnp_disable_source_current failed:%d\n", rc);
                return rc;
            }
            break;
        case 1:
            rc = qpnp_set_max_battery_charge_current(true);
            if (rc)
            {
                pr_info("TCMD : tcmd_driver : qpnp_set_max_battery_charge_current(true) failed:%d\n", rc);
                return rc;
            }
            rc = qpnp_disable_source_current(false);
            if (rc)
            {
                pr_info("TCMD : tcmd_driver : qpnp_disable_source_current(false) failed:%d\n", rc);
                return rc;
            }
            printk("TCMD : Enable charging with high current successful");
            break;
        case 2:
            rc = qpnp_set_max_battery_charge_current(false);
            if (rc)
            {
                printk("TCMD : tcmd_driver : qpnp_set_max_battery_charge_current(false) failed:%d\n", rc);
                return rc;
            }
            rc = qpnp_disable_source_current(false);
            if (rc)
            {
                pr_info("TCMD : tcmd_driver : qpnp_disable_source_current(false) failed:%d\n", rc);
                return rc;
            }
            printk("TCMD : Enable charging with low current successful");
            break;
            break;
        default:
            return -EINVAL;
            break;
        }
        break;
    }
    case TCMD_IOCTL_USB_CHRGING:
    {
        unsigned char usb_charger_enable;
        pr_info("TCMD: cmd = TCMD_IOCTL_USB_CHRGING");
        if(copy_from_user(&usb_charger_enable, argp, sizeof(unsigned char)))
            return -EFAULT;

        switch(usb_charger_enable)
        {
        case 0:
            printk("TCMD: tcmd_driver : Disable USB charging\n");
            rc = qpnp_disable_usb_charging(!usb_charger_enable);
            if(rc) {
                printk("TCMD: qpnp-charger disable usb charging failed:%d\n", rc);
                return rc;
            }
            break;
        case 1:
            printk("TCMD: tcmd_driver : Enable USB charging\n");
            rc = qpnp_disable_usb_charging(!usb_charger_enable);
            if(rc) {
                printk("TCMD: qpnp-charger enable usb charging failed:%d\n", rc);
                return rc;
            }
        }
        break;
    }
    case TCMD_IOCTL_CHGPTH_PRIORITY:
    {
        unsigned char charging_path_priority;
        pr_info("TCMD: cmd = TCMD_IOCTL_CHGPTH_PRIORITY\n");
        if(copy_from_user(&charging_path_priority, argp, sizeof(unsigned char)))
            return -EFAULT;

        switch(charging_path_priority)
        {
        case 0:
            printk("TCMD: tcmd_driver : USB_IN priority \n");
            rc = qpnp_chg_priority(charging_path_priority);
            if(rc) {
                printk("TCMD: qpnp_chg_priority USB_IN failed:%d\n", rc);
                return rc;
            }
            break;
        case 1:
            printk("TCMD: tcmd_driver : DC_IN priority \n");
            rc = qpnp_chg_priority(charging_path_priority);
            if(rc) {
                printk("TCMD: qpnp_chg_priority DC_IN failed:%d\n", rc);
                return rc;
            }
        }
        break;
    }
    /*case TCMD_IOCTL_SET_FLASH_LM3559:
    {
    	int flash_lm3559_state;
    	pr_info("TCMD_IOCTL_SET_FLASH_LM3559\n");

    	if(copy_from_user(&flash_lm3559_state, argp, sizeof(int)))
    		return -EFAULT;

    	rc = lm3559_flash_set_led_state(flash_lm3559_state);

    	if(rc){
    		pr_info("Error on calling set_flash_lm3559\n");
    		return rc;
    	}
    	break;
    }*/
    case TCMD_IOCTL_POWER_DOWN:
    {
        pr_info("TCMD_IOCTL_POWER_DOWN\n");
        kernel_power_off();
        break;
    }
    case TCMD_IOCTL_GET_ADC:
    {
        TCMD_QPNP_VADC_CHAN_PARAM  adc_arg;
        //struct qpnp_vadc_chip *vadc;
        int ibat_ua;

        printk("TCMD_IOCTL_GET_ADC");
        if (copy_from_user(&adc_arg, argp, sizeof(TCMD_QPNP_VADC_CHAN_PARAM)))
            return -EFAULT;
        printk("adc_arg.cmd: %d",adc_arg.cmd);
        if(!vchip)
        {
            printk("vchip is NULL\n");
        }
        if (adc_arg.cmd == TCMD_PMIC_ADC_BATTERY_CURRENT) {
            printk("adc_arg.cmd == TCMD_PMIC_ADC_BATTERY_CURRENT");
            rc = tcmd_get_battery_current(&ibat_ua);
            adc_arg.adc_config.physical = ibat_ua;
            adc_arg.adc_config.measurement = adc_arg.adc_config.physical;
        } else {
            rc = qpnp_vadc_read(vchip, adc_arg.cmd, &adc_arg.adc_config);
        }

        if (rc) {
            pr_info("Error on calling qpnp_vadc_read");
            return rc;
        }

        if(copy_to_user((TCMD_QPNP_VADC_CHAN_PARAM *)argp, &adc_arg, sizeof(TCMD_QPNP_VADC_CHAN_PARAM)))
            return -EFAULT;

        break;
    }
    case TCMD_IOCTL_SET_GPIO:
    {
        TCMD_PM8XXX_GPIO_PARAM gpio_arg;

        printk("TCMD_IOCTL_SET_GPIO");
        if (copy_from_user(&gpio_arg, argp, sizeof(TCMD_PM8XXX_GPIO_PARAM)))
            return -EFAULT;
        printk("gpio_arg.cmd: %d",  gpio_arg.cmd);

        rc = pm8xxx_gpio_config(gpio_arg.cmd, &gpio_arg.gpio_config);

        if (rc) {
            pr_info("Error on calling pm8xxx_gpio_config");
            return rc;
        }

        break;
    }
    case TCMD_IOCTL_GET_USB_BAT_CURRENT:
    {
        int rc = -1;
        TCMD_REG_USB_BAT_CURRENT adc_arg;
        printk("TCMD_IOCTL_GET_USB_BAT_CURRENT");
        if (copy_from_user(&adc_arg, argp, sizeof(TCMD_REG_USB_BAT_CURRENT)))
        {
            return -EFAULT;
        }

        qpnp_get_usb_max_current(&adc_arg.usbPresentCurrent);
        rc = qpnp_get_bat_max_current(&adc_arg.batPresentCurrent);

        if(rc < 0)
        {
            return rc;
        }

        if(copy_to_user((TCMD_REG_USB_BAT_CURRENT *)argp, &adc_arg, sizeof(TCMD_REG_USB_BAT_CURRENT)))
            return -EFAULT;

        return rc;
    }
    case TCMD_IOCTL_SET_USB_BAT_CURRENT:
    {
        int rc = -1;
        TCMD_REG_USB_BAT_CURRENT adc_arg;
        printk("TCMD_IOCTL_GET_USB_BAT_CURRENT");
        if (copy_from_user(&adc_arg, argp, sizeof(TCMD_REG_USB_BAT_CURRENT)))
        {
            return -EFAULT;
        }

        rc = qpnp_set_usb_max_current(adc_arg.usbPresentCurrent);
        if(rc < 0)
        {
            return rc;
        }

        rc = qpnp_set_bat_max_current(adc_arg.batPresentCurrent);
        return rc;
    }
    case TCMD_IOCTL_COINCELL_ENABLE_DISABLE:
    {
        int coincell_state;
        pr_info("TCMD_IOCTL_COINCELL_ENABLE_DISABLE\n");
        if(copy_from_user(&coincell_state, argp, sizeof(int)))
            return -EFAULT;
        printk("TCMD:Set charger state entering with value : %d",coincell_state);
        rc = tcmd_qpnp_coincell_set_charger(coincell_state);
        if(rc) {
            pr_info("Error on calling  tcmd_qpnp_coincell_set_charger\n");
            printk("TCMD:Error on calling tcms_qpnp_coincell_set_charger : %d",rc);
            return rc;
        }
        printk("TCMD:Set charger state out with value : %d",rc);
        break;
    }
    case TCMD_IOCTL_SET_COINCELL:
    {
        TCMD_QPNP_CC_CHG_PARAM coincell_arg;
        printk("TCMD_IOCTL_SET_COINCELL");
        if (copy_from_user(&coincell_arg, argp, sizeof(TCMD_QPNP_CC_CHG_PARAM)))
            return -EFAULT;

        //rc = pm8xxx_coincell_chg_config(&coincell_arg);
        printk("\nState - > %d \n Voltage - > %d \n Resistance -> %d \n",coincell_arg.state,coincell_arg.voltage,coincell_arg.resistance);
        if((rc = tcmd_qpnp_coincell_set_charger(coincell_arg.state))) {
            printk("Error in configuring the state : tcmd_qpnp_coincell_set_charger : rc= %d",rc);
            return rc;
        }
        if((rc =  tcmd_qpnp_coincell_set_voltage(coincell_arg.voltage))) {
            printk("Error in configuring Voltage :tcmd_qpnp_coincell_set_voltage: rc= %d",rc);
            return rc;
        }
        if((rc = tcmd_qpnp_coincell_set_resistance(coincell_arg.resistance)))	{
            printk("Error in configuring Resistance :tcmd_qpnp_coincell_set_resistance : rc= %d",rc);
            return rc;
        }

        if (rc) {
            pr_info("Error on calling pm8xxx_coincell_chg_config ");
            printk("value of rc = %d",rc);
            return rc;
        }
        break;
    }
    /*	case TCMD_IOCTL_SET_VIBRATOR:
    	{
    		TCMD_PM8XXX_VIB_PARAM vib_arg;

    		printk("TCMD_IOCTL_SET_VIBRATOR");
    		if (copy_from_user(&vib_arg, argp, sizeof(TCMD_PM8XXX_VIB_PARAM)))
    			return -EFAULT;

    		rc = pm8xxx_vibrator_config(&vib_arg);

    		if (rc) {
    		pr_info("Error on calling pm8xxx_vibrator_config");
    		return rc;
    		}

    		break;

    	}*/

    default:
    {
        struct tcmd_gpio_set_arg gpio_set_arg;

        if (cmd == TCMD_IOCTL_SET_INT) {
            if (copy_from_user(&gpio_set_arg, argp, 2))
                return -EFAULT;
            gpio_enum = gpio_set_arg.gpio;
            gpio_state = gpio_set_arg.gpio_state;
        }
        else if (copy_from_user(&gpio_enum, argp, sizeof(int)))
            return -EFAULT;

        if (gpio_enum < 0)
            return -EINVAL;

        switch (cmd) {
        case TCMD_IOCTL_MASK_INT:
        case TCMD_IOCTL_UNMASK_INT:
            irq = gpio_to_irq(gpio_enum);
            if (irq < 0)
                return -EINVAL;
            break;
        default:
            break;
        }

        switch (cmd) {
        case TCMD_IOCTL_MASK_INT:
            pr_info("tcmd mask interrupt: gpio = %d, irq = %d.\n",
                    gpio_enum, irq);
            disable_irq(irq);
            break;
        case TCMD_IOCTL_UNMASK_INT:
            pr_info("tcmd unmask interrupt: gpio = %d, irq = %d.\n",
                    gpio_enum, irq);
            enable_irq(irq);
            break;
        case TCMD_IOCTL_READ_INT:
            gpio_state = gpio_get_value(gpio_enum);
            pr_info("tcmd interrupt state: gpio = %d -> %d.\n",
                    gpio_enum, gpio_state);
            if (copy_to_user(argp, &gpio_state, sizeof(int)))
                return -EFAULT;
            break;
        case TCMD_IOCTL_SET_INT:
            pr_info("tcmd set interrupt state: gpio = %d -> %d.\n",
                    gpio_enum, gpio_state);
            gpio_set_value(gpio_enum, gpio_state);
            break;
        default:
            return -EINVAL;
        }
        break;
    }//default
    }
#endif
    return 0;
}
int lge_pm_get_cable_info(struct qpnp_vadc_chip *vadc,
		struct chg_cable_info *cable_info)
{
	char *type_str[] = {
		"NOT INIT", "MHL 1K", "U_28P7K", "28P7K", "56K",
		"100K", "130K", "180K", "200K", "220K",
		"270K", "330K", "620K", "910K", "OPEN"
	};

	struct qpnp_vadc_result result;
	struct chg_cable_info *info = cable_info;
	struct chg_cable_info_table *table;
	int table_size = ARRAY_SIZE(lge_acc_cable_type_data);
	int acc_read_value = 0;
	int i, rc;
	int count = 1;

	if (!info) {
		pr_err("%s : invalid info parameters\n", __func__);
		return -EINVAL;
	}

	if (!vadc) {
		pr_err("%s : invalid vadc parameters\n", __func__);
		return -EINVAL;
	}

	if (!cable_type_defined) {
		pr_err("%s : cable type is not defined yet.\n", __func__);
		return -EINVAL;
	}

	for (i = 0; i < count; i++) {
		rc = qpnp_vadc_read(vadc, LR_MUX10_USB_ID_LV, &result);

		if (rc < 0) {
			if (rc == -ETIMEDOUT) {
				/* reason: adc read timeout,
				 * assume it is open cable
				 */
				info->cable_type = CABLE_NONE;
				info->ta_ma = C_NONE_TA_MA;
				info->usb_ma = C_NONE_USB_MA;
			}
			pr_err("%s : adc read error - %d\n", __func__, rc);
			return rc;
		}

		acc_read_value = (int)result.physical;
		pr_info("%s : adc_read-%d\n", __func__, (int)result.physical);
		/* mdelay(10); */
	}

	info->cable_type = NO_INIT_CABLE;
	info->ta_ma = C_NO_INIT_TA_MA;
	info->usb_ma = C_NO_INIT_USB_MA;

	/* assume: adc value must be existed in ascending order */
	for (i = 0; i < table_size; i++) {
		table = &lge_acc_cable_type_data[i];

		if (acc_read_value <= table->threshhold) {
			info->cable_type = table->type;
			info->ta_ma = table->ta_ma;
			info->usb_ma = table->usb_ma;
			break;
		}
	}

	pr_err("\n\n[PM]Cable detected: %d(%s)(%d, %d)\n\n",
			acc_read_value, type_str[info->cable_type],
			info->ta_ma, info->usb_ma);

	return 0;
}
static int sec_bat_adc_ap_read(struct sec_battery_info *battery, int channel)
{
	struct qpnp_vadc_result results;
	int rc = -1;
	int data = -1;

	switch (channel)
	{
	case SEC_BAT_ADC_CHANNEL_TEMP:
		rc = qpnp_vadc_read(adc_client, LR_MUX1_BATT_THERM, &results);
		if (rc) {
			pr_err("%s: Unable to read batt temperature rc=%d\n",
					__func__, rc);
			return 0;
		}
		data = results.adc_code;
		break;
	case SEC_BAT_ADC_CHANNEL_TEMP_AMBIENT:
		data = 33000;
		break;
	case SEC_BAT_ADC_CHANNEL_BAT_CHECK:
		rc = qpnp_vadc_read(adc_client, LR_MUX2_BAT_ID, &results);
		if (rc) {
			pr_err("%s: Unable to read BATT_ID ADC rc=%d\n",
					__func__, rc);
			return 0;
		}
		pr_debug("BAT_ID physical= %lld, raw = 0x%x\n", results.physical, results.adc_code);
		data = results.physical;
		break;
	case SEC_BAT_ADC_CHANNEL_INBAT_VOLTAGE:
		rc = qpnp_vadc_read(adc_client, VBAT_SNS, &results);
		if (rc) {
			pr_err("%s: Unable to read VBAT_SNS ADC rc=%d\n",
					__func__, rc);
			return 0;
		}
		data = ((int)results.physical)/1000;
		break;
	case SEC_BAT_ADC_CHANNEL_DISCHARGING_CHECK:
#if defined(CONFIG_MACH_A8_CHN_OPEN)||defined(CONFIG_MACH_GTEL_USA_VZW) || defined(CONFIG_MACH_GTES_USA_SPR) || \
	defined(CONFIG_MACH_GTELWIFI_USA_OPEN)
                rc = qpnp_vadc_read(adc_client, LR_MUX2_BAT_ID, &results);
#else
                rc = qpnp_vadc_read(adc_client, LR_MUX1_BATT_THERM, &results);
#endif
                if (rc) {
                        pr_err("%s: Unable to read discharging_check ADC rc=%d\n",
                                        __func__, rc);
                        return 0;
                }
                data = results.adc_code;
                break;
	case SEC_BAT_ADC_CHANNEL_DISCHARGING_NTC:
		return 0;
		break;
	default :
		break;
	}

	return data;
}