Skip to contentSkip to conversation

misc devices: HC-SRO4 ultrasonic distance driver

PATCH New Johannes Thoma 4 participants 9 messages Mar 24, 2016 – Jun 1, 2016 1 message not in the archive

Subsystems (2)
lore
Share & tools
lore

A message that is not in the archive (sent off-list or not yet received): [email protected]

#1 lore raw

PATCH 1/1 misc devices: HC-SRO4 ultrasonic distance driver

From 56e8f71c990b92c28a8cb03d859880eab8d06a3d Mon Sep 17 00:00:00 2001
From: Johannes Thoma <[email protected]>
Date: Mon, 21 Mar 2016 22:11:01 +0100
Subject: [PATCH] HC-SRO4 ultrasonic distance sensor driver

The HC-SRO4 is an ultrasonic distance sensor attached to two GPIO pins. The driver is controlled via sysfs and supports an (in theory) unlimited number of HC-SRO4 devices.

Unlike user land solutions this driver produces precise results even when there is high load on the system. It uses a non-blocking interrupt triggered mechanism to record the length of the echo signal.

This patch is against the raspberry pi kernel from
https://github.com/raspberrypi/linux.git hash e481b5ceae6c94c7e60f8bb8591cbb362806246e

Note that this patch isn't meant for lkml (yet) see:
TODO's:

.) Patch against mainline (or whatever kernel it belongs to) .) Use IIO layer instead of creating random sysfs entries. .) Fill in GPIO device as parent to device_create_with_groups(). .) Test it with two or more HC-SRO4 devices.
.) Test it on other hardware than raspberry pi.
.) Test it with kernel debugging enabled.

Anyway, comments are highly appreciated.

---
  MAINTAINERS            |   5 +
  drivers/misc/Kconfig   |  11 ++
  drivers/misc/Makefile  |   1 +
  drivers/misc/hc-sro4.c | 360
+++++++++++++++++++++++++++++++++++++++++++++++++
  4 files changed, 377 insertions(+)

create mode 100644 drivers/misc/hc-sro4.c

MAINTAINERS +0 -0
index da3e4d8..f819d66 100644
@@ -4910,6 +4910,11 @@ W:

http://www.kernel.org/pub/linux/kernel/people/fseidel/hdaps/
S: Maintained
F: drivers/platform/x86/hdaps.c

+HC-SRO4 ULTRASONIC DISTANCE SENSOR DRIVER
+M: Johannes Thoma <[email protected]>
+S: Maintained
+F: drivers/misc/hc-sro4.c
+
HDPVR USB VIDEO ENCODER DRIVER
M: Hans Verkuil <[email protected]>
L: linux-media at vger.kernel.org

drivers/misc/Kconfig +11 -0
index 4c499de..1be88ad 100644
@@ -475,6 +475,17 @@ config BMP085_SPI
  	  To compile this driver as a module, choose M here: the
  	  module will be called bmp085-spi.
 
+config SENSORS_HC_SRO4
+	tristate "HC-SRO4 ultrasonic distance sensor on GPIO"
+	depends on GPIOLIB && SYSFS
+	help
+	  Say Y here if you want to support the HC-SRO4
+	  ultrasonic distance sensor to be hooked on two runtime-configurable
+	  GPIO pins.
+
+	  To compile this driver as a module, choose M here: the
+	  module will be called hc-sro4.
+
  config PCH_PHUB
  	tristate "Intel EG20T PCH/LAPIS Semicon IOH(ML7213/ML7223/ML7831) PHUB"
  	select GENERIC_NET_UTILS
drivers/misc/Makefile +1 -0
index 1acff5b..9a8e508 100644
@@ -23,6 +23,7 @@ obj-$(CONFIG_QCOM_COINCELL)	+= qcom-coincell.o
  obj-$(CONFIG_SENSORS_BH1780)	+= bh1780gli.o
  obj-$(CONFIG_SENSORS_BH1770)	+= bh1770glc.o
  obj-$(CONFIG_SENSORS_APDS990X)	+= apds990x.o
+obj-$(CONFIG_SENSORS_HC_SRO4)	+= hc-sro4.o
  obj-$(CONFIG_SGI_IOC4)		+= ioc4.o
  obj-$(CONFIG_ENCLOSURE_SERVICES) += enclosure.o
  obj-$(CONFIG_KGDB_TESTS)	+= kgdbts.o
drivers/misc/hc-sro4.c new file +18 -0
new file mode 100644
index 0000000..9925b7e
@@ -0,0 +1,360 @@
+/* Precise measurements of time delta between sending a trigger signal
+ * to the HC-SRO4 distance sensor and receiving the echo signal from
+ * the sensor back. This has to be precise in the usecs range. We
+ * use trigger interrupts to measure the signal, so no busy wait :)
+ *
+ * This supports an (in theory) unlimited number of HC-SRO4 devices.
+ * To add a device, do a (as root):
+ *
+ *	# echo 23 24 1000 > /sys/class/distance-sensor/configure
+ *
+ * (23 is the trigger GPIO, 24 is the echo GPIO and 1000 is a timeout in
+ *  milliseconds)
+ *
+ * Then a directory appears with a file measure in it. To measure, do a
+ *
+ *	# cat /sys/class/distance-sensor/distance_23_24/measure
+ *
+ * You'll receive the length of the echo signal in usecs. To convert

(roughly)
+ * to centimeters multiply by 17150 and divide by 1e6.
+ *
+ * To deconfigure the device, do a
+ *
+ * # echo -23 24 > /sys/class/distance-sensor/configure
+ *
+ * (normally not needed).
+ *
+ * DO NOT attach your HC-SRO4's echo pin directly to the raspberry, since
+ * it runs with 5V while raspberry expects 3V on the GPIO inputs.
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/timekeeping.h>
+#include <linux/gpio/consumer.h>
+#include <linux/mutex.h>
+#include <linux/device.h>
+#include <linux/sysfs.h>
+#include <linux/interrupt.h>
+#include <linux/kdev_t.h>
+#include <linux/list.h>
+#include <linux/slab.h>
+#include <linux/gpio/driver.h>
+#include <linux/delay.h>
+#include <linux/sched.h>
+
+struct hc_sro4 {
+ int gpio_trig;
+ int gpio_echo;
+ struct gpio_desc *trig_desc;
+ struct gpio_desc *echo_desc;
+ struct timeval time_triggered;
+ struct timeval time_echoed;
+ int echo_received;
+ int device_triggered;
+ struct mutex measurement_mutex;
+ wait_queue_head_t wait_for_echo;
+ unsigned long timeout;
+ struct list_head list;
+};
+
+static LIST_HEAD(hc_sro4_devices);
+static DEFINE_MUTEX(devices_mutex);
+
+static struct hc_sro4 *create_hc_sro4(int trig, int echo, unsigned long timeout)
+ /* must be called with devices_mutex held */
+{
+ struct hc_sro4 *new;
+ int err;
+
+ new = kmalloc(sizeof(*new), GFP_KERNEL);
+ if (new == NULL)
+ return ERR_PTR(-ENOMEM);
+
+ new->gpio_echo = echo;
+ new->gpio_trig = trig;
+ new->echo_desc = gpio_to_desc(echo);
+ if (new->echo_desc == NULL) {
+ kfree(new);
+ return ERR_PTR(-EINVAL);
+ }
+ new->trig_desc = gpio_to_desc(trig);
+ if (new->trig_desc == NULL) {
+ kfree(new);
+ return ERR_PTR(-EINVAL);
+ }
+
+ err = gpiod_direction_input(new->echo_desc);
+ if (err < 0) {
+ kfree(new);
+ return ERR_PTR(err);
+ }
+ err = gpiod_direction_output(new->trig_desc, 0);
+ if (err < 0) {
+ kfree(new);
+ return ERR_PTR(err);
+ }
+ gpiod_set_value(new->trig_desc, 0);
+
+ mutex_init(&new->measurement_mutex);
+ init_waitqueue_head(&new->wait_for_echo);
+ new->timeout = timeout;
+
+ list_add_tail(&new->list, &hc_sro4_devices);
+
+ return new;
+}
+
+static irqreturn_t echo_received_irq(int irq, void *data)
+{
+ struct hc_sro4 *device = (struct hc_sro4 *) data;
+ int val;
+ struct timeval irq_tv;
+
+ do_gettimeofday(&irq_tv);
+
+ if (!device->device_triggered)
+ return IRQ_HANDLED;
+ if (device->echo_received)
+ return IRQ_HANDLED;
+
+ val = gpiod_get_value(device->echo_desc);
+ if (val == 1) {
+ device->time_triggered = irq_tv;
+ } else {
+ device->time_echoed = irq_tv;
+ device->echo_received = 1;
+ wake_up_interruptible(&device->wait_for_echo);
+ }
+
+ return IRQ_HANDLED;
+}
+
+/* devices_mutex must be held by caller, so nobody deletes the device
+ * before we lock it.
+ */
+
+static int do_measurement(struct hc_sro4 *device,
+ unsigned long long *usecs_elapsed)
+{
+ long timeout;
+ int irq;
+ int ret;
+
+ if (!mutex_trylock(&device->measurement_mutex)) {
+ mutex_unlock(&devices_mutex);
+ return -EBUSY;
+ }
+ mutex_unlock(&devices_mutex);
+
+ msleep(60);
+ /* wait 60 ms between measurements.
+ * now, a while true ; do cat measure ; done should work
+ */
+
+ irq = gpiod_to_irq(device->echo_desc);
+ if (irq < 0)
+ return -EIO;
+
+ device->echo_received = 0;
+ device->device_triggered = 0;
+
+ ret = request_any_context_irq(irq, echo_received_irq,
+ IRQF_SHARED | IRQF_TRIGGER_FALLING | IRQF_TRIGGER_RISING,
+ "hc_sro4", device);
+
+ if (ret < 0)
+ goto out_mutex;
+
+ gpiod_set_value(device->trig_desc, 1);
+ udelay(10);
+ device->device_triggered = 1;
+ gpiod_set_value(device->trig_desc, 0);
+
+ ret = gpiochip_lock_as_irq(gpiod_to_chip(device->echo_desc),
+ device->gpio_echo);
+ if (ret < 0)
+ goto out_irq;
+
+ timeout = wait_event_interruptible_timeout(device->wait_for_echo,
+ device->echo_received, device->timeout);
+
+ if (timeout == 0)
+ ret = -ETIMEDOUT;
+ else if (timeout < 0)
+ ret = timeout;
+ else {
+ *usecs_elapsed =
+ (device->time_echoed.tv_sec - device->time_triggered.tv_sec) * 1000000 +
+ (device->time_echoed.tv_usec - device->time_triggered.tv_usec);
+ ret = 0;
+ }
+out_irq:
+ free_irq(irq, device);
+out_mutex:
+ mutex_unlock(&device->measurement_mutex);
+
+ return ret;
+}
+
+static ssize_t sysfs_do_measurement(struct device *dev,
+ struct device_attribute *attr,
+ char *buf)
+{
+ struct hc_sro4 *sensor = dev_get_drvdata(dev);
+ unsigned long long usecs_elapsed;
+ int status;
+
+ mutex_lock(&devices_mutex);
+ status = do_measurement(sensor, &usecs_elapsed);
+
+ if (status < 0)
+ return status;
+
+ return sprintf(buf, "%lld\n", usecs_elapsed);
+}
+
+DEVICE_ATTR(measure, 0444, sysfs_do_measurement, NULL);
+
+
+static struct attribute *sensor_attrs[] = {
+ &dev_attr_measure.attr,
+ NULL,
+};
+
+static const struct attribute_group sensor_group = {
+ .attrs = sensor_attrs
+};
+
+static const struct attribute_group *sensor_groups[] = {
+ &sensor_group,
+ NULL
+};
+
+static ssize_t sysfs_configure_store(struct class *class,
+ struct class_attribute *attr,
+ const char *buf, size_t len);
+
+static struct class_attribute hc_sro4_class_attrs[] = {
+ __ATTR(configure, 0200, NULL, sysfs_configure_store),
+ __ATTR_NULL,
+};
+
+static struct class hc_sro4_class = {
+ .name = "distance-sensor",
+ .owner = THIS_MODULE,
+ .class_attrs = hc_sro4_class_attrs
+};
+
+
+static struct hc_sro4 *find_sensor(int trig, int echo)
+{
+ struct hc_sro4 *sensor;
+
+ list_for_each_entry(sensor, &hc_sro4_devices, list) {
+ if (sensor->gpio_trig == trig &&
+ sensor->gpio_echo == echo)
+ return sensor;
+ }
+ return NULL;
+}
+
+static int match_device(struct device *dev, const void *data) +{
+ return dev_get_drvdata(dev) == data;
+}
+
+static int remove_sensor(struct hc_sro4 *rip_sensor)
+ /* must be called with devices_mutex held. */
+{
+ struct device *dev;
+
+ dev = class_find_device(&hc_sro4_class, NULL, rip_sensor, match_device);
+ if (dev == NULL)
+ return -ENODEV;
+
+ mutex_lock(&rip_sensor->measurement_mutex);
+ /* wait until measurement has finished */
+ list_del(&rip_sensor->list);
+ kfree(rip_sensor); /* ?? double free ?? */
+
+ device_unregister(dev);
+ put_device(dev);
+
+ return 0;
+}
+
+static ssize_t sysfs_configure_store(struct class *class,
+ struct class_attribute *attr,
+ const char *buf, size_t len)
+{
+ int add = buf[0] != '-';
+ const char *s = buf;
+ int trig, echo, timeout;
+ struct hc_sro4 *new_sensor, *rip_sensor;
+ int err;
+
+ if (buf[0] == '-' || buf[0] == '+')
+ s++;
+
+ if (add) {
+ if (sscanf(s, "%d %d %d", &trig, &echo, &timeout) != 3)
+ return -EINVAL;
+
+ mutex_lock(&devices_mutex);
+ if (find_sensor(trig, echo)) {
+ mutex_unlock(&devices_mutex);
+ return -EEXIST;
+ }
+
+ new_sensor = create_hc_sro4(trig, echo, timeout);
+ mutex_unlock(&devices_mutex);
+ if (IS_ERR(new_sensor))
+ return PTR_ERR(new_sensor);
+
+ device_create_with_groups(class, NULL, MKDEV(0, 0), new_sensor,
+ sensor_groups, "distance_%d_%d", trig, echo);
+ } else {
+ if (sscanf(s, "%d %d", &trig, &echo) != 2)
+ return -EINVAL;
+
+ mutex_lock(&devices_mutex);
+ rip_sensor = find_sensor(trig, echo);
+ if (rip_sensor == NULL) {
+ mutex_unlock(&devices_mutex);
+ return -ENODEV;
+ }
+ err = remove_sensor(rip_sensor);
+ mutex_unlock(&devices_mutex);
+ if (err < 0)
+ return err;
+ }
+ return len;
+}
+
+static int __init init_hc_sro4(void)
+{
+ return class_register(&hc_sro4_class);
+}
+
+static void exit_hc_sro4(void)
+{
+ struct hc_sro4 *rip_sensor, *tmp;
+
+ mutex_lock(&devices_mutex);
+ list_for_each_entry_safe(rip_sensor, tmp, &hc_sro4_devices, list) {
+ remove_sensor(rip_sensor); /* ignore errors */
+ }
+ mutex_unlock(&devices_mutex);
+
+ class_unregister(&hc_sro4_class);
+}
+
+module_init(init_hc_sro4);
+module_exit(exit_hc_sro4);
+
+MODULE_AUTHOR("Johannes Thoma"); +MODULE_DESCRIPTION("Distance measurement for the HC-SRO4 ultrasonic distance sensor for the raspberry pi"); +MODULE_LICENSE("GPL");
+

Signature · 1 line
1.9.1
#2 lore raw

PATCH 1/1 misc devices: HC-SRO4 ultrasonic distance driver

Quoted 30 lines · Johannes Thoma

From 56e8f71c990b92c28a8cb03d859880eab8d06a3d Mon Sep 17 00:00:00 2001
From: Johannes Thoma <[email protected]>
Date: Mon, 21 Mar 2016 22:11:01 +0100
Subject: [PATCH] HC-SRO4 ultrasonic distance sensor driver

The HC-SRO4 is an ultrasonic distance sensor attached to two GPIO pins. The driver is controlled via sysfs and supports an (in theory) unlimited number of HC-SRO4 devices.

Unlike user land solutions this driver produces precise results even when there is high load on the system. It uses a non-blocking interrupt triggered mechanism to record the length of the echo signal.

This patch is against the raspberry pi kernel from
https://github.com/raspberrypi/linux.git hash e481b5ceae6c94c7e60f8bb8591cbb362806246e

Note that this patch isn't meant for lkml (yet) see:
TODO's:

.) Patch against mainline (or whatever kernel it belongs to) .) Use IIO layer instead of creating random sysfs entries. .) Fill in GPIO device as parent to device_create_with_groups(). .) Test it with two or more HC-SRO4 devices.
.) Test it on other hardware than raspberry pi.
.) Test it with kernel debugging enabled.

Anyway, comments are highly appreciated.

Quoted 7 lines
---
  MAINTAINERS            |   5 +
  drivers/misc/Kconfig   |  11 ++
  drivers/misc/Makefile  |   1 +
  drivers/misc/hc-sro4.c | 360

+++++++++++++++++++++++++++++++++++++++++++++++++

Basic comment, your email client corrupted the patch, wrapping the lines and putting odd spaces at the front of the patch, making it impossible to apply. Try using 'git send-email' to fix this up, or fix up your email client.

Also, your patch should not have the email header up there in it, that's the sign that something went wrong.

try it again?

thanks

greg k-h

#3 lore raw

PATCH 1/1 HC-SR04 ultrasonic ranger IIO driver

From: Johannes Thoma <[email protected]>

The HC-SR04 is an ultrasonic distance sensor attached to two GPIO pins. The driver based on Industrial I/O (iio) subsystem and is controlled via configfs and sysfs. It supports an (in theory) unlimited number of HC-SR04 devices.

Datasheet to the device can be found at:

http://www.micropik.com/PDF/HCSR04.pdf

---
 MAINTAINERS                               |   7 +
 drivers/iio/Kconfig                       |   1 +
 drivers/iio/Makefile                      |   1 +
 drivers/iio/ultrasonic-distance/Kconfig   |  16 ++
 drivers/iio/ultrasonic-distance/Makefile  |   6 +
 drivers/iio/ultrasonic-distance/hc-sr04.c | 460 ++++++++++++++++++++++++++++++
 6 files changed, 491 insertions(+)
 create mode 100644 drivers/iio/ultrasonic-distance/Kconfig
 create mode 100644 drivers/iio/ultrasonic-distance/Makefile
 create mode 100644 drivers/iio/ultrasonic-distance/hc-sr04.c
MAINTAINERS +7 -0
index 9c567a4..fabb338 100644
@@ -4988,6 +4988,13 @@ W:	http://www.kernel.org/pub/linux/kernel/people/fseidel/hdaps/
 S:	Maintained
 F:	drivers/platform/x86/hdaps.c
 
+
+HC-SR04 ULTRASONIC DISTANCE SENSOR DRIVER
+M:	Johannes Thoma <[email protected]>
+S:	Maintained
+F:	drivers/iio/ultrasonic-distance/hc-sr04.c
+
+
 HDPVR USB VIDEO ENCODER DRIVER
 M:	Hans Verkuil <[email protected]>
 L:	linux-media at vger.kernel.org
drivers/iio/Kconfig +1 -0
index 505e921..3c82aad 100644
@@ -82,5 +82,6 @@ source "drivers/iio/potentiometer/Kconfig"
 source "drivers/iio/pressure/Kconfig"
 source "drivers/iio/proximity/Kconfig"
 source "drivers/iio/temperature/Kconfig"
+source "drivers/iio/ultrasonic-distance/Kconfig"
 
 endif # IIO
drivers/iio/Makefile +1 -0
index 20f6490..0f1c00c 100644
@@ -32,3 +32,4 @@ obj-y += pressure/
 obj-y += proximity/
 obj-y += temperature/
 obj-y += trigger/
+obj-y += ultrasonic-distance/
drivers/iio/ultrasonic-distance/Kconfig new file +16 -0
new file mode 100644
index 0000000..9d442dd
@@ -0,0 +1,16 @@
+#
+# Ultrasonic range sensors
+#
+
+menu "Ultrasonic ranger devices"
+
+config HC_SR04
+	tristate "HC-SR04 ultrasonic distance sensor on GPIO"
+	depends on GPIOLIB && SYSFS
+	help
+	  Say Y here if you want to support the HC-SR04 ultrasonic distance
+          sensor which is attached on two runtime-configurable GPIO pins.
+
+  	  To compile this driver as a module, choose M here: the
+	  module will be called hc-sr04.
+endmenu
drivers/iio/ultrasonic-distance/Makefile new file +6 -0
new file mode 100644
index 0000000..1f01d50c
@@ -0,0 +1,6 @@
+#
+# Makefile for IIO proximity sensors
+#
+
+# When adding new entries keep the list in alphabetical order
+obj-$(CONFIG_HC_SR04)		+= hc-sr04.o
drivers/iio/ultrasonic-distance/hc-sr04.c new file +460 -0

460 lines not on this page · raw message

Signature · 1 line
2.8.0-rc4
#4 lore raw

PATCH 1/1 HC-SR04 ultrasonic ranger IIO driver

Dear List,

I've ported my hc-sr04 driver to IIO now and wanted to ask if it is ok to post it to the
main kernel list (or some other list?) like this (see original mail, sent with git send-mail).

Thanks a lot,

- Johannes

#5 lore raw

PATCH 1/1 HC-SR04 ultrasonic ranger IIO driver

In reply to johannes at johannesthoma.com
Quoted 11 lines · johannes at johannesthoma.com

From: Johannes Thoma <[email protected]>

The HC-SR04 is an ultrasonic distance sensor attached to two GPIO pins. The driver based on Industrial I/O (iio) subsystem and is controlled via configfs and sysfs. It supports an (in theory) unlimited number of HC-SR04 devices.

Datasheet to the device can be found at:

http://www.micropik.com/PDF/HCSR04.pdf

Quoted 11 lines
---
 MAINTAINERS                               |   7 +
 drivers/iio/Kconfig                       |   1 +
 drivers/iio/Makefile                      |   1 +
 drivers/iio/ultrasonic-distance/Kconfig   |  16 ++
 drivers/iio/ultrasonic-distance/Makefile  |   6 +
 drivers/iio/ultrasonic-distance/hc-sr04.c | 460 ++++++++++++++++++++++++++++++
 6 files changed, 491 insertions(+)
 create mode 100644 drivers/iio/ultrasonic-distance/Kconfig
 create mode 100644 drivers/iio/ultrasonic-distance/Makefile
 create mode 100644 drivers/iio/ultrasonic-distance/hc-sr04.c

Hint, use scripts/get_maintainer.pl to find the correct mailing list and developers to send this patch to, in order to ensure the correct people who can apply it, receive it.

thanks,

greg k-h

#6 lore raw

PATCH 1/1 HC-SR04 ultrasonic ranger IIO driver

In reply to johannes at johannesthoma.com

On Tue, 31 May 2016 23:05:57 +0200, johannes at johannesthoma.com said:

Looks good overall, far from the ugliest driver I've seen. I spotted one locking bug, and a few small typos etc, noted inline...

Quoted 4 lines

From: Johannes Thoma <[email protected]>

The HC-SR04 is an ultrasonic distance sensor attached to two GPIO pins. The driver based on Industrial I/O (iio) subsystem and is

The driver is based on the Industrial...

Quoted 5 lines

+ * To configure a device do a
+ *
+ * mkdir /config/iio/triggers/hc-sr04/sensor0
+ *
+ * (you need to mount configfs to /config first)

Most distros seem to be using /sys/kernel/config as the mount point for this...

Quoted 3 lines

+ * Then you can measure distance with:
+ *
+ * cat /sys/devices/trigger0/measure

What are the units of the returned value? Inches? Hundredths of an inch?
inches.hundredths? Other?

(Yes, I looked at the datasheet.. and your driver source is more helpful than the sheed :)

drivers/iio/ultrasonic-distance/hc-sr04.c line 81

Quoted 2 lines
drivers/iio/ultrasonic-distance/hc-sr04.c new file +2 -0
+	struct gpio_desc *echo_desc;
+		/* Used to measure length of ECHO signal */

I was going to say "comments on same line", but that would result in *long* lines, this is better....

Quoted 3 lines
drivers/iio/ultrasonic-distance/hc-sr04.c new file +3 -0
+static int do_measurement(struct hc_sr04 *device,
+			  long long *usecs_elapsed)
+{

(...)

drivers/iio/ultrasonic-distance/hc-sr04.c line 144

Quoted 2 lines
drivers/iio/ultrasonic-distance/hc-sr04.c new file +2 -0
+	if (!mutex_trylock(&device->measurement_mutex))
+		return -EBUSY;

OK... this is a potential problem, because...

drivers/iio/ultrasonic-distance/hc-sr04.c line 164

Quoted 3 lines
drivers/iio/ultrasonic-distance/hc-sr04.c new file +3 -0
+	irq = gpiod_to_irq(device->echo_desc);
+	if (irq < 0)
+		return -EIO;

Here you do a 'return' without unlocking. This should probably be:

         if (irq < 0) {
		ret = -EIO;
		goto out_mutex;
	}

I admit not knowing the GPIO or IIO stuff well enough to comment on those details, but I didn't see anything obviously insane either....

#7 lore raw

PATCH 1/1 HC-SR04 ultrasonic ranger IIO driver

In reply to johannes at johannesthoma.com
Quoted 11 lines · On Wed, Jun 1, 2016 at 12:05 AM, <[email protected]> wrote:

From: Johannes Thoma <[email protected]>

The HC-SR04 is an ultrasonic distance sensor attached to two GPIO pins. The driver based on Industrial I/O (iio) subsystem and is controlled via configfs and sysfs. It supports an (in theory) unlimited number of HC-SR04 devices.

Datasheet to the device can be found at:

http://www.micropik.com/PDF/HCSR04.pdf

Please send this to the linux-iio mailing list (linux-iio at vger.kernel.org )

thanks,
Daniel.

#8 lore raw

PATCH 1/1 misc devices: HC-SRO4 ultrasonic distance driver

In reply to Johannes Thoma
Quoted 5 lines · Johannes Thoma

From 56e8f71c990b92c28a8cb03d859880eab8d06a3d Mon Sep 17 00:00:00 2001
From: Johannes Thoma <[email protected]>
Date: Mon, 21 Mar 2016 22:11:01 +0100
Subject: [PATCH] HC-SRO4 ultrasonic distance sensor driver

Quoted 8 lines

The HC-SRO4 is an ultrasonic distance sensor attached to two GPIO pins. The driver is controlled via sysfs and supports an (in theory) unlimited number of HC-SRO4 devices.

Unlike user land solutions this driver produces precise results even when there is high load on the system. It uses a non-blocking interrupt triggered mechanism to record the length of the echo signal.

Add link to datasheet.

Quoted 10 lines

This patch is against the raspberry pi kernel from
https://github.com/raspberrypi/linux.git hash e481b5ceae6c94c7e60f8bb8591cbb362806246e

Note that this patch isn't meant for lkml (yet) see:
TODO's:

.) Patch against mainline (or whatever kernel it belongs to) .) Use IIO layer instead of creating random sysfs entries.

So, why aren't you directly using IIO? :)

Also run ./scripts/checkpatch.pl --strict your.patch.

thanks,
Daniel.

#9 lore raw

PATCH 1/1 misc devices: HC-SRO4 ultrasonic distance driver

Dear Greg, dear Daniel,

Thank you for your suggestions, I will port the driver to IIO layer as you suggested and then get back (may take some days). I will also use git-send-mail, since that seems to be the best way to do it.

Am 24.03.16 um 16:52 schrieb Daniel Baluta:

Quoted 11 lines
Quoted 9 lines · Johannes Thoma

From 56e8f71c990b92c28a8cb03d859880eab8d06a3d Mon Sep 17 00:00:00 2001
From: Johannes Thoma <[email protected]>
Date: Mon, 21 Mar 2016 22:11:01 +0100
Subject: [PATCH] HC-SRO4 ultrasonic distance sensor driver

The HC-SRO4 is an ultrasonic distance sensor attached to two GPIO pins. The driver is controlled via sysfs and supports an (in theory) unlimited number of HC-SRO4 devices.

Quoted 6 lines
Quoted 4 lines

Unlike user land solutions this driver produces precise results even when there is high load on the system. It uses a non-blocking interrupt triggered mechanism to record the length of the echo signal.

Add link to datasheet.

One location is:

http://www.micropik.com/PDF/HCSR04.pdf

Quoted 5 lines
Quoted 5 lines

This patch is against the raspberry pi kernel from
https://github.com/raspberrypi/linux.git hash e481b5ceae6c94c7e60f8bb8591cbb362806246e

Quoted 8 lines
Quoted 5 lines

Note that this patch isn't meant for lkml (yet) see:
TODO's:

.) Patch against mainline (or whatever kernel it belongs to) .) Use IIO layer instead of creating random sysfs entries.

So, why aren't you directly using IIO? :)

I will but I just got the hint from greg that I should do so (didn't know about it ;).

all the best,

- Johannes