1
2
3
4
5
6
7
8
9#include <linux/interrupt.h>
10#include <linux/gpio.h>
11#include <linux/workqueue.h>
12#include <linux/device.h>
13#include <linux/kernel.h>
14#include <linux/slab.h>
15#include <linux/sysfs.h>
16#include <linux/list.h>
17#include <linux/spi/spi.h>
18#include <linux/rtc.h>
19
20#include "../iio.h"
21#include "../sysfs.h"
22
23
24
25
26#define AD7314_PD 0x2000
27
28
29
30
31#define AD7314_TEMP_SIGN 0x200
32#define AD7314_TEMP_MASK 0x7FE0
33#define AD7314_TEMP_OFFSET 5
34#define AD7314_TEMP_FLOAT_OFFSET 2
35#define AD7314_TEMP_FLOAT_MASK 0x3
36
37
38
39
40#define ADT7301_TEMP_SIGN 0x2000
41#define ADT7301_TEMP_MASK 0x2FFF
42#define ADT7301_TEMP_FLOAT_OFFSET 5
43#define ADT7301_TEMP_FLOAT_MASK 0x1F
44
45
46
47
48
49struct ad7314_chip_info {
50 const char *name;
51 struct spi_device *spi_dev;
52 struct iio_dev *indio_dev;
53 s64 last_timestamp;
54 u8 mode;
55};
56
57
58
59
60
61static int ad7314_spi_read(struct ad7314_chip_info *chip, u16 *data)
62{
63 struct spi_device *spi_dev = chip->spi_dev;
64 int ret = 0;
65 u16 value;
66
67 ret = spi_read(spi_dev, (u8 *)&value, sizeof(value));
68 if (ret < 0) {
69 dev_err(&spi_dev->dev, "SPI read error\n");
70 return ret;
71 }
72
73 *data = be16_to_cpu((u16)value);
74
75 return ret;
76}
77
78static int ad7314_spi_write(struct ad7314_chip_info *chip, u16 data)
79{
80 struct spi_device *spi_dev = chip->spi_dev;
81 int ret = 0;
82 u16 value = cpu_to_be16(data);
83
84 ret = spi_write(spi_dev, (u8 *)&value, sizeof(value));
85 if (ret < 0)
86 dev_err(&spi_dev->dev, "SPI write error\n");
87
88 return ret;
89}
90
91static ssize_t ad7314_show_mode(struct device *dev,
92 struct device_attribute *attr,
93 char *buf)
94{
95 struct iio_dev *dev_info = dev_get_drvdata(dev);
96 struct ad7314_chip_info *chip = dev_info->dev_data;
97
98 if (chip->mode)
99 return sprintf(buf, "power-save\n");
100 else
101 return sprintf(buf, "full\n");
102}
103
104static ssize_t ad7314_store_mode(struct device *dev,
105 struct device_attribute *attr,
106 const char *buf,
107 size_t len)
108{
109 struct iio_dev *dev_info = dev_get_drvdata(dev);
110 struct ad7314_chip_info *chip = dev_info->dev_data;
111 u16 mode = 0;
112 int ret;
113
114 if (!strcmp(buf, "full"))
115 mode = AD7314_PD;
116
117 ret = ad7314_spi_write(chip, mode);
118 if (ret)
119 return -EIO;
120
121 chip->mode = mode;
122
123 return len;
124}
125
126static IIO_DEVICE_ATTR(mode, S_IRUGO | S_IWUSR,
127 ad7314_show_mode,
128 ad7314_store_mode,
129 0);
130
131static ssize_t ad7314_show_available_modes(struct device *dev,
132 struct device_attribute *attr,
133 char *buf)
134{
135 return sprintf(buf, "full\npower-save\n");
136}
137
138static IIO_DEVICE_ATTR(available_modes, S_IRUGO, ad7314_show_available_modes, NULL, 0);
139
140static ssize_t ad7314_show_temperature(struct device *dev,
141 struct device_attribute *attr,
142 char *buf)
143{
144 struct iio_dev *dev_info = dev_get_drvdata(dev);
145 struct ad7314_chip_info *chip = dev_info->dev_data;
146 u16 data;
147 char sign = ' ';
148 int ret;
149
150 if (chip->mode) {
151 ret = ad7314_spi_write(chip, 0);
152 if (ret)
153 return -EIO;
154 }
155
156 ret = ad7314_spi_read(chip, &data);
157 if (ret)
158 return -EIO;
159
160 if (chip->mode)
161 ad7314_spi_write(chip, chip->mode);
162
163 if (strcmp(chip->name, "ad7314")) {
164 data = (data & AD7314_TEMP_MASK) >>
165 AD7314_TEMP_OFFSET;
166 if (data & AD7314_TEMP_SIGN) {
167 data = (AD7314_TEMP_SIGN << 1) - data;
168 sign = '-';
169 }
170
171 return sprintf(buf, "%c%d.%.2d\n", sign,
172 data >> AD7314_TEMP_FLOAT_OFFSET,
173 (data & AD7314_TEMP_FLOAT_MASK) * 25);
174 } else {
175 data &= ADT7301_TEMP_MASK;
176 if (data & ADT7301_TEMP_SIGN) {
177 data = (ADT7301_TEMP_SIGN << 1) - data;
178 sign = '-';
179 }
180
181 return sprintf(buf, "%c%d.%.5d\n", sign,
182 data >> ADT7301_TEMP_FLOAT_OFFSET,
183 (data & ADT7301_TEMP_FLOAT_MASK) * 3125);
184 }
185}
186
187static IIO_DEVICE_ATTR(temperature, S_IRUGO, ad7314_show_temperature, NULL, 0);
188
189static ssize_t ad7314_show_name(struct device *dev,
190 struct device_attribute *attr,
191 char *buf)
192{
193 struct iio_dev *dev_info = dev_get_drvdata(dev);
194 struct ad7314_chip_info *chip = dev_info->dev_data;
195 return sprintf(buf, "%s\n", chip->name);
196}
197
198static IIO_DEVICE_ATTR(name, S_IRUGO, ad7314_show_name, NULL, 0);
199
200static struct attribute *ad7314_attributes[] = {
201 &iio_dev_attr_available_modes.dev_attr.attr,
202 &iio_dev_attr_mode.dev_attr.attr,
203 &iio_dev_attr_temperature.dev_attr.attr,
204 &iio_dev_attr_name.dev_attr.attr,
205 NULL,
206};
207
208static const struct attribute_group ad7314_attribute_group = {
209 .attrs = ad7314_attributes,
210};
211
212
213
214
215
216static int __devinit ad7314_probe(struct spi_device *spi_dev)
217{
218 struct ad7314_chip_info *chip;
219 int ret = 0;
220
221 chip = kzalloc(sizeof(struct ad7314_chip_info), GFP_KERNEL);
222
223 if (chip == NULL)
224 return -ENOMEM;
225
226
227 dev_set_drvdata(&spi_dev->dev, chip);
228
229 chip->spi_dev = spi_dev;
230 chip->name = spi_dev->modalias;
231
232 chip->indio_dev = iio_allocate_device();
233 if (chip->indio_dev == NULL) {
234 ret = -ENOMEM;
235 goto error_free_chip;
236 }
237
238 chip->indio_dev->dev.parent = &spi_dev->dev;
239 chip->indio_dev->attrs = &ad7314_attribute_group;
240 chip->indio_dev->dev_data = (void *)chip;
241 chip->indio_dev->driver_module = THIS_MODULE;
242
243 ret = iio_device_register(chip->indio_dev);
244 if (ret)
245 goto error_free_dev;
246
247 dev_info(&spi_dev->dev, "%s temperature sensor registered.\n",
248 chip->name);
249
250 return 0;
251error_free_dev:
252 iio_free_device(chip->indio_dev);
253error_free_chip:
254 kfree(chip);
255
256 return ret;
257}
258
259static int __devexit ad7314_remove(struct spi_device *spi_dev)
260{
261 struct ad7314_chip_info *chip = dev_get_drvdata(&spi_dev->dev);
262 struct iio_dev *indio_dev = chip->indio_dev;
263
264 dev_set_drvdata(&spi_dev->dev, NULL);
265 if (spi_dev->irq)
266 iio_unregister_interrupt_line(indio_dev, 0);
267 iio_device_unregister(indio_dev);
268 iio_free_device(chip->indio_dev);
269 kfree(chip);
270
271 return 0;
272}
273
274static const struct spi_device_id ad7314_id[] = {
275 { "adt7301", 0 },
276 { "adt7302", 0 },
277 { "ad7314", 0 },
278 {}
279};
280
281static struct spi_driver ad7314_driver = {
282 .driver = {
283 .name = "ad7314",
284 .bus = &spi_bus_type,
285 .owner = THIS_MODULE,
286 },
287 .probe = ad7314_probe,
288 .remove = __devexit_p(ad7314_remove),
289 .id_table = ad7314_id,
290};
291
292static __init int ad7314_init(void)
293{
294 return spi_register_driver(&ad7314_driver);
295}
296
297static __exit void ad7314_exit(void)
298{
299 spi_unregister_driver(&ad7314_driver);
300}
301
302MODULE_AUTHOR("Sonic Zhang <sonic.zhang@analog.com>");
303MODULE_DESCRIPTION("Analog Devices AD7314, ADT7301 and ADT7302 digital"
304 " temperature sensor driver");
305MODULE_LICENSE("GPL v2");
306
307module_init(ad7314_init);
308module_exit(ad7314_exit);
309