xref: /linux/drivers/iio/temperature/maxim_thermocouple.c (revision 98838d95075a5295f3478ceba18bcccf472e30f4)
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 	}
140 
141 	if (ret)
142 		return ret;
143 
144 	/* check to be sure this is a valid reading */
145 	if (*val & data->chip->status_bit)
146 		return -EINVAL;
147 
148 	*val = sign_extend32(*val >> shift, chan->scan_type.realbits - 1);
149 
150 	return 0;
151 }
152 
153 static irqreturn_t maxim_thermocouple_trigger_handler(int irq, void *private)
154 {
155 	struct iio_poll_func *pf = private;
156 	struct iio_dev *indio_dev = pf->indio_dev;
157 	struct maxim_thermocouple_data *data = iio_priv(indio_dev);
158 	int ret;
159 
160 	ret = spi_read(data->spi, data->buffer, data->chip->read_size);
161 	if (!ret) {
162 		iio_push_to_buffers_with_timestamp(indio_dev, data->buffer,
163 						   iio_get_time_ns(indio_dev));
164 	}
165 
166 	iio_trigger_notify_done(indio_dev->trig);
167 
168 	return IRQ_HANDLED;
169 }
170 
171 static int maxim_thermocouple_read_raw(struct iio_dev *indio_dev,
172 				       struct iio_chan_spec const *chan,
173 				       int *val, int *val2, long mask)
174 {
175 	struct maxim_thermocouple_data *data = iio_priv(indio_dev);
176 	int ret = -EINVAL;
177 
178 	switch (mask) {
179 	case IIO_CHAN_INFO_RAW:
180 		ret = iio_device_claim_direct_mode(indio_dev);
181 		if (ret)
182 			return ret;
183 
184 		ret = maxim_thermocouple_read(data, chan, val);
185 		iio_device_release_direct_mode(indio_dev);
186 
187 		if (!ret)
188 			return IIO_VAL_INT;
189 
190 		break;
191 	case IIO_CHAN_INFO_SCALE:
192 		switch (chan->channel2) {
193 		case IIO_MOD_TEMP_AMBIENT:
194 			*val = 62;
195 			*val2 = 500000; /* 1000 * 0.0625 */
196 			ret = IIO_VAL_INT_PLUS_MICRO;
197 			break;
198 		default:
199 			*val = 250; /* 1000 * 0.25 */
200 			ret = IIO_VAL_INT;
201 		};
202 		break;
203 	}
204 
205 	return ret;
206 }
207 
208 static const struct iio_info maxim_thermocouple_info = {
209 	.driver_module = THIS_MODULE,
210 	.read_raw = maxim_thermocouple_read_raw,
211 };
212 
213 static int maxim_thermocouple_probe(struct spi_device *spi)
214 {
215 	const struct spi_device_id *id = spi_get_device_id(spi);
216 	struct iio_dev *indio_dev;
217 	struct maxim_thermocouple_data *data;
218 	const struct maxim_thermocouple_chip *chip =
219 			&maxim_thermocouple_chips[id->driver_data];
220 	int ret;
221 
222 	indio_dev = devm_iio_device_alloc(&spi->dev, sizeof(*data));
223 	if (!indio_dev)
224 		return -ENOMEM;
225 
226 	indio_dev->info = &maxim_thermocouple_info;
227 	indio_dev->name = MAXIM_THERMOCOUPLE_DRV_NAME;
228 	indio_dev->channels = chip->channels;
229 	indio_dev->available_scan_masks = chip->scan_masks;
230 	indio_dev->num_channels = chip->num_channels;
231 	indio_dev->modes = INDIO_DIRECT_MODE;
232 
233 	data = iio_priv(indio_dev);
234 	data->spi = spi;
235 	data->chip = chip;
236 
237 	ret = iio_triggered_buffer_setup(indio_dev, NULL,
238 				maxim_thermocouple_trigger_handler, NULL);
239 	if (ret)
240 		return ret;
241 
242 	ret = iio_device_register(indio_dev);
243 	if (ret)
244 		goto error_unreg_buffer;
245 
246 	return 0;
247 
248 error_unreg_buffer:
249 	iio_triggered_buffer_cleanup(indio_dev);
250 
251 	return ret;
252 }
253 
254 static int maxim_thermocouple_remove(struct spi_device *spi)
255 {
256 	struct iio_dev *indio_dev = spi_get_drvdata(spi);
257 
258 	iio_device_unregister(indio_dev);
259 	iio_triggered_buffer_cleanup(indio_dev);
260 
261 	return 0;
262 }
263 
264 static const struct spi_device_id maxim_thermocouple_id[] = {
265 	{"max6675", MAX6675},
266 	{"max31855", MAX31855},
267 	{},
268 };
269 MODULE_DEVICE_TABLE(spi, maxim_thermocouple_id);
270 
271 static struct spi_driver maxim_thermocouple_driver = {
272 	.driver = {
273 		.name	= MAXIM_THERMOCOUPLE_DRV_NAME,
274 	},
275 	.probe		= maxim_thermocouple_probe,
276 	.remove		= maxim_thermocouple_remove,
277 	.id_table	= maxim_thermocouple_id,
278 };
279 module_spi_driver(maxim_thermocouple_driver);
280 
281 MODULE_AUTHOR("Matt Ranostay <mranostay@gmail.com>");
282 MODULE_DESCRIPTION("Maxim thermocouple sensors");
283 MODULE_LICENSE("GPL");
284