Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-only
0002 /*
0003  * palmas-adc.c -- TI PALMAS GPADC.
0004  *
0005  * Copyright (c) 2013, NVIDIA Corporation. All rights reserved.
0006  *
0007  * Author: Pradeep Goudagunta <pgoudagunta@nvidia.com>
0008  */
0009 
0010 #include <linux/module.h>
0011 #include <linux/err.h>
0012 #include <linux/irq.h>
0013 #include <linux/interrupt.h>
0014 #include <linux/platform_device.h>
0015 #include <linux/slab.h>
0016 #include <linux/delay.h>
0017 #include <linux/i2c.h>
0018 #include <linux/pm.h>
0019 #include <linux/mfd/palmas.h>
0020 #include <linux/completion.h>
0021 #include <linux/of.h>
0022 #include <linux/of_device.h>
0023 #include <linux/iio/iio.h>
0024 #include <linux/iio/machine.h>
0025 #include <linux/iio/driver.h>
0026 
0027 #define MOD_NAME "palmas-gpadc"
0028 #define PALMAS_ADC_CONVERSION_TIMEOUT   (msecs_to_jiffies(5000))
0029 #define PALMAS_TO_BE_CALCULATED 0
0030 #define PALMAS_GPADC_TRIMINVALID    -1
0031 
0032 struct palmas_gpadc_info {
0033 /* calibration codes and regs */
0034     int x1; /* lower ideal code */
0035     int x2; /* higher ideal code */
0036     int v1; /* expected lower volt reading */
0037     int v2; /* expected higher volt reading */
0038     u8 trim1_reg;   /* register number for lower trim */
0039     u8 trim2_reg;   /* register number for upper trim */
0040     int gain;   /* calculated from above (after reading trim regs) */
0041     int offset; /* calculated from above (after reading trim regs) */
0042     int gain_error; /* calculated from above (after reading trim regs) */
0043     bool is_uncalibrated;   /* if channel has calibration data */
0044 };
0045 
0046 #define PALMAS_ADC_INFO(_chan, _x1, _x2, _v1, _v2, _t1, _t2, _is_uncalibrated) \
0047     [PALMAS_ADC_CH_##_chan] = { \
0048         .x1 = _x1, \
0049         .x2 = _x2, \
0050         .v1 = _v1, \
0051         .v2 = _v2, \
0052         .gain = PALMAS_TO_BE_CALCULATED, \
0053         .offset = PALMAS_TO_BE_CALCULATED, \
0054         .gain_error = PALMAS_TO_BE_CALCULATED, \
0055         .trim1_reg = PALMAS_GPADC_TRIM##_t1, \
0056         .trim2_reg = PALMAS_GPADC_TRIM##_t2,  \
0057         .is_uncalibrated = _is_uncalibrated \
0058     }
0059 
0060 static struct palmas_gpadc_info palmas_gpadc_info[] = {
0061     PALMAS_ADC_INFO(IN0, 2064, 3112, 630, 950, 1, 2, false),
0062     PALMAS_ADC_INFO(IN1, 2064, 3112, 630, 950, 1, 2, false),
0063     PALMAS_ADC_INFO(IN2, 2064, 3112, 1260, 1900, 3, 4, false),
0064     PALMAS_ADC_INFO(IN3, 2064, 3112, 630, 950, 1, 2, false),
0065     PALMAS_ADC_INFO(IN4, 2064, 3112, 630, 950, 1, 2, false),
0066     PALMAS_ADC_INFO(IN5, 2064, 3112, 630, 950, 1, 2, false),
0067     PALMAS_ADC_INFO(IN6, 2064, 3112, 2520, 3800, 5, 6, false),
0068     PALMAS_ADC_INFO(IN7, 2064, 3112, 2520, 3800, 7, 8, false),
0069     PALMAS_ADC_INFO(IN8, 2064, 3112, 3150, 4750, 9, 10, false),
0070     PALMAS_ADC_INFO(IN9, 2064, 3112, 5670, 8550, 11, 12, false),
0071     PALMAS_ADC_INFO(IN10, 2064, 3112, 3465, 5225, 13, 14, false),
0072     PALMAS_ADC_INFO(IN11, 0, 0, 0, 0, INVALID, INVALID, true),
0073     PALMAS_ADC_INFO(IN12, 0, 0, 0, 0, INVALID, INVALID, true),
0074     PALMAS_ADC_INFO(IN13, 0, 0, 0, 0, INVALID, INVALID, true),
0075     PALMAS_ADC_INFO(IN14, 2064, 3112, 3645, 5225, 15, 16, false),
0076     PALMAS_ADC_INFO(IN15, 0, 0, 0, 0, INVALID, INVALID, true),
0077 };
0078 
0079 /*
0080  * struct palmas_gpadc - the palmas_gpadc structure
0081  * @ch0_current:    channel 0 current source setting
0082  *          0: 0 uA
0083  *          1: 5 uA
0084  *          2: 15 uA
0085  *          3: 20 uA
0086  * @ch3_current:    channel 0 current source setting
0087  *          0: 0 uA
0088  *          1: 10 uA
0089  *          2: 400 uA
0090  *          3: 800 uA
0091  * @extended_delay: enable the gpadc extended delay mode
0092  * @auto_conversion_period: define the auto_conversion_period
0093  * @lock:   Lock to protect the device state during a potential concurrent
0094  *      read access from userspace. Reading a raw value requires a sequence
0095  *      of register writes, then a wait for a completion callback,
0096  *      and finally a register read, during which userspace could issue
0097  *      another read request. This lock protects a read access from
0098  *      ocurring before another one has finished.
0099  *
0100  * This is the palmas_gpadc structure to store run-time information
0101  * and pointers for this driver instance.
0102  */
0103 struct palmas_gpadc {
0104     struct device           *dev;
0105     struct palmas           *palmas;
0106     u8              ch0_current;
0107     u8              ch3_current;
0108     bool                extended_delay;
0109     int             irq;
0110     int             irq_auto_0;
0111     int             irq_auto_1;
0112     struct palmas_gpadc_info    *adc_info;
0113     struct completion       conv_completion;
0114     struct palmas_adc_wakeup_property wakeup1_data;
0115     struct palmas_adc_wakeup_property wakeup2_data;
0116     bool                wakeup1_enable;
0117     bool                wakeup2_enable;
0118     int             auto_conversion_period;
0119     struct mutex            lock;
0120 };
0121 
0122 /*
0123  * GPADC lock issue in AUTO mode.
0124  * Impact: In AUTO mode, GPADC conversion can be locked after disabling AUTO
0125  *     mode feature.
0126  * Details:
0127  *  When the AUTO mode is the only conversion mode enabled, if the AUTO
0128  *  mode feature is disabled with bit GPADC_AUTO_CTRL.  AUTO_CONV1_EN = 0
0129  *  or bit GPADC_AUTO_CTRL.  AUTO_CONV0_EN = 0 during a conversion, the
0130  *  conversion mechanism can be seen as locked meaning that all following
0131  *  conversion will give 0 as a result.  Bit GPADC_STATUS.GPADC_AVAILABLE
0132  *  will stay at 0 meaning that GPADC is busy.  An RT conversion can unlock
0133  *  the GPADC.
0134  *
0135  * Workaround(s):
0136  *  To avoid the lock mechanism, the workaround to follow before any stop
0137  *  conversion request is:
0138  *  Force the GPADC state machine to be ON by using the GPADC_CTRL1.
0139  *      GPADC_FORCE bit = 1
0140  *  Shutdown the GPADC AUTO conversion using
0141  *      GPADC_AUTO_CTRL.SHUTDOWN_CONV[01] = 0.
0142  *  After 100us, force the GPADC state machine to be OFF by using the
0143  *      GPADC_CTRL1.  GPADC_FORCE bit = 0
0144  */
0145 
0146 static int palmas_disable_auto_conversion(struct palmas_gpadc *adc)
0147 {
0148     int ret;
0149 
0150     ret = palmas_update_bits(adc->palmas, PALMAS_GPADC_BASE,
0151             PALMAS_GPADC_CTRL1,
0152             PALMAS_GPADC_CTRL1_GPADC_FORCE,
0153             PALMAS_GPADC_CTRL1_GPADC_FORCE);
0154     if (ret < 0) {
0155         dev_err(adc->dev, "GPADC_CTRL1 update failed: %d\n", ret);
0156         return ret;
0157     }
0158 
0159     ret = palmas_update_bits(adc->palmas, PALMAS_GPADC_BASE,
0160             PALMAS_GPADC_AUTO_CTRL,
0161             PALMAS_GPADC_AUTO_CTRL_SHUTDOWN_CONV1 |
0162             PALMAS_GPADC_AUTO_CTRL_SHUTDOWN_CONV0,
0163             0);
0164     if (ret < 0) {
0165         dev_err(adc->dev, "AUTO_CTRL update failed: %d\n", ret);
0166         return ret;
0167     }
0168 
0169     udelay(100);
0170 
0171     ret = palmas_update_bits(adc->palmas, PALMAS_GPADC_BASE,
0172             PALMAS_GPADC_CTRL1,
0173             PALMAS_GPADC_CTRL1_GPADC_FORCE, 0);
0174     if (ret < 0)
0175         dev_err(adc->dev, "GPADC_CTRL1 update failed: %d\n", ret);
0176 
0177     return ret;
0178 }
0179 
0180 static irqreturn_t palmas_gpadc_irq(int irq, void *data)
0181 {
0182     struct palmas_gpadc *adc = data;
0183 
0184     complete(&adc->conv_completion);
0185 
0186     return IRQ_HANDLED;
0187 }
0188 
0189 static irqreturn_t palmas_gpadc_irq_auto(int irq, void *data)
0190 {
0191     struct palmas_gpadc *adc = data;
0192 
0193     dev_dbg(adc->dev, "Threshold interrupt %d occurs\n", irq);
0194     palmas_disable_auto_conversion(adc);
0195 
0196     return IRQ_HANDLED;
0197 }
0198 
0199 static int palmas_gpadc_start_mask_interrupt(struct palmas_gpadc *adc,
0200                         bool mask)
0201 {
0202     int ret;
0203 
0204     if (!mask)
0205         ret = palmas_update_bits(adc->palmas, PALMAS_INTERRUPT_BASE,
0206                     PALMAS_INT3_MASK,
0207                     PALMAS_INT3_MASK_GPADC_EOC_SW, 0);
0208     else
0209         ret = palmas_update_bits(adc->palmas, PALMAS_INTERRUPT_BASE,
0210                     PALMAS_INT3_MASK,
0211                     PALMAS_INT3_MASK_GPADC_EOC_SW,
0212                     PALMAS_INT3_MASK_GPADC_EOC_SW);
0213     if (ret < 0)
0214         dev_err(adc->dev, "GPADC INT MASK update failed: %d\n", ret);
0215 
0216     return ret;
0217 }
0218 
0219 static int palmas_gpadc_enable(struct palmas_gpadc *adc, int adc_chan,
0220                    int enable)
0221 {
0222     unsigned int mask, val;
0223     int ret;
0224 
0225     if (enable) {
0226         val = (adc->extended_delay
0227             << PALMAS_GPADC_RT_CTRL_EXTEND_DELAY_SHIFT);
0228         ret = palmas_update_bits(adc->palmas, PALMAS_GPADC_BASE,
0229                     PALMAS_GPADC_RT_CTRL,
0230                     PALMAS_GPADC_RT_CTRL_EXTEND_DELAY, val);
0231         if (ret < 0) {
0232             dev_err(adc->dev, "RT_CTRL update failed: %d\n", ret);
0233             return ret;
0234         }
0235 
0236         mask = (PALMAS_GPADC_CTRL1_CURRENT_SRC_CH0_MASK |
0237             PALMAS_GPADC_CTRL1_CURRENT_SRC_CH3_MASK |
0238             PALMAS_GPADC_CTRL1_GPADC_FORCE);
0239         val = (adc->ch0_current
0240             << PALMAS_GPADC_CTRL1_CURRENT_SRC_CH0_SHIFT);
0241         val |= (adc->ch3_current
0242             << PALMAS_GPADC_CTRL1_CURRENT_SRC_CH3_SHIFT);
0243         val |= PALMAS_GPADC_CTRL1_GPADC_FORCE;
0244         ret = palmas_update_bits(adc->palmas, PALMAS_GPADC_BASE,
0245                 PALMAS_GPADC_CTRL1, mask, val);
0246         if (ret < 0) {
0247             dev_err(adc->dev,
0248                 "Failed to update current setting: %d\n", ret);
0249             return ret;
0250         }
0251 
0252         mask = (PALMAS_GPADC_SW_SELECT_SW_CONV0_SEL_MASK |
0253             PALMAS_GPADC_SW_SELECT_SW_CONV_EN);
0254         val = (adc_chan | PALMAS_GPADC_SW_SELECT_SW_CONV_EN);
0255         ret = palmas_update_bits(adc->palmas, PALMAS_GPADC_BASE,
0256                 PALMAS_GPADC_SW_SELECT, mask, val);
0257         if (ret < 0) {
0258             dev_err(adc->dev, "SW_SELECT update failed: %d\n", ret);
0259             return ret;
0260         }
0261     } else {
0262         ret = palmas_write(adc->palmas, PALMAS_GPADC_BASE,
0263                 PALMAS_GPADC_SW_SELECT, 0);
0264         if (ret < 0)
0265             dev_err(adc->dev, "SW_SELECT write failed: %d\n", ret);
0266 
0267         ret = palmas_update_bits(adc->palmas, PALMAS_GPADC_BASE,
0268                 PALMAS_GPADC_CTRL1,
0269                 PALMAS_GPADC_CTRL1_GPADC_FORCE, 0);
0270         if (ret < 0) {
0271             dev_err(adc->dev, "CTRL1 update failed: %d\n", ret);
0272             return ret;
0273         }
0274     }
0275 
0276     return ret;
0277 }
0278 
0279 static int palmas_gpadc_read_prepare(struct palmas_gpadc *adc, int adc_chan)
0280 {
0281     int ret;
0282 
0283     ret = palmas_gpadc_enable(adc, adc_chan, true);
0284     if (ret < 0)
0285         return ret;
0286 
0287     return palmas_gpadc_start_mask_interrupt(adc, 0);
0288 }
0289 
0290 static void palmas_gpadc_read_done(struct palmas_gpadc *adc, int adc_chan)
0291 {
0292     palmas_gpadc_start_mask_interrupt(adc, 1);
0293     palmas_gpadc_enable(adc, adc_chan, false);
0294 }
0295 
0296 static int palmas_gpadc_calibrate(struct palmas_gpadc *adc, int adc_chan)
0297 {
0298     int k;
0299     int d1;
0300     int d2;
0301     int ret;
0302     int gain;
0303     int x1 =  adc->adc_info[adc_chan].x1;
0304     int x2 =  adc->adc_info[adc_chan].x2;
0305     int v1 = adc->adc_info[adc_chan].v1;
0306     int v2 = adc->adc_info[adc_chan].v2;
0307 
0308     ret = palmas_read(adc->palmas, PALMAS_TRIM_GPADC_BASE,
0309                 adc->adc_info[adc_chan].trim1_reg, &d1);
0310     if (ret < 0) {
0311         dev_err(adc->dev, "TRIM read failed: %d\n", ret);
0312         goto scrub;
0313     }
0314 
0315     ret = palmas_read(adc->palmas, PALMAS_TRIM_GPADC_BASE,
0316                 adc->adc_info[adc_chan].trim2_reg, &d2);
0317     if (ret < 0) {
0318         dev_err(adc->dev, "TRIM read failed: %d\n", ret);
0319         goto scrub;
0320     }
0321 
0322     /* gain error calculation */
0323     k = (1000 + (1000 * (d2 - d1)) / (x2 - x1));
0324 
0325     /* gain calculation */
0326     gain = ((v2 - v1) * 1000) / (x2 - x1);
0327 
0328     adc->adc_info[adc_chan].gain_error = k;
0329     adc->adc_info[adc_chan].gain = gain;
0330     /* offset Calculation */
0331     adc->adc_info[adc_chan].offset = (d1 * 1000) - ((k - 1000) * x1);
0332 
0333 scrub:
0334     return ret;
0335 }
0336 
0337 static int palmas_gpadc_start_conversion(struct palmas_gpadc *adc, int adc_chan)
0338 {
0339     unsigned int val;
0340     int ret;
0341 
0342     init_completion(&adc->conv_completion);
0343     ret = palmas_update_bits(adc->palmas, PALMAS_GPADC_BASE,
0344                 PALMAS_GPADC_SW_SELECT,
0345                 PALMAS_GPADC_SW_SELECT_SW_START_CONV0,
0346                 PALMAS_GPADC_SW_SELECT_SW_START_CONV0);
0347     if (ret < 0) {
0348         dev_err(adc->dev, "SELECT_SW_START write failed: %d\n", ret);
0349         return ret;
0350     }
0351 
0352     ret = wait_for_completion_timeout(&adc->conv_completion,
0353                 PALMAS_ADC_CONVERSION_TIMEOUT);
0354     if (ret == 0) {
0355         dev_err(adc->dev, "conversion not completed\n");
0356         return -ETIMEDOUT;
0357     }
0358 
0359     ret = palmas_bulk_read(adc->palmas, PALMAS_GPADC_BASE,
0360                 PALMAS_GPADC_SW_CONV0_LSB, &val, 2);
0361     if (ret < 0) {
0362         dev_err(adc->dev, "SW_CONV0_LSB read failed: %d\n", ret);
0363         return ret;
0364     }
0365 
0366     ret = val & 0xFFF;
0367 
0368     return ret;
0369 }
0370 
0371 static int palmas_gpadc_get_calibrated_code(struct palmas_gpadc *adc,
0372                         int adc_chan, int val)
0373 {
0374     if (!adc->adc_info[adc_chan].is_uncalibrated)
0375         val  = (val*1000 - adc->adc_info[adc_chan].offset) /
0376                     adc->adc_info[adc_chan].gain_error;
0377 
0378     if (val < 0) {
0379         if (val < -10)
0380             dev_err(adc->dev, "Mismatch with calibration var = %d\n", val);
0381         return 0;
0382     }
0383 
0384     val = (val * adc->adc_info[adc_chan].gain) / 1000;
0385 
0386     return val;
0387 }
0388 
0389 static int palmas_gpadc_read_raw(struct iio_dev *indio_dev,
0390     struct iio_chan_spec const *chan, int *val, int *val2, long mask)
0391 {
0392     struct  palmas_gpadc *adc = iio_priv(indio_dev);
0393     int adc_chan = chan->channel;
0394     int ret = 0;
0395 
0396     if (adc_chan > PALMAS_ADC_CH_MAX)
0397         return -EINVAL;
0398 
0399     mutex_lock(&adc->lock);
0400 
0401     switch (mask) {
0402     case IIO_CHAN_INFO_RAW:
0403     case IIO_CHAN_INFO_PROCESSED:
0404         ret = palmas_gpadc_read_prepare(adc, adc_chan);
0405         if (ret < 0)
0406             goto out;
0407 
0408         ret = palmas_gpadc_start_conversion(adc, adc_chan);
0409         if (ret < 0) {
0410             dev_err(adc->dev,
0411             "ADC start conversion failed\n");
0412             goto out;
0413         }
0414 
0415         if (mask == IIO_CHAN_INFO_PROCESSED)
0416             ret = palmas_gpadc_get_calibrated_code(
0417                             adc, adc_chan, ret);
0418 
0419         *val = ret;
0420 
0421         ret = IIO_VAL_INT;
0422         goto out;
0423     }
0424 
0425     mutex_unlock(&adc->lock);
0426     return ret;
0427 
0428 out:
0429     palmas_gpadc_read_done(adc, adc_chan);
0430     mutex_unlock(&adc->lock);
0431 
0432     return ret;
0433 }
0434 
0435 static const struct iio_info palmas_gpadc_iio_info = {
0436     .read_raw = palmas_gpadc_read_raw,
0437 };
0438 
0439 #define PALMAS_ADC_CHAN_IIO(chan, _type, chan_info) \
0440 {                           \
0441     .datasheet_name = PALMAS_DATASHEET_NAME(chan),  \
0442     .type = _type,                  \
0443     .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |  \
0444             BIT(chan_info),         \
0445     .indexed = 1,                   \
0446     .channel = PALMAS_ADC_CH_##chan,        \
0447 }
0448 
0449 static const struct iio_chan_spec palmas_gpadc_iio_channel[] = {
0450     PALMAS_ADC_CHAN_IIO(IN0, IIO_VOLTAGE, IIO_CHAN_INFO_PROCESSED),
0451     PALMAS_ADC_CHAN_IIO(IN1, IIO_TEMP, IIO_CHAN_INFO_RAW),
0452     PALMAS_ADC_CHAN_IIO(IN2, IIO_VOLTAGE, IIO_CHAN_INFO_PROCESSED),
0453     PALMAS_ADC_CHAN_IIO(IN3, IIO_TEMP, IIO_CHAN_INFO_RAW),
0454     PALMAS_ADC_CHAN_IIO(IN4, IIO_VOLTAGE, IIO_CHAN_INFO_PROCESSED),
0455     PALMAS_ADC_CHAN_IIO(IN5, IIO_VOLTAGE, IIO_CHAN_INFO_PROCESSED),
0456     PALMAS_ADC_CHAN_IIO(IN6, IIO_VOLTAGE, IIO_CHAN_INFO_PROCESSED),
0457     PALMAS_ADC_CHAN_IIO(IN7, IIO_VOLTAGE, IIO_CHAN_INFO_PROCESSED),
0458     PALMAS_ADC_CHAN_IIO(IN8, IIO_VOLTAGE, IIO_CHAN_INFO_PROCESSED),
0459     PALMAS_ADC_CHAN_IIO(IN9, IIO_VOLTAGE, IIO_CHAN_INFO_PROCESSED),
0460     PALMAS_ADC_CHAN_IIO(IN10, IIO_VOLTAGE, IIO_CHAN_INFO_PROCESSED),
0461     PALMAS_ADC_CHAN_IIO(IN11, IIO_VOLTAGE, IIO_CHAN_INFO_PROCESSED),
0462     PALMAS_ADC_CHAN_IIO(IN12, IIO_TEMP, IIO_CHAN_INFO_RAW),
0463     PALMAS_ADC_CHAN_IIO(IN13, IIO_TEMP, IIO_CHAN_INFO_RAW),
0464     PALMAS_ADC_CHAN_IIO(IN14, IIO_VOLTAGE, IIO_CHAN_INFO_PROCESSED),
0465     PALMAS_ADC_CHAN_IIO(IN15, IIO_VOLTAGE, IIO_CHAN_INFO_PROCESSED),
0466 };
0467 
0468 static int palmas_gpadc_get_adc_dt_data(struct platform_device *pdev,
0469     struct palmas_gpadc_platform_data **gpadc_pdata)
0470 {
0471     struct device_node *np = pdev->dev.of_node;
0472     struct palmas_gpadc_platform_data *gp_data;
0473     int ret;
0474     u32 pval;
0475 
0476     gp_data = devm_kzalloc(&pdev->dev, sizeof(*gp_data), GFP_KERNEL);
0477     if (!gp_data)
0478         return -ENOMEM;
0479 
0480     ret = of_property_read_u32(np, "ti,channel0-current-microamp", &pval);
0481     if (!ret)
0482         gp_data->ch0_current = pval;
0483 
0484     ret = of_property_read_u32(np, "ti,channel3-current-microamp", &pval);
0485     if (!ret)
0486         gp_data->ch3_current = pval;
0487 
0488     gp_data->extended_delay = of_property_read_bool(np,
0489                     "ti,enable-extended-delay");
0490 
0491     *gpadc_pdata = gp_data;
0492 
0493     return 0;
0494 }
0495 
0496 static int palmas_gpadc_probe(struct platform_device *pdev)
0497 {
0498     struct palmas_gpadc *adc;
0499     struct palmas_platform_data *pdata;
0500     struct palmas_gpadc_platform_data *gpadc_pdata = NULL;
0501     struct iio_dev *indio_dev;
0502     int ret, i;
0503 
0504     pdata = dev_get_platdata(pdev->dev.parent);
0505 
0506     if (pdata && pdata->gpadc_pdata)
0507         gpadc_pdata = pdata->gpadc_pdata;
0508 
0509     if (!gpadc_pdata && pdev->dev.of_node) {
0510         ret = palmas_gpadc_get_adc_dt_data(pdev, &gpadc_pdata);
0511         if (ret < 0)
0512             return ret;
0513     }
0514     if (!gpadc_pdata)
0515         return -EINVAL;
0516 
0517     indio_dev = devm_iio_device_alloc(&pdev->dev, sizeof(*adc));
0518     if (!indio_dev) {
0519         dev_err(&pdev->dev, "iio_device_alloc failed\n");
0520         return -ENOMEM;
0521     }
0522 
0523     adc = iio_priv(indio_dev);
0524     adc->dev = &pdev->dev;
0525     adc->palmas = dev_get_drvdata(pdev->dev.parent);
0526     adc->adc_info = palmas_gpadc_info;
0527 
0528     mutex_init(&adc->lock);
0529 
0530     init_completion(&adc->conv_completion);
0531     platform_set_drvdata(pdev, indio_dev);
0532 
0533     adc->auto_conversion_period = gpadc_pdata->auto_conversion_period_ms;
0534     adc->irq = palmas_irq_get_virq(adc->palmas, PALMAS_GPADC_EOC_SW_IRQ);
0535     if (adc->irq < 0) {
0536         dev_err(adc->dev,
0537             "get virq failed: %d\n", adc->irq);
0538         ret = adc->irq;
0539         goto out;
0540     }
0541     ret = request_threaded_irq(adc->irq, NULL,
0542         palmas_gpadc_irq,
0543         IRQF_ONESHOT, dev_name(adc->dev),
0544         adc);
0545     if (ret < 0) {
0546         dev_err(adc->dev,
0547             "request irq %d failed: %d\n", adc->irq, ret);
0548         goto out;
0549     }
0550 
0551     if (gpadc_pdata->adc_wakeup1_data) {
0552         memcpy(&adc->wakeup1_data, gpadc_pdata->adc_wakeup1_data,
0553             sizeof(adc->wakeup1_data));
0554         adc->wakeup1_enable = true;
0555         adc->irq_auto_0 =  platform_get_irq(pdev, 1);
0556         ret = request_threaded_irq(adc->irq_auto_0, NULL,
0557                 palmas_gpadc_irq_auto,
0558                 IRQF_ONESHOT,
0559                 "palmas-adc-auto-0", adc);
0560         if (ret < 0) {
0561             dev_err(adc->dev, "request auto0 irq %d failed: %d\n",
0562                 adc->irq_auto_0, ret);
0563             goto out_irq_free;
0564         }
0565     }
0566 
0567     if (gpadc_pdata->adc_wakeup2_data) {
0568         memcpy(&adc->wakeup2_data, gpadc_pdata->adc_wakeup2_data,
0569                 sizeof(adc->wakeup2_data));
0570         adc->wakeup2_enable = true;
0571         adc->irq_auto_1 =  platform_get_irq(pdev, 2);
0572         ret = request_threaded_irq(adc->irq_auto_1, NULL,
0573                 palmas_gpadc_irq_auto,
0574                 IRQF_ONESHOT,
0575                 "palmas-adc-auto-1", adc);
0576         if (ret < 0) {
0577             dev_err(adc->dev, "request auto1 irq %d failed: %d\n",
0578                 adc->irq_auto_1, ret);
0579             goto out_irq_auto0_free;
0580         }
0581     }
0582 
0583     /* set the current source 0 (value 0/5/15/20 uA => 0..3) */
0584     if (gpadc_pdata->ch0_current <= 1)
0585         adc->ch0_current = PALMAS_ADC_CH0_CURRENT_SRC_0;
0586     else if (gpadc_pdata->ch0_current <= 5)
0587         adc->ch0_current = PALMAS_ADC_CH0_CURRENT_SRC_5;
0588     else if (gpadc_pdata->ch0_current <= 15)
0589         adc->ch0_current = PALMAS_ADC_CH0_CURRENT_SRC_15;
0590     else
0591         adc->ch0_current = PALMAS_ADC_CH0_CURRENT_SRC_20;
0592 
0593     /* set the current source 3 (value 0/10/400/800 uA => 0..3) */
0594     if (gpadc_pdata->ch3_current <= 1)
0595         adc->ch3_current = PALMAS_ADC_CH3_CURRENT_SRC_0;
0596     else if (gpadc_pdata->ch3_current <= 10)
0597         adc->ch3_current = PALMAS_ADC_CH3_CURRENT_SRC_10;
0598     else if (gpadc_pdata->ch3_current <= 400)
0599         adc->ch3_current = PALMAS_ADC_CH3_CURRENT_SRC_400;
0600     else
0601         adc->ch3_current = PALMAS_ADC_CH3_CURRENT_SRC_800;
0602 
0603     adc->extended_delay = gpadc_pdata->extended_delay;
0604 
0605     indio_dev->name = MOD_NAME;
0606     indio_dev->info = &palmas_gpadc_iio_info;
0607     indio_dev->modes = INDIO_DIRECT_MODE;
0608     indio_dev->channels = palmas_gpadc_iio_channel;
0609     indio_dev->num_channels = ARRAY_SIZE(palmas_gpadc_iio_channel);
0610 
0611     ret = iio_device_register(indio_dev);
0612     if (ret < 0) {
0613         dev_err(adc->dev, "iio_device_register() failed: %d\n", ret);
0614         goto out_irq_auto1_free;
0615     }
0616 
0617     device_set_wakeup_capable(&pdev->dev, 1);
0618     for (i = 0; i < PALMAS_ADC_CH_MAX; i++) {
0619         if (!(adc->adc_info[i].is_uncalibrated))
0620             palmas_gpadc_calibrate(adc, i);
0621     }
0622 
0623     if (adc->wakeup1_enable || adc->wakeup2_enable)
0624         device_wakeup_enable(&pdev->dev);
0625 
0626     return 0;
0627 
0628 out_irq_auto1_free:
0629     if (gpadc_pdata->adc_wakeup2_data)
0630         free_irq(adc->irq_auto_1, adc);
0631 out_irq_auto0_free:
0632     if (gpadc_pdata->adc_wakeup1_data)
0633         free_irq(adc->irq_auto_0, adc);
0634 out_irq_free:
0635     free_irq(adc->irq, adc);
0636 out:
0637     return ret;
0638 }
0639 
0640 static int palmas_gpadc_remove(struct platform_device *pdev)
0641 {
0642     struct iio_dev *indio_dev = dev_to_iio_dev(&pdev->dev);
0643     struct palmas_gpadc *adc = iio_priv(indio_dev);
0644 
0645     if (adc->wakeup1_enable || adc->wakeup2_enable)
0646         device_wakeup_disable(&pdev->dev);
0647     iio_device_unregister(indio_dev);
0648     free_irq(adc->irq, adc);
0649     if (adc->wakeup1_enable)
0650         free_irq(adc->irq_auto_0, adc);
0651     if (adc->wakeup2_enable)
0652         free_irq(adc->irq_auto_1, adc);
0653 
0654     return 0;
0655 }
0656 
0657 static int palmas_adc_wakeup_configure(struct palmas_gpadc *adc)
0658 {
0659     int adc_period, conv;
0660     int i;
0661     int ch0 = 0, ch1 = 0;
0662     int thres;
0663     int ret;
0664 
0665     adc_period = adc->auto_conversion_period;
0666     for (i = 0; i < 16; ++i) {
0667         if (((1000 * (1 << i)) / 32) >= adc_period)
0668             break;
0669     }
0670     if (i > 0)
0671         i--;
0672     adc_period = i;
0673     ret = palmas_update_bits(adc->palmas, PALMAS_GPADC_BASE,
0674             PALMAS_GPADC_AUTO_CTRL,
0675             PALMAS_GPADC_AUTO_CTRL_COUNTER_CONV_MASK,
0676             adc_period);
0677     if (ret < 0) {
0678         dev_err(adc->dev, "AUTO_CTRL write failed: %d\n", ret);
0679         return ret;
0680     }
0681 
0682     conv = 0;
0683     if (adc->wakeup1_enable) {
0684         int polarity;
0685 
0686         ch0 = adc->wakeup1_data.adc_channel_number;
0687         conv |= PALMAS_GPADC_AUTO_CTRL_AUTO_CONV0_EN;
0688         if (adc->wakeup1_data.adc_high_threshold > 0) {
0689             thres = adc->wakeup1_data.adc_high_threshold;
0690             polarity = 0;
0691         } else {
0692             thres = adc->wakeup1_data.adc_low_threshold;
0693             polarity = PALMAS_GPADC_THRES_CONV0_MSB_THRES_CONV0_POL;
0694         }
0695 
0696         ret = palmas_write(adc->palmas, PALMAS_GPADC_BASE,
0697                 PALMAS_GPADC_THRES_CONV0_LSB, thres & 0xFF);
0698         if (ret < 0) {
0699             dev_err(adc->dev,
0700                 "THRES_CONV0_LSB write failed: %d\n", ret);
0701             return ret;
0702         }
0703 
0704         ret = palmas_write(adc->palmas, PALMAS_GPADC_BASE,
0705                 PALMAS_GPADC_THRES_CONV0_MSB,
0706                 ((thres >> 8) & 0xF) | polarity);
0707         if (ret < 0) {
0708             dev_err(adc->dev,
0709                 "THRES_CONV0_MSB write failed: %d\n", ret);
0710             return ret;
0711         }
0712     }
0713 
0714     if (adc->wakeup2_enable) {
0715         int polarity;
0716 
0717         ch1 = adc->wakeup2_data.adc_channel_number;
0718         conv |= PALMAS_GPADC_AUTO_CTRL_AUTO_CONV1_EN;
0719         if (adc->wakeup2_data.adc_high_threshold > 0) {
0720             thres = adc->wakeup2_data.adc_high_threshold;
0721             polarity = 0;
0722         } else {
0723             thres = adc->wakeup2_data.adc_low_threshold;
0724             polarity = PALMAS_GPADC_THRES_CONV1_MSB_THRES_CONV1_POL;
0725         }
0726 
0727         ret = palmas_write(adc->palmas, PALMAS_GPADC_BASE,
0728                 PALMAS_GPADC_THRES_CONV1_LSB, thres & 0xFF);
0729         if (ret < 0) {
0730             dev_err(adc->dev,
0731                 "THRES_CONV1_LSB write failed: %d\n", ret);
0732             return ret;
0733         }
0734 
0735         ret = palmas_write(adc->palmas, PALMAS_GPADC_BASE,
0736                 PALMAS_GPADC_THRES_CONV1_MSB,
0737                 ((thres >> 8) & 0xF) | polarity);
0738         if (ret < 0) {
0739             dev_err(adc->dev,
0740                 "THRES_CONV1_MSB write failed: %d\n", ret);
0741             return ret;
0742         }
0743     }
0744 
0745     ret = palmas_write(adc->palmas, PALMAS_GPADC_BASE,
0746             PALMAS_GPADC_AUTO_SELECT, (ch1 << 4) | ch0);
0747     if (ret < 0) {
0748         dev_err(adc->dev, "AUTO_SELECT write failed: %d\n", ret);
0749         return ret;
0750     }
0751 
0752     ret = palmas_update_bits(adc->palmas, PALMAS_GPADC_BASE,
0753             PALMAS_GPADC_AUTO_CTRL,
0754             PALMAS_GPADC_AUTO_CTRL_AUTO_CONV1_EN |
0755             PALMAS_GPADC_AUTO_CTRL_AUTO_CONV0_EN, conv);
0756     if (ret < 0)
0757         dev_err(adc->dev, "AUTO_CTRL write failed: %d\n", ret);
0758 
0759     return ret;
0760 }
0761 
0762 static int palmas_adc_wakeup_reset(struct palmas_gpadc *adc)
0763 {
0764     int ret;
0765 
0766     ret = palmas_write(adc->palmas, PALMAS_GPADC_BASE,
0767             PALMAS_GPADC_AUTO_SELECT, 0);
0768     if (ret < 0) {
0769         dev_err(adc->dev, "AUTO_SELECT write failed: %d\n", ret);
0770         return ret;
0771     }
0772 
0773     ret = palmas_disable_auto_conversion(adc);
0774     if (ret < 0)
0775         dev_err(adc->dev, "Disable auto conversion failed: %d\n", ret);
0776 
0777     return ret;
0778 }
0779 
0780 static int palmas_gpadc_suspend(struct device *dev)
0781 {
0782     struct iio_dev *indio_dev = dev_get_drvdata(dev);
0783     struct palmas_gpadc *adc = iio_priv(indio_dev);
0784     int wakeup = adc->wakeup1_enable || adc->wakeup2_enable;
0785     int ret;
0786 
0787     if (!device_may_wakeup(dev) || !wakeup)
0788         return 0;
0789 
0790     ret = palmas_adc_wakeup_configure(adc);
0791     if (ret < 0)
0792         return ret;
0793 
0794     if (adc->wakeup1_enable)
0795         enable_irq_wake(adc->irq_auto_0);
0796 
0797     if (adc->wakeup2_enable)
0798         enable_irq_wake(adc->irq_auto_1);
0799 
0800     return 0;
0801 }
0802 
0803 static int palmas_gpadc_resume(struct device *dev)
0804 {
0805     struct iio_dev *indio_dev = dev_get_drvdata(dev);
0806     struct palmas_gpadc *adc = iio_priv(indio_dev);
0807     int wakeup = adc->wakeup1_enable || adc->wakeup2_enable;
0808     int ret;
0809 
0810     if (!device_may_wakeup(dev) || !wakeup)
0811         return 0;
0812 
0813     ret = palmas_adc_wakeup_reset(adc);
0814     if (ret < 0)
0815         return ret;
0816 
0817     if (adc->wakeup1_enable)
0818         disable_irq_wake(adc->irq_auto_0);
0819 
0820     if (adc->wakeup2_enable)
0821         disable_irq_wake(adc->irq_auto_1);
0822 
0823     return 0;
0824 };
0825 
0826 static DEFINE_SIMPLE_DEV_PM_OPS(palmas_pm_ops, palmas_gpadc_suspend,
0827                 palmas_gpadc_resume);
0828 
0829 static const struct of_device_id of_palmas_gpadc_match_tbl[] = {
0830     { .compatible = "ti,palmas-gpadc", },
0831     { /* end */ }
0832 };
0833 MODULE_DEVICE_TABLE(of, of_palmas_gpadc_match_tbl);
0834 
0835 static struct platform_driver palmas_gpadc_driver = {
0836     .probe = palmas_gpadc_probe,
0837     .remove = palmas_gpadc_remove,
0838     .driver = {
0839         .name = MOD_NAME,
0840         .pm = pm_sleep_ptr(&palmas_pm_ops),
0841         .of_match_table = of_palmas_gpadc_match_tbl,
0842     },
0843 };
0844 module_platform_driver(palmas_gpadc_driver);
0845 
0846 MODULE_DESCRIPTION("palmas GPADC driver");
0847 MODULE_AUTHOR("Pradeep Goudagunta<pgoudagunta@nvidia.com>");
0848 MODULE_ALIAS("platform:palmas-gpadc");
0849 MODULE_LICENSE("GPL v2");