linux/drivers/staging/iio/adc/ad7816.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0+
   2/*
   3 * AD7816 digital temperature sensor driver supporting AD7816/7/8
   4 *
   5 * Copyright 2010 Analog Devices Inc.
   6 */
   7
   8#include <linux/interrupt.h>
   9#include <linux/gpio/consumer.h>
  10#include <linux/device.h>
  11#include <linux/kernel.h>
  12#include <linux/slab.h>
  13#include <linux/sysfs.h>
  14#include <linux/list.h>
  15#include <linux/spi/spi.h>
  16#include <linux/module.h>
  17
  18#include <linux/iio/iio.h>
  19#include <linux/iio/sysfs.h>
  20#include <linux/iio/events.h>
  21
  22/*
  23 * AD7816 config masks
  24 */
  25#define AD7816_FULL                     0x1
  26#define AD7816_PD                       0x2
  27#define AD7816_CS_MASK                  0x7
  28#define AD7816_CS_MAX                   0x4
  29
  30/*
  31 * AD7816 temperature masks
  32 */
  33#define AD7816_VALUE_OFFSET             6
  34#define AD7816_BOUND_VALUE_BASE         0x8
  35#define AD7816_BOUND_VALUE_MIN          -95
  36#define AD7816_BOUND_VALUE_MAX          152
  37#define AD7816_TEMP_FLOAT_OFFSET        2
  38#define AD7816_TEMP_FLOAT_MASK          0x3
  39
  40/*
  41 * struct ad7816_chip_info - chip specific information
  42 */
  43
  44struct ad7816_chip_info {
  45        kernel_ulong_t id;
  46        struct spi_device *spi_dev;
  47        struct gpio_desc *rdwr_pin;
  48        struct gpio_desc *convert_pin;
  49        struct gpio_desc *busy_pin;
  50        u8  oti_data[AD7816_CS_MAX + 1];
  51        u8  channel_id; /* 0 always be temperature */
  52        u8  mode;
  53};
  54
  55enum ad7816_type {
  56        ID_AD7816,
  57        ID_AD7817,
  58        ID_AD7818,
  59};
  60
  61/*
  62 * ad7816 data access by SPI
  63 */
  64static int ad7816_spi_read(struct ad7816_chip_info *chip, u16 *data)
  65{
  66        struct spi_device *spi_dev = chip->spi_dev;
  67        int ret;
  68        __be16 buf;
  69
  70        gpiod_set_value(chip->rdwr_pin, 1);
  71        gpiod_set_value(chip->rdwr_pin, 0);
  72        ret = spi_write(spi_dev, &chip->channel_id, sizeof(chip->channel_id));
  73        if (ret < 0) {
  74                dev_err(&spi_dev->dev, "SPI channel setting error\n");
  75                return ret;
  76        }
  77        gpiod_set_value(chip->rdwr_pin, 1);
  78
  79        if (chip->mode == AD7816_PD) { /* operating mode 2 */
  80                gpiod_set_value(chip->convert_pin, 1);
  81                gpiod_set_value(chip->convert_pin, 0);
  82        } else { /* operating mode 1 */
  83                gpiod_set_value(chip->convert_pin, 0);
  84                gpiod_set_value(chip->convert_pin, 1);
  85        }
  86
  87        if (chip->id == ID_AD7816 || chip->id == ID_AD7817) {
  88                while (gpiod_get_value(chip->busy_pin))
  89                        cpu_relax();
  90        }
  91
  92        gpiod_set_value(chip->rdwr_pin, 0);
  93        gpiod_set_value(chip->rdwr_pin, 1);
  94        ret = spi_read(spi_dev, &buf, sizeof(*data));
  95        if (ret < 0) {
  96                dev_err(&spi_dev->dev, "SPI data read error\n");
  97                return ret;
  98        }
  99
 100        *data = be16_to_cpu(buf);
 101
 102        return ret;
 103}
 104
 105static int ad7816_spi_write(struct ad7816_chip_info *chip, u8 data)
 106{
 107        struct spi_device *spi_dev = chip->spi_dev;
 108        int ret;
 109
 110        gpiod_set_value(chip->rdwr_pin, 1);
 111        gpiod_set_value(chip->rdwr_pin, 0);
 112        ret = spi_write(spi_dev, &data, sizeof(data));
 113        if (ret < 0)
 114                dev_err(&spi_dev->dev, "SPI oti data write error\n");
 115
 116        return ret;
 117}
 118
 119static ssize_t ad7816_show_mode(struct device *dev,
 120                                struct device_attribute *attr,
 121                                char *buf)
 122{
 123        struct iio_dev *indio_dev = dev_to_iio_dev(dev);
 124        struct ad7816_chip_info *chip = iio_priv(indio_dev);
 125
 126        if (chip->mode)
 127                return sprintf(buf, "power-save\n");
 128        return sprintf(buf, "full\n");
 129}
 130
 131static ssize_t ad7816_store_mode(struct device *dev,
 132                                 struct device_attribute *attr,
 133                                 const char *buf,
 134                                 size_t len)
 135{
 136        struct iio_dev *indio_dev = dev_to_iio_dev(dev);
 137        struct ad7816_chip_info *chip = iio_priv(indio_dev);
 138
 139        if (strcmp(buf, "full")) {
 140                gpiod_set_value(chip->rdwr_pin, 1);
 141                chip->mode = AD7816_FULL;
 142        } else {
 143                gpiod_set_value(chip->rdwr_pin, 0);
 144                chip->mode = AD7816_PD;
 145        }
 146
 147        return len;
 148}
 149
 150static IIO_DEVICE_ATTR(mode, 0644,
 151                ad7816_show_mode,
 152                ad7816_store_mode,
 153                0);
 154
 155static ssize_t ad7816_show_available_modes(struct device *dev,
 156                                           struct device_attribute *attr,
 157                                           char *buf)
 158{
 159        return sprintf(buf, "full\npower-save\n");
 160}
 161
 162static IIO_DEVICE_ATTR(available_modes, 0444, ad7816_show_available_modes,
 163                        NULL, 0);
 164
 165static ssize_t ad7816_show_channel(struct device *dev,
 166                                   struct device_attribute *attr,
 167                                   char *buf)
 168{
 169        struct iio_dev *indio_dev = dev_to_iio_dev(dev);
 170        struct ad7816_chip_info *chip = iio_priv(indio_dev);
 171
 172        return sprintf(buf, "%d\n", chip->channel_id);
 173}
 174
 175static ssize_t ad7816_store_channel(struct device *dev,
 176                                    struct device_attribute *attr,
 177                                    const char *buf,
 178                                    size_t len)
 179{
 180        struct iio_dev *indio_dev = dev_to_iio_dev(dev);
 181        struct ad7816_chip_info *chip = iio_priv(indio_dev);
 182        unsigned long data;
 183        int ret;
 184
 185        ret = kstrtoul(buf, 10, &data);
 186        if (ret)
 187                return ret;
 188
 189        if (data > AD7816_CS_MAX && data != AD7816_CS_MASK) {
 190                dev_err(&chip->spi_dev->dev, "Invalid channel id %lu for %s.\n",
 191                        data, indio_dev->name);
 192                return -EINVAL;
 193        } else if (strcmp(indio_dev->name, "ad7818") == 0 && data > 1) {
 194                dev_err(&chip->spi_dev->dev,
 195                        "Invalid channel id %lu for ad7818.\n", data);
 196                return -EINVAL;
 197        } else if (strcmp(indio_dev->name, "ad7816") == 0 && data > 0) {
 198                dev_err(&chip->spi_dev->dev,
 199                        "Invalid channel id %lu for ad7816.\n", data);
 200                return -EINVAL;
 201        }
 202
 203        chip->channel_id = data;
 204
 205        return len;
 206}
 207
 208static IIO_DEVICE_ATTR(channel, 0644,
 209                ad7816_show_channel,
 210                ad7816_store_channel,
 211                0);
 212
 213static ssize_t ad7816_show_value(struct device *dev,
 214                                 struct device_attribute *attr,
 215                                 char *buf)
 216{
 217        struct iio_dev *indio_dev = dev_to_iio_dev(dev);
 218        struct ad7816_chip_info *chip = iio_priv(indio_dev);
 219        u16 data;
 220        s8 value;
 221        int ret;
 222
 223        ret = ad7816_spi_read(chip, &data);
 224        if (ret)
 225                return -EIO;
 226
 227        data >>= AD7816_VALUE_OFFSET;
 228
 229        if (chip->channel_id == 0) {
 230                value = (s8)((data >> AD7816_TEMP_FLOAT_OFFSET) - 103);
 231                data &= AD7816_TEMP_FLOAT_MASK;
 232                if (value < 0)
 233                        data = BIT(AD7816_TEMP_FLOAT_OFFSET) - data;
 234                return sprintf(buf, "%d.%.2d\n", value, data * 25);
 235        }
 236        return sprintf(buf, "%u\n", data);
 237}
 238
 239static IIO_DEVICE_ATTR(value, 0444, ad7816_show_value, NULL, 0);
 240
 241static struct attribute *ad7816_attributes[] = {
 242        &iio_dev_attr_available_modes.dev_attr.attr,
 243        &iio_dev_attr_mode.dev_attr.attr,
 244        &iio_dev_attr_channel.dev_attr.attr,
 245        &iio_dev_attr_value.dev_attr.attr,
 246        NULL,
 247};
 248
 249static const struct attribute_group ad7816_attribute_group = {
 250        .attrs = ad7816_attributes,
 251};
 252
 253/*
 254 * temperature bound events
 255 */
 256
 257#define IIO_EVENT_CODE_AD7816_OTI IIO_UNMOD_EVENT_CODE(IIO_TEMP,        \
 258                                                       0,               \
 259                                                       IIO_EV_TYPE_THRESH, \
 260                                                       IIO_EV_DIR_FALLING)
 261
 262static irqreturn_t ad7816_event_handler(int irq, void *private)
 263{
 264        iio_push_event(private, IIO_EVENT_CODE_AD7816_OTI,
 265                       iio_get_time_ns(private));
 266        return IRQ_HANDLED;
 267}
 268
 269static ssize_t ad7816_show_oti(struct device *dev,
 270                               struct device_attribute *attr,
 271                               char *buf)
 272{
 273        struct iio_dev *indio_dev = dev_to_iio_dev(dev);
 274        struct ad7816_chip_info *chip = iio_priv(indio_dev);
 275        int value;
 276
 277        if (chip->channel_id > AD7816_CS_MAX) {
 278                dev_err(dev, "Invalid oti channel id %d.\n", chip->channel_id);
 279                return -EINVAL;
 280        } else if (chip->channel_id == 0) {
 281                value = AD7816_BOUND_VALUE_MIN +
 282                        (chip->oti_data[chip->channel_id] -
 283                        AD7816_BOUND_VALUE_BASE);
 284                return sprintf(buf, "%d\n", value);
 285        }
 286        return sprintf(buf, "%u\n", chip->oti_data[chip->channel_id]);
 287}
 288
 289static inline ssize_t ad7816_set_oti(struct device *dev,
 290                                     struct device_attribute *attr,
 291                                     const char *buf,
 292                                     size_t len)
 293{
 294        struct iio_dev *indio_dev = dev_to_iio_dev(dev);
 295        struct ad7816_chip_info *chip = iio_priv(indio_dev);
 296        long value;
 297        u8 data;
 298        int ret;
 299
 300        ret = kstrtol(buf, 10, &value);
 301        if (ret)
 302                return ret;
 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                if (value < AD7816_BOUND_VALUE_MIN ||
 309                    value > AD7816_BOUND_VALUE_MAX)
 310                        return -EINVAL;
 311
 312                data = (u8)(value - AD7816_BOUND_VALUE_MIN +
 313                        AD7816_BOUND_VALUE_BASE);
 314        } else {
 315                if (value < AD7816_BOUND_VALUE_BASE || value > 255)
 316                        return -EINVAL;
 317
 318                data = (u8)value;
 319        }
 320
 321        ret = ad7816_spi_write(chip, data);
 322        if (ret)
 323                return -EIO;
 324
 325        chip->oti_data[chip->channel_id] = data;
 326
 327        return len;
 328}
 329
 330static IIO_DEVICE_ATTR(oti, 0644,
 331                       ad7816_show_oti, ad7816_set_oti, 0);
 332
 333static struct attribute *ad7816_event_attributes[] = {
 334        &iio_dev_attr_oti.dev_attr.attr,
 335        NULL,
 336};
 337
 338static const struct attribute_group ad7816_event_attribute_group = {
 339        .attrs = ad7816_event_attributes,
 340        .name = "events",
 341};
 342
 343static const struct iio_info ad7816_info = {
 344        .attrs = &ad7816_attribute_group,
 345        .event_attrs = &ad7816_event_attribute_group,
 346};
 347
 348/*
 349 * device probe and remove
 350 */
 351
 352static int ad7816_probe(struct spi_device *spi_dev)
 353{
 354        struct ad7816_chip_info *chip;
 355        struct iio_dev *indio_dev;
 356        int i, ret;
 357
 358        indio_dev = devm_iio_device_alloc(&spi_dev->dev, sizeof(*chip));
 359        if (!indio_dev)
 360                return -ENOMEM;
 361        chip = iio_priv(indio_dev);
 362        /* this is only used for device removal purposes */
 363        dev_set_drvdata(&spi_dev->dev, indio_dev);
 364
 365        chip->spi_dev = spi_dev;
 366        for (i = 0; i <= AD7816_CS_MAX; i++)
 367                chip->oti_data[i] = 203;
 368
 369        chip->id = spi_get_device_id(spi_dev)->driver_data;
 370        chip->rdwr_pin = devm_gpiod_get(&spi_dev->dev, "rdwr", GPIOD_OUT_HIGH);
 371        if (IS_ERR(chip->rdwr_pin)) {
 372                ret = PTR_ERR(chip->rdwr_pin);
 373                dev_err(&spi_dev->dev, "Failed to request rdwr GPIO: %d\n",
 374                        ret);
 375                return ret;
 376        }
 377        chip->convert_pin = devm_gpiod_get(&spi_dev->dev, "convert",
 378                                           GPIOD_OUT_HIGH);
 379        if (IS_ERR(chip->convert_pin)) {
 380                ret = PTR_ERR(chip->convert_pin);
 381                dev_err(&spi_dev->dev, "Failed to request convert GPIO: %d\n",
 382                        ret);
 383                return ret;
 384        }
 385        if (chip->id == ID_AD7816 || chip->id == ID_AD7817) {
 386                chip->busy_pin = devm_gpiod_get(&spi_dev->dev, "busy",
 387                                                GPIOD_IN);
 388                if (IS_ERR(chip->busy_pin)) {
 389                        ret = PTR_ERR(chip->busy_pin);
 390                        dev_err(&spi_dev->dev, "Failed to request busy GPIO: %d\n",
 391                                ret);
 392                        return ret;
 393                }
 394        }
 395
 396        indio_dev->name = spi_get_device_id(spi_dev)->name;
 397        indio_dev->info = &ad7816_info;
 398        indio_dev->modes = INDIO_DIRECT_MODE;
 399
 400        if (spi_dev->irq) {
 401                /* Only low trigger is supported in ad7816/7/8 */
 402                ret = devm_request_threaded_irq(&spi_dev->dev, spi_dev->irq,
 403                                                NULL,
 404                                                &ad7816_event_handler,
 405                                                IRQF_TRIGGER_LOW | IRQF_ONESHOT,
 406                                                indio_dev->name,
 407                                                indio_dev);
 408                if (ret)
 409                        return ret;
 410        }
 411
 412        ret = devm_iio_device_register(&spi_dev->dev, indio_dev);
 413        if (ret)
 414                return ret;
 415
 416        dev_info(&spi_dev->dev, "%s temperature sensor and ADC registered.\n",
 417                 indio_dev->name);
 418
 419        return 0;
 420}
 421
 422static const struct of_device_id ad7816_of_match[] = {
 423        { .compatible = "adi,ad7816", },
 424        { .compatible = "adi,ad7817", },
 425        { .compatible = "adi,ad7818", },
 426        { }
 427};
 428MODULE_DEVICE_TABLE(of, ad7816_of_match);
 429
 430static const struct spi_device_id ad7816_id[] = {
 431        { "ad7816", ID_AD7816 },
 432        { "ad7817", ID_AD7817 },
 433        { "ad7818", ID_AD7818 },
 434        {}
 435};
 436
 437MODULE_DEVICE_TABLE(spi, ad7816_id);
 438
 439static struct spi_driver ad7816_driver = {
 440        .driver = {
 441                .name = "ad7816",
 442                .of_match_table = ad7816_of_match,
 443        },
 444        .probe = ad7816_probe,
 445        .id_table = ad7816_id,
 446};
 447module_spi_driver(ad7816_driver);
 448
 449MODULE_AUTHOR("Sonic Zhang <sonic.zhang@analog.com>");
 450MODULE_DESCRIPTION("Analog Devices AD7816/7/8 digital temperature sensor driver");
 451MODULE_LICENSE("GPL v2");
 452