int32_t sprd_get_chg_current(struct sprd_battery_data * data)
{
	int32_t vbat, isense;
	int32_t cnt = 0;

	for (cnt = 0; cnt < 8; cnt++) {
		isense =
		    sprd_bat_adc_to_vol(data,
					sci_adc_get_value(ADC_CHANNEL_ISENSE,
							  false));
		vbat =
		    sprd_bat_adc_to_vol(data,
					sci_adc_get_value(ADC_CHANNEL_VBAT,
							  false));
		if (isense >= vbat) {
			break;
		}
	}
	if (isense > vbat) {
		return ((isense - vbat) * 10);	//(vol/0.1ohm)
	} else {
		printk(KERN_ERR
		       "chg_current err......................isense:%d..................vbat:%d\n",
		       isense, vbat);
		return 0;
	}
}
int32_t sprd_get_vprog(struct sprd_battery_data * data)
{
	int i, temp;
	volatile int j;
	int32_t vprog_result[VPROG_RESULT_NUM];

	for (i = 0; i < VPROG_RESULT_NUM;) {
		vprog_result[i] = sci_adc_get_value(ADC_CHANNEL_PROG, false);
		if (vprog_result[i] < 0)
			continue;

		i++;
		for (j = VBAT_RESULT_DELAY - 1; j >= 0; j--) {
			;
		}
	}

	for (j = 1; j <= VPROG_RESULT_NUM - 1; j++) {
		for (i = 0; i < VPROG_RESULT_NUM - j; i++) {
			if (vprog_result[i] > vprog_result[i + 1]) {
				temp = vprog_result[i];
				vprog_result[i] = vprog_result[i + 1];
				vprog_result[i + 1] = temp;
			}
		}
	}

	return vprog_result[VPROG_RESULT_NUM / 2];
}
static int sec_therm_get_adc_data(struct sec_therm_info *info, int thermistor)
{
	int adc_data;
	int adc_max = 0, adc_min = 0, adc_total = 0;
	int i;
	unsigned int adc_ch = ADC_CHANNEL_0;

	if (thermistor == AP_TEMP)
		adc_ch = info->pdata->ap_channel;
	else if (thermistor == DCXO_TEMP)
		adc_ch = info->pdata->dcxo_channel;

	for (i = 0; i < ADC_SAMPLING_CNT; i++) {
		adc_data = sci_adc_get_value(adc_ch,0);

		if (adc_data < 0) {
			dev_err(info->dev, "%s : err(%d) returned, skip read\n",
				__func__, adc_data);
			return adc_data;
		}

		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);
}
/* adc checking sys fs - ffkaka */
static ssize_t headset_adc_show(struct device *dev, struct device_attribute *attr,char *buf)
{
	int adc_value;

	headset_mic_bias_control(1);
	adc_value = sci_adc_get_value(headset.detect.adc_channel,ADC_SCALE_1V2);
	
	return sprintf(buf,"ADC Value = 0x%x\n",adc_value);
}
static int sec_bat_adc_ap_read(int channel)
{
    int data;
    int ret = 0;

    if (channel == SEC_BAT_ADC_CHANNEL_BAT_CHECK)
        data = sci_adc_get_value(ADC_CHANNEL_VF, false);
    else
        data = sci_adc_get_value(ADC_CHANNEL_TEMP, false);
    pr_info("read channel [%d]\n", data);
    /*
    int data = -1;
    int ret = 0;

    switch (channel)
    {
    case SEC_BAT_ADC_CHANNEL_CABLE_CHECK:
    case SEC_BAT_ADC_CHANNEL_BAT_CHECK:
    	break;
    case SEC_BAT_ADC_CHANNEL_TEMP:
    case SEC_BAT_ADC_CHANNEL_TEMP_AMBIENT:
    	data = sci_adc_get_value(ADC_CHANNEL_1,0);
    	if (ret < 0)
    		pr_info("read channel error[%d]\n", ret);
    	else
    		pr_debug("TEMP ADC(%d)\n", data);
    	break;
    case SEC_BAT_ADC_CHANNEL_FULL_CHECK:
    case SEC_BAT_ADC_CHANNEL_VOLTAGE_NOW:
    case SEC_BAT_ADC_CHANNEL_NUM:
    	break;
    default:
    	break;
    }
    */
    return data;
}
static enum hrtimer_restart report_headset_detect_status(int active, struct _headset_gpio *hgp)
{
	struct regulator *mic_regulator;
	mic_regulator = regulator_get(NULL, REGU_NAME_MIC);
	int adc_value;

	if (active) {
		if (!IS_ERR(mic_regulator)) {
			regulator_set_voltage(mic_regulator, 2800000, 2800000);
			regulator_enable(mic_regulator);
		}
		mdelay(20);

		headset_hook_detect(1);
		hgp->parent->headphone = 0;
		/*hgp->parent->headphone = hgp->parent->button.active_low ^ headset_gpio_get_value(hgp->parent->button.gpio);*/
		adc_value = sci_adc_get_value(ADC_CHANNEL_TEMP, false);

		hgp->parent->headphone = adc_value > 0x05? 0 : 1;

		if (hgp->parent->headphone) {
			switch_set_state(&hgp->parent->sdev, BIT_HEADSET_NO_MIC);
			if (!IS_ERR(mic_regulator))
				regulator_disable(mic_regulator);
			pr_info("headphone plug in\n");
		} else {

			switch_set_state(&hgp->parent->sdev, BIT_HEADSET_MIC);
			pr_info("headset plug in\n");
			headset_gpio_set_irq_type(hgp->parent->button.irq, hgp->parent->button.irq_type_active);
			headset_gpio_irq_enable(1, &hgp->parent->button);
		}
	} else {
		headset_gpio_irq_enable(0, &hgp->parent->button);
		hgp->parent->button.callback(-1, &hgp->parent->button);
		headset_hook_detect(0);
		if (hgp->parent->headphone)
			pr_info("headphone plug out\n");
		else {
			if (!IS_ERR(mic_regulator))
				regulator_disable(mic_regulator);
			pr_info("headset plug out\n");
		}
		switch_set_state(&hgp->parent->sdev, BIT_HEADSET_OUT);
	}
	/* use below code only when gpio irq misses state ? */
	/* headset_gpio_set_irq_type(hgp->irq, active ? hgp->irq_type_inactive : hgp->irq_type_active); */
	return HRTIMER_NORESTART;
}
/* Determine 3pole or 4pole is detected - ffkaka */
static void headset_hs_detect_mode(struct _headset_gpio *hgp)
{
	int adc_val = sci_adc_get_value(hgp->adc_channel, ADC_SCALE_1V2);
	pr_info("[headset] Detection ADC = 0x%0x !!!!\n",adc_val);

	if(adc_val < HEADSET_ADC_3POLE_MAX){
		hgp->parent->headphone = 1;
	}
	else if(adc_val < HEADSET_ADC_4POLE_MAX){
		hgp->parent->headphone = 0;
	}
	else{
		hgp->parent->headphone = 0;
	}
}
Esempio n. 8
0
static unsigned int headset_get_button_code_board_method(int v)
{
	static struct headset_adc_range {
		int min;
		int max;
		int code;
	} adc_range[] = {
		{ 0x0005, 0x0050, KEY_MEDIA},
		{ 0x0050, 0x0090, KEY_VOLUMEUP },
		{ 0x0090, 0x0150, KEY_VOLUMEDOWN },
	};
	int adc_value = sci_adc_get_value(ADC_CHANNEL_TEMP, false);
	int i;
	for (i = 0; i < ARRY_SIZE(adc_range); i++)
		if (adc_value >= adc_range[i].min && adc_value < adc_range[i].max)
			return adc_range[i].code;
	return KEY_RESERVED;
}
Esempio n. 9
0
static int adc_show_all(struct seq_file *s, void *v)
{
	int channel;

	seq_printf(s, "\nCalibration: %s\n\n", htc_adc_is_calibrated() ? "OK" : "NONE");

	for (channel = 0; channel <= ADC_MAX; channel++)
	{
		int val;
		uint16_t mV;

		if (channel_desc[channel] == NULL) continue;

		val = sci_adc_get_value(channel, true);
		mV = htc_adc_to_vol(channel, val);

		seq_printf(s, "[%02u] %-20s %4u %4u(mV)\n", channel, channel_desc[channel], val, mV);
	}

	return 0;
}
Esempio n. 10
0
static unsigned int headset_get_button_code_board_method(int v)
{
	static struct headset_adc_range {
		int min;
		int max;
		int code;
	} adc_range[] = {
		{ 0, 171, KEY_MEDIA},		
	       { 171, 350, KEY_VOLUMEUP },	
	       { 350, 700, KEY_VOLUMEDOWN },
	};
	int temp;
	int adc_value;
	temp = sci_adc_get_value(ADC_CHANNEL_TEMP, false);
	adc_value = ((1200 * (temp)) / 0x3FC);
	int i;
	pr_info("[%s]temp : %d, [button_adc_value] : %d\n", __func__,temp,  adc_value);
	for (i = 0; i < ARRY_SIZE(adc_range); i++)
		if (adc_value >= adc_range[i].min && adc_value < adc_range[i].max)
			return adc_range[i].code;
	return KEY_RESERVED;
}
static unsigned int headset_get_button_code_board_method(int v)
{
	static struct headset_adc_range {
		int min;
		int max;
		int code;
	} adc_range[] = {
		{ 0x0000, 0x0030, KEY_MEDIA},
		{ 0x0031, 0x0065, KEY_VOLUMEUP},
		{ 0x0066, 0x00cf, KEY_VOLUMEDOWN },
	};

	int adc_value;

	adc_value = sci_adc_get_value(ADC_CHANNEL_TEMP, ADC_SCALE_3V);
	pr_info("[headset] ********* adc value7 SCALE 0~3V : 0x%x ******* \n", adc_value);			

	int i;
	for (i = 0; i < ARRY_SIZE(adc_range); i++)
		if (adc_value >= adc_range[i].min && adc_value < adc_range[i].max)
			return adc_range[i].code;
	return KEY_RESERVED;
}
int dcdc_calibrate(int adc_chan, int def_vol, int to_vol)
{
	int i;
	u32 val[MEASURE_TIMES], sum = 0, adc_vol, ctl_vol, cal_vol;
	for (i = 0; i < ARRAY_SIZE(val); i++) {
		sum += val[i] = sci_adc_get_value(adc_chan, true);
	}
	sum /= ARRAY_SIZE(val);	/* get average value */
	info("adc chan %d, value %d\n", adc_chan, sum);
	adc_vol = sprd_get_adc_to_vol(sum) * (8 * 5) / (30 * 4);
	if (!def_vol) {
		switch (adc_chan) {
		case ADC_CHANNEL_DCDC:
			def_vol = 1100;
			cal_vol = sci_adi_read(ANA_DCDC_CTRL_CAL) & 0x1f;
			i = sci_adi_read(ANA_DCDC_CTRL) & 0x07;
			break;
		case ADC_CHANNEL_DCDCARM:
			def_vol = 1200;
			cal_vol = sci_adi_read(ANA_DCDCARM_CTRL_CAL) & 0x1f;
			i = sci_adi_read(ANA_DCDCARM_CTRL) & 0x07;
			break;
		default:
			goto exit;
		}
		if (0 != i /* + cal_vol */ )
			def_vol = dcdc_ctl_vol[i];
		def_vol += cal_vol * 100 / 32;
#if 0
		if (0 != i + cal_vol) {	/* dcdc had been adjusted in uboot-spl */
			debug("%s default %dmv, from %dmv to %dmv\n",
			     __FUNCTION__, def_vol, adc_vol, to_vol);
			goto exit;
		}
#endif
	}
	info("%s default %dmv, from %dmv to %dmv\n", __FUNCTION__, def_vol,
	     adc_vol, to_vol);

	cal_vol = abs(adc_vol - to_vol);
	if (cal_vol > 200 /* mv */ )
		goto exit;
	else if (cal_vol < to_vol / 100) {
		info("%s is ok\n", __FUNCTION__);
		return 0;
	}

	ctl_vol = def_vol * to_vol / adc_vol;
	for (i = 0; i < ARRAY_SIZE(dcdc_ctl_vol) - 1; i++) {
		if (ctl_vol < dcdc_ctl_vol[i + 1])
			break;
	}
	if (i >= ARRAY_SIZE(dcdc_ctl_vol) - 1)
		goto exit;

	cal_vol = ((ctl_vol - dcdc_ctl_vol[i]) * 32 / 100) % 32;
	debug("%s cal_vol %dmv: %d, 0x%02x\n", __FUNCTION__,
	      dcdc_ctl_vol[i] + cal_vol * 100 / 32, i, cal_vol);
	switch (adc_chan) {
	case ADC_CHANNEL_DCDC:
		sci_adi_raw_write(ANA_DCDC_CTRL_CAL,
				  cal_vol | (0x1f - cal_vol) << 8);
		sci_adi_raw_write(ANA_DCDC_CTRL, i | (0x07 - i) << 4);
		break;
	case ADC_CHANNEL_DCDCARM:
		sci_adi_raw_write(ANA_DCDCARM_CTRL_CAL,
				  cal_vol | (0x1f - cal_vol) << 8);
		sci_adi_raw_write(ANA_DCDCARM_CTRL, i | (0x07 - i) << 4);
		break;
	default:
		break;
	}

	return dcdc_ctl_vol[i] + cal_vol * 100 / 32;
      exit:
	info("%s failure\n", __FUNCTION__);
	return -1;
}