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 51 struct srf04_cfg { 52 unsigned long trigger_pulse_us; 53 }; 54 55 struct 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 70 static const struct srf04_cfg srf04_cfg = { 71 .trigger_pulse_us = 10, 72 }; 73 74 static const struct srf04_cfg mb_lv_cfg = { 75 .trigger_pulse_us = 20, 76 }; 77 78 static 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 95 static 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 193 static 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 223 static const struct iio_info srf04_iio_info = { 224 .read_raw = srf04_read_raw, 225 }; 226 227 static 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 236 static 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 246 MODULE_DEVICE_TABLE(of, of_srf04_match); 247 248 static 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 347 static void 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 360 static int srf04_pm_runtime_suspend(struct device *dev) 361 { 362 struct platform_device *pdev = container_of(dev, 363 struct platform_device, dev); 364 struct iio_dev *indio_dev = platform_get_drvdata(pdev); 365 struct srf04_data *data = iio_priv(indio_dev); 366 367 gpiod_set_value(data->gpiod_power, 0); 368 369 return 0; 370 } 371 372 static int srf04_pm_runtime_resume(struct device *dev) 373 { 374 struct platform_device *pdev = container_of(dev, 375 struct platform_device, dev); 376 struct iio_dev *indio_dev = platform_get_drvdata(pdev); 377 struct srf04_data *data = iio_priv(indio_dev); 378 379 gpiod_set_value(data->gpiod_power, 1); 380 msleep(data->startup_time_ms); 381 382 return 0; 383 } 384 385 static const struct dev_pm_ops srf04_pm_ops = { 386 RUNTIME_PM_OPS(srf04_pm_runtime_suspend, 387 srf04_pm_runtime_resume, NULL) 388 }; 389 390 static struct platform_driver srf04_driver = { 391 .probe = srf04_probe, 392 .remove = srf04_remove, 393 .driver = { 394 .name = "srf04-gpio", 395 .of_match_table = of_srf04_match, 396 .pm = pm_ptr(&srf04_pm_ops), 397 }, 398 }; 399 400 module_platform_driver(srf04_driver); 401 402 MODULE_AUTHOR("Andreas Klinger <ak@it-klinger.de>"); 403 MODULE_DESCRIPTION("SRF04 ultrasonic sensor for distance measuring using GPIOs"); 404 MODULE_LICENSE("GPL"); 405 MODULE_ALIAS("platform:srf04"); 406