305 lines · c
1// SPDX-License-Identifier: GPL-2.0+2/*3 * maxim_thermocouple.c - Support for Maxim thermocouple chips4 *5 * Copyright (C) 2016-2018 Matt Ranostay6 * Author: <matt.ranostay@konsulko.com>7 */8 9#include <linux/init.h>10#include <linux/mod_devicetable.h>11#include <linux/module.h>12#include <linux/mutex.h>13#include <linux/err.h>14#include <linux/spi/spi.h>15#include <linux/iio/iio.h>16#include <linux/iio/sysfs.h>17#include <linux/iio/trigger.h>18#include <linux/iio/buffer.h>19#include <linux/iio/triggered_buffer.h>20#include <linux/iio/trigger_consumer.h>21 22#define MAXIM_THERMOCOUPLE_DRV_NAME "maxim_thermocouple"23 24enum {25 MAX6675,26 MAX31855,27 MAX31855K,28 MAX31855J,29 MAX31855N,30 MAX31855S,31 MAX31855T,32 MAX31855E,33 MAX31855R,34};35 36static const char maxim_tc_types[] = {37 'K', '?', 'K', 'J', 'N', 'S', 'T', 'E', 'R'38};39 40static const struct iio_chan_spec max6675_channels[] = {41 { /* thermocouple temperature */42 .type = IIO_TEMP,43 .info_mask_separate =44 BIT(IIO_CHAN_INFO_RAW) | BIT(IIO_CHAN_INFO_SCALE) |45 BIT(IIO_CHAN_INFO_THERMOCOUPLE_TYPE),46 .scan_index = 0,47 .scan_type = {48 .sign = 's',49 .realbits = 13,50 .storagebits = 16,51 .shift = 3,52 .endianness = IIO_BE,53 },54 },55 IIO_CHAN_SOFT_TIMESTAMP(1),56};57 58static const struct iio_chan_spec max31855_channels[] = {59 { /* thermocouple temperature */60 .type = IIO_TEMP,61 .address = 2,62 .info_mask_separate =63 BIT(IIO_CHAN_INFO_RAW) | BIT(IIO_CHAN_INFO_SCALE) |64 BIT(IIO_CHAN_INFO_THERMOCOUPLE_TYPE),65 .scan_index = 0,66 .scan_type = {67 .sign = 's',68 .realbits = 14,69 .storagebits = 16,70 .shift = 2,71 .endianness = IIO_BE,72 },73 },74 { /* cold junction temperature */75 .type = IIO_TEMP,76 .address = 0,77 .channel2 = IIO_MOD_TEMP_AMBIENT,78 .modified = 1,79 .info_mask_separate =80 BIT(IIO_CHAN_INFO_RAW) | BIT(IIO_CHAN_INFO_SCALE),81 .scan_index = 1,82 .scan_type = {83 .sign = 's',84 .realbits = 12,85 .storagebits = 16,86 .shift = 4,87 .endianness = IIO_BE,88 },89 },90 IIO_CHAN_SOFT_TIMESTAMP(2),91};92 93static const unsigned long max31855_scan_masks[] = {0x3, 0};94 95struct maxim_thermocouple_chip {96 const struct iio_chan_spec *channels;97 const unsigned long *scan_masks;98 u8 num_channels;99 u8 read_size;100 101 /* bit-check for valid input */102 u32 status_bit;103};104 105static const struct maxim_thermocouple_chip maxim_thermocouple_chips[] = {106 [MAX6675] = {107 .channels = max6675_channels,108 .num_channels = ARRAY_SIZE(max6675_channels),109 .read_size = 2,110 .status_bit = BIT(2),111 },112 [MAX31855] = {113 .channels = max31855_channels,114 .num_channels = ARRAY_SIZE(max31855_channels),115 .read_size = 4,116 .scan_masks = max31855_scan_masks,117 .status_bit = BIT(16),118 },119};120 121struct maxim_thermocouple_data {122 struct spi_device *spi;123 const struct maxim_thermocouple_chip *chip;124 125 u8 buffer[16] __aligned(IIO_DMA_MINALIGN);126 char tc_type;127};128 129static int maxim_thermocouple_read(struct maxim_thermocouple_data *data,130 struct iio_chan_spec const *chan, int *val)131{132 unsigned int storage_bytes = data->chip->read_size;133 unsigned int shift = chan->scan_type.shift + (chan->address * 8);134 __be16 buf16;135 __be32 buf32;136 int ret;137 138 switch (storage_bytes) {139 case 2:140 ret = spi_read(data->spi, (void *)&buf16, storage_bytes);141 *val = be16_to_cpu(buf16);142 break;143 case 4:144 ret = spi_read(data->spi, (void *)&buf32, storage_bytes);145 *val = be32_to_cpu(buf32);146 break;147 default:148 ret = -EINVAL;149 }150 151 if (ret)152 return ret;153 154 /* check to be sure this is a valid reading */155 if (*val & data->chip->status_bit)156 return -EINVAL;157 158 *val = sign_extend32(*val >> shift, chan->scan_type.realbits - 1);159 160 return 0;161}162 163static irqreturn_t maxim_thermocouple_trigger_handler(int irq, void *private)164{165 struct iio_poll_func *pf = private;166 struct iio_dev *indio_dev = pf->indio_dev;167 struct maxim_thermocouple_data *data = iio_priv(indio_dev);168 int ret;169 170 ret = spi_read(data->spi, data->buffer, data->chip->read_size);171 if (!ret) {172 iio_push_to_buffers_with_timestamp(indio_dev, data->buffer,173 iio_get_time_ns(indio_dev));174 }175 176 iio_trigger_notify_done(indio_dev->trig);177 178 return IRQ_HANDLED;179}180 181static int maxim_thermocouple_read_raw(struct iio_dev *indio_dev,182 struct iio_chan_spec const *chan,183 int *val, int *val2, long mask)184{185 struct maxim_thermocouple_data *data = iio_priv(indio_dev);186 int ret = -EINVAL;187 188 switch (mask) {189 case IIO_CHAN_INFO_RAW:190 ret = iio_device_claim_direct_mode(indio_dev);191 if (ret)192 return ret;193 194 ret = maxim_thermocouple_read(data, chan, val);195 iio_device_release_direct_mode(indio_dev);196 197 if (!ret)198 return IIO_VAL_INT;199 200 break;201 case IIO_CHAN_INFO_SCALE:202 switch (chan->channel2) {203 case IIO_MOD_TEMP_AMBIENT:204 *val = 62;205 *val2 = 500000; /* 1000 * 0.0625 */206 ret = IIO_VAL_INT_PLUS_MICRO;207 break;208 default:209 *val = 250; /* 1000 * 0.25 */210 ret = IIO_VAL_INT;211 }212 break;213 case IIO_CHAN_INFO_THERMOCOUPLE_TYPE:214 *val = data->tc_type;215 ret = IIO_VAL_CHAR;216 break;217 }218 219 return ret;220}221 222static const struct iio_info maxim_thermocouple_info = {223 .read_raw = maxim_thermocouple_read_raw,224};225 226static int maxim_thermocouple_probe(struct spi_device *spi)227{228 const struct spi_device_id *id = spi_get_device_id(spi);229 struct iio_dev *indio_dev;230 struct maxim_thermocouple_data *data;231 const int chip_type = (id->driver_data == MAX6675) ? MAX6675 : MAX31855;232 const struct maxim_thermocouple_chip *chip =233 &maxim_thermocouple_chips[chip_type];234 int ret;235 236 indio_dev = devm_iio_device_alloc(&spi->dev, sizeof(*data));237 if (!indio_dev)238 return -ENOMEM;239 240 indio_dev->info = &maxim_thermocouple_info;241 indio_dev->name = MAXIM_THERMOCOUPLE_DRV_NAME;242 indio_dev->channels = chip->channels;243 indio_dev->available_scan_masks = chip->scan_masks;244 indio_dev->num_channels = chip->num_channels;245 indio_dev->modes = INDIO_DIRECT_MODE;246 247 data = iio_priv(indio_dev);248 data->spi = spi;249 data->chip = chip;250 data->tc_type = maxim_tc_types[id->driver_data];251 252 ret = devm_iio_triggered_buffer_setup(&spi->dev,253 indio_dev, NULL,254 maxim_thermocouple_trigger_handler, NULL);255 if (ret)256 return ret;257 258 if (id->driver_data == MAX31855)259 dev_warn(&spi->dev, "generic max31855 ID is deprecated\nplease use more specific part type");260 261 return devm_iio_device_register(&spi->dev, indio_dev);262}263 264static const struct spi_device_id maxim_thermocouple_id[] = {265 {"max6675", MAX6675},266 {"max31855", MAX31855},267 {"max31855k", MAX31855K},268 {"max31855j", MAX31855J},269 {"max31855n", MAX31855N},270 {"max31855s", MAX31855S},271 {"max31855t", MAX31855T},272 {"max31855e", MAX31855E},273 {"max31855r", MAX31855R},274 {},275};276MODULE_DEVICE_TABLE(spi, maxim_thermocouple_id);277 278static const struct of_device_id maxim_thermocouple_of_match[] = {279 { .compatible = "maxim,max6675" },280 { .compatible = "maxim,max31855" },281 { .compatible = "maxim,max31855k" },282 { .compatible = "maxim,max31855j" },283 { .compatible = "maxim,max31855n" },284 { .compatible = "maxim,max31855s" },285 { .compatible = "maxim,max31855t" },286 { .compatible = "maxim,max31855e" },287 { .compatible = "maxim,max31855r" },288 { },289};290MODULE_DEVICE_TABLE(of, maxim_thermocouple_of_match);291 292static struct spi_driver maxim_thermocouple_driver = {293 .driver = {294 .name = MAXIM_THERMOCOUPLE_DRV_NAME,295 .of_match_table = maxim_thermocouple_of_match,296 },297 .probe = maxim_thermocouple_probe,298 .id_table = maxim_thermocouple_id,299};300module_spi_driver(maxim_thermocouple_driver);301 302MODULE_AUTHOR("Matt Ranostay <matt.ranostay@konsulko.com>");303MODULE_DESCRIPTION("Maxim thermocouple sensors");304MODULE_LICENSE("GPL");305