xref: /linux/drivers/staging/iio/adc/ad7816.c (revision 2da68a77)
1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3  * AD7816 digital temperature sensor driver supporting AD7816/7/8
4  *
5  * Copyright 2010 Analog Devices Inc.
6  */
7 
8 #include <linux/interrupt.h>
9 #include <linux/gpio/consumer.h>
10 #include <linux/device.h>
11 #include <linux/kernel.h>
12 #include <linux/slab.h>
13 #include <linux/sysfs.h>
14 #include <linux/list.h>
15 #include <linux/spi/spi.h>
16 #include <linux/module.h>
17 
18 #include <linux/iio/iio.h>
19 #include <linux/iio/sysfs.h>
20 #include <linux/iio/events.h>
21 
22 /*
23  * AD7816 config masks
24  */
25 #define AD7816_FULL			0x1
26 #define AD7816_PD			0x2
27 #define AD7816_CS_MASK			0x7
28 #define AD7816_CS_MAX			0x4
29 
30 /*
31  * AD7816 temperature masks
32  */
33 #define AD7816_VALUE_OFFSET		6
34 #define AD7816_BOUND_VALUE_BASE		0x8
35 #define AD7816_BOUND_VALUE_MIN		-95
36 #define AD7816_BOUND_VALUE_MAX		152
37 #define AD7816_TEMP_FLOAT_OFFSET	2
38 #define AD7816_TEMP_FLOAT_MASK		0x3
39 
40 /*
41  * struct ad7816_chip_info - chip specific information
42  */
43 
44 struct ad7816_chip_info {
45 	kernel_ulong_t id;
46 	struct spi_device *spi_dev;
47 	struct gpio_desc *rdwr_pin;
48 	struct gpio_desc *convert_pin;
49 	struct gpio_desc *busy_pin;
50 	u8  oti_data[AD7816_CS_MAX + 1];
51 	u8  channel_id;	/* 0 always be temperature */
52 	u8  mode;
53 };
54 
55 enum ad7816_type {
56 	ID_AD7816,
57 	ID_AD7817,
58 	ID_AD7818,
59 };
60 
61 /*
62  * ad7816 data access by SPI
63  */
64 static int ad7816_spi_read(struct ad7816_chip_info *chip, u16 *data)
65 {
66 	struct spi_device *spi_dev = chip->spi_dev;
67 	int ret;
68 	__be16 buf;
69 
70 	gpiod_set_value(chip->rdwr_pin, 1);
71 	gpiod_set_value(chip->rdwr_pin, 0);
72 	ret = spi_write(spi_dev, &chip->channel_id, sizeof(chip->channel_id));
73 	if (ret < 0) {
74 		dev_err(&spi_dev->dev, "SPI channel setting error\n");
75 		return ret;
76 	}
77 	gpiod_set_value(chip->rdwr_pin, 1);
78 
79 	if (chip->mode == AD7816_PD) { /* operating mode 2 */
80 		gpiod_set_value(chip->convert_pin, 1);
81 		gpiod_set_value(chip->convert_pin, 0);
82 	} else { /* operating mode 1 */
83 		gpiod_set_value(chip->convert_pin, 0);
84 		gpiod_set_value(chip->convert_pin, 1);
85 	}
86 
87 	if (chip->id == ID_AD7816 || chip->id == ID_AD7817) {
88 		while (gpiod_get_value(chip->busy_pin))
89 			cpu_relax();
90 	}
91 
92 	gpiod_set_value(chip->rdwr_pin, 0);
93 	gpiod_set_value(chip->rdwr_pin, 1);
94 	ret = spi_read(spi_dev, &buf, sizeof(*data));
95 	if (ret < 0) {
96 		dev_err(&spi_dev->dev, "SPI data read error\n");
97 		return ret;
98 	}
99 
100 	*data = be16_to_cpu(buf);
101 
102 	return ret;
103 }
104 
105 static int ad7816_spi_write(struct ad7816_chip_info *chip, u8 data)
106 {
107 	struct spi_device *spi_dev = chip->spi_dev;
108 	int ret;
109 
110 	gpiod_set_value(chip->rdwr_pin, 1);
111 	gpiod_set_value(chip->rdwr_pin, 0);
112 	ret = spi_write(spi_dev, &data, sizeof(data));
113 	if (ret < 0)
114 		dev_err(&spi_dev->dev, "SPI oti data write error\n");
115 
116 	return ret;
117 }
118 
119 static ssize_t ad7816_show_mode(struct device *dev,
120 				struct device_attribute *attr,
121 				char *buf)
122 {
123 	struct iio_dev *indio_dev = dev_to_iio_dev(dev);
124 	struct ad7816_chip_info *chip = iio_priv(indio_dev);
125 
126 	if (chip->mode)
127 		return sprintf(buf, "power-save\n");
128 	return sprintf(buf, "full\n");
129 }
130 
131 static ssize_t ad7816_store_mode(struct device *dev,
132 				 struct device_attribute *attr,
133 				 const char *buf,
134 				 size_t len)
135 {
136 	struct iio_dev *indio_dev = dev_to_iio_dev(dev);
137 	struct ad7816_chip_info *chip = iio_priv(indio_dev);
138 
139 	if (strcmp(buf, "full")) {
140 		gpiod_set_value(chip->rdwr_pin, 1);
141 		chip->mode = AD7816_FULL;
142 	} else {
143 		gpiod_set_value(chip->rdwr_pin, 0);
144 		chip->mode = AD7816_PD;
145 	}
146 
147 	return len;
148 }
149 
150 static IIO_DEVICE_ATTR(mode, 0644,
151 		ad7816_show_mode,
152 		ad7816_store_mode,
153 		0);
154 
155 static ssize_t ad7816_show_available_modes(struct device *dev,
156 					   struct device_attribute *attr,
157 					   char *buf)
158 {
159 	return sprintf(buf, "full\npower-save\n");
160 }
161 
162 static IIO_DEVICE_ATTR(available_modes, 0444, ad7816_show_available_modes,
163 			NULL, 0);
164 
165 static ssize_t ad7816_show_channel(struct device *dev,
166 				   struct device_attribute *attr,
167 				   char *buf)
168 {
169 	struct iio_dev *indio_dev = dev_to_iio_dev(dev);
170 	struct ad7816_chip_info *chip = iio_priv(indio_dev);
171 
172 	return sprintf(buf, "%d\n", chip->channel_id);
173 }
174 
175 static ssize_t ad7816_store_channel(struct device *dev,
176 				    struct device_attribute *attr,
177 				    const char *buf,
178 				    size_t len)
179 {
180 	struct iio_dev *indio_dev = dev_to_iio_dev(dev);
181 	struct ad7816_chip_info *chip = iio_priv(indio_dev);
182 	unsigned long data;
183 	int ret;
184 
185 	ret = kstrtoul(buf, 10, &data);
186 	if (ret)
187 		return ret;
188 
189 	if (data > AD7816_CS_MAX && data != AD7816_CS_MASK) {
190 		dev_err(&chip->spi_dev->dev, "Invalid channel id %lu for %s.\n",
191 			data, indio_dev->name);
192 		return -EINVAL;
193 	} else if (strcmp(indio_dev->name, "ad7818") == 0 && data > 1) {
194 		dev_err(&chip->spi_dev->dev,
195 			"Invalid channel id %lu for ad7818.\n", data);
196 		return -EINVAL;
197 	} else if (strcmp(indio_dev->name, "ad7816") == 0 && data > 0) {
198 		dev_err(&chip->spi_dev->dev,
199 			"Invalid channel id %lu for ad7816.\n", data);
200 		return -EINVAL;
201 	}
202 
203 	chip->channel_id = data;
204 
205 	return len;
206 }
207 
208 static IIO_DEVICE_ATTR(channel, 0644,
209 		ad7816_show_channel,
210 		ad7816_store_channel,
211 		0);
212 
213 static ssize_t ad7816_show_value(struct device *dev,
214 				 struct device_attribute *attr,
215 				 char *buf)
216 {
217 	struct iio_dev *indio_dev = dev_to_iio_dev(dev);
218 	struct ad7816_chip_info *chip = iio_priv(indio_dev);
219 	u16 data;
220 	s8 value;
221 	int ret;
222 
223 	ret = ad7816_spi_read(chip, &data);
224 	if (ret)
225 		return -EIO;
226 
227 	data >>= AD7816_VALUE_OFFSET;
228 
229 	if (chip->channel_id == 0) {
230 		value = (s8)((data >> AD7816_TEMP_FLOAT_OFFSET) - 103);
231 		data &= AD7816_TEMP_FLOAT_MASK;
232 		if (value < 0)
233 			data = BIT(AD7816_TEMP_FLOAT_OFFSET) - data;
234 		return sprintf(buf, "%d.%.2d\n", value, data * 25);
235 	}
236 	return sprintf(buf, "%u\n", data);
237 }
238 
239 static IIO_DEVICE_ATTR(value, 0444, ad7816_show_value, NULL, 0);
240 
241 static struct attribute *ad7816_attributes[] = {
242 	&iio_dev_attr_available_modes.dev_attr.attr,
243 	&iio_dev_attr_mode.dev_attr.attr,
244 	&iio_dev_attr_channel.dev_attr.attr,
245 	&iio_dev_attr_value.dev_attr.attr,
246 	NULL,
247 };
248 
249 static const struct attribute_group ad7816_attribute_group = {
250 	.attrs = ad7816_attributes,
251 };
252 
253 /*
254  * temperature bound events
255  */
256 
257 #define IIO_EVENT_CODE_AD7816_OTI IIO_UNMOD_EVENT_CODE(IIO_TEMP,	\
258 						       0,		\
259 						       IIO_EV_TYPE_THRESH, \
260 						       IIO_EV_DIR_FALLING)
261 
262 static irqreturn_t ad7816_event_handler(int irq, void *private)
263 {
264 	iio_push_event(private, IIO_EVENT_CODE_AD7816_OTI,
265 		       iio_get_time_ns(private));
266 	return IRQ_HANDLED;
267 }
268 
269 static ssize_t ad7816_show_oti(struct device *dev,
270 			       struct device_attribute *attr,
271 			       char *buf)
272 {
273 	struct iio_dev *indio_dev = dev_to_iio_dev(dev);
274 	struct ad7816_chip_info *chip = iio_priv(indio_dev);
275 	int value;
276 
277 	if (chip->channel_id > AD7816_CS_MAX) {
278 		dev_err(dev, "Invalid oti channel id %d.\n", chip->channel_id);
279 		return -EINVAL;
280 	} else if (chip->channel_id == 0) {
281 		value = AD7816_BOUND_VALUE_MIN +
282 			(chip->oti_data[chip->channel_id] -
283 			AD7816_BOUND_VALUE_BASE);
284 		return sprintf(buf, "%d\n", value);
285 	}
286 	return sprintf(buf, "%u\n", chip->oti_data[chip->channel_id]);
287 }
288 
289 static inline ssize_t ad7816_set_oti(struct device *dev,
290 				     struct device_attribute *attr,
291 				     const char *buf,
292 				     size_t len)
293 {
294 	struct iio_dev *indio_dev = dev_to_iio_dev(dev);
295 	struct ad7816_chip_info *chip = iio_priv(indio_dev);
296 	long value;
297 	u8 data;
298 	int ret;
299 
300 	ret = kstrtol(buf, 10, &value);
301 	if (ret)
302 		return ret;
303 
304 	if (chip->channel_id > AD7816_CS_MAX) {
305 		dev_err(dev, "Invalid oti channel id %d.\n", chip->channel_id);
306 		return -EINVAL;
307 	} else if (chip->channel_id == 0) {
308 		if (value < AD7816_BOUND_VALUE_MIN ||
309 		    value > AD7816_BOUND_VALUE_MAX)
310 			return -EINVAL;
311 
312 		data = (u8)(value - AD7816_BOUND_VALUE_MIN +
313 			AD7816_BOUND_VALUE_BASE);
314 	} else {
315 		if (value < AD7816_BOUND_VALUE_BASE || value > 255)
316 			return -EINVAL;
317 
318 		data = (u8)value;
319 	}
320 
321 	ret = ad7816_spi_write(chip, data);
322 	if (ret)
323 		return -EIO;
324 
325 	chip->oti_data[chip->channel_id] = data;
326 
327 	return len;
328 }
329 
330 static IIO_DEVICE_ATTR(oti, 0644,
331 		       ad7816_show_oti, ad7816_set_oti, 0);
332 
333 static struct attribute *ad7816_event_attributes[] = {
334 	&iio_dev_attr_oti.dev_attr.attr,
335 	NULL,
336 };
337 
338 static const struct attribute_group ad7816_event_attribute_group = {
339 	.attrs = ad7816_event_attributes,
340 	.name = "events",
341 };
342 
343 static const struct iio_info ad7816_info = {
344 	.attrs = &ad7816_attribute_group,
345 	.event_attrs = &ad7816_event_attribute_group,
346 };
347 
348 /*
349  * device probe and remove
350  */
351 
352 static int ad7816_probe(struct spi_device *spi_dev)
353 {
354 	struct ad7816_chip_info *chip;
355 	struct iio_dev *indio_dev;
356 	int i, ret;
357 
358 	indio_dev = devm_iio_device_alloc(&spi_dev->dev, sizeof(*chip));
359 	if (!indio_dev)
360 		return -ENOMEM;
361 	chip = iio_priv(indio_dev);
362 	/* this is only used for device removal purposes */
363 	dev_set_drvdata(&spi_dev->dev, indio_dev);
364 
365 	chip->spi_dev = spi_dev;
366 	for (i = 0; i <= AD7816_CS_MAX; i++)
367 		chip->oti_data[i] = 203;
368 
369 	chip->id = spi_get_device_id(spi_dev)->driver_data;
370 	chip->rdwr_pin = devm_gpiod_get(&spi_dev->dev, "rdwr", GPIOD_OUT_HIGH);
371 	if (IS_ERR(chip->rdwr_pin)) {
372 		ret = PTR_ERR(chip->rdwr_pin);
373 		dev_err(&spi_dev->dev, "Failed to request rdwr GPIO: %d\n",
374 			ret);
375 		return ret;
376 	}
377 	chip->convert_pin = devm_gpiod_get(&spi_dev->dev, "convert",
378 					   GPIOD_OUT_HIGH);
379 	if (IS_ERR(chip->convert_pin)) {
380 		ret = PTR_ERR(chip->convert_pin);
381 		dev_err(&spi_dev->dev, "Failed to request convert GPIO: %d\n",
382 			ret);
383 		return ret;
384 	}
385 	if (chip->id == ID_AD7816 || chip->id == ID_AD7817) {
386 		chip->busy_pin = devm_gpiod_get(&spi_dev->dev, "busy",
387 						GPIOD_IN);
388 		if (IS_ERR(chip->busy_pin)) {
389 			ret = PTR_ERR(chip->busy_pin);
390 			dev_err(&spi_dev->dev, "Failed to request busy GPIO: %d\n",
391 				ret);
392 			return ret;
393 		}
394 	}
395 
396 	indio_dev->name = spi_get_device_id(spi_dev)->name;
397 	indio_dev->info = &ad7816_info;
398 	indio_dev->modes = INDIO_DIRECT_MODE;
399 
400 	if (spi_dev->irq) {
401 		/* Only low trigger is supported in ad7816/7/8 */
402 		ret = devm_request_threaded_irq(&spi_dev->dev, spi_dev->irq,
403 						NULL,
404 						&ad7816_event_handler,
405 						IRQF_TRIGGER_LOW | IRQF_ONESHOT,
406 						indio_dev->name,
407 						indio_dev);
408 		if (ret)
409 			return ret;
410 	}
411 
412 	ret = devm_iio_device_register(&spi_dev->dev, indio_dev);
413 	if (ret)
414 		return ret;
415 
416 	dev_info(&spi_dev->dev, "%s temperature sensor and ADC registered.\n",
417 		 indio_dev->name);
418 
419 	return 0;
420 }
421 
422 static const struct of_device_id ad7816_of_match[] = {
423 	{ .compatible = "adi,ad7816", },
424 	{ .compatible = "adi,ad7817", },
425 	{ .compatible = "adi,ad7818", },
426 	{ }
427 };
428 MODULE_DEVICE_TABLE(of, ad7816_of_match);
429 
430 static const struct spi_device_id ad7816_id[] = {
431 	{ "ad7816", ID_AD7816 },
432 	{ "ad7817", ID_AD7817 },
433 	{ "ad7818", ID_AD7818 },
434 	{}
435 };
436 
437 MODULE_DEVICE_TABLE(spi, ad7816_id);
438 
439 static struct spi_driver ad7816_driver = {
440 	.driver = {
441 		.name = "ad7816",
442 		.of_match_table = ad7816_of_match,
443 	},
444 	.probe = ad7816_probe,
445 	.id_table = ad7816_id,
446 };
447 module_spi_driver(ad7816_driver);
448 
449 MODULE_AUTHOR("Sonic Zhang <sonic.zhang@analog.com>");
450 MODULE_DESCRIPTION("Analog Devices AD7816/7/8 digital temperature sensor driver");
451 MODULE_LICENSE("GPL v2");
452