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; } }
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; }
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; }
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; }