]> asedeno.scripts.mit.edu Git - linux.git/blobdiff - drivers/iio/humidity/dht11.c
Merge branches 'pm-core', 'pm-qos', 'pm-domains' and 'pm-opp'
[linux.git] / drivers / iio / humidity / dht11.c
index 20b500da94db3f5914cd7e0e2c1118f2a47ec979..2a22ad92033306d02eec60f288c00a65d5186c37 100644 (file)
@@ -71,7 +71,8 @@
  * a) select an implementation using busy loop polling on those systems
  * b) use the checksum to do some probabilistic decoding
  */
-#define DHT11_START_TRANSMISSION       18  /* ms */
+#define DHT11_START_TRANSMISSION_MIN   18000  /* us */
+#define DHT11_START_TRANSMISSION_MAX   20000  /* us */
 #define DHT11_MIN_TIMERES      34000  /* ns */
 #define DHT11_THRESHOLD                49000  /* ns */
 #define DHT11_AMBIG_LOW                23000  /* ns */
@@ -96,6 +97,24 @@ struct dht11 {
        struct {s64 ts; int value; }    edges[DHT11_EDGES_PER_READ];
 };
 
+#ifdef CONFIG_DYNAMIC_DEBUG
+/*
+ * dht11_edges_print: show the data as actually received by the
+ *                    driver.
+ */
+static void dht11_edges_print(struct dht11 *dht11)
+{
+       int i;
+
+       dev_dbg(dht11->dev, "%d edges detected:\n", dht11->num_edges);
+       for (i = 1; i < dht11->num_edges; ++i) {
+               dev_dbg(dht11->dev, "%d: %lld ns %s\n", i,
+                       dht11->edges[i].ts - dht11->edges[i - 1].ts,
+                       dht11->edges[i - 1].value ? "high" : "low");
+       }
+}
+#endif /* CONFIG_DYNAMIC_DEBUG */
+
 static unsigned char dht11_decode_byte(char *bits)
 {
        unsigned char ret = 0;
@@ -119,8 +138,12 @@ static int dht11_decode(struct dht11 *dht11, int offset)
        for (i = 0; i < DHT11_BITS_PER_READ; ++i) {
                t = dht11->edges[offset + 2 * i + 2].ts -
                        dht11->edges[offset + 2 * i + 1].ts;
-               if (!dht11->edges[offset + 2 * i + 1].value)
-                       return -EIO;  /* lost synchronisation */
+               if (!dht11->edges[offset + 2 * i + 1].value) {
+                       dev_dbg(dht11->dev,
+                               "lost synchronisation at edge %d\n",
+                               offset + 2 * i + 1);
+                       return -EIO;
+               }
                bits[i] = t > DHT11_THRESHOLD;
        }
 
@@ -130,8 +153,10 @@ static int dht11_decode(struct dht11 *dht11, int offset)
        temp_dec = dht11_decode_byte(&bits[24]);
        checksum = dht11_decode_byte(&bits[32]);
 
-       if (((hum_int + hum_dec + temp_int + temp_dec) & 0xff) != checksum)
+       if (((hum_int + hum_dec + temp_int + temp_dec) & 0xff) != checksum) {
+               dev_dbg(dht11->dev, "invalid checksum\n");
                return -EIO;
+       }
 
        dht11->timestamp = ktime_get_boot_ns();
        if (hum_int < 20) {  /* DHT22 */
@@ -182,6 +207,7 @@ static int dht11_read_raw(struct iio_dev *iio_dev,
        mutex_lock(&dht11->lock);
        if (dht11->timestamp + DHT11_DATA_VALID_TIME < ktime_get_boot_ns()) {
                timeres = ktime_get_resolution_ns();
+               dev_dbg(dht11->dev, "current timeresolution: %dns\n", timeres);
                if (timeres > DHT11_MIN_TIMERES) {
                        dev_err(dht11->dev, "timeresolution %dns too low\n",
                                timeres);
@@ -203,7 +229,8 @@ static int dht11_read_raw(struct iio_dev *iio_dev,
                ret = gpio_direction_output(dht11->gpio, 0);
                if (ret)
                        goto err;
-               msleep(DHT11_START_TRANSMISSION);
+               usleep_range(DHT11_START_TRANSMISSION_MIN,
+                            DHT11_START_TRANSMISSION_MAX);
                ret = gpio_direction_input(dht11->gpio);
                if (ret)
                        goto err;
@@ -219,10 +246,13 @@ static int dht11_read_raw(struct iio_dev *iio_dev,
 
                free_irq(dht11->irq, iio_dev);
 
+#ifdef CONFIG_DYNAMIC_DEBUG
+               dht11_edges_print(dht11);
+#endif
+
                if (ret == 0 && dht11->num_edges < DHT11_EDGES_PER_READ - 1) {
-                       dev_err(&iio_dev->dev,
-                               "Only %d signal edges detected\n",
-                                       dht11->num_edges);
+                       dev_err(dht11->dev, "Only %d signal edges detected\n",
+                               dht11->num_edges);
                        ret = -ETIMEDOUT;
                }
                if (ret < 0)