1 // SPDX-License-Identifier: GPL-2.0-or-later 2 /* 3 * PING: ultrasonic sensor for distance measuring by using only one GPIOs 4 * 5 * Copyright (c) 2019 Andreas Klinger <ak@it-klinger.de> 6 * 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 10 * 11 * the measurement cycle as timing diagram looks like: 12 * 13 * GPIO ___ ________________________ 14 * ping: __/ \____________/ \________________ 15 * ^ ^ ^ ^ 16 * |<->| interrupt interrupt 17 * udelay(5) (ts_rising) (ts_falling) 18 * |<---------------------->| 19 * . pulse time measured . 20 * . --> one round trip of ultra sonic waves 21 * ultra . . 22 * sonic _ _ _. . 23 * burst: _________/ \_/ \_/ \_________________________________________ 24 * . 25 * ultra . 26 * sonic _ _ _. 27 * echo: __________________________________/ \_/ \_/ \________________ 28 */ 29 #include <linux/err.h> 30 #include <linux/gpio/consumer.h> 31 #include <linux/kernel.h> 32 #include <linux/module.h> 33 #include <linux/platform_device.h> 34 #include <linux/property.h> 35 #include <linux/sched.h> 36 #include <linux/interrupt.h> 37 #include <linux/delay.h> 38 #include <linux/iio/iio.h> 39 #include <linux/iio/sysfs.h> 40 41 struct ping_cfg { 42 unsigned long trigger_pulse_us; /* length of trigger pulse */ 43 int laserping_error; /* support error code in */ 44 /* pulse width of laser */ 45 /* ping sensors */ 46 s64 timeout_ns; /* timeout in ns */ 47 }; 48 49 struct ping_data { 50 struct device *dev; 51 struct gpio_desc *gpiod_ping; 52 struct mutex lock; 53 int irqnr; 54 ktime_t ts_rising; 55 ktime_t ts_falling; 56 struct completion rising; 57 struct completion falling; 58 const struct ping_cfg *cfg; 59 }; 60 61 static const struct ping_cfg pa_ping_cfg = { 62 .trigger_pulse_us = 5, 63 .laserping_error = 0, 64 .timeout_ns = 18500000, /* 3 meters */ 65 }; 66 67 static const struct ping_cfg pa_laser_ping_cfg = { 68 .trigger_pulse_us = 5, 69 .laserping_error = 1, 70 .timeout_ns = 15500000, /* 2 meters plus error codes */ 71 }; 72 73 static irqreturn_t ping_handle_irq(int irq, void *dev_id) 74 { 75 struct iio_dev *indio_dev = dev_id; 76 struct ping_data *data = iio_priv(indio_dev); 77 ktime_t now = ktime_get(); 78 79 if (gpiod_get_value(data->gpiod_ping)) { 80 data->ts_rising = now; 81 complete(&data->rising); 82 } else { 83 data->ts_falling = now; 84 complete(&data->falling); 85 } 86 87 return IRQ_HANDLED; 88 } 89 90 static int ping_read(struct iio_dev *indio_dev) 91 { 92 struct ping_data *data = iio_priv(indio_dev); 93 int ret; 94 ktime_t ktime_dt; 95 s64 dt_ns; 96 u32 time_ns, distance_mm; 97 struct platform_device *pdev = to_platform_device(data->dev); 98 99 /* 100 * just one read-echo-cycle can take place at a time 101 * ==> lock against concurrent reading calls 102 */ 103 mutex_lock(&data->lock); 104 105 reinit_completion(&data->rising); 106 reinit_completion(&data->falling); 107 108 gpiod_set_value(data->gpiod_ping, 1); 109 udelay(data->cfg->trigger_pulse_us); 110 gpiod_set_value(data->gpiod_ping, 0); 111 112 ret = gpiod_direction_input(data->gpiod_ping); 113 if (ret < 0) { 114 mutex_unlock(&data->lock); 115 return ret; 116 } 117 118 data->irqnr = gpiod_to_irq(data->gpiod_ping); 119 if (data->irqnr < 0) { 120 dev_err(data->dev, "gpiod_to_irq: %d\n", data->irqnr); 121 mutex_unlock(&data->lock); 122 return data->irqnr; 123 } 124 125 ret = request_irq(data->irqnr, ping_handle_irq, 126 IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING, 127 pdev->name, indio_dev); 128 if (ret < 0) { 129 dev_err(data->dev, "request_irq: %d\n", ret); 130 mutex_unlock(&data->lock); 131 return ret; 132 } 133 134 /* it should not take more than 20 ms until echo is rising */ 135 ret = wait_for_completion_killable_timeout(&data->rising, HZ/50); 136 if (ret < 0) 137 goto err_reset_direction; 138 else if (ret == 0) { 139 ret = -ETIMEDOUT; 140 goto err_reset_direction; 141 } 142 143 /* it cannot take more than 50 ms until echo is falling */ 144 ret = wait_for_completion_killable_timeout(&data->falling, HZ/20); 145 if (ret < 0) 146 goto err_reset_direction; 147 else if (ret == 0) { 148 ret = -ETIMEDOUT; 149 goto err_reset_direction; 150 } 151 152 ktime_dt = ktime_sub(data->ts_falling, data->ts_rising); 153 154 free_irq(data->irqnr, indio_dev); 155 156 ret = gpiod_direction_output(data->gpiod_ping, GPIOD_OUT_LOW); 157 if (ret < 0) { 158 mutex_unlock(&data->lock); 159 return ret; 160 } 161 162 mutex_unlock(&data->lock); 163 164 dt_ns = ktime_to_ns(ktime_dt); 165 if (dt_ns > data->cfg->timeout_ns) { 166 dev_dbg(data->dev, "distance out of range: dt=%lldns\n", 167 dt_ns); 168 return -EIO; 169 } 170 171 time_ns = dt_ns; 172 173 /* 174 * read error code of laser ping sensor and give users chance to 175 * figure out error by using dynamic debugging 176 */ 177 if (data->cfg->laserping_error) { 178 if ((time_ns > 12500000) && (time_ns <= 13500000)) { 179 dev_dbg(data->dev, "target too close or to far\n"); 180 return -EIO; 181 } 182 if ((time_ns > 13500000) && (time_ns <= 14500000)) { 183 dev_dbg(data->dev, "internal sensor error\n"); 184 return -EIO; 185 } 186 if ((time_ns > 14500000) && (time_ns <= 15500000)) { 187 dev_dbg(data->dev, "internal sensor timeout\n"); 188 return -EIO; 189 } 190 } 191 192 /* 193 * the speed as function of the temperature is approximately: 194 * 195 * speed = 331,5 + 0,6 * Temp 196 * with Temp in °C 197 * and speed in m/s 198 * 199 * use 343,5 m/s as ultrasonic speed at 20 °C here in absence of the 200 * temperature 201 * 202 * therefore: 203 * time 343,5 time * 232 204 * distance = ------ * ------- = ------------ 205 * 10^6 2 1350800 206 * with time in ns 207 * and distance in mm (one way) 208 * 209 * because we limit to 3 meters the multiplication with 232 just 210 * fits into 32 bit 211 */ 212 distance_mm = time_ns * 232 / 1350800; 213 214 return distance_mm; 215 216 err_reset_direction: 217 free_irq(data->irqnr, indio_dev); 218 mutex_unlock(&data->lock); 219 220 if (gpiod_direction_output(data->gpiod_ping, GPIOD_OUT_LOW)) 221 dev_dbg(data->dev, "error in gpiod_direction_output\n"); 222 return ret; 223 } 224 225 static int ping_read_raw(struct iio_dev *indio_dev, 226 struct iio_chan_spec const *channel, int *val, 227 int *val2, long info) 228 { 229 int ret; 230 231 if (channel->type != IIO_DISTANCE) 232 return -EINVAL; 233 234 switch (info) { 235 case IIO_CHAN_INFO_RAW: 236 ret = ping_read(indio_dev); 237 if (ret < 0) 238 return ret; 239 *val = ret; 240 return IIO_VAL_INT; 241 case IIO_CHAN_INFO_SCALE: 242 /* 243 * maximum resolution in datasheet is 1 mm 244 * 1 LSB is 1 mm 245 */ 246 *val = 0; 247 *val2 = 1000; 248 return IIO_VAL_INT_PLUS_MICRO; 249 default: 250 return -EINVAL; 251 } 252 } 253 254 static const struct iio_info ping_iio_info = { 255 .read_raw = ping_read_raw, 256 }; 257 258 static const struct iio_chan_spec ping_chan_spec[] = { 259 { 260 .type = IIO_DISTANCE, 261 .info_mask_separate = 262 BIT(IIO_CHAN_INFO_RAW) | 263 BIT(IIO_CHAN_INFO_SCALE), 264 }, 265 }; 266 267 static const struct of_device_id of_ping_match[] = { 268 { .compatible = "parallax,ping", .data = &pa_ping_cfg }, 269 { .compatible = "parallax,laserping", .data = &pa_laser_ping_cfg }, 270 { } 271 }; 272 273 MODULE_DEVICE_TABLE(of, of_ping_match); 274 275 static int ping_probe(struct platform_device *pdev) 276 { 277 struct device *dev = &pdev->dev; 278 struct ping_data *data; 279 struct iio_dev *indio_dev; 280 281 indio_dev = devm_iio_device_alloc(dev, sizeof(struct ping_data)); 282 if (!indio_dev) 283 return -ENOMEM; 284 285 data = iio_priv(indio_dev); 286 data->dev = dev; 287 data->cfg = device_get_match_data(dev); 288 289 mutex_init(&data->lock); 290 init_completion(&data->rising); 291 init_completion(&data->falling); 292 293 data->gpiod_ping = devm_gpiod_get(dev, "ping", GPIOD_OUT_LOW); 294 if (IS_ERR(data->gpiod_ping)) { 295 dev_err(dev, "failed to get ping-gpios: err=%ld\n", 296 PTR_ERR(data->gpiod_ping)); 297 return PTR_ERR(data->gpiod_ping); 298 } 299 300 if (gpiod_cansleep(data->gpiod_ping)) { 301 dev_err(data->dev, "cansleep-GPIOs not supported\n"); 302 return -ENODEV; 303 } 304 305 platform_set_drvdata(pdev, indio_dev); 306 307 indio_dev->name = "ping"; 308 indio_dev->info = &ping_iio_info; 309 indio_dev->modes = INDIO_DIRECT_MODE; 310 indio_dev->channels = ping_chan_spec; 311 indio_dev->num_channels = ARRAY_SIZE(ping_chan_spec); 312 313 return devm_iio_device_register(dev, indio_dev); 314 } 315 316 static struct platform_driver ping_driver = { 317 .probe = ping_probe, 318 .driver = { 319 .name = "ping-gpio", 320 .of_match_table = of_ping_match, 321 }, 322 }; 323 324 module_platform_driver(ping_driver); 325 326 MODULE_AUTHOR("Andreas Klinger <ak@it-klinger.de>"); 327 MODULE_DESCRIPTION("PING sensors for distance measuring using one GPIOs"); 328 MODULE_LICENSE("GPL"); 329 MODULE_ALIAS("platform:ping"); 330