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