linux/drivers/iio/adc/ti_am335x_adc.c
<<
>>
Prefs
   1/*
   2 * TI ADC MFD driver
   3 *
   4 * Copyright (C) 2012 Texas Instruments Incorporated - http://www.ti.com/
   5 *
   6 * This program is free software; you can redistribute it and/or
   7 * modify it under the terms of the GNU General Public License as
   8 * published by the Free Software Foundation version 2.
   9 *
  10 * This program is distributed "as is" WITHOUT ANY WARRANTY of any
  11 * kind, whether express or implied; without even the implied warranty
  12 * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  13 * GNU General Public License for more details.
  14 */
  15
  16#include <linux/init.h>
  17#include <linux/kernel.h>
  18#include <linux/err.h>
  19#include <linux/module.h>
  20#include <linux/slab.h>
  21#include <linux/interrupt.h>
  22#include <linux/platform_device.h>
  23#include <linux/io.h>
  24#include <linux/iio/iio.h>
  25
  26#include <linux/mfd/ti_am335x_tscadc.h>
  27#include <linux/platform_data/ti_am335x_adc.h>
  28
  29struct tiadc_device {
  30        struct ti_tscadc_dev *mfd_tscadc;
  31        int channels;
  32};
  33
  34static unsigned int tiadc_readl(struct tiadc_device *adc, unsigned int reg)
  35{
  36        return readl(adc->mfd_tscadc->tscadc_base + reg);
  37}
  38
  39static void tiadc_writel(struct tiadc_device *adc, unsigned int reg,
  40                                        unsigned int val)
  41{
  42        writel(val, adc->mfd_tscadc->tscadc_base + reg);
  43}
  44
  45static void tiadc_step_config(struct tiadc_device *adc_dev)
  46{
  47        unsigned int stepconfig;
  48        int i, channels = 0, steps;
  49
  50        /*
  51         * There are 16 configurable steps and 8 analog input
  52         * lines available which are shared between Touchscreen and ADC.
  53         *
  54         * Steps backwards i.e. from 16 towards 0 are used by ADC
  55         * depending on number of input lines needed.
  56         * Channel would represent which analog input
  57         * needs to be given to ADC to digitalize data.
  58         */
  59
  60        steps = TOTAL_STEPS - adc_dev->channels;
  61        channels = TOTAL_CHANNELS - adc_dev->channels;
  62
  63        stepconfig = STEPCONFIG_AVG_16 | STEPCONFIG_FIFO1;
  64
  65        for (i = (steps + 1); i <= TOTAL_STEPS; i++) {
  66                tiadc_writel(adc_dev, REG_STEPCONFIG(i),
  67                                stepconfig | STEPCONFIG_INP(channels));
  68                tiadc_writel(adc_dev, REG_STEPDELAY(i),
  69                                STEPCONFIG_OPENDLY);
  70                channels++;
  71        }
  72        tiadc_writel(adc_dev, REG_SE, STPENB_STEPENB);
  73}
  74
  75static int tiadc_channel_init(struct iio_dev *indio_dev, int channels)
  76{
  77        struct iio_chan_spec *chan_array;
  78        int i;
  79
  80        indio_dev->num_channels = channels;
  81        chan_array = kcalloc(indio_dev->num_channels,
  82                        sizeof(struct iio_chan_spec), GFP_KERNEL);
  83
  84        if (chan_array == NULL)
  85                return -ENOMEM;
  86
  87        for (i = 0; i < (indio_dev->num_channels); i++) {
  88                struct iio_chan_spec *chan = chan_array + i;
  89                chan->type = IIO_VOLTAGE;
  90                chan->indexed = 1;
  91                chan->channel = i;
  92                chan->info_mask_separate = BIT(IIO_CHAN_INFO_RAW);
  93        }
  94
  95        indio_dev->channels = chan_array;
  96
  97        return indio_dev->num_channels;
  98}
  99
 100static void tiadc_channels_remove(struct iio_dev *indio_dev)
 101{
 102        kfree(indio_dev->channels);
 103}
 104
 105static int tiadc_read_raw(struct iio_dev *indio_dev,
 106                struct iio_chan_spec const *chan,
 107                int *val, int *val2, long mask)
 108{
 109        struct tiadc_device *adc_dev = iio_priv(indio_dev);
 110        int i;
 111        unsigned int fifo1count, readx1;
 112
 113        /*
 114         * When the sub-system is first enabled,
 115         * the sequencer will always start with the
 116         * lowest step (1) and continue until step (16).
 117         * For ex: If we have enabled 4 ADC channels and
 118         * currently use only 1 out of them, the
 119         * sequencer still configures all the 4 steps,
 120         * leading to 3 unwanted data.
 121         * Hence we need to flush out this data.
 122         */
 123
 124        fifo1count = tiadc_readl(adc_dev, REG_FIFO1CNT);
 125        for (i = 0; i < fifo1count; i++) {
 126                readx1 = tiadc_readl(adc_dev, REG_FIFO1);
 127                if (i == chan->channel)
 128                        *val = readx1 & 0xfff;
 129        }
 130        tiadc_writel(adc_dev, REG_SE, STPENB_STEPENB);
 131
 132        return IIO_VAL_INT;
 133}
 134
 135static const struct iio_info tiadc_info = {
 136        .read_raw = &tiadc_read_raw,
 137};
 138
 139static int tiadc_probe(struct platform_device *pdev)
 140{
 141        struct iio_dev          *indio_dev;
 142        struct tiadc_device     *adc_dev;
 143        struct ti_tscadc_dev    *tscadc_dev = pdev->dev.platform_data;
 144        struct mfd_tscadc_board *pdata;
 145        int                     err;
 146
 147        pdata = tscadc_dev->dev->platform_data;
 148        if (!pdata || !pdata->adc_init) {
 149                dev_err(&pdev->dev, "Could not find platform data\n");
 150                return -EINVAL;
 151        }
 152
 153        indio_dev = iio_device_alloc(sizeof(struct tiadc_device));
 154        if (indio_dev == NULL) {
 155                dev_err(&pdev->dev, "failed to allocate iio device\n");
 156                err = -ENOMEM;
 157                goto err_ret;
 158        }
 159        adc_dev = iio_priv(indio_dev);
 160
 161        adc_dev->mfd_tscadc = tscadc_dev;
 162        adc_dev->channels = pdata->adc_init->adc_channels;
 163
 164        indio_dev->dev.parent = &pdev->dev;
 165        indio_dev->name = dev_name(&pdev->dev);
 166        indio_dev->modes = INDIO_DIRECT_MODE;
 167        indio_dev->info = &tiadc_info;
 168
 169        tiadc_step_config(adc_dev);
 170
 171        err = tiadc_channel_init(indio_dev, adc_dev->channels);
 172        if (err < 0)
 173                goto err_free_device;
 174
 175        err = iio_device_register(indio_dev);
 176        if (err)
 177                goto err_free_channels;
 178
 179        platform_set_drvdata(pdev, indio_dev);
 180
 181        return 0;
 182
 183err_free_channels:
 184        tiadc_channels_remove(indio_dev);
 185err_free_device:
 186        iio_device_free(indio_dev);
 187err_ret:
 188        return err;
 189}
 190
 191static int tiadc_remove(struct platform_device *pdev)
 192{
 193        struct iio_dev *indio_dev = platform_get_drvdata(pdev);
 194
 195        iio_device_unregister(indio_dev);
 196        tiadc_channels_remove(indio_dev);
 197
 198        iio_device_free(indio_dev);
 199
 200        return 0;
 201}
 202
 203#ifdef CONFIG_PM
 204static int tiadc_suspend(struct device *dev)
 205{
 206        struct iio_dev *indio_dev = dev_get_drvdata(dev);
 207        struct tiadc_device *adc_dev = iio_priv(indio_dev);
 208        struct ti_tscadc_dev *tscadc_dev = dev->platform_data;
 209        unsigned int idle;
 210
 211        if (!device_may_wakeup(tscadc_dev->dev)) {
 212                idle = tiadc_readl(adc_dev, REG_CTRL);
 213                idle &= ~(CNTRLREG_TSCSSENB);
 214                tiadc_writel(adc_dev, REG_CTRL, (idle |
 215                                CNTRLREG_POWERDOWN));
 216        }
 217
 218        return 0;
 219}
 220
 221static int tiadc_resume(struct device *dev)
 222{
 223        struct iio_dev *indio_dev = dev_get_drvdata(dev);
 224        struct tiadc_device *adc_dev = iio_priv(indio_dev);
 225        unsigned int restore;
 226
 227        /* Make sure ADC is powered up */
 228        restore = tiadc_readl(adc_dev, REG_CTRL);
 229        restore &= ~(CNTRLREG_POWERDOWN);
 230        tiadc_writel(adc_dev, REG_CTRL, restore);
 231
 232        tiadc_step_config(adc_dev);
 233
 234        return 0;
 235}
 236
 237static const struct dev_pm_ops tiadc_pm_ops = {
 238        .suspend = tiadc_suspend,
 239        .resume = tiadc_resume,
 240};
 241#define TIADC_PM_OPS (&tiadc_pm_ops)
 242#else
 243#define TIADC_PM_OPS NULL
 244#endif
 245
 246static struct platform_driver tiadc_driver = {
 247        .driver = {
 248                .name   = "tiadc",
 249                .owner  = THIS_MODULE,
 250                .pm     = TIADC_PM_OPS,
 251        },
 252        .probe  = tiadc_probe,
 253        .remove = tiadc_remove,
 254};
 255
 256module_platform_driver(tiadc_driver);
 257
 258MODULE_DESCRIPTION("TI ADC controller driver");
 259MODULE_AUTHOR("Rachna Patil <rachna@ti.com>");
 260MODULE_LICENSE("GPL");
 261