| .. | .. |
|---|
| 1 | +// SPDX-License-Identifier: GPL-2.0+ |
|---|
| 1 | 2 | /* |
|---|
| 2 | 3 | * AD7816 digital temperature sensor driver supporting AD7816/7/8 |
|---|
| 3 | 4 | * |
|---|
| 4 | 5 | * Copyright 2010 Analog Devices Inc. |
|---|
| 5 | | - * |
|---|
| 6 | | - * Licensed under the GPL-2 or later. |
|---|
| 7 | 6 | */ |
|---|
| 8 | 7 | |
|---|
| 9 | 8 | #include <linux/interrupt.h> |
|---|
| 10 | | -#include <linux/gpio.h> |
|---|
| 9 | +#include <linux/gpio/consumer.h> |
|---|
| 11 | 10 | #include <linux/device.h> |
|---|
| 12 | 11 | #include <linux/kernel.h> |
|---|
| 13 | 12 | #include <linux/slab.h> |
|---|
| .. | .. |
|---|
| 43 | 42 | */ |
|---|
| 44 | 43 | |
|---|
| 45 | 44 | struct ad7816_chip_info { |
|---|
| 45 | + kernel_ulong_t id; |
|---|
| 46 | 46 | struct spi_device *spi_dev; |
|---|
| 47 | | - u16 rdwr_pin; |
|---|
| 48 | | - u16 convert_pin; |
|---|
| 49 | | - u16 busy_pin; |
|---|
| 47 | + struct gpio_desc *rdwr_pin; |
|---|
| 48 | + struct gpio_desc *convert_pin; |
|---|
| 49 | + struct gpio_desc *busy_pin; |
|---|
| 50 | 50 | u8 oti_data[AD7816_CS_MAX + 1]; |
|---|
| 51 | 51 | u8 channel_id; /* 0 always be temperature */ |
|---|
| 52 | 52 | u8 mode; |
|---|
| 53 | +}; |
|---|
| 54 | + |
|---|
| 55 | +enum ad7816_type { |
|---|
| 56 | + ID_AD7816, |
|---|
| 57 | + ID_AD7817, |
|---|
| 58 | + ID_AD7818, |
|---|
| 53 | 59 | }; |
|---|
| 54 | 60 | |
|---|
| 55 | 61 | /* |
|---|
| .. | .. |
|---|
| 58 | 64 | static int ad7816_spi_read(struct ad7816_chip_info *chip, u16 *data) |
|---|
| 59 | 65 | { |
|---|
| 60 | 66 | struct spi_device *spi_dev = chip->spi_dev; |
|---|
| 61 | | - int ret = 0; |
|---|
| 67 | + int ret; |
|---|
| 62 | 68 | __be16 buf; |
|---|
| 63 | 69 | |
|---|
| 64 | | - gpio_set_value(chip->rdwr_pin, 1); |
|---|
| 65 | | - gpio_set_value(chip->rdwr_pin, 0); |
|---|
| 70 | + gpiod_set_value(chip->rdwr_pin, 1); |
|---|
| 71 | + gpiod_set_value(chip->rdwr_pin, 0); |
|---|
| 66 | 72 | ret = spi_write(spi_dev, &chip->channel_id, sizeof(chip->channel_id)); |
|---|
| 67 | 73 | if (ret < 0) { |
|---|
| 68 | 74 | dev_err(&spi_dev->dev, "SPI channel setting error\n"); |
|---|
| 69 | 75 | return ret; |
|---|
| 70 | 76 | } |
|---|
| 71 | | - gpio_set_value(chip->rdwr_pin, 1); |
|---|
| 77 | + gpiod_set_value(chip->rdwr_pin, 1); |
|---|
| 72 | 78 | |
|---|
| 73 | 79 | if (chip->mode == AD7816_PD) { /* operating mode 2 */ |
|---|
| 74 | | - gpio_set_value(chip->convert_pin, 1); |
|---|
| 75 | | - gpio_set_value(chip->convert_pin, 0); |
|---|
| 80 | + gpiod_set_value(chip->convert_pin, 1); |
|---|
| 81 | + gpiod_set_value(chip->convert_pin, 0); |
|---|
| 76 | 82 | } else { /* operating mode 1 */ |
|---|
| 77 | | - gpio_set_value(chip->convert_pin, 0); |
|---|
| 78 | | - gpio_set_value(chip->convert_pin, 1); |
|---|
| 83 | + gpiod_set_value(chip->convert_pin, 0); |
|---|
| 84 | + gpiod_set_value(chip->convert_pin, 1); |
|---|
| 79 | 85 | } |
|---|
| 80 | 86 | |
|---|
| 81 | | - while (gpio_get_value(chip->busy_pin)) |
|---|
| 82 | | - cpu_relax(); |
|---|
| 87 | + if (chip->id == ID_AD7816 || chip->id == ID_AD7817) { |
|---|
| 88 | + while (gpiod_get_value(chip->busy_pin)) |
|---|
| 89 | + cpu_relax(); |
|---|
| 90 | + } |
|---|
| 83 | 91 | |
|---|
| 84 | | - gpio_set_value(chip->rdwr_pin, 0); |
|---|
| 85 | | - gpio_set_value(chip->rdwr_pin, 1); |
|---|
| 92 | + gpiod_set_value(chip->rdwr_pin, 0); |
|---|
| 93 | + gpiod_set_value(chip->rdwr_pin, 1); |
|---|
| 86 | 94 | ret = spi_read(spi_dev, &buf, sizeof(*data)); |
|---|
| 87 | 95 | if (ret < 0) { |
|---|
| 88 | 96 | dev_err(&spi_dev->dev, "SPI data read error\n"); |
|---|
| .. | .. |
|---|
| 97 | 105 | static int ad7816_spi_write(struct ad7816_chip_info *chip, u8 data) |
|---|
| 98 | 106 | { |
|---|
| 99 | 107 | struct spi_device *spi_dev = chip->spi_dev; |
|---|
| 100 | | - int ret = 0; |
|---|
| 108 | + int ret; |
|---|
| 101 | 109 | |
|---|
| 102 | | - gpio_set_value(chip->rdwr_pin, 1); |
|---|
| 103 | | - gpio_set_value(chip->rdwr_pin, 0); |
|---|
| 110 | + gpiod_set_value(chip->rdwr_pin, 1); |
|---|
| 111 | + gpiod_set_value(chip->rdwr_pin, 0); |
|---|
| 104 | 112 | ret = spi_write(spi_dev, &data, sizeof(data)); |
|---|
| 105 | 113 | if (ret < 0) |
|---|
| 106 | 114 | dev_err(&spi_dev->dev, "SPI oti data write error\n"); |
|---|
| .. | .. |
|---|
| 129 | 137 | struct ad7816_chip_info *chip = iio_priv(indio_dev); |
|---|
| 130 | 138 | |
|---|
| 131 | 139 | if (strcmp(buf, "full")) { |
|---|
| 132 | | - gpio_set_value(chip->rdwr_pin, 1); |
|---|
| 140 | + gpiod_set_value(chip->rdwr_pin, 1); |
|---|
| 133 | 141 | chip->mode = AD7816_FULL; |
|---|
| 134 | 142 | } else { |
|---|
| 135 | | - gpio_set_value(chip->rdwr_pin, 0); |
|---|
| 143 | + gpiod_set_value(chip->rdwr_pin, 0); |
|---|
| 136 | 144 | chip->mode = AD7816_PD; |
|---|
| 137 | 145 | } |
|---|
| 138 | 146 | |
|---|
| .. | .. |
|---|
| 222 | 230 | value = (s8)((data >> AD7816_TEMP_FLOAT_OFFSET) - 103); |
|---|
| 223 | 231 | data &= AD7816_TEMP_FLOAT_MASK; |
|---|
| 224 | 232 | if (value < 0) |
|---|
| 225 | | - data = (1 << AD7816_TEMP_FLOAT_OFFSET) - data; |
|---|
| 233 | + data = BIT(AD7816_TEMP_FLOAT_OFFSET) - data; |
|---|
| 226 | 234 | return sprintf(buf, "%d.%.2d\n", value, data * 25); |
|---|
| 227 | 235 | } |
|---|
| 228 | 236 | return sprintf(buf, "%u\n", data); |
|---|
| .. | .. |
|---|
| 345 | 353 | { |
|---|
| 346 | 354 | struct ad7816_chip_info *chip; |
|---|
| 347 | 355 | struct iio_dev *indio_dev; |
|---|
| 348 | | - unsigned short *pins = dev_get_platdata(&spi_dev->dev); |
|---|
| 349 | | - int ret = 0; |
|---|
| 350 | | - int i; |
|---|
| 351 | | - |
|---|
| 352 | | - if (!pins) { |
|---|
| 353 | | - dev_err(&spi_dev->dev, "No necessary GPIO platform data.\n"); |
|---|
| 354 | | - return -EINVAL; |
|---|
| 355 | | - } |
|---|
| 356 | + int i, ret; |
|---|
| 356 | 357 | |
|---|
| 357 | 358 | indio_dev = devm_iio_device_alloc(&spi_dev->dev, sizeof(*chip)); |
|---|
| 358 | 359 | if (!indio_dev) |
|---|
| .. | .. |
|---|
| 364 | 365 | chip->spi_dev = spi_dev; |
|---|
| 365 | 366 | for (i = 0; i <= AD7816_CS_MAX; i++) |
|---|
| 366 | 367 | chip->oti_data[i] = 203; |
|---|
| 367 | | - chip->rdwr_pin = pins[0]; |
|---|
| 368 | | - chip->convert_pin = pins[1]; |
|---|
| 369 | | - chip->busy_pin = pins[2]; |
|---|
| 370 | 368 | |
|---|
| 371 | | - ret = devm_gpio_request(&spi_dev->dev, chip->rdwr_pin, |
|---|
| 372 | | - spi_get_device_id(spi_dev)->name); |
|---|
| 373 | | - if (ret) { |
|---|
| 374 | | - dev_err(&spi_dev->dev, "Fail to request rdwr gpio PIN %d.\n", |
|---|
| 375 | | - chip->rdwr_pin); |
|---|
| 369 | + chip->id = spi_get_device_id(spi_dev)->driver_data; |
|---|
| 370 | + chip->rdwr_pin = devm_gpiod_get(&spi_dev->dev, "rdwr", GPIOD_OUT_HIGH); |
|---|
| 371 | + if (IS_ERR(chip->rdwr_pin)) { |
|---|
| 372 | + ret = PTR_ERR(chip->rdwr_pin); |
|---|
| 373 | + dev_err(&spi_dev->dev, "Failed to request rdwr GPIO: %d\n", |
|---|
| 374 | + ret); |
|---|
| 376 | 375 | return ret; |
|---|
| 377 | 376 | } |
|---|
| 378 | | - gpio_direction_input(chip->rdwr_pin); |
|---|
| 379 | | - ret = devm_gpio_request(&spi_dev->dev, chip->convert_pin, |
|---|
| 380 | | - spi_get_device_id(spi_dev)->name); |
|---|
| 381 | | - if (ret) { |
|---|
| 382 | | - dev_err(&spi_dev->dev, "Fail to request convert gpio PIN %d.\n", |
|---|
| 383 | | - chip->convert_pin); |
|---|
| 377 | + chip->convert_pin = devm_gpiod_get(&spi_dev->dev, "convert", |
|---|
| 378 | + GPIOD_OUT_HIGH); |
|---|
| 379 | + if (IS_ERR(chip->convert_pin)) { |
|---|
| 380 | + ret = PTR_ERR(chip->convert_pin); |
|---|
| 381 | + dev_err(&spi_dev->dev, "Failed to request convert GPIO: %d\n", |
|---|
| 382 | + ret); |
|---|
| 384 | 383 | return ret; |
|---|
| 385 | 384 | } |
|---|
| 386 | | - gpio_direction_input(chip->convert_pin); |
|---|
| 387 | | - ret = devm_gpio_request(&spi_dev->dev, chip->busy_pin, |
|---|
| 388 | | - spi_get_device_id(spi_dev)->name); |
|---|
| 389 | | - if (ret) { |
|---|
| 390 | | - dev_err(&spi_dev->dev, "Fail to request busy gpio PIN %d.\n", |
|---|
| 391 | | - chip->busy_pin); |
|---|
| 392 | | - return ret; |
|---|
| 385 | + if (chip->id == ID_AD7816 || chip->id == ID_AD7817) { |
|---|
| 386 | + chip->busy_pin = devm_gpiod_get(&spi_dev->dev, "busy", |
|---|
| 387 | + GPIOD_IN); |
|---|
| 388 | + if (IS_ERR(chip->busy_pin)) { |
|---|
| 389 | + ret = PTR_ERR(chip->busy_pin); |
|---|
| 390 | + dev_err(&spi_dev->dev, "Failed to request busy GPIO: %d\n", |
|---|
| 391 | + ret); |
|---|
| 392 | + return ret; |
|---|
| 393 | + } |
|---|
| 393 | 394 | } |
|---|
| 394 | | - gpio_direction_input(chip->busy_pin); |
|---|
| 395 | 395 | |
|---|
| 396 | 396 | indio_dev->name = spi_get_device_id(spi_dev)->name; |
|---|
| 397 | | - indio_dev->dev.parent = &spi_dev->dev; |
|---|
| 398 | 397 | indio_dev->info = &ad7816_info; |
|---|
| 399 | 398 | indio_dev->modes = INDIO_DIRECT_MODE; |
|---|
| 400 | 399 | |
|---|
| .. | .. |
|---|
| 420 | 419 | return 0; |
|---|
| 421 | 420 | } |
|---|
| 422 | 421 | |
|---|
| 422 | +static const struct of_device_id ad7816_of_match[] = { |
|---|
| 423 | + { .compatible = "adi,ad7816", }, |
|---|
| 424 | + { .compatible = "adi,ad7817", }, |
|---|
| 425 | + { .compatible = "adi,ad7818", }, |
|---|
| 426 | + { } |
|---|
| 427 | +}; |
|---|
| 428 | +MODULE_DEVICE_TABLE(of, ad7816_of_match); |
|---|
| 429 | + |
|---|
| 423 | 430 | static const struct spi_device_id ad7816_id[] = { |
|---|
| 424 | | - { "ad7816", 0 }, |
|---|
| 425 | | - { "ad7817", 0 }, |
|---|
| 426 | | - { "ad7818", 0 }, |
|---|
| 431 | + { "ad7816", ID_AD7816 }, |
|---|
| 432 | + { "ad7817", ID_AD7817 }, |
|---|
| 433 | + { "ad7818", ID_AD7818 }, |
|---|
| 427 | 434 | {} |
|---|
| 428 | 435 | }; |
|---|
| 429 | 436 | |
|---|
| .. | .. |
|---|
| 432 | 439 | static struct spi_driver ad7816_driver = { |
|---|
| 433 | 440 | .driver = { |
|---|
| 434 | 441 | .name = "ad7816", |
|---|
| 442 | + .of_match_table = ad7816_of_match, |
|---|
| 435 | 443 | }, |
|---|
| 436 | 444 | .probe = ad7816_probe, |
|---|
| 437 | 445 | .id_table = ad7816_id, |
|---|