linux/drivers/iio/temperature/max31856.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0
   2/* max31856.c
   3 *
   4 * Maxim MAX31856 thermocouple sensor driver
   5 *
   6 * Copyright (C) 2018-2019 Rockwell Collins
   7 */
   8
   9#include <linux/ctype.h>
  10#include <linux/module.h>
  11#include <linux/init.h>
  12#include <linux/err.h>
  13#include <linux/spi/spi.h>
  14#include <linux/iio/iio.h>
  15#include <linux/iio/sysfs.h>
  16#include <linux/util_macros.h>
  17#include <asm/unaligned.h>
  18#include <dt-bindings/iio/temperature/thermocouple.h>
  19/*
  20 * The MSB of the register value determines whether the following byte will
  21 * be written or read. If it is 0, one or more byte reads will follow.
  22 */
  23#define MAX31856_RD_WR_BIT         BIT(7)
  24
  25#define MAX31856_CR0_AUTOCONVERT   BIT(7)
  26#define MAX31856_CR0_1SHOT         BIT(6)
  27#define MAX31856_CR0_OCFAULT       BIT(4)
  28#define MAX31856_CR0_OCFAULT_MASK  GENMASK(5, 4)
  29#define MAX31856_CR0_FILTER_50HZ   BIT(0)
  30#define MAX31856_AVERAGING_MASK    GENMASK(6, 4)
  31#define MAX31856_AVERAGING_SHIFT   4
  32#define MAX31856_TC_TYPE_MASK      GENMASK(3, 0)
  33#define MAX31856_FAULT_OVUV        BIT(1)
  34#define MAX31856_FAULT_OPEN        BIT(0)
  35
  36/* The MAX31856 registers */
  37#define MAX31856_CR0_REG           0x00
  38#define MAX31856_CR1_REG           0x01
  39#define MAX31856_MASK_REG          0x02
  40#define MAX31856_CJHF_REG          0x03
  41#define MAX31856_CJLF_REG          0x04
  42#define MAX31856_LTHFTH_REG        0x05
  43#define MAX31856_LTHFTL_REG        0x06
  44#define MAX31856_LTLFTH_REG        0x07
  45#define MAX31856_LTLFTL_REG        0x08
  46#define MAX31856_CJTO_REG          0x09
  47#define MAX31856_CJTH_REG          0x0A
  48#define MAX31856_CJTL_REG          0x0B
  49#define MAX31856_LTCBH_REG         0x0C
  50#define MAX31856_LTCBM_REG         0x0D
  51#define MAX31856_LTCBL_REG         0x0E
  52#define MAX31856_SR_REG            0x0F
  53
  54static const struct iio_chan_spec max31856_channels[] = {
  55        {       /* Thermocouple Temperature */
  56                .type = IIO_TEMP,
  57                .info_mask_separate =
  58                        BIT(IIO_CHAN_INFO_RAW) | BIT(IIO_CHAN_INFO_SCALE) |
  59                        BIT(IIO_CHAN_INFO_THERMOCOUPLE_TYPE),
  60                .info_mask_shared_by_type =
  61                        BIT(IIO_CHAN_INFO_OVERSAMPLING_RATIO)
  62        },
  63        {       /* Cold Junction Temperature */
  64                .type = IIO_TEMP,
  65                .channel2 = IIO_MOD_TEMP_AMBIENT,
  66                .modified = 1,
  67                .info_mask_separate =
  68                        BIT(IIO_CHAN_INFO_RAW) | BIT(IIO_CHAN_INFO_SCALE),
  69                .info_mask_shared_by_type =
  70                        BIT(IIO_CHAN_INFO_OVERSAMPLING_RATIO)
  71        },
  72};
  73
  74struct max31856_data {
  75        struct spi_device *spi;
  76        u32 thermocouple_type;
  77        bool filter_50hz;
  78        int averaging;
  79};
  80
  81static const char max31856_tc_types[] = {
  82        'B', 'E', 'J', 'K', 'N', 'R', 'S', 'T'
  83};
  84
  85static int max31856_read(struct max31856_data *data, u8 reg,
  86                         u8 val[], unsigned int read_size)
  87{
  88        return spi_write_then_read(data->spi, &reg, 1, val, read_size);
  89}
  90
  91static int max31856_write(struct max31856_data *data, u8 reg,
  92                          unsigned int val)
  93{
  94        u8 buf[2];
  95
  96        buf[0] = reg | (MAX31856_RD_WR_BIT);
  97        buf[1] = val;
  98
  99        return spi_write(data->spi, buf, 2);
 100}
 101
 102static int max31856_init(struct max31856_data *data)
 103{
 104        int ret;
 105        u8 reg_cr0_val, reg_cr1_val;
 106
 107        /* Start by changing to Off mode before making changes as
 108         * some settings are recommended to be set only when the device
 109         * is off
 110         */
 111        ret = max31856_read(data, MAX31856_CR0_REG, &reg_cr0_val, 1);
 112        if (ret)
 113                return ret;
 114
 115        reg_cr0_val &= ~MAX31856_CR0_AUTOCONVERT;
 116        ret = max31856_write(data, MAX31856_CR0_REG, reg_cr0_val);
 117        if (ret)
 118                return ret;
 119
 120        /* Set thermocouple type based on dts property */
 121        ret = max31856_read(data, MAX31856_CR1_REG, &reg_cr1_val, 1);
 122        if (ret)
 123                return ret;
 124
 125        reg_cr1_val &= ~MAX31856_TC_TYPE_MASK;
 126        reg_cr1_val |= data->thermocouple_type;
 127
 128        reg_cr1_val &= ~MAX31856_AVERAGING_MASK;
 129        reg_cr1_val |= data->averaging << MAX31856_AVERAGING_SHIFT;
 130
 131        ret = max31856_write(data, MAX31856_CR1_REG, reg_cr1_val);
 132        if (ret)
 133                return ret;
 134
 135        /*
 136         * Enable Open circuit fault detection
 137         * Read datasheet for more information: Table 4.
 138         * Value 01 means : Enabled (Once every 16 conversions)
 139         */
 140        reg_cr0_val &= ~MAX31856_CR0_OCFAULT_MASK;
 141        reg_cr0_val |= MAX31856_CR0_OCFAULT;
 142
 143        /* Set Auto Conversion Mode */
 144        reg_cr0_val &= ~MAX31856_CR0_1SHOT;
 145        reg_cr0_val |= MAX31856_CR0_AUTOCONVERT;
 146
 147        if (data->filter_50hz)
 148                reg_cr0_val |= MAX31856_CR0_FILTER_50HZ;
 149        else
 150                reg_cr0_val &= ~MAX31856_CR0_FILTER_50HZ;
 151
 152        return max31856_write(data, MAX31856_CR0_REG, reg_cr0_val);
 153}
 154
 155static int max31856_thermocouple_read(struct max31856_data *data,
 156                                      struct iio_chan_spec const *chan,
 157                                      int *val)
 158{
 159        int ret, offset_cjto;
 160        u8 reg_val[3];
 161
 162        switch (chan->channel2) {
 163        case IIO_NO_MOD:
 164                /*
 165                 * Multibyte Read
 166                 * MAX31856_LTCBH_REG, MAX31856_LTCBM_REG, MAX31856_LTCBL_REG
 167                 */
 168                ret = max31856_read(data, MAX31856_LTCBH_REG, reg_val, 3);
 169                if (ret)
 170                        return ret;
 171                /* Skip last 5 dead bits of LTCBL */
 172                *val = get_unaligned_be24(&reg_val[0]) >> 5;
 173                /* Check 7th bit of LTCBH reg. value for sign*/
 174                if (reg_val[0] & 0x80)
 175                        *val -= 0x80000;
 176                break;
 177
 178        case IIO_MOD_TEMP_AMBIENT:
 179                /*
 180                 * Multibyte Read
 181                 * MAX31856_CJTO_REG, MAX31856_CJTH_REG, MAX31856_CJTL_REG
 182                 */
 183                ret = max31856_read(data, MAX31856_CJTO_REG, reg_val, 3);
 184                if (ret)
 185                        return ret;
 186                /* Get Cold Junction Temp. offset register value */
 187                offset_cjto = reg_val[0];
 188                /* Get CJTH and CJTL value and skip last 2 dead bits of CJTL */
 189                *val = get_unaligned_be16(&reg_val[1]) >> 2;
 190                /* As per datasheet add offset into CJTH and CJTL */
 191                *val += offset_cjto;
 192                /* Check 7th bit of CJTH reg. value for sign */
 193                if (reg_val[1] & 0x80)
 194                        *val -= 0x4000;
 195                break;
 196
 197        default:
 198                return -EINVAL;
 199        }
 200
 201        ret = max31856_read(data, MAX31856_SR_REG, reg_val, 1);
 202        if (ret)
 203                return ret;
 204        /* Check for over/under voltage or open circuit fault */
 205        if (reg_val[0] & (MAX31856_FAULT_OVUV | MAX31856_FAULT_OPEN))
 206                return -EIO;
 207
 208        return ret;
 209}
 210
 211static int max31856_read_raw(struct iio_dev *indio_dev,
 212                             struct iio_chan_spec const *chan,
 213                             int *val, int *val2, long mask)
 214{
 215        struct max31856_data *data = iio_priv(indio_dev);
 216        int ret;
 217
 218        switch (mask) {
 219        case IIO_CHAN_INFO_RAW:
 220                ret = max31856_thermocouple_read(data, chan, val);
 221                if (ret)
 222                        return ret;
 223                return IIO_VAL_INT;
 224        case IIO_CHAN_INFO_SCALE:
 225                switch (chan->channel2) {
 226                case IIO_MOD_TEMP_AMBIENT:
 227                        /* Cold junction Temp. Data resolution is 0.015625 */
 228                        *val = 15;
 229                        *val2 = 625000; /* 1000 * 0.015625 */
 230                        ret = IIO_VAL_INT_PLUS_MICRO;
 231                        break;
 232                default:
 233                        /* Thermocouple Temp. Data resolution is 0.0078125 */
 234                        *val = 7;
 235                        *val2 = 812500; /* 1000 * 0.0078125) */
 236                        return IIO_VAL_INT_PLUS_MICRO;
 237                }
 238                break;
 239        case IIO_CHAN_INFO_OVERSAMPLING_RATIO:
 240                *val = 1 << data->averaging;
 241                return IIO_VAL_INT;
 242        case IIO_CHAN_INFO_THERMOCOUPLE_TYPE:
 243                *val = max31856_tc_types[data->thermocouple_type];
 244                return IIO_VAL_CHAR;
 245        default:
 246                ret = -EINVAL;
 247                break;
 248        }
 249
 250        return ret;
 251}
 252
 253static int max31856_write_raw_get_fmt(struct iio_dev *indio_dev,
 254                                      struct iio_chan_spec const *chan,
 255                                      long mask)
 256{
 257        switch (mask) {
 258        case IIO_CHAN_INFO_THERMOCOUPLE_TYPE:
 259                return IIO_VAL_CHAR;
 260        default:
 261                return IIO_VAL_INT;
 262        }
 263}
 264
 265static int max31856_write_raw(struct iio_dev *indio_dev,
 266                              struct iio_chan_spec const *chan,
 267                              int val, int val2, long mask)
 268{
 269        struct max31856_data *data = iio_priv(indio_dev);
 270        int msb;
 271
 272        switch (mask) {
 273        case IIO_CHAN_INFO_OVERSAMPLING_RATIO:
 274                if (val > 16 || val < 1)
 275                        return -EINVAL;
 276                msb = fls(val) - 1;
 277                /* Round up to next 2pow if needed */
 278                if (BIT(msb) < val)
 279                        msb++;
 280
 281                data->averaging = msb;
 282                max31856_init(data);
 283                break;
 284        case IIO_CHAN_INFO_THERMOCOUPLE_TYPE:
 285        {
 286                int tc_type = -1;
 287                int i;
 288
 289                for (i = 0; i < ARRAY_SIZE(max31856_tc_types); i++) {
 290                        if (max31856_tc_types[i] == toupper(val)) {
 291                                tc_type = i;
 292                                break;
 293                        }
 294                }
 295                if (tc_type < 0)
 296                        return -EINVAL;
 297
 298                data->thermocouple_type = tc_type;
 299                max31856_init(data);
 300                break;
 301        }
 302        default:
 303                return -EINVAL;
 304        }
 305
 306        return 0;
 307}
 308
 309static ssize_t show_fault(struct device *dev, u8 faultbit, char *buf)
 310{
 311        struct iio_dev *indio_dev = dev_to_iio_dev(dev);
 312        struct max31856_data *data = iio_priv(indio_dev);
 313        u8 reg_val;
 314        int ret;
 315        bool fault;
 316
 317        ret = max31856_read(data, MAX31856_SR_REG, &reg_val, 1);
 318        if (ret)
 319                return ret;
 320
 321        fault = reg_val & faultbit;
 322
 323        return sprintf(buf, "%d\n", fault);
 324}
 325
 326static ssize_t show_fault_ovuv(struct device *dev,
 327                               struct device_attribute *attr,
 328                               char *buf)
 329{
 330        return show_fault(dev, MAX31856_FAULT_OVUV, buf);
 331}
 332
 333static ssize_t show_fault_oc(struct device *dev,
 334                             struct device_attribute *attr,
 335                             char *buf)
 336{
 337        return show_fault(dev, MAX31856_FAULT_OPEN, buf);
 338}
 339
 340static ssize_t show_filter(struct device *dev,
 341                           struct device_attribute *attr,
 342                           char *buf)
 343{
 344        struct iio_dev *indio_dev = dev_to_iio_dev(dev);
 345        struct max31856_data *data = iio_priv(indio_dev);
 346
 347        return sprintf(buf, "%d\n", data->filter_50hz ? 50 : 60);
 348}
 349
 350static ssize_t set_filter(struct device *dev,
 351                          struct device_attribute *attr,
 352                          const char *buf,
 353                          size_t len)
 354{
 355        struct iio_dev *indio_dev = dev_to_iio_dev(dev);
 356        struct max31856_data *data = iio_priv(indio_dev);
 357        unsigned int freq;
 358        int ret;
 359
 360        ret = kstrtouint(buf, 10, &freq);
 361        if (ret)
 362                return ret;
 363
 364        switch (freq) {
 365        case 50:
 366                data->filter_50hz = true;
 367                break;
 368        case 60:
 369                data->filter_50hz = false;
 370                break;
 371        default:
 372                return -EINVAL;
 373        }
 374
 375        max31856_init(data);
 376        return len;
 377}
 378
 379static IIO_DEVICE_ATTR(fault_ovuv, 0444, show_fault_ovuv, NULL, 0);
 380static IIO_DEVICE_ATTR(fault_oc, 0444, show_fault_oc, NULL, 0);
 381static IIO_DEVICE_ATTR(in_temp_filter_notch_center_frequency, 0644,
 382                       show_filter, set_filter, 0);
 383
 384static struct attribute *max31856_attributes[] = {
 385        &iio_dev_attr_fault_ovuv.dev_attr.attr,
 386        &iio_dev_attr_fault_oc.dev_attr.attr,
 387        &iio_dev_attr_in_temp_filter_notch_center_frequency.dev_attr.attr,
 388        NULL,
 389};
 390
 391static const struct attribute_group max31856_group = {
 392        .attrs = max31856_attributes,
 393};
 394
 395static const struct iio_info max31856_info = {
 396        .read_raw = max31856_read_raw,
 397        .write_raw = max31856_write_raw,
 398        .write_raw_get_fmt = max31856_write_raw_get_fmt,
 399        .attrs = &max31856_group,
 400};
 401
 402static int max31856_probe(struct spi_device *spi)
 403{
 404        const struct spi_device_id *id = spi_get_device_id(spi);
 405        struct iio_dev *indio_dev;
 406        struct max31856_data *data;
 407        int ret;
 408
 409        indio_dev = devm_iio_device_alloc(&spi->dev, sizeof(*data));
 410        if (!indio_dev)
 411                return -ENOMEM;
 412
 413        data = iio_priv(indio_dev);
 414        data->spi = spi;
 415        data->filter_50hz = false;
 416
 417        spi_set_drvdata(spi, indio_dev);
 418
 419        indio_dev->info = &max31856_info;
 420        indio_dev->name = id->name;
 421        indio_dev->modes = INDIO_DIRECT_MODE;
 422        indio_dev->channels = max31856_channels;
 423        indio_dev->num_channels = ARRAY_SIZE(max31856_channels);
 424
 425        ret = of_property_read_u32(spi->dev.of_node, "thermocouple-type",
 426                                   &data->thermocouple_type);
 427
 428        if (ret) {
 429                dev_info(&spi->dev,
 430                         "Could not read thermocouple type DT property, configuring as a K-Type\n");
 431                data->thermocouple_type = THERMOCOUPLE_TYPE_K;
 432        }
 433
 434        /*
 435         * no need to translate values as the supported types
 436         * have the same value as the #defines
 437         */
 438        switch (data->thermocouple_type) {
 439        case THERMOCOUPLE_TYPE_B:
 440        case THERMOCOUPLE_TYPE_E:
 441        case THERMOCOUPLE_TYPE_J:
 442        case THERMOCOUPLE_TYPE_K:
 443        case THERMOCOUPLE_TYPE_N:
 444        case THERMOCOUPLE_TYPE_R:
 445        case THERMOCOUPLE_TYPE_S:
 446        case THERMOCOUPLE_TYPE_T:
 447                break;
 448        default:
 449                dev_err(&spi->dev,
 450                        "error: thermocouple-type %u not supported by max31856\n"
 451                        , data->thermocouple_type);
 452                return -EINVAL;
 453        }
 454
 455        ret = max31856_init(data);
 456        if (ret) {
 457                dev_err(&spi->dev, "error: Failed to configure max31856\n");
 458                return ret;
 459        }
 460
 461        return devm_iio_device_register(&spi->dev, indio_dev);
 462}
 463
 464static const struct spi_device_id max31856_id[] = {
 465        { "max31856", 0 },
 466        { }
 467};
 468MODULE_DEVICE_TABLE(spi, max31856_id);
 469
 470static const struct of_device_id max31856_of_match[] = {
 471        { .compatible = "maxim,max31856" },
 472        { }
 473};
 474MODULE_DEVICE_TABLE(of, max31856_of_match);
 475
 476static struct spi_driver max31856_driver = {
 477        .driver = {
 478                .name = "max31856",
 479                .of_match_table = max31856_of_match,
 480        },
 481        .probe = max31856_probe,
 482        .id_table = max31856_id,
 483};
 484module_spi_driver(max31856_driver);
 485
 486MODULE_AUTHOR("Paresh Chaudhary <paresh.chaudhary@rockwellcollins.com>");
 487MODULE_AUTHOR("Patrick Havelange <patrick.havelange@essensium.com>");
 488MODULE_DESCRIPTION("Maxim MAX31856 thermocouple sensor driver");
 489MODULE_LICENSE("GPL");
 490