maxim_thermocouple.c (7485B)
1// SPDX-License-Identifier: GPL-2.0+ 2/* 3 * maxim_thermocouple.c - Support for Maxim thermocouple chips 4 * 5 * Copyright (C) 2016-2018 Matt Ranostay 6 * 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] ____cacheline_aligned; 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");