1 /* 2 * maxim_thermocouple.c - Support for Maxim thermocouple chips 3 * 4 * Copyright (C) 2016 Matt Ranostay <mranostay@gmail.com> 5 * 6 * This program is free software; you can redistribute it and/or modify 7 * it under the terms of the GNU General Public License as published by 8 * the Free Software Foundation; either version 2 of the License, or 9 * (at your option) any later version. 10 * 11 * This program is distributed in the hope that it will be useful, 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 * GNU General Public License for more details. 15 */ 16 17 #include <linux/module.h> 18 #include <linux/init.h> 19 #include <linux/mutex.h> 20 #include <linux/err.h> 21 #include <linux/spi/spi.h> 22 #include <linux/iio/iio.h> 23 #include <linux/iio/trigger.h> 24 #include <linux/iio/buffer.h> 25 #include <linux/iio/triggered_buffer.h> 26 #include <linux/iio/trigger_consumer.h> 27 28 #define MAXIM_THERMOCOUPLE_DRV_NAME "maxim_thermocouple" 29 30 enum { 31 MAX6675, 32 MAX31855, 33 }; 34 35 static const struct iio_chan_spec max6675_channels[] = { 36 { /* thermocouple temperature */ 37 .type = IIO_TEMP, 38 .info_mask_separate = 39 BIT(IIO_CHAN_INFO_RAW) | BIT(IIO_CHAN_INFO_SCALE), 40 .scan_index = 0, 41 .scan_type = { 42 .sign = 's', 43 .realbits = 13, 44 .storagebits = 16, 45 .shift = 3, 46 .endianness = IIO_BE, 47 }, 48 }, 49 IIO_CHAN_SOFT_TIMESTAMP(1), 50 }; 51 52 static const struct iio_chan_spec max31855_channels[] = { 53 { /* thermocouple temperature */ 54 .type = IIO_TEMP, 55 .address = 2, 56 .info_mask_separate = 57 BIT(IIO_CHAN_INFO_RAW) | BIT(IIO_CHAN_INFO_SCALE), 58 .scan_index = 0, 59 .scan_type = { 60 .sign = 's', 61 .realbits = 14, 62 .storagebits = 16, 63 .shift = 2, 64 .endianness = IIO_BE, 65 }, 66 }, 67 { /* cold junction temperature */ 68 .type = IIO_TEMP, 69 .address = 0, 70 .channel2 = IIO_MOD_TEMP_AMBIENT, 71 .modified = 1, 72 .info_mask_separate = 73 BIT(IIO_CHAN_INFO_RAW) | BIT(IIO_CHAN_INFO_SCALE), 74 .scan_index = 1, 75 .scan_type = { 76 .sign = 's', 77 .realbits = 12, 78 .storagebits = 16, 79 .shift = 4, 80 .endianness = IIO_BE, 81 }, 82 }, 83 IIO_CHAN_SOFT_TIMESTAMP(2), 84 }; 85 86 static const unsigned long max31855_scan_masks[] = {0x3, 0}; 87 88 struct maxim_thermocouple_chip { 89 const struct iio_chan_spec *channels; 90 const unsigned long *scan_masks; 91 u8 num_channels; 92 u8 read_size; 93 94 /* bit-check for valid input */ 95 u32 status_bit; 96 }; 97 98 static const struct maxim_thermocouple_chip maxim_thermocouple_chips[] = { 99 [MAX6675] = { 100 .channels = max6675_channels, 101 .num_channels = ARRAY_SIZE(max6675_channels), 102 .read_size = 2, 103 .status_bit = BIT(2), 104 }, 105 [MAX31855] = { 106 .channels = max31855_channels, 107 .num_channels = ARRAY_SIZE(max31855_channels), 108 .read_size = 4, 109 .scan_masks = max31855_scan_masks, 110 .status_bit = BIT(16), 111 }, 112 }; 113 114 struct maxim_thermocouple_data { 115 struct spi_device *spi; 116 const struct maxim_thermocouple_chip *chip; 117 118 u8 buffer[16] ____cacheline_aligned; 119 }; 120 121 static int maxim_thermocouple_read(struct maxim_thermocouple_data *data, 122 struct iio_chan_spec const *chan, int *val) 123 { 124 unsigned int storage_bytes = data->chip->read_size; 125 unsigned int shift = chan->scan_type.shift + (chan->address * 8); 126 __be16 buf16; 127 __be32 buf32; 128 int ret; 129 130 switch (storage_bytes) { 131 case 2: 132 ret = spi_read(data->spi, (void *)&buf16, storage_bytes); 133 *val = be16_to_cpu(buf16); 134 break; 135 case 4: 136 ret = spi_read(data->spi, (void *)&buf32, storage_bytes); 137 *val = be32_to_cpu(buf32); 138 break; 139 default: 140 ret = -EINVAL; 141 } 142 143 if (ret) 144 return ret; 145 146 /* check to be sure this is a valid reading */ 147 if (*val & data->chip->status_bit) 148 return -EINVAL; 149 150 *val = sign_extend32(*val >> shift, chan->scan_type.realbits - 1); 151 152 return 0; 153 } 154 155 static irqreturn_t maxim_thermocouple_trigger_handler(int irq, void *private) 156 { 157 struct iio_poll_func *pf = private; 158 struct iio_dev *indio_dev = pf->indio_dev; 159 struct maxim_thermocouple_data *data = iio_priv(indio_dev); 160 int ret; 161 162 ret = spi_read(data->spi, data->buffer, data->chip->read_size); 163 if (!ret) { 164 iio_push_to_buffers_with_timestamp(indio_dev, data->buffer, 165 iio_get_time_ns(indio_dev)); 166 } 167 168 iio_trigger_notify_done(indio_dev->trig); 169 170 return IRQ_HANDLED; 171 } 172 173 static int maxim_thermocouple_read_raw(struct iio_dev *indio_dev, 174 struct iio_chan_spec const *chan, 175 int *val, int *val2, long mask) 176 { 177 struct maxim_thermocouple_data *data = iio_priv(indio_dev); 178 int ret = -EINVAL; 179 180 switch (mask) { 181 case IIO_CHAN_INFO_RAW: 182 ret = iio_device_claim_direct_mode(indio_dev); 183 if (ret) 184 return ret; 185 186 ret = maxim_thermocouple_read(data, chan, val); 187 iio_device_release_direct_mode(indio_dev); 188 189 if (!ret) 190 return IIO_VAL_INT; 191 192 break; 193 case IIO_CHAN_INFO_SCALE: 194 switch (chan->channel2) { 195 case IIO_MOD_TEMP_AMBIENT: 196 *val = 62; 197 *val2 = 500000; /* 1000 * 0.0625 */ 198 ret = IIO_VAL_INT_PLUS_MICRO; 199 break; 200 default: 201 *val = 250; /* 1000 * 0.25 */ 202 ret = IIO_VAL_INT; 203 }; 204 break; 205 } 206 207 return ret; 208 } 209 210 static const struct iio_info maxim_thermocouple_info = { 211 .driver_module = THIS_MODULE, 212 .read_raw = maxim_thermocouple_read_raw, 213 }; 214 215 static int maxim_thermocouple_probe(struct spi_device *spi) 216 { 217 const struct spi_device_id *id = spi_get_device_id(spi); 218 struct iio_dev *indio_dev; 219 struct maxim_thermocouple_data *data; 220 const struct maxim_thermocouple_chip *chip = 221 &maxim_thermocouple_chips[id->driver_data]; 222 int ret; 223 224 indio_dev = devm_iio_device_alloc(&spi->dev, sizeof(*data)); 225 if (!indio_dev) 226 return -ENOMEM; 227 228 indio_dev->info = &maxim_thermocouple_info; 229 indio_dev->name = MAXIM_THERMOCOUPLE_DRV_NAME; 230 indio_dev->channels = chip->channels; 231 indio_dev->available_scan_masks = chip->scan_masks; 232 indio_dev->num_channels = chip->num_channels; 233 indio_dev->modes = INDIO_DIRECT_MODE; 234 indio_dev->dev.parent = &spi->dev; 235 236 data = iio_priv(indio_dev); 237 data->spi = spi; 238 data->chip = chip; 239 240 ret = iio_triggered_buffer_setup(indio_dev, NULL, 241 maxim_thermocouple_trigger_handler, NULL); 242 if (ret) 243 return ret; 244 245 ret = iio_device_register(indio_dev); 246 if (ret) 247 goto error_unreg_buffer; 248 249 return 0; 250 251 error_unreg_buffer: 252 iio_triggered_buffer_cleanup(indio_dev); 253 254 return ret; 255 } 256 257 static int maxim_thermocouple_remove(struct spi_device *spi) 258 { 259 struct iio_dev *indio_dev = spi_get_drvdata(spi); 260 261 iio_device_unregister(indio_dev); 262 iio_triggered_buffer_cleanup(indio_dev); 263 264 return 0; 265 } 266 267 static const struct spi_device_id maxim_thermocouple_id[] = { 268 {"max6675", MAX6675}, 269 {"max31855", MAX31855}, 270 {"max31856", MAX31855}, 271 {}, 272 }; 273 MODULE_DEVICE_TABLE(spi, maxim_thermocouple_id); 274 275 static struct spi_driver maxim_thermocouple_driver = { 276 .driver = { 277 .name = MAXIM_THERMOCOUPLE_DRV_NAME, 278 }, 279 .probe = maxim_thermocouple_probe, 280 .remove = maxim_thermocouple_remove, 281 .id_table = maxim_thermocouple_id, 282 }; 283 module_spi_driver(maxim_thermocouple_driver); 284 285 MODULE_AUTHOR("Matt Ranostay <mranostay@gmail.com>"); 286 MODULE_DESCRIPTION("Maxim thermocouple sensors"); 287 MODULE_LICENSE("GPL"); 288