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 * http://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 52 struct srf04_cfg { 53 unsigned long trigger_pulse_us; 54 }; 55 56 struct 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 71 static const struct srf04_cfg srf04_cfg = { 72 .trigger_pulse_us = 10, 73 }; 74 75 static const struct srf04_cfg mb_lv_cfg = { 76 .trigger_pulse_us = 20, 77 }; 78 79 static 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 96 static 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 192 static 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 222 static const struct iio_info srf04_iio_info = { 223 .read_raw = srf04_read_raw, 224 }; 225 226 static 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 235 static 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 245 MODULE_DEVICE_TABLE(of, of_srf04_match); 246 247 static 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->dev.parent = &pdev->dev; 321 indio_dev->info = &srf04_iio_info; 322 indio_dev->modes = INDIO_DIRECT_MODE; 323 indio_dev->channels = srf04_chan_spec; 324 indio_dev->num_channels = ARRAY_SIZE(srf04_chan_spec); 325 326 ret = iio_device_register(indio_dev); 327 if (ret < 0) { 328 dev_err(data->dev, "iio_device_register: %d\n", ret); 329 return ret; 330 } 331 332 if (data->gpiod_power) { 333 pm_runtime_set_autosuspend_delay(data->dev, 1000); 334 pm_runtime_use_autosuspend(data->dev); 335 336 ret = pm_runtime_set_active(data->dev); 337 if (ret) { 338 dev_err(data->dev, "pm_runtime_set_active: %d\n", ret); 339 iio_device_unregister(indio_dev); 340 } 341 342 pm_runtime_enable(data->dev); 343 pm_runtime_idle(data->dev); 344 } 345 346 return ret; 347 } 348 349 static int srf04_remove(struct platform_device *pdev) 350 { 351 struct iio_dev *indio_dev = platform_get_drvdata(pdev); 352 struct srf04_data *data = iio_priv(indio_dev); 353 354 iio_device_unregister(indio_dev); 355 356 if (data->gpiod_power) { 357 pm_runtime_disable(data->dev); 358 pm_runtime_set_suspended(data->dev); 359 } 360 361 return 0; 362 } 363 364 static int __maybe_unused srf04_pm_runtime_suspend(struct device *dev) 365 { 366 struct platform_device *pdev = container_of(dev, 367 struct platform_device, dev); 368 struct iio_dev *indio_dev = platform_get_drvdata(pdev); 369 struct srf04_data *data = iio_priv(indio_dev); 370 371 gpiod_set_value(data->gpiod_power, 0); 372 373 return 0; 374 } 375 376 static int __maybe_unused srf04_pm_runtime_resume(struct device *dev) 377 { 378 struct platform_device *pdev = container_of(dev, 379 struct platform_device, dev); 380 struct iio_dev *indio_dev = platform_get_drvdata(pdev); 381 struct srf04_data *data = iio_priv(indio_dev); 382 383 gpiod_set_value(data->gpiod_power, 1); 384 msleep(data->startup_time_ms); 385 386 return 0; 387 } 388 389 static const struct dev_pm_ops srf04_pm_ops = { 390 SET_RUNTIME_PM_OPS(srf04_pm_runtime_suspend, 391 srf04_pm_runtime_resume, NULL) 392 }; 393 394 static struct platform_driver srf04_driver = { 395 .probe = srf04_probe, 396 .remove = srf04_remove, 397 .driver = { 398 .name = "srf04-gpio", 399 .of_match_table = of_srf04_match, 400 .pm = &srf04_pm_ops, 401 }, 402 }; 403 404 module_platform_driver(srf04_driver); 405 406 MODULE_AUTHOR("Andreas Klinger <ak@it-klinger.de>"); 407 MODULE_DESCRIPTION("SRF04 ultrasonic sensor for distance measuring using GPIOs"); 408 MODULE_LICENSE("GPL"); 409 MODULE_ALIAS("platform:srf04"); 410