| .. | .. |
|---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-or-later |
|---|
| 1 | 2 | /* |
|---|
| 2 | 3 | * DHT11/DHT22 bit banging GPIO driver |
|---|
| 3 | 4 | * |
|---|
| 4 | 5 | * 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 | 6 | */ |
|---|
| 16 | 7 | |
|---|
| 17 | 8 | #include <linux/err.h> |
|---|
| .. | .. |
|---|
| 31 | 22 | #include <linux/completion.h> |
|---|
| 32 | 23 | #include <linux/mutex.h> |
|---|
| 33 | 24 | #include <linux/delay.h> |
|---|
| 34 | | -#include <linux/gpio.h> |
|---|
| 35 | | -#include <linux/of_gpio.h> |
|---|
| 25 | +#include <linux/gpio/consumer.h> |
|---|
| 36 | 26 | #include <linux/timekeeping.h> |
|---|
| 37 | 27 | |
|---|
| 38 | 28 | #include <linux/iio/iio.h> |
|---|
| .. | .. |
|---|
| 81 | 71 | struct dht11 { |
|---|
| 82 | 72 | struct device *dev; |
|---|
| 83 | 73 | |
|---|
| 84 | | - int gpio; |
|---|
| 74 | + struct gpio_desc *gpiod; |
|---|
| 85 | 75 | int irq; |
|---|
| 86 | 76 | |
|---|
| 87 | 77 | struct completion completion; |
|---|
| .. | .. |
|---|
| 158 | 148 | return -EIO; |
|---|
| 159 | 149 | } |
|---|
| 160 | 150 | |
|---|
| 161 | | - dht11->timestamp = ktime_get_boot_ns(); |
|---|
| 151 | + dht11->timestamp = ktime_get_boottime_ns(); |
|---|
| 162 | 152 | if (hum_int < 4) { /* DHT22: 100000 = (3*256+232)*100 */ |
|---|
| 163 | 153 | dht11->temperature = (((temp_int & 0x7f) << 8) + temp_dec) * |
|---|
| 164 | 154 | ((temp_int & 0x80) ? -100 : 100); |
|---|
| .. | .. |
|---|
| 184 | 174 | struct iio_dev *iio = data; |
|---|
| 185 | 175 | struct dht11 *dht11 = iio_priv(iio); |
|---|
| 186 | 176 | |
|---|
| 187 | | - /* TODO: Consider making the handler safe for IRQ sharing */ |
|---|
| 188 | 177 | if (dht11->num_edges < DHT11_EDGES_PER_READ && dht11->num_edges >= 0) { |
|---|
| 189 | | - dht11->edges[dht11->num_edges].ts = ktime_get_boot_ns(); |
|---|
| 178 | + dht11->edges[dht11->num_edges].ts = ktime_get_boottime_ns(); |
|---|
| 190 | 179 | dht11->edges[dht11->num_edges++].value = |
|---|
| 191 | | - gpio_get_value(dht11->gpio); |
|---|
| 180 | + gpiod_get_value(dht11->gpiod); |
|---|
| 192 | 181 | |
|---|
| 193 | 182 | if (dht11->num_edges >= DHT11_EDGES_PER_READ) |
|---|
| 194 | 183 | complete(&dht11->completion); |
|---|
| .. | .. |
|---|
| 205 | 194 | int ret, timeres, offset; |
|---|
| 206 | 195 | |
|---|
| 207 | 196 | mutex_lock(&dht11->lock); |
|---|
| 208 | | - if (dht11->timestamp + DHT11_DATA_VALID_TIME < ktime_get_boot_ns()) { |
|---|
| 197 | + if (dht11->timestamp + DHT11_DATA_VALID_TIME < ktime_get_boottime_ns()) { |
|---|
| 209 | 198 | timeres = ktime_get_resolution_ns(); |
|---|
| 210 | 199 | dev_dbg(dht11->dev, "current timeresolution: %dns\n", timeres); |
|---|
| 211 | 200 | if (timeres > DHT11_MIN_TIMERES) { |
|---|
| .. | .. |
|---|
| 226 | 215 | reinit_completion(&dht11->completion); |
|---|
| 227 | 216 | |
|---|
| 228 | 217 | dht11->num_edges = 0; |
|---|
| 229 | | - ret = gpio_direction_output(dht11->gpio, 0); |
|---|
| 218 | + ret = gpiod_direction_output(dht11->gpiod, 0); |
|---|
| 230 | 219 | if (ret) |
|---|
| 231 | 220 | goto err; |
|---|
| 232 | 221 | usleep_range(DHT11_START_TRANSMISSION_MIN, |
|---|
| 233 | 222 | DHT11_START_TRANSMISSION_MAX); |
|---|
| 234 | | - ret = gpio_direction_input(dht11->gpio); |
|---|
| 223 | + ret = gpiod_direction_input(dht11->gpiod); |
|---|
| 235 | 224 | if (ret) |
|---|
| 236 | 225 | goto err; |
|---|
| 237 | 226 | |
|---|
| .. | .. |
|---|
| 303 | 292 | static int dht11_probe(struct platform_device *pdev) |
|---|
| 304 | 293 | { |
|---|
| 305 | 294 | struct device *dev = &pdev->dev; |
|---|
| 306 | | - struct device_node *node = dev->of_node; |
|---|
| 307 | 295 | struct dht11 *dht11; |
|---|
| 308 | 296 | struct iio_dev *iio; |
|---|
| 309 | | - int ret; |
|---|
| 310 | 297 | |
|---|
| 311 | 298 | iio = devm_iio_device_alloc(dev, sizeof(*dht11)); |
|---|
| 312 | 299 | if (!iio) { |
|---|
| .. | .. |
|---|
| 316 | 303 | |
|---|
| 317 | 304 | dht11 = iio_priv(iio); |
|---|
| 318 | 305 | dht11->dev = dev; |
|---|
| 306 | + dht11->gpiod = devm_gpiod_get(dev, NULL, GPIOD_IN); |
|---|
| 307 | + if (IS_ERR(dht11->gpiod)) |
|---|
| 308 | + return PTR_ERR(dht11->gpiod); |
|---|
| 319 | 309 | |
|---|
| 320 | | - ret = of_get_gpio(node, 0); |
|---|
| 321 | | - if (ret < 0) |
|---|
| 322 | | - return ret; |
|---|
| 323 | | - dht11->gpio = ret; |
|---|
| 324 | | - ret = devm_gpio_request_one(dev, dht11->gpio, GPIOF_IN, pdev->name); |
|---|
| 325 | | - if (ret) |
|---|
| 326 | | - return ret; |
|---|
| 327 | | - |
|---|
| 328 | | - dht11->irq = gpio_to_irq(dht11->gpio); |
|---|
| 310 | + dht11->irq = gpiod_to_irq(dht11->gpiod); |
|---|
| 329 | 311 | if (dht11->irq < 0) { |
|---|
| 330 | | - dev_err(dev, "GPIO %d has no interrupt\n", dht11->gpio); |
|---|
| 312 | + dev_err(dev, "GPIO %d has no interrupt\n", desc_to_gpio(dht11->gpiod)); |
|---|
| 331 | 313 | return -EINVAL; |
|---|
| 332 | 314 | } |
|---|
| 333 | 315 | |
|---|
| 334 | | - dht11->timestamp = ktime_get_boot_ns() - DHT11_DATA_VALID_TIME - 1; |
|---|
| 316 | + dht11->timestamp = ktime_get_boottime_ns() - DHT11_DATA_VALID_TIME - 1; |
|---|
| 335 | 317 | dht11->num_edges = -1; |
|---|
| 336 | 318 | |
|---|
| 337 | 319 | platform_set_drvdata(pdev, iio); |
|---|
| .. | .. |
|---|
| 339 | 321 | init_completion(&dht11->completion); |
|---|
| 340 | 322 | mutex_init(&dht11->lock); |
|---|
| 341 | 323 | iio->name = pdev->name; |
|---|
| 342 | | - iio->dev.parent = &pdev->dev; |
|---|
| 343 | 324 | iio->info = &dht11_iio_info; |
|---|
| 344 | 325 | iio->modes = INDIO_DIRECT_MODE; |
|---|
| 345 | 326 | iio->channels = dht11_chan_spec; |
|---|