Loading drivers/iio/adc/qcom-spmi-adc5.c +233 −3 Original line number Diff line number Diff line Loading @@ -26,6 +26,7 @@ #include "qcom-vadc-common.h" #define ADC_USR_STATUS1 0x8 #define ADC7_USR_STATUS1_CONV_FAULT BIT(7) #define ADC_USR_STATUS1_REQ_STS BIT(1) #define ADC_USR_STATUS1_EOC BIT(0) #define ADC_USR_STATUS1_REQ_STS_EOC_MASK 0x3 Loading Loading @@ -73,6 +74,9 @@ #define ADC_CHAN_MIN ADC_USBIN #define ADC_CHAN_MAX ADC_LR_MUX3_BUF_PU1_PU2_XO_THERM #define ADC_CHANNEL_OFFSET 0x8 #define ADC_CHANNEL_MASK 0xff /* * Conversion time varies between 139uS to 6827uS based on the decimation, * clock rate, fast average samples with no measurement in queue. Loading @@ -89,6 +93,11 @@ #define ADC_CAL_DELAY_CTL_VAL_256S 0x73 #define ADC_CAL_DELAY_CTL_VAL_125MS 0x3 /* For PMIC7 */ #define ADC_APP_SID 0x40 #define ADC_APP_SID_MASK 0xf #define ADC7_CONV_TIMEOUT msecs_to_jiffies(10) enum adc_cal_method { ADC_NO_CAL = 0, ADC_RATIOMETRIC_CAL, Loading @@ -111,6 +120,7 @@ struct pmic_rev_data { * @cal_method: calibration method. * @cal_val: calibration value * @decimation: sampling rate supported for the channel. * @sid: slave id of PMIC owning the channel, for PMIC7. * @prescale: channel scaling performed on the input signal. * @hw_settle_time: the time between AMUX being configured and the * start of conversion. Loading @@ -124,6 +134,7 @@ struct adc_channel_prop { enum adc_cal_method cal_method; enum adc_cal_val cal_val; unsigned int decimation; unsigned int sid; unsigned int prescale; unsigned int hw_settle_time; unsigned int avg_samples; Loading Loading @@ -161,6 +172,7 @@ struct adc_chip { bool skip_usb_wa; void *ipc_log0; void *ipc_log1; bool is_pmic7; struct pmic_revid_data *pmic_rev_id; const struct adc_data *data; }; Loading @@ -187,6 +199,11 @@ static int adc_write(struct adc_chip *adc, u16 offset, u8 *data, int len) return regmap_bulk_write(adc->regmap, adc->base + offset, data, len); } static int adc_masked_write(struct adc_chip *adc, u16 offset, u8 mask, u8 val) { return regmap_update_bits(adc->regmap, adc->base + offset, mask, val); } static int adc_prescaling_from_dt(u32 num, u32 den) { unsigned int pre; Loading Loading @@ -529,6 +546,49 @@ static int adc_configure(struct adc_chip *adc, return ret; } static int adc7_configure(struct adc_chip *adc, struct adc_channel_prop *prop) { int ret; u8 conv_req = 0, buf[4]; ret = adc_masked_write(adc, ADC_APP_SID, ADC_APP_SID_MASK, prop->sid); if (ret) return ret; ret = adc_read(adc, ADC_USR_DIG_PARAM, buf, sizeof(buf)); if (ret < 0) return ret; /* Digital param selection */ adc_update_dig_param(adc, prop, &buf[0]); /* Update fast average sample value */ buf[1] &= (u8) ~ADC_USR_FAST_AVG_CTL_SAMPLES_MASK; buf[1] |= prop->avg_samples; /* Select ADC channel */ buf[2] = prop->channel; /* Select HW settle delay for channel */ buf[3] &= (u8) ~ADC_USR_HW_SETTLE_DELAY_MASK; buf[3] |= prop->hw_settle_time; /* Select CONV request */ conv_req = ADC_USR_CONV_REQ_REQ; if (!adc->poll_eoc) reinit_completion(&adc->complete); ret = adc_write(adc, ADC_USR_DIG_PARAM, buf, sizeof(buf)); if (ret) return ret; ret = adc_write(adc, ADC_USR_CONV_REQ, &conv_req, 1); return ret; } static int adc_do_conversion(struct adc_chip *adc, struct adc_channel_prop *prop, struct iio_chan_spec const *chan, Loading Loading @@ -579,6 +639,44 @@ static int adc_do_conversion(struct adc_chip *adc, return ret; } static int adc7_do_conversion(struct adc_chip *adc, struct adc_channel_prop *prop, struct iio_chan_spec const *chan, u16 *data_volt, u16 *data_cur) { int ret; u8 status = 0; mutex_lock(&adc->lock); ret = adc7_configure(adc, prop); if (ret) { pr_err("ADC configure failed with %d\n", ret); goto unlock; } /* No support for polling mode at present*/ wait_for_completion_timeout(&adc->complete, ADC7_CONV_TIMEOUT); ret = adc_read(adc, ADC_USR_STATUS1, &status, 1); if (ret < 0) goto unlock; if (status & ADC7_USR_STATUS1_CONV_FAULT) { pr_err("Unexpected conversion fault\n"); ret = -EIO; goto unlock; } ret = adc_read_voltage_data(adc, data_volt); unlock: mutex_unlock(&adc->lock); return ret; } static irqreturn_t adc_isr(int irq, void *dev_id) { struct adc_chip *adc = dev_id; Loading @@ -601,6 +699,66 @@ static int adc_of_xlate(struct iio_dev *indio_dev, return -EINVAL; } static int adc7_of_xlate(struct iio_dev *indio_dev, const struct of_phandle_args *iiospec) { struct adc_chip *adc = iio_priv(indio_dev); int i, v_channel; for (i = 0; i < adc->nchannels; i++) { v_channel = ((adc->chan_props[i].sid << ADC_CHANNEL_OFFSET) | adc->chan_props[i].channel); if (v_channel == iiospec->args[0]) return i; } return -EINVAL; } static int adc7_read_raw(struct iio_dev *indio_dev, struct iio_chan_spec const *chan, int *val, int *val2, long mask) { struct adc_chip *adc = iio_priv(indio_dev); struct adc_channel_prop *prop; u16 adc_code_volt, adc_code_cur; int ret; prop = &adc->chan_props[chan->address]; switch (mask) { case IIO_CHAN_INFO_PROCESSED: ret = adc7_do_conversion(adc, prop, chan, &adc_code_volt, &adc_code_cur); if (ret) return ret; ret = qcom_vadc_hw_scale(prop->scale_fn_type, &adc_prescale_ratios[prop->prescale], adc->data, prop->lut_index, adc_code_volt, val); if (ret) return ret; return IIO_VAL_INT; case IIO_CHAN_INFO_RAW: ret = adc7_do_conversion(adc, prop, chan, &adc_code_volt, &adc_code_cur); if (ret) return ret; *val = (int)adc_code_volt; return IIO_VAL_INT; default: return -EINVAL; } return 0; } static int adc_read_raw(struct iio_dev *indio_dev, struct iio_chan_spec const *chan, int *val, int *val2, long mask) Loading Loading @@ -672,6 +830,11 @@ static const struct iio_info adc_info = { .of_xlate = adc_of_xlate, }; static const struct iio_info adc7_info = { .read_raw = adc7_read_raw, .of_xlate = adc7_of_xlate, }; struct adc_channels { const char *datasheet_name; unsigned int prescale_index; Loading Loading @@ -770,6 +933,39 @@ static const struct adc_channels adc_chans_pmic5[ADC_MAX_CHANNEL] = { SCALE_HW_CALIB_THERM_100K_PULLUP) }; static const struct adc_channels adc7_chans_pmic[ADC_MAX_CHANNEL] = { [ADC7_REF_GND] = ADC_CHAN_VOLT("ref_gnd", 0, SCALE_HW_CALIB_DEFAULT) [ADC7_1P25VREF] = ADC_CHAN_VOLT("vref_1p25", 0, SCALE_HW_CALIB_DEFAULT) [ADC7_VPH_PWR] = ADC_CHAN_VOLT("vph_pwr", 1, SCALE_HW_CALIB_DEFAULT) [ADC7_VBAT_SNS] = ADC_CHAN_VOLT("vbat_sns", 3, SCALE_HW_CALIB_DEFAULT) [ADC7_DIE_TEMP] = ADC_CHAN_TEMP("die_temp", 0, SCALE_HW_CALIB_PMIC_THERM_PM7) [ADC7_AMUX_THM1_100K_PU] = ADC_CHAN_TEMP("amux_thm1_pu2", 0, SCALE_HW_CALIB_THERM_100K_PU_PM7) [ADC7_AMUX_THM2_100K_PU] = ADC_CHAN_TEMP("amux_thm2_pu2", 0, SCALE_HW_CALIB_THERM_100K_PU_PM7) [ADC7_AMUX_THM3_100K_PU] = ADC_CHAN_TEMP("amux_thm3_pu2", 0, SCALE_HW_CALIB_THERM_100K_PU_PM7) [ADC7_AMUX_THM4_100K_PU] = ADC_CHAN_TEMP("amux_thm4_pu2", 0, SCALE_HW_CALIB_THERM_100K_PU_PM7) [ADC7_AMUX_THM5_100K_PU] = ADC_CHAN_TEMP("amux_thm5_pu2", 0, SCALE_HW_CALIB_THERM_100K_PU_PM7) [ADC7_AMUX_THM6_100K_PU] = ADC_CHAN_TEMP("amux_thm6_pu2", 0, SCALE_HW_CALIB_THERM_100K_PU_PM7) [ADC7_GPIO1_100K_PU] = ADC_CHAN_TEMP("gpio1_pu2", 0, SCALE_HW_CALIB_THERM_100K_PU_PM7) [ADC7_GPIO2_100K_PU] = ADC_CHAN_TEMP("gpio2_pu2", 0, SCALE_HW_CALIB_THERM_100K_PU_PM7) [ADC7_GPIO3_100K_PU] = ADC_CHAN_TEMP("gpio3_pu2", 0, SCALE_HW_CALIB_THERM_100K_PU_PM7) [ADC7_GPIO4_100K_PU] = ADC_CHAN_TEMP("gpio4_pu2", 0, SCALE_HW_CALIB_THERM_100K_PU_PM7) }; static const struct adc_channels adc_chans_rev2[ADC_MAX_CHANNEL] = { [ADC_REF_GND] = ADC_CHAN_VOLT("ref_gnd", 1, SCALE_HW_CALIB_DEFAULT) Loading @@ -793,14 +989,16 @@ static const struct adc_channels adc_chans_rev2[ADC_MAX_CHANNEL] = { SCALE_HW_CALIB_THERM_100K_PULLUP) }; static int adc_get_dt_channel_data(struct device *dev, static int adc_get_dt_channel_data(struct adc_chip *adc, struct adc_channel_prop *prop, struct device_node *node, const struct adc_data *data) { const char *name = node->name, *channel_name; u32 chan, value, varr[2]; u32 sid = 0; int ret; struct device *dev = adc->dev; ret = of_property_read_u32(node, "reg", &chan); if (ret) { Loading @@ -808,6 +1006,16 @@ static int adc_get_dt_channel_data(struct device *dev, return ret; } /* * Value read from "reg" is virtual channel number * virtual channel number = (sid << 8 | channel number). */ if (adc->is_pmic7) { sid = (chan >> ADC_CHANNEL_OFFSET); chan = (chan & ADC_CHANNEL_MASK); } if (chan > ADC_PARALLEL_ISENSE_VBAT_IDATA) { dev_err(dev, "%s invalid channel number %d\n", name, chan); return -EINVAL; Loading @@ -815,6 +1023,7 @@ static int adc_get_dt_channel_data(struct device *dev, /* the channel has DT description */ prop->channel = chan; prop->sid = sid; channel_name = of_get_property(node, "label", NULL) ? : node->name; Loading Loading @@ -876,6 +1085,7 @@ static int adc_get_dt_channel_data(struct device *dev, prop->scale_fn_type = -EINVAL; ret = of_property_read_u32(node, "qcom,scale-fn-type", &value); if (!ret && value < SCALE_HW_CALIB_MAX) prop->scale_fn_type = value; Loading Loading @@ -921,6 +1131,14 @@ const struct adc_data data_pmic5_lite = { 800, 900, 1, 2, 4, 6, 8, 10}, }; const struct adc_data adc7_data_pmic = { .full_scale_code_volt = 0x70e4, .adc_chans = adc7_chans_pmic, .decimation = (unsigned int []) {85, 340, 1360}, .hw_settle = (unsigned int []) {15, 100, 200, 300, 400, 500, 600, 700, 1000, 2000, 4000, 8000, 16000, 32000, 64000, 128000}, }; const struct adc_data data_pmic_rev2 = { .full_scale_code_volt = 0x4000, .full_scale_code_cur = 0x1800, Loading @@ -935,6 +1153,10 @@ static const struct of_device_id adc_match_table[] = { .compatible = "qcom,spmi-adc5", .data = &data_pmic5, }, { .compatible = "qcom,spmi-adc7", .data = &adc7_data_pmic, }, { .compatible = "qcom,spmi-adc-rev2", .data = &data_pmic_rev2, Loading Loading @@ -980,7 +1202,7 @@ static int adc_get_dt_data(struct adc_chip *adc, struct device_node *node) adc->data = data; for_each_available_child_of_node(node, child) { ret = adc_get_dt_channel_data(adc->dev, &prop, child, data); ret = adc_get_dt_channel_data(adc, &prop, child, data); if (ret) { of_node_put(child); return ret; Loading Loading @@ -1069,6 +1291,7 @@ static int adc_probe(struct platform_device *pdev) adc = iio_priv(indio_dev); adc->regmap = regmap; adc->dev = dev; adc->pmic_rev_id = pmic_rev_id; prop_addr = of_get_address(dev->of_node, 0, NULL, NULL); Loading @@ -1086,6 +1309,14 @@ static int adc_probe(struct platform_device *pdev) adc->skip_usb_wa = skip_usb_wa; if (of_device_is_compatible(node, "qcom,spmi-adc7")) { indio_dev->info = &adc7_info; adc->is_pmic7 = true; } else indio_dev->info = &adc_info; platform_set_drvdata(pdev, adc); init_completion(&adc->complete); mutex_init(&adc->lock); Loading @@ -1111,7 +1342,6 @@ static int adc_probe(struct platform_device *pdev) indio_dev->dev.of_node = node; indio_dev->name = pdev->name; indio_dev->modes = INDIO_DIRECT_MODE; indio_dev->info = &adc_info; indio_dev->channels = adc->iio_chans; indio_dev->num_channels = adc->nchannels; Loading drivers/iio/adc/qcom-vadc-common.c +259 −0 Original line number Diff line number Diff line Loading @@ -570,6 +570,195 @@ static const struct lut_table lut_table_400[] = { {adcmap_batt_therm_400k_6125, ARRAY_SIZE(adcmap_batt_therm_400k_6125)}, }; static const struct vadc_map_pt adcmap7_die_temp[] = { { 433700, 1967}, { 473100, 1964}, { 512400, 1957}, { 551500, 1949}, { 590500, 1940}, { 629300, 1930}, { 667900, 1921}, { 706400, 1910}, { 744600, 1896}, { 782500, 1878}, { 820100, 1859}, { 857300, 0}, }; /* * Resistance to temperature table for 100k pull up for NTCG104EF104. */ static const struct vadc_map_pt adcmap7_100k[] = { { 4250657, -40960 }, { 3962085, -39936 }, { 3694875, -38912 }, { 3447322, -37888 }, { 3217867, -36864 }, { 3005082, -35840 }, { 2807660, -34816 }, { 2624405, -33792 }, { 2454218, -32768 }, { 2296094, -31744 }, { 2149108, -30720 }, { 2012414, -29696 }, { 1885232, -28672 }, { 1766846, -27648 }, { 1656598, -26624 }, { 1553884, -25600 }, { 1458147, -24576 }, { 1368873, -23552 }, { 1285590, -22528 }, { 1207863, -21504 }, { 1135290, -20480 }, { 1067501, -19456 }, { 1004155, -18432 }, { 944935, -17408 }, { 889550, -16384 }, { 837731, -15360 }, { 789229, -14336 }, { 743813, -13312 }, { 701271, -12288 }, { 661405, -11264 }, { 624032, -10240 }, { 588982, -9216 }, { 556100, -8192 }, { 525239, -7168 }, { 496264, -6144 }, { 469050, -5120 }, { 443480, -4096 }, { 419448, -3072 }, { 396851, -2048 }, { 375597, -1024 }, { 355598, 0 }, { 336775, 1024 }, { 319052, 2048 }, { 302359, 3072 }, { 286630, 4096 }, { 271806, 5120 }, { 257829, 6144 }, { 244646, 7168 }, { 232209, 8192 }, { 220471, 9216 }, { 209390, 10240 }, { 198926, 11264 }, { 189040, 12288 }, { 179698, 13312 }, { 170868, 14336 }, { 162519, 15360 }, { 154622, 16384 }, { 147150, 17408 }, { 140079, 18432 }, { 133385, 19456 }, { 127046, 20480 }, { 121042, 21504 }, { 115352, 22528 }, { 109960, 23552 }, { 104848, 24576 }, { 100000, 25600 }, { 95402, 26624 }, { 91038, 27648 }, { 86897, 28672 }, { 82965, 29696 }, { 79232, 30720 }, { 75686, 31744 }, { 72316, 32768 }, { 69114, 33792 }, { 66070, 34816 }, { 63176, 35840 }, { 60423, 36864 }, { 57804, 37888 }, { 55312, 38912 }, { 52940, 39936 }, { 50681, 40960 }, { 48531, 41984 }, { 46482, 43008 }, { 44530, 44032 }, { 42670, 45056 }, { 40897, 46080 }, { 39207, 47104 }, { 37595, 48128 }, { 36057, 49152 }, { 34590, 50176 }, { 33190, 51200 }, { 31853, 52224 }, { 30577, 53248 }, { 29358, 54272 }, { 28194, 55296 }, { 27082, 56320 }, { 26020, 57344 }, { 25004, 58368 }, { 24033, 59392 }, { 23104, 60416 }, { 22216, 61440 }, { 21367, 62464 }, { 20554, 63488 }, { 19776, 64512 }, { 19031, 65536 }, { 18318, 66560 }, { 17636, 67584 }, { 16982, 68608 }, { 16355, 69632 }, { 15755, 70656 }, { 15180, 71680 }, { 14628, 72704 }, { 14099, 73728 }, { 13592, 74752 }, { 13106, 75776 }, { 12640, 76800 }, { 12192, 77824 }, { 11762, 78848 }, { 11350, 79872 }, { 10954, 80896 }, { 10574, 81920 }, { 10209, 82944 }, { 9858, 83968 }, { 9521, 84992 }, { 9197, 86016 }, { 8886, 87040 }, { 8587, 88064 }, { 8299, 89088 }, { 8023, 90112 }, { 7757, 91136 }, { 7501, 92160 }, { 7254, 93184 }, { 7017, 94208 }, { 6789, 95232 }, { 6570, 96256 }, { 6358, 97280 }, { 6155, 98304 }, { 5959, 99328 }, { 5770, 100352 }, { 5588, 101376 }, { 5412, 102400 }, { 5243, 103424 }, { 5080, 104448 }, { 4923, 105472 }, { 4771, 106496 }, { 4625, 107520 }, { 4484, 108544 }, { 4348, 109568 }, { 4217, 110592 }, { 4090, 111616 }, { 3968, 112640 }, { 3850, 113664 }, { 3736, 114688 }, { 3626, 115712 }, { 3519, 116736 }, { 3417, 117760 }, { 3317, 118784 }, { 3221, 119808 }, { 3129, 120832 }, { 3039, 121856 }, { 2952, 122880 }, { 2868, 123904 }, { 2787, 124928 }, { 2709, 125952 }, { 2633, 126976 }, { 2560, 128000 }, { 2489, 129024 }, { 2420, 130048 } }; static int qcom_vadc_map_voltage_temp(const struct vadc_map_pt *pts, u32 tablesize, s32 input, s64 *output) { Loading Loading @@ -796,6 +985,32 @@ static int qcom_vadc_scale_hw_calib_batt_therm_100( return 0; } static int qcom_vadc7_scale_hw_calib_therm( const struct vadc_prescale_ratio *prescale, const struct adc_data *data, u16 adc_code, int *result_mdec) { s64 resistance = 0, result = 0; int ret; if (adc_code >= RATIO_MAX_ADC7) return -EINVAL; /* (ADC code * R_PULLUP (100Kohm)) / (full_scale_code - ADC code)*/ resistance = (s64) adc_code * R_PU_100K; resistance = div64_s64(resistance, (RATIO_MAX_ADC7 - adc_code)); ret = qcom_vadc_map_voltage_temp(adcmap7_100k, ARRAY_SIZE(adcmap7_100k), resistance, &result); if (ret) return ret; *result_mdec = result; return 0; } static int qcom_vadc_scale_hw_calib_batt_therm_30( const struct vadc_prescale_ratio *prescale, const struct adc_data *data, Loading Loading @@ -896,6 +1111,44 @@ static int qcom_vadc_scale_hw_calib_die_temp( return 0; } static int qcom_vadc7_scale_hw_calib_die_temp( const struct vadc_prescale_ratio *prescale, const struct adc_data *data, u16 adc_code, int *result_mdec) { s64 voltage, vtemp0, temp; int adc_vdd_ref_mv = 1875, i = 0; if (adc_code > VADC5_MAX_CODE) adc_code = 0; /* (ADC code * vref_vadc (1.875V)) / full_scale_code */ voltage = (s64) adc_code * adc_vdd_ref_mv * 1000; voltage = div64_s64(voltage, data->full_scale_code_volt); voltage = voltage * prescale->den; voltage = div64_s64(voltage, prescale->num); while (i < ARRAY_SIZE(adcmap7_die_temp)) { if (adcmap7_die_temp[i].x > voltage) break; i++; } if (i == 0) { *result_mdec = DIE_TEMP_ADC7_SCALE_1; } else if (i == ARRAY_SIZE(adcmap7_die_temp)) { *result_mdec = DIE_TEMP_ADC7_MAX; } else { vtemp0 = adcmap7_die_temp[i-1].x; voltage = voltage - vtemp0; temp = div64_s64(voltage, adcmap7_die_temp[i-1].y); temp += DIE_TEMP_ADC7_SCALE_1 + (DIE_TEMP_ADC7_SCALE_2 * (i-1)); *result_mdec = temp; } return 0; } static int qcom_vadc_scale_hw_smb_temp( const struct vadc_prescale_ratio *prescale, const struct adc_data *data, Loading Loading @@ -1075,6 +1328,12 @@ int qcom_vadc_hw_scale(enum vadc_scale_fn_type scaletype, case SCALE_HW_CALIB_PM5_SMB1398_TEMP: return qcom_vadc_scale_hw_smb1398_temp(prescale, data, adc_code, result); case SCALE_HW_CALIB_THERM_100K_PU_PM7: return qcom_vadc7_scale_hw_calib_therm(prescale, data, adc_code, result); case SCALE_HW_CALIB_PMIC_THERM_PM7: return qcom_vadc7_scale_hw_calib_die_temp(prescale, data, adc_code, result); default: return -EINVAL; } Loading drivers/iio/adc/qcom-vadc-common.h +13 −0 Original line number Diff line number Diff line Loading @@ -83,6 +83,13 @@ #define ADC_DBG1(dev, msg, args...) pr_debug(msg, ##args) #endif #define R_PU_100K 100000 #define RATIO_MAX_ADC7 0x4000 #define DIE_TEMP_ADC7_SCALE_1 -60 #define DIE_TEMP_ADC7_SCALE_2 20 #define DIE_TEMP_ADC7_MAX 160 /** * struct vadc_map_pt - Map the graph representation for ADC channel * @x: Represent the ADC digitized code. Loading Loading @@ -144,9 +151,13 @@ struct vadc_prescale_ratio { * lookup table. The hardware applies offset/slope to adc code. * SCALE_HW_CALIB_XOTHERM: Returns XO thermistor voltage in millidegC using * 100k pullup. The hardware applies offset/slope to adc code. * SCALE_HW_CALIB_THERM_100K_PU_PM7: Returns temperature in millidegC using * lookup table for PMIC7. The hardware applies offset/slope to adc code. * SCALE_HW_CALIB_PMIC_THERM: Returns result in milli degree's Centigrade. * The hardware applies offset/slope to adc code. * SCALE_HW_CALIB_CUR: Returns result in uA for PMIC5. * SCALE_HW_CALIB_PMIC_THERM: Returns result in milli degree's Centigrade. * The hardware applies offset/slope to adc code. This is for PMIC7. * SCALE_HW_CALIB_PM5_CHG_TEMP: Returns result in millidegrees for PMIC5 * charger temperature. * SCALE_HW_CALIB_PM5_SMB_TEMP: Returns result in millidegrees for PMIC5 Loading @@ -170,8 +181,10 @@ enum vadc_scale_fn_type { SCALE_HW_CALIB_DEFAULT, SCALE_HW_CALIB_THERM_100K_PULLUP, SCALE_HW_CALIB_XOTHERM, SCALE_HW_CALIB_THERM_100K_PU_PM7, SCALE_HW_CALIB_PMIC_THERM, SCALE_HW_CALIB_CUR, SCALE_HW_CALIB_PMIC_THERM_PM7, SCALE_HW_CALIB_PM5_CHG_TEMP, SCALE_HW_CALIB_PM5_SMB_TEMP, SCALE_HW_CALIB_BATT_THERM_100K, Loading drivers/thermal/qcom/Makefile +1 −1 Original line number Diff line number Diff line obj-$(CONFIG_QCOM_TSENS) += qcom_tsens.o qcom_tsens-y += tsens.o tsens-common.o tsens-8916.o tsens-8974.o tsens-8960.o tsens-v2.o obj-$(CONFIG_QTI_ADC_TM) += adc-tm.o adc-tm-common.o adc-tm5.o obj-$(CONFIG_QTI_ADC_TM) += adc-tm.o adc-tm-common.o adc-tm5.o adc-tm7.o obj-$(CONFIG_QTI_VIRTUAL_SENSOR) += qti_virtual_sensor.o obj-$(CONFIG_QTI_QMI_SENSOR) += thermal_sensor_service_v01.o qmi_sensors.o obj-$(CONFIG_QTI_BCL_PMIC5) += bcl_pmic5.o Loading drivers/thermal/qcom/adc-tm-common.c +258 −0 Original line number Diff line number Diff line Loading @@ -47,6 +47,181 @@ static const struct adc_tm_map_pt adcmap_100k_104ef_104fb_1875_vref[] = { { 46000, 125000 }, }; /* * Resistance to temperature table for NTCG104EF104 thermistor with * 100k pull-up. */ static const struct adc_tm_map_pt adcmap_100k_adc7[] = { { 4250657, -40960 }, { 3962085, -39936 }, { 3694875, -38912 }, { 3447322, -37888 }, { 3217867, -36864 }, { 3005082, -35840 }, { 2807660, -34816 }, { 2624405, -33792 }, { 2454218, -32768 }, { 2296094, -31744 }, { 2149108, -30720 }, { 2012414, -29696 }, { 1885232, -28672 }, { 1766846, -27648 }, { 1656598, -26624 }, { 1553884, -25600 }, { 1458147, -24576 }, { 1368873, -23552 }, { 1285590, -22528 }, { 1207863, -21504 }, { 1135290, -20480 }, { 1067501, -19456 }, { 1004155, -18432 }, { 944935, -17408 }, { 889550, -16384 }, { 837731, -15360 }, { 789229, -14336 }, { 743813, -13312 }, { 701271, -12288 }, { 661405, -11264 }, { 624032, -10240 }, { 588982, -9216 }, { 556100, -8192 }, { 525239, -7168 }, { 496264, -6144 }, { 469050, -5120 }, { 443480, -4096 }, { 419448, -3072 }, { 396851, -2048 }, { 375597, -1024 }, { 355598, 0 }, { 336775, 1024 }, { 319052, 2048 }, { 302359, 3072 }, { 286630, 4096 }, { 271806, 5120 }, { 257829, 6144 }, { 244646, 7168 }, { 232209, 8192 }, { 220471, 9216 }, { 209390, 10240 }, { 198926, 11264 }, { 189040, 12288 }, { 179698, 13312 }, { 170868, 14336 }, { 162519, 15360 }, { 154622, 16384 }, { 147150, 17408 }, { 140079, 18432 }, { 133385, 19456 }, { 127046, 20480 }, { 121042, 21504 }, { 115352, 22528 }, { 109960, 23552 }, { 104848, 24576 }, { 100000, 25600 }, { 95402, 26624 }, { 91038, 27648 }, { 86897, 28672 }, { 82965, 29696 }, { 79232, 30720 }, { 75686, 31744 }, { 72316, 32768 }, { 69114, 33792 }, { 66070, 34816 }, { 63176, 35840 }, { 60423, 36864 }, { 57804, 37888 }, { 55312, 38912 }, { 52940, 39936 }, { 50681, 40960 }, { 48531, 41984 }, { 46482, 43008 }, { 44530, 44032 }, { 42670, 45056 }, { 40897, 46080 }, { 39207, 47104 }, { 37595, 48128 }, { 36057, 49152 }, { 34590, 50176 }, { 33190, 51200 }, { 31853, 52224 }, { 30577, 53248 }, { 29358, 54272 }, { 28194, 55296 }, { 27082, 56320 }, { 26020, 57344 }, { 25004, 58368 }, { 24033, 59392 }, { 23104, 60416 }, { 22216, 61440 }, { 21367, 62464 }, { 20554, 63488 }, { 19776, 64512 }, { 19031, 65536 }, { 18318, 66560 }, { 17636, 67584 }, { 16982, 68608 }, { 16355, 69632 }, { 15755, 70656 }, { 15180, 71680 }, { 14628, 72704 }, { 14099, 73728 }, { 13592, 74752 }, { 13106, 75776 }, { 12640, 76800 }, { 12192, 77824 }, { 11762, 78848 }, { 11350, 79872 }, { 10954, 80896 }, { 10574, 81920 }, { 10209, 82944 }, { 9858, 83968 }, { 9521, 84992 }, { 9197, 86016 }, { 8886, 87040 }, { 8587, 88064 }, { 8299, 89088 }, { 8023, 90112 }, { 7757, 91136 }, { 7501, 92160 }, { 7254, 93184 }, { 7017, 94208 }, { 6789, 95232 }, { 6570, 96256 }, { 6358, 97280 }, { 6155, 98304 }, { 5959, 99328 }, { 5770, 100352 }, { 5588, 101376 }, { 5412, 102400 }, { 5243, 103424 }, { 5080, 104448 }, { 4923, 105472 }, { 4771, 106496 }, { 4625, 107520 }, { 4484, 108544 }, { 4348, 109568 }, { 4217, 110592 }, { 4090, 111616 }, { 3968, 112640 }, { 3850, 113664 }, { 3736, 114688 }, { 3626, 115712 }, { 3519, 116736 }, { 3417, 117760 }, { 3317, 118784 }, { 3221, 119808 }, { 3129, 120832 }, { 3039, 121856 }, { 2952, 122880 }, { 2868, 123904 }, { 2787, 124928 }, { 2709, 125952 }, { 2633, 126976 }, { 2560, 128000 }, { 2489, 129024 }, { 2420, 130048 } }; static void adc_tm_map_voltage_temp(const struct adc_tm_map_pt *pts, size_t tablesize, int input, int *output) { Loading Loading @@ -140,6 +315,7 @@ int therm_fwd_scale(int64_t code, uint32_t adc_hc_vdd_ref_mv, volt = (s64) code * adc_hc_vdd_ref_mv; volt = div64_s64(volt, (data->full_scale_code_volt)); /* Same API can be used for resistance-temperature table */ adc_tm_map_voltage_temp(adcmap_100k_104ef_104fb_1875_vref, ARRAY_SIZE(adcmap_100k_104ef_104fb_1875_vref), (int) volt, &result); Loading @@ -148,6 +324,25 @@ int therm_fwd_scale(int64_t code, uint32_t adc_hc_vdd_ref_mv, } EXPORT_SYMBOL(therm_fwd_scale); int therm_fwd_scale_adc7(int64_t code) { int64_t resistance = 0; int result = 0; if (code >= RATIO_MAX_ADC7) return -EINVAL; resistance = (s64) code * R_PU_100K; resistance = div64_s64(resistance, (RATIO_MAX_ADC7 - code)); adc_tm_map_voltage_temp(adcmap_100k_adc7, ARRAY_SIZE(adcmap_100k_adc7), (int) resistance, &result); return result; } EXPORT_SYMBOL(therm_fwd_scale_adc7); void adc_tm_scale_therm_voltage_100k(struct adc_tm_config *param, const struct adc_tm_data *data) { Loading Loading @@ -188,6 +383,47 @@ void adc_tm_scale_therm_voltage_100k(struct adc_tm_config *param, } EXPORT_SYMBOL(adc_tm_scale_therm_voltage_100k); void adc_tm_scale_therm_voltage_100k_adc7(struct adc_tm_config *param) { int temp; int64_t resistance = 0; /* High temperature maps to lower threshold voltage */ /* Same API can be used for resistance-temperature table */ adc_tm_map_temp_voltage( adcmap_100k_adc7, ARRAY_SIZE(adcmap_100k_adc7), param->high_thr_temp, &resistance); param->low_thr_voltage = resistance * RATIO_MAX_ADC7; param->low_thr_voltage = div64_s64(param->low_thr_voltage, (resistance + R_PU_100K)); temp = therm_fwd_scale_adc7(param->low_thr_voltage); if (temp == -EINVAL) return; if (temp < param->high_thr_temp) param->low_thr_voltage--; /* Low temperature maps to higher threshold voltage */ /* Same API can be used for resistance-temperature table */ adc_tm_map_temp_voltage( adcmap_100k_adc7, ARRAY_SIZE(adcmap_100k_adc7), param->low_thr_temp, &resistance); param->high_thr_voltage = resistance * RATIO_MAX_ADC7; param->high_thr_voltage = div64_s64(param->high_thr_voltage, (resistance + R_PU_100K)); temp = therm_fwd_scale_adc7(param->high_thr_voltage); if (temp > param->low_thr_temp) param->high_thr_voltage++; } EXPORT_SYMBOL(adc_tm_scale_therm_voltage_100k_adc7); int32_t adc_tm_absolute_rthr(const struct adc_tm_data *data, struct adc_tm_config *tm_config) { Loading @@ -195,11 +431,13 @@ int32_t adc_tm_absolute_rthr(const struct adc_tm_data *data, low_thr = div_s64(tm_config->low_thr_voltage, tm_config->prescal); low_thr *= data->full_scale_code_volt; low_thr = div64_s64(low_thr, ADC_HC_VDD_REF); tm_config->low_thr_voltage = low_thr; high_thr = div_s64(tm_config->high_thr_voltage, tm_config->prescal); high_thr *= data->full_scale_code_volt; high_thr = div64_s64(high_thr, ADC_HC_VDD_REF); tm_config->high_thr_voltage = high_thr; Loading @@ -207,5 +445,25 @@ int32_t adc_tm_absolute_rthr(const struct adc_tm_data *data, } EXPORT_SYMBOL(adc_tm_absolute_rthr); int32_t adc_tm_absolute_rthr_adc7(struct adc_tm_config *tm_config) { int64_t low_thr = 0, high_thr = 0; low_thr = div_s64(tm_config->low_thr_voltage, tm_config->prescal); low_thr *= MAX_CODE_VOLT; low_thr = div64_s64(low_thr, ADC_HC_VDD_REF); tm_config->low_thr_voltage = low_thr; high_thr = div_s64(tm_config->high_thr_voltage, tm_config->prescal); high_thr *= MAX_CODE_VOLT; high_thr = div64_s64(high_thr, ADC_HC_VDD_REF); tm_config->high_thr_voltage = high_thr; return 0; } EXPORT_SYMBOL(adc_tm_absolute_rthr_adc7); MODULE_DESCRIPTION("Qualcomm Technologies Inc. PMIC ADC_TM common driver"); MODULE_LICENSE("GPL v2"); Loading
drivers/iio/adc/qcom-spmi-adc5.c +233 −3 Original line number Diff line number Diff line Loading @@ -26,6 +26,7 @@ #include "qcom-vadc-common.h" #define ADC_USR_STATUS1 0x8 #define ADC7_USR_STATUS1_CONV_FAULT BIT(7) #define ADC_USR_STATUS1_REQ_STS BIT(1) #define ADC_USR_STATUS1_EOC BIT(0) #define ADC_USR_STATUS1_REQ_STS_EOC_MASK 0x3 Loading Loading @@ -73,6 +74,9 @@ #define ADC_CHAN_MIN ADC_USBIN #define ADC_CHAN_MAX ADC_LR_MUX3_BUF_PU1_PU2_XO_THERM #define ADC_CHANNEL_OFFSET 0x8 #define ADC_CHANNEL_MASK 0xff /* * Conversion time varies between 139uS to 6827uS based on the decimation, * clock rate, fast average samples with no measurement in queue. Loading @@ -89,6 +93,11 @@ #define ADC_CAL_DELAY_CTL_VAL_256S 0x73 #define ADC_CAL_DELAY_CTL_VAL_125MS 0x3 /* For PMIC7 */ #define ADC_APP_SID 0x40 #define ADC_APP_SID_MASK 0xf #define ADC7_CONV_TIMEOUT msecs_to_jiffies(10) enum adc_cal_method { ADC_NO_CAL = 0, ADC_RATIOMETRIC_CAL, Loading @@ -111,6 +120,7 @@ struct pmic_rev_data { * @cal_method: calibration method. * @cal_val: calibration value * @decimation: sampling rate supported for the channel. * @sid: slave id of PMIC owning the channel, for PMIC7. * @prescale: channel scaling performed on the input signal. * @hw_settle_time: the time between AMUX being configured and the * start of conversion. Loading @@ -124,6 +134,7 @@ struct adc_channel_prop { enum adc_cal_method cal_method; enum adc_cal_val cal_val; unsigned int decimation; unsigned int sid; unsigned int prescale; unsigned int hw_settle_time; unsigned int avg_samples; Loading Loading @@ -161,6 +172,7 @@ struct adc_chip { bool skip_usb_wa; void *ipc_log0; void *ipc_log1; bool is_pmic7; struct pmic_revid_data *pmic_rev_id; const struct adc_data *data; }; Loading @@ -187,6 +199,11 @@ static int adc_write(struct adc_chip *adc, u16 offset, u8 *data, int len) return regmap_bulk_write(adc->regmap, adc->base + offset, data, len); } static int adc_masked_write(struct adc_chip *adc, u16 offset, u8 mask, u8 val) { return regmap_update_bits(adc->regmap, adc->base + offset, mask, val); } static int adc_prescaling_from_dt(u32 num, u32 den) { unsigned int pre; Loading Loading @@ -529,6 +546,49 @@ static int adc_configure(struct adc_chip *adc, return ret; } static int adc7_configure(struct adc_chip *adc, struct adc_channel_prop *prop) { int ret; u8 conv_req = 0, buf[4]; ret = adc_masked_write(adc, ADC_APP_SID, ADC_APP_SID_MASK, prop->sid); if (ret) return ret; ret = adc_read(adc, ADC_USR_DIG_PARAM, buf, sizeof(buf)); if (ret < 0) return ret; /* Digital param selection */ adc_update_dig_param(adc, prop, &buf[0]); /* Update fast average sample value */ buf[1] &= (u8) ~ADC_USR_FAST_AVG_CTL_SAMPLES_MASK; buf[1] |= prop->avg_samples; /* Select ADC channel */ buf[2] = prop->channel; /* Select HW settle delay for channel */ buf[3] &= (u8) ~ADC_USR_HW_SETTLE_DELAY_MASK; buf[3] |= prop->hw_settle_time; /* Select CONV request */ conv_req = ADC_USR_CONV_REQ_REQ; if (!adc->poll_eoc) reinit_completion(&adc->complete); ret = adc_write(adc, ADC_USR_DIG_PARAM, buf, sizeof(buf)); if (ret) return ret; ret = adc_write(adc, ADC_USR_CONV_REQ, &conv_req, 1); return ret; } static int adc_do_conversion(struct adc_chip *adc, struct adc_channel_prop *prop, struct iio_chan_spec const *chan, Loading Loading @@ -579,6 +639,44 @@ static int adc_do_conversion(struct adc_chip *adc, return ret; } static int adc7_do_conversion(struct adc_chip *adc, struct adc_channel_prop *prop, struct iio_chan_spec const *chan, u16 *data_volt, u16 *data_cur) { int ret; u8 status = 0; mutex_lock(&adc->lock); ret = adc7_configure(adc, prop); if (ret) { pr_err("ADC configure failed with %d\n", ret); goto unlock; } /* No support for polling mode at present*/ wait_for_completion_timeout(&adc->complete, ADC7_CONV_TIMEOUT); ret = adc_read(adc, ADC_USR_STATUS1, &status, 1); if (ret < 0) goto unlock; if (status & ADC7_USR_STATUS1_CONV_FAULT) { pr_err("Unexpected conversion fault\n"); ret = -EIO; goto unlock; } ret = adc_read_voltage_data(adc, data_volt); unlock: mutex_unlock(&adc->lock); return ret; } static irqreturn_t adc_isr(int irq, void *dev_id) { struct adc_chip *adc = dev_id; Loading @@ -601,6 +699,66 @@ static int adc_of_xlate(struct iio_dev *indio_dev, return -EINVAL; } static int adc7_of_xlate(struct iio_dev *indio_dev, const struct of_phandle_args *iiospec) { struct adc_chip *adc = iio_priv(indio_dev); int i, v_channel; for (i = 0; i < adc->nchannels; i++) { v_channel = ((adc->chan_props[i].sid << ADC_CHANNEL_OFFSET) | adc->chan_props[i].channel); if (v_channel == iiospec->args[0]) return i; } return -EINVAL; } static int adc7_read_raw(struct iio_dev *indio_dev, struct iio_chan_spec const *chan, int *val, int *val2, long mask) { struct adc_chip *adc = iio_priv(indio_dev); struct adc_channel_prop *prop; u16 adc_code_volt, adc_code_cur; int ret; prop = &adc->chan_props[chan->address]; switch (mask) { case IIO_CHAN_INFO_PROCESSED: ret = adc7_do_conversion(adc, prop, chan, &adc_code_volt, &adc_code_cur); if (ret) return ret; ret = qcom_vadc_hw_scale(prop->scale_fn_type, &adc_prescale_ratios[prop->prescale], adc->data, prop->lut_index, adc_code_volt, val); if (ret) return ret; return IIO_VAL_INT; case IIO_CHAN_INFO_RAW: ret = adc7_do_conversion(adc, prop, chan, &adc_code_volt, &adc_code_cur); if (ret) return ret; *val = (int)adc_code_volt; return IIO_VAL_INT; default: return -EINVAL; } return 0; } static int adc_read_raw(struct iio_dev *indio_dev, struct iio_chan_spec const *chan, int *val, int *val2, long mask) Loading Loading @@ -672,6 +830,11 @@ static const struct iio_info adc_info = { .of_xlate = adc_of_xlate, }; static const struct iio_info adc7_info = { .read_raw = adc7_read_raw, .of_xlate = adc7_of_xlate, }; struct adc_channels { const char *datasheet_name; unsigned int prescale_index; Loading Loading @@ -770,6 +933,39 @@ static const struct adc_channels adc_chans_pmic5[ADC_MAX_CHANNEL] = { SCALE_HW_CALIB_THERM_100K_PULLUP) }; static const struct adc_channels adc7_chans_pmic[ADC_MAX_CHANNEL] = { [ADC7_REF_GND] = ADC_CHAN_VOLT("ref_gnd", 0, SCALE_HW_CALIB_DEFAULT) [ADC7_1P25VREF] = ADC_CHAN_VOLT("vref_1p25", 0, SCALE_HW_CALIB_DEFAULT) [ADC7_VPH_PWR] = ADC_CHAN_VOLT("vph_pwr", 1, SCALE_HW_CALIB_DEFAULT) [ADC7_VBAT_SNS] = ADC_CHAN_VOLT("vbat_sns", 3, SCALE_HW_CALIB_DEFAULT) [ADC7_DIE_TEMP] = ADC_CHAN_TEMP("die_temp", 0, SCALE_HW_CALIB_PMIC_THERM_PM7) [ADC7_AMUX_THM1_100K_PU] = ADC_CHAN_TEMP("amux_thm1_pu2", 0, SCALE_HW_CALIB_THERM_100K_PU_PM7) [ADC7_AMUX_THM2_100K_PU] = ADC_CHAN_TEMP("amux_thm2_pu2", 0, SCALE_HW_CALIB_THERM_100K_PU_PM7) [ADC7_AMUX_THM3_100K_PU] = ADC_CHAN_TEMP("amux_thm3_pu2", 0, SCALE_HW_CALIB_THERM_100K_PU_PM7) [ADC7_AMUX_THM4_100K_PU] = ADC_CHAN_TEMP("amux_thm4_pu2", 0, SCALE_HW_CALIB_THERM_100K_PU_PM7) [ADC7_AMUX_THM5_100K_PU] = ADC_CHAN_TEMP("amux_thm5_pu2", 0, SCALE_HW_CALIB_THERM_100K_PU_PM7) [ADC7_AMUX_THM6_100K_PU] = ADC_CHAN_TEMP("amux_thm6_pu2", 0, SCALE_HW_CALIB_THERM_100K_PU_PM7) [ADC7_GPIO1_100K_PU] = ADC_CHAN_TEMP("gpio1_pu2", 0, SCALE_HW_CALIB_THERM_100K_PU_PM7) [ADC7_GPIO2_100K_PU] = ADC_CHAN_TEMP("gpio2_pu2", 0, SCALE_HW_CALIB_THERM_100K_PU_PM7) [ADC7_GPIO3_100K_PU] = ADC_CHAN_TEMP("gpio3_pu2", 0, SCALE_HW_CALIB_THERM_100K_PU_PM7) [ADC7_GPIO4_100K_PU] = ADC_CHAN_TEMP("gpio4_pu2", 0, SCALE_HW_CALIB_THERM_100K_PU_PM7) }; static const struct adc_channels adc_chans_rev2[ADC_MAX_CHANNEL] = { [ADC_REF_GND] = ADC_CHAN_VOLT("ref_gnd", 1, SCALE_HW_CALIB_DEFAULT) Loading @@ -793,14 +989,16 @@ static const struct adc_channels adc_chans_rev2[ADC_MAX_CHANNEL] = { SCALE_HW_CALIB_THERM_100K_PULLUP) }; static int adc_get_dt_channel_data(struct device *dev, static int adc_get_dt_channel_data(struct adc_chip *adc, struct adc_channel_prop *prop, struct device_node *node, const struct adc_data *data) { const char *name = node->name, *channel_name; u32 chan, value, varr[2]; u32 sid = 0; int ret; struct device *dev = adc->dev; ret = of_property_read_u32(node, "reg", &chan); if (ret) { Loading @@ -808,6 +1006,16 @@ static int adc_get_dt_channel_data(struct device *dev, return ret; } /* * Value read from "reg" is virtual channel number * virtual channel number = (sid << 8 | channel number). */ if (adc->is_pmic7) { sid = (chan >> ADC_CHANNEL_OFFSET); chan = (chan & ADC_CHANNEL_MASK); } if (chan > ADC_PARALLEL_ISENSE_VBAT_IDATA) { dev_err(dev, "%s invalid channel number %d\n", name, chan); return -EINVAL; Loading @@ -815,6 +1023,7 @@ static int adc_get_dt_channel_data(struct device *dev, /* the channel has DT description */ prop->channel = chan; prop->sid = sid; channel_name = of_get_property(node, "label", NULL) ? : node->name; Loading Loading @@ -876,6 +1085,7 @@ static int adc_get_dt_channel_data(struct device *dev, prop->scale_fn_type = -EINVAL; ret = of_property_read_u32(node, "qcom,scale-fn-type", &value); if (!ret && value < SCALE_HW_CALIB_MAX) prop->scale_fn_type = value; Loading Loading @@ -921,6 +1131,14 @@ const struct adc_data data_pmic5_lite = { 800, 900, 1, 2, 4, 6, 8, 10}, }; const struct adc_data adc7_data_pmic = { .full_scale_code_volt = 0x70e4, .adc_chans = adc7_chans_pmic, .decimation = (unsigned int []) {85, 340, 1360}, .hw_settle = (unsigned int []) {15, 100, 200, 300, 400, 500, 600, 700, 1000, 2000, 4000, 8000, 16000, 32000, 64000, 128000}, }; const struct adc_data data_pmic_rev2 = { .full_scale_code_volt = 0x4000, .full_scale_code_cur = 0x1800, Loading @@ -935,6 +1153,10 @@ static const struct of_device_id adc_match_table[] = { .compatible = "qcom,spmi-adc5", .data = &data_pmic5, }, { .compatible = "qcom,spmi-adc7", .data = &adc7_data_pmic, }, { .compatible = "qcom,spmi-adc-rev2", .data = &data_pmic_rev2, Loading Loading @@ -980,7 +1202,7 @@ static int adc_get_dt_data(struct adc_chip *adc, struct device_node *node) adc->data = data; for_each_available_child_of_node(node, child) { ret = adc_get_dt_channel_data(adc->dev, &prop, child, data); ret = adc_get_dt_channel_data(adc, &prop, child, data); if (ret) { of_node_put(child); return ret; Loading Loading @@ -1069,6 +1291,7 @@ static int adc_probe(struct platform_device *pdev) adc = iio_priv(indio_dev); adc->regmap = regmap; adc->dev = dev; adc->pmic_rev_id = pmic_rev_id; prop_addr = of_get_address(dev->of_node, 0, NULL, NULL); Loading @@ -1086,6 +1309,14 @@ static int adc_probe(struct platform_device *pdev) adc->skip_usb_wa = skip_usb_wa; if (of_device_is_compatible(node, "qcom,spmi-adc7")) { indio_dev->info = &adc7_info; adc->is_pmic7 = true; } else indio_dev->info = &adc_info; platform_set_drvdata(pdev, adc); init_completion(&adc->complete); mutex_init(&adc->lock); Loading @@ -1111,7 +1342,6 @@ static int adc_probe(struct platform_device *pdev) indio_dev->dev.of_node = node; indio_dev->name = pdev->name; indio_dev->modes = INDIO_DIRECT_MODE; indio_dev->info = &adc_info; indio_dev->channels = adc->iio_chans; indio_dev->num_channels = adc->nchannels; Loading
drivers/iio/adc/qcom-vadc-common.c +259 −0 Original line number Diff line number Diff line Loading @@ -570,6 +570,195 @@ static const struct lut_table lut_table_400[] = { {adcmap_batt_therm_400k_6125, ARRAY_SIZE(adcmap_batt_therm_400k_6125)}, }; static const struct vadc_map_pt adcmap7_die_temp[] = { { 433700, 1967}, { 473100, 1964}, { 512400, 1957}, { 551500, 1949}, { 590500, 1940}, { 629300, 1930}, { 667900, 1921}, { 706400, 1910}, { 744600, 1896}, { 782500, 1878}, { 820100, 1859}, { 857300, 0}, }; /* * Resistance to temperature table for 100k pull up for NTCG104EF104. */ static const struct vadc_map_pt adcmap7_100k[] = { { 4250657, -40960 }, { 3962085, -39936 }, { 3694875, -38912 }, { 3447322, -37888 }, { 3217867, -36864 }, { 3005082, -35840 }, { 2807660, -34816 }, { 2624405, -33792 }, { 2454218, -32768 }, { 2296094, -31744 }, { 2149108, -30720 }, { 2012414, -29696 }, { 1885232, -28672 }, { 1766846, -27648 }, { 1656598, -26624 }, { 1553884, -25600 }, { 1458147, -24576 }, { 1368873, -23552 }, { 1285590, -22528 }, { 1207863, -21504 }, { 1135290, -20480 }, { 1067501, -19456 }, { 1004155, -18432 }, { 944935, -17408 }, { 889550, -16384 }, { 837731, -15360 }, { 789229, -14336 }, { 743813, -13312 }, { 701271, -12288 }, { 661405, -11264 }, { 624032, -10240 }, { 588982, -9216 }, { 556100, -8192 }, { 525239, -7168 }, { 496264, -6144 }, { 469050, -5120 }, { 443480, -4096 }, { 419448, -3072 }, { 396851, -2048 }, { 375597, -1024 }, { 355598, 0 }, { 336775, 1024 }, { 319052, 2048 }, { 302359, 3072 }, { 286630, 4096 }, { 271806, 5120 }, { 257829, 6144 }, { 244646, 7168 }, { 232209, 8192 }, { 220471, 9216 }, { 209390, 10240 }, { 198926, 11264 }, { 189040, 12288 }, { 179698, 13312 }, { 170868, 14336 }, { 162519, 15360 }, { 154622, 16384 }, { 147150, 17408 }, { 140079, 18432 }, { 133385, 19456 }, { 127046, 20480 }, { 121042, 21504 }, { 115352, 22528 }, { 109960, 23552 }, { 104848, 24576 }, { 100000, 25600 }, { 95402, 26624 }, { 91038, 27648 }, { 86897, 28672 }, { 82965, 29696 }, { 79232, 30720 }, { 75686, 31744 }, { 72316, 32768 }, { 69114, 33792 }, { 66070, 34816 }, { 63176, 35840 }, { 60423, 36864 }, { 57804, 37888 }, { 55312, 38912 }, { 52940, 39936 }, { 50681, 40960 }, { 48531, 41984 }, { 46482, 43008 }, { 44530, 44032 }, { 42670, 45056 }, { 40897, 46080 }, { 39207, 47104 }, { 37595, 48128 }, { 36057, 49152 }, { 34590, 50176 }, { 33190, 51200 }, { 31853, 52224 }, { 30577, 53248 }, { 29358, 54272 }, { 28194, 55296 }, { 27082, 56320 }, { 26020, 57344 }, { 25004, 58368 }, { 24033, 59392 }, { 23104, 60416 }, { 22216, 61440 }, { 21367, 62464 }, { 20554, 63488 }, { 19776, 64512 }, { 19031, 65536 }, { 18318, 66560 }, { 17636, 67584 }, { 16982, 68608 }, { 16355, 69632 }, { 15755, 70656 }, { 15180, 71680 }, { 14628, 72704 }, { 14099, 73728 }, { 13592, 74752 }, { 13106, 75776 }, { 12640, 76800 }, { 12192, 77824 }, { 11762, 78848 }, { 11350, 79872 }, { 10954, 80896 }, { 10574, 81920 }, { 10209, 82944 }, { 9858, 83968 }, { 9521, 84992 }, { 9197, 86016 }, { 8886, 87040 }, { 8587, 88064 }, { 8299, 89088 }, { 8023, 90112 }, { 7757, 91136 }, { 7501, 92160 }, { 7254, 93184 }, { 7017, 94208 }, { 6789, 95232 }, { 6570, 96256 }, { 6358, 97280 }, { 6155, 98304 }, { 5959, 99328 }, { 5770, 100352 }, { 5588, 101376 }, { 5412, 102400 }, { 5243, 103424 }, { 5080, 104448 }, { 4923, 105472 }, { 4771, 106496 }, { 4625, 107520 }, { 4484, 108544 }, { 4348, 109568 }, { 4217, 110592 }, { 4090, 111616 }, { 3968, 112640 }, { 3850, 113664 }, { 3736, 114688 }, { 3626, 115712 }, { 3519, 116736 }, { 3417, 117760 }, { 3317, 118784 }, { 3221, 119808 }, { 3129, 120832 }, { 3039, 121856 }, { 2952, 122880 }, { 2868, 123904 }, { 2787, 124928 }, { 2709, 125952 }, { 2633, 126976 }, { 2560, 128000 }, { 2489, 129024 }, { 2420, 130048 } }; static int qcom_vadc_map_voltage_temp(const struct vadc_map_pt *pts, u32 tablesize, s32 input, s64 *output) { Loading Loading @@ -796,6 +985,32 @@ static int qcom_vadc_scale_hw_calib_batt_therm_100( return 0; } static int qcom_vadc7_scale_hw_calib_therm( const struct vadc_prescale_ratio *prescale, const struct adc_data *data, u16 adc_code, int *result_mdec) { s64 resistance = 0, result = 0; int ret; if (adc_code >= RATIO_MAX_ADC7) return -EINVAL; /* (ADC code * R_PULLUP (100Kohm)) / (full_scale_code - ADC code)*/ resistance = (s64) adc_code * R_PU_100K; resistance = div64_s64(resistance, (RATIO_MAX_ADC7 - adc_code)); ret = qcom_vadc_map_voltage_temp(adcmap7_100k, ARRAY_SIZE(adcmap7_100k), resistance, &result); if (ret) return ret; *result_mdec = result; return 0; } static int qcom_vadc_scale_hw_calib_batt_therm_30( const struct vadc_prescale_ratio *prescale, const struct adc_data *data, Loading Loading @@ -896,6 +1111,44 @@ static int qcom_vadc_scale_hw_calib_die_temp( return 0; } static int qcom_vadc7_scale_hw_calib_die_temp( const struct vadc_prescale_ratio *prescale, const struct adc_data *data, u16 adc_code, int *result_mdec) { s64 voltage, vtemp0, temp; int adc_vdd_ref_mv = 1875, i = 0; if (adc_code > VADC5_MAX_CODE) adc_code = 0; /* (ADC code * vref_vadc (1.875V)) / full_scale_code */ voltage = (s64) adc_code * adc_vdd_ref_mv * 1000; voltage = div64_s64(voltage, data->full_scale_code_volt); voltage = voltage * prescale->den; voltage = div64_s64(voltage, prescale->num); while (i < ARRAY_SIZE(adcmap7_die_temp)) { if (adcmap7_die_temp[i].x > voltage) break; i++; } if (i == 0) { *result_mdec = DIE_TEMP_ADC7_SCALE_1; } else if (i == ARRAY_SIZE(adcmap7_die_temp)) { *result_mdec = DIE_TEMP_ADC7_MAX; } else { vtemp0 = adcmap7_die_temp[i-1].x; voltage = voltage - vtemp0; temp = div64_s64(voltage, adcmap7_die_temp[i-1].y); temp += DIE_TEMP_ADC7_SCALE_1 + (DIE_TEMP_ADC7_SCALE_2 * (i-1)); *result_mdec = temp; } return 0; } static int qcom_vadc_scale_hw_smb_temp( const struct vadc_prescale_ratio *prescale, const struct adc_data *data, Loading Loading @@ -1075,6 +1328,12 @@ int qcom_vadc_hw_scale(enum vadc_scale_fn_type scaletype, case SCALE_HW_CALIB_PM5_SMB1398_TEMP: return qcom_vadc_scale_hw_smb1398_temp(prescale, data, adc_code, result); case SCALE_HW_CALIB_THERM_100K_PU_PM7: return qcom_vadc7_scale_hw_calib_therm(prescale, data, adc_code, result); case SCALE_HW_CALIB_PMIC_THERM_PM7: return qcom_vadc7_scale_hw_calib_die_temp(prescale, data, adc_code, result); default: return -EINVAL; } Loading
drivers/iio/adc/qcom-vadc-common.h +13 −0 Original line number Diff line number Diff line Loading @@ -83,6 +83,13 @@ #define ADC_DBG1(dev, msg, args...) pr_debug(msg, ##args) #endif #define R_PU_100K 100000 #define RATIO_MAX_ADC7 0x4000 #define DIE_TEMP_ADC7_SCALE_1 -60 #define DIE_TEMP_ADC7_SCALE_2 20 #define DIE_TEMP_ADC7_MAX 160 /** * struct vadc_map_pt - Map the graph representation for ADC channel * @x: Represent the ADC digitized code. Loading Loading @@ -144,9 +151,13 @@ struct vadc_prescale_ratio { * lookup table. The hardware applies offset/slope to adc code. * SCALE_HW_CALIB_XOTHERM: Returns XO thermistor voltage in millidegC using * 100k pullup. The hardware applies offset/slope to adc code. * SCALE_HW_CALIB_THERM_100K_PU_PM7: Returns temperature in millidegC using * lookup table for PMIC7. The hardware applies offset/slope to adc code. * SCALE_HW_CALIB_PMIC_THERM: Returns result in milli degree's Centigrade. * The hardware applies offset/slope to adc code. * SCALE_HW_CALIB_CUR: Returns result in uA for PMIC5. * SCALE_HW_CALIB_PMIC_THERM: Returns result in milli degree's Centigrade. * The hardware applies offset/slope to adc code. This is for PMIC7. * SCALE_HW_CALIB_PM5_CHG_TEMP: Returns result in millidegrees for PMIC5 * charger temperature. * SCALE_HW_CALIB_PM5_SMB_TEMP: Returns result in millidegrees for PMIC5 Loading @@ -170,8 +181,10 @@ enum vadc_scale_fn_type { SCALE_HW_CALIB_DEFAULT, SCALE_HW_CALIB_THERM_100K_PULLUP, SCALE_HW_CALIB_XOTHERM, SCALE_HW_CALIB_THERM_100K_PU_PM7, SCALE_HW_CALIB_PMIC_THERM, SCALE_HW_CALIB_CUR, SCALE_HW_CALIB_PMIC_THERM_PM7, SCALE_HW_CALIB_PM5_CHG_TEMP, SCALE_HW_CALIB_PM5_SMB_TEMP, SCALE_HW_CALIB_BATT_THERM_100K, Loading
drivers/thermal/qcom/Makefile +1 −1 Original line number Diff line number Diff line obj-$(CONFIG_QCOM_TSENS) += qcom_tsens.o qcom_tsens-y += tsens.o tsens-common.o tsens-8916.o tsens-8974.o tsens-8960.o tsens-v2.o obj-$(CONFIG_QTI_ADC_TM) += adc-tm.o adc-tm-common.o adc-tm5.o obj-$(CONFIG_QTI_ADC_TM) += adc-tm.o adc-tm-common.o adc-tm5.o adc-tm7.o obj-$(CONFIG_QTI_VIRTUAL_SENSOR) += qti_virtual_sensor.o obj-$(CONFIG_QTI_QMI_SENSOR) += thermal_sensor_service_v01.o qmi_sensors.o obj-$(CONFIG_QTI_BCL_PMIC5) += bcl_pmic5.o Loading
drivers/thermal/qcom/adc-tm-common.c +258 −0 Original line number Diff line number Diff line Loading @@ -47,6 +47,181 @@ static const struct adc_tm_map_pt adcmap_100k_104ef_104fb_1875_vref[] = { { 46000, 125000 }, }; /* * Resistance to temperature table for NTCG104EF104 thermistor with * 100k pull-up. */ static const struct adc_tm_map_pt adcmap_100k_adc7[] = { { 4250657, -40960 }, { 3962085, -39936 }, { 3694875, -38912 }, { 3447322, -37888 }, { 3217867, -36864 }, { 3005082, -35840 }, { 2807660, -34816 }, { 2624405, -33792 }, { 2454218, -32768 }, { 2296094, -31744 }, { 2149108, -30720 }, { 2012414, -29696 }, { 1885232, -28672 }, { 1766846, -27648 }, { 1656598, -26624 }, { 1553884, -25600 }, { 1458147, -24576 }, { 1368873, -23552 }, { 1285590, -22528 }, { 1207863, -21504 }, { 1135290, -20480 }, { 1067501, -19456 }, { 1004155, -18432 }, { 944935, -17408 }, { 889550, -16384 }, { 837731, -15360 }, { 789229, -14336 }, { 743813, -13312 }, { 701271, -12288 }, { 661405, -11264 }, { 624032, -10240 }, { 588982, -9216 }, { 556100, -8192 }, { 525239, -7168 }, { 496264, -6144 }, { 469050, -5120 }, { 443480, -4096 }, { 419448, -3072 }, { 396851, -2048 }, { 375597, -1024 }, { 355598, 0 }, { 336775, 1024 }, { 319052, 2048 }, { 302359, 3072 }, { 286630, 4096 }, { 271806, 5120 }, { 257829, 6144 }, { 244646, 7168 }, { 232209, 8192 }, { 220471, 9216 }, { 209390, 10240 }, { 198926, 11264 }, { 189040, 12288 }, { 179698, 13312 }, { 170868, 14336 }, { 162519, 15360 }, { 154622, 16384 }, { 147150, 17408 }, { 140079, 18432 }, { 133385, 19456 }, { 127046, 20480 }, { 121042, 21504 }, { 115352, 22528 }, { 109960, 23552 }, { 104848, 24576 }, { 100000, 25600 }, { 95402, 26624 }, { 91038, 27648 }, { 86897, 28672 }, { 82965, 29696 }, { 79232, 30720 }, { 75686, 31744 }, { 72316, 32768 }, { 69114, 33792 }, { 66070, 34816 }, { 63176, 35840 }, { 60423, 36864 }, { 57804, 37888 }, { 55312, 38912 }, { 52940, 39936 }, { 50681, 40960 }, { 48531, 41984 }, { 46482, 43008 }, { 44530, 44032 }, { 42670, 45056 }, { 40897, 46080 }, { 39207, 47104 }, { 37595, 48128 }, { 36057, 49152 }, { 34590, 50176 }, { 33190, 51200 }, { 31853, 52224 }, { 30577, 53248 }, { 29358, 54272 }, { 28194, 55296 }, { 27082, 56320 }, { 26020, 57344 }, { 25004, 58368 }, { 24033, 59392 }, { 23104, 60416 }, { 22216, 61440 }, { 21367, 62464 }, { 20554, 63488 }, { 19776, 64512 }, { 19031, 65536 }, { 18318, 66560 }, { 17636, 67584 }, { 16982, 68608 }, { 16355, 69632 }, { 15755, 70656 }, { 15180, 71680 }, { 14628, 72704 }, { 14099, 73728 }, { 13592, 74752 }, { 13106, 75776 }, { 12640, 76800 }, { 12192, 77824 }, { 11762, 78848 }, { 11350, 79872 }, { 10954, 80896 }, { 10574, 81920 }, { 10209, 82944 }, { 9858, 83968 }, { 9521, 84992 }, { 9197, 86016 }, { 8886, 87040 }, { 8587, 88064 }, { 8299, 89088 }, { 8023, 90112 }, { 7757, 91136 }, { 7501, 92160 }, { 7254, 93184 }, { 7017, 94208 }, { 6789, 95232 }, { 6570, 96256 }, { 6358, 97280 }, { 6155, 98304 }, { 5959, 99328 }, { 5770, 100352 }, { 5588, 101376 }, { 5412, 102400 }, { 5243, 103424 }, { 5080, 104448 }, { 4923, 105472 }, { 4771, 106496 }, { 4625, 107520 }, { 4484, 108544 }, { 4348, 109568 }, { 4217, 110592 }, { 4090, 111616 }, { 3968, 112640 }, { 3850, 113664 }, { 3736, 114688 }, { 3626, 115712 }, { 3519, 116736 }, { 3417, 117760 }, { 3317, 118784 }, { 3221, 119808 }, { 3129, 120832 }, { 3039, 121856 }, { 2952, 122880 }, { 2868, 123904 }, { 2787, 124928 }, { 2709, 125952 }, { 2633, 126976 }, { 2560, 128000 }, { 2489, 129024 }, { 2420, 130048 } }; static void adc_tm_map_voltage_temp(const struct adc_tm_map_pt *pts, size_t tablesize, int input, int *output) { Loading Loading @@ -140,6 +315,7 @@ int therm_fwd_scale(int64_t code, uint32_t adc_hc_vdd_ref_mv, volt = (s64) code * adc_hc_vdd_ref_mv; volt = div64_s64(volt, (data->full_scale_code_volt)); /* Same API can be used for resistance-temperature table */ adc_tm_map_voltage_temp(adcmap_100k_104ef_104fb_1875_vref, ARRAY_SIZE(adcmap_100k_104ef_104fb_1875_vref), (int) volt, &result); Loading @@ -148,6 +324,25 @@ int therm_fwd_scale(int64_t code, uint32_t adc_hc_vdd_ref_mv, } EXPORT_SYMBOL(therm_fwd_scale); int therm_fwd_scale_adc7(int64_t code) { int64_t resistance = 0; int result = 0; if (code >= RATIO_MAX_ADC7) return -EINVAL; resistance = (s64) code * R_PU_100K; resistance = div64_s64(resistance, (RATIO_MAX_ADC7 - code)); adc_tm_map_voltage_temp(adcmap_100k_adc7, ARRAY_SIZE(adcmap_100k_adc7), (int) resistance, &result); return result; } EXPORT_SYMBOL(therm_fwd_scale_adc7); void adc_tm_scale_therm_voltage_100k(struct adc_tm_config *param, const struct adc_tm_data *data) { Loading Loading @@ -188,6 +383,47 @@ void adc_tm_scale_therm_voltage_100k(struct adc_tm_config *param, } EXPORT_SYMBOL(adc_tm_scale_therm_voltage_100k); void adc_tm_scale_therm_voltage_100k_adc7(struct adc_tm_config *param) { int temp; int64_t resistance = 0; /* High temperature maps to lower threshold voltage */ /* Same API can be used for resistance-temperature table */ adc_tm_map_temp_voltage( adcmap_100k_adc7, ARRAY_SIZE(adcmap_100k_adc7), param->high_thr_temp, &resistance); param->low_thr_voltage = resistance * RATIO_MAX_ADC7; param->low_thr_voltage = div64_s64(param->low_thr_voltage, (resistance + R_PU_100K)); temp = therm_fwd_scale_adc7(param->low_thr_voltage); if (temp == -EINVAL) return; if (temp < param->high_thr_temp) param->low_thr_voltage--; /* Low temperature maps to higher threshold voltage */ /* Same API can be used for resistance-temperature table */ adc_tm_map_temp_voltage( adcmap_100k_adc7, ARRAY_SIZE(adcmap_100k_adc7), param->low_thr_temp, &resistance); param->high_thr_voltage = resistance * RATIO_MAX_ADC7; param->high_thr_voltage = div64_s64(param->high_thr_voltage, (resistance + R_PU_100K)); temp = therm_fwd_scale_adc7(param->high_thr_voltage); if (temp > param->low_thr_temp) param->high_thr_voltage++; } EXPORT_SYMBOL(adc_tm_scale_therm_voltage_100k_adc7); int32_t adc_tm_absolute_rthr(const struct adc_tm_data *data, struct adc_tm_config *tm_config) { Loading @@ -195,11 +431,13 @@ int32_t adc_tm_absolute_rthr(const struct adc_tm_data *data, low_thr = div_s64(tm_config->low_thr_voltage, tm_config->prescal); low_thr *= data->full_scale_code_volt; low_thr = div64_s64(low_thr, ADC_HC_VDD_REF); tm_config->low_thr_voltage = low_thr; high_thr = div_s64(tm_config->high_thr_voltage, tm_config->prescal); high_thr *= data->full_scale_code_volt; high_thr = div64_s64(high_thr, ADC_HC_VDD_REF); tm_config->high_thr_voltage = high_thr; Loading @@ -207,5 +445,25 @@ int32_t adc_tm_absolute_rthr(const struct adc_tm_data *data, } EXPORT_SYMBOL(adc_tm_absolute_rthr); int32_t adc_tm_absolute_rthr_adc7(struct adc_tm_config *tm_config) { int64_t low_thr = 0, high_thr = 0; low_thr = div_s64(tm_config->low_thr_voltage, tm_config->prescal); low_thr *= MAX_CODE_VOLT; low_thr = div64_s64(low_thr, ADC_HC_VDD_REF); tm_config->low_thr_voltage = low_thr; high_thr = div_s64(tm_config->high_thr_voltage, tm_config->prescal); high_thr *= MAX_CODE_VOLT; high_thr = div64_s64(high_thr, ADC_HC_VDD_REF); tm_config->high_thr_voltage = high_thr; return 0; } EXPORT_SYMBOL(adc_tm_absolute_rthr_adc7); MODULE_DESCRIPTION("Qualcomm Technologies Inc. PMIC ADC_TM common driver"); MODULE_LICENSE("GPL v2");