Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

iio: Add new driver dht11

This driver handles DHT11 and DHT22 sensors.

Signed-off-by: Harald Geyer <harald@ccbib.org>
Signed-off-by: Jonathan Cameron <jic23@kernel.org>

authored by

Harald Geyer and committed by
Jonathan Cameron
091a121b ac216aa2

+330
+14
Documentation/devicetree/bindings/iio/humidity/dht11.txt
··· 1 + * DHT11 humidity/temperature sensor (and compatibles like DHT22) 2 + 3 + Required properties: 4 + - compatible: Should be "dht11" 5 + - gpios: Should specify the GPIO connected to the sensor's data 6 + line, see "gpios property" in 7 + Documentation/devicetree/bindings/gpio/gpio.txt. 8 + 9 + Example: 10 + 11 + humidity_sensor { 12 + compatible = "dht11"; 13 + gpios = <&gpio0 6 0>; 14 + }
+1
drivers/iio/Kconfig
··· 65 65 source "drivers/iio/dac/Kconfig" 66 66 source "drivers/iio/frequency/Kconfig" 67 67 source "drivers/iio/gyro/Kconfig" 68 + source "drivers/iio/humidity/Kconfig" 68 69 source "drivers/iio/imu/Kconfig" 69 70 source "drivers/iio/light/Kconfig" 70 71 source "drivers/iio/magnetometer/Kconfig"
+1
drivers/iio/Makefile
··· 18 18 obj-y += dac/ 19 19 obj-y += gyro/ 20 20 obj-y += frequency/ 21 + obj-y += humidity/ 21 22 obj-y += imu/ 22 23 obj-y += light/ 23 24 obj-y += magnetometer/
+15
drivers/iio/humidity/Kconfig
··· 1 + # 2 + # humidity sensor drivers 3 + # 4 + menu "Humidity sensors" 5 + 6 + config DHT11 7 + tristate "DHT11 (and compatible sensors) driver" 8 + depends on GPIOLIB 9 + help 10 + This driver supports reading data via a single interrupt 11 + generating GPIO line. Currently tested are DHT11 and DHT22. 12 + Other sensors should work as well as long as they speak the 13 + same protocol. 14 + 15 + endmenu
+5
drivers/iio/humidity/Makefile
··· 1 + # 2 + # Makefile for IIO humidity sensor drivers 3 + # 4 + 5 + obj-$(CONFIG_DHT11) += dht11.o
+294
drivers/iio/humidity/dht11.c
··· 1 + /* 2 + * DHT11/DHT22 bit banging GPIO driver 3 + * 4 + * Copyright (c) Harald Geyer <harald@ccbib.org> 5 + * 6 + * This program is free software; you can redistribute it and/or modify 7 + * it under the terms of the GNU General Public License as published by 8 + * the Free Software Foundation; either version 2 of the License, or 9 + * (at your option) any later version. 10 + * 11 + * This program is distributed in the hope that it will be useful, 12 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 + * GNU General Public License for more details. 15 + */ 16 + 17 + #include <linux/err.h> 18 + #include <linux/interrupt.h> 19 + #include <linux/device.h> 20 + #include <linux/kernel.h> 21 + #include <linux/printk.h> 22 + #include <linux/slab.h> 23 + #include <linux/of.h> 24 + #include <linux/of_device.h> 25 + #include <linux/sysfs.h> 26 + #include <linux/io.h> 27 + #include <linux/module.h> 28 + #include <linux/platform_device.h> 29 + #include <linux/wait.h> 30 + #include <linux/bitops.h> 31 + #include <linux/completion.h> 32 + #include <linux/delay.h> 33 + #include <linux/gpio.h> 34 + #include <linux/of_gpio.h> 35 + 36 + #include <linux/iio/iio.h> 37 + 38 + #define DRIVER_NAME "dht11" 39 + 40 + #define DHT11_DATA_VALID_TIME 2000000000 /* 2s in ns */ 41 + 42 + #define DHT11_EDGES_PREAMBLE 4 43 + #define DHT11_BITS_PER_READ 40 44 + #define DHT11_EDGES_PER_READ (2*DHT11_BITS_PER_READ + DHT11_EDGES_PREAMBLE + 1) 45 + 46 + /* Data transmission timing (nano seconds) */ 47 + #define DHT11_START_TRANSMISSION 18 /* ms */ 48 + #define DHT11_SENSOR_RESPONSE 80000 49 + #define DHT11_START_BIT 50000 50 + #define DHT11_DATA_BIT_LOW 27000 51 + #define DHT11_DATA_BIT_HIGH 70000 52 + 53 + struct dht11 { 54 + struct device *dev; 55 + 56 + int gpio; 57 + int irq; 58 + 59 + struct completion completion; 60 + 61 + s64 timestamp; 62 + int temperature; 63 + int humidity; 64 + 65 + /* num_edges: -1 means "no transmission in progress" */ 66 + int num_edges; 67 + struct {s64 ts; int value; } edges[DHT11_EDGES_PER_READ]; 68 + }; 69 + 70 + static unsigned char dht11_decode_byte(int *timing, int threshold) 71 + { 72 + unsigned char ret = 0; 73 + int i; 74 + 75 + for (i = 0; i < 8; ++i) { 76 + ret <<= 1; 77 + if (timing[i] >= threshold) 78 + ++ret; 79 + } 80 + 81 + return ret; 82 + } 83 + 84 + static int dht11_decode(struct dht11 *dht11, int offset) 85 + { 86 + int i, t, timing[DHT11_BITS_PER_READ], threshold, 87 + timeres = DHT11_SENSOR_RESPONSE; 88 + unsigned char temp_int, temp_dec, hum_int, hum_dec, checksum; 89 + 90 + /* Calculate timestamp resolution */ 91 + for (i = 0; i < dht11->num_edges; ++i) { 92 + t = dht11->edges[i].ts - dht11->edges[i-1].ts; 93 + if (t > 0 && t < timeres) 94 + timeres = t; 95 + } 96 + if (2*timeres > DHT11_DATA_BIT_HIGH) { 97 + pr_err("dht11: timeresolution %d too bad for decoding\n", 98 + timeres); 99 + return -EIO; 100 + } 101 + threshold = DHT11_DATA_BIT_HIGH / timeres; 102 + if (DHT11_DATA_BIT_LOW/timeres + 1 >= threshold) 103 + pr_err("dht11: WARNING: decoding ambiguous\n"); 104 + 105 + /* scale down with timeres and check validity */ 106 + for (i = 0; i < DHT11_BITS_PER_READ; ++i) { 107 + t = dht11->edges[offset + 2*i + 2].ts - 108 + dht11->edges[offset + 2*i + 1].ts; 109 + if (!dht11->edges[offset + 2*i + 1].value) 110 + return -EIO; /* lost synchronisation */ 111 + timing[i] = t / timeres; 112 + } 113 + 114 + hum_int = dht11_decode_byte(timing, threshold); 115 + hum_dec = dht11_decode_byte(&timing[8], threshold); 116 + temp_int = dht11_decode_byte(&timing[16], threshold); 117 + temp_dec = dht11_decode_byte(&timing[24], threshold); 118 + checksum = dht11_decode_byte(&timing[32], threshold); 119 + 120 + if (((hum_int + hum_dec + temp_int + temp_dec) & 0xff) != checksum) 121 + return -EIO; 122 + 123 + dht11->timestamp = iio_get_time_ns(); 124 + if (hum_int < 20) { /* DHT22 */ 125 + dht11->temperature = (((temp_int & 0x7f) << 8) + temp_dec) * 126 + ((temp_int & 0x80) ? -100 : 100); 127 + dht11->humidity = ((hum_int << 8) + hum_dec) * 100; 128 + } else if (temp_dec == 0 && hum_dec == 0) { /* DHT11 */ 129 + dht11->temperature = temp_int * 1000; 130 + dht11->humidity = hum_int * 1000; 131 + } else { 132 + dev_err(dht11->dev, 133 + "Don't know how to decode data: %d %d %d %d\n", 134 + hum_int, hum_dec, temp_int, temp_dec); 135 + return -EIO; 136 + } 137 + 138 + return 0; 139 + } 140 + 141 + static int dht11_read_raw(struct iio_dev *iio_dev, 142 + const struct iio_chan_spec *chan, 143 + int *val, int *val2, long m) 144 + { 145 + struct dht11 *dht11 = iio_priv(iio_dev); 146 + int ret; 147 + 148 + if (dht11->timestamp + DHT11_DATA_VALID_TIME < iio_get_time_ns()) { 149 + reinit_completion(&dht11->completion); 150 + 151 + dht11->num_edges = 0; 152 + ret = gpio_direction_output(dht11->gpio, 0); 153 + if (ret) 154 + goto err; 155 + msleep(DHT11_START_TRANSMISSION); 156 + ret = gpio_direction_input(dht11->gpio); 157 + if (ret) 158 + goto err; 159 + 160 + ret = wait_for_completion_killable_timeout(&dht11->completion, 161 + HZ); 162 + if (ret == 0 && dht11->num_edges < DHT11_EDGES_PER_READ - 1) { 163 + dev_err(&iio_dev->dev, 164 + "Only %d signal edges detected\n", 165 + dht11->num_edges); 166 + ret = -ETIMEDOUT; 167 + } 168 + if (ret < 0) 169 + goto err; 170 + 171 + ret = dht11_decode(dht11, 172 + dht11->num_edges == DHT11_EDGES_PER_READ ? 173 + DHT11_EDGES_PREAMBLE : 174 + DHT11_EDGES_PREAMBLE - 2); 175 + if (ret) 176 + goto err; 177 + } 178 + 179 + ret = IIO_VAL_INT; 180 + if (chan->type == IIO_TEMP) 181 + *val = dht11->temperature; 182 + else if (chan->type == IIO_HUMIDITYRELATIVE) 183 + *val = dht11->humidity; 184 + else 185 + ret = -EINVAL; 186 + err: 187 + dht11->num_edges = -1; 188 + return ret; 189 + } 190 + 191 + static const struct iio_info dht11_iio_info = { 192 + .driver_module = THIS_MODULE, 193 + .read_raw = dht11_read_raw, 194 + }; 195 + 196 + /* 197 + * IRQ handler called on GPIO edges 198 + */ 199 + static irqreturn_t dht11_handle_irq(int irq, void *data) 200 + { 201 + struct iio_dev *iio = data; 202 + struct dht11 *dht11 = iio_priv(iio); 203 + 204 + /* TODO: Consider making the handler safe for IRQ sharing */ 205 + if (dht11->num_edges < DHT11_EDGES_PER_READ && dht11->num_edges >= 0) { 206 + dht11->edges[dht11->num_edges].ts = iio_get_time_ns(); 207 + dht11->edges[dht11->num_edges++].value = 208 + gpio_get_value(dht11->gpio); 209 + 210 + if (dht11->num_edges >= DHT11_EDGES_PER_READ) 211 + complete(&dht11->completion); 212 + } 213 + 214 + return IRQ_HANDLED; 215 + } 216 + 217 + static const struct iio_chan_spec dht11_chan_spec[] = { 218 + { .type = IIO_TEMP, 219 + .info_mask_separate = BIT(IIO_CHAN_INFO_PROCESSED), }, 220 + { .type = IIO_HUMIDITYRELATIVE, 221 + .info_mask_separate = BIT(IIO_CHAN_INFO_PROCESSED), } 222 + }; 223 + 224 + static const struct of_device_id dht11_dt_ids[] = { 225 + { .compatible = "dht11", }, 226 + { } 227 + }; 228 + MODULE_DEVICE_TABLE(of, dht11_dt_ids); 229 + 230 + static int dht11_probe(struct platform_device *pdev) 231 + { 232 + struct device *dev = &pdev->dev; 233 + struct device_node *node = dev->of_node; 234 + struct dht11 *dht11; 235 + struct iio_dev *iio; 236 + int ret; 237 + 238 + iio = devm_iio_device_alloc(dev, sizeof(*dht11)); 239 + if (!iio) { 240 + dev_err(dev, "Failed to allocate IIO device\n"); 241 + return -ENOMEM; 242 + } 243 + 244 + dht11 = iio_priv(iio); 245 + dht11->dev = dev; 246 + 247 + dht11->gpio = ret = of_get_gpio(node, 0); 248 + if (ret < 0) 249 + return ret; 250 + ret = devm_gpio_request_one(dev, dht11->gpio, GPIOF_IN, pdev->name); 251 + if (ret) 252 + return ret; 253 + 254 + dht11->irq = gpio_to_irq(dht11->gpio); 255 + if (dht11->irq < 0) { 256 + dev_err(dev, "GPIO %d has no interrupt\n", dht11->gpio); 257 + return -EINVAL; 258 + } 259 + ret = devm_request_irq(dev, dht11->irq, dht11_handle_irq, 260 + IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING, 261 + pdev->name, iio); 262 + if (ret) 263 + return ret; 264 + 265 + dht11->timestamp = iio_get_time_ns() - DHT11_DATA_VALID_TIME - 1; 266 + dht11->num_edges = -1; 267 + 268 + platform_set_drvdata(pdev, iio); 269 + 270 + init_completion(&dht11->completion); 271 + iio->name = pdev->name; 272 + iio->dev.parent = &pdev->dev; 273 + iio->info = &dht11_iio_info; 274 + iio->modes = INDIO_DIRECT_MODE; 275 + iio->channels = dht11_chan_spec; 276 + iio->num_channels = ARRAY_SIZE(dht11_chan_spec); 277 + 278 + return devm_iio_device_register(dev, iio); 279 + } 280 + 281 + static struct platform_driver dht11_driver = { 282 + .driver = { 283 + .name = DRIVER_NAME, 284 + .owner = THIS_MODULE, 285 + .of_match_table = dht11_dt_ids, 286 + }, 287 + .probe = dht11_probe, 288 + }; 289 + 290 + module_platform_driver(dht11_driver); 291 + 292 + MODULE_AUTHOR("Harald Geyer <harald@ccbib.org>"); 293 + MODULE_DESCRIPTION("DHT11 humidity/temperature sensor driver"); 294 + MODULE_LICENSE("GPL v2");