Lines Matching +full:resistance +full:- +full:temp +full:- +full:table
1 // SPDX-License-Identifier: GPL-2.0-only
3 * Copyright (C) ST-Ericsson SA 2010
15 * detection by resistance measurements using relative voltages and GSM burst
54 /* 0 = use VTVOUT, 1 = use VRTC as pull-up supply for battery temp NTC */
63 * the bit layout is the same for SW and HW conversion set-up
163 #define AB8500_ADC_CH_IBAT_MIN (-6000) /* mA range measured by ADC for ibat */
165 #define AB8500_ADC_CH_IBAT_MIN_V (-60) /* mV range measured by ADC for ibat */
167 #define AB8500_GPADC_IBAT_VDROP_L (-56) /* mV */
192 * struct ab8500_adc_cal_data - Table for storing gain and offset for the
207 * struct ab8500_gpadc_chan_info - per-channel GPADC info
230 * struct ab8500_gpadc - AB8500 GPADC device information
233 * @chans: internal per-channel information container
260 for (i = 0; i < gpadc->nchans; i++) { in ab8500_gpadc_get_channel()
261 ch = &gpadc->chans[i]; in ab8500_gpadc_get_channel()
262 if (ch->id == chan) in ab8500_gpadc_get_channel()
265 if (i == gpadc->nchans) in ab8500_gpadc_get_channel()
272 * ab8500_gpadc_ad_to_voltage() - Convert a raw ADC value to a voltage
286 if (!gpadc->cal_data[AB8500_CAL_VMAIN].gain) { in ab8500_gpadc_ad_to_voltage()
287 res = AB8500_ADC_CH_CHG_V_MIN + (AB8500_ADC_CH_CHG_V_MAX - in ab8500_gpadc_ad_to_voltage()
293 res = (int) (ad_value * gpadc->cal_data[AB8500_CAL_VMAIN].gain + in ab8500_gpadc_ad_to_voltage()
294 gpadc->cal_data[AB8500_CAL_VMAIN].offset) / AB8500_GPADC_CALIB_SCALE; in ab8500_gpadc_ad_to_voltage()
304 if (!gpadc->cal_data[AB8500_CAL_BTEMP].gain) { in ab8500_gpadc_ad_to_voltage()
305 res = AB8500_ADC_CH_BTEMP_MIN + (AB8500_ADC_CH_BTEMP_MAX - in ab8500_gpadc_ad_to_voltage()
311 res = (int) (ad_value * gpadc->cal_data[AB8500_CAL_BTEMP].gain + in ab8500_gpadc_ad_to_voltage()
312 gpadc->cal_data[AB8500_CAL_BTEMP].offset) / AB8500_GPADC_CALIB_SCALE; in ab8500_gpadc_ad_to_voltage()
318 if (!gpadc->cal_data[AB8500_CAL_VBAT].gain) { in ab8500_gpadc_ad_to_voltage()
319 res = AB8500_ADC_CH_VBAT_MIN + (AB8500_ADC_CH_VBAT_MAX - in ab8500_gpadc_ad_to_voltage()
325 res = (int) (ad_value * gpadc->cal_data[AB8500_CAL_VBAT].gain + in ab8500_gpadc_ad_to_voltage()
326 gpadc->cal_data[AB8500_CAL_VBAT].offset) / AB8500_GPADC_CALIB_SCALE; in ab8500_gpadc_ad_to_voltage()
331 (AB8500_ADC_CH_DIETEMP_MAX - AB8500_ADC_CH_DIETEMP_MIN) * ad_value / in ab8500_gpadc_ad_to_voltage()
337 (AB8500_ADC_CH_ACCDET2_MAX - AB8500_ADC_CH_ACCDET2_MIN) * ad_value / in ab8500_gpadc_ad_to_voltage()
343 (AB8500_ADC_CH_CHG_V_MAX - AB8500_ADC_CH_CHG_V_MIN) * ad_value / in ab8500_gpadc_ad_to_voltage()
350 (AB8500_ADC_CH_CHG_I_MAX - AB8500_ADC_CH_CHG_I_MIN) * ad_value / in ab8500_gpadc_ad_to_voltage()
356 (AB8500_ADC_CH_BKBAT_MAX - AB8500_ADC_CH_BKBAT_MIN) * ad_value / in ab8500_gpadc_ad_to_voltage()
362 if (!gpadc->cal_data[AB8500_CAL_IBAT].gain) { in ab8500_gpadc_ad_to_voltage()
363 res = AB8500_ADC_CH_IBAT_MIN + (AB8500_ADC_CH_IBAT_MAX - in ab8500_gpadc_ad_to_voltage()
369 res = (int) (ad_value * gpadc->cal_data[AB8500_CAL_IBAT].gain + in ab8500_gpadc_ad_to_voltage()
370 gpadc->cal_data[AB8500_CAL_IBAT].offset) in ab8500_gpadc_ad_to_voltage()
375 dev_err(gpadc->dev, in ab8500_gpadc_ad_to_voltage()
378 res = -EINVAL; in ab8500_gpadc_ad_to_voltage()
402 return -ENODEV; in ab8500_gpadc_read()
405 if ((gpadc->irq_sw <= 0) && !ch->hardware_control) in ab8500_gpadc_read()
406 return -ENOTSUPP; in ab8500_gpadc_read()
407 if ((gpadc->irq_hw <= 0) && ch->hardware_control) in ab8500_gpadc_read()
408 return -ENOTSUPP; in ab8500_gpadc_read()
411 pm_runtime_get_sync(gpadc->dev); in ab8500_gpadc_read()
415 ret = abx500_get_register_interruptible(gpadc->dev, in ab8500_gpadc_read()
424 dev_err(gpadc->dev, "gpadc_conversion: GPADC busy"); in ab8500_gpadc_read()
425 ret = -EINVAL; in ab8500_gpadc_read()
433 switch (ch->avg_sample) { in ab8500_gpadc_read()
435 ctrl23 = ch->id | AB8500_GPADC_CTRL2_AVG_1; in ab8500_gpadc_read()
438 ctrl23 = ch->id | AB8500_GPADC_CTRL2_AVG_4; in ab8500_gpadc_read()
441 ctrl23 = ch->id | AB8500_GPADC_CTRL2_AVG_8; in ab8500_gpadc_read()
444 ctrl23 = ch->id | AB8500_GPADC_CTRL2_AVG_16; in ab8500_gpadc_read()
448 if (ch->hardware_control) { in ab8500_gpadc_read()
449 ret = abx500_set_register_interruptible(gpadc->dev, in ab8500_gpadc_read()
452 if (ch->falling_edge) in ab8500_gpadc_read()
455 ret = abx500_set_register_interruptible(gpadc->dev, in ab8500_gpadc_read()
459 dev_err(gpadc->dev, in ab8500_gpadc_read()
469 switch (ch->id) { in ab8500_gpadc_read()
476 if (!is_ab8500_2p0_or_earlier(gpadc->ab8500)) { in ab8500_gpadc_read()
494 ret = abx500_set_register_interruptible(gpadc->dev, in ab8500_gpadc_read()
497 dev_err(gpadc->dev, in ab8500_gpadc_read()
505 if (ch->hardware_control) { in ab8500_gpadc_read()
507 ret = abx500_set_register_interruptible(gpadc->dev, in ab8500_gpadc_read()
509 ch->trig_timer); in ab8500_gpadc_read()
511 dev_err(gpadc->dev, in ab8500_gpadc_read()
520 ret = abx500_mask_and_set_register_interruptible(gpadc->dev, in ab8500_gpadc_read()
525 dev_err(gpadc->dev, in ab8500_gpadc_read()
535 if (!wait_for_completion_timeout(&gpadc->complete, in ab8500_gpadc_read()
537 dev_err(gpadc->dev, in ab8500_gpadc_read()
539 ret = -EINVAL; in ab8500_gpadc_read()
544 ret = abx500_get_register_interruptible(gpadc->dev, in ab8500_gpadc_read()
547 dev_err(gpadc->dev, in ab8500_gpadc_read()
552 ret = abx500_get_register_interruptible(gpadc->dev, in ab8500_gpadc_read()
555 dev_err(gpadc->dev, in ab8500_gpadc_read()
561 if ((ch->id == AB8500_GPADC_CHAN_BAT_CTRL_AND_IBAT) || in ab8500_gpadc_read()
562 (ch->id == AB8500_GPADC_CHAN_VBAT_MEAS_AND_IBAT) || in ab8500_gpadc_read()
563 (ch->id == AB8500_GPADC_CHAN_VBAT_TRUE_MEAS_AND_IBAT) || in ab8500_gpadc_read()
564 (ch->id == AB8500_GPADC_CHAN_BAT_TEMP_AND_IBAT)) { in ab8500_gpadc_read()
566 if (ch->hardware_control) { in ab8500_gpadc_read()
568 ret = -ENOTSUPP; in ab8500_gpadc_read()
569 dev_err(gpadc->dev, in ab8500_gpadc_read()
574 ret = abx500_get_register_interruptible(gpadc->dev, in ab8500_gpadc_read()
578 dev_err(gpadc->dev, in ab8500_gpadc_read()
583 ret = abx500_get_register_interruptible(gpadc->dev, in ab8500_gpadc_read()
587 dev_err(gpadc->dev, in ab8500_gpadc_read()
594 dev_warn(gpadc->dev, in ab8500_gpadc_read()
602 ret = abx500_set_register_interruptible(gpadc->dev, AB8500_GPADC, in ab8500_gpadc_read()
605 dev_err(gpadc->dev, "gpadc_conversion: disable gpadc failed\n"); in ab8500_gpadc_read()
610 pm_runtime_mark_last_busy(gpadc->dev); in ab8500_gpadc_read()
611 pm_runtime_put_autosuspend(gpadc->dev); in ab8500_gpadc_read()
622 (void) abx500_set_register_interruptible(gpadc->dev, AB8500_GPADC, in ab8500_gpadc_read()
624 pm_runtime_put(gpadc->dev); in ab8500_gpadc_read()
625 dev_err(gpadc->dev, in ab8500_gpadc_read()
626 "gpadc_conversion: Failed to AD convert channel %d\n", ch->id); in ab8500_gpadc_read()
632 * ab8500_bm_gpadcconvend_handler() - isr for gpadc conversion completion
645 complete(&gpadc->complete); in ab8500_bm_gpadcconvend_handler()
681 ret[i] = abx500_get_register_interruptible(gpadc->dev, in ab8500_gpadc_read_calibration_data()
685 dev_err(gpadc->dev, "%s: read otp reg 0x%02x failed\n", in ab8500_gpadc_read_calibration_data()
688 /* Put this in the entropy pool as device-unique */ in ab8500_gpadc_read_calibration_data()
761 if (is_ab8540(gpadc->ab8500)) { in ab8500_gpadc_read_calibration_data()
768 gpadc->cal_data[AB8500_CAL_VMAIN].otp_calib_hi = in ab8500_gpadc_read_calibration_data()
770 gpadc->cal_data[AB8500_CAL_VMAIN].otp_calib_lo = in ab8500_gpadc_read_calibration_data()
773 gpadc->cal_data[AB8500_CAL_VMAIN].gain = AB8500_GPADC_CALIB_SCALE * in ab8500_gpadc_read_calibration_data()
774 (19500 - 315) / (vmain_high - vmain_low); in ab8500_gpadc_read_calibration_data()
775 gpadc->cal_data[AB8500_CAL_VMAIN].offset = AB8500_GPADC_CALIB_SCALE * in ab8500_gpadc_read_calibration_data()
776 19500 - (AB8500_GPADC_CALIB_SCALE * (19500 - 315) / in ab8500_gpadc_read_calibration_data()
777 (vmain_high - vmain_low)) * vmain_high; in ab8500_gpadc_read_calibration_data()
779 gpadc->cal_data[AB8500_CAL_VMAIN].gain = 0; in ab8500_gpadc_read_calibration_data()
785 gpadc->dev, AB8500_OTP_EMUL, in ab8500_gpadc_read_calibration_data()
788 dev_err(gpadc->dev, in ab8500_gpadc_read_calibration_data()
800 gpadc->cal_data[AB8500_CAL_IBAT].otp_calib_hi = in ab8500_gpadc_read_calibration_data()
802 gpadc->cal_data[AB8500_CAL_IBAT].otp_calib_lo = in ab8500_gpadc_read_calibration_data()
805 V_gain = ((AB8500_GPADC_IBAT_VDROP_H - AB8500_GPADC_IBAT_VDROP_L) in ab8500_gpadc_read_calibration_data()
806 << AB8500_GPADC_CALIB_SHIFT_IBAT) / (ibat_high - ibat_low); in ab8500_gpadc_read_calibration_data()
808 V_offset = (AB8500_GPADC_IBAT_VDROP_H << AB8500_GPADC_CALIB_SHIFT_IBAT) - in ab8500_gpadc_read_calibration_data()
809 (((AB8500_GPADC_IBAT_VDROP_H - AB8500_GPADC_IBAT_VDROP_L) << in ab8500_gpadc_read_calibration_data()
810 AB8500_GPADC_CALIB_SHIFT_IBAT) / (ibat_high - ibat_low)) in ab8500_gpadc_read_calibration_data()
816 V2A_gain = (AB8500_ADC_CH_IBAT_MAX - AB8500_ADC_CH_IBAT_MIN)/ in ab8500_gpadc_read_calibration_data()
817 (AB8500_ADC_CH_IBAT_MAX_V - AB8500_ADC_CH_IBAT_MIN_V); in ab8500_gpadc_read_calibration_data()
818 V2A_offset = ((AB8500_ADC_CH_IBAT_MAX_V * AB8500_ADC_CH_IBAT_MIN - in ab8500_gpadc_read_calibration_data()
821 / (AB8500_ADC_CH_IBAT_MAX_V - AB8500_ADC_CH_IBAT_MIN_V); in ab8500_gpadc_read_calibration_data()
823 gpadc->cal_data[AB8500_CAL_IBAT].gain = in ab8500_gpadc_read_calibration_data()
825 gpadc->cal_data[AB8500_CAL_IBAT].offset = in ab8500_gpadc_read_calibration_data()
828 gpadc->cal_data[AB8500_CAL_IBAT].gain = 0; in ab8500_gpadc_read_calibration_data()
838 gpadc->cal_data[AB8500_CAL_VMAIN].otp_calib_hi = in ab8500_gpadc_read_calibration_data()
840 gpadc->cal_data[AB8500_CAL_VMAIN].otp_calib_lo = in ab8500_gpadc_read_calibration_data()
843 gpadc->cal_data[AB8500_CAL_VMAIN].gain = AB8500_GPADC_CALIB_SCALE * in ab8500_gpadc_read_calibration_data()
844 (19500 - 315) / (vmain_high - vmain_low); in ab8500_gpadc_read_calibration_data()
846 gpadc->cal_data[AB8500_CAL_VMAIN].offset = AB8500_GPADC_CALIB_SCALE * in ab8500_gpadc_read_calibration_data()
847 19500 - (AB8500_GPADC_CALIB_SCALE * (19500 - 315) / in ab8500_gpadc_read_calibration_data()
848 (vmain_high - vmain_low)) * vmain_high; in ab8500_gpadc_read_calibration_data()
850 gpadc->cal_data[AB8500_CAL_VMAIN].gain = 0; in ab8500_gpadc_read_calibration_data()
860 gpadc->cal_data[AB8500_CAL_BTEMP].otp_calib_hi = (u16)btemp_high; in ab8500_gpadc_read_calibration_data()
861 gpadc->cal_data[AB8500_CAL_BTEMP].otp_calib_lo = (u16)btemp_low; in ab8500_gpadc_read_calibration_data()
863 gpadc->cal_data[AB8500_CAL_BTEMP].gain = in ab8500_gpadc_read_calibration_data()
864 AB8500_GPADC_CALIB_SCALE * (1300 - 21) / (btemp_high - btemp_low); in ab8500_gpadc_read_calibration_data()
865 gpadc->cal_data[AB8500_CAL_BTEMP].offset = AB8500_GPADC_CALIB_SCALE * 1300 - in ab8500_gpadc_read_calibration_data()
866 (AB8500_GPADC_CALIB_SCALE * (1300 - 21) / (btemp_high - btemp_low)) in ab8500_gpadc_read_calibration_data()
869 gpadc->cal_data[AB8500_CAL_BTEMP].gain = 0; in ab8500_gpadc_read_calibration_data()
877 gpadc->cal_data[AB8500_CAL_VBAT].otp_calib_hi = (u16)vbat_high; in ab8500_gpadc_read_calibration_data()
878 gpadc->cal_data[AB8500_CAL_VBAT].otp_calib_lo = (u16)vbat_low; in ab8500_gpadc_read_calibration_data()
880 gpadc->cal_data[AB8500_CAL_VBAT].gain = AB8500_GPADC_CALIB_SCALE * in ab8500_gpadc_read_calibration_data()
881 (4700 - 2380) / (vbat_high - vbat_low); in ab8500_gpadc_read_calibration_data()
882 gpadc->cal_data[AB8500_CAL_VBAT].offset = AB8500_GPADC_CALIB_SCALE * 4700 - in ab8500_gpadc_read_calibration_data()
883 (AB8500_GPADC_CALIB_SCALE * (4700 - 2380) / in ab8500_gpadc_read_calibration_data()
884 (vbat_high - vbat_low)) * vbat_high; in ab8500_gpadc_read_calibration_data()
886 gpadc->cal_data[AB8500_CAL_VBAT].gain = 0; in ab8500_gpadc_read_calibration_data()
899 ch = ab8500_gpadc_get_channel(gpadc, chan->address); in ab8500_gpadc_read_raw()
901 dev_err(gpadc->dev, "no such channel %lu\n", in ab8500_gpadc_read_raw()
902 chan->address); in ab8500_gpadc_read_raw()
903 return -EINVAL; in ab8500_gpadc_read_raw()
916 processed = ab8500_gpadc_ad_to_voltage(gpadc, ch->id, raw_val); in ab8500_gpadc_read_raw()
925 return -EINVAL; in ab8500_gpadc_read_raw()
933 for (i = 0; i < indio_dev->num_channels; i++) in ab8500_gpadc_of_xlate()
934 if (indio_dev->channels[i].channel == iiospec->args[0]) in ab8500_gpadc_of_xlate()
937 return -EINVAL; in ab8500_gpadc_of_xlate()
951 regulator_disable(gpadc->vddadc); in ab8500_gpadc_runtime_suspend()
962 ret = regulator_enable(gpadc->vddadc); in ab8500_gpadc_runtime_resume()
971 * ab8500_gpadc_parse_channel() - process devicetree channel configuration
985 const char *name = np->name; in ab8500_gpadc_parse_channel()
996 return -EINVAL; in ab8500_gpadc_parse_channel()
999 iio_chan->channel = chan; in ab8500_gpadc_parse_channel()
1000 iio_chan->datasheet_name = name; in ab8500_gpadc_parse_channel()
1001 iio_chan->indexed = 1; in ab8500_gpadc_parse_channel()
1002 iio_chan->address = chan; in ab8500_gpadc_parse_channel()
1003 iio_chan->info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | in ab8500_gpadc_parse_channel()
1008 iio_chan->type = IIO_CURRENT; in ab8500_gpadc_parse_channel()
1010 iio_chan->type = IIO_VOLTAGE; in ab8500_gpadc_parse_channel()
1012 ch->id = chan; in ab8500_gpadc_parse_channel()
1015 ch->avg_sample = 16; in ab8500_gpadc_parse_channel()
1016 ch->hardware_control = false; in ab8500_gpadc_parse_channel()
1017 ch->falling_edge = false; in ab8500_gpadc_parse_channel()
1018 ch->trig_timer = 0; in ab8500_gpadc_parse_channel()
1024 * ab8500_gpadc_parse_channels() - Parse the GPADC channels from DT
1043 dev_err(gpadc->dev, "no channel children\n"); in ab8500_gpadc_parse_channels()
1044 return -ENODEV; in ab8500_gpadc_parse_channels()
1046 dev_info(gpadc->dev, "found %d ADC channels\n", nchans); in ab8500_gpadc_parse_channels()
1048 iio_chans = devm_kcalloc(gpadc->dev, nchans, in ab8500_gpadc_parse_channels()
1051 return -ENOMEM; in ab8500_gpadc_parse_channels()
1053 gpadc->chans = devm_kcalloc(gpadc->dev, nchans, in ab8500_gpadc_parse_channels()
1054 sizeof(*gpadc->chans), GFP_KERNEL); in ab8500_gpadc_parse_channels()
1055 if (!gpadc->chans) in ab8500_gpadc_parse_channels()
1056 return -ENOMEM; in ab8500_gpadc_parse_channels()
1063 ch = &gpadc->chans[i]; in ab8500_gpadc_parse_channels()
1066 ret = ab8500_gpadc_parse_channel(gpadc->dev, child, ch, in ab8500_gpadc_parse_channels()
1074 gpadc->nchans = nchans; in ab8500_gpadc_parse_channels()
1085 struct device *dev = &pdev->dev; in ab8500_gpadc_probe()
1086 struct device_node *np = pdev->dev.of_node; in ab8500_gpadc_probe()
1093 return -ENOMEM; in ab8500_gpadc_probe()
1098 gpadc->dev = dev; in ab8500_gpadc_probe()
1099 gpadc->ab8500 = dev_get_drvdata(dev->parent); in ab8500_gpadc_probe()
1105 gpadc->irq_sw = platform_get_irq_byname(pdev, "SW_CONV_END"); in ab8500_gpadc_probe()
1106 if (gpadc->irq_sw < 0) { in ab8500_gpadc_probe()
1108 return gpadc->irq_sw; in ab8500_gpadc_probe()
1111 gpadc->irq_hw = platform_get_irq_byname(pdev, "HW_CONV_END"); in ab8500_gpadc_probe()
1112 if (gpadc->irq_hw < 0) { in ab8500_gpadc_probe()
1114 return gpadc->irq_hw; in ab8500_gpadc_probe()
1118 init_completion(&gpadc->complete); in ab8500_gpadc_probe()
1121 ret = devm_request_threaded_irq(dev, gpadc->irq_sw, NULL, in ab8500_gpadc_probe()
1123 "ab8500-gpadc-sw", gpadc); in ab8500_gpadc_probe()
1127 gpadc->irq_sw); in ab8500_gpadc_probe()
1131 ret = devm_request_threaded_irq(dev, gpadc->irq_hw, NULL, in ab8500_gpadc_probe()
1133 "ab8500-gpadc-hw", gpadc); in ab8500_gpadc_probe()
1137 gpadc->irq_hw); in ab8500_gpadc_probe()
1142 gpadc->vddadc = devm_regulator_get(dev, "vddadc"); in ab8500_gpadc_probe()
1143 if (IS_ERR(gpadc->vddadc)) { in ab8500_gpadc_probe()
1144 ret = PTR_ERR(gpadc->vddadc); in ab8500_gpadc_probe()
1149 ret = regulator_enable(gpadc->vddadc); in ab8500_gpadc_probe()
1166 indio_dev->name = "ab8500-gpadc"; in ab8500_gpadc_probe()
1167 indio_dev->modes = INDIO_DIRECT_MODE; in ab8500_gpadc_probe()
1168 indio_dev->info = &ab8500_gpadc_info; in ab8500_gpadc_probe()
1169 indio_dev->channels = iio_chans; in ab8500_gpadc_probe()
1170 indio_dev->num_channels = n_iio_chans; in ab8500_gpadc_probe()
1182 regulator_disable(gpadc->vddadc); in ab8500_gpadc_probe()
1192 pm_runtime_get_sync(gpadc->dev); in ab8500_gpadc_remove()
1193 pm_runtime_put_noidle(gpadc->dev); in ab8500_gpadc_remove()
1194 pm_runtime_disable(gpadc->dev); in ab8500_gpadc_remove()
1195 regulator_disable(gpadc->vddadc); in ab8500_gpadc_remove()
1212 .name = "ab8500-gpadc",