linux/drivers/staging/iio/cdc/ad7152.c
<<
>>
Prefs
   1/*
   2 * AD7152 capacitive sensor driver supporting AD7152/3
   3 *
   4 * Copyright 2010-2011a Analog Devices Inc.
   5 *
   6 * Licensed under the GPL-2 or later.
   7 */
   8
   9#include <linux/interrupt.h>
  10#include <linux/device.h>
  11#include <linux/kernel.h>
  12#include <linux/slab.h>
  13#include <linux/sysfs.h>
  14#include <linux/i2c.h>
  15#include <linux/module.h>
  16#include <linux/delay.h>
  17
  18#include <linux/iio/iio.h>
  19#include <linux/iio/sysfs.h>
  20
  21/*
  22 * TODO: Check compliance of calibbias with abi (units)
  23 */
  24/*
  25 * AD7152 registers definition
  26 */
  27
  28#define AD7152_REG_STATUS               0
  29#define AD7152_REG_CH1_DATA_HIGH        1
  30#define AD7152_REG_CH2_DATA_HIGH        3
  31#define AD7152_REG_CH1_OFFS_HIGH        5
  32#define AD7152_REG_CH2_OFFS_HIGH        7
  33#define AD7152_REG_CH1_GAIN_HIGH        9
  34#define AD7152_REG_CH1_SETUP            11
  35#define AD7152_REG_CH2_GAIN_HIGH        12
  36#define AD7152_REG_CH2_SETUP            14
  37#define AD7152_REG_CFG                  15
  38#define AD7152_REG_RESEVERD             16
  39#define AD7152_REG_CAPDAC_POS           17
  40#define AD7152_REG_CAPDAC_NEG           18
  41#define AD7152_REG_CFG2                 26
  42
  43/* Status Register Bit Designations (AD7152_REG_STATUS) */
  44#define AD7152_STATUS_RDY1              BIT(0)
  45#define AD7152_STATUS_RDY2              BIT(1)
  46#define AD7152_STATUS_C1C2              BIT(2)
  47#define AD7152_STATUS_PWDN              BIT(7)
  48
  49/* Setup Register Bit Designations (AD7152_REG_CHx_SETUP) */
  50#define AD7152_SETUP_CAPDIFF            BIT(5)
  51#define AD7152_SETUP_RANGE_2pF          (0 << 6)
  52#define AD7152_SETUP_RANGE_0_5pF        (1 << 6)
  53#define AD7152_SETUP_RANGE_1pF          (2 << 6)
  54#define AD7152_SETUP_RANGE_4pF          (3 << 6)
  55#define AD7152_SETUP_RANGE(x)           ((x) << 6)
  56
  57/* Config Register Bit Designations (AD7152_REG_CFG) */
  58#define AD7152_CONF_CH2EN               BIT(3)
  59#define AD7152_CONF_CH1EN               BIT(4)
  60#define AD7152_CONF_MODE_IDLE           (0 << 0)
  61#define AD7152_CONF_MODE_CONT_CONV      (1 << 0)
  62#define AD7152_CONF_MODE_SINGLE_CONV    (2 << 0)
  63#define AD7152_CONF_MODE_OFFS_CAL       (5 << 0)
  64#define AD7152_CONF_MODE_GAIN_CAL       (6 << 0)
  65
  66/* Capdac Register Bit Designations (AD7152_REG_CAPDAC_XXX) */
  67#define AD7152_CAPDAC_DACEN             BIT(7)
  68#define AD7152_CAPDAC_DACP(x)           ((x) & 0x1F)
  69
  70/* CFG2 Register Bit Designations (AD7152_REG_CFG2) */
  71#define AD7152_CFG2_OSR(x)              (((x) & 0x3) << 4)
  72
  73enum {
  74        AD7152_DATA,
  75        AD7152_OFFS,
  76        AD7152_GAIN,
  77        AD7152_SETUP
  78};
  79
  80/*
  81 * struct ad7152_chip_info - chip specific information
  82 */
  83
  84struct ad7152_chip_info {
  85        struct i2c_client *client;
  86        /*
  87         * Capacitive channel digital filter setup;
  88         * conversion time/update rate setup per channel
  89         */
  90        u8      filter_rate_setup;
  91        u8      setup[2];
  92        struct mutex state_lock;        /* protect hardware state */
  93};
  94
  95static inline ssize_t ad7152_start_calib(struct device *dev,
  96                                         struct device_attribute *attr,
  97                                         const char *buf,
  98                                         size_t len,
  99                                         u8 regval)
 100{
 101        struct iio_dev *indio_dev = dev_to_iio_dev(dev);
 102        struct ad7152_chip_info *chip = iio_priv(indio_dev);
 103        struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
 104        bool doit;
 105        int ret, timeout = 10;
 106
 107        ret = strtobool(buf, &doit);
 108        if (ret < 0)
 109                return ret;
 110
 111        if (!doit)
 112                return 0;
 113
 114        if (this_attr->address == 0)
 115                regval |= AD7152_CONF_CH1EN;
 116        else
 117                regval |= AD7152_CONF_CH2EN;
 118
 119        mutex_lock(&chip->state_lock);
 120        ret = i2c_smbus_write_byte_data(chip->client, AD7152_REG_CFG, regval);
 121        if (ret < 0)
 122                goto unlock;
 123
 124        do {
 125                mdelay(20);
 126                ret = i2c_smbus_read_byte_data(chip->client, AD7152_REG_CFG);
 127                if (ret < 0)
 128                        goto unlock;
 129
 130        } while ((ret == regval) && timeout--);
 131
 132        mutex_unlock(&chip->state_lock);
 133        return len;
 134
 135unlock:
 136        mutex_unlock(&chip->state_lock);
 137        return ret;
 138}
 139
 140static ssize_t ad7152_start_offset_calib(struct device *dev,
 141                                         struct device_attribute *attr,
 142                                         const char *buf,
 143                                         size_t len)
 144{
 145        return ad7152_start_calib(dev, attr, buf, len,
 146                                  AD7152_CONF_MODE_OFFS_CAL);
 147}
 148
 149static ssize_t ad7152_start_gain_calib(struct device *dev,
 150                                       struct device_attribute *attr,
 151                                       const char *buf,
 152                                       size_t len)
 153{
 154        return ad7152_start_calib(dev, attr, buf, len,
 155                                  AD7152_CONF_MODE_GAIN_CAL);
 156}
 157
 158static IIO_DEVICE_ATTR(in_capacitance0_calibbias_calibration,
 159                       0200, NULL, ad7152_start_offset_calib, 0);
 160static IIO_DEVICE_ATTR(in_capacitance1_calibbias_calibration,
 161                       0200, NULL, ad7152_start_offset_calib, 1);
 162static IIO_DEVICE_ATTR(in_capacitance0_calibscale_calibration,
 163                       0200, NULL, ad7152_start_gain_calib, 0);
 164static IIO_DEVICE_ATTR(in_capacitance1_calibscale_calibration,
 165                       0200, NULL, ad7152_start_gain_calib, 1);
 166
 167/* Values are Update Rate (Hz), Conversion Time (ms) + 1*/
 168static const unsigned char ad7152_filter_rate_table[][2] = {
 169        {200, 5 + 1}, {50, 20 + 1}, {20, 50 + 1}, {17, 60 + 1},
 170};
 171
 172static IIO_CONST_ATTR_SAMP_FREQ_AVAIL("200 50 20 17");
 173
 174static IIO_CONST_ATTR(in_capacitance_scale_available,
 175                      "0.000061050 0.000030525 0.000015263 0.000007631");
 176
 177static struct attribute *ad7152_attributes[] = {
 178        &iio_dev_attr_in_capacitance0_calibbias_calibration.dev_attr.attr,
 179        &iio_dev_attr_in_capacitance1_calibbias_calibration.dev_attr.attr,
 180        &iio_dev_attr_in_capacitance0_calibscale_calibration.dev_attr.attr,
 181        &iio_dev_attr_in_capacitance1_calibscale_calibration.dev_attr.attr,
 182        &iio_const_attr_in_capacitance_scale_available.dev_attr.attr,
 183        &iio_const_attr_sampling_frequency_available.dev_attr.attr,
 184        NULL,
 185};
 186
 187static const struct attribute_group ad7152_attribute_group = {
 188        .attrs = ad7152_attributes,
 189};
 190
 191static const u8 ad7152_addresses[][4] = {
 192        { AD7152_REG_CH1_DATA_HIGH, AD7152_REG_CH1_OFFS_HIGH,
 193          AD7152_REG_CH1_GAIN_HIGH, AD7152_REG_CH1_SETUP },
 194        { AD7152_REG_CH2_DATA_HIGH, AD7152_REG_CH2_OFFS_HIGH,
 195          AD7152_REG_CH2_GAIN_HIGH, AD7152_REG_CH2_SETUP },
 196};
 197
 198/* Values are nano relative to pf base. */
 199static const int ad7152_scale_table[] = {
 200        30525, 7631, 15263, 61050
 201};
 202
 203/**
 204 * read_raw handler for IIO_CHAN_INFO_SAMP_FREQ
 205 *
 206 * lock must be held
 207 **/
 208static int ad7152_read_raw_samp_freq(struct device *dev, int *val)
 209{
 210        struct ad7152_chip_info *chip = iio_priv(dev_to_iio_dev(dev));
 211
 212        *val = ad7152_filter_rate_table[chip->filter_rate_setup][0];
 213
 214        return 0;
 215}
 216
 217/**
 218 * write_raw handler for IIO_CHAN_INFO_SAMP_FREQ
 219 *
 220 * lock must be held
 221 **/
 222static int ad7152_write_raw_samp_freq(struct device *dev, int val)
 223{
 224        struct iio_dev *indio_dev = dev_to_iio_dev(dev);
 225        struct ad7152_chip_info *chip = iio_priv(indio_dev);
 226        int ret, i;
 227
 228        for (i = 0; i < ARRAY_SIZE(ad7152_filter_rate_table); i++)
 229                if (val >= ad7152_filter_rate_table[i][0])
 230                        break;
 231
 232        if (i >= ARRAY_SIZE(ad7152_filter_rate_table))
 233                i = ARRAY_SIZE(ad7152_filter_rate_table) - 1;
 234
 235        ret = i2c_smbus_write_byte_data(chip->client,
 236                                        AD7152_REG_CFG2, AD7152_CFG2_OSR(i));
 237        if (ret < 0)
 238                return ret;
 239
 240        chip->filter_rate_setup = i;
 241
 242        return ret;
 243}
 244
 245static int ad7152_write_raw(struct iio_dev *indio_dev,
 246                            struct iio_chan_spec const *chan,
 247                            int val,
 248                            int val2,
 249                            long mask)
 250{
 251        struct ad7152_chip_info *chip = iio_priv(indio_dev);
 252        int ret, i;
 253
 254        mutex_lock(&chip->state_lock);
 255
 256        switch (mask) {
 257        case IIO_CHAN_INFO_CALIBSCALE:
 258                if (val != 1) {
 259                        ret = -EINVAL;
 260                        goto out;
 261                }
 262
 263                val = (val2 * 1024) / 15625;
 264
 265                ret = i2c_smbus_write_word_data(chip->client,
 266                                ad7152_addresses[chan->channel][AD7152_GAIN],
 267                                swab16(val));
 268                if (ret < 0)
 269                        goto out;
 270
 271                ret = 0;
 272                break;
 273
 274        case IIO_CHAN_INFO_CALIBBIAS:
 275                if ((val < 0) | (val > 0xFFFF)) {
 276                        ret = -EINVAL;
 277                        goto out;
 278                }
 279                ret = i2c_smbus_write_word_data(chip->client,
 280                                ad7152_addresses[chan->channel][AD7152_OFFS],
 281                                swab16(val));
 282                if (ret < 0)
 283                        goto out;
 284
 285                ret = 0;
 286                break;
 287        case IIO_CHAN_INFO_SCALE:
 288                if (val) {
 289                        ret = -EINVAL;
 290                        goto out;
 291                }
 292                for (i = 0; i < ARRAY_SIZE(ad7152_scale_table); i++)
 293                        if (val2 == ad7152_scale_table[i])
 294                                break;
 295
 296                chip->setup[chan->channel] &= ~AD7152_SETUP_RANGE_4pF;
 297                chip->setup[chan->channel] |= AD7152_SETUP_RANGE(i);
 298
 299                ret = i2c_smbus_write_byte_data(chip->client,
 300                                ad7152_addresses[chan->channel][AD7152_SETUP],
 301                                chip->setup[chan->channel]);
 302                if (ret < 0)
 303                        goto out;
 304
 305                ret = 0;
 306                break;
 307        case IIO_CHAN_INFO_SAMP_FREQ:
 308                if (val2) {
 309                        ret = -EINVAL;
 310                        goto out;
 311                }
 312                ret = ad7152_write_raw_samp_freq(&indio_dev->dev, val);
 313                if (ret < 0)
 314                        goto out;
 315
 316                ret = 0;
 317                break;
 318        default:
 319                ret = -EINVAL;
 320        }
 321
 322out:
 323        mutex_unlock(&chip->state_lock);
 324        return ret;
 325}
 326
 327static int ad7152_read_raw(struct iio_dev *indio_dev,
 328                           struct iio_chan_spec const *chan,
 329                           int *val, int *val2,
 330                           long mask)
 331{
 332        struct ad7152_chip_info *chip = iio_priv(indio_dev);
 333        int ret;
 334        u8 regval = 0;
 335
 336        mutex_lock(&chip->state_lock);
 337
 338        switch (mask) {
 339        case IIO_CHAN_INFO_RAW:
 340                /* First set whether in differential mode */
 341
 342                regval = chip->setup[chan->channel];
 343
 344                if (chan->differential)
 345                        chip->setup[chan->channel] |= AD7152_SETUP_CAPDIFF;
 346                else
 347                        chip->setup[chan->channel] &= ~AD7152_SETUP_CAPDIFF;
 348
 349                if (regval != chip->setup[chan->channel]) {
 350                        ret = i2c_smbus_write_byte_data(chip->client,
 351                                ad7152_addresses[chan->channel][AD7152_SETUP],
 352                                chip->setup[chan->channel]);
 353                        if (ret < 0)
 354                                goto out;
 355                }
 356                /* Make sure the channel is enabled */
 357                if (chan->channel == 0)
 358                        regval = AD7152_CONF_CH1EN;
 359                else
 360                        regval = AD7152_CONF_CH2EN;
 361
 362                /* Trigger a single read */
 363                regval |= AD7152_CONF_MODE_SINGLE_CONV;
 364                ret = i2c_smbus_write_byte_data(chip->client, AD7152_REG_CFG,
 365                                regval);
 366                if (ret < 0)
 367                        goto out;
 368
 369                msleep(ad7152_filter_rate_table[chip->filter_rate_setup][1]);
 370                /* Now read the actual register */
 371                ret = i2c_smbus_read_word_data(chip->client,
 372                                ad7152_addresses[chan->channel][AD7152_DATA]);
 373                if (ret < 0)
 374                        goto out;
 375                *val = swab16(ret);
 376
 377                if (chan->differential)
 378                        *val -= 0x8000;
 379
 380                ret = IIO_VAL_INT;
 381                break;
 382        case IIO_CHAN_INFO_CALIBSCALE:
 383
 384                ret = i2c_smbus_read_word_data(chip->client,
 385                                ad7152_addresses[chan->channel][AD7152_GAIN]);
 386                if (ret < 0)
 387                        goto out;
 388                /* 1 + gain_val / 2^16 */
 389                *val = 1;
 390                *val2 = (15625 * swab16(ret)) / 1024;
 391
 392                ret = IIO_VAL_INT_PLUS_MICRO;
 393                break;
 394        case IIO_CHAN_INFO_CALIBBIAS:
 395                ret = i2c_smbus_read_word_data(chip->client,
 396                                ad7152_addresses[chan->channel][AD7152_OFFS]);
 397                if (ret < 0)
 398                        goto out;
 399                *val = swab16(ret);
 400
 401                ret = IIO_VAL_INT;
 402                break;
 403        case IIO_CHAN_INFO_SCALE:
 404                ret = i2c_smbus_read_byte_data(chip->client,
 405                                ad7152_addresses[chan->channel][AD7152_SETUP]);
 406                if (ret < 0)
 407                        goto out;
 408                *val = 0;
 409                *val2 = ad7152_scale_table[ret >> 6];
 410
 411                ret = IIO_VAL_INT_PLUS_NANO;
 412                break;
 413        case IIO_CHAN_INFO_SAMP_FREQ:
 414                ret = ad7152_read_raw_samp_freq(&indio_dev->dev, val);
 415                if (ret < 0)
 416                        goto out;
 417
 418                ret = IIO_VAL_INT;
 419                break;
 420        default:
 421                ret = -EINVAL;
 422        }
 423out:
 424        mutex_unlock(&chip->state_lock);
 425        return ret;
 426}
 427
 428static int ad7152_write_raw_get_fmt(struct iio_dev *indio_dev,
 429                                    struct iio_chan_spec const *chan,
 430                                    long mask)
 431{
 432        switch (mask) {
 433        case IIO_CHAN_INFO_SCALE:
 434                return IIO_VAL_INT_PLUS_NANO;
 435        default:
 436                return IIO_VAL_INT_PLUS_MICRO;
 437        }
 438}
 439
 440static const struct iio_info ad7152_info = {
 441        .attrs = &ad7152_attribute_group,
 442        .read_raw = ad7152_read_raw,
 443        .write_raw = ad7152_write_raw,
 444        .write_raw_get_fmt = ad7152_write_raw_get_fmt,
 445};
 446
 447static const struct iio_chan_spec ad7152_channels[] = {
 448        {
 449                .type = IIO_CAPACITANCE,
 450                .indexed = 1,
 451                .channel = 0,
 452                .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
 453                BIT(IIO_CHAN_INFO_CALIBSCALE) |
 454                BIT(IIO_CHAN_INFO_CALIBBIAS) |
 455                BIT(IIO_CHAN_INFO_SCALE),
 456                .info_mask_shared_by_all = BIT(IIO_CHAN_INFO_SAMP_FREQ),
 457        }, {
 458                .type = IIO_CAPACITANCE,
 459                .differential = 1,
 460                .indexed = 1,
 461                .channel = 0,
 462                .channel2 = 2,
 463                .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
 464                BIT(IIO_CHAN_INFO_CALIBSCALE) |
 465                BIT(IIO_CHAN_INFO_CALIBBIAS) |
 466                BIT(IIO_CHAN_INFO_SCALE),
 467                .info_mask_shared_by_all = BIT(IIO_CHAN_INFO_SAMP_FREQ),
 468        }, {
 469                .type = IIO_CAPACITANCE,
 470                .indexed = 1,
 471                .channel = 1,
 472                .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
 473                BIT(IIO_CHAN_INFO_CALIBSCALE) |
 474                BIT(IIO_CHAN_INFO_CALIBBIAS) |
 475                BIT(IIO_CHAN_INFO_SCALE),
 476                .info_mask_shared_by_all = BIT(IIO_CHAN_INFO_SAMP_FREQ),
 477        }, {
 478                .type = IIO_CAPACITANCE,
 479                .differential = 1,
 480                .indexed = 1,
 481                .channel = 1,
 482                .channel2 = 3,
 483                .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
 484                BIT(IIO_CHAN_INFO_CALIBSCALE) |
 485                BIT(IIO_CHAN_INFO_CALIBBIAS) |
 486                BIT(IIO_CHAN_INFO_SCALE),
 487                .info_mask_shared_by_all = BIT(IIO_CHAN_INFO_SAMP_FREQ),
 488        }
 489};
 490
 491/*
 492 * device probe and remove
 493 */
 494
 495static int ad7152_probe(struct i2c_client *client,
 496                        const struct i2c_device_id *id)
 497{
 498        int ret = 0;
 499        struct ad7152_chip_info *chip;
 500        struct iio_dev *indio_dev;
 501
 502        indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*chip));
 503        if (!indio_dev)
 504                return -ENOMEM;
 505        chip = iio_priv(indio_dev);
 506        /* this is only used for device removal purposes */
 507        i2c_set_clientdata(client, indio_dev);
 508
 509        chip->client = client;
 510        mutex_init(&chip->state_lock);
 511
 512        /* Establish that the iio_dev is a child of the i2c device */
 513        indio_dev->name = id->name;
 514        indio_dev->dev.parent = &client->dev;
 515        indio_dev->info = &ad7152_info;
 516        indio_dev->channels = ad7152_channels;
 517        if (id->driver_data == 0)
 518                indio_dev->num_channels = ARRAY_SIZE(ad7152_channels);
 519        else
 520                indio_dev->num_channels = 2;
 521        indio_dev->num_channels = ARRAY_SIZE(ad7152_channels);
 522        indio_dev->modes = INDIO_DIRECT_MODE;
 523
 524        ret = devm_iio_device_register(indio_dev->dev.parent, indio_dev);
 525        if (ret)
 526                return ret;
 527
 528        dev_err(&client->dev, "%s capacitive sensor registered\n", id->name);
 529
 530        return 0;
 531}
 532
 533static const struct i2c_device_id ad7152_id[] = {
 534        { "ad7152", 0 },
 535        { "ad7153", 1 },
 536        {}
 537};
 538
 539MODULE_DEVICE_TABLE(i2c, ad7152_id);
 540
 541static struct i2c_driver ad7152_driver = {
 542        .driver = {
 543                .name = KBUILD_MODNAME,
 544        },
 545        .probe = ad7152_probe,
 546        .id_table = ad7152_id,
 547};
 548module_i2c_driver(ad7152_driver);
 549
 550MODULE_AUTHOR("Barry Song <21cnbao@gmail.com>");
 551MODULE_DESCRIPTION("Analog Devices AD7152/3 capacitive sensor driver");
 552MODULE_LICENSE("GPL v2");
 553