xref: /linux/drivers/iio/proximity/srf08.c (revision 6093a688a07da07808f0122f9aa2a3eed250d853)
1 // SPDX-License-Identifier: GPL-2.0-only
2 /*
3  * srf08.c - Support for Devantech SRFxx ultrasonic ranger
4  *           with i2c interface
5  * actually supported are srf02, srf08, srf10
6  *
7  * Copyright (c) 2016, 2017 Andreas Klinger <ak@it-klinger.de>
8  *
9  * For details about the device see:
10  * https://www.robot-electronics.co.uk/htm/srf08tech.html
11  * https://www.robot-electronics.co.uk/htm/srf10tech.htm
12  * https://www.robot-electronics.co.uk/htm/srf02tech.htm
13  */
14 
15 #include <linux/err.h>
16 #include <linux/i2c.h>
17 #include <linux/delay.h>
18 #include <linux/module.h>
19 #include <linux/bitops.h>
20 #include <linux/iio/iio.h>
21 #include <linux/iio/sysfs.h>
22 #include <linux/iio/buffer.h>
23 #include <linux/iio/trigger_consumer.h>
24 #include <linux/iio/triggered_buffer.h>
25 
26 /* registers of SRF08 device */
27 #define SRF08_WRITE_COMMAND	0x00	/* Command Register */
28 #define SRF08_WRITE_MAX_GAIN	0x01	/* Max Gain Register: 0 .. 31 */
29 #define SRF08_WRITE_RANGE	0x02	/* Range Register: 0 .. 255 */
30 #define SRF08_READ_SW_REVISION	0x00	/* Software Revision */
31 #define SRF08_READ_LIGHT	0x01	/* Light Sensor during last echo */
32 #define SRF08_READ_ECHO_1_HIGH	0x02	/* Range of first echo received */
33 #define SRF08_READ_ECHO_1_LOW	0x03	/* Range of first echo received */
34 
35 #define SRF08_CMD_RANGING_CM	0x51	/* Ranging Mode - Result in cm */
36 
37 enum srf08_sensor_type {
38 	SRF02,
39 	SRF08,
40 	SRF10,
41 	SRF_MAX_TYPE
42 };
43 
44 struct srf08_chip_info {
45 	const int		*sensitivity_avail;
46 	int			num_sensitivity_avail;
47 	int			sensitivity_default;
48 
49 	/* default value of Range in mm */
50 	int			range_default;
51 };
52 
53 struct srf08_data {
54 	struct i2c_client	*client;
55 
56 	/*
57 	 * Gain in the datasheet is called sensitivity here to distinct it
58 	 * from the gain used with amplifiers of adc's
59 	 */
60 	int			sensitivity;
61 
62 	/* max. Range in mm */
63 	int			range_mm;
64 	struct mutex		lock;
65 
66 	/* Sensor-Type */
67 	enum srf08_sensor_type	sensor_type;
68 
69 	/* Chip-specific information */
70 	const struct srf08_chip_info	*chip_info;
71 };
72 
73 /*
74  * in the documentation one can read about the "Gain" of the device
75  * which is used here for amplifying the signal and filtering out unwanted
76  * ones.
77  * But with ADC's this term is already used differently and that's why it
78  * is called "Sensitivity" here.
79  */
80 static const struct srf08_chip_info srf02_chip_info = {
81 	.sensitivity_avail	= NULL,
82 	.num_sensitivity_avail	= 0,
83 	.sensitivity_default	= 0,
84 
85 	.range_default		= 0,
86 };
87 
88 static const int srf08_sensitivity_avail[] = {
89 	 94,  97, 100, 103, 107, 110, 114, 118,
90 	123, 128, 133, 139, 145, 152, 159, 168,
91 	177, 187, 199, 212, 227, 245, 265, 288,
92 	317, 352, 395, 450, 524, 626, 777, 1025
93 	};
94 
95 static const struct srf08_chip_info srf08_chip_info = {
96 	.sensitivity_avail	= srf08_sensitivity_avail,
97 	.num_sensitivity_avail	= ARRAY_SIZE(srf08_sensitivity_avail),
98 	.sensitivity_default	= 1025,
99 
100 	.range_default		= 6020,
101 };
102 
103 static const int srf10_sensitivity_avail[] = {
104 	 40,  40,  50,  60,  70,  80, 100, 120,
105 	140, 200, 250, 300, 350, 400, 500, 600,
106 	700,
107 	};
108 
109 static const struct srf08_chip_info srf10_chip_info = {
110 	.sensitivity_avail	= srf10_sensitivity_avail,
111 	.num_sensitivity_avail	= ARRAY_SIZE(srf10_sensitivity_avail),
112 	.sensitivity_default	= 700,
113 
114 	.range_default		= 6020,
115 };
116 
117 static int srf08_read_ranging(struct srf08_data *data)
118 {
119 	struct i2c_client *client = data->client;
120 	int ret, i;
121 	int waittime;
122 
123 	mutex_lock(&data->lock);
124 
125 	ret = i2c_smbus_write_byte_data(data->client,
126 			SRF08_WRITE_COMMAND, SRF08_CMD_RANGING_CM);
127 	if (ret < 0) {
128 		dev_err(&client->dev, "write command - err: %d\n", ret);
129 		mutex_unlock(&data->lock);
130 		return ret;
131 	}
132 
133 	/*
134 	 * we read here until a correct version number shows up as
135 	 * suggested by the documentation
136 	 *
137 	 * with an ultrasonic speed of 343 m/s and a roundtrip of it
138 	 * sleep the expected duration and try to read from the device
139 	 * if nothing useful is read try it in a shorter grid
140 	 *
141 	 * polling for not more than 20 ms should be enough
142 	 */
143 	waittime = 1 + data->range_mm / 172;
144 	msleep(waittime);
145 	for (i = 0; i < 4; i++) {
146 		ret = i2c_smbus_read_byte_data(data->client,
147 						SRF08_READ_SW_REVISION);
148 
149 		/* check if a valid version number is read */
150 		if (ret < 255 && ret > 0)
151 			break;
152 		msleep(5);
153 	}
154 
155 	if (ret >= 255 || ret <= 0) {
156 		dev_err(&client->dev, "device not ready\n");
157 		mutex_unlock(&data->lock);
158 		return -EIO;
159 	}
160 
161 	ret = i2c_smbus_read_word_swapped(data->client,
162 						SRF08_READ_ECHO_1_HIGH);
163 	if (ret < 0) {
164 		dev_err(&client->dev, "cannot read distance: ret=%d\n", ret);
165 		mutex_unlock(&data->lock);
166 		return ret;
167 	}
168 
169 	mutex_unlock(&data->lock);
170 
171 	return ret;
172 }
173 
174 static irqreturn_t srf08_trigger_handler(int irq, void *p)
175 {
176 	struct iio_poll_func *pf = p;
177 	struct iio_dev *indio_dev = pf->indio_dev;
178 	struct srf08_data *data = iio_priv(indio_dev);
179 	struct {
180 		s16 chan;
181 		aligned_s64 timestamp;
182 	} scan = { };
183 
184 	scan.chan = srf08_read_ranging(data);
185 	if (scan.chan < 0)
186 		goto err;
187 
188 	mutex_lock(&data->lock);
189 
190 	iio_push_to_buffers_with_ts(indio_dev, &scan, sizeof(scan),
191 				    pf->timestamp);
192 
193 	mutex_unlock(&data->lock);
194 err:
195 	iio_trigger_notify_done(indio_dev->trig);
196 	return IRQ_HANDLED;
197 }
198 
199 static int srf08_read_raw(struct iio_dev *indio_dev,
200 			    struct iio_chan_spec const *channel, int *val,
201 			    int *val2, long mask)
202 {
203 	struct srf08_data *data = iio_priv(indio_dev);
204 	int ret;
205 
206 	if (channel->type != IIO_DISTANCE)
207 		return -EINVAL;
208 
209 	switch (mask) {
210 	case IIO_CHAN_INFO_RAW:
211 		ret = srf08_read_ranging(data);
212 		if (ret < 0)
213 			return ret;
214 		*val = ret;
215 		return IIO_VAL_INT;
216 	case IIO_CHAN_INFO_SCALE:
217 		/* 1 LSB is 1 cm */
218 		*val = 0;
219 		*val2 = 10000;
220 		return IIO_VAL_INT_PLUS_MICRO;
221 	default:
222 		return -EINVAL;
223 	}
224 }
225 
226 static ssize_t srf08_show_range_mm_available(struct device *dev,
227 				struct device_attribute *attr, char *buf)
228 {
229 	return sprintf(buf, "[0.043 0.043 11.008]\n");
230 }
231 
232 static IIO_DEVICE_ATTR(sensor_max_range_available, S_IRUGO,
233 				srf08_show_range_mm_available, NULL, 0);
234 
235 static ssize_t srf08_show_range_mm(struct device *dev,
236 				struct device_attribute *attr, char *buf)
237 {
238 	struct iio_dev *indio_dev = dev_to_iio_dev(dev);
239 	struct srf08_data *data = iio_priv(indio_dev);
240 
241 	return sprintf(buf, "%d.%03d\n", data->range_mm / 1000,
242 						data->range_mm % 1000);
243 }
244 
245 /*
246  * set the range of the sensor to an even multiple of 43 mm
247  * which corresponds to 1 LSB in the register
248  *
249  * register value    corresponding range
250  *         0x00             43 mm
251  *         0x01             86 mm
252  *         0x02            129 mm
253  *         ...
254  *         0xFF          11008 mm
255  */
256 static ssize_t srf08_write_range_mm(struct srf08_data *data, unsigned int val)
257 {
258 	int ret;
259 	struct i2c_client *client = data->client;
260 	unsigned int mod;
261 	u8 regval;
262 
263 	ret = val / 43 - 1;
264 	mod = val % 43;
265 
266 	if (mod || (ret < 0) || (ret > 255))
267 		return -EINVAL;
268 
269 	regval = ret;
270 
271 	mutex_lock(&data->lock);
272 
273 	ret = i2c_smbus_write_byte_data(client, SRF08_WRITE_RANGE, regval);
274 	if (ret < 0) {
275 		dev_err(&client->dev, "write_range - err: %d\n", ret);
276 		mutex_unlock(&data->lock);
277 		return ret;
278 	}
279 
280 	data->range_mm = val;
281 
282 	mutex_unlock(&data->lock);
283 
284 	return 0;
285 }
286 
287 static ssize_t srf08_store_range_mm(struct device *dev,
288 					struct device_attribute *attr,
289 					const char *buf, size_t len)
290 {
291 	struct iio_dev *indio_dev = dev_to_iio_dev(dev);
292 	struct srf08_data *data = iio_priv(indio_dev);
293 	int ret;
294 	int integer, fract;
295 
296 	ret = iio_str_to_fixpoint(buf, 100, &integer, &fract);
297 	if (ret)
298 		return ret;
299 
300 	ret = srf08_write_range_mm(data, integer * 1000 + fract);
301 	if (ret < 0)
302 		return ret;
303 
304 	return len;
305 }
306 
307 static IIO_DEVICE_ATTR(sensor_max_range, S_IRUGO | S_IWUSR,
308 			srf08_show_range_mm, srf08_store_range_mm, 0);
309 
310 static ssize_t srf08_show_sensitivity_available(struct device *dev,
311 				struct device_attribute *attr, char *buf)
312 {
313 	int i, len = 0;
314 	struct iio_dev *indio_dev = dev_to_iio_dev(dev);
315 	struct srf08_data *data = iio_priv(indio_dev);
316 
317 	for (i = 0; i < data->chip_info->num_sensitivity_avail; i++)
318 		if (data->chip_info->sensitivity_avail[i])
319 			len += sprintf(buf + len, "%d ",
320 				data->chip_info->sensitivity_avail[i]);
321 
322 	len += sprintf(buf + len, "\n");
323 
324 	return len;
325 }
326 
327 static IIO_DEVICE_ATTR(sensor_sensitivity_available, S_IRUGO,
328 				srf08_show_sensitivity_available, NULL, 0);
329 
330 static ssize_t srf08_show_sensitivity(struct device *dev,
331 				struct device_attribute *attr, char *buf)
332 {
333 	struct iio_dev *indio_dev = dev_to_iio_dev(dev);
334 	struct srf08_data *data = iio_priv(indio_dev);
335 	int len;
336 
337 	len = sprintf(buf, "%d\n", data->sensitivity);
338 
339 	return len;
340 }
341 
342 static ssize_t srf08_write_sensitivity(struct srf08_data *data,
343 							unsigned int val)
344 {
345 	struct i2c_client *client = data->client;
346 	int ret, i;
347 	u8 regval;
348 
349 	if (!val)
350 		return -EINVAL;
351 
352 	for (i = 0; i < data->chip_info->num_sensitivity_avail; i++)
353 		if (val == data->chip_info->sensitivity_avail[i]) {
354 			regval = i;
355 			break;
356 		}
357 
358 	if (i >= data->chip_info->num_sensitivity_avail)
359 		return -EINVAL;
360 
361 	mutex_lock(&data->lock);
362 
363 	ret = i2c_smbus_write_byte_data(client, SRF08_WRITE_MAX_GAIN, regval);
364 	if (ret < 0) {
365 		dev_err(&client->dev, "write_sensitivity - err: %d\n", ret);
366 		mutex_unlock(&data->lock);
367 		return ret;
368 	}
369 
370 	data->sensitivity = val;
371 
372 	mutex_unlock(&data->lock);
373 
374 	return 0;
375 }
376 
377 static ssize_t srf08_store_sensitivity(struct device *dev,
378 						struct device_attribute *attr,
379 						const char *buf, size_t len)
380 {
381 	struct iio_dev *indio_dev = dev_to_iio_dev(dev);
382 	struct srf08_data *data = iio_priv(indio_dev);
383 	int ret;
384 	unsigned int val;
385 
386 	ret = kstrtouint(buf, 10, &val);
387 	if (ret)
388 		return ret;
389 
390 	ret = srf08_write_sensitivity(data, val);
391 	if (ret < 0)
392 		return ret;
393 
394 	return len;
395 }
396 
397 static IIO_DEVICE_ATTR(sensor_sensitivity, S_IRUGO | S_IWUSR,
398 			srf08_show_sensitivity, srf08_store_sensitivity, 0);
399 
400 static struct attribute *srf08_attributes[] = {
401 	&iio_dev_attr_sensor_max_range.dev_attr.attr,
402 	&iio_dev_attr_sensor_max_range_available.dev_attr.attr,
403 	&iio_dev_attr_sensor_sensitivity.dev_attr.attr,
404 	&iio_dev_attr_sensor_sensitivity_available.dev_attr.attr,
405 	NULL,
406 };
407 
408 static const struct attribute_group srf08_attribute_group = {
409 	.attrs = srf08_attributes,
410 };
411 
412 static const struct iio_chan_spec srf08_channels[] = {
413 	{
414 		.type = IIO_DISTANCE,
415 		.info_mask_separate =
416 				BIT(IIO_CHAN_INFO_RAW) |
417 				BIT(IIO_CHAN_INFO_SCALE),
418 		.scan_index = 0,
419 		.scan_type = {
420 			.sign = 's',
421 			.realbits = 16,
422 			.storagebits = 16,
423 			.endianness = IIO_CPU,
424 		},
425 	},
426 	IIO_CHAN_SOFT_TIMESTAMP(1),
427 };
428 
429 static const struct iio_info srf08_info = {
430 	.read_raw = srf08_read_raw,
431 	.attrs = &srf08_attribute_group,
432 };
433 
434 /*
435  * srf02 don't have an adjustable range or sensitivity,
436  * so we don't need attributes at all
437  */
438 static const struct iio_info srf02_info = {
439 	.read_raw = srf08_read_raw,
440 };
441 
442 static int srf08_probe(struct i2c_client *client)
443 {
444 	const struct i2c_device_id *id = i2c_client_get_device_id(client);
445 	struct iio_dev *indio_dev;
446 	struct srf08_data *data;
447 	int ret;
448 
449 	if (!i2c_check_functionality(client->adapter,
450 					I2C_FUNC_SMBUS_READ_BYTE_DATA |
451 					I2C_FUNC_SMBUS_WRITE_BYTE_DATA |
452 					I2C_FUNC_SMBUS_READ_WORD_DATA))
453 		return -ENODEV;
454 
455 	indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*data));
456 	if (!indio_dev)
457 		return -ENOMEM;
458 
459 	data = iio_priv(indio_dev);
460 	i2c_set_clientdata(client, indio_dev);
461 	data->client = client;
462 	data->sensor_type = (enum srf08_sensor_type)id->driver_data;
463 
464 	switch (data->sensor_type) {
465 	case SRF02:
466 		data->chip_info = &srf02_chip_info;
467 		indio_dev->info = &srf02_info;
468 		break;
469 	case SRF08:
470 		data->chip_info = &srf08_chip_info;
471 		indio_dev->info = &srf08_info;
472 		break;
473 	case SRF10:
474 		data->chip_info = &srf10_chip_info;
475 		indio_dev->info = &srf08_info;
476 		break;
477 	default:
478 		return -EINVAL;
479 	}
480 
481 	indio_dev->name = id->name;
482 	indio_dev->modes = INDIO_DIRECT_MODE;
483 	indio_dev->channels = srf08_channels;
484 	indio_dev->num_channels = ARRAY_SIZE(srf08_channels);
485 
486 	mutex_init(&data->lock);
487 
488 	ret = devm_iio_triggered_buffer_setup(&client->dev, indio_dev,
489 			iio_pollfunc_store_time, srf08_trigger_handler, NULL);
490 	if (ret < 0) {
491 		dev_err(&client->dev, "setup of iio triggered buffer failed\n");
492 		return ret;
493 	}
494 
495 	if (data->chip_info->range_default) {
496 		/*
497 		 * set default range of device in mm here
498 		 * these register values cannot be read from the hardware
499 		 * therefore set driver specific default values
500 		 *
501 		 * srf02 don't have a default value so it'll be omitted
502 		 */
503 		ret = srf08_write_range_mm(data,
504 					data->chip_info->range_default);
505 		if (ret < 0)
506 			return ret;
507 	}
508 
509 	if (data->chip_info->sensitivity_default) {
510 		/*
511 		 * set default sensitivity of device here
512 		 * these register values cannot be read from the hardware
513 		 * therefore set driver specific default values
514 		 *
515 		 * srf02 don't have a default value so it'll be omitted
516 		 */
517 		ret = srf08_write_sensitivity(data,
518 				data->chip_info->sensitivity_default);
519 		if (ret < 0)
520 			return ret;
521 	}
522 
523 	return devm_iio_device_register(&client->dev, indio_dev);
524 }
525 
526 static const struct of_device_id of_srf08_match[] = {
527 	{ .compatible = "devantech,srf02", (void *)SRF02 },
528 	{ .compatible = "devantech,srf08", (void *)SRF08 },
529 	{ .compatible = "devantech,srf10", (void *)SRF10 },
530 	{ }
531 };
532 
533 MODULE_DEVICE_TABLE(of, of_srf08_match);
534 
535 static const struct i2c_device_id srf08_id[] = {
536 	{ "srf02", SRF02 },
537 	{ "srf08", SRF08 },
538 	{ "srf10", SRF10 },
539 	{ }
540 };
541 MODULE_DEVICE_TABLE(i2c, srf08_id);
542 
543 static struct i2c_driver srf08_driver = {
544 	.driver = {
545 		.name	= "srf08",
546 		.of_match_table	= of_srf08_match,
547 	},
548 	.probe = srf08_probe,
549 	.id_table = srf08_id,
550 };
551 module_i2c_driver(srf08_driver);
552 
553 MODULE_AUTHOR("Andreas Klinger <ak@it-klinger.de>");
554 MODULE_DESCRIPTION("Devantech SRF02/SRF08/SRF10 i2c ultrasonic ranger driver");
555 MODULE_LICENSE("GPL");
556