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