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