Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0
0002 
0003 #include <linux/bits.h>
0004 #include <linux/delay.h>
0005 #include <linux/irq.h>
0006 #include <linux/kernel.h>
0007 #include <linux/ktime.h>
0008 #include <linux/mod_devicetable.h>
0009 #include <linux/module.h>
0010 #include <linux/mutex.h>
0011 #include <linux/platform_device.h>
0012 #include <linux/regmap.h>
0013 
0014 #include <linux/iio/buffer.h>
0015 #include <linux/iio/iio.h>
0016 #include <linux/iio/trigger_consumer.h>
0017 #include <linux/iio/triggered_buffer.h>
0018 
0019 #include <asm/unaligned.h>
0020 
0021 #define MT6360_REG_PMUCHGCTRL3  0x313
0022 #define MT6360_REG_PMUADCCFG    0x356
0023 #define MT6360_REG_PMUADCIDLET  0x358
0024 #define MT6360_REG_PMUADCRPT1   0x35A
0025 
0026 /* PMUCHGCTRL3 0x313 */
0027 #define MT6360_AICR_MASK    GENMASK(7, 2)
0028 #define MT6360_AICR_SHFT    2
0029 #define MT6360_AICR_400MA   0x6
0030 /* PMUADCCFG 0x356 */
0031 #define MT6360_ADCEN_MASK   BIT(15)
0032 /* PMUADCRPT1 0x35A */
0033 #define MT6360_PREFERCH_MASK    GENMASK(7, 4)
0034 #define MT6360_PREFERCH_SHFT    4
0035 #define MT6360_RPTCH_MASK   GENMASK(3, 0)
0036 #define MT6360_NO_PREFER    15
0037 
0038 /* Time in ms */
0039 #define ADC_WAIT_TIME_MS    25
0040 #define ADC_CONV_TIMEOUT_MS 100
0041 #define ADC_LOOP_TIME_US    2000
0042 
0043 enum {
0044     MT6360_CHAN_USBID = 0,
0045     MT6360_CHAN_VBUSDIV5,
0046     MT6360_CHAN_VBUSDIV2,
0047     MT6360_CHAN_VSYS,
0048     MT6360_CHAN_VBAT,
0049     MT6360_CHAN_IBUS,
0050     MT6360_CHAN_IBAT,
0051     MT6360_CHAN_CHG_VDDP,
0052     MT6360_CHAN_TEMP_JC,
0053     MT6360_CHAN_VREF_TS,
0054     MT6360_CHAN_TS,
0055     MT6360_CHAN_MAX
0056 };
0057 
0058 struct mt6360_adc_data {
0059     struct device *dev;
0060     struct regmap *regmap;
0061     /* Due to only one set of ADC control, this lock is used to prevent the race condition */
0062     struct mutex adc_lock;
0063     ktime_t last_off_timestamps[MT6360_CHAN_MAX];
0064 };
0065 
0066 static int mt6360_adc_read_channel(struct mt6360_adc_data *mad, int channel, int *val)
0067 {
0068     __be16 adc_enable;
0069     u8 rpt[3];
0070     ktime_t predict_end_t, timeout;
0071     unsigned int pre_wait_time;
0072     int ret;
0073 
0074     mutex_lock(&mad->adc_lock);
0075 
0076     /* Select the preferred ADC channel */
0077     ret = regmap_update_bits(mad->regmap, MT6360_REG_PMUADCRPT1, MT6360_PREFERCH_MASK,
0078                  channel << MT6360_PREFERCH_SHFT);
0079     if (ret)
0080         goto out_adc_lock;
0081 
0082     adc_enable = cpu_to_be16(MT6360_ADCEN_MASK | BIT(channel));
0083     ret = regmap_raw_write(mad->regmap, MT6360_REG_PMUADCCFG, &adc_enable, sizeof(adc_enable));
0084     if (ret)
0085         goto out_adc_lock;
0086 
0087     predict_end_t = ktime_add_ms(mad->last_off_timestamps[channel], 2 * ADC_WAIT_TIME_MS);
0088 
0089     if (ktime_after(ktime_get(), predict_end_t))
0090         pre_wait_time = ADC_WAIT_TIME_MS;
0091     else
0092         pre_wait_time = 3 * ADC_WAIT_TIME_MS;
0093 
0094     if (msleep_interruptible(pre_wait_time)) {
0095         ret = -ERESTARTSYS;
0096         goto out_adc_conv;
0097     }
0098 
0099     timeout = ktime_add_ms(ktime_get(), ADC_CONV_TIMEOUT_MS);
0100     while (true) {
0101         ret = regmap_raw_read(mad->regmap, MT6360_REG_PMUADCRPT1, rpt, sizeof(rpt));
0102         if (ret)
0103             goto out_adc_conv;
0104 
0105         /*
0106          * There are two functions, ZCV and TypeC OTP, running ADC VBAT and TS in
0107          * background, and ADC samples are taken on a fixed frequency no matter read the
0108          * previous one or not.
0109          * To avoid conflict, We set minimum time threshold after enable ADC and
0110          * check report channel is the same.
0111          * The worst case is run the same ADC twice and background function is also running,
0112          * ADC conversion sequence is desire channel before start ADC, background ADC,
0113          * desire channel after start ADC.
0114          * So the minimum correct data is three times of typical conversion time.
0115          */
0116         if ((rpt[0] & MT6360_RPTCH_MASK) == channel)
0117             break;
0118 
0119         if (ktime_compare(ktime_get(), timeout) > 0) {
0120             ret = -ETIMEDOUT;
0121             goto out_adc_conv;
0122         }
0123 
0124         usleep_range(ADC_LOOP_TIME_US / 2, ADC_LOOP_TIME_US);
0125     }
0126 
0127     *val = rpt[1] << 8 | rpt[2];
0128     ret = IIO_VAL_INT;
0129 
0130 out_adc_conv:
0131     /* Only keep ADC enable */
0132     adc_enable = cpu_to_be16(MT6360_ADCEN_MASK);
0133     regmap_raw_write(mad->regmap, MT6360_REG_PMUADCCFG, &adc_enable, sizeof(adc_enable));
0134     mad->last_off_timestamps[channel] = ktime_get();
0135     /* Config prefer channel to NO_PREFER */
0136     regmap_update_bits(mad->regmap, MT6360_REG_PMUADCRPT1, MT6360_PREFERCH_MASK,
0137                MT6360_NO_PREFER << MT6360_PREFERCH_SHFT);
0138 out_adc_lock:
0139     mutex_unlock(&mad->adc_lock);
0140 
0141     return ret;
0142 }
0143 
0144 static int mt6360_adc_read_scale(struct mt6360_adc_data *mad, int channel, int *val, int *val2)
0145 {
0146     unsigned int regval;
0147     int ret;
0148 
0149     switch (channel) {
0150     case MT6360_CHAN_USBID:
0151     case MT6360_CHAN_VSYS:
0152     case MT6360_CHAN_VBAT:
0153     case MT6360_CHAN_CHG_VDDP:
0154     case MT6360_CHAN_VREF_TS:
0155     case MT6360_CHAN_TS:
0156         *val = 1250;
0157         return IIO_VAL_INT;
0158     case MT6360_CHAN_VBUSDIV5:
0159         *val = 6250;
0160         return IIO_VAL_INT;
0161     case MT6360_CHAN_VBUSDIV2:
0162     case MT6360_CHAN_IBUS:
0163     case MT6360_CHAN_IBAT:
0164         *val = 2500;
0165 
0166         if (channel == MT6360_CHAN_IBUS) {
0167             /* IBUS will be affected by input current limit for the different Ron */
0168             /* Check whether the config is <400mA or not */
0169             ret = regmap_read(mad->regmap, MT6360_REG_PMUCHGCTRL3, &regval);
0170             if (ret)
0171                 return ret;
0172 
0173             regval = (regval & MT6360_AICR_MASK) >> MT6360_AICR_SHFT;
0174             if (regval < MT6360_AICR_400MA)
0175                 *val = 1900;
0176         }
0177 
0178         return IIO_VAL_INT;
0179     case MT6360_CHAN_TEMP_JC:
0180         *val = 105;
0181         *val2 = 100;
0182         return IIO_VAL_FRACTIONAL;
0183     }
0184 
0185     return -EINVAL;
0186 }
0187 
0188 static int mt6360_adc_read_offset(struct mt6360_adc_data *mad, int channel, int *val)
0189 {
0190     *val = (channel == MT6360_CHAN_TEMP_JC) ? -80 : 0;
0191     return IIO_VAL_INT;
0192 }
0193 
0194 static int mt6360_adc_read_raw(struct iio_dev *iio_dev, const struct iio_chan_spec *chan,
0195                    int *val, int *val2, long mask)
0196 {
0197     struct mt6360_adc_data *mad = iio_priv(iio_dev);
0198 
0199     switch (mask) {
0200     case IIO_CHAN_INFO_RAW:
0201         return mt6360_adc_read_channel(mad, chan->channel, val);
0202     case IIO_CHAN_INFO_SCALE:
0203         return mt6360_adc_read_scale(mad, chan->channel, val, val2);
0204     case IIO_CHAN_INFO_OFFSET:
0205         return mt6360_adc_read_offset(mad, chan->channel, val);
0206     }
0207 
0208     return -EINVAL;
0209 }
0210 
0211 static const char *mt6360_channel_labels[MT6360_CHAN_MAX] = {
0212     "usbid", "vbusdiv5", "vbusdiv2", "vsys", "vbat", "ibus", "ibat", "chg_vddp",
0213     "temp_jc", "vref_ts", "ts",
0214 };
0215 
0216 static int mt6360_adc_read_label(struct iio_dev *iio_dev, const struct iio_chan_spec *chan,
0217                  char *label)
0218 {
0219     return snprintf(label, PAGE_SIZE, "%s\n", mt6360_channel_labels[chan->channel]);
0220 }
0221 
0222 static const struct iio_info mt6360_adc_iio_info = {
0223     .read_raw = mt6360_adc_read_raw,
0224     .read_label = mt6360_adc_read_label,
0225 };
0226 
0227 #define MT6360_ADC_CHAN(_idx, _type) {              \
0228     .type = _type,                      \
0229     .channel = MT6360_CHAN_##_idx,              \
0230     .scan_index = MT6360_CHAN_##_idx,           \
0231     .datasheet_name = #_idx,                \
0232     .scan_type =  {                     \
0233         .sign = 'u',                    \
0234         .realbits = 16,                 \
0235         .storagebits = 16,              \
0236         .endianness = IIO_CPU,              \
0237     },                          \
0238     .indexed = 1,                       \
0239     .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |      \
0240                 BIT(IIO_CHAN_INFO_SCALE) |  \
0241                 BIT(IIO_CHAN_INFO_OFFSET),  \
0242 }
0243 
0244 static const struct iio_chan_spec mt6360_adc_channels[] = {
0245     MT6360_ADC_CHAN(USBID, IIO_VOLTAGE),
0246     MT6360_ADC_CHAN(VBUSDIV5, IIO_VOLTAGE),
0247     MT6360_ADC_CHAN(VBUSDIV2, IIO_VOLTAGE),
0248     MT6360_ADC_CHAN(VSYS, IIO_VOLTAGE),
0249     MT6360_ADC_CHAN(VBAT, IIO_VOLTAGE),
0250     MT6360_ADC_CHAN(IBUS, IIO_CURRENT),
0251     MT6360_ADC_CHAN(IBAT, IIO_CURRENT),
0252     MT6360_ADC_CHAN(CHG_VDDP, IIO_VOLTAGE),
0253     MT6360_ADC_CHAN(TEMP_JC, IIO_TEMP),
0254     MT6360_ADC_CHAN(VREF_TS, IIO_VOLTAGE),
0255     MT6360_ADC_CHAN(TS, IIO_VOLTAGE),
0256     IIO_CHAN_SOFT_TIMESTAMP(MT6360_CHAN_MAX),
0257 };
0258 
0259 static irqreturn_t mt6360_adc_trigger_handler(int irq, void *p)
0260 {
0261     struct iio_poll_func *pf = p;
0262     struct iio_dev *indio_dev = pf->indio_dev;
0263     struct mt6360_adc_data *mad = iio_priv(indio_dev);
0264     struct {
0265         u16 values[MT6360_CHAN_MAX];
0266         int64_t timestamp;
0267     } data __aligned(8);
0268     int i = 0, bit, val, ret;
0269 
0270     memset(&data, 0, sizeof(data));
0271     for_each_set_bit(bit, indio_dev->active_scan_mask, indio_dev->masklength) {
0272         ret = mt6360_adc_read_channel(mad, bit, &val);
0273         if (ret < 0) {
0274             dev_warn(&indio_dev->dev, "Failed to get channel %d conversion val\n", bit);
0275             goto out;
0276         }
0277 
0278         data.values[i++] = val;
0279     }
0280     iio_push_to_buffers_with_timestamp(indio_dev, &data, iio_get_time_ns(indio_dev));
0281 out:
0282     iio_trigger_notify_done(indio_dev->trig);
0283 
0284     return IRQ_HANDLED;
0285 }
0286 
0287 static inline int mt6360_adc_reset(struct mt6360_adc_data *info)
0288 {
0289     __be16 adc_enable;
0290     ktime_t all_off_time;
0291     int i, ret;
0292 
0293     /* Clear ADC idle wait time to 0 */
0294     ret = regmap_write(info->regmap, MT6360_REG_PMUADCIDLET, 0);
0295     if (ret)
0296         return ret;
0297 
0298     /* Only keep ADC enable, but keep all channels off */
0299     adc_enable = cpu_to_be16(MT6360_ADCEN_MASK);
0300     ret = regmap_raw_write(info->regmap, MT6360_REG_PMUADCCFG, &adc_enable, sizeof(adc_enable));
0301     if (ret)
0302         return ret;
0303 
0304     /* Reset all channel off time to the current one */
0305     all_off_time = ktime_get();
0306     for (i = 0; i < MT6360_CHAN_MAX; i++)
0307         info->last_off_timestamps[i] = all_off_time;
0308 
0309     return 0;
0310 }
0311 
0312 static int mt6360_adc_probe(struct platform_device *pdev)
0313 {
0314     struct mt6360_adc_data *mad;
0315     struct regmap *regmap;
0316     struct iio_dev *indio_dev;
0317     int ret;
0318 
0319     regmap = dev_get_regmap(pdev->dev.parent, NULL);
0320     if (!regmap) {
0321         dev_err(&pdev->dev, "Failed to get parent regmap\n");
0322         return -ENODEV;
0323     }
0324 
0325     indio_dev = devm_iio_device_alloc(&pdev->dev, sizeof(*mad));
0326     if (!indio_dev)
0327         return -ENOMEM;
0328 
0329     mad = iio_priv(indio_dev);
0330     mad->dev = &pdev->dev;
0331     mad->regmap = regmap;
0332     mutex_init(&mad->adc_lock);
0333 
0334     ret = mt6360_adc_reset(mad);
0335     if (ret < 0) {
0336         dev_err(&pdev->dev, "Failed to reset adc\n");
0337         return ret;
0338     }
0339 
0340     indio_dev->name = dev_name(&pdev->dev);
0341     indio_dev->info = &mt6360_adc_iio_info;
0342     indio_dev->modes = INDIO_DIRECT_MODE;
0343     indio_dev->channels = mt6360_adc_channels;
0344     indio_dev->num_channels = ARRAY_SIZE(mt6360_adc_channels);
0345 
0346     ret = devm_iio_triggered_buffer_setup(&pdev->dev, indio_dev, NULL,
0347                           mt6360_adc_trigger_handler, NULL);
0348     if (ret) {
0349         dev_err(&pdev->dev, "Failed to allocate iio trigger buffer\n");
0350         return ret;
0351     }
0352 
0353     return devm_iio_device_register(&pdev->dev, indio_dev);
0354 }
0355 
0356 static const struct of_device_id __maybe_unused mt6360_adc_of_id[] = {
0357     { .compatible = "mediatek,mt6360-adc", },
0358     {}
0359 };
0360 MODULE_DEVICE_TABLE(of, mt6360_adc_of_id);
0361 
0362 static struct platform_driver mt6360_adc_driver = {
0363     .driver = {
0364         .name = "mt6360-adc",
0365         .of_match_table = mt6360_adc_of_id,
0366     },
0367     .probe = mt6360_adc_probe,
0368 };
0369 module_platform_driver(mt6360_adc_driver);
0370 
0371 MODULE_AUTHOR("Gene Chen <gene_chen@richtek.com>");
0372 MODULE_DESCRIPTION("MT6360 ADC Driver");
0373 MODULE_LICENSE("GPL v2");