xref: /linux/drivers/iio/temperature/maxim_thermocouple.c (revision fada1935590f66dc6784981e0d557ca09013c847)
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 	.read_raw = maxim_thermocouple_read_raw,
212 };
213 
214 static int maxim_thermocouple_probe(struct spi_device *spi)
215 {
216 	const struct spi_device_id *id = spi_get_device_id(spi);
217 	struct iio_dev *indio_dev;
218 	struct maxim_thermocouple_data *data;
219 	const struct maxim_thermocouple_chip *chip =
220 			&maxim_thermocouple_chips[id->driver_data];
221 	int ret;
222 
223 	indio_dev = devm_iio_device_alloc(&spi->dev, sizeof(*data));
224 	if (!indio_dev)
225 		return -ENOMEM;
226 
227 	indio_dev->info = &maxim_thermocouple_info;
228 	indio_dev->name = MAXIM_THERMOCOUPLE_DRV_NAME;
229 	indio_dev->channels = chip->channels;
230 	indio_dev->available_scan_masks = chip->scan_masks;
231 	indio_dev->num_channels = chip->num_channels;
232 	indio_dev->modes = INDIO_DIRECT_MODE;
233 	indio_dev->dev.parent = &spi->dev;
234 
235 	data = iio_priv(indio_dev);
236 	data->spi = spi;
237 	data->chip = chip;
238 
239 	ret = iio_triggered_buffer_setup(indio_dev, NULL,
240 				maxim_thermocouple_trigger_handler, NULL);
241 	if (ret)
242 		return ret;
243 
244 	ret = iio_device_register(indio_dev);
245 	if (ret)
246 		goto error_unreg_buffer;
247 
248 	return 0;
249 
250 error_unreg_buffer:
251 	iio_triggered_buffer_cleanup(indio_dev);
252 
253 	return ret;
254 }
255 
256 static int maxim_thermocouple_remove(struct spi_device *spi)
257 {
258 	struct iio_dev *indio_dev = spi_get_drvdata(spi);
259 
260 	iio_device_unregister(indio_dev);
261 	iio_triggered_buffer_cleanup(indio_dev);
262 
263 	return 0;
264 }
265 
266 static const struct spi_device_id maxim_thermocouple_id[] = {
267 	{"max6675", MAX6675},
268 	{"max31855", MAX31855},
269 	{"max31856", MAX31855},
270 	{},
271 };
272 MODULE_DEVICE_TABLE(spi, maxim_thermocouple_id);
273 
274 static struct spi_driver maxim_thermocouple_driver = {
275 	.driver = {
276 		.name	= MAXIM_THERMOCOUPLE_DRV_NAME,
277 	},
278 	.probe		= maxim_thermocouple_probe,
279 	.remove		= maxim_thermocouple_remove,
280 	.id_table	= maxim_thermocouple_id,
281 };
282 module_spi_driver(maxim_thermocouple_driver);
283 
284 MODULE_AUTHOR("Matt Ranostay <mranostay@gmail.com>");
285 MODULE_DESCRIPTION("Maxim thermocouple sensors");
286 MODULE_LICENSE("GPL");
287