linux/drivers/staging/iio/adc/ad7816.c
<<
>>
Prefs
   1/*
   2 * AD7816 digital temperature sensor driver supporting AD7816/7/8
   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 * AD7816 config masks
  25 */
  26#define AD7816_FULL                     0x1
  27#define AD7816_PD                       0x2
  28#define AD7816_CS_MASK                  0x7
  29#define AD7816_CS_MAX                   0x4
  30
  31/*
  32 * AD7816 temperature masks
  33 */
  34#define AD7816_VALUE_OFFSET             6
  35#define AD7816_BOUND_VALUE_BASE         0x8
  36#define AD7816_BOUND_VALUE_MIN          -95
  37#define AD7816_BOUND_VALUE_MAX          152
  38#define AD7816_TEMP_FLOAT_OFFSET        2
  39#define AD7816_TEMP_FLOAT_MASK          0x3
  40
  41
  42/*
  43 * struct ad7816_chip_info - chip specifc information
  44 */
  45
  46struct ad7816_chip_info {
  47        const char *name;
  48        struct spi_device *spi_dev;
  49        struct iio_dev *indio_dev;
  50        struct work_struct thresh_work;
  51        s64 last_timestamp;
  52        u16 rdwr_pin;
  53        u16 convert_pin;
  54        u16 busy_pin;
  55        u8  oti_data[AD7816_CS_MAX+1];
  56        u8  channel_id; /* 0 always be temperature */
  57        u8  mode;
  58};
  59
  60/*
  61 * ad7816 data access by SPI
  62 */
  63static int ad7816_spi_read(struct ad7816_chip_info *chip, u16 *data)
  64{
  65        struct spi_device *spi_dev = chip->spi_dev;
  66        int ret = 0;
  67
  68        gpio_set_value(chip->rdwr_pin, 1);
  69        gpio_set_value(chip->rdwr_pin, 0);
  70        ret = spi_write(spi_dev, &chip->channel_id, sizeof(chip->channel_id));
  71        if (ret < 0) {
  72                dev_err(&spi_dev->dev, "SPI channel setting error\n");
  73                return ret;
  74        }
  75        gpio_set_value(chip->rdwr_pin, 1);
  76
  77
  78        if (chip->mode == AD7816_PD) { /* operating mode 2 */
  79                gpio_set_value(chip->convert_pin, 1);
  80                gpio_set_value(chip->convert_pin, 0);
  81        } else { /* operating mode 1 */
  82                gpio_set_value(chip->convert_pin, 0);
  83                gpio_set_value(chip->convert_pin, 1);
  84        }
  85
  86        while (gpio_get_value(chip->busy_pin))
  87                cpu_relax();
  88
  89        gpio_set_value(chip->rdwr_pin, 0);
  90        gpio_set_value(chip->rdwr_pin, 1);
  91        ret = spi_read(spi_dev, (u8 *)data, sizeof(*data));
  92        if (ret < 0) {
  93                dev_err(&spi_dev->dev, "SPI data read error\n");
  94                return ret;
  95        }
  96
  97        *data = be16_to_cpu(*data);
  98
  99        return ret;
 100}
 101
 102static int ad7816_spi_write(struct ad7816_chip_info *chip, u8 data)
 103{
 104        struct spi_device *spi_dev = chip->spi_dev;
 105        int ret = 0;
 106
 107        gpio_set_value(chip->rdwr_pin, 1);
 108        gpio_set_value(chip->rdwr_pin, 0);
 109        ret = spi_write(spi_dev, &data, sizeof(data));
 110        if (ret < 0)
 111                dev_err(&spi_dev->dev, "SPI oti data write error\n");
 112
 113        return ret;
 114}
 115
 116static ssize_t ad7816_show_mode(struct device *dev,
 117                struct device_attribute *attr,
 118                char *buf)
 119{
 120        struct iio_dev *dev_info = dev_get_drvdata(dev);
 121        struct ad7816_chip_info *chip = dev_info->dev_data;
 122
 123        if (chip->mode)
 124                return sprintf(buf, "power-save\n");
 125        else
 126                return sprintf(buf, "full\n");
 127}
 128
 129static ssize_t ad7816_store_mode(struct device *dev,
 130                struct device_attribute *attr,
 131                const char *buf,
 132                size_t len)
 133{
 134        struct iio_dev *dev_info = dev_get_drvdata(dev);
 135        struct ad7816_chip_info *chip = dev_info->dev_data;
 136
 137        if (strcmp(buf, "full")) {
 138                gpio_set_value(chip->rdwr_pin, 1);
 139                chip->mode = AD7816_FULL;
 140        } else {
 141                gpio_set_value(chip->rdwr_pin, 0);
 142                chip->mode = AD7816_PD;
 143        }
 144
 145        return len;
 146}
 147
 148static IIO_DEVICE_ATTR(mode, S_IRUGO | S_IWUSR,
 149                ad7816_show_mode,
 150                ad7816_store_mode,
 151                0);
 152
 153static ssize_t ad7816_show_available_modes(struct device *dev,
 154                struct device_attribute *attr,
 155                char *buf)
 156{
 157        return sprintf(buf, "full\npower-save\n");
 158}
 159
 160static IIO_DEVICE_ATTR(available_modes, S_IRUGO, ad7816_show_available_modes, NULL, 0);
 161
 162static ssize_t ad7816_show_channel(struct device *dev,
 163                struct device_attribute *attr,
 164                char *buf)
 165{
 166        struct iio_dev *dev_info = dev_get_drvdata(dev);
 167        struct ad7816_chip_info *chip = dev_info->dev_data;
 168
 169        return sprintf(buf, "%d\n", chip->channel_id);
 170}
 171
 172static ssize_t ad7816_store_channel(struct device *dev,
 173                struct device_attribute *attr,
 174                const char *buf,
 175                size_t len)
 176{
 177        struct iio_dev *dev_info = dev_get_drvdata(dev);
 178        struct ad7816_chip_info *chip = dev_info->dev_data;
 179        unsigned long data;
 180        int ret;
 181
 182        ret = strict_strtoul(buf, 10, &data);
 183        if (ret)
 184                return -EINVAL;
 185
 186        if (data > AD7816_CS_MAX && data != AD7816_CS_MASK) {
 187                dev_err(&chip->spi_dev->dev, "Invalid channel id %lu for %s.\n",
 188                        data, chip->name);
 189                return -EINVAL;
 190        } else if (strcmp(chip->name, "ad7818") == 0 && data > 1) {
 191                dev_err(&chip->spi_dev->dev,
 192                        "Invalid channel id %lu for ad7818.\n", data);
 193                return -EINVAL;
 194        } else if (strcmp(chip->name, "ad7816") == 0 && data > 0) {
 195                dev_err(&chip->spi_dev->dev,
 196                        "Invalid channel id %lu for ad7816.\n", data);
 197                return -EINVAL;
 198        }
 199
 200        chip->channel_id = data;
 201
 202        return len;
 203}
 204
 205static IIO_DEVICE_ATTR(channel, S_IRUGO | S_IWUSR,
 206                ad7816_show_channel,
 207                ad7816_store_channel,
 208                0);
 209
 210
 211static ssize_t ad7816_show_value(struct device *dev,
 212                struct device_attribute *attr,
 213                char *buf)
 214{
 215        struct iio_dev *dev_info = dev_get_drvdata(dev);
 216        struct ad7816_chip_info *chip = dev_info->dev_data;
 217        u16 data;
 218        s8 value;
 219        int ret;
 220
 221        ret = ad7816_spi_read(chip, &data);
 222        if (ret)
 223                return -EIO;
 224
 225        data >>= AD7816_VALUE_OFFSET;
 226
 227        if (chip->channel_id == 0) {
 228                value = (s8)((data >> AD7816_TEMP_FLOAT_OFFSET) - 103);
 229                data &= AD7816_TEMP_FLOAT_MASK;
 230                if (value < 0)
 231                        data = (1 << AD7816_TEMP_FLOAT_OFFSET) - data;
 232                return sprintf(buf, "%d.%.2d\n", value, data * 25);
 233        } else
 234                return sprintf(buf, "%u\n", data);
 235}
 236
 237static IIO_DEVICE_ATTR(value, S_IRUGO, ad7816_show_value, NULL, 0);
 238
 239static ssize_t ad7816_show_name(struct device *dev,
 240                struct device_attribute *attr,
 241                char *buf)
 242{
 243        struct iio_dev *dev_info = dev_get_drvdata(dev);
 244        struct ad7816_chip_info *chip = dev_info->dev_data;
 245        return sprintf(buf, "%s\n", chip->name);
 246}
 247
 248static IIO_DEVICE_ATTR(name, S_IRUGO, ad7816_show_name, NULL, 0);
 249
 250static struct attribute *ad7816_attributes[] = {
 251        &iio_dev_attr_available_modes.dev_attr.attr,
 252        &iio_dev_attr_mode.dev_attr.attr,
 253        &iio_dev_attr_channel.dev_attr.attr,
 254        &iio_dev_attr_value.dev_attr.attr,
 255        &iio_dev_attr_name.dev_attr.attr,
 256        NULL,
 257};
 258
 259static const struct attribute_group ad7816_attribute_group = {
 260        .attrs = ad7816_attributes,
 261};
 262
 263/*
 264 * temperature bound events
 265 */
 266
 267#define IIO_EVENT_CODE_AD7816_OTI    IIO_BUFFER_EVENT_CODE(0)
 268
 269static void ad7816_interrupt_bh(struct work_struct *work_s)
 270{
 271        struct ad7816_chip_info *chip =
 272                container_of(work_s, struct ad7816_chip_info, thresh_work);
 273
 274        enable_irq(chip->spi_dev->irq);
 275
 276        iio_push_event(chip->indio_dev, 0,
 277                        IIO_EVENT_CODE_AD7816_OTI,
 278                        chip->last_timestamp);
 279}
 280
 281static int ad7816_interrupt(struct iio_dev *dev_info,
 282                int index,
 283                s64 timestamp,
 284                int no_test)
 285{
 286        struct ad7816_chip_info *chip = dev_info->dev_data;
 287
 288        chip->last_timestamp = timestamp;
 289        schedule_work(&chip->thresh_work);
 290
 291        return 0;
 292}
 293
 294IIO_EVENT_SH(ad7816, &ad7816_interrupt);
 295
 296static ssize_t ad7816_show_oti(struct device *dev,
 297                struct device_attribute *attr,
 298                char *buf)
 299{
 300        struct iio_dev *dev_info = dev_get_drvdata(dev);
 301        struct ad7816_chip_info *chip = dev_info->dev_data;
 302        int value;
 303
 304        if (chip->channel_id > AD7816_CS_MAX) {
 305                dev_err(dev, "Invalid oti channel id %d.\n", chip->channel_id);
 306                return -EINVAL;
 307        } else if (chip->channel_id == 0) {
 308                value = AD7816_BOUND_VALUE_MIN +
 309                        (chip->oti_data[chip->channel_id] -
 310                        AD7816_BOUND_VALUE_BASE);
 311                return sprintf(buf, "%d\n", value);
 312        } else
 313                return sprintf(buf, "%u\n", chip->oti_data[chip->channel_id]);
 314}
 315
 316static inline ssize_t ad7816_set_oti(struct device *dev,
 317                struct device_attribute *attr,
 318                const char *buf,
 319                size_t len)
 320{
 321        struct iio_dev *dev_info = dev_get_drvdata(dev);
 322        struct ad7816_chip_info *chip = dev_info->dev_data;
 323        long value;
 324        u8 data;
 325        int ret;
 326
 327        ret = strict_strtol(buf, 10, &value);
 328
 329        if (chip->channel_id > AD7816_CS_MAX) {
 330                dev_err(dev, "Invalid oti channel id %d.\n", chip->channel_id);
 331                return -EINVAL;
 332        } else if (chip->channel_id == 0) {
 333                if (ret || value < AD7816_BOUND_VALUE_MIN ||
 334                        value > AD7816_BOUND_VALUE_MAX)
 335                        return -EINVAL;
 336
 337                data = (u8)(value - AD7816_BOUND_VALUE_MIN +
 338                        AD7816_BOUND_VALUE_BASE);
 339        } else {
 340                if (ret || value < AD7816_BOUND_VALUE_BASE || value > 255)
 341                        return -EINVAL;
 342
 343                data = (u8)value;
 344        }
 345
 346        ret = ad7816_spi_write(chip, data);
 347        if (ret)
 348                return -EIO;
 349
 350        chip->oti_data[chip->channel_id] = data;
 351
 352        return len;
 353}
 354
 355IIO_EVENT_ATTR_SH(oti, iio_event_ad7816,
 356                ad7816_show_oti, ad7816_set_oti, 0);
 357
 358static struct attribute *ad7816_event_attributes[] = {
 359        &iio_event_attr_oti.dev_attr.attr,
 360        NULL,
 361};
 362
 363static struct attribute_group ad7816_event_attribute_group = {
 364        .attrs = ad7816_event_attributes,
 365};
 366
 367/*
 368 * device probe and remove
 369 */
 370
 371static int __devinit ad7816_probe(struct spi_device *spi_dev)
 372{
 373        struct ad7816_chip_info *chip;
 374        unsigned short *pins = spi_dev->dev.platform_data;
 375        int ret = 0;
 376        int i;
 377
 378        if (!pins) {
 379                dev_err(&spi_dev->dev, "No necessary GPIO platform data.\n");
 380                return -EINVAL;
 381        }
 382
 383        chip = kzalloc(sizeof(struct ad7816_chip_info), GFP_KERNEL);
 384
 385        if (chip == NULL)
 386                return -ENOMEM;
 387
 388        /* this is only used for device removal purposes */
 389        dev_set_drvdata(&spi_dev->dev, chip);
 390
 391        chip->spi_dev = spi_dev;
 392        chip->name = spi_dev->modalias;
 393        for (i = 0; i <= AD7816_CS_MAX; i++)
 394                chip->oti_data[i] = 203;
 395        chip->rdwr_pin = pins[0];
 396        chip->convert_pin = pins[1];
 397        chip->busy_pin = pins[2];
 398
 399        ret = gpio_request(chip->rdwr_pin, chip->name);
 400        if (ret) {
 401                dev_err(&spi_dev->dev, "Fail to request rdwr gpio PIN %d.\n",
 402                        chip->rdwr_pin);
 403                goto error_free_chip;
 404        }
 405        gpio_direction_input(chip->rdwr_pin);
 406        ret = gpio_request(chip->convert_pin, chip->name);
 407        if (ret) {
 408                dev_err(&spi_dev->dev, "Fail to request convert gpio PIN %d.\n",
 409                        chip->convert_pin);
 410                goto error_free_gpio_rdwr;
 411        }
 412        gpio_direction_input(chip->convert_pin);
 413        ret = gpio_request(chip->busy_pin, chip->name);
 414        if (ret) {
 415                dev_err(&spi_dev->dev, "Fail to request busy gpio PIN %d.\n",
 416                        chip->busy_pin);
 417                goto error_free_gpio_convert;
 418        }
 419        gpio_direction_input(chip->busy_pin);
 420
 421        chip->indio_dev = iio_allocate_device();
 422        if (chip->indio_dev == NULL) {
 423                ret = -ENOMEM;
 424                goto error_free_gpio;
 425        }
 426
 427        chip->indio_dev->dev.parent = &spi_dev->dev;
 428        chip->indio_dev->attrs = &ad7816_attribute_group;
 429        chip->indio_dev->event_attrs = &ad7816_event_attribute_group;
 430        chip->indio_dev->dev_data = (void *)chip;
 431        chip->indio_dev->driver_module = THIS_MODULE;
 432        chip->indio_dev->num_interrupt_lines = 1;
 433        chip->indio_dev->modes = INDIO_DIRECT_MODE;
 434
 435        ret = iio_device_register(chip->indio_dev);
 436        if (ret)
 437                goto error_free_dev;
 438
 439        if (spi_dev->irq) {
 440                /* Only low trigger is supported in ad7816/7/8 */
 441                ret = iio_register_interrupt_line(spi_dev->irq,
 442                                chip->indio_dev,
 443                                0,
 444                                IRQF_TRIGGER_LOW,
 445                                chip->name);
 446                if (ret)
 447                        goto error_unreg_dev;
 448
 449                /*
 450                 * The event handler list element refer to iio_event_ad7816.
 451                 * All event attributes bind to the same event handler.
 452                 * So, only register event handler once.
 453                 */
 454                iio_add_event_to_list(&iio_event_ad7816,
 455                                &chip->indio_dev->interrupts[0]->ev_list);
 456
 457                INIT_WORK(&chip->thresh_work, ad7816_interrupt_bh);
 458        }
 459
 460        dev_info(&spi_dev->dev, "%s temperature sensor and ADC registered.\n",
 461                         chip->name);
 462
 463        return 0;
 464
 465error_unreg_dev:
 466        iio_device_unregister(chip->indio_dev);
 467error_free_dev:
 468        iio_free_device(chip->indio_dev);
 469error_free_gpio:
 470        gpio_free(chip->busy_pin);
 471error_free_gpio_convert:
 472        gpio_free(chip->convert_pin);
 473error_free_gpio_rdwr:
 474        gpio_free(chip->rdwr_pin);
 475error_free_chip:
 476        kfree(chip);
 477
 478        return ret;
 479}
 480
 481static int __devexit ad7816_remove(struct spi_device *spi_dev)
 482{
 483        struct ad7816_chip_info *chip = dev_get_drvdata(&spi_dev->dev);
 484        struct iio_dev *indio_dev = chip->indio_dev;
 485
 486        dev_set_drvdata(&spi_dev->dev, NULL);
 487        if (spi_dev->irq)
 488                iio_unregister_interrupt_line(indio_dev, 0);
 489        iio_device_unregister(indio_dev);
 490        iio_free_device(chip->indio_dev);
 491        gpio_free(chip->busy_pin);
 492        gpio_free(chip->convert_pin);
 493        gpio_free(chip->rdwr_pin);
 494        kfree(chip);
 495
 496        return 0;
 497}
 498
 499static const struct spi_device_id ad7816_id[] = {
 500        { "ad7816", 0 },
 501        { "ad7817", 0 },
 502        { "ad7818", 0 },
 503        {}
 504};
 505
 506MODULE_DEVICE_TABLE(spi, ad7816_id);
 507
 508static struct spi_driver ad7816_driver = {
 509        .driver = {
 510                .name = "ad7816",
 511                .bus = &spi_bus_type,
 512                .owner = THIS_MODULE,
 513        },
 514        .probe = ad7816_probe,
 515        .remove = __devexit_p(ad7816_remove),
 516        .id_table = ad7816_id,
 517};
 518
 519static __init int ad7816_init(void)
 520{
 521        return spi_register_driver(&ad7816_driver);
 522}
 523
 524static __exit void ad7816_exit(void)
 525{
 526        spi_unregister_driver(&ad7816_driver);
 527}
 528
 529MODULE_AUTHOR("Sonic Zhang <sonic.zhang@analog.com>");
 530MODULE_DESCRIPTION("Analog Devices AD7816/7/8 digital"
 531                        " temperature sensor driver");
 532MODULE_LICENSE("GPL v2");
 533
 534module_init(ad7816_init);
 535module_exit(ad7816_exit);
 536