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