xref: /linux/drivers/iio/proximity/srf08.c (revision 23d66dbab84e8518943563df2ced14aaab28b77a)
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 sysfs_emit(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 sysfs_emit(buf, "%d.%03d\n",
242 			  data->range_mm / 1000, 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 += sysfs_emit_at(buf, len, "%d ",
320 					     data->chip_info->sensitivity_avail[i]);
321 
322 	len += sysfs_emit_at(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 
336 	return sysfs_emit(buf, "%d\n", data->sensitivity);
337 }
338 
339 static ssize_t srf08_write_sensitivity(struct srf08_data *data,
340 							unsigned int val)
341 {
342 	struct i2c_client *client = data->client;
343 	int ret, i;
344 	u8 regval;
345 
346 	if (!val)
347 		return -EINVAL;
348 
349 	for (i = 0; i < data->chip_info->num_sensitivity_avail; i++)
350 		if (val == data->chip_info->sensitivity_avail[i]) {
351 			regval = i;
352 			break;
353 		}
354 
355 	if (i >= data->chip_info->num_sensitivity_avail)
356 		return -EINVAL;
357 
358 	mutex_lock(&data->lock);
359 
360 	ret = i2c_smbus_write_byte_data(client, SRF08_WRITE_MAX_GAIN, regval);
361 	if (ret < 0) {
362 		dev_err(&client->dev, "write_sensitivity - err: %d\n", ret);
363 		mutex_unlock(&data->lock);
364 		return ret;
365 	}
366 
367 	data->sensitivity = val;
368 
369 	mutex_unlock(&data->lock);
370 
371 	return 0;
372 }
373 
374 static ssize_t srf08_store_sensitivity(struct device *dev,
375 						struct device_attribute *attr,
376 						const char *buf, size_t len)
377 {
378 	struct iio_dev *indio_dev = dev_to_iio_dev(dev);
379 	struct srf08_data *data = iio_priv(indio_dev);
380 	int ret;
381 	unsigned int val;
382 
383 	ret = kstrtouint(buf, 10, &val);
384 	if (ret)
385 		return ret;
386 
387 	ret = srf08_write_sensitivity(data, val);
388 	if (ret < 0)
389 		return ret;
390 
391 	return len;
392 }
393 
394 static IIO_DEVICE_ATTR(sensor_sensitivity, S_IRUGO | S_IWUSR,
395 			srf08_show_sensitivity, srf08_store_sensitivity, 0);
396 
397 static struct attribute *srf08_attributes[] = {
398 	&iio_dev_attr_sensor_max_range.dev_attr.attr,
399 	&iio_dev_attr_sensor_max_range_available.dev_attr.attr,
400 	&iio_dev_attr_sensor_sensitivity.dev_attr.attr,
401 	&iio_dev_attr_sensor_sensitivity_available.dev_attr.attr,
402 	NULL,
403 };
404 
405 static const struct attribute_group srf08_attribute_group = {
406 	.attrs = srf08_attributes,
407 };
408 
409 static const struct iio_chan_spec srf08_channels[] = {
410 	{
411 		.type = IIO_DISTANCE,
412 		.info_mask_separate =
413 				BIT(IIO_CHAN_INFO_RAW) |
414 				BIT(IIO_CHAN_INFO_SCALE),
415 		.scan_index = 0,
416 		.scan_type = {
417 			.sign = 's',
418 			.realbits = 16,
419 			.storagebits = 16,
420 			.endianness = IIO_CPU,
421 		},
422 	},
423 	IIO_CHAN_SOFT_TIMESTAMP(1),
424 };
425 
426 static const struct iio_info srf08_info = {
427 	.read_raw = srf08_read_raw,
428 	.attrs = &srf08_attribute_group,
429 };
430 
431 /*
432  * srf02 don't have an adjustable range or sensitivity,
433  * so we don't need attributes at all
434  */
435 static const struct iio_info srf02_info = {
436 	.read_raw = srf08_read_raw,
437 };
438 
439 static int srf08_probe(struct i2c_client *client)
440 {
441 	const struct i2c_device_id *id = i2c_client_get_device_id(client);
442 	struct iio_dev *indio_dev;
443 	struct srf08_data *data;
444 	int ret;
445 
446 	if (!i2c_check_functionality(client->adapter,
447 					I2C_FUNC_SMBUS_READ_BYTE_DATA |
448 					I2C_FUNC_SMBUS_WRITE_BYTE_DATA |
449 					I2C_FUNC_SMBUS_READ_WORD_DATA))
450 		return -ENODEV;
451 
452 	indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*data));
453 	if (!indio_dev)
454 		return -ENOMEM;
455 
456 	data = iio_priv(indio_dev);
457 	i2c_set_clientdata(client, indio_dev);
458 	data->client = client;
459 	data->sensor_type = (enum srf08_sensor_type)id->driver_data;
460 
461 	switch (data->sensor_type) {
462 	case SRF02:
463 		data->chip_info = &srf02_chip_info;
464 		indio_dev->info = &srf02_info;
465 		break;
466 	case SRF08:
467 		data->chip_info = &srf08_chip_info;
468 		indio_dev->info = &srf08_info;
469 		break;
470 	case SRF10:
471 		data->chip_info = &srf10_chip_info;
472 		indio_dev->info = &srf08_info;
473 		break;
474 	default:
475 		return -EINVAL;
476 	}
477 
478 	indio_dev->name = id->name;
479 	indio_dev->modes = INDIO_DIRECT_MODE;
480 	indio_dev->channels = srf08_channels;
481 	indio_dev->num_channels = ARRAY_SIZE(srf08_channels);
482 
483 	mutex_init(&data->lock);
484 
485 	ret = devm_iio_triggered_buffer_setup(&client->dev, indio_dev,
486 			iio_pollfunc_store_time, srf08_trigger_handler, NULL);
487 	if (ret < 0) {
488 		dev_err(&client->dev, "setup of iio triggered buffer failed\n");
489 		return ret;
490 	}
491 
492 	if (data->chip_info->range_default) {
493 		/*
494 		 * set default range of device in mm here
495 		 * these register values cannot be read from the hardware
496 		 * therefore set driver specific default values
497 		 *
498 		 * srf02 don't have a default value so it'll be omitted
499 		 */
500 		ret = srf08_write_range_mm(data,
501 					data->chip_info->range_default);
502 		if (ret < 0)
503 			return ret;
504 	}
505 
506 	if (data->chip_info->sensitivity_default) {
507 		/*
508 		 * set default sensitivity of device here
509 		 * these register values cannot be read from the hardware
510 		 * therefore set driver specific default values
511 		 *
512 		 * srf02 don't have a default value so it'll be omitted
513 		 */
514 		ret = srf08_write_sensitivity(data,
515 				data->chip_info->sensitivity_default);
516 		if (ret < 0)
517 			return ret;
518 	}
519 
520 	return devm_iio_device_register(&client->dev, indio_dev);
521 }
522 
523 static const struct of_device_id of_srf08_match[] = {
524 	{ .compatible = "devantech,srf02", (void *)SRF02 },
525 	{ .compatible = "devantech,srf08", (void *)SRF08 },
526 	{ .compatible = "devantech,srf10", (void *)SRF10 },
527 	{ }
528 };
529 
530 MODULE_DEVICE_TABLE(of, of_srf08_match);
531 
532 static const struct i2c_device_id srf08_id[] = {
533 	{ .name = "srf02", .driver_data = SRF02 },
534 	{ .name = "srf08", .driver_data = SRF08 },
535 	{ .name = "srf10", .driver_data = SRF10 },
536 	{ }
537 };
538 MODULE_DEVICE_TABLE(i2c, srf08_id);
539 
540 static struct i2c_driver srf08_driver = {
541 	.driver = {
542 		.name	= "srf08",
543 		.of_match_table	= of_srf08_match,
544 	},
545 	.probe = srf08_probe,
546 	.id_table = srf08_id,
547 };
548 module_i2c_driver(srf08_driver);
549 
550 MODULE_AUTHOR("Andreas Klinger <ak@it-klinger.de>");
551 MODULE_DESCRIPTION("Devantech SRF02/SRF08/SRF10 i2c ultrasonic ranger driver");
552 MODULE_LICENSE("GPL");
553