1 // SPDX-License-Identifier: GPL-2.0-or-later
3 * PING: ultrasonic sensor for distance measuring by using only one GPIOs
5 * Copyright (c) 2019 Andreas Klinger <ak@it-klinger.de>
7 * For details about the devices see:
8 * http://parallax.com/sites/default/files/downloads/28041-LaserPING-2m-Rangefinder-Guide.pdf
9 * http://parallax.com/sites/default/files/downloads/28015-PING-Documentation-v1.6.pdf
11 * the measurement cycle as timing diagram looks like:
13 * GPIO ___ ________________________
14 * ping: __/ \____________/ \________________
16 * |<->| interrupt interrupt
17 * udelay(5) (ts_rising) (ts_falling)
18 * |<---------------------->|
19 * . pulse time measured .
20 * . --> one round trip of ultra sonic waves
23 * burst: _________/ \_/ \_/ \_________________________________________
27 * echo: __________________________________/ \_/ \_/ \________________
29 #include <linux/err.h>
30 #include <linux/gpio/consumer.h>
31 #include <linux/kernel.h>
32 #include <linux/module.h>
34 #include <linux/of_device.h>
35 #include <linux/platform_device.h>
36 #include <linux/property.h>
37 #include <linux/sched.h>
38 #include <linux/interrupt.h>
39 #include <linux/delay.h>
40 #include <linux/iio/iio.h>
41 #include <linux/iio/sysfs.h>
44 unsigned long trigger_pulse_us
; /* length of trigger pulse */
45 int laserping_error
; /* support error code in */
46 /* pulse width of laser */
48 s64 timeout_ns
; /* timeout in ns */
53 struct gpio_desc
*gpiod_ping
;
58 struct completion rising
;
59 struct completion falling
;
60 const struct ping_cfg
*cfg
;
63 static const struct ping_cfg pa_ping_cfg
= {
64 .trigger_pulse_us
= 5,
66 .timeout_ns
= 18500000, /* 3 meters */
69 static const struct ping_cfg pa_laser_ping_cfg
= {
70 .trigger_pulse_us
= 5,
72 .timeout_ns
= 15500000, /* 2 meters plus error codes */
75 static irqreturn_t
ping_handle_irq(int irq
, void *dev_id
)
77 struct iio_dev
*indio_dev
= dev_id
;
78 struct ping_data
*data
= iio_priv(indio_dev
);
79 ktime_t now
= ktime_get();
81 if (gpiod_get_value(data
->gpiod_ping
)) {
82 data
->ts_rising
= now
;
83 complete(&data
->rising
);
85 data
->ts_falling
= now
;
86 complete(&data
->falling
);
92 static int ping_read(struct ping_data
*data
)
97 u32 time_ns
, distance_mm
;
98 struct platform_device
*pdev
= to_platform_device(data
->dev
);
99 struct iio_dev
*indio_dev
= iio_priv_to_dev(data
);
102 * just one read-echo-cycle can take place at a time
103 * ==> lock against concurrent reading calls
105 mutex_lock(&data
->lock
);
107 reinit_completion(&data
->rising
);
108 reinit_completion(&data
->falling
);
110 gpiod_set_value(data
->gpiod_ping
, 1);
111 udelay(data
->cfg
->trigger_pulse_us
);
112 gpiod_set_value(data
->gpiod_ping
, 0);
114 ret
= gpiod_direction_input(data
->gpiod_ping
);
116 mutex_unlock(&data
->lock
);
120 data
->irqnr
= gpiod_to_irq(data
->gpiod_ping
);
121 if (data
->irqnr
< 0) {
122 dev_err(data
->dev
, "gpiod_to_irq: %d\n", data
->irqnr
);
123 mutex_unlock(&data
->lock
);
127 ret
= request_irq(data
->irqnr
, ping_handle_irq
,
128 IRQF_TRIGGER_RISING
| IRQF_TRIGGER_FALLING
,
129 pdev
->name
, indio_dev
);
131 dev_err(data
->dev
, "request_irq: %d\n", ret
);
132 mutex_unlock(&data
->lock
);
136 /* it should not take more than 20 ms until echo is rising */
137 ret
= wait_for_completion_killable_timeout(&data
->rising
, HZ
/50);
139 goto err_reset_direction
;
142 goto err_reset_direction
;
145 /* it cannot take more than 50 ms until echo is falling */
146 ret
= wait_for_completion_killable_timeout(&data
->falling
, HZ
/20);
148 goto err_reset_direction
;
151 goto err_reset_direction
;
154 ktime_dt
= ktime_sub(data
->ts_falling
, data
->ts_rising
);
156 free_irq(data
->irqnr
, indio_dev
);
158 ret
= gpiod_direction_output(data
->gpiod_ping
, GPIOD_OUT_LOW
);
160 mutex_unlock(&data
->lock
);
164 mutex_unlock(&data
->lock
);
166 dt_ns
= ktime_to_ns(ktime_dt
);
167 if (dt_ns
> data
->cfg
->timeout_ns
) {
168 dev_dbg(data
->dev
, "distance out of range: dt=%lldns\n",
176 * read error code of laser ping sensor and give users chance to
177 * figure out error by using dynamic debuggging
179 if (data
->cfg
->laserping_error
) {
180 if ((time_ns
> 12500000) && (time_ns
<= 13500000)) {
181 dev_dbg(data
->dev
, "target too close or to far\n");
184 if ((time_ns
> 13500000) && (time_ns
<= 14500000)) {
185 dev_dbg(data
->dev
, "internal sensor error\n");
188 if ((time_ns
> 14500000) && (time_ns
<= 15500000)) {
189 dev_dbg(data
->dev
, "internal sensor timeout\n");
195 * the speed as function of the temperature is approximately:
197 * speed = 331,5 + 0,6 * Temp
201 * use 343,5 m/s as ultrasonic speed at 20 °C here in absence of the
205 * time 343,5 time * 232
206 * distance = ------ * ------- = ------------
209 * and distance in mm (one way)
211 * because we limit to 3 meters the multiplication with 232 just
214 distance_mm
= time_ns
* 232 / 1350800;
219 free_irq(data
->irqnr
, indio_dev
);
220 mutex_unlock(&data
->lock
);
222 if (gpiod_direction_output(data
->gpiod_ping
, GPIOD_OUT_LOW
))
223 dev_dbg(data
->dev
, "error in gpiod_direction_output\n");
227 static int ping_read_raw(struct iio_dev
*indio_dev
,
228 struct iio_chan_spec
const *channel
, int *val
,
229 int *val2
, long info
)
231 struct ping_data
*data
= iio_priv(indio_dev
);
234 if (channel
->type
!= IIO_DISTANCE
)
238 case IIO_CHAN_INFO_RAW
:
239 ret
= ping_read(data
);
244 case IIO_CHAN_INFO_SCALE
:
246 * maximum resolution in datasheet is 1 mm
251 return IIO_VAL_INT_PLUS_MICRO
;
257 static const struct iio_info ping_iio_info
= {
258 .read_raw
= ping_read_raw
,
261 static const struct iio_chan_spec ping_chan_spec
[] = {
263 .type
= IIO_DISTANCE
,
264 .info_mask_separate
=
265 BIT(IIO_CHAN_INFO_RAW
) |
266 BIT(IIO_CHAN_INFO_SCALE
),
270 static const struct of_device_id of_ping_match
[] = {
271 { .compatible
= "parallax,ping", .data
= &pa_ping_cfg
},
272 { .compatible
= "parallax,laserping", .data
= &pa_laser_ping_cfg
},
276 MODULE_DEVICE_TABLE(of
, of_ping_match
);
278 static int ping_probe(struct platform_device
*pdev
)
280 struct device
*dev
= &pdev
->dev
;
281 struct ping_data
*data
;
282 struct iio_dev
*indio_dev
;
284 indio_dev
= devm_iio_device_alloc(dev
, sizeof(struct ping_data
));
286 dev_err(dev
, "failed to allocate IIO device\n");
290 data
= iio_priv(indio_dev
);
292 data
->cfg
= of_device_get_match_data(dev
);
294 mutex_init(&data
->lock
);
295 init_completion(&data
->rising
);
296 init_completion(&data
->falling
);
298 data
->gpiod_ping
= devm_gpiod_get(dev
, "ping", GPIOD_OUT_LOW
);
299 if (IS_ERR(data
->gpiod_ping
)) {
300 dev_err(dev
, "failed to get ping-gpios: err=%ld\n",
301 PTR_ERR(data
->gpiod_ping
));
302 return PTR_ERR(data
->gpiod_ping
);
305 if (gpiod_cansleep(data
->gpiod_ping
)) {
306 dev_err(data
->dev
, "cansleep-GPIOs not supported\n");
310 platform_set_drvdata(pdev
, indio_dev
);
312 indio_dev
->name
= "ping";
313 indio_dev
->dev
.parent
= &pdev
->dev
;
314 indio_dev
->info
= &ping_iio_info
;
315 indio_dev
->modes
= INDIO_DIRECT_MODE
;
316 indio_dev
->channels
= ping_chan_spec
;
317 indio_dev
->num_channels
= ARRAY_SIZE(ping_chan_spec
);
319 return devm_iio_device_register(dev
, indio_dev
);
322 static struct platform_driver ping_driver
= {
326 .of_match_table
= of_ping_match
,
330 module_platform_driver(ping_driver
);
332 MODULE_AUTHOR("Andreas Klinger <ak@it-klinger.de>");
333 MODULE_DESCRIPTION("PING sensors for distance measuring using one GPIOs");
334 MODULE_LICENSE("GPL");
335 MODULE_ALIAS("platform:ping");