linux/drivers/staging/iio/adc/ad7298.c
<<
>>
Prefs
   1/*
   2 * AD7298 digital temperature sensor driver supporting AD7298
   3 *
   4 * Copyright 2010 Analog Devices Inc.
   5 *
   6 * Licensed under the GPL-2 or later.
   7 */
   8
   9#include <linux/interrupt.h>
  10#include <linux/gpio.h>
  11#include <linux/workqueue.h>
  12#include <linux/device.h>
  13#include <linux/kernel.h>
  14#include <linux/slab.h>
  15#include <linux/sysfs.h>
  16#include <linux/list.h>
  17#include <linux/spi/spi.h>
  18#include <linux/rtc.h>
  19
  20#include "../iio.h"
  21#include "../sysfs.h"
  22
  23/*
  24 * AD7298 command
  25 */
  26#define AD7298_PD                       0x1
  27#define AD7298_T_AVG_MASK               0x2
  28#define AD7298_EXT_REF                  0x4
  29#define AD7298_T_SENSE_MASK             0x20
  30#define AD7298_VOLTAGE_MASK             0x3fc0
  31#define AD7298_VOLTAGE_OFFSET           0x6
  32#define AD7298_VOLTAGE_LIMIT_COUNT      8
  33#define AD7298_REPEAT                   0x40
  34#define AD7298_WRITE                    0x80
  35
  36/*
  37 * AD7298 value masks
  38 */
  39#define AD7298_CHANNEL_MASK             0xf000
  40#define AD7298_VALUE_MASK               0xfff
  41#define AD7298_T_VALUE_SIGN             0x400
  42#define AD7298_T_VALUE_FLOAT_OFFSET     2
  43#define AD7298_T_VALUE_FLOAT_MASK       0x2
  44
  45/*
  46 * struct ad7298_chip_info - chip specifc information
  47 */
  48
  49struct ad7298_chip_info {
  50        const char *name;
  51        struct spi_device *spi_dev;
  52        struct iio_dev *indio_dev;
  53        u16 command;
  54        u16 busy_pin;
  55        u8  channels;   /* Active voltage channels */
  56};
  57
  58/*
  59 * ad7298 register access by SPI
  60 */
  61static int ad7298_spi_write(struct ad7298_chip_info *chip, u16 data)
  62{
  63        struct spi_device *spi_dev = chip->spi_dev;
  64        int ret = 0;
  65
  66        data |= AD7298_WRITE;
  67        data = cpu_to_be16(data);
  68        ret = spi_write(spi_dev, (u8 *)&data, sizeof(data));
  69        if (ret < 0)
  70                dev_err(&spi_dev->dev, "SPI write error\n");
  71
  72        return ret;
  73}
  74
  75static int ad7298_spi_read(struct ad7298_chip_info *chip, u16 mask, u16 *data)
  76{
  77        struct spi_device *spi_dev = chip->spi_dev;
  78        int ret = 0;
  79        u8 count = chip->channels;
  80        u16 command;
  81        int i;
  82
  83        if (mask & AD7298_T_SENSE_MASK) {
  84                command = chip->command & ~(AD7298_T_AVG_MASK | AD7298_VOLTAGE_MASK);
  85                command |= AD7298_T_SENSE_MASK;
  86                count = 1;
  87        } else if (mask & AD7298_T_AVG_MASK) {
  88                command = chip->command & ~AD7298_VOLTAGE_MASK;
  89                command |= AD7298_T_SENSE_MASK | AD7298_T_AVG_MASK;
  90                count = 2;
  91        } else if (mask & AD7298_VOLTAGE_MASK) {
  92                command = chip->command & ~(AD7298_T_AVG_MASK | AD7298_T_SENSE_MASK);
  93                count = chip->channels;
  94        }
  95
  96        ret = ad7298_spi_write(chip, chip->command);
  97        if (ret < 0) {
  98                dev_err(&spi_dev->dev, "SPI write command error\n");
  99                return ret;
 100        }
 101
 102        ret = spi_read(spi_dev, (u8 *)&command, sizeof(command));
 103        if (ret < 0) {
 104                dev_err(&spi_dev->dev, "SPI read error\n");
 105                return ret;
 106        }
 107
 108        i = 10000;
 109        while (i && gpio_get_value(chip->busy_pin)) {
 110                cpu_relax();
 111                i--;
 112        }
 113        if (!i) {
 114                dev_err(&spi_dev->dev, "Always in busy convertion.\n");
 115                return -EBUSY;
 116        }
 117
 118        for (i = 0; i < count; i++) {
 119                ret = spi_read(spi_dev, (u8 *)&data[i], sizeof(data[i]));
 120                if (ret < 0) {
 121                        dev_err(&spi_dev->dev, "SPI read error\n");
 122                        return ret;
 123                }
 124                *data = be16_to_cpu(data[i]);
 125        }
 126
 127        return 0;
 128}
 129
 130static ssize_t ad7298_show_mode(struct device *dev,
 131                struct device_attribute *attr,
 132                char *buf)
 133{
 134        struct iio_dev *dev_info = dev_get_drvdata(dev);
 135        struct ad7298_chip_info *chip = dev_info->dev_data;
 136
 137        if (chip->command & AD7298_REPEAT)
 138                return sprintf(buf, "repeat\n");
 139        else
 140                return sprintf(buf, "normal\n");
 141}
 142
 143static ssize_t ad7298_store_mode(struct device *dev,
 144                struct device_attribute *attr,
 145                const char *buf,
 146                size_t len)
 147{
 148        struct iio_dev *dev_info = dev_get_drvdata(dev);
 149        struct ad7298_chip_info *chip = dev_info->dev_data;
 150
 151        if (strcmp(buf, "repeat"))
 152                chip->command |= AD7298_REPEAT;
 153        else
 154                chip->command &= (~AD7298_REPEAT);
 155
 156        return 1;
 157}
 158
 159static IIO_DEVICE_ATTR(mode, S_IRUGO | S_IWUSR,
 160                ad7298_show_mode,
 161                ad7298_store_mode,
 162                0);
 163
 164static ssize_t ad7298_show_available_modes(struct device *dev,
 165                struct device_attribute *attr,
 166                char *buf)
 167{
 168        return sprintf(buf, "normal\nrepeat\n");
 169}
 170
 171static IIO_DEVICE_ATTR(available_modes, S_IRUGO, ad7298_show_available_modes, NULL, 0);
 172
 173static ssize_t ad7298_store_reset(struct device *dev,
 174                struct device_attribute *attr,
 175                const char *buf,
 176                size_t len)
 177{
 178        struct iio_dev *dev_info = dev_get_drvdata(dev);
 179        struct ad7298_chip_info *chip = dev_info->dev_data;
 180        u16 command;
 181        int ret;
 182
 183        command = chip->command & ~AD7298_PD;
 184
 185        ret = ad7298_spi_write(chip, command);
 186        if (ret)
 187                return -EIO;
 188
 189        command = chip->command | AD7298_PD;
 190
 191        ret = ad7298_spi_write(chip, command);
 192        if (ret)
 193                return -EIO;
 194
 195        return len;
 196}
 197
 198static IIO_DEVICE_ATTR(reset, S_IWUSR,
 199                NULL,
 200                ad7298_store_reset,
 201                0);
 202
 203static ssize_t ad7298_show_ext_ref(struct device *dev,
 204                struct device_attribute *attr,
 205                char *buf)
 206{
 207        struct iio_dev *dev_info = dev_get_drvdata(dev);
 208        struct ad7298_chip_info *chip = dev_info->dev_data;
 209
 210        return sprintf(buf, "%d\n", !!(chip->command & AD7298_EXT_REF));
 211}
 212
 213static ssize_t ad7298_store_ext_ref(struct device *dev,
 214                struct device_attribute *attr,
 215                const char *buf,
 216                size_t len)
 217{
 218        struct iio_dev *dev_info = dev_get_drvdata(dev);
 219        struct ad7298_chip_info *chip = dev_info->dev_data;
 220        u16 command;
 221        int ret;
 222
 223        command = chip->command & (~AD7298_EXT_REF);
 224        if (strcmp(buf, "1"))
 225                command |= AD7298_EXT_REF;
 226
 227        ret = ad7298_spi_write(chip, command);
 228        if (ret)
 229                return -EIO;
 230
 231        chip->command = command;
 232
 233        return len;
 234}
 235
 236static IIO_DEVICE_ATTR(ext_ref, S_IRUGO | S_IWUSR,
 237                ad7298_show_ext_ref,
 238                ad7298_store_ext_ref,
 239                0);
 240
 241static ssize_t ad7298_show_t_sense(struct device *dev,
 242                struct device_attribute *attr,
 243                char *buf)
 244{
 245        struct iio_dev *dev_info = dev_get_drvdata(dev);
 246        struct ad7298_chip_info *chip = dev_info->dev_data;
 247        u16 data;
 248        char sign = ' ';
 249        int ret;
 250
 251        ret = ad7298_spi_read(chip, AD7298_T_SENSE_MASK, &data);
 252        if (ret)
 253                return -EIO;
 254
 255        if (data & AD7298_T_VALUE_SIGN) {
 256                /* convert supplement to positive value */
 257                data = (AD7298_T_VALUE_SIGN << 1) - data;
 258                sign = '-';
 259        }
 260
 261        return sprintf(buf, "%c%d.%.2d\n", sign,
 262                (data >> AD7298_T_VALUE_FLOAT_OFFSET),
 263                (data & AD7298_T_VALUE_FLOAT_MASK) * 25);
 264}
 265
 266static IIO_DEVICE_ATTR(t_sense, S_IRUGO, ad7298_show_t_sense, NULL, 0);
 267
 268static ssize_t ad7298_show_t_average(struct device *dev,
 269                struct device_attribute *attr,
 270                char *buf)
 271{
 272        struct iio_dev *dev_info = dev_get_drvdata(dev);
 273        struct ad7298_chip_info *chip = dev_info->dev_data;
 274        u16 data[2];
 275        char sign = ' ';
 276        int ret;
 277
 278        ret = ad7298_spi_read(chip, AD7298_T_AVG_MASK, data);
 279        if (ret)
 280                return -EIO;
 281
 282        if (data[1] & AD7298_T_VALUE_SIGN) {
 283                /* convert supplement to positive value */
 284                data[1] = (AD7298_T_VALUE_SIGN << 1) - data[1];
 285                sign = '-';
 286        }
 287
 288        return sprintf(buf, "%c%d.%.2d\n", sign,
 289                (data[1] >> AD7298_T_VALUE_FLOAT_OFFSET),
 290                (data[1] & AD7298_T_VALUE_FLOAT_MASK) * 25);
 291}
 292
 293static IIO_DEVICE_ATTR(t_average, S_IRUGO, ad7298_show_t_average, NULL, 0);
 294
 295static ssize_t ad7298_show_voltage(struct device *dev,
 296                struct device_attribute *attr,
 297                char *buf)
 298{
 299        struct iio_dev *dev_info = dev_get_drvdata(dev);
 300        struct ad7298_chip_info *chip = dev_info->dev_data;
 301        u16 data[AD7298_VOLTAGE_LIMIT_COUNT];
 302        int i, size, ret;
 303
 304        ret = ad7298_spi_read(chip, AD7298_VOLTAGE_MASK, data);
 305        if (ret)
 306                return -EIO;
 307
 308        for (i = 0; i < AD7298_VOLTAGE_LIMIT_COUNT; i++) {
 309                if (chip->command & (AD7298_T_SENSE_MASK << i)) {
 310                        ret = sprintf(buf, "channel[%d]=%d\n", i,
 311                                        data[i] & AD7298_VALUE_MASK);
 312                        if (ret < 0)
 313                                break;
 314                        buf += ret;
 315                        size += ret;
 316                }
 317        }
 318
 319        return size;
 320}
 321
 322static IIO_DEVICE_ATTR(voltage, S_IRUGO, ad7298_show_voltage, NULL, 0);
 323
 324static ssize_t ad7298_show_channel_mask(struct device *dev,
 325                struct device_attribute *attr,
 326                char *buf)
 327{
 328        struct iio_dev *dev_info = dev_get_drvdata(dev);
 329        struct ad7298_chip_info *chip = dev_info->dev_data;
 330
 331        return sprintf(buf, "0x%x\n", (chip->command & AD7298_VOLTAGE_MASK) >>
 332                        AD7298_VOLTAGE_OFFSET);
 333}
 334
 335static ssize_t ad7298_store_channel_mask(struct device *dev,
 336                struct device_attribute *attr,
 337                const char *buf,
 338                size_t len)
 339{
 340        struct iio_dev *dev_info = dev_get_drvdata(dev);
 341        struct ad7298_chip_info *chip = dev_info->dev_data;
 342        unsigned long data;
 343        int i, ret;
 344
 345        ret = strict_strtoul(buf, 16, &data);
 346        if (ret || data > 0xff)
 347                return -EINVAL;
 348
 349        chip->command &= (~AD7298_VOLTAGE_MASK);
 350        chip->command |= data << AD7298_VOLTAGE_OFFSET;
 351
 352        for (i = 0, chip->channels = 0; i < AD7298_VOLTAGE_LIMIT_COUNT; i++) {
 353                if (chip->command & (AD7298_T_SENSE_MASK << i))
 354                        chip->channels++;
 355        }
 356
 357        return ret;
 358}
 359
 360static IIO_DEVICE_ATTR(channel_mask, S_IRUGO | S_IWUSR,
 361                ad7298_show_channel_mask,
 362                ad7298_store_channel_mask,
 363                0);
 364
 365static ssize_t ad7298_show_name(struct device *dev,
 366                struct device_attribute *attr,
 367                char *buf)
 368{
 369        struct iio_dev *dev_info = dev_get_drvdata(dev);
 370        struct ad7298_chip_info *chip = dev_info->dev_data;
 371        return sprintf(buf, "%s\n", chip->name);
 372}
 373
 374static IIO_DEVICE_ATTR(name, S_IRUGO, ad7298_show_name, NULL, 0);
 375
 376static struct attribute *ad7298_attributes[] = {
 377        &iio_dev_attr_available_modes.dev_attr.attr,
 378        &iio_dev_attr_mode.dev_attr.attr,
 379        &iio_dev_attr_reset.dev_attr.attr,
 380        &iio_dev_attr_ext_ref.dev_attr.attr,
 381        &iio_dev_attr_t_sense.dev_attr.attr,
 382        &iio_dev_attr_t_average.dev_attr.attr,
 383        &iio_dev_attr_voltage.dev_attr.attr,
 384        &iio_dev_attr_channel_mask.dev_attr.attr,
 385        &iio_dev_attr_name.dev_attr.attr,
 386        NULL,
 387};
 388
 389static const struct attribute_group ad7298_attribute_group = {
 390        .attrs = ad7298_attributes,
 391};
 392
 393/*
 394 * device probe and remove
 395 */
 396static int __devinit ad7298_probe(struct spi_device *spi_dev)
 397{
 398        struct ad7298_chip_info *chip;
 399        unsigned short *pins = spi_dev->dev.platform_data;
 400        int ret = 0;
 401
 402        chip = kzalloc(sizeof(struct ad7298_chip_info), GFP_KERNEL);
 403
 404        if (chip == NULL)
 405                return -ENOMEM;
 406
 407        /* this is only used for device removal purposes */
 408        dev_set_drvdata(&spi_dev->dev, chip);
 409
 410        chip->spi_dev = spi_dev;
 411        chip->name = spi_dev->modalias;
 412        chip->busy_pin = pins[0];
 413
 414        ret = gpio_request(chip->busy_pin, chip->name);
 415        if (ret) {
 416                dev_err(&spi_dev->dev, "Fail to request busy gpio PIN %d.\n",
 417                        chip->busy_pin);
 418                goto error_free_chip;
 419        }
 420        gpio_direction_input(chip->busy_pin);
 421
 422        chip->indio_dev = iio_allocate_device();
 423        if (chip->indio_dev == NULL) {
 424                ret = -ENOMEM;
 425                goto error_free_gpio;
 426        }
 427
 428        chip->indio_dev->dev.parent = &spi_dev->dev;
 429        chip->indio_dev->attrs = &ad7298_attribute_group;
 430        chip->indio_dev->dev_data = (void *)chip;
 431        chip->indio_dev->driver_module = THIS_MODULE;
 432        chip->indio_dev->modes = INDIO_DIRECT_MODE;
 433
 434        ret = iio_device_register(chip->indio_dev);
 435        if (ret)
 436                goto error_free_dev;
 437
 438        dev_info(&spi_dev->dev, "%s temperature sensor and ADC registered.\n",
 439                         chip->name);
 440
 441        return 0;
 442
 443error_free_dev:
 444        iio_free_device(chip->indio_dev);
 445error_free_gpio:
 446        gpio_free(chip->busy_pin);
 447error_free_chip:
 448        kfree(chip);
 449
 450        return ret;
 451}
 452
 453static int __devexit ad7298_remove(struct spi_device *spi_dev)
 454{
 455        struct ad7298_chip_info *chip = dev_get_drvdata(&spi_dev->dev);
 456        struct iio_dev *indio_dev = chip->indio_dev;
 457
 458        dev_set_drvdata(&spi_dev->dev, NULL);
 459        iio_device_unregister(indio_dev);
 460        iio_free_device(chip->indio_dev);
 461        gpio_free(chip->busy_pin);
 462        kfree(chip);
 463
 464        return 0;
 465}
 466
 467static const struct spi_device_id ad7298_id[] = {
 468        { "ad7298", 0 },
 469        {}
 470};
 471
 472MODULE_DEVICE_TABLE(spi, ad7298_id);
 473
 474static struct spi_driver ad7298_driver = {
 475        .driver = {
 476                .name = "ad7298",
 477                .bus = &spi_bus_type,
 478                .owner = THIS_MODULE,
 479        },
 480        .probe = ad7298_probe,
 481        .remove = __devexit_p(ad7298_remove),
 482        .id_table = ad7298_id,
 483};
 484
 485static __init int ad7298_init(void)
 486{
 487        return spi_register_driver(&ad7298_driver);
 488}
 489
 490static __exit void ad7298_exit(void)
 491{
 492        spi_unregister_driver(&ad7298_driver);
 493}
 494
 495MODULE_AUTHOR("Sonic Zhang <sonic.zhang@analog.com>");
 496MODULE_DESCRIPTION("Analog Devices AD7298 digital"
 497                        " temperature sensor and ADC driver");
 498MODULE_LICENSE("GPL v2");
 499
 500module_init(ad7298_init);
 501module_exit(ad7298_exit);
 502