root/drivers/hwmon/ad7314.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. ad7314_spi_read
  2. ad7314_temperature_show
  3. ad7314_probe

   1 // SPDX-License-Identifier: GPL-2.0-or-later
   2 /*
   3  * AD7314 digital temperature sensor driver for AD7314, ADT7301 and ADT7302
   4  *
   5  * Copyright 2010 Analog Devices Inc.
   6  *
   7  * Conversion to hwmon from IIO done by Jonathan Cameron <jic23@cam.ac.uk>
   8  */
   9 #include <linux/device.h>
  10 #include <linux/kernel.h>
  11 #include <linux/slab.h>
  12 #include <linux/sysfs.h>
  13 #include <linux/spi/spi.h>
  14 #include <linux/module.h>
  15 #include <linux/err.h>
  16 #include <linux/hwmon.h>
  17 #include <linux/hwmon-sysfs.h>
  18 #include <linux/bitops.h>
  19 
  20 /*
  21  * AD7314 temperature masks
  22  */
  23 #define AD7314_TEMP_MASK                0x7FE0
  24 #define AD7314_TEMP_SHIFT               5
  25 
  26 /*
  27  * ADT7301 and ADT7302 temperature masks
  28  */
  29 #define ADT7301_TEMP_MASK               0x3FFF
  30 
  31 enum ad7314_variant {
  32         adt7301,
  33         adt7302,
  34         ad7314,
  35 };
  36 
  37 struct ad7314_data {
  38         struct spi_device       *spi_dev;
  39         u16 rx ____cacheline_aligned;
  40 };
  41 
  42 static int ad7314_spi_read(struct ad7314_data *chip)
  43 {
  44         int ret;
  45 
  46         ret = spi_read(chip->spi_dev, (u8 *)&chip->rx, sizeof(chip->rx));
  47         if (ret < 0) {
  48                 dev_err(&chip->spi_dev->dev, "SPI read error\n");
  49                 return ret;
  50         }
  51 
  52         return be16_to_cpu(chip->rx);
  53 }
  54 
  55 static ssize_t ad7314_temperature_show(struct device *dev,
  56                                        struct device_attribute *attr,
  57                                        char *buf)
  58 {
  59         struct ad7314_data *chip = dev_get_drvdata(dev);
  60         s16 data;
  61         int ret;
  62 
  63         ret = ad7314_spi_read(chip);
  64         if (ret < 0)
  65                 return ret;
  66         switch (spi_get_device_id(chip->spi_dev)->driver_data) {
  67         case ad7314:
  68                 data = (ret & AD7314_TEMP_MASK) >> AD7314_TEMP_SHIFT;
  69                 data = sign_extend32(data, 9);
  70 
  71                 return sprintf(buf, "%d\n", 250 * data);
  72         case adt7301:
  73         case adt7302:
  74                 /*
  75                  * Documented as a 13 bit twos complement register
  76                  * with a sign bit - which is a 14 bit 2's complement
  77                  * register.  1lsb - 31.25 milli degrees centigrade
  78                  */
  79                 data = ret & ADT7301_TEMP_MASK;
  80                 data = sign_extend32(data, 13);
  81 
  82                 return sprintf(buf, "%d\n",
  83                                DIV_ROUND_CLOSEST(data * 3125, 100));
  84         default:
  85                 return -EINVAL;
  86         }
  87 }
  88 
  89 static SENSOR_DEVICE_ATTR_RO(temp1_input, ad7314_temperature, 0);
  90 
  91 static struct attribute *ad7314_attrs[] = {
  92         &sensor_dev_attr_temp1_input.dev_attr.attr,
  93         NULL,
  94 };
  95 
  96 ATTRIBUTE_GROUPS(ad7314);
  97 
  98 static int ad7314_probe(struct spi_device *spi_dev)
  99 {
 100         struct ad7314_data *chip;
 101         struct device *hwmon_dev;
 102 
 103         chip = devm_kzalloc(&spi_dev->dev, sizeof(*chip), GFP_KERNEL);
 104         if (chip == NULL)
 105                 return -ENOMEM;
 106 
 107         chip->spi_dev = spi_dev;
 108         hwmon_dev = devm_hwmon_device_register_with_groups(&spi_dev->dev,
 109                                                            spi_dev->modalias,
 110                                                            chip, ad7314_groups);
 111         return PTR_ERR_OR_ZERO(hwmon_dev);
 112 }
 113 
 114 static const struct spi_device_id ad7314_id[] = {
 115         { "adt7301", adt7301 },
 116         { "adt7302", adt7302 },
 117         { "ad7314", ad7314 },
 118         { }
 119 };
 120 MODULE_DEVICE_TABLE(spi, ad7314_id);
 121 
 122 static struct spi_driver ad7314_driver = {
 123         .driver = {
 124                 .name = "ad7314",
 125         },
 126         .probe = ad7314_probe,
 127         .id_table = ad7314_id,
 128 };
 129 
 130 module_spi_driver(ad7314_driver);
 131 
 132 MODULE_AUTHOR("Sonic Zhang <sonic.zhang@analog.com>");
 133 MODULE_DESCRIPTION("Analog Devices AD7314, ADT7301 and ADT7302 digital temperature sensor driver");
 134 MODULE_LICENSE("GPL v2");

/* [<][>][^][v][top][bottom][index][help] */