1// SPDX-License-Identifier: GPL-2.0-or-later
2/*
3 * SRF04: ultrasonic sensor for distance measuring by using GPIOs
4 *
5 * Copyright (c) 2017 Andreas Klinger <ak@it-klinger.de>
6 *
7 * For details about the device see:
8 * https://www.robot-electronics.co.uk/htm/srf04tech.htm
9 *
10 * the measurement cycle as timing diagram looks like:
11 *
12 *          +---+
13 * GPIO     |   |
14 * trig:  --+   +------------------------------------------------------
15 *          ^   ^
16 *          |<->|
17 *         udelay(trigger_pulse_us)
18 *
19 * ultra           +-+ +-+ +-+
20 * sonic           | | | | | |
21 * burst: ---------+ +-+ +-+ +-----------------------------------------
22 *                           .
23 * ultra                     .              +-+ +-+ +-+
24 * sonic                     .              | | | | | |
25 * echo:  ----------------------------------+ +-+ +-+ +----------------
26 *                           .                        .
27 *                           +------------------------+
28 * GPIO                      |                        |
29 * echo:  -------------------+                        +---------------
30 *                           ^                        ^
31 *                           interrupt                interrupt
32 *                           (ts_rising)              (ts_falling)
33 *                           |<---------------------->|
34 *                              pulse time measured
35 *                              --> one round trip of ultra sonic waves
36 */
37#include <linux/err.h>
38#include <linux/gpio/consumer.h>
39#include <linux/kernel.h>
40#include <linux/module.h>
41#include <linux/of.h>
42#include <linux/of_device.h>
43#include <linux/platform_device.h>
44#include <linux/property.h>
45#include <linux/sched.h>
46#include <linux/interrupt.h>
47#include <linux/delay.h>
48#include <linux/pm_runtime.h>
49#include <linux/iio/iio.h>
50#include <linux/iio/sysfs.h>
51
52struct srf04_cfg {
53	unsigned long trigger_pulse_us;
54};
55
56struct srf04_data {
57	struct device		*dev;
58	struct gpio_desc	*gpiod_trig;
59	struct gpio_desc	*gpiod_echo;
60	struct gpio_desc	*gpiod_power;
61	struct mutex		lock;
62	int			irqnr;
63	ktime_t			ts_rising;
64	ktime_t			ts_falling;
65	struct completion	rising;
66	struct completion	falling;
67	const struct srf04_cfg	*cfg;
68	int			startup_time_ms;
69};
70
71static const struct srf04_cfg srf04_cfg = {
72	.trigger_pulse_us = 10,
73};
74
75static const struct srf04_cfg mb_lv_cfg = {
76	.trigger_pulse_us = 20,
77};
78
79static irqreturn_t srf04_handle_irq(int irq, void *dev_id)
80{
81	struct iio_dev *indio_dev = dev_id;
82	struct srf04_data *data = iio_priv(indio_dev);
83	ktime_t now = ktime_get();
84
85	if (gpiod_get_value(data->gpiod_echo)) {
86		data->ts_rising = now;
87		complete(&data->rising);
88	} else {
89		data->ts_falling = now;
90		complete(&data->falling);
91	}
92
93	return IRQ_HANDLED;
94}
95
96static int srf04_read(struct srf04_data *data)
97{
98	int ret;
99	ktime_t ktime_dt;
100	u64 dt_ns;
101	u32 time_ns, distance_mm;
102
103	if (data->gpiod_power)
104		pm_runtime_get_sync(data->dev);
105
106	/*
107	 * just one read-echo-cycle can take place at a time
108	 * ==> lock against concurrent reading calls
109	 */
110	mutex_lock(&data->lock);
111
112	reinit_completion(&data->rising);
113	reinit_completion(&data->falling);
114
115	gpiod_set_value(data->gpiod_trig, 1);
116	udelay(data->cfg->trigger_pulse_us);
117	gpiod_set_value(data->gpiod_trig, 0);
118
119	if (data->gpiod_power) {
120		pm_runtime_mark_last_busy(data->dev);
121		pm_runtime_put_autosuspend(data->dev);
122	}
123
124	/* it should not take more than 20 ms until echo is rising */
125	ret = wait_for_completion_killable_timeout(&data->rising, HZ/50);
126	if (ret < 0) {
127		mutex_unlock(&data->lock);
128		return ret;
129	} else if (ret == 0) {
130		mutex_unlock(&data->lock);
131		return -ETIMEDOUT;
132	}
133
134	/* it cannot take more than 50 ms until echo is falling */
135	ret = wait_for_completion_killable_timeout(&data->falling, HZ/20);
136	if (ret < 0) {
137		mutex_unlock(&data->lock);
138		return ret;
139	} else if (ret == 0) {
140		mutex_unlock(&data->lock);
141		return -ETIMEDOUT;
142	}
143
144	ktime_dt = ktime_sub(data->ts_falling, data->ts_rising);
145
146	mutex_unlock(&data->lock);
147
148	dt_ns = ktime_to_ns(ktime_dt);
149	/*
150	 * measuring more than 6,45 meters is beyond the capabilities of
151	 * the supported sensors
152	 * ==> filter out invalid results for not measuring echos of
153	 *     another us sensor
154	 *
155	 * formula:
156	 *         distance     6,45 * 2 m
157	 * time = ---------- = ------------ = 40438871 ns
158	 *          speed         319 m/s
159	 *
160	 * using a minimum speed at -20 °C of 319 m/s
161	 */
162	if (dt_ns > 40438871)
163		return -EIO;
164
165	time_ns = dt_ns;
166
167	/*
168	 * the speed as function of the temperature is approximately:
169	 *
170	 * speed = 331,5 + 0,6 * Temp
171	 *   with Temp in °C
172	 *   and speed in m/s
173	 *
174	 * use 343,5 m/s as ultrasonic speed at 20 °C here in absence of the
175	 * temperature
176	 *
177	 * therefore:
178	 *             time     343,5     time * 106
179	 * distance = ------ * ------- = ------------
180	 *             10^6         2         617176
181	 *   with time in ns
182	 *   and distance in mm (one way)
183	 *
184	 * because we limit to 6,45 meters the multiplication with 106 just
185	 * fits into 32 bit
186	 */
187	distance_mm = time_ns * 106 / 617176;
188
189	return distance_mm;
190}
191
192static int srf04_read_raw(struct iio_dev *indio_dev,
193			    struct iio_chan_spec const *channel, int *val,
194			    int *val2, long info)
195{
196	struct srf04_data *data = iio_priv(indio_dev);
197	int ret;
198
199	if (channel->type != IIO_DISTANCE)
200		return -EINVAL;
201
202	switch (info) {
203	case IIO_CHAN_INFO_RAW:
204		ret = srf04_read(data);
205		if (ret < 0)
206			return ret;
207		*val = ret;
208		return IIO_VAL_INT;
209	case IIO_CHAN_INFO_SCALE:
210		/*
211		 * theoretical maximum resolution is 3 mm
212		 * 1 LSB is 1 mm
213		 */
214		*val = 0;
215		*val2 = 1000;
216		return IIO_VAL_INT_PLUS_MICRO;
217	default:
218		return -EINVAL;
219	}
220}
221
222static const struct iio_info srf04_iio_info = {
223	.read_raw		= srf04_read_raw,
224};
225
226static const struct iio_chan_spec srf04_chan_spec[] = {
227	{
228		.type = IIO_DISTANCE,
229		.info_mask_separate =
230				BIT(IIO_CHAN_INFO_RAW) |
231				BIT(IIO_CHAN_INFO_SCALE),
232	},
233};
234
235static const struct of_device_id of_srf04_match[] = {
236	{ .compatible = "devantech,srf04", .data = &srf04_cfg},
237	{ .compatible = "maxbotix,mb1000", .data = &mb_lv_cfg},
238	{ .compatible = "maxbotix,mb1010", .data = &mb_lv_cfg},
239	{ .compatible = "maxbotix,mb1020", .data = &mb_lv_cfg},
240	{ .compatible = "maxbotix,mb1030", .data = &mb_lv_cfg},
241	{ .compatible = "maxbotix,mb1040", .data = &mb_lv_cfg},
242	{},
243};
244
245MODULE_DEVICE_TABLE(of, of_srf04_match);
246
247static int srf04_probe(struct platform_device *pdev)
248{
249	struct device *dev = &pdev->dev;
250	struct srf04_data *data;
251	struct iio_dev *indio_dev;
252	int ret;
253
254	indio_dev = devm_iio_device_alloc(dev, sizeof(struct srf04_data));
255	if (!indio_dev) {
256		dev_err(dev, "failed to allocate IIO device\n");
257		return -ENOMEM;
258	}
259
260	data = iio_priv(indio_dev);
261	data->dev = dev;
262	data->cfg = of_match_device(of_srf04_match, dev)->data;
263
264	mutex_init(&data->lock);
265	init_completion(&data->rising);
266	init_completion(&data->falling);
267
268	data->gpiod_trig = devm_gpiod_get(dev, "trig", GPIOD_OUT_LOW);
269	if (IS_ERR(data->gpiod_trig)) {
270		dev_err(dev, "failed to get trig-gpios: err=%ld\n",
271					PTR_ERR(data->gpiod_trig));
272		return PTR_ERR(data->gpiod_trig);
273	}
274
275	data->gpiod_echo = devm_gpiod_get(dev, "echo", GPIOD_IN);
276	if (IS_ERR(data->gpiod_echo)) {
277		dev_err(dev, "failed to get echo-gpios: err=%ld\n",
278					PTR_ERR(data->gpiod_echo));
279		return PTR_ERR(data->gpiod_echo);
280	}
281
282	data->gpiod_power = devm_gpiod_get_optional(dev, "power",
283								GPIOD_OUT_LOW);
284	if (IS_ERR(data->gpiod_power)) {
285		dev_err(dev, "failed to get power-gpios: err=%ld\n",
286						PTR_ERR(data->gpiod_power));
287		return PTR_ERR(data->gpiod_power);
288	}
289	if (data->gpiod_power) {
290
291		if (of_property_read_u32(dev->of_node, "startup-time-ms",
292						&data->startup_time_ms))
293			data->startup_time_ms = 100;
294		dev_dbg(dev, "using power gpio: startup-time-ms=%d\n",
295							data->startup_time_ms);
296	}
297
298	if (gpiod_cansleep(data->gpiod_echo)) {
299		dev_err(data->dev, "cansleep-GPIOs not supported\n");
300		return -ENODEV;
301	}
302
303	data->irqnr = gpiod_to_irq(data->gpiod_echo);
304	if (data->irqnr < 0) {
305		dev_err(data->dev, "gpiod_to_irq: %d\n", data->irqnr);
306		return data->irqnr;
307	}
308
309	ret = devm_request_irq(dev, data->irqnr, srf04_handle_irq,
310			IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING,
311			pdev->name, indio_dev);
312	if (ret < 0) {
313		dev_err(data->dev, "request_irq: %d\n", ret);
314		return ret;
315	}
316
317	platform_set_drvdata(pdev, indio_dev);
318
319	indio_dev->name = "srf04";
320	indio_dev->info = &srf04_iio_info;
321	indio_dev->modes = INDIO_DIRECT_MODE;
322	indio_dev->channels = srf04_chan_spec;
323	indio_dev->num_channels = ARRAY_SIZE(srf04_chan_spec);
324
325	ret = iio_device_register(indio_dev);
326	if (ret < 0) {
327		dev_err(data->dev, "iio_device_register: %d\n", ret);
328		return ret;
329	}
330
331	if (data->gpiod_power) {
332		pm_runtime_set_autosuspend_delay(data->dev, 1000);
333		pm_runtime_use_autosuspend(data->dev);
334
335		ret = pm_runtime_set_active(data->dev);
336		if (ret) {
337			dev_err(data->dev, "pm_runtime_set_active: %d\n", ret);
338			iio_device_unregister(indio_dev);
339		}
340
341		pm_runtime_enable(data->dev);
342		pm_runtime_idle(data->dev);
343	}
344
345	return ret;
346}
347
348static int srf04_remove(struct platform_device *pdev)
349{
350	struct iio_dev *indio_dev = platform_get_drvdata(pdev);
351	struct srf04_data *data = iio_priv(indio_dev);
352
353	iio_device_unregister(indio_dev);
354
355	if (data->gpiod_power) {
356		pm_runtime_disable(data->dev);
357		pm_runtime_set_suspended(data->dev);
358	}
359
360	return 0;
361}
362
363static int __maybe_unused srf04_pm_runtime_suspend(struct device *dev)
364{
365	struct platform_device *pdev = container_of(dev,
366						struct platform_device, dev);
367	struct iio_dev *indio_dev = platform_get_drvdata(pdev);
368	struct srf04_data *data = iio_priv(indio_dev);
369
370	gpiod_set_value(data->gpiod_power, 0);
371
372	return 0;
373}
374
375static int __maybe_unused srf04_pm_runtime_resume(struct device *dev)
376{
377	struct platform_device *pdev = container_of(dev,
378						struct platform_device, dev);
379	struct iio_dev *indio_dev = platform_get_drvdata(pdev);
380	struct srf04_data *data = iio_priv(indio_dev);
381
382	gpiod_set_value(data->gpiod_power, 1);
383	msleep(data->startup_time_ms);
384
385	return 0;
386}
387
388static const struct dev_pm_ops srf04_pm_ops = {
389	SET_RUNTIME_PM_OPS(srf04_pm_runtime_suspend,
390				srf04_pm_runtime_resume, NULL)
391};
392
393static struct platform_driver srf04_driver = {
394	.probe		= srf04_probe,
395	.remove		= srf04_remove,
396	.driver		= {
397		.name		= "srf04-gpio",
398		.of_match_table	= of_srf04_match,
399		.pm		= &srf04_pm_ops,
400	},
401};
402
403module_platform_driver(srf04_driver);
404
405MODULE_AUTHOR("Andreas Klinger <ak@it-klinger.de>");
406MODULE_DESCRIPTION("SRF04 ultrasonic sensor for distance measuring using GPIOs");
407MODULE_LICENSE("GPL");
408MODULE_ALIAS("platform:srf04");
409