diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2015-08-31 19:24:06 +0300 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2015-08-31 19:24:06 +0300 |
commit | 2f37d65a6a5c360ba0c386a6aa0d2afcbda7060d (patch) | |
tree | a2c0ab8b6d7fd7ea57d0140f22a79337064d761e /drivers/iio/humidity/dht11.c | |
parent | 1af115d675f323afee1e64650277a9b170845b81 (diff) | |
parent | 415bcb5c6eff630967baa4e671cebe883d83ee79 (diff) | |
download | linux-2f37d65a6a5c360ba0c386a6aa0d2afcbda7060d.tar.xz |
Merge tag 'staging-4.3-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/staging
Pull staging driver updates from Greg KH:
"Here is the big staging driver updates for 4.3-rc1.
Lots of things all over the place, almost all of them trivial fixups
and changes. The usual IIO updates and new drivers and we have added
the MOST driver subsystem which is getting cleaned up in the tree.
The ozwpan driver is finally being deleted as it is obviously
abandoned and no one cares about it.
Full details are in the shortlog, and all of these have been in
linux-next with no reported issues"
* tag 'staging-4.3-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/staging: (912 commits)
staging/lustre/o2iblnd: remove references to ib_reg_phsy_mr()
staging: wilc1000: fix build warning with setup_timer()
staging: wilc1000: remove DECLARE_WILC_BUFFER()
staging: wilc1000: remove void function return statements that are not useful
staging: wilc1000: coreconfigurator.c: fix kmalloc error check
staging: wilc1000: coreconfigurator.c: use kmalloc instead of WILC_MALLOC
staging: wilc1000: remove unused codes of gps8ConfigPacket
staging: wilc1000: remove unnecessary void pointer cast
staging: wilc1000: remove WILC_NEW and WILC_NEW_EX
staging: wilc1000: use kmalloc instead of WILC_NEW
staging: wilc1000: Process WARN, INFO options of debug levels from user
staging: wilc1000: remove unneeded tstrWILC_MsgQueueAttrs typedef
staging: wilc1000: delete wilc_osconfig.h
staging: wilc1000: delete wilc_log.h
staging: wilc1000: delete wilc_timer.h
staging: wilc1000: remove WILC_TimerStart()
staging: wilc1000: remove WILC_TimerCreate()
staging: wilc1000: remove WILC_TimerDestroy()
staging: wilc1000: remove WILC_TimerStop()
staging: wilc1000: remove tstrWILC_TimerAttrs typedef
...
Diffstat (limited to 'drivers/iio/humidity/dht11.c')
-rw-r--r-- | drivers/iio/humidity/dht11.c | 65 |
1 files changed, 35 insertions, 30 deletions
diff --git a/drivers/iio/humidity/dht11.c b/drivers/iio/humidity/dht11.c index 7d79a1ac5f5f..1165b1c4f9d6 100644 --- a/drivers/iio/humidity/dht11.c +++ b/drivers/iio/humidity/dht11.c @@ -33,6 +33,7 @@ #include <linux/delay.h> #include <linux/gpio.h> #include <linux/of_gpio.h> +#include <linux/timekeeping.h> #include <linux/iio/iio.h> @@ -46,7 +47,8 @@ * Note that when reading the sensor actually 84 edges are detected, but * since the last edge is not significant, we only store 83: */ -#define DHT11_EDGES_PER_READ (2*DHT11_BITS_PER_READ + DHT11_EDGES_PREAMBLE + 1) +#define DHT11_EDGES_PER_READ (2 * DHT11_BITS_PER_READ + \ + DHT11_EDGES_PREAMBLE + 1) /* Data transmission timing (nano seconds) */ #define DHT11_START_TRANSMISSION 18 /* ms */ @@ -62,6 +64,7 @@ struct dht11 { int irq; struct completion completion; + /* The iio sysfs interface doesn't prevent concurrent reads: */ struct mutex lock; s64 timestamp; @@ -87,32 +90,20 @@ static unsigned char dht11_decode_byte(int *timing, int threshold) return ret; } -static int dht11_decode(struct dht11 *dht11, int offset) +static int dht11_decode(struct dht11 *dht11, int offset, int timeres) { - int i, t, timing[DHT11_BITS_PER_READ], threshold, - timeres = DHT11_SENSOR_RESPONSE; + int i, t, timing[DHT11_BITS_PER_READ], threshold; unsigned char temp_int, temp_dec, hum_int, hum_dec, checksum; - /* Calculate timestamp resolution */ - for (i = 1; i < dht11->num_edges; ++i) { - t = dht11->edges[i].ts - dht11->edges[i-1].ts; - if (t > 0 && t < timeres) - timeres = t; - } - if (2*timeres > DHT11_DATA_BIT_HIGH) { - pr_err("dht11: timeresolution %d too bad for decoding\n", - timeres); - return -EIO; - } threshold = DHT11_DATA_BIT_HIGH / timeres; - if (DHT11_DATA_BIT_LOW/timeres + 1 >= threshold) + if (DHT11_DATA_BIT_LOW / timeres + 1 >= threshold) pr_err("dht11: WARNING: decoding ambiguous\n"); /* scale down with timeres and check validity */ 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) + 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 */ timing[i] = t / timeres; } @@ -126,7 +117,7 @@ static int dht11_decode(struct dht11 *dht11, int offset) if (((hum_int + hum_dec + temp_int + temp_dec) & 0xff) != checksum) return -EIO; - dht11->timestamp = iio_get_time_ns(); + dht11->timestamp = ktime_get_real_ns(); if (hum_int < 20) { /* DHT22 */ dht11->temperature = (((temp_int & 0x7f) << 8) + temp_dec) * ((temp_int & 0x80) ? -100 : 100); @@ -154,7 +145,7 @@ static irqreturn_t dht11_handle_irq(int irq, void *data) /* TODO: Consider making the handler safe for IRQ sharing */ if (dht11->num_edges < DHT11_EDGES_PER_READ && dht11->num_edges >= 0) { - dht11->edges[dht11->num_edges].ts = iio_get_time_ns(); + dht11->edges[dht11->num_edges].ts = ktime_get_real_ns(); dht11->edges[dht11->num_edges++].value = gpio_get_value(dht11->gpio); @@ -166,14 +157,26 @@ static irqreturn_t dht11_handle_irq(int irq, void *data) } static int dht11_read_raw(struct iio_dev *iio_dev, - const struct iio_chan_spec *chan, + const struct iio_chan_spec *chan, int *val, int *val2, long m) { struct dht11 *dht11 = iio_priv(iio_dev); - int ret; + int ret, timeres; mutex_lock(&dht11->lock); - if (dht11->timestamp + DHT11_DATA_VALID_TIME < iio_get_time_ns()) { + if (dht11->timestamp + DHT11_DATA_VALID_TIME < ktime_get_real_ns()) { + timeres = ktime_get_resolution_ns(); + if (DHT11_DATA_BIT_HIGH < 2 * timeres) { + dev_err(dht11->dev, "timeresolution %dns too low\n", + timeres); + /* In theory a better clock could become available + * at some point ... and there is no error code + * that really fits better. + */ + ret = -EAGAIN; + goto err; + } + reinit_completion(&dht11->completion); dht11->num_edges = 0; @@ -192,13 +195,13 @@ static int dht11_read_raw(struct iio_dev *iio_dev, goto err; ret = wait_for_completion_killable_timeout(&dht11->completion, - HZ); + HZ); free_irq(dht11->irq, iio_dev); if (ret == 0 && dht11->num_edges < DHT11_EDGES_PER_READ - 1) { dev_err(&iio_dev->dev, - "Only %d signal edges detected\n", + "Only %d signal edges detected\n", dht11->num_edges); ret = -ETIMEDOUT; } @@ -206,9 +209,10 @@ static int dht11_read_raw(struct iio_dev *iio_dev, goto err; ret = dht11_decode(dht11, - dht11->num_edges == DHT11_EDGES_PER_READ ? + dht11->num_edges == DHT11_EDGES_PER_READ ? DHT11_EDGES_PREAMBLE : - DHT11_EDGES_PREAMBLE - 2); + DHT11_EDGES_PREAMBLE - 2, + timeres); if (ret) goto err; } @@ -261,9 +265,10 @@ static int dht11_probe(struct platform_device *pdev) dht11 = iio_priv(iio); dht11->dev = dev; - dht11->gpio = ret = of_get_gpio(node, 0); + ret = of_get_gpio(node, 0); if (ret < 0) return ret; + dht11->gpio = ret; ret = devm_gpio_request_one(dev, dht11->gpio, GPIOF_IN, pdev->name); if (ret) return ret; @@ -274,7 +279,7 @@ static int dht11_probe(struct platform_device *pdev) return -EINVAL; } - dht11->timestamp = iio_get_time_ns() - DHT11_DATA_VALID_TIME - 1; + dht11->timestamp = ktime_get_real_ns() - DHT11_DATA_VALID_TIME - 1; dht11->num_edges = -1; platform_set_drvdata(pdev, iio); |