Lines Matching +full:3 +full:- +full:channel
1 // SPDX-License-Identifier: GPL-2.0-only
5 * Copyright (C) 2009-2013 Texas Instruments Inc.
13 * Based on twl4030-madc.c
48 #define TWL6030_GPADC_CTRL_P1_SP1 BIT(3)
61 * struct twl6030_chnl_calib - channel calibration
73 * struct twl6030_ideal_code - GPADC calibration parameters
77 * @channel: channel number
84 int channel; member
94 * struct twl6030_gpadc_platform_data - platform specific data
99 * @channel_to_reg: pointer to ADC function to convert channel to
107 int (*start_conversion)(int channel);
108 u8 (*channel_to_reg)(int channel);
113 * struct twl6030_gpadc_data - GPADC data
118 * channel with gain error and offset
131 * calibration offset is same for channels 1, 3, 4, 5
140 .channel = 0,
147 .channel = 1,
154 .channel = 2,
160 [3] = { /* ch 3, external, general purpose */
161 .channel = 3,
168 .channel = 4,
175 .channel = 5,
182 .channel = 6,
189 .channel = 7,
196 .channel = 8,
203 .channel = 9,
210 .channel = 10,
217 .channel = 11,
222 .channel = 14,
233 .channel = 0,
240 .channel = 1,
247 .channel = 2,
253 [3] = { /* ch 3, external, temperature with external diode/general
255 .channel = 3,
262 .channel = 4,
269 .channel = 5,
276 .channel = 6,
283 .channel = 7,
290 .channel = 8,
297 .channel = 9,
304 .channel = 10,
310 [11] = { /* ch 11, internal, VBUS DC-DC output current */
311 .channel = 11,
320 .channel = 14,
329 .channel = 17,
332 .channel = 18,
374 complete(&gpadc->irq_complete); in twl6030_gpadc_irq_handler()
379 static int twl6030_start_conversion(int channel) in twl6030_start_conversion() argument
385 static int twl6032_start_conversion(int channel) in twl6032_start_conversion() argument
389 ret = twl6030_gpadc_write(TWL6032_GPADC_GPSELECT_ISB, channel); in twl6032_start_conversion()
397 static u8 twl6030_channel_to_reg(int channel) in twl6030_channel_to_reg() argument
399 return TWL6030_GPADC_GPCH0_LSB + 2 * channel; in twl6030_channel_to_reg()
402 static u8 twl6032_channel_to_reg(int channel) in twl6032_channel_to_reg() argument
405 * for any prior chosen channel, when the conversion is ready in twl6032_channel_to_reg()
413 int channel, int size) in twl6030_gpadc_lookup() argument
418 if (ideal[i].channel == channel) in twl6030_gpadc_lookup()
425 *pdata, int channel) in twl6030_channel_calibrated() argument
427 const struct twl6030_ideal_code *ideal = pdata->ideal; in twl6030_channel_calibrated()
430 i = twl6030_gpadc_lookup(ideal, channel, pdata->nchannels); in twl6030_channel_calibrated()
432 return pdata->ideal[i].code2; in twl6030_channel_calibrated()
436 int channel, int raw_code) in twl6030_gpadc_make_correction() argument
438 const struct twl6030_ideal_code *ideal = gpadc->pdata->ideal; in twl6030_gpadc_make_correction()
442 i = twl6030_gpadc_lookup(ideal, channel, gpadc->pdata->nchannels); in twl6030_gpadc_make_correction()
443 corrected_code = ((raw_code * 1000) - in twl6030_gpadc_make_correction()
444 gpadc->twl6030_cal_tbl[i].offset_error) / in twl6030_gpadc_make_correction()
445 gpadc->twl6030_cal_tbl[i].gain_error; in twl6030_gpadc_make_correction()
451 int channel, int *res) in twl6030_gpadc_get_raw() argument
453 u8 reg = gpadc->pdata->channel_to_reg(channel); in twl6030_gpadc_get_raw()
460 dev_dbg(gpadc->dev, "unable to read register 0x%X\n", reg); in twl6030_gpadc_get_raw()
465 dev_dbg(gpadc->dev, "GPADC raw code: %d", raw_code); in twl6030_gpadc_get_raw()
467 if (twl6030_channel_calibrated(gpadc->pdata, channel)) in twl6030_gpadc_get_raw()
468 *res = twl6030_gpadc_make_correction(gpadc, channel, raw_code); in twl6030_gpadc_get_raw()
476 int channel, int *val) in twl6030_gpadc_get_processed() argument
478 const struct twl6030_ideal_code *ideal = gpadc->pdata->ideal; in twl6030_gpadc_get_processed()
484 ret = twl6030_gpadc_get_raw(gpadc, channel, &corrected_code); in twl6030_gpadc_get_processed()
488 i = twl6030_gpadc_lookup(ideal, channel, gpadc->pdata->nchannels); in twl6030_gpadc_get_processed()
490 gpadc->twl6030_cal_tbl[i].gain; in twl6030_gpadc_get_processed()
495 dev_dbg(gpadc->dev, "GPADC corrected code: %d", corrected_code); in twl6030_gpadc_get_processed()
496 dev_dbg(gpadc->dev, "GPADC value: %d", channel_value); in twl6030_gpadc_get_processed()
511 mutex_lock(&gpadc->lock); in twl6030_gpadc_read_raw()
513 ret = gpadc->pdata->start_conversion(chan->channel); in twl6030_gpadc_read_raw()
515 dev_err(gpadc->dev, "failed to start conversion\n"); in twl6030_gpadc_read_raw()
520 &gpadc->irq_complete, msecs_to_jiffies(5000)); in twl6030_gpadc_read_raw()
522 ret = -ETIMEDOUT; in twl6030_gpadc_read_raw()
525 ret = -EINTR; in twl6030_gpadc_read_raw()
531 ret = twl6030_gpadc_get_raw(gpadc, chan->channel, val); in twl6030_gpadc_read_raw()
532 ret = ret ? -EIO : IIO_VAL_INT; in twl6030_gpadc_read_raw()
536 ret = twl6030_gpadc_get_processed(gpadc, chan->channel, val); in twl6030_gpadc_read_raw()
537 ret = ret ? -EIO : IIO_VAL_INT; in twl6030_gpadc_read_raw()
544 mutex_unlock(&gpadc->lock); in twl6030_gpadc_read_raw()
556 * channel.
557 * gain: k = 1 + ((d2 - d1) / (x2 - x1))
558 * offset: b = d1 + (k - 1) * x1
561 int channel, int d1, int d2) in twl6030_calibrate_channel() argument
564 const struct twl6030_ideal_code *ideal = gpadc->pdata->ideal; in twl6030_calibrate_channel()
566 i = twl6030_gpadc_lookup(ideal, channel, gpadc->pdata->nchannels); in twl6030_calibrate_channel()
569 gain = ((ideal[i].volt2 - ideal[i].volt1) * 1000) / in twl6030_calibrate_channel()
570 (ideal[i].code2 - ideal[i].code1); in twl6030_calibrate_channel()
575 /* k - real curve gain */ in twl6030_calibrate_channel()
576 k = 1000 + (((d2 - d1) * 1000) / (x2 - x1)); in twl6030_calibrate_channel()
578 /* b - offset of the real curve gain */ in twl6030_calibrate_channel()
579 b = (d1 * 1000) - (k - 1000) * x1; in twl6030_calibrate_channel()
581 gpadc->twl6030_cal_tbl[i].gain = gain; in twl6030_calibrate_channel()
582 gpadc->twl6030_cal_tbl[i].gain_error = k; in twl6030_calibrate_channel()
583 gpadc->twl6030_cal_tbl[i].offset_error = b; in twl6030_calibrate_channel()
585 dev_dbg(gpadc->dev, "GPADC d1 for Chn: %d = %d\n", channel, d1); in twl6030_calibrate_channel()
586 dev_dbg(gpadc->dev, "GPADC d2 for Chn: %d = %d\n", channel, d2); in twl6030_calibrate_channel()
587 dev_dbg(gpadc->dev, "GPADC x1 for Chn: %d = %d\n", channel, x1); in twl6030_calibrate_channel()
588 dev_dbg(gpadc->dev, "GPADC x2 for Chn: %d = %d\n", channel, x2); in twl6030_calibrate_channel()
589 dev_dbg(gpadc->dev, "GPADC Gain for Chn: %d = %d\n", channel, gain); in twl6030_calibrate_channel()
590 dev_dbg(gpadc->dev, "GPADC k for Chn: %d = %d\n", channel, k); in twl6030_calibrate_channel()
591 dev_dbg(gpadc->dev, "GPADC b for Chn: %d = %d\n", channel, b); in twl6030_calibrate_channel()
598 * bit 0 - sign, bit 7 - reserved, 6..1 - trim value in twl6030_gpadc_get_trim_offset()
625 dev_err(gpadc->dev, "calibration failed\n"); in twl6030_calibration()
637 case 3: in twl6030_calibration()
654 d2 = trim_regs[3]; in twl6030_calibration()
690 val = -val; in twl6032_get_trim_value()
704 dev_err(gpadc->dev, "calibration failed\n"); in twl6032_calibration()
712 * gain is calculated to 3 decimal places fixed point. in twl6032_calibration()
720 case 3: in twl6032_calibration()
728 d2 = twl6032_get_trim_value(trim_regs, 3, 1, 0x3f, in twl6032_calibration()
737 temp = twl6032_get_trim_value(trim_regs, 3, 1, 0x3F, in twl6032_calibration()
748 temp = twl6032_get_trim_value(trim_regs, 3, 1, 0x3f, in twl6032_calibration()
755 0x0E, 3); in twl6032_calibration()
757 0x0E, 3); in twl6032_calibration()
766 d1 = -d1; in twl6032_calibration()
769 temp = twl6032_get_trim_value(trim_regs, 3, 1, 0x3f, in twl6032_calibration()
774 d2 = -d2; in twl6032_calibration()
791 .channel = chn, \
800 TWL6030_GPADC_CHAN(3, IIO_VOLTAGE, IIO_CHAN_INFO_PROCESSED),
816 TWL6030_GPADC_CHAN(3, IIO_VOLTAGE, IIO_CHAN_INFO_PROCESSED),
854 .compatible = "ti,twl6030-gpadc",
858 .compatible = "ti,twl6032-gpadc",
867 struct device *dev = &pdev->dev; in twl6030_gpadc_probe()
877 return -EINVAL; in twl6030_gpadc_probe()
879 pdata = match->data; in twl6030_gpadc_probe()
883 return -ENOMEM; in twl6030_gpadc_probe()
887 gpadc->twl6030_cal_tbl = devm_kcalloc(dev, in twl6030_gpadc_probe()
888 pdata->nchannels, in twl6030_gpadc_probe()
889 sizeof(*gpadc->twl6030_cal_tbl), in twl6030_gpadc_probe()
891 if (!gpadc->twl6030_cal_tbl) in twl6030_gpadc_probe()
892 return -ENOMEM; in twl6030_gpadc_probe()
894 gpadc->dev = dev; in twl6030_gpadc_probe()
895 gpadc->pdata = pdata; in twl6030_gpadc_probe()
898 mutex_init(&gpadc->lock); in twl6030_gpadc_probe()
899 init_completion(&gpadc->irq_complete); in twl6030_gpadc_probe()
901 ret = pdata->calibrate(gpadc); in twl6030_gpadc_probe()
903 dev_err(&pdev->dev, "failed to read calibration registers\n"); in twl6030_gpadc_probe()
917 dev_err(&pdev->dev, "failed to enable GPADC interrupt\n"); in twl6030_gpadc_probe()
924 dev_err(&pdev->dev, "failed to enable GPADC module\n"); in twl6030_gpadc_probe()
928 indio_dev->name = DRIVER_NAME; in twl6030_gpadc_probe()
929 indio_dev->info = &twl6030_gpadc_iio_info; in twl6030_gpadc_probe()
930 indio_dev->modes = INDIO_DIRECT_MODE; in twl6030_gpadc_probe()
931 indio_dev->channels = pdata->iio_channels; in twl6030_gpadc_probe()
932 indio_dev->num_channels = pdata->nchannels; in twl6030_gpadc_probe()