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