1// SPDX-License-Identifier: GPL-2.0-only
2
3/*
4 * Copyright (c) Linumiz 2021
5 *
6 * max31865.c - Maxim MAX31865 RTD-to-Digital Converter sensor driver
7 *
8 * Author: Navin Sankar Velliangiri <navin@linumiz.com>
9 */
10
11#include <linux/ctype.h>
12#include <linux/delay.h>
13#include <linux/err.h>
14#include <linux/init.h>
15#include <linux/mod_devicetable.h>
16#include <linux/module.h>
17#include <linux/iio/iio.h>
18#include <linux/iio/sysfs.h>
19#include <linux/property.h>
20#include <linux/spi/spi.h>
21#include <asm/unaligned.h>
22
23/*
24 * The MSB of the register value determines whether the following byte will
25 * be written or read. If it is 0, read will follow and if it is 1, write
26 * will follow.
27 */
28#define MAX31865_RD_WR_BIT			BIT(7)
29
30#define MAX31865_CFG_VBIAS			BIT(7)
31#define MAX31865_CFG_1SHOT			BIT(5)
32#define MAX31865_3WIRE_RTD			BIT(4)
33#define MAX31865_FAULT_STATUS_CLEAR		BIT(1)
34#define MAX31865_FILTER_50HZ			BIT(0)
35
36/* The MAX31865 registers */
37#define MAX31865_CFG_REG			0x00
38#define MAX31865_RTD_MSB			0x01
39#define MAX31865_FAULT_STATUS			0x07
40
41#define MAX31865_FAULT_OVUV			BIT(2)
42
43static const char max31865_show_samp_freq[] = "50 60";
44
45static const struct iio_chan_spec max31865_channels[] = {
46	{	/* RTD Temperature */
47		.type = IIO_TEMP,
48		.info_mask_separate =
49			BIT(IIO_CHAN_INFO_RAW) | BIT(IIO_CHAN_INFO_SCALE)
50	},
51};
52
53struct max31865_data {
54	struct spi_device *spi;
55	struct mutex lock;
56	bool filter_50hz;
57	bool three_wire;
58	u8 buf[2] __aligned(IIO_DMA_MINALIGN);
59};
60
61static int max31865_read(struct max31865_data *data, u8 reg,
62			 unsigned int read_size)
63{
64	return spi_write_then_read(data->spi, &reg, 1, data->buf, read_size);
65}
66
67static int max31865_write(struct max31865_data *data, size_t len)
68{
69	return spi_write(data->spi, data->buf, len);
70}
71
72static int enable_bias(struct max31865_data *data)
73{
74	u8 cfg;
75	int ret;
76
77	ret = max31865_read(data, MAX31865_CFG_REG, 1);
78	if (ret)
79		return ret;
80
81	cfg = data->buf[0];
82
83	data->buf[0] = MAX31865_CFG_REG | MAX31865_RD_WR_BIT;
84	data->buf[1] = cfg | MAX31865_CFG_VBIAS;
85
86	return max31865_write(data, 2);
87}
88
89static int disable_bias(struct max31865_data *data)
90{
91	u8 cfg;
92	int ret;
93
94	ret = max31865_read(data, MAX31865_CFG_REG, 1);
95	if (ret)
96		return ret;
97
98	cfg = data->buf[0];
99	cfg &= ~MAX31865_CFG_VBIAS;
100
101	data->buf[0] = MAX31865_CFG_REG | MAX31865_RD_WR_BIT;
102	data->buf[1] = cfg;
103
104	return max31865_write(data, 2);
105}
106
107static int max31865_rtd_read(struct max31865_data *data, int *val)
108{
109	u8 reg;
110	int ret;
111
112	/* Enable BIAS to start the conversion */
113	ret = enable_bias(data);
114	if (ret)
115		return ret;
116
117	/* wait 10.5ms before initiating the conversion */
118	msleep(11);
119
120	ret = max31865_read(data, MAX31865_CFG_REG, 1);
121	if (ret)
122		return ret;
123
124	reg = data->buf[0];
125	reg |= MAX31865_CFG_1SHOT | MAX31865_FAULT_STATUS_CLEAR;
126	data->buf[0] = MAX31865_CFG_REG | MAX31865_RD_WR_BIT;
127	data->buf[1] = reg;
128
129	ret = max31865_write(data, 2);
130	if (ret)
131		return ret;
132
133	if (data->filter_50hz) {
134		/* 50Hz filter mode requires 62.5ms to complete */
135		msleep(63);
136	} else {
137		/* 60Hz filter mode requires 52ms to complete */
138		msleep(52);
139	}
140
141	ret = max31865_read(data, MAX31865_RTD_MSB, 2);
142	if (ret)
143		return ret;
144
145	*val = get_unaligned_be16(&data->buf) >> 1;
146
147	return disable_bias(data);
148}
149
150static int max31865_read_raw(struct iio_dev *indio_dev,
151			     struct iio_chan_spec const *chan,
152			     int *val, int *val2, long mask)
153{
154	struct max31865_data *data = iio_priv(indio_dev);
155	int ret;
156
157	switch (mask) {
158	case IIO_CHAN_INFO_RAW:
159		mutex_lock(&data->lock);
160		ret = max31865_rtd_read(data, val);
161		mutex_unlock(&data->lock);
162		if (ret)
163			return ret;
164		return IIO_VAL_INT;
165	case IIO_CHAN_INFO_SCALE:
166		/* Temp. Data resolution is 0.03125 degree centigrade */
167		*val = 31;
168		*val2 = 250000; /* 1000 * 0.03125 */
169		return IIO_VAL_INT_PLUS_MICRO;
170	default:
171		return -EINVAL;
172	}
173}
174
175static int max31865_init(struct max31865_data *data)
176{
177	u8 cfg;
178	int ret;
179
180	ret = max31865_read(data, MAX31865_CFG_REG, 1);
181	if (ret)
182		return ret;
183
184	cfg = data->buf[0];
185
186	if (data->three_wire)
187		/* 3-wire RTD connection */
188		cfg |= MAX31865_3WIRE_RTD;
189
190	if (data->filter_50hz)
191		/* 50Hz noise rejection filter */
192		cfg |= MAX31865_FILTER_50HZ;
193
194	data->buf[0] = MAX31865_CFG_REG | MAX31865_RD_WR_BIT;
195	data->buf[1] = cfg;
196
197	return max31865_write(data, 2);
198}
199
200static ssize_t show_fault(struct device *dev, u8 faultbit, char *buf)
201{
202	int ret;
203	bool fault;
204	struct iio_dev *indio_dev = dev_to_iio_dev(dev);
205	struct max31865_data *data = iio_priv(indio_dev);
206
207	ret = max31865_read(data, MAX31865_FAULT_STATUS, 1);
208	if (ret)
209		return ret;
210
211	fault = data->buf[0] & faultbit;
212
213	return sysfs_emit(buf, "%d\n", fault);
214}
215
216static ssize_t show_fault_ovuv(struct device *dev,
217			      struct device_attribute *attr,
218			      char *buf)
219{
220	return show_fault(dev, MAX31865_FAULT_OVUV, buf);
221}
222
223static ssize_t show_filter(struct device *dev,
224			   struct device_attribute *attr,
225			   char *buf)
226{
227	struct iio_dev *indio_dev = dev_to_iio_dev(dev);
228	struct max31865_data *data = iio_priv(indio_dev);
229
230	return sysfs_emit(buf, "%d\n", data->filter_50hz ? 50 : 60);
231}
232
233static ssize_t set_filter(struct device *dev,
234			  struct device_attribute *attr,
235			  const char *buf,
236			  size_t len)
237{
238	struct iio_dev *indio_dev = dev_to_iio_dev(dev);
239	struct max31865_data *data = iio_priv(indio_dev);
240	unsigned int freq;
241	int ret;
242
243	ret = kstrtouint(buf, 10, &freq);
244	if (ret)
245		return ret;
246
247	switch (freq) {
248	case 50:
249		data->filter_50hz = true;
250		break;
251	case 60:
252		data->filter_50hz = false;
253		break;
254	default:
255		return -EINVAL;
256	}
257
258	mutex_lock(&data->lock);
259	ret = max31865_init(data);
260	mutex_unlock(&data->lock);
261	if (ret)
262		return ret;
263
264	return len;
265}
266
267static IIO_CONST_ATTR_SAMP_FREQ_AVAIL(max31865_show_samp_freq);
268static IIO_DEVICE_ATTR(fault_ovuv, 0444, show_fault_ovuv, NULL, 0);
269static IIO_DEVICE_ATTR(in_filter_notch_center_frequency, 0644,
270		    show_filter, set_filter, 0);
271
272static struct attribute *max31865_attributes[] = {
273	&iio_dev_attr_fault_ovuv.dev_attr.attr,
274	&iio_const_attr_sampling_frequency_available.dev_attr.attr,
275	&iio_dev_attr_in_filter_notch_center_frequency.dev_attr.attr,
276	NULL,
277};
278
279static const struct attribute_group max31865_group = {
280	.attrs = max31865_attributes,
281};
282
283static const struct iio_info max31865_info = {
284	.read_raw = max31865_read_raw,
285	.attrs = &max31865_group,
286};
287
288static int max31865_probe(struct spi_device *spi)
289{
290	const struct spi_device_id *id = spi_get_device_id(spi);
291	struct iio_dev *indio_dev;
292	struct max31865_data *data;
293	int ret;
294
295	indio_dev = devm_iio_device_alloc(&spi->dev, sizeof(*data));
296	if (!indio_dev)
297		return -ENOMEM;
298
299	data = iio_priv(indio_dev);
300	data->spi = spi;
301	data->filter_50hz = false;
302	mutex_init(&data->lock);
303
304	indio_dev->info = &max31865_info;
305	indio_dev->name = id->name;
306	indio_dev->modes = INDIO_DIRECT_MODE;
307	indio_dev->channels = max31865_channels;
308	indio_dev->num_channels = ARRAY_SIZE(max31865_channels);
309
310	if (device_property_read_bool(&spi->dev, "maxim,3-wire")) {
311		/* select 3 wire */
312		data->three_wire = 1;
313	} else {
314		/* select 2 or 4 wire */
315		data->three_wire = 0;
316	}
317
318	ret = max31865_init(data);
319	if (ret) {
320		dev_err(&spi->dev, "error: Failed to configure max31865\n");
321		return ret;
322	}
323
324	return devm_iio_device_register(&spi->dev, indio_dev);
325}
326
327static const struct spi_device_id max31865_id[] = {
328	{ "max31865", 0 },
329	{ }
330};
331MODULE_DEVICE_TABLE(spi, max31865_id);
332
333static const struct of_device_id max31865_of_match[] = {
334	{ .compatible = "maxim,max31865" },
335	{ }
336};
337MODULE_DEVICE_TABLE(of, max31865_of_match);
338
339static struct spi_driver max31865_driver = {
340	.driver = {
341		.name	= "max31865",
342		.of_match_table = max31865_of_match,
343	},
344	.probe = max31865_probe,
345	.id_table = max31865_id,
346};
347module_spi_driver(max31865_driver);
348
349MODULE_AUTHOR("Navin Sankar Velliangiri <navin@linumiz.com>");
350MODULE_DESCRIPTION("Maxim MAX31865 RTD-to-Digital Converter sensor driver");
351MODULE_LICENSE("GPL v2");
352