高通ADC
adc dtsi中的属性配置详解:
qcom,pre-scaling的缩放的比例是1:1还是1:3主要和要读取的电压值范围有关系,如果参考电压为1.8V,需要读取的电压范围超过1.8V,那么就要选择1:3的adc通道,这样adc可读取的电压范围就变为0~5.4V
在adc通道选择时,高通主要分为四类通道:无内部上拉,上拉30K、上拉100K、上拉400K电阻。
怎样去选择这几种类型的adc通道呢?
- 读电压一般选择无内部上拉
- 读电流或者温度会选择上拉,上拉电阻的大小和外部下拉的电阻大小有关。
- 注意,经实际示波器抓adc信号,当配置adc通道为内部上拉时,万用表是量不出adc电压的,可能为了省电,这个adc信号是个脉冲,不是一个直流电平信号。
内部上拉的目的是给电路供电,在读温度时,adc外部接的NTC电阻,大概的原理图如下:
NTC电阻的阻值随着温度的变化而变化,所以NTC电阻的分压也会产生变化。
NTC电阻阻值和温度对照表
软件中的对应表:qcom-vadc-common.c
软件会进行计算出NTC电阻的分压,公式为:
(ADC code * vref_vadc (1.875V)) / full_scale_code
并通过对应表,读出相应的温度:
static int qcom_vadc_scale_hw_calib_therm(
const struct vadc_prescale_ratio *prescale,
const struct adc_data *data,
u16 adc_code, int *result_mdec)
{
s64 voltage = 0, result = 0;
int ret;
if (adc_code > VADC5_MAX_CODE)
adc_code = 0;
/* (ADC code * vref_vadc (1.875V)) / full_scale_code */
voltage = (s64) adc_code * ADC_HC_VDD_REF * 1000;
voltage = div64_s64(voltage, (data->full_scale_code_volt
* 1000));
ret = qcom_vadc_map_voltage_temp(adcmap_100k_104ef_104fb_1875_vref,
ARRAY_SIZE(adcmap_100k_104ef_104fb_1875_vref),
voltage, &result);
if (ret)
return ret;
*result_mdec = result;
return 0;
}
adcmap_100k_104ef_104fb_1875_vref表对应的是100k上拉和SCALE_HW_CALIB_XOTHERM
case SCALE_HW_CALIB_THERM_100K_PULLUP:
case SCALE_HW_CALIB_XOTHERM:
return qcom_vadc_scale_hw_calib_therm(prescale, data,
adc_code, result);
由下面代码可知此adc的分辨率为0x70e4
const struct adc_data data_pmic5 = {
.full_scale_code_volt = 0x70e4,
/* On PM8150B, IBAT LSB = 10A/32767 */
.full_scale_code_cur = 10000,
.adc_chans = adc_chans_pmic5,
.decimation = (unsigned int []) {250, 420, 840},
.hw_settle = (unsigned int []) {15, 100, 200, 300, 400, 500, 600, 700,
800, 900, 1, 2, 4, 6, 8, 10},
};
adc读出来的电压计算公式:
实际电压/1.875=raw值(adc值)/0x70e4(10进制为28900)。
驱动中添加ADC通道是的注意点:
这个ADC5_CHAN_VOLT的第二个参数为选择的分频系数,具体是按照下面这个表选择的,如果是1:1,则为0,其它的同理。
static const struct vadc_prescale_ratio adc5_prescale_ratios[] = { {.num = 1, .den = 1}, {.num = 1, .den = 3}, {.num = 1, .den = 4}, {.num = 1, .den = 6}, {.num = 1, .den = 20}, {.num = 1, .den = 8}, {.num = 10, .den = 81}, {.num = 1, .den = 10}, {.num = 1, .den = 16}, {.num = 40, .den = 41}, /* PM7_SMB_TEMP */ /* Prescale ratios for current channels below */ {.num = 32, .den = 100}, /* IIN_FB, IIN_SMB */ {.num = 16, .den = 100}, /* ICHG_SMB */ {.num = 1280, .den = 4100}, /* IIN_SMB_new */ {.num = 640, .den = 4100}, /* ICHG_SMB_new */ {.num = 1000, .den = 305185}, /* ICHG_FB */ {.num = 1000, .den = 610370}, /* ICHG_FB_2X */ {.num = 1000, .den = 366220}, /* ICHG_FB ADC5_GEN3 */ {.num = 1000, .den = 732440} /* ICHG_FB_2X ADC5_GEN3 */ };