Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0+
0002 /*
0003  * AD7816 digital temperature sensor driver supporting AD7816/7/8
0004  *
0005  * Copyright 2010 Analog Devices Inc.
0006  */
0007 
0008 #include <linux/interrupt.h>
0009 #include <linux/gpio/consumer.h>
0010 #include <linux/device.h>
0011 #include <linux/kernel.h>
0012 #include <linux/slab.h>
0013 #include <linux/sysfs.h>
0014 #include <linux/list.h>
0015 #include <linux/spi/spi.h>
0016 #include <linux/module.h>
0017 
0018 #include <linux/iio/iio.h>
0019 #include <linux/iio/sysfs.h>
0020 #include <linux/iio/events.h>
0021 
0022 /*
0023  * AD7816 config masks
0024  */
0025 #define AD7816_FULL         0x1
0026 #define AD7816_PD           0x2
0027 #define AD7816_CS_MASK          0x7
0028 #define AD7816_CS_MAX           0x4
0029 
0030 /*
0031  * AD7816 temperature masks
0032  */
0033 #define AD7816_VALUE_OFFSET     6
0034 #define AD7816_BOUND_VALUE_BASE     0x8
0035 #define AD7816_BOUND_VALUE_MIN      -95
0036 #define AD7816_BOUND_VALUE_MAX      152
0037 #define AD7816_TEMP_FLOAT_OFFSET    2
0038 #define AD7816_TEMP_FLOAT_MASK      0x3
0039 
0040 /*
0041  * struct ad7816_chip_info - chip specific information
0042  */
0043 
0044 struct ad7816_chip_info {
0045     kernel_ulong_t id;
0046     struct spi_device *spi_dev;
0047     struct gpio_desc *rdwr_pin;
0048     struct gpio_desc *convert_pin;
0049     struct gpio_desc *busy_pin;
0050     u8  oti_data[AD7816_CS_MAX + 1];
0051     u8  channel_id; /* 0 always be temperature */
0052     u8  mode;
0053 };
0054 
0055 enum ad7816_type {
0056     ID_AD7816,
0057     ID_AD7817,
0058     ID_AD7818,
0059 };
0060 
0061 /*
0062  * ad7816 data access by SPI
0063  */
0064 static int ad7816_spi_read(struct ad7816_chip_info *chip, u16 *data)
0065 {
0066     struct spi_device *spi_dev = chip->spi_dev;
0067     int ret;
0068     __be16 buf;
0069 
0070     gpiod_set_value(chip->rdwr_pin, 1);
0071     gpiod_set_value(chip->rdwr_pin, 0);
0072     ret = spi_write(spi_dev, &chip->channel_id, sizeof(chip->channel_id));
0073     if (ret < 0) {
0074         dev_err(&spi_dev->dev, "SPI channel setting error\n");
0075         return ret;
0076     }
0077     gpiod_set_value(chip->rdwr_pin, 1);
0078 
0079     if (chip->mode == AD7816_PD) { /* operating mode 2 */
0080         gpiod_set_value(chip->convert_pin, 1);
0081         gpiod_set_value(chip->convert_pin, 0);
0082     } else { /* operating mode 1 */
0083         gpiod_set_value(chip->convert_pin, 0);
0084         gpiod_set_value(chip->convert_pin, 1);
0085     }
0086 
0087     if (chip->id == ID_AD7816 || chip->id == ID_AD7817) {
0088         while (gpiod_get_value(chip->busy_pin))
0089             cpu_relax();
0090     }
0091 
0092     gpiod_set_value(chip->rdwr_pin, 0);
0093     gpiod_set_value(chip->rdwr_pin, 1);
0094     ret = spi_read(spi_dev, &buf, sizeof(*data));
0095     if (ret < 0) {
0096         dev_err(&spi_dev->dev, "SPI data read error\n");
0097         return ret;
0098     }
0099 
0100     *data = be16_to_cpu(buf);
0101 
0102     return ret;
0103 }
0104 
0105 static int ad7816_spi_write(struct ad7816_chip_info *chip, u8 data)
0106 {
0107     struct spi_device *spi_dev = chip->spi_dev;
0108     int ret;
0109 
0110     gpiod_set_value(chip->rdwr_pin, 1);
0111     gpiod_set_value(chip->rdwr_pin, 0);
0112     ret = spi_write(spi_dev, &data, sizeof(data));
0113     if (ret < 0)
0114         dev_err(&spi_dev->dev, "SPI oti data write error\n");
0115 
0116     return ret;
0117 }
0118 
0119 static ssize_t ad7816_show_mode(struct device *dev,
0120                 struct device_attribute *attr,
0121                 char *buf)
0122 {
0123     struct iio_dev *indio_dev = dev_to_iio_dev(dev);
0124     struct ad7816_chip_info *chip = iio_priv(indio_dev);
0125 
0126     if (chip->mode)
0127         return sprintf(buf, "power-save\n");
0128     return sprintf(buf, "full\n");
0129 }
0130 
0131 static ssize_t ad7816_store_mode(struct device *dev,
0132                  struct device_attribute *attr,
0133                  const char *buf,
0134                  size_t len)
0135 {
0136     struct iio_dev *indio_dev = dev_to_iio_dev(dev);
0137     struct ad7816_chip_info *chip = iio_priv(indio_dev);
0138 
0139     if (strcmp(buf, "full")) {
0140         gpiod_set_value(chip->rdwr_pin, 1);
0141         chip->mode = AD7816_FULL;
0142     } else {
0143         gpiod_set_value(chip->rdwr_pin, 0);
0144         chip->mode = AD7816_PD;
0145     }
0146 
0147     return len;
0148 }
0149 
0150 static IIO_DEVICE_ATTR(mode, 0644,
0151         ad7816_show_mode,
0152         ad7816_store_mode,
0153         0);
0154 
0155 static ssize_t ad7816_show_available_modes(struct device *dev,
0156                        struct device_attribute *attr,
0157                        char *buf)
0158 {
0159     return sprintf(buf, "full\npower-save\n");
0160 }
0161 
0162 static IIO_DEVICE_ATTR(available_modes, 0444, ad7816_show_available_modes,
0163             NULL, 0);
0164 
0165 static ssize_t ad7816_show_channel(struct device *dev,
0166                    struct device_attribute *attr,
0167                    char *buf)
0168 {
0169     struct iio_dev *indio_dev = dev_to_iio_dev(dev);
0170     struct ad7816_chip_info *chip = iio_priv(indio_dev);
0171 
0172     return sprintf(buf, "%d\n", chip->channel_id);
0173 }
0174 
0175 static ssize_t ad7816_store_channel(struct device *dev,
0176                     struct device_attribute *attr,
0177                     const char *buf,
0178                     size_t len)
0179 {
0180     struct iio_dev *indio_dev = dev_to_iio_dev(dev);
0181     struct ad7816_chip_info *chip = iio_priv(indio_dev);
0182     unsigned long data;
0183     int ret;
0184 
0185     ret = kstrtoul(buf, 10, &data);
0186     if (ret)
0187         return ret;
0188 
0189     if (data > AD7816_CS_MAX && data != AD7816_CS_MASK) {
0190         dev_err(&chip->spi_dev->dev, "Invalid channel id %lu for %s.\n",
0191             data, indio_dev->name);
0192         return -EINVAL;
0193     } else if (strcmp(indio_dev->name, "ad7818") == 0 && data > 1) {
0194         dev_err(&chip->spi_dev->dev,
0195             "Invalid channel id %lu for ad7818.\n", data);
0196         return -EINVAL;
0197     } else if (strcmp(indio_dev->name, "ad7816") == 0 && data > 0) {
0198         dev_err(&chip->spi_dev->dev,
0199             "Invalid channel id %lu for ad7816.\n", data);
0200         return -EINVAL;
0201     }
0202 
0203     chip->channel_id = data;
0204 
0205     return len;
0206 }
0207 
0208 static IIO_DEVICE_ATTR(channel, 0644,
0209         ad7816_show_channel,
0210         ad7816_store_channel,
0211         0);
0212 
0213 static ssize_t ad7816_show_value(struct device *dev,
0214                  struct device_attribute *attr,
0215                  char *buf)
0216 {
0217     struct iio_dev *indio_dev = dev_to_iio_dev(dev);
0218     struct ad7816_chip_info *chip = iio_priv(indio_dev);
0219     u16 data;
0220     s8 value;
0221     int ret;
0222 
0223     ret = ad7816_spi_read(chip, &data);
0224     if (ret)
0225         return -EIO;
0226 
0227     data >>= AD7816_VALUE_OFFSET;
0228 
0229     if (chip->channel_id == 0) {
0230         value = (s8)((data >> AD7816_TEMP_FLOAT_OFFSET) - 103);
0231         data &= AD7816_TEMP_FLOAT_MASK;
0232         if (value < 0)
0233             data = BIT(AD7816_TEMP_FLOAT_OFFSET) - data;
0234         return sprintf(buf, "%d.%.2d\n", value, data * 25);
0235     }
0236     return sprintf(buf, "%u\n", data);
0237 }
0238 
0239 static IIO_DEVICE_ATTR(value, 0444, ad7816_show_value, NULL, 0);
0240 
0241 static struct attribute *ad7816_attributes[] = {
0242     &iio_dev_attr_available_modes.dev_attr.attr,
0243     &iio_dev_attr_mode.dev_attr.attr,
0244     &iio_dev_attr_channel.dev_attr.attr,
0245     &iio_dev_attr_value.dev_attr.attr,
0246     NULL,
0247 };
0248 
0249 static const struct attribute_group ad7816_attribute_group = {
0250     .attrs = ad7816_attributes,
0251 };
0252 
0253 /*
0254  * temperature bound events
0255  */
0256 
0257 #define IIO_EVENT_CODE_AD7816_OTI IIO_UNMOD_EVENT_CODE(IIO_TEMP,    \
0258                                0,       \
0259                                IIO_EV_TYPE_THRESH, \
0260                                IIO_EV_DIR_FALLING)
0261 
0262 static irqreturn_t ad7816_event_handler(int irq, void *private)
0263 {
0264     iio_push_event(private, IIO_EVENT_CODE_AD7816_OTI,
0265                iio_get_time_ns(private));
0266     return IRQ_HANDLED;
0267 }
0268 
0269 static ssize_t ad7816_show_oti(struct device *dev,
0270                    struct device_attribute *attr,
0271                    char *buf)
0272 {
0273     struct iio_dev *indio_dev = dev_to_iio_dev(dev);
0274     struct ad7816_chip_info *chip = iio_priv(indio_dev);
0275     int value;
0276 
0277     if (chip->channel_id > AD7816_CS_MAX) {
0278         dev_err(dev, "Invalid oti channel id %d.\n", chip->channel_id);
0279         return -EINVAL;
0280     } else if (chip->channel_id == 0) {
0281         value = AD7816_BOUND_VALUE_MIN +
0282             (chip->oti_data[chip->channel_id] -
0283             AD7816_BOUND_VALUE_BASE);
0284         return sprintf(buf, "%d\n", value);
0285     }
0286     return sprintf(buf, "%u\n", chip->oti_data[chip->channel_id]);
0287 }
0288 
0289 static inline ssize_t ad7816_set_oti(struct device *dev,
0290                      struct device_attribute *attr,
0291                      const char *buf,
0292                      size_t len)
0293 {
0294     struct iio_dev *indio_dev = dev_to_iio_dev(dev);
0295     struct ad7816_chip_info *chip = iio_priv(indio_dev);
0296     long value;
0297     u8 data;
0298     int ret;
0299 
0300     ret = kstrtol(buf, 10, &value);
0301     if (ret)
0302         return ret;
0303 
0304     if (chip->channel_id > AD7816_CS_MAX) {
0305         dev_err(dev, "Invalid oti channel id %d.\n", chip->channel_id);
0306         return -EINVAL;
0307     } else if (chip->channel_id == 0) {
0308         if (value < AD7816_BOUND_VALUE_MIN ||
0309             value > AD7816_BOUND_VALUE_MAX)
0310             return -EINVAL;
0311 
0312         data = (u8)(value - AD7816_BOUND_VALUE_MIN +
0313             AD7816_BOUND_VALUE_BASE);
0314     } else {
0315         if (value < AD7816_BOUND_VALUE_BASE || value > 255)
0316             return -EINVAL;
0317 
0318         data = (u8)value;
0319     }
0320 
0321     ret = ad7816_spi_write(chip, data);
0322     if (ret)
0323         return -EIO;
0324 
0325     chip->oti_data[chip->channel_id] = data;
0326 
0327     return len;
0328 }
0329 
0330 static IIO_DEVICE_ATTR(oti, 0644,
0331                ad7816_show_oti, ad7816_set_oti, 0);
0332 
0333 static struct attribute *ad7816_event_attributes[] = {
0334     &iio_dev_attr_oti.dev_attr.attr,
0335     NULL,
0336 };
0337 
0338 static const struct attribute_group ad7816_event_attribute_group = {
0339     .attrs = ad7816_event_attributes,
0340     .name = "events",
0341 };
0342 
0343 static const struct iio_info ad7816_info = {
0344     .attrs = &ad7816_attribute_group,
0345     .event_attrs = &ad7816_event_attribute_group,
0346 };
0347 
0348 /*
0349  * device probe and remove
0350  */
0351 
0352 static int ad7816_probe(struct spi_device *spi_dev)
0353 {
0354     struct ad7816_chip_info *chip;
0355     struct iio_dev *indio_dev;
0356     int i, ret;
0357 
0358     indio_dev = devm_iio_device_alloc(&spi_dev->dev, sizeof(*chip));
0359     if (!indio_dev)
0360         return -ENOMEM;
0361     chip = iio_priv(indio_dev);
0362     /* this is only used for device removal purposes */
0363     dev_set_drvdata(&spi_dev->dev, indio_dev);
0364 
0365     chip->spi_dev = spi_dev;
0366     for (i = 0; i <= AD7816_CS_MAX; i++)
0367         chip->oti_data[i] = 203;
0368 
0369     chip->id = spi_get_device_id(spi_dev)->driver_data;
0370     chip->rdwr_pin = devm_gpiod_get(&spi_dev->dev, "rdwr", GPIOD_OUT_HIGH);
0371     if (IS_ERR(chip->rdwr_pin)) {
0372         ret = PTR_ERR(chip->rdwr_pin);
0373         dev_err(&spi_dev->dev, "Failed to request rdwr GPIO: %d\n",
0374             ret);
0375         return ret;
0376     }
0377     chip->convert_pin = devm_gpiod_get(&spi_dev->dev, "convert",
0378                        GPIOD_OUT_HIGH);
0379     if (IS_ERR(chip->convert_pin)) {
0380         ret = PTR_ERR(chip->convert_pin);
0381         dev_err(&spi_dev->dev, "Failed to request convert GPIO: %d\n",
0382             ret);
0383         return ret;
0384     }
0385     if (chip->id == ID_AD7816 || chip->id == ID_AD7817) {
0386         chip->busy_pin = devm_gpiod_get(&spi_dev->dev, "busy",
0387                         GPIOD_IN);
0388         if (IS_ERR(chip->busy_pin)) {
0389             ret = PTR_ERR(chip->busy_pin);
0390             dev_err(&spi_dev->dev, "Failed to request busy GPIO: %d\n",
0391                 ret);
0392             return ret;
0393         }
0394     }
0395 
0396     indio_dev->name = spi_get_device_id(spi_dev)->name;
0397     indio_dev->info = &ad7816_info;
0398     indio_dev->modes = INDIO_DIRECT_MODE;
0399 
0400     if (spi_dev->irq) {
0401         /* Only low trigger is supported in ad7816/7/8 */
0402         ret = devm_request_threaded_irq(&spi_dev->dev, spi_dev->irq,
0403                         NULL,
0404                         &ad7816_event_handler,
0405                         IRQF_TRIGGER_LOW | IRQF_ONESHOT,
0406                         indio_dev->name,
0407                         indio_dev);
0408         if (ret)
0409             return ret;
0410     }
0411 
0412     ret = devm_iio_device_register(&spi_dev->dev, indio_dev);
0413     if (ret)
0414         return ret;
0415 
0416     dev_info(&spi_dev->dev, "%s temperature sensor and ADC registered.\n",
0417          indio_dev->name);
0418 
0419     return 0;
0420 }
0421 
0422 static const struct of_device_id ad7816_of_match[] = {
0423     { .compatible = "adi,ad7816", },
0424     { .compatible = "adi,ad7817", },
0425     { .compatible = "adi,ad7818", },
0426     { }
0427 };
0428 MODULE_DEVICE_TABLE(of, ad7816_of_match);
0429 
0430 static const struct spi_device_id ad7816_id[] = {
0431     { "ad7816", ID_AD7816 },
0432     { "ad7817", ID_AD7817 },
0433     { "ad7818", ID_AD7818 },
0434     {}
0435 };
0436 
0437 MODULE_DEVICE_TABLE(spi, ad7816_id);
0438 
0439 static struct spi_driver ad7816_driver = {
0440     .driver = {
0441         .name = "ad7816",
0442         .of_match_table = ad7816_of_match,
0443     },
0444     .probe = ad7816_probe,
0445     .id_table = ad7816_id,
0446 };
0447 module_spi_driver(ad7816_driver);
0448 
0449 MODULE_AUTHOR("Sonic Zhang <sonic.zhang@analog.com>");
0450 MODULE_DESCRIPTION("Analog Devices AD7816/7/8 digital temperature sensor driver");
0451 MODULE_LICENSE("GPL v2");