···11+* DHT11 humidity/temperature sensor (and compatibles like DHT22)22+33+Required properties:44+ - compatible: Should be "dht11"55+ - gpios: Should specify the GPIO connected to the sensor's data66+ line, see "gpios property" in77+ Documentation/devicetree/bindings/gpio/gpio.txt.88+99+Example:1010+1111+humidity_sensor {1212+ compatible = "dht11";1313+ gpios = <&gpio0 6 0>;1414+}
···11+#22+# humidity sensor drivers33+#44+menu "Humidity sensors"55+66+config DHT1177+ tristate "DHT11 (and compatible sensors) driver"88+ depends on GPIOLIB99+ help1010+ This driver supports reading data via a single interrupt1111+ generating GPIO line. Currently tested are DHT11 and DHT22.1212+ Other sensors should work as well as long as they speak the1313+ same protocol.1414+1515+endmenu
+5
drivers/iio/humidity/Makefile
···11+#22+# Makefile for IIO humidity sensor drivers33+#44+55+obj-$(CONFIG_DHT11) += dht11.o
+294
drivers/iio/humidity/dht11.c
···11+/*22+ * DHT11/DHT22 bit banging GPIO driver33+ *44+ * Copyright (c) Harald Geyer <harald@ccbib.org>55+ *66+ * This program is free software; you can redistribute it and/or modify77+ * it under the terms of the GNU General Public License as published by88+ * the Free Software Foundation; either version 2 of the License, or99+ * (at your option) any later version.1010+ *1111+ * This program is distributed in the hope that it will be useful,1212+ * but WITHOUT ANY WARRANTY; without even the implied warranty of1313+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the1414+ * GNU General Public License for more details.1515+ */1616+1717+#include <linux/err.h>1818+#include <linux/interrupt.h>1919+#include <linux/device.h>2020+#include <linux/kernel.h>2121+#include <linux/printk.h>2222+#include <linux/slab.h>2323+#include <linux/of.h>2424+#include <linux/of_device.h>2525+#include <linux/sysfs.h>2626+#include <linux/io.h>2727+#include <linux/module.h>2828+#include <linux/platform_device.h>2929+#include <linux/wait.h>3030+#include <linux/bitops.h>3131+#include <linux/completion.h>3232+#include <linux/delay.h>3333+#include <linux/gpio.h>3434+#include <linux/of_gpio.h>3535+3636+#include <linux/iio/iio.h>3737+3838+#define DRIVER_NAME "dht11"3939+4040+#define DHT11_DATA_VALID_TIME 2000000000 /* 2s in ns */4141+4242+#define DHT11_EDGES_PREAMBLE 44343+#define DHT11_BITS_PER_READ 404444+#define DHT11_EDGES_PER_READ (2*DHT11_BITS_PER_READ + DHT11_EDGES_PREAMBLE + 1)4545+4646+/* Data transmission timing (nano seconds) */4747+#define DHT11_START_TRANSMISSION 18 /* ms */4848+#define DHT11_SENSOR_RESPONSE 800004949+#define DHT11_START_BIT 500005050+#define DHT11_DATA_BIT_LOW 270005151+#define DHT11_DATA_BIT_HIGH 700005252+5353+struct dht11 {5454+ struct device *dev;5555+5656+ int gpio;5757+ int irq;5858+5959+ struct completion completion;6060+6161+ s64 timestamp;6262+ int temperature;6363+ int humidity;6464+6565+ /* num_edges: -1 means "no transmission in progress" */6666+ int num_edges;6767+ struct {s64 ts; int value; } edges[DHT11_EDGES_PER_READ];6868+};6969+7070+static unsigned char dht11_decode_byte(int *timing, int threshold)7171+{7272+ unsigned char ret = 0;7373+ int i;7474+7575+ for (i = 0; i < 8; ++i) {7676+ ret <<= 1;7777+ if (timing[i] >= threshold)7878+ ++ret;7979+ }8080+8181+ return ret;8282+}8383+8484+static int dht11_decode(struct dht11 *dht11, int offset)8585+{8686+ int i, t, timing[DHT11_BITS_PER_READ], threshold,8787+ timeres = DHT11_SENSOR_RESPONSE;8888+ unsigned char temp_int, temp_dec, hum_int, hum_dec, checksum;8989+9090+ /* Calculate timestamp resolution */9191+ for (i = 0; i < dht11->num_edges; ++i) {9292+ t = dht11->edges[i].ts - dht11->edges[i-1].ts;9393+ if (t > 0 && t < timeres)9494+ timeres = t;9595+ }9696+ if (2*timeres > DHT11_DATA_BIT_HIGH) {9797+ pr_err("dht11: timeresolution %d too bad for decoding\n",9898+ timeres);9999+ return -EIO;100100+ }101101+ threshold = DHT11_DATA_BIT_HIGH / timeres;102102+ if (DHT11_DATA_BIT_LOW/timeres + 1 >= threshold)103103+ pr_err("dht11: WARNING: decoding ambiguous\n");104104+105105+ /* scale down with timeres and check validity */106106+ for (i = 0; i < DHT11_BITS_PER_READ; ++i) {107107+ t = dht11->edges[offset + 2*i + 2].ts -108108+ dht11->edges[offset + 2*i + 1].ts;109109+ if (!dht11->edges[offset + 2*i + 1].value)110110+ return -EIO; /* lost synchronisation */111111+ timing[i] = t / timeres;112112+ }113113+114114+ hum_int = dht11_decode_byte(timing, threshold);115115+ hum_dec = dht11_decode_byte(&timing[8], threshold);116116+ temp_int = dht11_decode_byte(&timing[16], threshold);117117+ temp_dec = dht11_decode_byte(&timing[24], threshold);118118+ checksum = dht11_decode_byte(&timing[32], threshold);119119+120120+ if (((hum_int + hum_dec + temp_int + temp_dec) & 0xff) != checksum)121121+ return -EIO;122122+123123+ dht11->timestamp = iio_get_time_ns();124124+ if (hum_int < 20) { /* DHT22 */125125+ dht11->temperature = (((temp_int & 0x7f) << 8) + temp_dec) *126126+ ((temp_int & 0x80) ? -100 : 100);127127+ dht11->humidity = ((hum_int << 8) + hum_dec) * 100;128128+ } else if (temp_dec == 0 && hum_dec == 0) { /* DHT11 */129129+ dht11->temperature = temp_int * 1000;130130+ dht11->humidity = hum_int * 1000;131131+ } else {132132+ dev_err(dht11->dev,133133+ "Don't know how to decode data: %d %d %d %d\n",134134+ hum_int, hum_dec, temp_int, temp_dec);135135+ return -EIO;136136+ }137137+138138+ return 0;139139+}140140+141141+static int dht11_read_raw(struct iio_dev *iio_dev,142142+ const struct iio_chan_spec *chan,143143+ int *val, int *val2, long m)144144+{145145+ struct dht11 *dht11 = iio_priv(iio_dev);146146+ int ret;147147+148148+ if (dht11->timestamp + DHT11_DATA_VALID_TIME < iio_get_time_ns()) {149149+ reinit_completion(&dht11->completion);150150+151151+ dht11->num_edges = 0;152152+ ret = gpio_direction_output(dht11->gpio, 0);153153+ if (ret)154154+ goto err;155155+ msleep(DHT11_START_TRANSMISSION);156156+ ret = gpio_direction_input(dht11->gpio);157157+ if (ret)158158+ goto err;159159+160160+ ret = wait_for_completion_killable_timeout(&dht11->completion,161161+ HZ);162162+ if (ret == 0 && dht11->num_edges < DHT11_EDGES_PER_READ - 1) {163163+ dev_err(&iio_dev->dev,164164+ "Only %d signal edges detected\n",165165+ dht11->num_edges);166166+ ret = -ETIMEDOUT;167167+ }168168+ if (ret < 0)169169+ goto err;170170+171171+ ret = dht11_decode(dht11,172172+ dht11->num_edges == DHT11_EDGES_PER_READ ?173173+ DHT11_EDGES_PREAMBLE :174174+ DHT11_EDGES_PREAMBLE - 2);175175+ if (ret)176176+ goto err;177177+ }178178+179179+ ret = IIO_VAL_INT;180180+ if (chan->type == IIO_TEMP)181181+ *val = dht11->temperature;182182+ else if (chan->type == IIO_HUMIDITYRELATIVE)183183+ *val = dht11->humidity;184184+ else185185+ ret = -EINVAL;186186+err:187187+ dht11->num_edges = -1;188188+ return ret;189189+}190190+191191+static const struct iio_info dht11_iio_info = {192192+ .driver_module = THIS_MODULE,193193+ .read_raw = dht11_read_raw,194194+};195195+196196+/*197197+ * IRQ handler called on GPIO edges198198+*/199199+static irqreturn_t dht11_handle_irq(int irq, void *data)200200+{201201+ struct iio_dev *iio = data;202202+ struct dht11 *dht11 = iio_priv(iio);203203+204204+ /* TODO: Consider making the handler safe for IRQ sharing */205205+ if (dht11->num_edges < DHT11_EDGES_PER_READ && dht11->num_edges >= 0) {206206+ dht11->edges[dht11->num_edges].ts = iio_get_time_ns();207207+ dht11->edges[dht11->num_edges++].value =208208+ gpio_get_value(dht11->gpio);209209+210210+ if (dht11->num_edges >= DHT11_EDGES_PER_READ)211211+ complete(&dht11->completion);212212+ }213213+214214+ return IRQ_HANDLED;215215+}216216+217217+static const struct iio_chan_spec dht11_chan_spec[] = {218218+ { .type = IIO_TEMP,219219+ .info_mask_separate = BIT(IIO_CHAN_INFO_PROCESSED), },220220+ { .type = IIO_HUMIDITYRELATIVE,221221+ .info_mask_separate = BIT(IIO_CHAN_INFO_PROCESSED), }222222+};223223+224224+static const struct of_device_id dht11_dt_ids[] = {225225+ { .compatible = "dht11", },226226+ { }227227+};228228+MODULE_DEVICE_TABLE(of, dht11_dt_ids);229229+230230+static int dht11_probe(struct platform_device *pdev)231231+{232232+ struct device *dev = &pdev->dev;233233+ struct device_node *node = dev->of_node;234234+ struct dht11 *dht11;235235+ struct iio_dev *iio;236236+ int ret;237237+238238+ iio = devm_iio_device_alloc(dev, sizeof(*dht11));239239+ if (!iio) {240240+ dev_err(dev, "Failed to allocate IIO device\n");241241+ return -ENOMEM;242242+ }243243+244244+ dht11 = iio_priv(iio);245245+ dht11->dev = dev;246246+247247+ dht11->gpio = ret = of_get_gpio(node, 0);248248+ if (ret < 0)249249+ return ret;250250+ ret = devm_gpio_request_one(dev, dht11->gpio, GPIOF_IN, pdev->name);251251+ if (ret)252252+ return ret;253253+254254+ dht11->irq = gpio_to_irq(dht11->gpio);255255+ if (dht11->irq < 0) {256256+ dev_err(dev, "GPIO %d has no interrupt\n", dht11->gpio);257257+ return -EINVAL;258258+ }259259+ ret = devm_request_irq(dev, dht11->irq, dht11_handle_irq,260260+ IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING,261261+ pdev->name, iio);262262+ if (ret)263263+ return ret;264264+265265+ dht11->timestamp = iio_get_time_ns() - DHT11_DATA_VALID_TIME - 1;266266+ dht11->num_edges = -1;267267+268268+ platform_set_drvdata(pdev, iio);269269+270270+ init_completion(&dht11->completion);271271+ iio->name = pdev->name;272272+ iio->dev.parent = &pdev->dev;273273+ iio->info = &dht11_iio_info;274274+ iio->modes = INDIO_DIRECT_MODE;275275+ iio->channels = dht11_chan_spec;276276+ iio->num_channels = ARRAY_SIZE(dht11_chan_spec);277277+278278+ return devm_iio_device_register(dev, iio);279279+}280280+281281+static struct platform_driver dht11_driver = {282282+ .driver = {283283+ .name = DRIVER_NAME,284284+ .owner = THIS_MODULE,285285+ .of_match_table = dht11_dt_ids,286286+ },287287+ .probe = dht11_probe,288288+};289289+290290+module_platform_driver(dht11_driver);291291+292292+MODULE_AUTHOR("Harald Geyer <harald@ccbib.org>");293293+MODULE_DESCRIPTION("DHT11 humidity/temperature sensor driver");294294+MODULE_LICENSE("GPL v2");