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/err.h> 13 #include <linux/spi/spi.h> 14 #include <linux/types.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 24 enum { 25 MAX6675, 26 MAX31855, 27 MAX31855K, 28 MAX31855J, 29 MAX31855N, 30 MAX31855S, 31 MAX31855T, 32 MAX31855E, 33 MAX31855R, 34 }; 35 36 static const char maxim_tc_types[] = { 37 'K', '?', 'K', 'J', 'N', 'S', 'T', 'E', 'R' 38 }; 39 40 static 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 58 static 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 93 static const unsigned long max31855_scan_masks[] = {0x3, 0}; 94 95 struct 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 105 static 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 121 struct maxim_thermocouple_data { 122 struct spi_device *spi; 123 const struct maxim_thermocouple_chip *chip; 124 char tc_type; 125 /* Buffer for reading up to 2 hardware channels. */ 126 struct { 127 union { 128 __be16 raw16; 129 __be32 raw32; 130 __be16 raw[2]; 131 }; 132 aligned_s64 timestamp; 133 } buffer __aligned(IIO_DMA_MINALIGN); 134 }; 135 136 static int maxim_thermocouple_read(struct maxim_thermocouple_data *data, 137 struct iio_chan_spec const *chan, int *val) 138 { 139 unsigned int storage_bytes = data->chip->read_size; 140 unsigned int shift = chan->scan_type.shift + (chan->address * 8); 141 int ret; 142 143 switch (storage_bytes) { 144 case 2: 145 ret = spi_read(data->spi, &data->buffer.raw16, storage_bytes); 146 *val = be16_to_cpu(data->buffer.raw16); 147 break; 148 case 4: 149 ret = spi_read(data->spi, &data->buffer.raw32, storage_bytes); 150 *val = be32_to_cpu(data->buffer.raw32); 151 break; 152 default: 153 ret = -EINVAL; 154 } 155 156 if (ret) 157 return ret; 158 159 /* check to be sure this is a valid reading */ 160 if (*val & data->chip->status_bit) 161 return -EINVAL; 162 163 *val = sign_extend32(*val >> shift, chan->scan_type.realbits - 1); 164 165 return 0; 166 } 167 168 static irqreturn_t maxim_thermocouple_trigger_handler(int irq, void *private) 169 { 170 struct iio_poll_func *pf = private; 171 struct iio_dev *indio_dev = pf->indio_dev; 172 struct maxim_thermocouple_data *data = iio_priv(indio_dev); 173 int ret; 174 175 ret = spi_read(data->spi, data->buffer.raw, data->chip->read_size); 176 if (!ret) { 177 iio_push_to_buffers_with_ts(indio_dev, &data->buffer, 178 sizeof(data->buffer), 179 iio_get_time_ns(indio_dev)); 180 } 181 182 iio_trigger_notify_done(indio_dev->trig); 183 184 return IRQ_HANDLED; 185 } 186 187 static int maxim_thermocouple_read_raw(struct iio_dev *indio_dev, 188 struct iio_chan_spec const *chan, 189 int *val, int *val2, long mask) 190 { 191 struct maxim_thermocouple_data *data = iio_priv(indio_dev); 192 int ret; 193 194 switch (mask) { 195 case IIO_CHAN_INFO_RAW: 196 if (!iio_device_claim_direct(indio_dev)) 197 return -EBUSY; 198 199 ret = maxim_thermocouple_read(data, chan, val); 200 iio_device_release_direct(indio_dev); 201 if (ret) 202 return ret; 203 204 return IIO_VAL_INT; 205 case IIO_CHAN_INFO_SCALE: 206 switch (chan->channel2) { 207 case IIO_MOD_TEMP_AMBIENT: 208 *val = 62; 209 *val2 = 500000; /* 1000 * 0.0625 */ 210 return IIO_VAL_INT_PLUS_MICRO; 211 default: 212 *val = 250; /* 1000 * 0.25 */ 213 return IIO_VAL_INT; 214 } 215 case IIO_CHAN_INFO_THERMOCOUPLE_TYPE: 216 *val = data->tc_type; 217 return IIO_VAL_CHAR; 218 default: 219 return -EINVAL; 220 } 221 } 222 223 static const struct iio_info maxim_thermocouple_info = { 224 .read_raw = maxim_thermocouple_read_raw, 225 }; 226 227 static int maxim_thermocouple_probe(struct spi_device *spi) 228 { 229 const struct spi_device_id *id = spi_get_device_id(spi); 230 struct iio_dev *indio_dev; 231 struct maxim_thermocouple_data *data; 232 const int chip_type = (id->driver_data == MAX6675) ? MAX6675 : MAX31855; 233 const struct maxim_thermocouple_chip *chip = 234 &maxim_thermocouple_chips[chip_type]; 235 int ret; 236 237 indio_dev = devm_iio_device_alloc(&spi->dev, sizeof(*data)); 238 if (!indio_dev) 239 return -ENOMEM; 240 241 indio_dev->info = &maxim_thermocouple_info; 242 indio_dev->name = MAXIM_THERMOCOUPLE_DRV_NAME; 243 indio_dev->channels = chip->channels; 244 indio_dev->available_scan_masks = chip->scan_masks; 245 indio_dev->num_channels = chip->num_channels; 246 indio_dev->modes = INDIO_DIRECT_MODE; 247 248 data = iio_priv(indio_dev); 249 data->spi = spi; 250 data->chip = chip; 251 data->tc_type = maxim_tc_types[id->driver_data]; 252 253 ret = devm_iio_triggered_buffer_setup(&spi->dev, 254 indio_dev, NULL, 255 maxim_thermocouple_trigger_handler, NULL); 256 if (ret) 257 return ret; 258 259 if (id->driver_data == MAX31855) 260 dev_warn(&spi->dev, "generic max31855 ID is deprecated\nplease use more specific part type"); 261 262 return devm_iio_device_register(&spi->dev, indio_dev); 263 } 264 265 static const struct spi_device_id maxim_thermocouple_id[] = { 266 {"max6675", MAX6675}, 267 {"max31855", MAX31855}, 268 {"max31855k", MAX31855K}, 269 {"max31855j", MAX31855J}, 270 {"max31855n", MAX31855N}, 271 {"max31855s", MAX31855S}, 272 {"max31855t", MAX31855T}, 273 {"max31855e", MAX31855E}, 274 {"max31855r", MAX31855R}, 275 { } 276 }; 277 MODULE_DEVICE_TABLE(spi, maxim_thermocouple_id); 278 279 static const struct of_device_id maxim_thermocouple_of_match[] = { 280 { .compatible = "maxim,max6675" }, 281 { .compatible = "maxim,max31855" }, 282 { .compatible = "maxim,max31855k" }, 283 { .compatible = "maxim,max31855j" }, 284 { .compatible = "maxim,max31855n" }, 285 { .compatible = "maxim,max31855s" }, 286 { .compatible = "maxim,max31855t" }, 287 { .compatible = "maxim,max31855e" }, 288 { .compatible = "maxim,max31855r" }, 289 { }, 290 }; 291 MODULE_DEVICE_TABLE(of, maxim_thermocouple_of_match); 292 293 static struct spi_driver maxim_thermocouple_driver = { 294 .driver = { 295 .name = MAXIM_THERMOCOUPLE_DRV_NAME, 296 .of_match_table = maxim_thermocouple_of_match, 297 }, 298 .probe = maxim_thermocouple_probe, 299 .id_table = maxim_thermocouple_id, 300 }; 301 module_spi_driver(maxim_thermocouple_driver); 302 303 MODULE_AUTHOR("Matt Ranostay <matt.ranostay@konsulko.com>"); 304 MODULE_DESCRIPTION("Maxim thermocouple sensors"); 305 MODULE_LICENSE("GPL"); 306