aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/hwmon
diff options
context:
space:
mode:
authorJonathan Cameron <jic23@cam.ac.uk>2011-09-29 12:50:04 -0400
committerGuenter Roeck <guenter.roeck@ericsson.com>2011-10-24 14:09:41 -0400
commit4f3a659581cabf1be441d6467b523be914615496 (patch)
tree7d5d581f10409b883fab255f7ccede8692497b2b /drivers/hwmon
parent200855e52db1b1834121ba57fbd89c5b4911e02c (diff)
hwmon: AD7314 driver (ported from IIO)
Driver for AD7314, ADT7301, and ADT7302, ported from IIO. Currently dropped power down mode support. Signed-off-by: Jonathan Cameron <jic23@cam.ac.uk> [guenter.roeck@ericsson.com: Added MODULE_DEVICE_TABLE] Signed-off-by: Guenter Roeck <guenter.roeck@ericsson.com>
Diffstat (limited to 'drivers/hwmon')
-rw-r--r--drivers/hwmon/Kconfig10
-rw-r--r--drivers/hwmon/Makefile1
-rw-r--r--drivers/hwmon/ad7314.c186
3 files changed, 197 insertions, 0 deletions
diff --git a/drivers/hwmon/Kconfig b/drivers/hwmon/Kconfig
index c6fb7611dd1..378ed8ae34d 100644
--- a/drivers/hwmon/Kconfig
+++ b/drivers/hwmon/Kconfig
@@ -68,6 +68,16 @@ config SENSORS_ABITUGURU3
68 This driver can also be built as a module. If so, the module 68 This driver can also be built as a module. If so, the module
69 will be called abituguru3. 69 will be called abituguru3.
70 70
71config SENSORS_AD7314
72 tristate "Analog Devices AD7314 and compatibles"
73 depends on SPI && EXPERIMENTAL
74 help
75 If you say yes here you get support for the Analog Devices
76 AD7314, ADT7301 and ADT7302 temperature sensors.
77
78 This driver can also be built as a module. If so, the module
79 will be called ad7314.
80
71config SENSORS_AD7414 81config SENSORS_AD7414
72 tristate "Analog Devices AD7414" 82 tristate "Analog Devices AD7414"
73 depends on I2C && EXPERIMENTAL 83 depends on I2C && EXPERIMENTAL
diff --git a/drivers/hwmon/Makefile b/drivers/hwmon/Makefile
index dbd8963ec7f..8251ce8cd03 100644
--- a/drivers/hwmon/Makefile
+++ b/drivers/hwmon/Makefile
@@ -21,6 +21,7 @@ obj-$(CONFIG_SENSORS_W83791D) += w83791d.o
21 21
22obj-$(CONFIG_SENSORS_ABITUGURU) += abituguru.o 22obj-$(CONFIG_SENSORS_ABITUGURU) += abituguru.o
23obj-$(CONFIG_SENSORS_ABITUGURU3)+= abituguru3.o 23obj-$(CONFIG_SENSORS_ABITUGURU3)+= abituguru3.o
24obj-$(CONFIG_SENSORS_AD7314) += ad7314.o
24obj-$(CONFIG_SENSORS_AD7414) += ad7414.o 25obj-$(CONFIG_SENSORS_AD7414) += ad7414.o
25obj-$(CONFIG_SENSORS_AD7418) += ad7418.o 26obj-$(CONFIG_SENSORS_AD7418) += ad7418.o
26obj-$(CONFIG_SENSORS_ADCXX) += adcxx.o 27obj-$(CONFIG_SENSORS_ADCXX) += adcxx.o
diff --git a/drivers/hwmon/ad7314.c b/drivers/hwmon/ad7314.c
new file mode 100644
index 00000000000..318e38e8537
--- /dev/null
+++ b/drivers/hwmon/ad7314.c
@@ -0,0 +1,186 @@
1/*
2 * AD7314 digital temperature sensor driver for AD7314, ADT7301 and ADT7302
3 *
4 * Copyright 2010 Analog Devices Inc.
5 *
6 * Licensed under the GPL-2 or later.
7 *
8 * Conversion to hwmon from IIO done by Jonathan Cameron <jic23@cam.ac.uk>
9 */
10#include <linux/device.h>
11#include <linux/kernel.h>
12#include <linux/slab.h>
13#include <linux/sysfs.h>
14#include <linux/spi/spi.h>
15#include <linux/module.h>
16#include <linux/err.h>
17#include <linux/hwmon.h>
18#include <linux/hwmon-sysfs.h>
19
20/*
21 * AD7314 power mode
22 */
23#define AD7314_PD 0x2000
24
25/*
26 * AD7314 temperature masks
27 */
28#define AD7314_TEMP_SIGN 0x200
29#define AD7314_TEMP_MASK 0x7FE0
30#define AD7314_TEMP_OFFSET 5
31
32/*
33 * ADT7301 and ADT7302 temperature masks
34 */
35#define ADT7301_TEMP_SIGN 0x2000
36#define ADT7301_TEMP_MASK 0x3FFF
37
38enum ad7314_variant {
39 adt7301,
40 adt7302,
41 ad7314,
42};
43
44struct ad7314_data {
45 struct spi_device *spi_dev;
46 struct device *hwmon_dev;
47 u16 rx ____cacheline_aligned;
48};
49
50static int ad7314_spi_read(struct ad7314_data *chip, s16 *data)
51{
52 int ret;
53
54 ret = spi_read(chip->spi_dev, (u8 *)&chip->rx, sizeof(chip->rx));
55 if (ret < 0) {
56 dev_err(&chip->spi_dev->dev, "SPI read error\n");
57 return ret;
58 }
59
60 *data = be16_to_cpu(chip->rx);
61
62 return ret;
63}
64
65static ssize_t ad7314_show_temperature(struct device *dev,
66 struct device_attribute *attr,
67 char *buf)
68{
69 struct ad7314_data *chip = dev_get_drvdata(dev);
70 s16 data;
71 int ret;
72
73 ret = ad7314_spi_read(chip, &data);
74 if (ret < 0)
75 return ret;
76 switch (spi_get_device_id(chip->spi_dev)->driver_data) {
77 case ad7314:
78 data = (data & AD7314_TEMP_MASK) >> AD7314_TEMP_OFFSET;
79 data = (data << 6) >> 6;
80
81 return sprintf(buf, "%d\n", 250 * data);
82 case adt7301:
83 case adt7302:
84 /*
85 * Documented as a 13 bit twos complement register
86 * with a sign bit - which is a 14 bit 2's complement
87 * register. 1lsb - 31.25 milli degrees centigrade
88 */
89 data &= ADT7301_TEMP_MASK;
90 data = (data << 2) >> 2;
91
92 return sprintf(buf, "%d\n",
93 DIV_ROUND_CLOSEST(data * 3125, 100));
94 default:
95 return -EINVAL;
96 }
97}
98
99static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO,
100 ad7314_show_temperature, NULL, 0);
101
102static struct attribute *ad7314_attributes[] = {
103 &sensor_dev_attr_temp1_input.dev_attr.attr,
104 NULL,
105};
106
107static const struct attribute_group ad7314_group = {
108 .attrs = ad7314_attributes,
109};
110
111static int __devinit ad7314_probe(struct spi_device *spi_dev)
112{
113 int ret;
114 struct ad7314_data *chip;
115
116 chip = kzalloc(sizeof(*chip), GFP_KERNEL);
117 if (chip == NULL) {
118 ret = -ENOMEM;
119 goto error_ret;
120 }
121 dev_set_drvdata(&spi_dev->dev, chip);
122
123 ret = sysfs_create_group(&spi_dev->dev.kobj, &ad7314_group);
124 if (ret < 0)
125 goto error_free_chip;
126 chip->hwmon_dev = hwmon_device_register(&spi_dev->dev);
127 if (IS_ERR(chip->hwmon_dev)) {
128 ret = PTR_ERR(chip->hwmon_dev);
129 goto error_remove_group;
130 }
131
132 return 0;
133error_remove_group:
134 sysfs_remove_group(&spi_dev->dev.kobj, &ad7314_group);
135error_free_chip:
136 kfree(chip);
137error_ret:
138 return ret;
139}
140
141static int __devexit ad7314_remove(struct spi_device *spi_dev)
142{
143 struct ad7314_data *chip = dev_get_drvdata(&spi_dev->dev);
144
145 hwmon_device_unregister(chip->hwmon_dev);
146 sysfs_remove_group(&spi_dev->dev.kobj, &ad7314_group);
147 kfree(chip);
148
149 return 0;
150}
151
152static const struct spi_device_id ad7314_id[] = {
153 { "adt7301", adt7301 },
154 { "adt7302", adt7302 },
155 { "ad7314", ad7314 },
156 { }
157};
158MODULE_DEVICE_TABLE(spi, ad7314_id);
159
160static struct spi_driver ad7314_driver = {
161 .driver = {
162 .name = "ad7314",
163 .bus = &spi_bus_type,
164 .owner = THIS_MODULE,
165 },
166 .probe = ad7314_probe,
167 .remove = __devexit_p(ad7314_remove),
168 .id_table = ad7314_id,
169};
170
171static __init int ad7314_init(void)
172{
173 return spi_register_driver(&ad7314_driver);
174}
175module_init(ad7314_init);
176
177static __exit void ad7314_exit(void)
178{
179 spi_unregister_driver(&ad7314_driver);
180}
181module_exit(ad7314_exit);
182
183MODULE_AUTHOR("Sonic Zhang <sonic.zhang@analog.com>");
184MODULE_DESCRIPTION("Analog Devices AD7314, ADT7301 and ADT7302 digital"
185 " temperature sensor driver");
186MODULE_LICENSE("GPL v2");