linux/drivers/staging/iio/cdc/ad7746.c
<<
>>
Prefs
   1/*
   2 * AD7746 capacitive sensor driver supporting AD7745, AD7746 and AD7747
   3 *
   4 * Copyright 2011 Analog Devices Inc.
   5 *
   6 * Licensed under the GPL-2.
   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/delay.h>
  16#include <linux/module.h>
  17#include <linux/stat.h>
  18
  19#include <linux/iio/iio.h>
  20#include <linux/iio/sysfs.h>
  21
  22#include "ad7746.h"
  23
  24/*
  25 * AD7746 Register Definition
  26 */
  27
  28#define AD7746_REG_STATUS               0
  29#define AD7746_REG_CAP_DATA_HIGH        1
  30#define AD7746_REG_CAP_DATA_MID         2
  31#define AD7746_REG_CAP_DATA_LOW         3
  32#define AD7746_REG_VT_DATA_HIGH         4
  33#define AD7746_REG_VT_DATA_MID          5
  34#define AD7746_REG_VT_DATA_LOW          6
  35#define AD7746_REG_CAP_SETUP            7
  36#define AD7746_REG_VT_SETUP             8
  37#define AD7746_REG_EXC_SETUP            9
  38#define AD7746_REG_CFG                  10
  39#define AD7746_REG_CAPDACA              11
  40#define AD7746_REG_CAPDACB              12
  41#define AD7746_REG_CAP_OFFH             13
  42#define AD7746_REG_CAP_OFFL             14
  43#define AD7746_REG_CAP_GAINH            15
  44#define AD7746_REG_CAP_GAINL            16
  45#define AD7746_REG_VOLT_GAINH           17
  46#define AD7746_REG_VOLT_GAINL           18
  47
  48/* Status Register Bit Designations (AD7746_REG_STATUS) */
  49#define AD7746_STATUS_EXCERR            (1 << 3)
  50#define AD7746_STATUS_RDY               (1 << 2)
  51#define AD7746_STATUS_RDYVT             (1 << 1)
  52#define AD7746_STATUS_RDYCAP            (1 << 0)
  53
  54/* Capacitive Channel Setup Register Bit Designations (AD7746_REG_CAP_SETUP) */
  55#define AD7746_CAPSETUP_CAPEN           (1 << 7)
  56#define AD7746_CAPSETUP_CIN2            (1 << 6) /* AD7746 only */
  57#define AD7746_CAPSETUP_CAPDIFF         (1 << 5)
  58#define AD7746_CAPSETUP_CACHOP          (1 << 0)
  59
  60/* Voltage/Temperature Setup Register Bit Designations (AD7746_REG_VT_SETUP) */
  61#define AD7746_VTSETUP_VTEN             (1 << 7)
  62#define AD7746_VTSETUP_VTMD_INT_TEMP    (0 << 5)
  63#define AD7746_VTSETUP_VTMD_EXT_TEMP    (1 << 5)
  64#define AD7746_VTSETUP_VTMD_VDD_MON     (2 << 5)
  65#define AD7746_VTSETUP_VTMD_EXT_VIN     (3 << 5)
  66#define AD7746_VTSETUP_EXTREF           (1 << 4)
  67#define AD7746_VTSETUP_VTSHORT          (1 << 1)
  68#define AD7746_VTSETUP_VTCHOP           (1 << 0)
  69
  70/* Excitation Setup Register Bit Designations (AD7746_REG_EXC_SETUP) */
  71#define AD7746_EXCSETUP_CLKCTRL         (1 << 7)
  72#define AD7746_EXCSETUP_EXCON           (1 << 6)
  73#define AD7746_EXCSETUP_EXCB            (1 << 5)
  74#define AD7746_EXCSETUP_NEXCB           (1 << 4)
  75#define AD7746_EXCSETUP_EXCA            (1 << 3)
  76#define AD7746_EXCSETUP_NEXCA           (1 << 2)
  77#define AD7746_EXCSETUP_EXCLVL(x)       (((x) & 0x3) << 0)
  78
  79/* Config Register Bit Designations (AD7746_REG_CFG) */
  80#define AD7746_CONF_VTFS(x)             ((x) << 6)
  81#define AD7746_CONF_CAPFS(x)            ((x) << 3)
  82#define AD7746_CONF_MODE_IDLE           (0 << 0)
  83#define AD7746_CONF_MODE_CONT_CONV      (1 << 0)
  84#define AD7746_CONF_MODE_SINGLE_CONV    (2 << 0)
  85#define AD7746_CONF_MODE_PWRDN          (3 << 0)
  86#define AD7746_CONF_MODE_OFFS_CAL       (5 << 0)
  87#define AD7746_CONF_MODE_GAIN_CAL       (6 << 0)
  88
  89/* CAPDAC Register Bit Designations (AD7746_REG_CAPDACx) */
  90#define AD7746_CAPDAC_DACEN             (1 << 7)
  91#define AD7746_CAPDAC_DACP(x)           ((x) & 0x7F)
  92
  93/*
  94 * struct ad7746_chip_info - chip specifc information
  95 */
  96
  97struct ad7746_chip_info {
  98        struct i2c_client *client;
  99        /*
 100         * Capacitive channel digital filter setup;
 101         * conversion time/update rate setup per channel
 102         */
 103        u8      config;
 104        u8      cap_setup;
 105        u8      vt_setup;
 106        u8      capdac[2][2];
 107        s8      capdac_set;
 108};
 109
 110enum ad7746_chan {
 111        VIN,
 112        VIN_VDD,
 113        TEMP_INT,
 114        TEMP_EXT,
 115        CIN1,
 116        CIN1_DIFF,
 117        CIN2,
 118        CIN2_DIFF,
 119};
 120
 121static const struct iio_chan_spec ad7746_channels[] = {
 122        [VIN] = {
 123                .type = IIO_VOLTAGE,
 124                .indexed = 1,
 125                .channel = 0,
 126                .info_mask_separate = BIT(IIO_CHAN_INFO_RAW),
 127                .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE),
 128                .address = AD7746_REG_VT_DATA_HIGH << 8 |
 129                        AD7746_VTSETUP_VTMD_EXT_VIN,
 130        },
 131        [VIN_VDD] = {
 132                .type = IIO_VOLTAGE,
 133                .indexed = 1,
 134                .channel = 1,
 135                .extend_name = "supply",
 136                .info_mask_separate = BIT(IIO_CHAN_INFO_RAW),
 137                .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE),
 138                .address = AD7746_REG_VT_DATA_HIGH << 8 |
 139                        AD7746_VTSETUP_VTMD_VDD_MON,
 140        },
 141        [TEMP_INT] = {
 142                .type = IIO_TEMP,
 143                .indexed = 1,
 144                .channel = 0,
 145                .info_mask_separate = BIT(IIO_CHAN_INFO_PROCESSED),
 146                .address = AD7746_REG_VT_DATA_HIGH << 8 |
 147                        AD7746_VTSETUP_VTMD_INT_TEMP,
 148        },
 149        [TEMP_EXT] = {
 150                .type = IIO_TEMP,
 151                .indexed = 1,
 152                .channel = 1,
 153                .info_mask_separate = BIT(IIO_CHAN_INFO_PROCESSED),
 154                .address = AD7746_REG_VT_DATA_HIGH << 8 |
 155                        AD7746_VTSETUP_VTMD_EXT_TEMP,
 156        },
 157        [CIN1] = {
 158                .type = IIO_CAPACITANCE,
 159                .indexed = 1,
 160                .channel = 0,
 161                .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
 162                BIT(IIO_CHAN_INFO_CALIBSCALE) | BIT(IIO_CHAN_INFO_OFFSET),
 163                .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_CALIBBIAS) |
 164                BIT(IIO_CHAN_INFO_SCALE),
 165                .address = AD7746_REG_CAP_DATA_HIGH << 8,
 166        },
 167        [CIN1_DIFF] = {
 168                .type = IIO_CAPACITANCE,
 169                .differential = 1,
 170                .indexed = 1,
 171                .channel = 0,
 172                .channel2 = 2,
 173                .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
 174                BIT(IIO_CHAN_INFO_CALIBSCALE) | BIT(IIO_CHAN_INFO_OFFSET),
 175                .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_CALIBBIAS) |
 176                BIT(IIO_CHAN_INFO_SCALE),
 177                .address = AD7746_REG_CAP_DATA_HIGH << 8 |
 178                        AD7746_CAPSETUP_CAPDIFF
 179        },
 180        [CIN2] = {
 181                .type = IIO_CAPACITANCE,
 182                .indexed = 1,
 183                .channel = 1,
 184                .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
 185                BIT(IIO_CHAN_INFO_CALIBSCALE) | BIT(IIO_CHAN_INFO_OFFSET),
 186                .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_CALIBBIAS) |
 187                BIT(IIO_CHAN_INFO_SCALE),
 188                .address = AD7746_REG_CAP_DATA_HIGH << 8 |
 189                        AD7746_CAPSETUP_CIN2,
 190        },
 191        [CIN2_DIFF] = {
 192                .type = IIO_CAPACITANCE,
 193                .differential = 1,
 194                .indexed = 1,
 195                .channel = 1,
 196                .channel2 = 3,
 197                .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
 198                BIT(IIO_CHAN_INFO_CALIBSCALE) | BIT(IIO_CHAN_INFO_OFFSET),
 199                .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_CALIBBIAS) |
 200                BIT(IIO_CHAN_INFO_SCALE),
 201                .address = AD7746_REG_CAP_DATA_HIGH << 8 |
 202                        AD7746_CAPSETUP_CAPDIFF | AD7746_CAPSETUP_CIN2,
 203        }
 204};
 205
 206/* Values are Update Rate (Hz), Conversion Time (ms) + 1*/
 207static const unsigned char ad7746_vt_filter_rate_table[][2] = {
 208        {50, 20 + 1}, {31, 32 + 1}, {16, 62 + 1}, {8, 122 + 1},
 209};
 210
 211static const unsigned char ad7746_cap_filter_rate_table[][2] = {
 212        {91, 11 + 1}, {84, 12 + 1}, {50, 20 + 1}, {26, 38 + 1},
 213        {16, 62 + 1}, {13, 77 + 1}, {11, 92 + 1}, {9, 110 + 1},
 214};
 215
 216static int ad7746_select_channel(struct iio_dev *indio_dev,
 217                            struct iio_chan_spec const *chan)
 218{
 219        struct ad7746_chip_info *chip = iio_priv(indio_dev);
 220        int ret, delay;
 221        u8 vt_setup, cap_setup;
 222
 223        switch (chan->type) {
 224        case IIO_CAPACITANCE:
 225                cap_setup = (chan->address & 0xFF) | AD7746_CAPSETUP_CAPEN;
 226                vt_setup = chip->vt_setup & ~AD7746_VTSETUP_VTEN;
 227                delay = ad7746_cap_filter_rate_table[(chip->config >> 3) &
 228                        0x7][1];
 229
 230                if (chip->capdac_set != chan->channel) {
 231                        ret = i2c_smbus_write_byte_data(chip->client,
 232                                AD7746_REG_CAPDACA,
 233                                chip->capdac[chan->channel][0]);
 234                        if (ret < 0)
 235                                return ret;
 236                        ret = i2c_smbus_write_byte_data(chip->client,
 237                                AD7746_REG_CAPDACB,
 238                                chip->capdac[chan->channel][1]);
 239                        if (ret < 0)
 240                                return ret;
 241
 242                        chip->capdac_set = chan->channel;
 243                }
 244                break;
 245        case IIO_VOLTAGE:
 246        case IIO_TEMP:
 247                vt_setup = (chan->address & 0xFF) | AD7746_VTSETUP_VTEN;
 248                cap_setup = chip->cap_setup & ~AD7746_CAPSETUP_CAPEN;
 249                delay = ad7746_cap_filter_rate_table[(chip->config >> 6) &
 250                        0x3][1];
 251                break;
 252        default:
 253                return -EINVAL;
 254        }
 255
 256        if (chip->cap_setup != cap_setup) {
 257                ret = i2c_smbus_write_byte_data(chip->client,
 258                                                AD7746_REG_CAP_SETUP,
 259                                                cap_setup);
 260                if (ret < 0)
 261                        return ret;
 262
 263                chip->cap_setup = cap_setup;
 264        }
 265
 266        if (chip->vt_setup != vt_setup) {
 267                ret = i2c_smbus_write_byte_data(chip->client,
 268                                                AD7746_REG_VT_SETUP,
 269                                                vt_setup);
 270                if (ret < 0)
 271                        return ret;
 272
 273                chip->vt_setup = vt_setup;
 274        }
 275
 276        return delay;
 277}
 278
 279static inline ssize_t ad7746_start_calib(struct device *dev,
 280                                         struct device_attribute *attr,
 281                                         const char *buf,
 282                                         size_t len,
 283                                         u8 regval)
 284{
 285        struct iio_dev *indio_dev = dev_to_iio_dev(dev);
 286        struct ad7746_chip_info *chip = iio_priv(indio_dev);
 287        bool doit;
 288        int ret, timeout = 10;
 289
 290        ret = strtobool(buf, &doit);
 291        if (ret < 0)
 292                return ret;
 293
 294        if (!doit)
 295                return 0;
 296
 297        mutex_lock(&indio_dev->mlock);
 298        regval |= chip->config;
 299        ret = i2c_smbus_write_byte_data(chip->client, AD7746_REG_CFG, regval);
 300        if (ret < 0) {
 301                mutex_unlock(&indio_dev->mlock);
 302                return ret;
 303        }
 304
 305        do {
 306                msleep(20);
 307                ret = i2c_smbus_read_byte_data(chip->client, AD7746_REG_CFG);
 308                if (ret < 0) {
 309                        mutex_unlock(&indio_dev->mlock);
 310                        return ret;
 311                }
 312        } while ((ret == regval) && timeout--);
 313
 314        mutex_unlock(&indio_dev->mlock);
 315
 316        return len;
 317}
 318
 319static ssize_t ad7746_start_offset_calib(struct device *dev,
 320                                         struct device_attribute *attr,
 321                                         const char *buf,
 322                                         size_t len)
 323{
 324        struct iio_dev *indio_dev = dev_to_iio_dev(dev);
 325        int ret = ad7746_select_channel(indio_dev,
 326                              &ad7746_channels[to_iio_dev_attr(attr)->address]);
 327        if (ret < 0)
 328                return ret;
 329
 330        return ad7746_start_calib(dev, attr, buf, len,
 331                                  AD7746_CONF_MODE_OFFS_CAL);
 332}
 333
 334static ssize_t ad7746_start_gain_calib(struct device *dev,
 335                                       struct device_attribute *attr,
 336                                       const char *buf,
 337                                       size_t len)
 338{
 339        struct iio_dev *indio_dev = dev_to_iio_dev(dev);
 340        int ret = ad7746_select_channel(indio_dev,
 341                              &ad7746_channels[to_iio_dev_attr(attr)->address]);
 342        if (ret < 0)
 343                return ret;
 344
 345        return ad7746_start_calib(dev, attr, buf, len,
 346                                  AD7746_CONF_MODE_GAIN_CAL);
 347}
 348
 349static IIO_DEVICE_ATTR(in_capacitance0_calibbias_calibration,
 350                       S_IWUSR, NULL, ad7746_start_offset_calib, CIN1);
 351static IIO_DEVICE_ATTR(in_capacitance1_calibbias_calibration,
 352                       S_IWUSR, NULL, ad7746_start_offset_calib, CIN2);
 353static IIO_DEVICE_ATTR(in_capacitance0_calibscale_calibration,
 354                       S_IWUSR, NULL, ad7746_start_gain_calib, CIN1);
 355static IIO_DEVICE_ATTR(in_capacitance1_calibscale_calibration,
 356                       S_IWUSR, NULL, ad7746_start_gain_calib, CIN2);
 357static IIO_DEVICE_ATTR(in_voltage0_calibscale_calibration,
 358                       S_IWUSR, NULL, ad7746_start_gain_calib, VIN);
 359
 360static ssize_t ad7746_show_cap_filter_rate_setup(struct device *dev,
 361                struct device_attribute *attr,
 362                char *buf)
 363{
 364        struct iio_dev *indio_dev = dev_to_iio_dev(dev);
 365        struct ad7746_chip_info *chip = iio_priv(indio_dev);
 366
 367        return sprintf(buf, "%d\n", ad7746_cap_filter_rate_table[
 368                        (chip->config >> 3) & 0x7][0]);
 369}
 370
 371static ssize_t ad7746_store_cap_filter_rate_setup(struct device *dev,
 372                struct device_attribute *attr,
 373                const char *buf,
 374                size_t len)
 375{
 376        struct iio_dev *indio_dev = dev_to_iio_dev(dev);
 377        struct ad7746_chip_info *chip = iio_priv(indio_dev);
 378        u8 data;
 379        int ret, i;
 380
 381        ret = kstrtou8(buf, 10, &data);
 382        if (ret < 0)
 383                return ret;
 384
 385        for (i = 0; i < ARRAY_SIZE(ad7746_cap_filter_rate_table); i++)
 386                if (data >= ad7746_cap_filter_rate_table[i][0])
 387                        break;
 388
 389        if (i >= ARRAY_SIZE(ad7746_cap_filter_rate_table))
 390                i = ARRAY_SIZE(ad7746_cap_filter_rate_table) - 1;
 391
 392        mutex_lock(&indio_dev->mlock);
 393        chip->config &= ~AD7746_CONF_CAPFS(0x7);
 394        chip->config |= AD7746_CONF_CAPFS(i);
 395        mutex_unlock(&indio_dev->mlock);
 396
 397        return len;
 398}
 399
 400static ssize_t ad7746_show_vt_filter_rate_setup(struct device *dev,
 401                struct device_attribute *attr,
 402                char *buf)
 403{
 404        struct iio_dev *indio_dev = dev_to_iio_dev(dev);
 405        struct ad7746_chip_info *chip = iio_priv(indio_dev);
 406
 407        return sprintf(buf, "%d\n", ad7746_vt_filter_rate_table[
 408                        (chip->config >> 6) & 0x3][0]);
 409}
 410
 411static ssize_t ad7746_store_vt_filter_rate_setup(struct device *dev,
 412                struct device_attribute *attr,
 413                const char *buf,
 414                size_t len)
 415{
 416        struct iio_dev *indio_dev = dev_to_iio_dev(dev);
 417        struct ad7746_chip_info *chip = iio_priv(indio_dev);
 418        u8 data;
 419        int ret, i;
 420
 421        ret = kstrtou8(buf, 10, &data);
 422        if (ret < 0)
 423                return ret;
 424
 425        for (i = 0; i < ARRAY_SIZE(ad7746_vt_filter_rate_table); i++)
 426                if (data >= ad7746_vt_filter_rate_table[i][0])
 427                        break;
 428
 429        if (i >= ARRAY_SIZE(ad7746_vt_filter_rate_table))
 430                i = ARRAY_SIZE(ad7746_vt_filter_rate_table) - 1;
 431
 432        mutex_lock(&indio_dev->mlock);
 433        chip->config &= ~AD7746_CONF_VTFS(0x3);
 434        chip->config |= AD7746_CONF_VTFS(i);
 435        mutex_unlock(&indio_dev->mlock);
 436
 437        return len;
 438}
 439
 440static IIO_DEVICE_ATTR(in_capacitance_sampling_frequency,
 441                       S_IRUGO | S_IWUSR, ad7746_show_cap_filter_rate_setup,
 442                        ad7746_store_cap_filter_rate_setup, 0);
 443
 444static IIO_DEVICE_ATTR(in_voltage_sampling_frequency,
 445                       S_IRUGO | S_IWUSR, ad7746_show_vt_filter_rate_setup,
 446                       ad7746_store_vt_filter_rate_setup, 0);
 447
 448static IIO_CONST_ATTR(in_voltage_sampling_frequency_available, "50 31 16 8");
 449static IIO_CONST_ATTR(in_capacitance_sampling_frequency_available,
 450                       "91 84 50 26 16 13 11 9");
 451
 452static struct attribute *ad7746_attributes[] = {
 453        &iio_dev_attr_in_capacitance_sampling_frequency.dev_attr.attr,
 454        &iio_dev_attr_in_voltage_sampling_frequency.dev_attr.attr,
 455        &iio_dev_attr_in_capacitance0_calibbias_calibration.dev_attr.attr,
 456        &iio_dev_attr_in_capacitance0_calibscale_calibration.dev_attr.attr,
 457        &iio_dev_attr_in_capacitance1_calibscale_calibration.dev_attr.attr,
 458        &iio_dev_attr_in_capacitance1_calibbias_calibration.dev_attr.attr,
 459        &iio_dev_attr_in_voltage0_calibscale_calibration.dev_attr.attr,
 460        &iio_const_attr_in_voltage_sampling_frequency_available.dev_attr.attr,
 461        &iio_const_attr_in_capacitance_sampling_frequency_available.
 462        dev_attr.attr,
 463        NULL,
 464};
 465
 466static const struct attribute_group ad7746_attribute_group = {
 467        .attrs = ad7746_attributes,
 468};
 469
 470static int ad7746_write_raw(struct iio_dev *indio_dev,
 471                            struct iio_chan_spec const *chan,
 472                            int val,
 473                            int val2,
 474                            long mask)
 475{
 476        struct ad7746_chip_info *chip = iio_priv(indio_dev);
 477        int ret, reg;
 478
 479        mutex_lock(&indio_dev->mlock);
 480
 481        switch (mask) {
 482        case IIO_CHAN_INFO_CALIBSCALE:
 483                if (val != 1) {
 484                        ret = -EINVAL;
 485                        goto out;
 486                }
 487
 488                val = (val2 * 1024) / 15625;
 489
 490                switch (chan->type) {
 491                case IIO_CAPACITANCE:
 492                        reg = AD7746_REG_CAP_GAINH;
 493                        break;
 494                case IIO_VOLTAGE:
 495                        reg = AD7746_REG_VOLT_GAINH;
 496                        break;
 497                default:
 498                        ret = -EINVAL;
 499                        goto out;
 500                }
 501
 502                ret = i2c_smbus_write_word_data(chip->client, reg, swab16(val));
 503                if (ret < 0)
 504                        goto out;
 505
 506                ret = 0;
 507                break;
 508        case IIO_CHAN_INFO_CALIBBIAS:
 509                if ((val < 0) | (val > 0xFFFF)) {
 510                        ret = -EINVAL;
 511                        goto out;
 512                }
 513                ret = i2c_smbus_write_word_data(chip->client,
 514                                AD7746_REG_CAP_OFFH, swab16(val));
 515                if (ret < 0)
 516                        goto out;
 517
 518                ret = 0;
 519                break;
 520        case IIO_CHAN_INFO_OFFSET:
 521                if ((val < 0) | (val > 43008000)) { /* 21pF */
 522                        ret = -EINVAL;
 523                        goto out;
 524                }
 525
 526                /* CAPDAC Scale = 21pF_typ / 127
 527                 * CIN Scale = 8.192pF / 2^24
 528                 * Offset Scale = CAPDAC Scale / CIN Scale = 338646
 529                 * */
 530
 531                val /= 338646;
 532
 533                chip->capdac[chan->channel][chan->differential] = (val > 0 ?
 534                        AD7746_CAPDAC_DACP(val) | AD7746_CAPDAC_DACEN : 0);
 535
 536                ret = i2c_smbus_write_byte_data(chip->client,
 537                        AD7746_REG_CAPDACA,
 538                        chip->capdac[chan->channel][0]);
 539                if (ret < 0)
 540                        goto out;
 541                ret = i2c_smbus_write_byte_data(chip->client,
 542                        AD7746_REG_CAPDACB,
 543                        chip->capdac[chan->channel][1]);
 544                if (ret < 0)
 545                        goto out;
 546
 547                chip->capdac_set = chan->channel;
 548
 549                ret = 0;
 550                break;
 551        default:
 552                ret = -EINVAL;
 553        }
 554
 555out:
 556        mutex_unlock(&indio_dev->mlock);
 557        return ret;
 558}
 559
 560static int ad7746_read_raw(struct iio_dev *indio_dev,
 561                           struct iio_chan_spec const *chan,
 562                           int *val, int *val2,
 563                           long mask)
 564{
 565        struct ad7746_chip_info *chip = iio_priv(indio_dev);
 566        int ret, delay;
 567        u8 regval, reg;
 568
 569        union {
 570                u32 d32;
 571                u8 d8[4];
 572        } data;
 573
 574        mutex_lock(&indio_dev->mlock);
 575
 576        switch (mask) {
 577        case IIO_CHAN_INFO_RAW:
 578        case IIO_CHAN_INFO_PROCESSED:
 579                ret = ad7746_select_channel(indio_dev, chan);
 580                if (ret < 0)
 581                        goto out;
 582                delay = ret;
 583
 584                regval = chip->config | AD7746_CONF_MODE_SINGLE_CONV;
 585                ret = i2c_smbus_write_byte_data(chip->client, AD7746_REG_CFG,
 586                                regval);
 587                if (ret < 0)
 588                        goto out;
 589
 590                msleep(delay);
 591                /* Now read the actual register */
 592
 593                ret = i2c_smbus_read_i2c_block_data(chip->client,
 594                        chan->address >> 8, 3, &data.d8[1]);
 595
 596                if (ret < 0)
 597                        goto out;
 598
 599                *val = (be32_to_cpu(data.d32) & 0xFFFFFF) - 0x800000;
 600
 601                switch (chan->type) {
 602                case IIO_TEMP:
 603                /* temperature in milli degrees Celsius
 604                 * T = ((*val / 2048) - 4096) * 1000
 605                 */
 606                        *val = (*val * 125) / 256;
 607                        break;
 608                case IIO_VOLTAGE:
 609                        if (chan->channel == 1) /* supply_raw*/
 610                                *val = *val * 6;
 611                        break;
 612                default:
 613                        break;
 614                }
 615
 616                ret = IIO_VAL_INT;
 617                break;
 618        case IIO_CHAN_INFO_CALIBSCALE:
 619                switch (chan->type) {
 620                case IIO_CAPACITANCE:
 621                        reg = AD7746_REG_CAP_GAINH;
 622                        break;
 623                case IIO_VOLTAGE:
 624                        reg = AD7746_REG_VOLT_GAINH;
 625                        break;
 626                default:
 627                        ret = -EINVAL;
 628                        goto out;
 629                }
 630
 631                ret = i2c_smbus_read_word_data(chip->client, reg);
 632                if (ret < 0)
 633                        goto out;
 634                /* 1 + gain_val / 2^16 */
 635                *val = 1;
 636                *val2 = (15625 * swab16(ret)) / 1024;
 637
 638                ret = IIO_VAL_INT_PLUS_MICRO;
 639                break;
 640        case IIO_CHAN_INFO_CALIBBIAS:
 641                ret = i2c_smbus_read_word_data(chip->client,
 642                                               AD7746_REG_CAP_OFFH);
 643                if (ret < 0)
 644                        goto out;
 645                *val = swab16(ret);
 646
 647                ret = IIO_VAL_INT;
 648                break;
 649        case IIO_CHAN_INFO_OFFSET:
 650                *val = AD7746_CAPDAC_DACP(chip->capdac[chan->channel]
 651                        [chan->differential]) * 338646;
 652
 653                ret = IIO_VAL_INT;
 654                break;
 655        case IIO_CHAN_INFO_SCALE:
 656                switch (chan->type) {
 657                case IIO_CAPACITANCE:
 658                        /* 8.192pf / 2^24 */
 659                        *val2 = 488;
 660                        *val =  0;
 661                        break;
 662                case IIO_VOLTAGE:
 663                        /* 1170mV / 2^23 */
 664                        *val2 = 139475;
 665                        *val =  0;
 666                        break;
 667                default:
 668                        ret =  -EINVAL;
 669                        goto out;
 670                }
 671
 672                ret = IIO_VAL_INT_PLUS_NANO;
 673                break;
 674        default:
 675                ret = -EINVAL;
 676        }
 677out:
 678        mutex_unlock(&indio_dev->mlock);
 679        return ret;
 680}
 681
 682static const struct iio_info ad7746_info = {
 683        .attrs = &ad7746_attribute_group,
 684        .read_raw = &ad7746_read_raw,
 685        .write_raw = &ad7746_write_raw,
 686        .driver_module = THIS_MODULE,
 687};
 688
 689/*
 690 * device probe and remove
 691 */
 692
 693static int ad7746_probe(struct i2c_client *client,
 694                const struct i2c_device_id *id)
 695{
 696        struct ad7746_platform_data *pdata = client->dev.platform_data;
 697        struct ad7746_chip_info *chip;
 698        struct iio_dev *indio_dev;
 699        int ret = 0;
 700        unsigned char regval = 0;
 701
 702        indio_dev = iio_device_alloc(sizeof(*chip));
 703        if (indio_dev == NULL) {
 704                ret = -ENOMEM;
 705                goto error_ret;
 706        }
 707        chip = iio_priv(indio_dev);
 708        /* this is only used for device removal purposes */
 709        i2c_set_clientdata(client, indio_dev);
 710
 711        chip->client = client;
 712        chip->capdac_set = -1;
 713
 714        /* Establish that the iio_dev is a child of the i2c device */
 715        indio_dev->name = id->name;
 716        indio_dev->dev.parent = &client->dev;
 717        indio_dev->info = &ad7746_info;
 718        indio_dev->channels = ad7746_channels;
 719        if (id->driver_data == 7746)
 720                indio_dev->num_channels = ARRAY_SIZE(ad7746_channels);
 721        else
 722                indio_dev->num_channels =  ARRAY_SIZE(ad7746_channels) - 2;
 723        indio_dev->num_channels = ARRAY_SIZE(ad7746_channels);
 724        indio_dev->modes = INDIO_DIRECT_MODE;
 725
 726        if (pdata) {
 727                if (pdata->exca_en) {
 728                        if (pdata->exca_inv_en)
 729                                regval |= AD7746_EXCSETUP_NEXCA;
 730                        else
 731                                regval |= AD7746_EXCSETUP_EXCA;
 732                }
 733
 734                if (pdata->excb_en) {
 735                        if (pdata->excb_inv_en)
 736                                regval |= AD7746_EXCSETUP_NEXCB;
 737                        else
 738                                regval |= AD7746_EXCSETUP_EXCB;
 739                }
 740
 741                regval |= AD7746_EXCSETUP_EXCLVL(pdata->exclvl);
 742        } else {
 743                dev_warn(&client->dev, "No platform data? using default\n");
 744                regval = AD7746_EXCSETUP_EXCA | AD7746_EXCSETUP_EXCB |
 745                        AD7746_EXCSETUP_EXCLVL(3);
 746        }
 747
 748        ret = i2c_smbus_write_byte_data(chip->client,
 749                                        AD7746_REG_EXC_SETUP, regval);
 750        if (ret < 0)
 751                goto error_free_dev;
 752
 753        ret = iio_device_register(indio_dev);
 754        if (ret)
 755                goto error_free_dev;
 756
 757        dev_info(&client->dev, "%s capacitive sensor registered\n", id->name);
 758
 759        return 0;
 760
 761error_free_dev:
 762        iio_device_free(indio_dev);
 763error_ret:
 764        return ret;
 765}
 766
 767static int ad7746_remove(struct i2c_client *client)
 768{
 769        struct iio_dev *indio_dev = i2c_get_clientdata(client);
 770
 771        iio_device_unregister(indio_dev);
 772        iio_device_free(indio_dev);
 773
 774        return 0;
 775}
 776
 777static const struct i2c_device_id ad7746_id[] = {
 778        { "ad7745", 7745 },
 779        { "ad7746", 7746 },
 780        { "ad7747", 7747 },
 781        {}
 782};
 783
 784MODULE_DEVICE_TABLE(i2c, ad7746_id);
 785
 786static struct i2c_driver ad7746_driver = {
 787        .driver = {
 788                .name = KBUILD_MODNAME,
 789        },
 790        .probe = ad7746_probe,
 791        .remove = ad7746_remove,
 792        .id_table = ad7746_id,
 793};
 794module_i2c_driver(ad7746_driver);
 795
 796MODULE_AUTHOR("Michael Hennerich <hennerich@blackfin.uclinux.org>");
 797MODULE_DESCRIPTION("Analog Devices AD7746/5/7 capacitive sensor driver");
 798MODULE_LICENSE("GPL v2");
 799