linux/drivers/staging/iio/adc/adt7410.c
<<
>>
Prefs
   1/*
   2 * ADT7410 digital temperature sensor driver supporting ADT7310/ADT7410
   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/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/i2c.h>
  16#include <linux/spi/spi.h>
  17#include <linux/module.h>
  18
  19#include <linux/iio/iio.h>
  20#include <linux/iio/sysfs.h>
  21#include <linux/iio/events.h>
  22
  23/*
  24 * ADT7410 registers definition
  25 */
  26
  27#define ADT7410_TEMPERATURE             0
  28#define ADT7410_STATUS                  2
  29#define ADT7410_CONFIG                  3
  30#define ADT7410_T_ALARM_HIGH            4
  31#define ADT7410_T_ALARM_LOW             6
  32#define ADT7410_T_CRIT                  8
  33#define ADT7410_T_HYST                  0xA
  34#define ADT7410_ID                      0xB
  35#define ADT7410_RESET                   0x2F
  36
  37/*
  38 * ADT7310 registers definition
  39 */
  40
  41#define ADT7310_STATUS                  0
  42#define ADT7310_CONFIG                  1
  43#define ADT7310_TEMPERATURE             2
  44#define ADT7310_ID                      3
  45#define ADT7310_T_CRIT                  4
  46#define ADT7310_T_HYST                  5
  47#define ADT7310_T_ALARM_HIGH            6
  48#define ADT7310_T_ALARM_LOW             7
  49
  50/*
  51 * ADT7410 status
  52 */
  53#define ADT7410_STAT_T_LOW              0x10
  54#define ADT7410_STAT_T_HIGH             0x20
  55#define ADT7410_STAT_T_CRIT             0x40
  56#define ADT7410_STAT_NOT_RDY            0x80
  57
  58/*
  59 * ADT7410 config
  60 */
  61#define ADT7410_FAULT_QUEUE_MASK        0x3
  62#define ADT7410_CT_POLARITY             0x4
  63#define ADT7410_INT_POLARITY            0x8
  64#define ADT7410_EVENT_MODE              0x10
  65#define ADT7410_MODE_MASK               0x60
  66#define ADT7410_ONESHOT                 0x20
  67#define ADT7410_SPS                     0x40
  68#define ADT7410_PD                      0x60
  69#define ADT7410_RESOLUTION              0x80
  70
  71/*
  72 * ADT7410 masks
  73 */
  74#define ADT7410_T16_VALUE_SIGN                  0x8000
  75#define ADT7410_T16_VALUE_FLOAT_OFFSET          7
  76#define ADT7410_T16_VALUE_FLOAT_MASK            0x7F
  77#define ADT7410_T13_VALUE_SIGN                  0x1000
  78#define ADT7410_T13_VALUE_OFFSET                3
  79#define ADT7410_T13_VALUE_FLOAT_OFFSET          4
  80#define ADT7410_T13_VALUE_FLOAT_MASK            0xF
  81#define ADT7410_T_HYST_MASK                     0xF
  82#define ADT7410_DEVICE_ID_MASK                  0xF
  83#define ADT7410_MANUFACTORY_ID_MASK             0xF0
  84#define ADT7410_MANUFACTORY_ID_OFFSET           4
  85
  86
  87#define ADT7310_CMD_REG_MASK                    0x28
  88#define ADT7310_CMD_REG_OFFSET                  3
  89#define ADT7310_CMD_READ                        0x40
  90#define ADT7310_CMD_CON_READ                    0x4
  91
  92#define ADT7410_IRQS                            2
  93
  94/*
  95 * struct adt7410_chip_info - chip specifc information
  96 */
  97
  98struct adt7410_chip_info;
  99
 100struct adt7410_ops {
 101        int (*read_word)(struct adt7410_chip_info *, u8 reg, u16 *data);
 102        int (*write_word)(struct adt7410_chip_info *, u8 reg, u16 data);
 103        int (*read_byte)(struct adt7410_chip_info *, u8 reg, u8 *data);
 104        int (*write_byte)(struct adt7410_chip_info *, u8 reg, u8 data);
 105};
 106
 107struct adt7410_chip_info {
 108        struct device *dev;
 109        u8  config;
 110
 111        const struct adt7410_ops *ops;
 112};
 113
 114static int adt7410_read_word(struct adt7410_chip_info *chip, u8 reg, u16 *data)
 115{
 116        return chip->ops->read_word(chip, reg, data);
 117}
 118
 119static int adt7410_write_word(struct adt7410_chip_info *chip, u8 reg, u16 data)
 120{
 121        return chip->ops->write_word(chip, reg, data);
 122}
 123
 124static int adt7410_read_byte(struct adt7410_chip_info *chip, u8 reg, u8 *data)
 125{
 126        return chip->ops->read_byte(chip, reg, data);
 127}
 128
 129static int adt7410_write_byte(struct adt7410_chip_info *chip, u8 reg, u8 data)
 130{
 131        return chip->ops->write_byte(chip, reg, data);
 132}
 133
 134static ssize_t adt7410_show_mode(struct device *dev,
 135                struct device_attribute *attr,
 136                char *buf)
 137{
 138        struct iio_dev *dev_info = dev_to_iio_dev(dev);
 139        struct adt7410_chip_info *chip = iio_priv(dev_info);
 140        u8 config;
 141
 142        config = chip->config & ADT7410_MODE_MASK;
 143
 144        switch (config) {
 145        case ADT7410_PD:
 146                return sprintf(buf, "power-down\n");
 147        case ADT7410_ONESHOT:
 148                return sprintf(buf, "one-shot\n");
 149        case ADT7410_SPS:
 150                return sprintf(buf, "sps\n");
 151        default:
 152                return sprintf(buf, "full\n");
 153        }
 154}
 155
 156static ssize_t adt7410_store_mode(struct device *dev,
 157                struct device_attribute *attr,
 158                const char *buf,
 159                size_t len)
 160{
 161        struct iio_dev *dev_info = dev_to_iio_dev(dev);
 162        struct adt7410_chip_info *chip = iio_priv(dev_info);
 163        u16 config;
 164        int ret;
 165
 166        ret = adt7410_read_byte(chip, ADT7410_CONFIG, &chip->config);
 167        if (ret)
 168                return -EIO;
 169
 170        config = chip->config & (~ADT7410_MODE_MASK);
 171        if (strcmp(buf, "power-down"))
 172                config |= ADT7410_PD;
 173        else if (strcmp(buf, "one-shot"))
 174                config |= ADT7410_ONESHOT;
 175        else if (strcmp(buf, "sps"))
 176                config |= ADT7410_SPS;
 177
 178        ret = adt7410_write_byte(chip, ADT7410_CONFIG, config);
 179        if (ret)
 180                return -EIO;
 181
 182        chip->config = config;
 183
 184        return len;
 185}
 186
 187static IIO_DEVICE_ATTR(mode, S_IRUGO | S_IWUSR,
 188                adt7410_show_mode,
 189                adt7410_store_mode,
 190                0);
 191
 192static ssize_t adt7410_show_available_modes(struct device *dev,
 193                struct device_attribute *attr,
 194                char *buf)
 195{
 196        return sprintf(buf, "full\none-shot\nsps\npower-down\n");
 197}
 198
 199static IIO_DEVICE_ATTR(available_modes, S_IRUGO, adt7410_show_available_modes, NULL, 0);
 200
 201static ssize_t adt7410_show_resolution(struct device *dev,
 202                struct device_attribute *attr,
 203                char *buf)
 204{
 205        struct iio_dev *dev_info = dev_to_iio_dev(dev);
 206        struct adt7410_chip_info *chip = iio_priv(dev_info);
 207        int ret;
 208        int bits;
 209
 210        ret = adt7410_read_byte(chip, ADT7410_CONFIG, &chip->config);
 211        if (ret)
 212                return -EIO;
 213
 214        if (chip->config & ADT7410_RESOLUTION)
 215                bits = 16;
 216        else
 217                bits = 13;
 218
 219        return sprintf(buf, "%d bits\n", bits);
 220}
 221
 222static ssize_t adt7410_store_resolution(struct device *dev,
 223                struct device_attribute *attr,
 224                const char *buf,
 225                size_t len)
 226{
 227        struct iio_dev *dev_info = dev_to_iio_dev(dev);
 228        struct adt7410_chip_info *chip = iio_priv(dev_info);
 229        unsigned long data;
 230        u16 config;
 231        int ret;
 232
 233        ret = strict_strtoul(buf, 10, &data);
 234        if (ret)
 235                return -EINVAL;
 236
 237        ret = adt7410_read_byte(chip, ADT7410_CONFIG, &chip->config);
 238        if (ret)
 239                return -EIO;
 240
 241        config = chip->config & (~ADT7410_RESOLUTION);
 242        if (data)
 243                config |= ADT7410_RESOLUTION;
 244
 245        ret = adt7410_write_byte(chip, ADT7410_CONFIG, config);
 246        if (ret)
 247                return -EIO;
 248
 249        chip->config = config;
 250
 251        return len;
 252}
 253
 254static IIO_DEVICE_ATTR(resolution, S_IRUGO | S_IWUSR,
 255                adt7410_show_resolution,
 256                adt7410_store_resolution,
 257                0);
 258
 259static ssize_t adt7410_show_id(struct device *dev,
 260                struct device_attribute *attr,
 261                char *buf)
 262{
 263        struct iio_dev *dev_info = dev_to_iio_dev(dev);
 264        struct adt7410_chip_info *chip = iio_priv(dev_info);
 265        u8 id;
 266        int ret;
 267
 268        ret = adt7410_read_byte(chip, ADT7410_ID, &id);
 269        if (ret)
 270                return -EIO;
 271
 272        return sprintf(buf, "device id: 0x%x\nmanufactory id: 0x%x\n",
 273                        id & ADT7410_DEVICE_ID_MASK,
 274                        (id & ADT7410_MANUFACTORY_ID_MASK) >> ADT7410_MANUFACTORY_ID_OFFSET);
 275}
 276
 277static IIO_DEVICE_ATTR(id, S_IRUGO | S_IWUSR,
 278                adt7410_show_id,
 279                NULL,
 280                0);
 281
 282static ssize_t adt7410_convert_temperature(struct adt7410_chip_info *chip,
 283                u16 data, char *buf)
 284{
 285        char sign = ' ';
 286
 287        if (!(chip->config & ADT7410_RESOLUTION))
 288                data &= ~0x7;
 289
 290        if (data & ADT7410_T16_VALUE_SIGN) {
 291                /* convert supplement to positive value */
 292                data = (u16)((ADT7410_T16_VALUE_SIGN << 1) - (u32)data);
 293                sign = '-';
 294        }
 295        return sprintf(buf, "%c%d.%.7d\n", sign,
 296                        (data >> ADT7410_T16_VALUE_FLOAT_OFFSET),
 297                        (data & ADT7410_T16_VALUE_FLOAT_MASK) * 78125);
 298}
 299
 300static ssize_t adt7410_show_value(struct device *dev,
 301                struct device_attribute *attr,
 302                char *buf)
 303{
 304        struct iio_dev *dev_info = dev_to_iio_dev(dev);
 305        struct adt7410_chip_info *chip = iio_priv(dev_info);
 306        u8 status;
 307        u16 data;
 308        int ret, i = 0;
 309
 310        do {
 311                ret = adt7410_read_byte(chip, ADT7410_STATUS, &status);
 312                if (ret)
 313                        return -EIO;
 314                i++;
 315                if (i == 10000)
 316                        return -EIO;
 317        } while (status & ADT7410_STAT_NOT_RDY);
 318
 319        ret = adt7410_read_word(chip, ADT7410_TEMPERATURE, &data);
 320        if (ret)
 321                return -EIO;
 322
 323        return adt7410_convert_temperature(chip, data, buf);
 324}
 325
 326static IIO_DEVICE_ATTR(value, S_IRUGO, adt7410_show_value, NULL, 0);
 327
 328static struct attribute *adt7410_attributes[] = {
 329        &iio_dev_attr_available_modes.dev_attr.attr,
 330        &iio_dev_attr_mode.dev_attr.attr,
 331        &iio_dev_attr_resolution.dev_attr.attr,
 332        &iio_dev_attr_id.dev_attr.attr,
 333        &iio_dev_attr_value.dev_attr.attr,
 334        NULL,
 335};
 336
 337static const struct attribute_group adt7410_attribute_group = {
 338        .attrs = adt7410_attributes,
 339};
 340
 341static irqreturn_t adt7410_event_handler(int irq, void *private)
 342{
 343        struct iio_dev *indio_dev = private;
 344        struct adt7410_chip_info *chip = iio_priv(indio_dev);
 345        s64 timestamp = iio_get_time_ns();
 346        u8 status;
 347
 348        if (adt7410_read_byte(chip, ADT7410_STATUS, &status))
 349                return IRQ_HANDLED;
 350
 351        if (status & ADT7410_STAT_T_HIGH)
 352                iio_push_event(indio_dev,
 353                               IIO_UNMOD_EVENT_CODE(IIO_TEMP, 0,
 354                                                    IIO_EV_TYPE_THRESH,
 355                                                    IIO_EV_DIR_RISING),
 356                               timestamp);
 357        if (status & ADT7410_STAT_T_LOW)
 358                iio_push_event(indio_dev,
 359                               IIO_UNMOD_EVENT_CODE(IIO_TEMP, 0,
 360                                                    IIO_EV_TYPE_THRESH,
 361                                                    IIO_EV_DIR_FALLING),
 362                               timestamp);
 363        if (status & ADT7410_STAT_T_CRIT)
 364                iio_push_event(indio_dev,
 365                               IIO_UNMOD_EVENT_CODE(IIO_TEMP, 0,
 366                                                    IIO_EV_TYPE_THRESH,
 367                                                    IIO_EV_DIR_RISING),
 368                               timestamp);
 369
 370        return IRQ_HANDLED;
 371}
 372
 373static ssize_t adt7410_show_event_mode(struct device *dev,
 374                struct device_attribute *attr,
 375                char *buf)
 376{
 377        struct iio_dev *dev_info = dev_to_iio_dev(dev);
 378        struct adt7410_chip_info *chip = iio_priv(dev_info);
 379        int ret;
 380
 381        ret = adt7410_read_byte(chip, ADT7410_CONFIG, &chip->config);
 382        if (ret)
 383                return -EIO;
 384
 385        if (chip->config & ADT7410_EVENT_MODE)
 386                return sprintf(buf, "interrupt\n");
 387        else
 388                return sprintf(buf, "comparator\n");
 389}
 390
 391static ssize_t adt7410_set_event_mode(struct device *dev,
 392                struct device_attribute *attr,
 393                const char *buf,
 394                size_t len)
 395{
 396        struct iio_dev *dev_info = dev_to_iio_dev(dev);
 397        struct adt7410_chip_info *chip = iio_priv(dev_info);
 398        u16 config;
 399        int ret;
 400
 401        ret = adt7410_read_byte(chip, ADT7410_CONFIG, &chip->config);
 402        if (ret)
 403                return -EIO;
 404
 405        config = chip->config &= ~ADT7410_EVENT_MODE;
 406        if (strcmp(buf, "comparator") != 0)
 407                config |= ADT7410_EVENT_MODE;
 408
 409        ret = adt7410_write_byte(chip, ADT7410_CONFIG, config);
 410        if (ret)
 411                return -EIO;
 412
 413        chip->config = config;
 414
 415        return ret;
 416}
 417
 418static ssize_t adt7410_show_available_event_modes(struct device *dev,
 419                struct device_attribute *attr,
 420                char *buf)
 421{
 422        return sprintf(buf, "comparator\ninterrupt\n");
 423}
 424
 425static ssize_t adt7410_show_fault_queue(struct device *dev,
 426                struct device_attribute *attr,
 427                char *buf)
 428{
 429        struct iio_dev *dev_info = dev_to_iio_dev(dev);
 430        struct adt7410_chip_info *chip = iio_priv(dev_info);
 431        int ret;
 432
 433        ret = adt7410_read_byte(chip, ADT7410_CONFIG, &chip->config);
 434        if (ret)
 435                return -EIO;
 436
 437        return sprintf(buf, "%d\n", chip->config & ADT7410_FAULT_QUEUE_MASK);
 438}
 439
 440static ssize_t adt7410_set_fault_queue(struct device *dev,
 441                struct device_attribute *attr,
 442                const char *buf,
 443                size_t len)
 444{
 445        struct iio_dev *dev_info = dev_to_iio_dev(dev);
 446        struct adt7410_chip_info *chip = iio_priv(dev_info);
 447        unsigned long data;
 448        int ret;
 449        u8 config;
 450
 451        ret = strict_strtoul(buf, 10, &data);
 452        if (ret || data > 3)
 453                return -EINVAL;
 454
 455        ret = adt7410_read_byte(chip, ADT7410_CONFIG, &chip->config);
 456        if (ret)
 457                return -EIO;
 458
 459        config = chip->config & ~ADT7410_FAULT_QUEUE_MASK;
 460        config |= data;
 461        ret = adt7410_write_byte(chip, ADT7410_CONFIG, config);
 462        if (ret)
 463                return -EIO;
 464
 465        chip->config = config;
 466
 467        return ret;
 468}
 469
 470static inline ssize_t adt7410_show_t_bound(struct device *dev,
 471                struct device_attribute *attr,
 472                u8 bound_reg,
 473                char *buf)
 474{
 475        struct iio_dev *dev_info = dev_to_iio_dev(dev);
 476        struct adt7410_chip_info *chip = iio_priv(dev_info);
 477        u16 data;
 478        int ret;
 479
 480        ret = adt7410_read_word(chip, bound_reg, &data);
 481        if (ret)
 482                return -EIO;
 483
 484        return adt7410_convert_temperature(chip, data, buf);
 485}
 486
 487static inline ssize_t adt7410_set_t_bound(struct device *dev,
 488                struct device_attribute *attr,
 489                u8 bound_reg,
 490                const char *buf,
 491                size_t len)
 492{
 493        struct iio_dev *dev_info = dev_to_iio_dev(dev);
 494        struct adt7410_chip_info *chip = iio_priv(dev_info);
 495        long tmp1, tmp2;
 496        u16 data;
 497        char *pos;
 498        int ret;
 499
 500        pos = strchr(buf, '.');
 501
 502        ret = strict_strtol(buf, 10, &tmp1);
 503
 504        if (ret || tmp1 > 127 || tmp1 < -128)
 505                return -EINVAL;
 506
 507        if (pos) {
 508                len = strlen(pos);
 509
 510                if (chip->config & ADT7410_RESOLUTION) {
 511                        if (len > ADT7410_T16_VALUE_FLOAT_OFFSET)
 512                                len = ADT7410_T16_VALUE_FLOAT_OFFSET;
 513                        pos[len] = 0;
 514                        ret = strict_strtol(pos, 10, &tmp2);
 515
 516                        if (!ret)
 517                                tmp2 = (tmp2 / 78125) * 78125;
 518                } else {
 519                        if (len > ADT7410_T13_VALUE_FLOAT_OFFSET)
 520                                len = ADT7410_T13_VALUE_FLOAT_OFFSET;
 521                        pos[len] = 0;
 522                        ret = strict_strtol(pos, 10, &tmp2);
 523
 524                        if (!ret)
 525                                tmp2 = (tmp2 / 625) * 625;
 526                }
 527        }
 528
 529        if (tmp1 < 0)
 530                data = (u16)(-tmp1);
 531        else
 532                data = (u16)tmp1;
 533
 534        if (chip->config & ADT7410_RESOLUTION) {
 535                data = (data << ADT7410_T16_VALUE_FLOAT_OFFSET) |
 536                        (tmp2 & ADT7410_T16_VALUE_FLOAT_MASK);
 537
 538                if (tmp1 < 0)
 539                        /* convert positive value to supplyment */
 540                        data = (u16)((ADT7410_T16_VALUE_SIGN << 1) - (u32)data);
 541        } else {
 542                data = (data << ADT7410_T13_VALUE_FLOAT_OFFSET) |
 543                        (tmp2 & ADT7410_T13_VALUE_FLOAT_MASK);
 544
 545                if (tmp1 < 0)
 546                        /* convert positive value to supplyment */
 547                        data = (ADT7410_T13_VALUE_SIGN << 1) - data;
 548                data <<= ADT7410_T13_VALUE_OFFSET;
 549        }
 550
 551        ret = adt7410_write_word(chip, bound_reg, data);
 552        if (ret)
 553                return -EIO;
 554
 555        return ret;
 556}
 557
 558static ssize_t adt7410_show_t_alarm_high(struct device *dev,
 559                struct device_attribute *attr,
 560                char *buf)
 561{
 562        return adt7410_show_t_bound(dev, attr,
 563                        ADT7410_T_ALARM_HIGH, buf);
 564}
 565
 566static inline ssize_t adt7410_set_t_alarm_high(struct device *dev,
 567                struct device_attribute *attr,
 568                const char *buf,
 569                size_t len)
 570{
 571        return adt7410_set_t_bound(dev, attr,
 572                        ADT7410_T_ALARM_HIGH, buf, len);
 573}
 574
 575static ssize_t adt7410_show_t_alarm_low(struct device *dev,
 576                struct device_attribute *attr,
 577                char *buf)
 578{
 579        return adt7410_show_t_bound(dev, attr,
 580                        ADT7410_T_ALARM_LOW, buf);
 581}
 582
 583static inline ssize_t adt7410_set_t_alarm_low(struct device *dev,
 584                struct device_attribute *attr,
 585                const char *buf,
 586                size_t len)
 587{
 588        return adt7410_set_t_bound(dev, attr,
 589                        ADT7410_T_ALARM_LOW, buf, len);
 590}
 591
 592static ssize_t adt7410_show_t_crit(struct device *dev,
 593                struct device_attribute *attr,
 594                char *buf)
 595{
 596        return adt7410_show_t_bound(dev, attr,
 597                        ADT7410_T_CRIT, buf);
 598}
 599
 600static inline ssize_t adt7410_set_t_crit(struct device *dev,
 601                struct device_attribute *attr,
 602                const char *buf,
 603                size_t len)
 604{
 605        return adt7410_set_t_bound(dev, attr,
 606                        ADT7410_T_CRIT, buf, len);
 607}
 608
 609static ssize_t adt7410_show_t_hyst(struct device *dev,
 610                struct device_attribute *attr,
 611                char *buf)
 612{
 613        struct iio_dev *dev_info = dev_to_iio_dev(dev);
 614        struct adt7410_chip_info *chip = iio_priv(dev_info);
 615        int ret;
 616        u8 t_hyst;
 617
 618        ret = adt7410_read_byte(chip, ADT7410_T_HYST, &t_hyst);
 619        if (ret)
 620                return -EIO;
 621
 622        return sprintf(buf, "%d\n", t_hyst & ADT7410_T_HYST_MASK);
 623}
 624
 625static inline ssize_t adt7410_set_t_hyst(struct device *dev,
 626                struct device_attribute *attr,
 627                const char *buf,
 628                size_t len)
 629{
 630        struct iio_dev *dev_info = dev_to_iio_dev(dev);
 631        struct adt7410_chip_info *chip = iio_priv(dev_info);
 632        int ret;
 633        unsigned long data;
 634        u8 t_hyst;
 635
 636        ret = strict_strtol(buf, 10, &data);
 637
 638        if (ret || data > ADT7410_T_HYST_MASK)
 639                return -EINVAL;
 640
 641        t_hyst = (u8)data;
 642
 643        ret = adt7410_write_byte(chip, ADT7410_T_HYST, t_hyst);
 644        if (ret)
 645                return -EIO;
 646
 647        return ret;
 648}
 649
 650static IIO_DEVICE_ATTR(event_mode,
 651                       S_IRUGO | S_IWUSR,
 652                       adt7410_show_event_mode, adt7410_set_event_mode, 0);
 653static IIO_DEVICE_ATTR(available_event_modes,
 654                       S_IRUGO,
 655                       adt7410_show_available_event_modes, NULL, 0);
 656static IIO_DEVICE_ATTR(fault_queue,
 657                       S_IRUGO | S_IWUSR,
 658                       adt7410_show_fault_queue, adt7410_set_fault_queue, 0);
 659static IIO_DEVICE_ATTR(t_alarm_high,
 660                       S_IRUGO | S_IWUSR,
 661                       adt7410_show_t_alarm_high, adt7410_set_t_alarm_high, 0);
 662static IIO_DEVICE_ATTR(t_alarm_low,
 663                       S_IRUGO | S_IWUSR,
 664                       adt7410_show_t_alarm_low, adt7410_set_t_alarm_low, 0);
 665static IIO_DEVICE_ATTR(t_crit,
 666                       S_IRUGO | S_IWUSR,
 667                       adt7410_show_t_crit, adt7410_set_t_crit, 0);
 668static IIO_DEVICE_ATTR(t_hyst,
 669                       S_IRUGO | S_IWUSR,
 670                       adt7410_show_t_hyst, adt7410_set_t_hyst, 0);
 671
 672static struct attribute *adt7410_event_int_attributes[] = {
 673        &iio_dev_attr_event_mode.dev_attr.attr,
 674        &iio_dev_attr_available_event_modes.dev_attr.attr,
 675        &iio_dev_attr_fault_queue.dev_attr.attr,
 676        &iio_dev_attr_t_alarm_high.dev_attr.attr,
 677        &iio_dev_attr_t_alarm_low.dev_attr.attr,
 678        &iio_dev_attr_t_crit.dev_attr.attr,
 679        &iio_dev_attr_t_hyst.dev_attr.attr,
 680        NULL,
 681};
 682
 683static struct attribute_group adt7410_event_attribute_group = {
 684        .attrs = adt7410_event_int_attributes,
 685        .name = "events",
 686};
 687
 688static const struct iio_info adt7410_info = {
 689        .attrs = &adt7410_attribute_group,
 690        .event_attrs = &adt7410_event_attribute_group,
 691        .driver_module = THIS_MODULE,
 692};
 693
 694/*
 695 * device probe and remove
 696 */
 697
 698static int adt7410_probe(struct device *dev, int irq,
 699        const char *name, const struct adt7410_ops *ops)
 700{
 701        unsigned long *adt7410_platform_data = dev->platform_data;
 702        unsigned long local_pdata[] = {0, 0};
 703        struct adt7410_chip_info *chip;
 704        struct iio_dev *indio_dev;
 705        int ret = 0;
 706
 707        indio_dev = iio_device_alloc(sizeof(*chip));
 708        if (indio_dev == NULL) {
 709                ret = -ENOMEM;
 710                goto error_ret;
 711        }
 712        chip = iio_priv(indio_dev);
 713        /* this is only used for device removal purposes */
 714        dev_set_drvdata(dev, indio_dev);
 715
 716        chip->dev = dev;
 717        chip->ops = ops;
 718
 719        indio_dev->name = name;
 720        indio_dev->dev.parent = dev;
 721        indio_dev->info = &adt7410_info;
 722        indio_dev->modes = INDIO_DIRECT_MODE;
 723
 724        if (!adt7410_platform_data)
 725                adt7410_platform_data = local_pdata;
 726
 727        /* CT critcal temperature event. line 0 */
 728        if (irq) {
 729                ret = request_threaded_irq(irq,
 730                                           NULL,
 731                                           &adt7410_event_handler,
 732                                           IRQF_TRIGGER_LOW | IRQF_ONESHOT,
 733                                           name,
 734                                           indio_dev);
 735                if (ret)
 736                        goto error_free_dev;
 737        }
 738
 739        /* INT bound temperature alarm event. line 1 */
 740        if (adt7410_platform_data[0]) {
 741                ret = request_threaded_irq(adt7410_platform_data[0],
 742                                           NULL,
 743                                           &adt7410_event_handler,
 744                                           adt7410_platform_data[1] |
 745                                           IRQF_ONESHOT,
 746                                           name,
 747                                           indio_dev);
 748                if (ret)
 749                        goto error_unreg_ct_irq;
 750        }
 751
 752        ret = adt7410_read_byte(chip, ADT7410_CONFIG, &chip->config);
 753        if (ret) {
 754                ret = -EIO;
 755                goto error_unreg_int_irq;
 756        }
 757
 758        chip->config |= ADT7410_RESOLUTION;
 759
 760        if (irq && adt7410_platform_data[0]) {
 761
 762                /* set irq polarity low level */
 763                chip->config &= ~ADT7410_CT_POLARITY;
 764
 765                if (adt7410_platform_data[1] & IRQF_TRIGGER_HIGH)
 766                        chip->config |= ADT7410_INT_POLARITY;
 767                else
 768                        chip->config &= ~ADT7410_INT_POLARITY;
 769        }
 770
 771        ret = adt7410_write_byte(chip, ADT7410_CONFIG, chip->config);
 772        if (ret) {
 773                ret = -EIO;
 774                goto error_unreg_int_irq;
 775        }
 776        ret = iio_device_register(indio_dev);
 777        if (ret)
 778                goto error_unreg_int_irq;
 779
 780        dev_info(dev, "%s temperature sensor registered.\n",
 781                         name);
 782
 783        return 0;
 784
 785error_unreg_int_irq:
 786        free_irq(adt7410_platform_data[0], indio_dev);
 787error_unreg_ct_irq:
 788        free_irq(irq, indio_dev);
 789error_free_dev:
 790        iio_device_free(indio_dev);
 791error_ret:
 792        return ret;
 793}
 794
 795static int adt7410_remove(struct device *dev, int irq)
 796{
 797        struct iio_dev *indio_dev = dev_get_drvdata(dev);
 798        unsigned long *adt7410_platform_data = dev->platform_data;
 799
 800        iio_device_unregister(indio_dev);
 801        if (adt7410_platform_data[0])
 802                free_irq(adt7410_platform_data[0], indio_dev);
 803        if (irq)
 804                free_irq(irq, indio_dev);
 805        iio_device_free(indio_dev);
 806
 807        return 0;
 808}
 809
 810#if IS_ENABLED(CONFIG_I2C)
 811
 812static int adt7410_i2c_read_word(struct adt7410_chip_info *chip, u8 reg,
 813        u16 *data)
 814{
 815        struct i2c_client *client = to_i2c_client(chip->dev);
 816        int ret = 0;
 817
 818        ret = i2c_smbus_read_word_data(client, reg);
 819        if (ret < 0) {
 820                dev_err(&client->dev, "I2C read error\n");
 821                return ret;
 822        }
 823
 824        *data = swab16((u16)ret);
 825
 826        return 0;
 827}
 828
 829static int adt7410_i2c_write_word(struct adt7410_chip_info *chip, u8 reg,
 830        u16 data)
 831{
 832        struct i2c_client *client = to_i2c_client(chip->dev);
 833        int ret = 0;
 834
 835        ret = i2c_smbus_write_word_data(client, reg, swab16(data));
 836        if (ret < 0)
 837                dev_err(&client->dev, "I2C write error\n");
 838
 839        return ret;
 840}
 841
 842static int adt7410_i2c_read_byte(struct adt7410_chip_info *chip, u8 reg,
 843        u8 *data)
 844{
 845        struct i2c_client *client = to_i2c_client(chip->dev);
 846        int ret = 0;
 847
 848        ret = i2c_smbus_read_byte_data(client, reg);
 849        if (ret < 0) {
 850                dev_err(&client->dev, "I2C read error\n");
 851                return ret;
 852        }
 853
 854        *data = (u8)ret;
 855
 856        return 0;
 857}
 858
 859static int adt7410_i2c_write_byte(struct adt7410_chip_info *chip, u8 reg,
 860        u8 data)
 861{
 862        struct i2c_client *client = to_i2c_client(chip->dev);
 863        int ret = 0;
 864
 865        ret = i2c_smbus_write_byte_data(client, reg, data);
 866        if (ret < 0)
 867                dev_err(&client->dev, "I2C write error\n");
 868
 869        return ret;
 870}
 871
 872static const struct adt7410_ops adt7410_i2c_ops = {
 873        .read_word = adt7410_i2c_read_word,
 874        .write_word = adt7410_i2c_write_word,
 875        .read_byte = adt7410_i2c_read_byte,
 876        .write_byte = adt7410_i2c_write_byte,
 877};
 878
 879static int adt7410_i2c_probe(struct i2c_client *client,
 880        const struct i2c_device_id *id)
 881{
 882        return adt7410_probe(&client->dev, client->irq, id->name,
 883                &adt7410_i2c_ops);
 884}
 885
 886static int adt7410_i2c_remove(struct i2c_client *client)
 887{
 888        return adt7410_remove(&client->dev, client->irq);
 889}
 890
 891static const struct i2c_device_id adt7410_id[] = {
 892        { "adt7410", 0 },
 893        {}
 894};
 895
 896MODULE_DEVICE_TABLE(i2c, adt7410_id);
 897
 898static struct i2c_driver adt7410_driver = {
 899        .driver = {
 900                .name = "adt7410",
 901        },
 902        .probe = adt7410_i2c_probe,
 903        .remove = adt7410_i2c_remove,
 904        .id_table = adt7410_id,
 905};
 906
 907static int __init adt7410_i2c_init(void)
 908{
 909        return i2c_add_driver(&adt7410_driver);
 910}
 911
 912static void __exit adt7410_i2c_exit(void)
 913{
 914        i2c_del_driver(&adt7410_driver);
 915}
 916
 917#else
 918
 919static int  __init adt7410_i2c_init(void) { return 0; };
 920static void __exit adt7410_i2c_exit(void) {};
 921
 922#endif
 923
 924#if IS_ENABLED(CONFIG_SPI_MASTER)
 925
 926static const u8 adt7371_reg_table[] = {
 927        [ADT7410_TEMPERATURE]   = ADT7310_TEMPERATURE,
 928        [ADT7410_STATUS]        = ADT7310_STATUS,
 929        [ADT7410_CONFIG]        = ADT7310_CONFIG,
 930        [ADT7410_T_ALARM_HIGH]  = ADT7310_T_ALARM_HIGH,
 931        [ADT7410_T_ALARM_LOW]   = ADT7310_T_ALARM_LOW,
 932        [ADT7410_T_CRIT]        = ADT7310_T_CRIT,
 933        [ADT7410_T_HYST]        = ADT7310_T_HYST,
 934        [ADT7410_ID]            = ADT7310_ID,
 935};
 936
 937#define AD7310_COMMAND(reg) (adt7371_reg_table[(reg)] << ADT7310_CMD_REG_OFFSET)
 938
 939static int adt7310_spi_read_word(struct adt7410_chip_info *chip,
 940        u8 reg, u16 *data)
 941{
 942        struct spi_device *spi = to_spi_device(chip->dev);
 943        u8 command = AD7310_COMMAND(reg);
 944        int ret = 0;
 945
 946        command |= ADT7310_CMD_READ;
 947        ret = spi_write(spi, &command, sizeof(command));
 948        if (ret < 0) {
 949                dev_err(&spi->dev, "SPI write command error\n");
 950                return ret;
 951        }
 952
 953        ret = spi_read(spi, (u8 *)data, sizeof(*data));
 954        if (ret < 0) {
 955                dev_err(&spi->dev, "SPI read word error\n");
 956                return ret;
 957        }
 958
 959        *data = be16_to_cpu(*data);
 960
 961        return 0;
 962}
 963
 964static int adt7310_spi_write_word(struct adt7410_chip_info *chip, u8 reg,
 965        u16 data)
 966{
 967        struct spi_device *spi = to_spi_device(chip->dev);
 968        u8 buf[3];
 969        int ret = 0;
 970
 971        buf[0] = AD7310_COMMAND(reg);
 972        buf[1] = (u8)(data >> 8);
 973        buf[2] = (u8)(data & 0xFF);
 974
 975        ret = spi_write(spi, buf, 3);
 976        if (ret < 0) {
 977                dev_err(&spi->dev, "SPI write word error\n");
 978                return ret;
 979        }
 980
 981        return ret;
 982}
 983
 984static int adt7310_spi_read_byte(struct adt7410_chip_info *chip, u8 reg,
 985        u8 *data)
 986{
 987        struct spi_device *spi = to_spi_device(chip->dev);
 988        u8 command = AD7310_COMMAND(reg);
 989        int ret = 0;
 990
 991        command |= ADT7310_CMD_READ;
 992        ret = spi_write(spi, &command, sizeof(command));
 993        if (ret < 0) {
 994                dev_err(&spi->dev, "SPI write command error\n");
 995                return ret;
 996        }
 997
 998        ret = spi_read(spi, data, sizeof(*data));
 999        if (ret < 0) {
1000                dev_err(&spi->dev, "SPI read byte error\n");
1001                return ret;
1002        }
1003
1004        return 0;
1005}
1006
1007static int adt7310_spi_write_byte(struct adt7410_chip_info *chip, u8 reg,
1008        u8 data)
1009{
1010        struct spi_device *spi = to_spi_device(chip->dev);
1011        u8 buf[2];
1012        int ret = 0;
1013
1014        buf[0] = AD7310_COMMAND(reg);
1015        buf[1] = data;
1016
1017        ret = spi_write(spi, buf, 2);
1018        if (ret < 0) {
1019                dev_err(&spi->dev, "SPI write byte error\n");
1020                return ret;
1021        }
1022
1023        return ret;
1024}
1025
1026static const struct adt7410_ops adt7310_spi_ops = {
1027        .read_word = adt7310_spi_read_word,
1028        .write_word = adt7310_spi_write_word,
1029        .read_byte = adt7310_spi_read_byte,
1030        .write_byte = adt7310_spi_write_byte,
1031};
1032
1033static int adt7310_spi_probe(struct spi_device *spi)
1034{
1035        return adt7410_probe(&spi->dev, spi->irq,
1036                spi_get_device_id(spi)->name, &adt7310_spi_ops);
1037}
1038
1039static int adt7310_spi_remove(struct spi_device *spi)
1040{
1041        return adt7410_remove(&spi->dev, spi->irq);
1042}
1043
1044static const struct spi_device_id adt7310_id[] = {
1045        { "adt7310", 0 },
1046        {}
1047};
1048MODULE_DEVICE_TABLE(spi, adt7310_id);
1049
1050static struct spi_driver adt7310_driver = {
1051        .driver = {
1052                .name = "adt7310",
1053                .owner = THIS_MODULE,
1054        },
1055        .probe = adt7310_spi_probe,
1056        .remove = adt7310_spi_remove,
1057        .id_table = adt7310_id,
1058};
1059
1060static int __init adt7310_spi_init(void)
1061{
1062        return spi_register_driver(&adt7310_driver);
1063}
1064
1065static void adt7310_spi_exit(void)
1066{
1067        spi_unregister_driver(&adt7310_driver);
1068}
1069
1070#else
1071
1072static int __init adt7310_spi_init(void) { return 0; };
1073static void adt7310_spi_exit(void) {};
1074
1075#endif
1076
1077static int __init adt7410_init(void)
1078{
1079        int ret;
1080
1081        ret = adt7310_spi_init();
1082        if (ret)
1083                return ret;
1084
1085        ret = adt7410_i2c_init();
1086        if (ret)
1087                adt7310_spi_exit();
1088
1089        return ret;
1090}
1091module_init(adt7410_init);
1092
1093static void __exit adt7410_exit(void)
1094{
1095        adt7410_i2c_exit();
1096        adt7310_spi_exit();
1097}
1098module_exit(adt7410_exit);
1099
1100MODULE_AUTHOR("Sonic Zhang <sonic.zhang@analog.com>");
1101MODULE_DESCRIPTION("Analog Devices ADT7310/ADT7410 digital temperature sensor driver");
1102MODULE_LICENSE("GPL v2");
1103