.. | .. |
---|
| 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; |
---|