linux/drivers/iio/adc/mcp320x.c
<<
>>
Prefs
   1/*
   2 * Copyright (C) 2013 Oskar Andero <oskar.andero@gmail.com>
   3 * Copyright (C) 2014 Rose Technology
   4 *         Allan Bendorff Jensen <abj@rosetechnology.dk>
   5 *         Soren Andersen <san@rosetechnology.dk>
   6 *
   7 * Driver for following ADC chips from Microchip Technology's:
   8 * 10 Bit converter
   9 * MCP3001
  10 * MCP3002
  11 * MCP3004
  12 * MCP3008
  13 * ------------
  14 * 12 bit converter
  15 * MCP3201
  16 * MCP3202
  17 * MCP3204
  18 * MCP3208
  19 * ------------
  20 *
  21 * Datasheet can be found here:
  22 * http://ww1.microchip.com/downloads/en/DeviceDoc/21293C.pdf  mcp3001
  23 * http://ww1.microchip.com/downloads/en/DeviceDoc/21294E.pdf  mcp3002
  24 * http://ww1.microchip.com/downloads/en/DeviceDoc/21295d.pdf  mcp3004/08
  25 * http://ww1.microchip.com/downloads/en/DeviceDoc/21290D.pdf  mcp3201
  26 * http://ww1.microchip.com/downloads/en/DeviceDoc/21034D.pdf  mcp3202
  27 * http://ww1.microchip.com/downloads/en/DeviceDoc/21298c.pdf  mcp3204/08
  28 * http://ww1.microchip.com/downloads/en/DeviceDoc/21700E.pdf  mcp3301
  29 *
  30 * This program is free software; you can redistribute it and/or modify
  31 * it under the terms of the GNU General Public License version 2 as
  32 * published by the Free Software Foundation.
  33 */
  34
  35#include <linux/err.h>
  36#include <linux/delay.h>
  37#include <linux/spi/spi.h>
  38#include <linux/module.h>
  39#include <linux/iio/iio.h>
  40#include <linux/regulator/consumer.h>
  41
  42enum {
  43        mcp3001,
  44        mcp3002,
  45        mcp3004,
  46        mcp3008,
  47        mcp3201,
  48        mcp3202,
  49        mcp3204,
  50        mcp3208,
  51        mcp3301,
  52};
  53
  54struct mcp320x_chip_info {
  55        const struct iio_chan_spec *channels;
  56        unsigned int num_channels;
  57        unsigned int resolution;
  58};
  59
  60struct mcp320x {
  61        struct spi_device *spi;
  62        struct spi_message msg;
  63        struct spi_transfer transfer[2];
  64
  65        struct regulator *reg;
  66        struct mutex lock;
  67        const struct mcp320x_chip_info *chip_info;
  68
  69        u8 tx_buf ____cacheline_aligned;
  70        u8 rx_buf[2];
  71};
  72
  73static int mcp320x_channel_to_tx_data(int device_index,
  74                        const unsigned int channel, bool differential)
  75{
  76        int start_bit = 1;
  77
  78        switch (device_index) {
  79        case mcp3001:
  80        case mcp3201:
  81        case mcp3301:
  82                return 0;
  83        case mcp3002:
  84        case mcp3202:
  85                return ((start_bit << 4) | (!differential << 3) |
  86                                                        (channel << 2));
  87        case mcp3004:
  88        case mcp3204:
  89        case mcp3008:
  90        case mcp3208:
  91                return ((start_bit << 6) | (!differential << 5) |
  92                                                        (channel << 2));
  93        default:
  94                return -EINVAL;
  95        }
  96}
  97
  98static int mcp320x_adc_conversion(struct mcp320x *adc, u8 channel,
  99                                  bool differential, int device_index)
 100{
 101        int ret;
 102
 103        adc->rx_buf[0] = 0;
 104        adc->rx_buf[1] = 0;
 105        adc->tx_buf = mcp320x_channel_to_tx_data(device_index,
 106                                                channel, differential);
 107
 108        if (device_index != mcp3001 && device_index != mcp3201 && device_index != mcp3301) {
 109                ret = spi_sync(adc->spi, &adc->msg);
 110                if (ret < 0)
 111                        return ret;
 112        } else {
 113                ret = spi_read(adc->spi, &adc->rx_buf, sizeof(adc->rx_buf));
 114                if (ret < 0)
 115                        return ret;
 116        }
 117
 118        switch (device_index) {
 119        case mcp3001:
 120                return (adc->rx_buf[0] << 5 | adc->rx_buf[1] >> 3);
 121        case mcp3002:
 122        case mcp3004:
 123        case mcp3008:
 124                return (adc->rx_buf[0] << 2 | adc->rx_buf[1] >> 6);
 125        case mcp3201:
 126                return (adc->rx_buf[0] << 7 | adc->rx_buf[1] >> 1);
 127        case mcp3202:
 128        case mcp3204:
 129        case mcp3208:
 130                return (adc->rx_buf[0] << 4 | adc->rx_buf[1] >> 4);
 131        case mcp3301:
 132                return sign_extend32((adc->rx_buf[0] & 0x1f) << 8 | adc->rx_buf[1], 12);
 133        default:
 134                return -EINVAL;
 135        }
 136}
 137
 138static int mcp320x_read_raw(struct iio_dev *indio_dev,
 139                            struct iio_chan_spec const *channel, int *val,
 140                            int *val2, long mask)
 141{
 142        struct mcp320x *adc = iio_priv(indio_dev);
 143        int ret = -EINVAL;
 144        int device_index = 0;
 145
 146        mutex_lock(&adc->lock);
 147
 148        device_index = spi_get_device_id(adc->spi)->driver_data;
 149
 150        switch (mask) {
 151        case IIO_CHAN_INFO_RAW:
 152                ret = mcp320x_adc_conversion(adc, channel->address,
 153                        channel->differential, device_index);
 154
 155                if (ret < 0)
 156                        goto out;
 157
 158                *val = ret;
 159                ret = IIO_VAL_INT;
 160                break;
 161
 162        case IIO_CHAN_INFO_SCALE:
 163                ret = regulator_get_voltage(adc->reg);
 164                if (ret < 0)
 165                        goto out;
 166
 167                /* convert regulator output voltage to mV */
 168                *val = ret / 1000;
 169                *val2 = adc->chip_info->resolution;
 170                ret = IIO_VAL_FRACTIONAL_LOG2;
 171                break;
 172        }
 173
 174out:
 175        mutex_unlock(&adc->lock);
 176
 177        return ret;
 178}
 179
 180#define MCP320X_VOLTAGE_CHANNEL(num)                            \
 181        {                                                       \
 182                .type = IIO_VOLTAGE,                            \
 183                .indexed = 1,                                   \
 184                .channel = (num),                               \
 185                .address = (num),                               \
 186                .info_mask_separate = BIT(IIO_CHAN_INFO_RAW),   \
 187                .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE) \
 188        }
 189
 190#define MCP320X_VOLTAGE_CHANNEL_DIFF(chan1, chan2)              \
 191        {                                                       \
 192                .type = IIO_VOLTAGE,                            \
 193                .indexed = 1,                                   \
 194                .channel = (chan1),                             \
 195                .channel2 = (chan2),                            \
 196                .address = (chan1),                             \
 197                .differential = 1,                              \
 198                .info_mask_separate = BIT(IIO_CHAN_INFO_RAW),   \
 199                .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE) \
 200        }
 201
 202static const struct iio_chan_spec mcp3201_channels[] = {
 203        MCP320X_VOLTAGE_CHANNEL_DIFF(0, 1),
 204};
 205
 206static const struct iio_chan_spec mcp3202_channels[] = {
 207        MCP320X_VOLTAGE_CHANNEL(0),
 208        MCP320X_VOLTAGE_CHANNEL(1),
 209        MCP320X_VOLTAGE_CHANNEL_DIFF(0, 1),
 210        MCP320X_VOLTAGE_CHANNEL_DIFF(1, 0),
 211};
 212
 213static const struct iio_chan_spec mcp3204_channels[] = {
 214        MCP320X_VOLTAGE_CHANNEL(0),
 215        MCP320X_VOLTAGE_CHANNEL(1),
 216        MCP320X_VOLTAGE_CHANNEL(2),
 217        MCP320X_VOLTAGE_CHANNEL(3),
 218        MCP320X_VOLTAGE_CHANNEL_DIFF(0, 1),
 219        MCP320X_VOLTAGE_CHANNEL_DIFF(1, 0),
 220        MCP320X_VOLTAGE_CHANNEL_DIFF(2, 3),
 221        MCP320X_VOLTAGE_CHANNEL_DIFF(3, 2),
 222};
 223
 224static const struct iio_chan_spec mcp3208_channels[] = {
 225        MCP320X_VOLTAGE_CHANNEL(0),
 226        MCP320X_VOLTAGE_CHANNEL(1),
 227        MCP320X_VOLTAGE_CHANNEL(2),
 228        MCP320X_VOLTAGE_CHANNEL(3),
 229        MCP320X_VOLTAGE_CHANNEL(4),
 230        MCP320X_VOLTAGE_CHANNEL(5),
 231        MCP320X_VOLTAGE_CHANNEL(6),
 232        MCP320X_VOLTAGE_CHANNEL(7),
 233        MCP320X_VOLTAGE_CHANNEL_DIFF(0, 1),
 234        MCP320X_VOLTAGE_CHANNEL_DIFF(1, 0),
 235        MCP320X_VOLTAGE_CHANNEL_DIFF(2, 3),
 236        MCP320X_VOLTAGE_CHANNEL_DIFF(3, 2),
 237        MCP320X_VOLTAGE_CHANNEL_DIFF(4, 5),
 238        MCP320X_VOLTAGE_CHANNEL_DIFF(5, 4),
 239        MCP320X_VOLTAGE_CHANNEL_DIFF(6, 7),
 240        MCP320X_VOLTAGE_CHANNEL_DIFF(7, 6),
 241};
 242
 243static const struct iio_info mcp320x_info = {
 244        .read_raw = mcp320x_read_raw,
 245        .driver_module = THIS_MODULE,
 246};
 247
 248static const struct mcp320x_chip_info mcp320x_chip_infos[] = {
 249        [mcp3001] = {
 250                .channels = mcp3201_channels,
 251                .num_channels = ARRAY_SIZE(mcp3201_channels),
 252                .resolution = 10
 253        },
 254        [mcp3002] = {
 255                .channels = mcp3202_channels,
 256                .num_channels = ARRAY_SIZE(mcp3202_channels),
 257                .resolution = 10
 258        },
 259        [mcp3004] = {
 260                .channels = mcp3204_channels,
 261                .num_channels = ARRAY_SIZE(mcp3204_channels),
 262                .resolution = 10
 263        },
 264        [mcp3008] = {
 265                .channels = mcp3208_channels,
 266                .num_channels = ARRAY_SIZE(mcp3208_channels),
 267                .resolution = 10
 268        },
 269        [mcp3201] = {
 270                .channels = mcp3201_channels,
 271                .num_channels = ARRAY_SIZE(mcp3201_channels),
 272                .resolution = 12
 273        },
 274        [mcp3202] = {
 275                .channels = mcp3202_channels,
 276                .num_channels = ARRAY_SIZE(mcp3202_channels),
 277                .resolution = 12
 278        },
 279        [mcp3204] = {
 280                .channels = mcp3204_channels,
 281                .num_channels = ARRAY_SIZE(mcp3204_channels),
 282                .resolution = 12
 283        },
 284        [mcp3208] = {
 285                .channels = mcp3208_channels,
 286                .num_channels = ARRAY_SIZE(mcp3208_channels),
 287                .resolution = 12
 288        },
 289        [mcp3301] = {
 290                .channels = mcp3201_channels,
 291                .num_channels = ARRAY_SIZE(mcp3201_channels),
 292                .resolution = 13
 293        },
 294};
 295
 296static int mcp320x_probe(struct spi_device *spi)
 297{
 298        struct iio_dev *indio_dev;
 299        struct mcp320x *adc;
 300        const struct mcp320x_chip_info *chip_info;
 301        int ret;
 302
 303        indio_dev = devm_iio_device_alloc(&spi->dev, sizeof(*adc));
 304        if (!indio_dev)
 305                return -ENOMEM;
 306
 307        adc = iio_priv(indio_dev);
 308        adc->spi = spi;
 309
 310        indio_dev->dev.parent = &spi->dev;
 311        indio_dev->name = spi_get_device_id(spi)->name;
 312        indio_dev->modes = INDIO_DIRECT_MODE;
 313        indio_dev->info = &mcp320x_info;
 314
 315        chip_info = &mcp320x_chip_infos[spi_get_device_id(spi)->driver_data];
 316        indio_dev->channels = chip_info->channels;
 317        indio_dev->num_channels = chip_info->num_channels;
 318
 319        adc->chip_info = chip_info;
 320
 321        adc->transfer[0].tx_buf = &adc->tx_buf;
 322        adc->transfer[0].len = sizeof(adc->tx_buf);
 323        adc->transfer[1].rx_buf = adc->rx_buf;
 324        adc->transfer[1].len = sizeof(adc->rx_buf);
 325
 326        spi_message_init_with_transfers(&adc->msg, adc->transfer,
 327                                        ARRAY_SIZE(adc->transfer));
 328
 329        adc->reg = devm_regulator_get(&spi->dev, "vref");
 330        if (IS_ERR(adc->reg))
 331                return PTR_ERR(adc->reg);
 332
 333        ret = regulator_enable(adc->reg);
 334        if (ret < 0)
 335                return ret;
 336
 337        mutex_init(&adc->lock);
 338
 339        ret = iio_device_register(indio_dev);
 340        if (ret < 0)
 341                goto reg_disable;
 342
 343        return 0;
 344
 345reg_disable:
 346        regulator_disable(adc->reg);
 347
 348        return ret;
 349}
 350
 351static int mcp320x_remove(struct spi_device *spi)
 352{
 353        struct iio_dev *indio_dev = spi_get_drvdata(spi);
 354        struct mcp320x *adc = iio_priv(indio_dev);
 355
 356        iio_device_unregister(indio_dev);
 357        regulator_disable(adc->reg);
 358
 359        return 0;
 360}
 361
 362#if defined(CONFIG_OF)
 363static const struct of_device_id mcp320x_dt_ids[] = {
 364        /* NOTE: The use of compatibles with no vendor prefix is deprecated. */
 365        {
 366                .compatible = "mcp3001",
 367                .data = &mcp320x_chip_infos[mcp3001],
 368        }, {
 369                .compatible = "mcp3002",
 370                .data = &mcp320x_chip_infos[mcp3002],
 371        }, {
 372                .compatible = "mcp3004",
 373                .data = &mcp320x_chip_infos[mcp3004],
 374        }, {
 375                .compatible = "mcp3008",
 376                .data = &mcp320x_chip_infos[mcp3008],
 377        }, {
 378                .compatible = "mcp3201",
 379                .data = &mcp320x_chip_infos[mcp3201],
 380        }, {
 381                .compatible = "mcp3202",
 382                .data = &mcp320x_chip_infos[mcp3202],
 383        }, {
 384                .compatible = "mcp3204",
 385                .data = &mcp320x_chip_infos[mcp3204],
 386        }, {
 387                .compatible = "mcp3208",
 388                .data = &mcp320x_chip_infos[mcp3208],
 389        }, {
 390                .compatible = "mcp3301",
 391                .data = &mcp320x_chip_infos[mcp3301],
 392        }, {
 393                .compatible = "microchip,mcp3001",
 394                .data = &mcp320x_chip_infos[mcp3001],
 395        }, {
 396                .compatible = "microchip,mcp3002",
 397                .data = &mcp320x_chip_infos[mcp3002],
 398        }, {
 399                .compatible = "microchip,mcp3004",
 400                .data = &mcp320x_chip_infos[mcp3004],
 401        }, {
 402                .compatible = "microchip,mcp3008",
 403                .data = &mcp320x_chip_infos[mcp3008],
 404        }, {
 405                .compatible = "microchip,mcp3201",
 406                .data = &mcp320x_chip_infos[mcp3201],
 407        }, {
 408                .compatible = "microchip,mcp3202",
 409                .data = &mcp320x_chip_infos[mcp3202],
 410        }, {
 411                .compatible = "microchip,mcp3204",
 412                .data = &mcp320x_chip_infos[mcp3204],
 413        }, {
 414                .compatible = "microchip,mcp3208",
 415                .data = &mcp320x_chip_infos[mcp3208],
 416        }, {
 417                .compatible = "microchip,mcp3301",
 418                .data = &mcp320x_chip_infos[mcp3301],
 419        }, {
 420        }
 421};
 422MODULE_DEVICE_TABLE(of, mcp320x_dt_ids);
 423#endif
 424
 425static const struct spi_device_id mcp320x_id[] = {
 426        { "mcp3001", mcp3001 },
 427        { "mcp3002", mcp3002 },
 428        { "mcp3004", mcp3004 },
 429        { "mcp3008", mcp3008 },
 430        { "mcp3201", mcp3201 },
 431        { "mcp3202", mcp3202 },
 432        { "mcp3204", mcp3204 },
 433        { "mcp3208", mcp3208 },
 434        { "mcp3301", mcp3301 },
 435        { }
 436};
 437MODULE_DEVICE_TABLE(spi, mcp320x_id);
 438
 439static struct spi_driver mcp320x_driver = {
 440        .driver = {
 441                .name = "mcp320x",
 442                .of_match_table = of_match_ptr(mcp320x_dt_ids),
 443        },
 444        .probe = mcp320x_probe,
 445        .remove = mcp320x_remove,
 446        .id_table = mcp320x_id,
 447};
 448module_spi_driver(mcp320x_driver);
 449
 450MODULE_AUTHOR("Oskar Andero <oskar.andero@gmail.com>");
 451MODULE_DESCRIPTION("Microchip Technology MCP3x01/02/04/08");
 452MODULE_LICENSE("GPL v2");
 453