diff options
author | Lars-Peter Clausen <lars@metafoo.de> | 2012-10-22 05:42:00 -0400 |
---|---|---|
committer | Jonathan Cameron <jic23@kernel.org> | 2012-10-31 06:40:34 -0400 |
commit | 2b0c856ad9571013db8fc369194b7108dff3c18e (patch) | |
tree | 3eeb31b681966918b952c1ddb6993353f14179e4 | |
parent | e446f5a8540a845ed92fca4109e67c8f0c76031f (diff) |
staging:iio: Consolidate adt7310 and adt7410 driver
The adt7310 is the SPI version of the adt7410, so there is no need to have a
separate driver for it. The register map layout is a bit different, i.e. the
addresses of the register differ, but the individual register layouts are
identical. We solve this by adding a small look-up table, which translates
adt7410 register addresses to ad7310 register addresses.
Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
Signed-off-by: Jonathan Cameron <jic23@kernel.org>
-rw-r--r-- | drivers/staging/iio/adc/Kconfig | 13 | ||||
-rw-r--r-- | drivers/staging/iio/adc/Makefile | 1 | ||||
-rw-r--r-- | drivers/staging/iio/adc/adt7310.c | 881 | ||||
-rw-r--r-- | drivers/staging/iio/adc/adt7410.c | 458 |
4 files changed, 364 insertions, 989 deletions
diff --git a/drivers/staging/iio/adc/Kconfig b/drivers/staging/iio/adc/Kconfig index a525143ecbea..71a515d0a6de 100644 --- a/drivers/staging/iio/adc/Kconfig +++ b/drivers/staging/iio/adc/Kconfig | |||
@@ -126,18 +126,11 @@ config AD7192 | |||
126 | To compile this driver as a module, choose M here: the | 126 | To compile this driver as a module, choose M here: the |
127 | module will be called ad7192. | 127 | module will be called ad7192. |
128 | 128 | ||
129 | config ADT7310 | ||
130 | tristate "Analog Devices ADT7310 temperature sensor driver" | ||
131 | depends on SPI | ||
132 | help | ||
133 | Say yes here to build support for Analog Devices ADT7310 | ||
134 | temperature sensors. | ||
135 | |||
136 | config ADT7410 | 129 | config ADT7410 |
137 | tristate "Analog Devices ADT7410 temperature sensor driver" | 130 | tristate "Analog Devices ADT7310/ADT7410 temperature sensor driver" |
138 | depends on I2C | 131 | depends on I2C || SPI_MASTER |
139 | help | 132 | help |
140 | Say yes here to build support for Analog Devices ADT7410 | 133 | Say yes here to build support for Analog Devices ADT7310/ADT7410 |
141 | temperature sensors. | 134 | temperature sensors. |
142 | 135 | ||
143 | config AD7280 | 136 | config AD7280 |
diff --git a/drivers/staging/iio/adc/Makefile b/drivers/staging/iio/adc/Makefile index 62ee02e80cf9..ff561c591d66 100644 --- a/drivers/staging/iio/adc/Makefile +++ b/drivers/staging/iio/adc/Makefile | |||
@@ -30,7 +30,6 @@ obj-$(CONFIG_AD7780) += ad7780.o | |||
30 | obj-$(CONFIG_AD7793) += ad7793.o | 30 | obj-$(CONFIG_AD7793) += ad7793.o |
31 | obj-$(CONFIG_AD7816) += ad7816.o | 31 | obj-$(CONFIG_AD7816) += ad7816.o |
32 | obj-$(CONFIG_AD7192) += ad7192.o | 32 | obj-$(CONFIG_AD7192) += ad7192.o |
33 | obj-$(CONFIG_ADT7310) += adt7310.o | ||
34 | obj-$(CONFIG_ADT7410) += adt7410.o | 33 | obj-$(CONFIG_ADT7410) += adt7410.o |
35 | obj-$(CONFIG_AD7280) += ad7280a.o | 34 | obj-$(CONFIG_AD7280) += ad7280a.o |
36 | obj-$(CONFIG_LPC32XX_ADC) += lpc32xx_adc.o | 35 | obj-$(CONFIG_LPC32XX_ADC) += lpc32xx_adc.o |
diff --git a/drivers/staging/iio/adc/adt7310.c b/drivers/staging/iio/adc/adt7310.c deleted file mode 100644 index 72460b6dc2f4..000000000000 --- a/drivers/staging/iio/adc/adt7310.c +++ /dev/null | |||
@@ -1,881 +0,0 @@ | |||
1 | /* | ||
2 | * ADT7310 digital temperature sensor driver supporting ADT7310 | ||
3 | * | ||
4 | * Copyright 2010 Analog Devices Inc. | ||
5 | * | ||
6 | * Licensed under the GPL-2 or later. | ||
7 | */ | ||
8 | |||
9 | #include <linux/interrupt.h> | ||
10 | #include <linux/device.h> | ||
11 | #include <linux/kernel.h> | ||
12 | #include <linux/slab.h> | ||
13 | #include <linux/sysfs.h> | ||
14 | #include <linux/list.h> | ||
15 | #include <linux/spi/spi.h> | ||
16 | #include <linux/module.h> | ||
17 | |||
18 | #include <linux/iio/iio.h> | ||
19 | #include <linux/iio/sysfs.h> | ||
20 | #include <linux/iio/events.h> | ||
21 | /* | ||
22 | * ADT7310 registers definition | ||
23 | */ | ||
24 | |||
25 | #define ADT7310_STATUS 0 | ||
26 | #define ADT7310_CONFIG 1 | ||
27 | #define ADT7310_TEMPERATURE 2 | ||
28 | #define ADT7310_ID 3 | ||
29 | #define ADT7310_T_CRIT 4 | ||
30 | #define ADT7310_T_HYST 5 | ||
31 | #define ADT7310_T_ALARM_HIGH 6 | ||
32 | #define ADT7310_T_ALARM_LOW 7 | ||
33 | |||
34 | /* | ||
35 | * ADT7310 status | ||
36 | */ | ||
37 | #define ADT7310_STAT_T_LOW 0x10 | ||
38 | #define ADT7310_STAT_T_HIGH 0x20 | ||
39 | #define ADT7310_STAT_T_CRIT 0x40 | ||
40 | #define ADT7310_STAT_NOT_RDY 0x80 | ||
41 | |||
42 | /* | ||
43 | * ADT7310 config | ||
44 | */ | ||
45 | #define ADT7310_FAULT_QUEUE_MASK 0x3 | ||
46 | #define ADT7310_CT_POLARITY 0x4 | ||
47 | #define ADT7310_INT_POLARITY 0x8 | ||
48 | #define ADT7310_EVENT_MODE 0x10 | ||
49 | #define ADT7310_MODE_MASK 0x60 | ||
50 | #define ADT7310_ONESHOT 0x20 | ||
51 | #define ADT7310_SPS 0x40 | ||
52 | #define ADT7310_PD 0x60 | ||
53 | #define ADT7310_RESOLUTION 0x80 | ||
54 | |||
55 | /* | ||
56 | * ADT7310 masks | ||
57 | */ | ||
58 | #define ADT7310_T16_VALUE_SIGN 0x8000 | ||
59 | #define ADT7310_T16_VALUE_FLOAT_OFFSET 7 | ||
60 | #define ADT7310_T16_VALUE_FLOAT_MASK 0x7F | ||
61 | #define ADT7310_T13_VALUE_SIGN 0x1000 | ||
62 | #define ADT7310_T13_VALUE_OFFSET 3 | ||
63 | #define ADT7310_T13_VALUE_FLOAT_OFFSET 4 | ||
64 | #define ADT7310_T13_VALUE_FLOAT_MASK 0xF | ||
65 | #define ADT7310_T_HYST_MASK 0xF | ||
66 | #define ADT7310_DEVICE_ID_MASK 0x7 | ||
67 | #define ADT7310_MANUFACTORY_ID_MASK 0xF8 | ||
68 | #define ADT7310_MANUFACTORY_ID_OFFSET 3 | ||
69 | |||
70 | |||
71 | #define ADT7310_CMD_REG_MASK 0x28 | ||
72 | #define ADT7310_CMD_REG_OFFSET 3 | ||
73 | #define ADT7310_CMD_READ 0x40 | ||
74 | #define ADT7310_CMD_CON_READ 0x4 | ||
75 | |||
76 | #define ADT7310_IRQS 2 | ||
77 | |||
78 | /* | ||
79 | * struct adt7310_chip_info - chip specifc information | ||
80 | */ | ||
81 | |||
82 | struct adt7310_chip_info { | ||
83 | struct spi_device *spi_dev; | ||
84 | u8 config; | ||
85 | }; | ||
86 | |||
87 | /* | ||
88 | * adt7310 register access by SPI | ||
89 | */ | ||
90 | |||
91 | static int adt7310_spi_read_word(struct adt7310_chip_info *chip, u8 reg, u16 *data) | ||
92 | { | ||
93 | struct spi_device *spi_dev = chip->spi_dev; | ||
94 | u8 command = (reg << ADT7310_CMD_REG_OFFSET) & ADT7310_CMD_REG_MASK; | ||
95 | int ret = 0; | ||
96 | |||
97 | command |= ADT7310_CMD_READ; | ||
98 | ret = spi_write(spi_dev, &command, sizeof(command)); | ||
99 | if (ret < 0) { | ||
100 | dev_err(&spi_dev->dev, "SPI write command error\n"); | ||
101 | return ret; | ||
102 | } | ||
103 | |||
104 | ret = spi_read(spi_dev, (u8 *)data, sizeof(*data)); | ||
105 | if (ret < 0) { | ||
106 | dev_err(&spi_dev->dev, "SPI read word error\n"); | ||
107 | return ret; | ||
108 | } | ||
109 | |||
110 | *data = be16_to_cpu(*data); | ||
111 | |||
112 | return 0; | ||
113 | } | ||
114 | |||
115 | static int adt7310_spi_write_word(struct adt7310_chip_info *chip, u8 reg, u16 data) | ||
116 | { | ||
117 | struct spi_device *spi_dev = chip->spi_dev; | ||
118 | u8 buf[3]; | ||
119 | int ret = 0; | ||
120 | |||
121 | buf[0] = (reg << ADT7310_CMD_REG_OFFSET) & ADT7310_CMD_REG_MASK; | ||
122 | buf[1] = (u8)(data >> 8); | ||
123 | buf[2] = (u8)(data & 0xFF); | ||
124 | |||
125 | ret = spi_write(spi_dev, buf, 3); | ||
126 | if (ret < 0) { | ||
127 | dev_err(&spi_dev->dev, "SPI write word error\n"); | ||
128 | return ret; | ||
129 | } | ||
130 | |||
131 | return ret; | ||
132 | } | ||
133 | |||
134 | static int adt7310_spi_read_byte(struct adt7310_chip_info *chip, u8 reg, u8 *data) | ||
135 | { | ||
136 | struct spi_device *spi_dev = chip->spi_dev; | ||
137 | u8 command = (reg << ADT7310_CMD_REG_OFFSET) & ADT7310_CMD_REG_MASK; | ||
138 | int ret = 0; | ||
139 | |||
140 | command |= ADT7310_CMD_READ; | ||
141 | ret = spi_write(spi_dev, &command, sizeof(command)); | ||
142 | if (ret < 0) { | ||
143 | dev_err(&spi_dev->dev, "SPI write command error\n"); | ||
144 | return ret; | ||
145 | } | ||
146 | |||
147 | ret = spi_read(spi_dev, data, sizeof(*data)); | ||
148 | if (ret < 0) { | ||
149 | dev_err(&spi_dev->dev, "SPI read byte error\n"); | ||
150 | return ret; | ||
151 | } | ||
152 | |||
153 | return 0; | ||
154 | } | ||
155 | |||
156 | static int adt7310_spi_write_byte(struct adt7310_chip_info *chip, u8 reg, u8 data) | ||
157 | { | ||
158 | struct spi_device *spi_dev = chip->spi_dev; | ||
159 | u8 buf[2]; | ||
160 | int ret = 0; | ||
161 | |||
162 | buf[0] = (reg << ADT7310_CMD_REG_OFFSET) & ADT7310_CMD_REG_MASK; | ||
163 | buf[1] = data; | ||
164 | |||
165 | ret = spi_write(spi_dev, buf, 2); | ||
166 | if (ret < 0) { | ||
167 | dev_err(&spi_dev->dev, "SPI write byte error\n"); | ||
168 | return ret; | ||
169 | } | ||
170 | |||
171 | return ret; | ||
172 | } | ||
173 | |||
174 | static ssize_t adt7310_show_mode(struct device *dev, | ||
175 | struct device_attribute *attr, | ||
176 | char *buf) | ||
177 | { | ||
178 | struct iio_dev *dev_info = dev_to_iio_dev(dev); | ||
179 | struct adt7310_chip_info *chip = iio_priv(dev_info); | ||
180 | u8 config; | ||
181 | |||
182 | config = chip->config & ADT7310_MODE_MASK; | ||
183 | |||
184 | switch (config) { | ||
185 | case ADT7310_PD: | ||
186 | return sprintf(buf, "power-down\n"); | ||
187 | case ADT7310_ONESHOT: | ||
188 | return sprintf(buf, "one-shot\n"); | ||
189 | case ADT7310_SPS: | ||
190 | return sprintf(buf, "sps\n"); | ||
191 | default: | ||
192 | return sprintf(buf, "full\n"); | ||
193 | } | ||
194 | } | ||
195 | |||
196 | static ssize_t adt7310_store_mode(struct device *dev, | ||
197 | struct device_attribute *attr, | ||
198 | const char *buf, | ||
199 | size_t len) | ||
200 | { | ||
201 | struct iio_dev *dev_info = dev_to_iio_dev(dev); | ||
202 | struct adt7310_chip_info *chip = iio_priv(dev_info); | ||
203 | u16 config; | ||
204 | int ret; | ||
205 | |||
206 | ret = adt7310_spi_read_byte(chip, ADT7310_CONFIG, &chip->config); | ||
207 | if (ret) | ||
208 | return -EIO; | ||
209 | |||
210 | config = chip->config & (~ADT7310_MODE_MASK); | ||
211 | if (strcmp(buf, "power-down")) | ||
212 | config |= ADT7310_PD; | ||
213 | else if (strcmp(buf, "one-shot")) | ||
214 | config |= ADT7310_ONESHOT; | ||
215 | else if (strcmp(buf, "sps")) | ||
216 | config |= ADT7310_SPS; | ||
217 | |||
218 | ret = adt7310_spi_write_byte(chip, ADT7310_CONFIG, config); | ||
219 | if (ret) | ||
220 | return -EIO; | ||
221 | |||
222 | chip->config = config; | ||
223 | |||
224 | return len; | ||
225 | } | ||
226 | |||
227 | static IIO_DEVICE_ATTR(mode, S_IRUGO | S_IWUSR, | ||
228 | adt7310_show_mode, | ||
229 | adt7310_store_mode, | ||
230 | 0); | ||
231 | |||
232 | static ssize_t adt7310_show_available_modes(struct device *dev, | ||
233 | struct device_attribute *attr, | ||
234 | char *buf) | ||
235 | { | ||
236 | return sprintf(buf, "full\none-shot\nsps\npower-down\n"); | ||
237 | } | ||
238 | |||
239 | static IIO_DEVICE_ATTR(available_modes, S_IRUGO, adt7310_show_available_modes, NULL, 0); | ||
240 | |||
241 | static ssize_t adt7310_show_resolution(struct device *dev, | ||
242 | struct device_attribute *attr, | ||
243 | char *buf) | ||
244 | { | ||
245 | struct iio_dev *dev_info = dev_to_iio_dev(dev); | ||
246 | struct adt7310_chip_info *chip = iio_priv(dev_info); | ||
247 | int ret; | ||
248 | int bits; | ||
249 | |||
250 | ret = adt7310_spi_read_byte(chip, ADT7310_CONFIG, &chip->config); | ||
251 | if (ret) | ||
252 | return -EIO; | ||
253 | |||
254 | if (chip->config & ADT7310_RESOLUTION) | ||
255 | bits = 16; | ||
256 | else | ||
257 | bits = 13; | ||
258 | |||
259 | return sprintf(buf, "%d bits\n", bits); | ||
260 | } | ||
261 | |||
262 | static ssize_t adt7310_store_resolution(struct device *dev, | ||
263 | struct device_attribute *attr, | ||
264 | const char *buf, | ||
265 | size_t len) | ||
266 | { | ||
267 | struct iio_dev *dev_info = dev_to_iio_dev(dev); | ||
268 | struct adt7310_chip_info *chip = iio_priv(dev_info); | ||
269 | unsigned long data; | ||
270 | u16 config; | ||
271 | int ret; | ||
272 | |||
273 | ret = strict_strtoul(buf, 10, &data); | ||
274 | if (ret) | ||
275 | return -EINVAL; | ||
276 | |||
277 | ret = adt7310_spi_read_byte(chip, ADT7310_CONFIG, &chip->config); | ||
278 | if (ret) | ||
279 | return -EIO; | ||
280 | |||
281 | config = chip->config & (~ADT7310_RESOLUTION); | ||
282 | if (data) | ||
283 | config |= ADT7310_RESOLUTION; | ||
284 | |||
285 | ret = adt7310_spi_write_byte(chip, ADT7310_CONFIG, config); | ||
286 | if (ret) | ||
287 | return -EIO; | ||
288 | |||
289 | chip->config = config; | ||
290 | |||
291 | return len; | ||
292 | } | ||
293 | |||
294 | static IIO_DEVICE_ATTR(resolution, S_IRUGO | S_IWUSR, | ||
295 | adt7310_show_resolution, | ||
296 | adt7310_store_resolution, | ||
297 | 0); | ||
298 | |||
299 | static ssize_t adt7310_show_id(struct device *dev, | ||
300 | struct device_attribute *attr, | ||
301 | char *buf) | ||
302 | { | ||
303 | struct iio_dev *dev_info = dev_to_iio_dev(dev); | ||
304 | struct adt7310_chip_info *chip = iio_priv(dev_info); | ||
305 | u8 id; | ||
306 | int ret; | ||
307 | |||
308 | ret = adt7310_spi_read_byte(chip, ADT7310_ID, &id); | ||
309 | if (ret) | ||
310 | return -EIO; | ||
311 | |||
312 | return sprintf(buf, "device id: 0x%x\nmanufactory id: 0x%x\n", | ||
313 | id & ADT7310_DEVICE_ID_MASK, | ||
314 | (id & ADT7310_MANUFACTORY_ID_MASK) >> ADT7310_MANUFACTORY_ID_OFFSET); | ||
315 | } | ||
316 | |||
317 | static IIO_DEVICE_ATTR(id, S_IRUGO | S_IWUSR, | ||
318 | adt7310_show_id, | ||
319 | NULL, | ||
320 | 0); | ||
321 | |||
322 | static ssize_t adt7310_convert_temperature(struct adt7310_chip_info *chip, | ||
323 | u16 data, char *buf) | ||
324 | { | ||
325 | char sign = ' '; | ||
326 | |||
327 | if (chip->config & ADT7310_RESOLUTION) { | ||
328 | if (data & ADT7310_T16_VALUE_SIGN) { | ||
329 | /* convert supplement to positive value */ | ||
330 | data = (u16)((ADT7310_T16_VALUE_SIGN << 1) - (u32)data); | ||
331 | sign = '-'; | ||
332 | } | ||
333 | return sprintf(buf, "%c%d.%.7d\n", sign, | ||
334 | (data >> ADT7310_T16_VALUE_FLOAT_OFFSET), | ||
335 | (data & ADT7310_T16_VALUE_FLOAT_MASK) * 78125); | ||
336 | } else { | ||
337 | if (data & ADT7310_T13_VALUE_SIGN) { | ||
338 | /* convert supplement to positive value */ | ||
339 | data >>= ADT7310_T13_VALUE_OFFSET; | ||
340 | data = (ADT7310_T13_VALUE_SIGN << 1) - data; | ||
341 | sign = '-'; | ||
342 | } | ||
343 | return sprintf(buf, "%c%d.%.4d\n", sign, | ||
344 | (data >> ADT7310_T13_VALUE_FLOAT_OFFSET), | ||
345 | (data & ADT7310_T13_VALUE_FLOAT_MASK) * 625); | ||
346 | } | ||
347 | } | ||
348 | |||
349 | static ssize_t adt7310_show_value(struct device *dev, | ||
350 | struct device_attribute *attr, | ||
351 | char *buf) | ||
352 | { | ||
353 | struct iio_dev *dev_info = dev_to_iio_dev(dev); | ||
354 | struct adt7310_chip_info *chip = iio_priv(dev_info); | ||
355 | u8 status; | ||
356 | u16 data; | ||
357 | int ret, i = 0; | ||
358 | |||
359 | do { | ||
360 | ret = adt7310_spi_read_byte(chip, ADT7310_STATUS, &status); | ||
361 | if (ret) | ||
362 | return -EIO; | ||
363 | i++; | ||
364 | if (i == 10000) | ||
365 | return -EIO; | ||
366 | } while (status & ADT7310_STAT_NOT_RDY); | ||
367 | |||
368 | ret = adt7310_spi_read_word(chip, ADT7310_TEMPERATURE, &data); | ||
369 | if (ret) | ||
370 | return -EIO; | ||
371 | |||
372 | return adt7310_convert_temperature(chip, data, buf); | ||
373 | } | ||
374 | |||
375 | static IIO_DEVICE_ATTR(value, S_IRUGO, adt7310_show_value, NULL, 0); | ||
376 | |||
377 | static struct attribute *adt7310_attributes[] = { | ||
378 | &iio_dev_attr_available_modes.dev_attr.attr, | ||
379 | &iio_dev_attr_mode.dev_attr.attr, | ||
380 | &iio_dev_attr_resolution.dev_attr.attr, | ||
381 | &iio_dev_attr_id.dev_attr.attr, | ||
382 | &iio_dev_attr_value.dev_attr.attr, | ||
383 | NULL, | ||
384 | }; | ||
385 | |||
386 | static const struct attribute_group adt7310_attribute_group = { | ||
387 | .attrs = adt7310_attributes, | ||
388 | }; | ||
389 | |||
390 | static irqreturn_t adt7310_event_handler(int irq, void *private) | ||
391 | { | ||
392 | struct iio_dev *indio_dev = private; | ||
393 | struct adt7310_chip_info *chip = iio_priv(indio_dev); | ||
394 | s64 timestamp = iio_get_time_ns(); | ||
395 | u8 status; | ||
396 | int ret; | ||
397 | |||
398 | ret = adt7310_spi_read_byte(chip, ADT7310_STATUS, &status); | ||
399 | if (ret) | ||
400 | goto done; | ||
401 | |||
402 | if (status & ADT7310_STAT_T_HIGH) | ||
403 | iio_push_event(indio_dev, | ||
404 | IIO_UNMOD_EVENT_CODE(IIO_TEMP, 0, | ||
405 | IIO_EV_TYPE_THRESH, | ||
406 | IIO_EV_DIR_RISING), | ||
407 | timestamp); | ||
408 | if (status & ADT7310_STAT_T_LOW) | ||
409 | iio_push_event(indio_dev, | ||
410 | IIO_UNMOD_EVENT_CODE(IIO_TEMP, 0, | ||
411 | IIO_EV_TYPE_THRESH, | ||
412 | IIO_EV_DIR_FALLING), | ||
413 | timestamp); | ||
414 | if (status & ADT7310_STAT_T_CRIT) | ||
415 | iio_push_event(indio_dev, | ||
416 | IIO_UNMOD_EVENT_CODE(IIO_TEMP, 0, | ||
417 | IIO_EV_TYPE_THRESH, | ||
418 | IIO_EV_DIR_RISING), | ||
419 | timestamp); | ||
420 | |||
421 | done: | ||
422 | return IRQ_HANDLED; | ||
423 | } | ||
424 | |||
425 | static ssize_t adt7310_show_event_mode(struct device *dev, | ||
426 | struct device_attribute *attr, | ||
427 | char *buf) | ||
428 | { | ||
429 | struct iio_dev *dev_info = dev_to_iio_dev(dev); | ||
430 | struct adt7310_chip_info *chip = iio_priv(dev_info); | ||
431 | int ret; | ||
432 | |||
433 | ret = adt7310_spi_read_byte(chip, ADT7310_CONFIG, &chip->config); | ||
434 | if (ret) | ||
435 | return -EIO; | ||
436 | |||
437 | if (chip->config & ADT7310_EVENT_MODE) | ||
438 | return sprintf(buf, "interrupt\n"); | ||
439 | else | ||
440 | return sprintf(buf, "comparator\n"); | ||
441 | } | ||
442 | |||
443 | static ssize_t adt7310_set_event_mode(struct device *dev, | ||
444 | struct device_attribute *attr, | ||
445 | const char *buf, | ||
446 | size_t len) | ||
447 | { | ||
448 | struct iio_dev *dev_info = dev_to_iio_dev(dev); | ||
449 | struct adt7310_chip_info *chip = iio_priv(dev_info); | ||
450 | u16 config; | ||
451 | int ret; | ||
452 | |||
453 | ret = adt7310_spi_read_byte(chip, ADT7310_CONFIG, &chip->config); | ||
454 | if (ret) | ||
455 | return -EIO; | ||
456 | |||
457 | config = chip->config &= ~ADT7310_EVENT_MODE; | ||
458 | if (strcmp(buf, "comparator") != 0) | ||
459 | config |= ADT7310_EVENT_MODE; | ||
460 | |||
461 | ret = adt7310_spi_write_byte(chip, ADT7310_CONFIG, config); | ||
462 | if (ret) | ||
463 | return -EIO; | ||
464 | |||
465 | chip->config = config; | ||
466 | |||
467 | return len; | ||
468 | } | ||
469 | |||
470 | static ssize_t adt7310_show_available_event_modes(struct device *dev, | ||
471 | struct device_attribute *attr, | ||
472 | char *buf) | ||
473 | { | ||
474 | return sprintf(buf, "comparator\ninterrupt\n"); | ||
475 | } | ||
476 | |||
477 | static ssize_t adt7310_show_fault_queue(struct device *dev, | ||
478 | struct device_attribute *attr, | ||
479 | char *buf) | ||
480 | { | ||
481 | struct iio_dev *dev_info = dev_to_iio_dev(dev); | ||
482 | struct adt7310_chip_info *chip = iio_priv(dev_info); | ||
483 | int ret; | ||
484 | |||
485 | ret = adt7310_spi_read_byte(chip, ADT7310_CONFIG, &chip->config); | ||
486 | if (ret) | ||
487 | return -EIO; | ||
488 | |||
489 | return sprintf(buf, "%d\n", chip->config & ADT7310_FAULT_QUEUE_MASK); | ||
490 | } | ||
491 | |||
492 | static ssize_t adt7310_set_fault_queue(struct device *dev, | ||
493 | struct device_attribute *attr, | ||
494 | const char *buf, | ||
495 | size_t len) | ||
496 | { | ||
497 | struct iio_dev *dev_info = dev_to_iio_dev(dev); | ||
498 | struct adt7310_chip_info *chip = iio_priv(dev_info); | ||
499 | unsigned long data; | ||
500 | int ret; | ||
501 | u8 config; | ||
502 | |||
503 | ret = strict_strtoul(buf, 10, &data); | ||
504 | if (ret || data > 3) | ||
505 | return -EINVAL; | ||
506 | |||
507 | ret = adt7310_spi_read_byte(chip, ADT7310_CONFIG, &chip->config); | ||
508 | if (ret) | ||
509 | return -EIO; | ||
510 | |||
511 | config = chip->config & ~ADT7310_FAULT_QUEUE_MASK; | ||
512 | config |= data; | ||
513 | ret = adt7310_spi_write_byte(chip, ADT7310_CONFIG, config); | ||
514 | if (ret) | ||
515 | return -EIO; | ||
516 | |||
517 | chip->config = config; | ||
518 | |||
519 | return len; | ||
520 | } | ||
521 | |||
522 | static inline ssize_t adt7310_show_t_bound(struct device *dev, | ||
523 | struct device_attribute *attr, | ||
524 | u8 bound_reg, | ||
525 | char *buf) | ||
526 | { | ||
527 | struct iio_dev *dev_info = dev_to_iio_dev(dev); | ||
528 | struct adt7310_chip_info *chip = iio_priv(dev_info); | ||
529 | u16 data; | ||
530 | int ret; | ||
531 | |||
532 | ret = adt7310_spi_read_word(chip, bound_reg, &data); | ||
533 | if (ret) | ||
534 | return -EIO; | ||
535 | |||
536 | return adt7310_convert_temperature(chip, data, buf); | ||
537 | } | ||
538 | |||
539 | static inline ssize_t adt7310_set_t_bound(struct device *dev, | ||
540 | struct device_attribute *attr, | ||
541 | u8 bound_reg, | ||
542 | const char *buf, | ||
543 | size_t len) | ||
544 | { | ||
545 | struct iio_dev *dev_info = dev_to_iio_dev(dev); | ||
546 | struct adt7310_chip_info *chip = iio_priv(dev_info); | ||
547 | long tmp1, tmp2; | ||
548 | u16 data; | ||
549 | char *pos; | ||
550 | int ret; | ||
551 | |||
552 | pos = strchr(buf, '.'); | ||
553 | |||
554 | ret = strict_strtol(buf, 10, &tmp1); | ||
555 | |||
556 | if (ret || tmp1 > 127 || tmp1 < -128) | ||
557 | return -EINVAL; | ||
558 | |||
559 | if (pos) { | ||
560 | len = strlen(pos); | ||
561 | |||
562 | if (chip->config & ADT7310_RESOLUTION) { | ||
563 | if (len > ADT7310_T16_VALUE_FLOAT_OFFSET) | ||
564 | len = ADT7310_T16_VALUE_FLOAT_OFFSET; | ||
565 | pos[len] = 0; | ||
566 | ret = strict_strtol(pos, 10, &tmp2); | ||
567 | |||
568 | if (!ret) | ||
569 | tmp2 = (tmp2 / 78125) * 78125; | ||
570 | } else { | ||
571 | if (len > ADT7310_T13_VALUE_FLOAT_OFFSET) | ||
572 | len = ADT7310_T13_VALUE_FLOAT_OFFSET; | ||
573 | pos[len] = 0; | ||
574 | ret = strict_strtol(pos, 10, &tmp2); | ||
575 | |||
576 | if (!ret) | ||
577 | tmp2 = (tmp2 / 625) * 625; | ||
578 | } | ||
579 | } | ||
580 | |||
581 | if (tmp1 < 0) | ||
582 | data = (u16)(-tmp1); | ||
583 | else | ||
584 | data = (u16)tmp1; | ||
585 | |||
586 | if (chip->config & ADT7310_RESOLUTION) { | ||
587 | data = (data << ADT7310_T16_VALUE_FLOAT_OFFSET) | | ||
588 | (tmp2 & ADT7310_T16_VALUE_FLOAT_MASK); | ||
589 | |||
590 | if (tmp1 < 0) | ||
591 | /* convert positive value to supplyment */ | ||
592 | data = (u16)((ADT7310_T16_VALUE_SIGN << 1) - (u32)data); | ||
593 | } else { | ||
594 | data = (data << ADT7310_T13_VALUE_FLOAT_OFFSET) | | ||
595 | (tmp2 & ADT7310_T13_VALUE_FLOAT_MASK); | ||
596 | |||
597 | if (tmp1 < 0) | ||
598 | /* convert positive value to supplyment */ | ||
599 | data = (ADT7310_T13_VALUE_SIGN << 1) - data; | ||
600 | data <<= ADT7310_T13_VALUE_OFFSET; | ||
601 | } | ||
602 | |||
603 | ret = adt7310_spi_write_word(chip, bound_reg, data); | ||
604 | if (ret) | ||
605 | return -EIO; | ||
606 | |||
607 | return len; | ||
608 | } | ||
609 | |||
610 | static ssize_t adt7310_show_t_alarm_high(struct device *dev, | ||
611 | struct device_attribute *attr, | ||
612 | char *buf) | ||
613 | { | ||
614 | return adt7310_show_t_bound(dev, attr, | ||
615 | ADT7310_T_ALARM_HIGH, buf); | ||
616 | } | ||
617 | |||
618 | static inline ssize_t adt7310_set_t_alarm_high(struct device *dev, | ||
619 | struct device_attribute *attr, | ||
620 | const char *buf, | ||
621 | size_t len) | ||
622 | { | ||
623 | return adt7310_set_t_bound(dev, attr, | ||
624 | ADT7310_T_ALARM_HIGH, buf, len); | ||
625 | } | ||
626 | |||
627 | static ssize_t adt7310_show_t_alarm_low(struct device *dev, | ||
628 | struct device_attribute *attr, | ||
629 | char *buf) | ||
630 | { | ||
631 | return adt7310_show_t_bound(dev, attr, | ||
632 | ADT7310_T_ALARM_LOW, buf); | ||
633 | } | ||
634 | |||
635 | static inline ssize_t adt7310_set_t_alarm_low(struct device *dev, | ||
636 | struct device_attribute *attr, | ||
637 | const char *buf, | ||
638 | size_t len) | ||
639 | { | ||
640 | return adt7310_set_t_bound(dev, attr, | ||
641 | ADT7310_T_ALARM_LOW, buf, len); | ||
642 | } | ||
643 | |||
644 | static ssize_t adt7310_show_t_crit(struct device *dev, | ||
645 | struct device_attribute *attr, | ||
646 | char *buf) | ||
647 | { | ||
648 | return adt7310_show_t_bound(dev, attr, | ||
649 | ADT7310_T_CRIT, buf); | ||
650 | } | ||
651 | |||
652 | static inline ssize_t adt7310_set_t_crit(struct device *dev, | ||
653 | struct device_attribute *attr, | ||
654 | const char *buf, | ||
655 | size_t len) | ||
656 | { | ||
657 | return adt7310_set_t_bound(dev, attr, | ||
658 | ADT7310_T_CRIT, buf, len); | ||
659 | } | ||
660 | |||
661 | static ssize_t adt7310_show_t_hyst(struct device *dev, | ||
662 | struct device_attribute *attr, | ||
663 | char *buf) | ||
664 | { | ||
665 | struct iio_dev *dev_info = dev_to_iio_dev(dev); | ||
666 | struct adt7310_chip_info *chip = iio_priv(dev_info); | ||
667 | int ret; | ||
668 | u8 t_hyst; | ||
669 | |||
670 | ret = adt7310_spi_read_byte(chip, ADT7310_T_HYST, &t_hyst); | ||
671 | if (ret) | ||
672 | return -EIO; | ||
673 | |||
674 | return sprintf(buf, "%d\n", t_hyst & ADT7310_T_HYST_MASK); | ||
675 | } | ||
676 | |||
677 | static inline ssize_t adt7310_set_t_hyst(struct device *dev, | ||
678 | struct device_attribute *attr, | ||
679 | const char *buf, | ||
680 | size_t len) | ||
681 | { | ||
682 | struct iio_dev *dev_info = dev_to_iio_dev(dev); | ||
683 | struct adt7310_chip_info *chip = iio_priv(dev_info); | ||
684 | int ret; | ||
685 | unsigned long data; | ||
686 | u8 t_hyst; | ||
687 | |||
688 | ret = strict_strtol(buf, 10, &data); | ||
689 | |||
690 | if (ret || data > ADT7310_T_HYST_MASK) | ||
691 | return -EINVAL; | ||
692 | |||
693 | t_hyst = (u8)data; | ||
694 | |||
695 | ret = adt7310_spi_write_byte(chip, ADT7310_T_HYST, t_hyst); | ||
696 | if (ret) | ||
697 | return -EIO; | ||
698 | |||
699 | return len; | ||
700 | } | ||
701 | |||
702 | static IIO_DEVICE_ATTR(event_mode, | ||
703 | S_IRUGO | S_IWUSR, | ||
704 | adt7310_show_event_mode, adt7310_set_event_mode, 0); | ||
705 | static IIO_DEVICE_ATTR(available_event_modes, | ||
706 | S_IRUGO | S_IWUSR, | ||
707 | adt7310_show_available_event_modes, NULL, 0); | ||
708 | static IIO_DEVICE_ATTR(fault_queue, | ||
709 | S_IRUGO | S_IWUSR, | ||
710 | adt7310_show_fault_queue, adt7310_set_fault_queue, 0); | ||
711 | static IIO_DEVICE_ATTR(t_alarm_high, | ||
712 | S_IRUGO | S_IWUSR, | ||
713 | adt7310_show_t_alarm_high, adt7310_set_t_alarm_high, 0); | ||
714 | static IIO_DEVICE_ATTR(t_alarm_low, | ||
715 | S_IRUGO | S_IWUSR, | ||
716 | adt7310_show_t_alarm_low, adt7310_set_t_alarm_low, 0); | ||
717 | static IIO_DEVICE_ATTR(t_crit, | ||
718 | S_IRUGO | S_IWUSR, | ||
719 | adt7310_show_t_crit, adt7310_set_t_crit, 0); | ||
720 | static IIO_DEVICE_ATTR(t_hyst, | ||
721 | S_IRUGO | S_IWUSR, | ||
722 | adt7310_show_t_hyst, adt7310_set_t_hyst, 0); | ||
723 | |||
724 | static struct attribute *adt7310_event_int_attributes[] = { | ||
725 | &iio_dev_attr_event_mode.dev_attr.attr, | ||
726 | &iio_dev_attr_available_event_modes.dev_attr.attr, | ||
727 | &iio_dev_attr_fault_queue.dev_attr.attr, | ||
728 | &iio_dev_attr_t_alarm_high.dev_attr.attr, | ||
729 | &iio_dev_attr_t_alarm_low.dev_attr.attr, | ||
730 | &iio_dev_attr_t_crit.dev_attr.attr, | ||
731 | &iio_dev_attr_t_hyst.dev_attr.attr, | ||
732 | NULL, | ||
733 | }; | ||
734 | |||
735 | static struct attribute_group adt7310_event_attribute_group = { | ||
736 | .attrs = adt7310_event_int_attributes, | ||
737 | .name = "events", | ||
738 | }; | ||
739 | |||
740 | static const struct iio_info adt7310_info = { | ||
741 | .attrs = &adt7310_attribute_group, | ||
742 | .event_attrs = &adt7310_event_attribute_group, | ||
743 | .driver_module = THIS_MODULE, | ||
744 | }; | ||
745 | |||
746 | /* | ||
747 | * device probe and remove | ||
748 | */ | ||
749 | |||
750 | static int __devinit adt7310_probe(struct spi_device *spi_dev) | ||
751 | { | ||
752 | struct adt7310_chip_info *chip; | ||
753 | struct iio_dev *indio_dev; | ||
754 | int ret = 0; | ||
755 | unsigned long *adt7310_platform_data = spi_dev->dev.platform_data; | ||
756 | unsigned long irq_flags; | ||
757 | |||
758 | indio_dev = iio_device_alloc(sizeof(*chip)); | ||
759 | if (indio_dev == NULL) { | ||
760 | ret = -ENOMEM; | ||
761 | goto error_ret; | ||
762 | } | ||
763 | chip = iio_priv(indio_dev); | ||
764 | /* this is only used for device removal purposes */ | ||
765 | dev_set_drvdata(&spi_dev->dev, indio_dev); | ||
766 | |||
767 | chip->spi_dev = spi_dev; | ||
768 | |||
769 | indio_dev->dev.parent = &spi_dev->dev; | ||
770 | indio_dev->name = spi_get_device_id(spi_dev)->name; | ||
771 | indio_dev->info = &adt7310_info; | ||
772 | indio_dev->modes = INDIO_DIRECT_MODE; | ||
773 | |||
774 | /* CT critcal temperature event. line 0 */ | ||
775 | if (spi_dev->irq) { | ||
776 | if (adt7310_platform_data[2]) | ||
777 | irq_flags = adt7310_platform_data[2]; | ||
778 | else | ||
779 | irq_flags = IRQF_TRIGGER_LOW; | ||
780 | ret = request_threaded_irq(spi_dev->irq, | ||
781 | NULL, | ||
782 | &adt7310_event_handler, | ||
783 | irq_flags | IRQF_ONESHOT, | ||
784 | indio_dev->name, | ||
785 | indio_dev); | ||
786 | if (ret) | ||
787 | goto error_free_dev; | ||
788 | } | ||
789 | |||
790 | /* INT bound temperature alarm event. line 1 */ | ||
791 | if (adt7310_platform_data[0]) { | ||
792 | ret = request_threaded_irq(adt7310_platform_data[0], | ||
793 | NULL, | ||
794 | &adt7310_event_handler, | ||
795 | adt7310_platform_data[1] | | ||
796 | IRQF_ONESHOT, | ||
797 | indio_dev->name, | ||
798 | indio_dev); | ||
799 | if (ret) | ||
800 | goto error_unreg_ct_irq; | ||
801 | } | ||
802 | |||
803 | if (spi_dev->irq && adt7310_platform_data[0]) { | ||
804 | ret = adt7310_spi_read_byte(chip, ADT7310_CONFIG, &chip->config); | ||
805 | if (ret) { | ||
806 | ret = -EIO; | ||
807 | goto error_unreg_int_irq; | ||
808 | } | ||
809 | |||
810 | /* set irq polarity low level */ | ||
811 | chip->config &= ~ADT7310_CT_POLARITY; | ||
812 | |||
813 | if (adt7310_platform_data[1] & IRQF_TRIGGER_HIGH) | ||
814 | chip->config |= ADT7310_INT_POLARITY; | ||
815 | else | ||
816 | chip->config &= ~ADT7310_INT_POLARITY; | ||
817 | |||
818 | ret = adt7310_spi_write_byte(chip, ADT7310_CONFIG, chip->config); | ||
819 | if (ret) { | ||
820 | ret = -EIO; | ||
821 | goto error_unreg_int_irq; | ||
822 | } | ||
823 | } | ||
824 | |||
825 | ret = iio_device_register(indio_dev); | ||
826 | if (ret) | ||
827 | goto error_unreg_int_irq; | ||
828 | |||
829 | dev_info(&spi_dev->dev, "%s temperature sensor registered.\n", | ||
830 | indio_dev->name); | ||
831 | |||
832 | return 0; | ||
833 | |||
834 | error_unreg_int_irq: | ||
835 | free_irq(adt7310_platform_data[0], indio_dev); | ||
836 | error_unreg_ct_irq: | ||
837 | free_irq(spi_dev->irq, indio_dev); | ||
838 | error_free_dev: | ||
839 | iio_device_free(indio_dev); | ||
840 | error_ret: | ||
841 | return ret; | ||
842 | } | ||
843 | |||
844 | static int __devexit adt7310_remove(struct spi_device *spi_dev) | ||
845 | { | ||
846 | struct iio_dev *indio_dev = dev_get_drvdata(&spi_dev->dev); | ||
847 | unsigned long *adt7310_platform_data = spi_dev->dev.platform_data; | ||
848 | |||
849 | iio_device_unregister(indio_dev); | ||
850 | dev_set_drvdata(&spi_dev->dev, NULL); | ||
851 | if (adt7310_platform_data[0]) | ||
852 | free_irq(adt7310_platform_data[0], indio_dev); | ||
853 | if (spi_dev->irq) | ||
854 | free_irq(spi_dev->irq, indio_dev); | ||
855 | iio_device_free(indio_dev); | ||
856 | |||
857 | return 0; | ||
858 | } | ||
859 | |||
860 | static const struct spi_device_id adt7310_id[] = { | ||
861 | { "adt7310", 0 }, | ||
862 | {} | ||
863 | }; | ||
864 | |||
865 | MODULE_DEVICE_TABLE(spi, adt7310_id); | ||
866 | |||
867 | static struct spi_driver adt7310_driver = { | ||
868 | .driver = { | ||
869 | .name = "adt7310", | ||
870 | .owner = THIS_MODULE, | ||
871 | }, | ||
872 | .probe = adt7310_probe, | ||
873 | .remove = __devexit_p(adt7310_remove), | ||
874 | .id_table = adt7310_id, | ||
875 | }; | ||
876 | module_spi_driver(adt7310_driver); | ||
877 | |||
878 | MODULE_AUTHOR("Sonic Zhang <sonic.zhang@analog.com>"); | ||
879 | MODULE_DESCRIPTION("Analog Devices ADT7310 digital" | ||
880 | " temperature sensor driver"); | ||
881 | MODULE_LICENSE("GPL v2"); | ||
diff --git a/drivers/staging/iio/adc/adt7410.c b/drivers/staging/iio/adc/adt7410.c index 4157596ea3b0..5e93d868b3fe 100644 --- a/drivers/staging/iio/adc/adt7410.c +++ b/drivers/staging/iio/adc/adt7410.c | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * ADT7410 digital temperature sensor driver supporting ADT7410 | 2 | * ADT7410 digital temperature sensor driver supporting ADT7310/ADT7410 |
3 | * | 3 | * |
4 | * Copyright 2010 Analog Devices Inc. | 4 | * Copyright 2010 Analog Devices Inc. |
5 | * | 5 | * |
@@ -13,6 +13,7 @@ | |||
13 | #include <linux/sysfs.h> | 13 | #include <linux/sysfs.h> |
14 | #include <linux/list.h> | 14 | #include <linux/list.h> |
15 | #include <linux/i2c.h> | 15 | #include <linux/i2c.h> |
16 | #include <linux/spi/spi.h> | ||
16 | #include <linux/module.h> | 17 | #include <linux/module.h> |
17 | 18 | ||
18 | #include <linux/iio/iio.h> | 19 | #include <linux/iio/iio.h> |
@@ -34,6 +35,19 @@ | |||
34 | #define ADT7410_RESET 0x2F | 35 | #define ADT7410_RESET 0x2F |
35 | 36 | ||
36 | /* | 37 | /* |
38 | * ADT7310 registers definition | ||
39 | */ | ||
40 | |||
41 | #define ADT7310_STATUS 0 | ||
42 | #define ADT7310_CONFIG 1 | ||
43 | #define ADT7310_TEMPERATURE 2 | ||
44 | #define ADT7310_ID 3 | ||
45 | #define ADT7310_T_CRIT 4 | ||
46 | #define ADT7310_T_HYST 5 | ||
47 | #define ADT7310_T_ALARM_HIGH 6 | ||
48 | #define ADT7310_T_ALARM_LOW 7 | ||
49 | |||
50 | /* | ||
37 | * ADT7410 status | 51 | * ADT7410 status |
38 | */ | 52 | */ |
39 | #define ADT7410_STAT_T_LOW 0x10 | 53 | #define ADT7410_STAT_T_LOW 0x10 |
@@ -69,75 +83,52 @@ | |||
69 | #define ADT7410_MANUFACTORY_ID_MASK 0xF0 | 83 | #define ADT7410_MANUFACTORY_ID_MASK 0xF0 |
70 | #define ADT7410_MANUFACTORY_ID_OFFSET 4 | 84 | #define ADT7410_MANUFACTORY_ID_OFFSET 4 |
71 | 85 | ||
86 | |||
87 | #define ADT7310_CMD_REG_MASK 0x28 | ||
88 | #define ADT7310_CMD_REG_OFFSET 3 | ||
89 | #define ADT7310_CMD_READ 0x40 | ||
90 | #define ADT7310_CMD_CON_READ 0x4 | ||
91 | |||
72 | #define ADT7410_IRQS 2 | 92 | #define ADT7410_IRQS 2 |
73 | 93 | ||
74 | /* | 94 | /* |
75 | * struct adt7410_chip_info - chip specifc information | 95 | * struct adt7410_chip_info - chip specifc information |
76 | */ | 96 | */ |
77 | 97 | ||
98 | struct adt7410_chip_info; | ||
99 | |||
100 | struct adt7410_ops { | ||
101 | int (*read_word)(struct adt7410_chip_info *, u8 reg, u16 *data); | ||
102 | int (*write_word)(struct adt7410_chip_info *, u8 reg, u16 data); | ||
103 | int (*read_byte)(struct adt7410_chip_info *, u8 reg, u8 *data); | ||
104 | int (*write_byte)(struct adt7410_chip_info *, u8 reg, u8 data); | ||
105 | }; | ||
106 | |||
78 | struct adt7410_chip_info { | 107 | struct adt7410_chip_info { |
79 | struct i2c_client *client; | 108 | struct device *dev; |
80 | u8 config; | 109 | u8 config; |
81 | }; | ||
82 | 110 | ||
83 | /* | 111 | const struct adt7410_ops *ops; |
84 | * adt7410 register access by I2C | 112 | }; |
85 | */ | ||
86 | 113 | ||
87 | static int adt7410_i2c_read_word(struct adt7410_chip_info *chip, u8 reg, u16 *data) | 114 | static int adt7410_read_word(struct adt7410_chip_info *chip, u8 reg, u16 *data) |
88 | { | 115 | { |
89 | struct i2c_client *client = chip->client; | 116 | return chip->ops->read_word(chip, reg, data); |
90 | int ret = 0; | ||
91 | |||
92 | ret = i2c_smbus_read_word_data(client, reg); | ||
93 | if (ret < 0) { | ||
94 | dev_err(&client->dev, "I2C read error\n"); | ||
95 | return ret; | ||
96 | } | ||
97 | |||
98 | *data = swab16((u16)ret); | ||
99 | |||
100 | return 0; | ||
101 | } | 117 | } |
102 | 118 | ||
103 | static int adt7410_i2c_write_word(struct adt7410_chip_info *chip, u8 reg, u16 data) | 119 | static int adt7410_write_word(struct adt7410_chip_info *chip, u8 reg, u16 data) |
104 | { | 120 | { |
105 | struct i2c_client *client = chip->client; | 121 | return chip->ops->write_word(chip, reg, data); |
106 | int ret = 0; | ||
107 | |||
108 | ret = i2c_smbus_write_word_data(client, reg, swab16(data)); | ||
109 | if (ret < 0) | ||
110 | dev_err(&client->dev, "I2C write error\n"); | ||
111 | |||
112 | return ret; | ||
113 | } | 122 | } |
114 | 123 | ||
115 | static int adt7410_i2c_read_byte(struct adt7410_chip_info *chip, u8 reg, u8 *data) | 124 | static int adt7410_read_byte(struct adt7410_chip_info *chip, u8 reg, u8 *data) |
116 | { | 125 | { |
117 | struct i2c_client *client = chip->client; | 126 | return chip->ops->read_byte(chip, reg, data); |
118 | int ret = 0; | ||
119 | |||
120 | ret = i2c_smbus_read_byte_data(client, reg); | ||
121 | if (ret < 0) { | ||
122 | dev_err(&client->dev, "I2C read error\n"); | ||
123 | return ret; | ||
124 | } | ||
125 | |||
126 | *data = (u8)ret; | ||
127 | |||
128 | return 0; | ||
129 | } | 127 | } |
130 | 128 | ||
131 | static int adt7410_i2c_write_byte(struct adt7410_chip_info *chip, u8 reg, u8 data) | 129 | static int adt7410_write_byte(struct adt7410_chip_info *chip, u8 reg, u8 data) |
132 | { | 130 | { |
133 | struct i2c_client *client = chip->client; | 131 | return chip->ops->write_byte(chip, reg, data); |
134 | int ret = 0; | ||
135 | |||
136 | ret = i2c_smbus_write_byte_data(client, reg, data); | ||
137 | if (ret < 0) | ||
138 | dev_err(&client->dev, "I2C write error\n"); | ||
139 | |||
140 | return ret; | ||
141 | } | 132 | } |
142 | 133 | ||
143 | static ssize_t adt7410_show_mode(struct device *dev, | 134 | static ssize_t adt7410_show_mode(struct device *dev, |
@@ -172,7 +163,7 @@ static ssize_t adt7410_store_mode(struct device *dev, | |||
172 | u16 config; | 163 | u16 config; |
173 | int ret; | 164 | int ret; |
174 | 165 | ||
175 | ret = adt7410_i2c_read_byte(chip, ADT7410_CONFIG, &chip->config); | 166 | ret = adt7410_read_byte(chip, ADT7410_CONFIG, &chip->config); |
176 | if (ret) | 167 | if (ret) |
177 | return -EIO; | 168 | return -EIO; |
178 | 169 | ||
@@ -184,7 +175,7 @@ static ssize_t adt7410_store_mode(struct device *dev, | |||
184 | else if (strcmp(buf, "sps")) | 175 | else if (strcmp(buf, "sps")) |
185 | config |= ADT7410_SPS; | 176 | config |= ADT7410_SPS; |
186 | 177 | ||
187 | ret = adt7410_i2c_write_byte(chip, ADT7410_CONFIG, config); | 178 | ret = adt7410_write_byte(chip, ADT7410_CONFIG, config); |
188 | if (ret) | 179 | if (ret) |
189 | return -EIO; | 180 | return -EIO; |
190 | 181 | ||
@@ -216,7 +207,7 @@ static ssize_t adt7410_show_resolution(struct device *dev, | |||
216 | int ret; | 207 | int ret; |
217 | int bits; | 208 | int bits; |
218 | 209 | ||
219 | ret = adt7410_i2c_read_byte(chip, ADT7410_CONFIG, &chip->config); | 210 | ret = adt7410_read_byte(chip, ADT7410_CONFIG, &chip->config); |
220 | if (ret) | 211 | if (ret) |
221 | return -EIO; | 212 | return -EIO; |
222 | 213 | ||
@@ -243,7 +234,7 @@ static ssize_t adt7410_store_resolution(struct device *dev, | |||
243 | if (ret) | 234 | if (ret) |
244 | return -EINVAL; | 235 | return -EINVAL; |
245 | 236 | ||
246 | ret = adt7410_i2c_read_byte(chip, ADT7410_CONFIG, &chip->config); | 237 | ret = adt7410_read_byte(chip, ADT7410_CONFIG, &chip->config); |
247 | if (ret) | 238 | if (ret) |
248 | return -EIO; | 239 | return -EIO; |
249 | 240 | ||
@@ -251,7 +242,7 @@ static ssize_t adt7410_store_resolution(struct device *dev, | |||
251 | if (data) | 242 | if (data) |
252 | config |= ADT7410_RESOLUTION; | 243 | config |= ADT7410_RESOLUTION; |
253 | 244 | ||
254 | ret = adt7410_i2c_write_byte(chip, ADT7410_CONFIG, config); | 245 | ret = adt7410_write_byte(chip, ADT7410_CONFIG, config); |
255 | if (ret) | 246 | if (ret) |
256 | return -EIO; | 247 | return -EIO; |
257 | 248 | ||
@@ -274,7 +265,7 @@ static ssize_t adt7410_show_id(struct device *dev, | |||
274 | u8 id; | 265 | u8 id; |
275 | int ret; | 266 | int ret; |
276 | 267 | ||
277 | ret = adt7410_i2c_read_byte(chip, ADT7410_ID, &id); | 268 | ret = adt7410_read_byte(chip, ADT7410_ID, &id); |
278 | if (ret) | 269 | if (ret) |
279 | return -EIO; | 270 | return -EIO; |
280 | 271 | ||
@@ -317,7 +308,7 @@ static ssize_t adt7410_show_value(struct device *dev, | |||
317 | int ret, i = 0; | 308 | int ret, i = 0; |
318 | 309 | ||
319 | do { | 310 | do { |
320 | ret = adt7410_i2c_read_byte(chip, ADT7410_STATUS, &status); | 311 | ret = adt7410_read_byte(chip, ADT7410_STATUS, &status); |
321 | if (ret) | 312 | if (ret) |
322 | return -EIO; | 313 | return -EIO; |
323 | i++; | 314 | i++; |
@@ -325,7 +316,7 @@ static ssize_t adt7410_show_value(struct device *dev, | |||
325 | return -EIO; | 316 | return -EIO; |
326 | } while (status & ADT7410_STAT_NOT_RDY); | 317 | } while (status & ADT7410_STAT_NOT_RDY); |
327 | 318 | ||
328 | ret = adt7410_i2c_read_word(chip, ADT7410_TEMPERATURE, &data); | 319 | ret = adt7410_read_word(chip, ADT7410_TEMPERATURE, &data); |
329 | if (ret) | 320 | if (ret) |
330 | return -EIO; | 321 | return -EIO; |
331 | 322 | ||
@@ -354,7 +345,7 @@ static irqreturn_t adt7410_event_handler(int irq, void *private) | |||
354 | s64 timestamp = iio_get_time_ns(); | 345 | s64 timestamp = iio_get_time_ns(); |
355 | u8 status; | 346 | u8 status; |
356 | 347 | ||
357 | if (adt7410_i2c_read_byte(chip, ADT7410_STATUS, &status)) | 348 | if (adt7410_read_byte(chip, ADT7410_STATUS, &status)) |
358 | return IRQ_HANDLED; | 349 | return IRQ_HANDLED; |
359 | 350 | ||
360 | if (status & ADT7410_STAT_T_HIGH) | 351 | if (status & ADT7410_STAT_T_HIGH) |
@@ -387,7 +378,7 @@ static ssize_t adt7410_show_event_mode(struct device *dev, | |||
387 | struct adt7410_chip_info *chip = iio_priv(dev_info); | 378 | struct adt7410_chip_info *chip = iio_priv(dev_info); |
388 | int ret; | 379 | int ret; |
389 | 380 | ||
390 | ret = adt7410_i2c_read_byte(chip, ADT7410_CONFIG, &chip->config); | 381 | ret = adt7410_read_byte(chip, ADT7410_CONFIG, &chip->config); |
391 | if (ret) | 382 | if (ret) |
392 | return -EIO; | 383 | return -EIO; |
393 | 384 | ||
@@ -407,7 +398,7 @@ static ssize_t adt7410_set_event_mode(struct device *dev, | |||
407 | u16 config; | 398 | u16 config; |
408 | int ret; | 399 | int ret; |
409 | 400 | ||
410 | ret = adt7410_i2c_read_byte(chip, ADT7410_CONFIG, &chip->config); | 401 | ret = adt7410_read_byte(chip, ADT7410_CONFIG, &chip->config); |
411 | if (ret) | 402 | if (ret) |
412 | return -EIO; | 403 | return -EIO; |
413 | 404 | ||
@@ -415,7 +406,7 @@ static ssize_t adt7410_set_event_mode(struct device *dev, | |||
415 | if (strcmp(buf, "comparator") != 0) | 406 | if (strcmp(buf, "comparator") != 0) |
416 | config |= ADT7410_EVENT_MODE; | 407 | config |= ADT7410_EVENT_MODE; |
417 | 408 | ||
418 | ret = adt7410_i2c_write_byte(chip, ADT7410_CONFIG, config); | 409 | ret = adt7410_write_byte(chip, ADT7410_CONFIG, config); |
419 | if (ret) | 410 | if (ret) |
420 | return -EIO; | 411 | return -EIO; |
421 | 412 | ||
@@ -439,7 +430,7 @@ static ssize_t adt7410_show_fault_queue(struct device *dev, | |||
439 | struct adt7410_chip_info *chip = iio_priv(dev_info); | 430 | struct adt7410_chip_info *chip = iio_priv(dev_info); |
440 | int ret; | 431 | int ret; |
441 | 432 | ||
442 | ret = adt7410_i2c_read_byte(chip, ADT7410_CONFIG, &chip->config); | 433 | ret = adt7410_read_byte(chip, ADT7410_CONFIG, &chip->config); |
443 | if (ret) | 434 | if (ret) |
444 | return -EIO; | 435 | return -EIO; |
445 | 436 | ||
@@ -461,13 +452,13 @@ static ssize_t adt7410_set_fault_queue(struct device *dev, | |||
461 | if (ret || data > 3) | 452 | if (ret || data > 3) |
462 | return -EINVAL; | 453 | return -EINVAL; |
463 | 454 | ||
464 | ret = adt7410_i2c_read_byte(chip, ADT7410_CONFIG, &chip->config); | 455 | ret = adt7410_read_byte(chip, ADT7410_CONFIG, &chip->config); |
465 | if (ret) | 456 | if (ret) |
466 | return -EIO; | 457 | return -EIO; |
467 | 458 | ||
468 | config = chip->config & ~ADT7410_FAULT_QUEUE_MASK; | 459 | config = chip->config & ~ADT7410_FAULT_QUEUE_MASK; |
469 | config |= data; | 460 | config |= data; |
470 | ret = adt7410_i2c_write_byte(chip, ADT7410_CONFIG, config); | 461 | ret = adt7410_write_byte(chip, ADT7410_CONFIG, config); |
471 | if (ret) | 462 | if (ret) |
472 | return -EIO; | 463 | return -EIO; |
473 | 464 | ||
@@ -486,7 +477,7 @@ static inline ssize_t adt7410_show_t_bound(struct device *dev, | |||
486 | u16 data; | 477 | u16 data; |
487 | int ret; | 478 | int ret; |
488 | 479 | ||
489 | ret = adt7410_i2c_read_word(chip, bound_reg, &data); | 480 | ret = adt7410_read_word(chip, bound_reg, &data); |
490 | if (ret) | 481 | if (ret) |
491 | return -EIO; | 482 | return -EIO; |
492 | 483 | ||
@@ -557,7 +548,7 @@ static inline ssize_t adt7410_set_t_bound(struct device *dev, | |||
557 | data <<= ADT7410_T13_VALUE_OFFSET; | 548 | data <<= ADT7410_T13_VALUE_OFFSET; |
558 | } | 549 | } |
559 | 550 | ||
560 | ret = adt7410_i2c_write_word(chip, bound_reg, data); | 551 | ret = adt7410_write_word(chip, bound_reg, data); |
561 | if (ret) | 552 | if (ret) |
562 | return -EIO; | 553 | return -EIO; |
563 | 554 | ||
@@ -624,7 +615,7 @@ static ssize_t adt7410_show_t_hyst(struct device *dev, | |||
624 | int ret; | 615 | int ret; |
625 | u8 t_hyst; | 616 | u8 t_hyst; |
626 | 617 | ||
627 | ret = adt7410_i2c_read_byte(chip, ADT7410_T_HYST, &t_hyst); | 618 | ret = adt7410_read_byte(chip, ADT7410_T_HYST, &t_hyst); |
628 | if (ret) | 619 | if (ret) |
629 | return -EIO; | 620 | return -EIO; |
630 | 621 | ||
@@ -649,7 +640,7 @@ static inline ssize_t adt7410_set_t_hyst(struct device *dev, | |||
649 | 640 | ||
650 | t_hyst = (u8)data; | 641 | t_hyst = (u8)data; |
651 | 642 | ||
652 | ret = adt7410_i2c_write_byte(chip, ADT7410_T_HYST, t_hyst); | 643 | ret = adt7410_write_byte(chip, ADT7410_T_HYST, t_hyst); |
653 | if (ret) | 644 | if (ret) |
654 | return -EIO; | 645 | return -EIO; |
655 | 646 | ||
@@ -704,14 +695,14 @@ static const struct iio_info adt7410_info = { | |||
704 | * device probe and remove | 695 | * device probe and remove |
705 | */ | 696 | */ |
706 | 697 | ||
707 | static int __devinit adt7410_probe(struct i2c_client *client, | 698 | static int __devinit adt7410_probe(struct device *dev, int irq, |
708 | const struct i2c_device_id *id) | 699 | const char *name, const struct adt7410_ops *ops) |
709 | { | 700 | { |
701 | unsigned long *adt7410_platform_data = dev->platform_data; | ||
702 | unsigned long local_pdata[] = {0, 0}; | ||
710 | struct adt7410_chip_info *chip; | 703 | struct adt7410_chip_info *chip; |
711 | struct iio_dev *indio_dev; | 704 | struct iio_dev *indio_dev; |
712 | int ret = 0; | 705 | int ret = 0; |
713 | unsigned long *adt7410_platform_data = client->dev.platform_data; | ||
714 | unsigned long local_pdata[] = {0, 0}; | ||
715 | 706 | ||
716 | indio_dev = iio_device_alloc(sizeof(*chip)); | 707 | indio_dev = iio_device_alloc(sizeof(*chip)); |
717 | if (indio_dev == NULL) { | 708 | if (indio_dev == NULL) { |
@@ -720,12 +711,13 @@ static int __devinit adt7410_probe(struct i2c_client *client, | |||
720 | } | 711 | } |
721 | chip = iio_priv(indio_dev); | 712 | chip = iio_priv(indio_dev); |
722 | /* this is only used for device removal purposes */ | 713 | /* this is only used for device removal purposes */ |
723 | i2c_set_clientdata(client, indio_dev); | 714 | dev_set_drvdata(dev, indio_dev); |
724 | 715 | ||
725 | chip->client = client; | 716 | chip->dev = dev; |
717 | chip->ops = ops; | ||
726 | 718 | ||
727 | indio_dev->name = id->name; | 719 | indio_dev->name = name; |
728 | indio_dev->dev.parent = &client->dev; | 720 | indio_dev->dev.parent = dev; |
729 | indio_dev->info = &adt7410_info; | 721 | indio_dev->info = &adt7410_info; |
730 | indio_dev->modes = INDIO_DIRECT_MODE; | 722 | indio_dev->modes = INDIO_DIRECT_MODE; |
731 | 723 | ||
@@ -733,12 +725,12 @@ static int __devinit adt7410_probe(struct i2c_client *client, | |||
733 | adt7410_platform_data = local_pdata; | 725 | adt7410_platform_data = local_pdata; |
734 | 726 | ||
735 | /* CT critcal temperature event. line 0 */ | 727 | /* CT critcal temperature event. line 0 */ |
736 | if (client->irq) { | 728 | if (irq) { |
737 | ret = request_threaded_irq(client->irq, | 729 | ret = request_threaded_irq(irq, |
738 | NULL, | 730 | NULL, |
739 | &adt7410_event_handler, | 731 | &adt7410_event_handler, |
740 | IRQF_TRIGGER_LOW | IRQF_ONESHOT, | 732 | IRQF_TRIGGER_LOW | IRQF_ONESHOT, |
741 | id->name, | 733 | name, |
742 | indio_dev); | 734 | indio_dev); |
743 | if (ret) | 735 | if (ret) |
744 | goto error_free_dev; | 736 | goto error_free_dev; |
@@ -751,13 +743,13 @@ static int __devinit adt7410_probe(struct i2c_client *client, | |||
751 | &adt7410_event_handler, | 743 | &adt7410_event_handler, |
752 | adt7410_platform_data[1] | | 744 | adt7410_platform_data[1] | |
753 | IRQF_ONESHOT, | 745 | IRQF_ONESHOT, |
754 | id->name, | 746 | name, |
755 | indio_dev); | 747 | indio_dev); |
756 | if (ret) | 748 | if (ret) |
757 | goto error_unreg_ct_irq; | 749 | goto error_unreg_ct_irq; |
758 | } | 750 | } |
759 | 751 | ||
760 | ret = adt7410_i2c_read_byte(chip, ADT7410_CONFIG, &chip->config); | 752 | ret = adt7410_read_byte(chip, ADT7410_CONFIG, &chip->config); |
761 | if (ret) { | 753 | if (ret) { |
762 | ret = -EIO; | 754 | ret = -EIO; |
763 | goto error_unreg_int_irq; | 755 | goto error_unreg_int_irq; |
@@ -765,7 +757,7 @@ static int __devinit adt7410_probe(struct i2c_client *client, | |||
765 | 757 | ||
766 | chip->config |= ADT7410_RESOLUTION; | 758 | chip->config |= ADT7410_RESOLUTION; |
767 | 759 | ||
768 | if (client->irq && adt7410_platform_data[0]) { | 760 | if (irq && adt7410_platform_data[0]) { |
769 | 761 | ||
770 | /* set irq polarity low level */ | 762 | /* set irq polarity low level */ |
771 | chip->config &= ~ADT7410_CT_POLARITY; | 763 | chip->config &= ~ADT7410_CT_POLARITY; |
@@ -776,7 +768,7 @@ static int __devinit adt7410_probe(struct i2c_client *client, | |||
776 | chip->config &= ~ADT7410_INT_POLARITY; | 768 | chip->config &= ~ADT7410_INT_POLARITY; |
777 | } | 769 | } |
778 | 770 | ||
779 | ret = adt7410_i2c_write_byte(chip, ADT7410_CONFIG, chip->config); | 771 | ret = adt7410_write_byte(chip, ADT7410_CONFIG, chip->config); |
780 | if (ret) { | 772 | if (ret) { |
781 | ret = -EIO; | 773 | ret = -EIO; |
782 | goto error_unreg_int_irq; | 774 | goto error_unreg_int_irq; |
@@ -785,36 +777,117 @@ static int __devinit adt7410_probe(struct i2c_client *client, | |||
785 | if (ret) | 777 | if (ret) |
786 | goto error_unreg_int_irq; | 778 | goto error_unreg_int_irq; |
787 | 779 | ||
788 | dev_info(&client->dev, "%s temperature sensor registered.\n", | 780 | dev_info(dev, "%s temperature sensor registered.\n", |
789 | id->name); | 781 | name); |
790 | 782 | ||
791 | return 0; | 783 | return 0; |
792 | 784 | ||
793 | error_unreg_int_irq: | 785 | error_unreg_int_irq: |
794 | free_irq(adt7410_platform_data[0], indio_dev); | 786 | free_irq(adt7410_platform_data[0], indio_dev); |
795 | error_unreg_ct_irq: | 787 | error_unreg_ct_irq: |
796 | free_irq(client->irq, indio_dev); | 788 | free_irq(irq, indio_dev); |
797 | error_free_dev: | 789 | error_free_dev: |
798 | iio_device_free(indio_dev); | 790 | iio_device_free(indio_dev); |
799 | error_ret: | 791 | error_ret: |
800 | return ret; | 792 | return ret; |
801 | } | 793 | } |
802 | 794 | ||
803 | static int __devexit adt7410_remove(struct i2c_client *client) | 795 | static int __devexit adt7410_remove(struct device *dev, int irq) |
804 | { | 796 | { |
805 | struct iio_dev *indio_dev = i2c_get_clientdata(client); | 797 | struct iio_dev *indio_dev = dev_get_drvdata(dev); |
806 | unsigned long *adt7410_platform_data = client->dev.platform_data; | 798 | unsigned long *adt7410_platform_data = dev->platform_data; |
807 | 799 | ||
808 | iio_device_unregister(indio_dev); | 800 | iio_device_unregister(indio_dev); |
809 | if (adt7410_platform_data[0]) | 801 | if (adt7410_platform_data[0]) |
810 | free_irq(adt7410_platform_data[0], indio_dev); | 802 | free_irq(adt7410_platform_data[0], indio_dev); |
811 | if (client->irq) | 803 | if (irq) |
812 | free_irq(client->irq, indio_dev); | 804 | free_irq(irq, indio_dev); |
813 | iio_device_free(indio_dev); | 805 | iio_device_free(indio_dev); |
814 | 806 | ||
815 | return 0; | 807 | return 0; |
816 | } | 808 | } |
817 | 809 | ||
810 | #if IS_ENABLED(CONFIG_I2C) | ||
811 | |||
812 | static int adt7410_i2c_read_word(struct adt7410_chip_info *chip, u8 reg, | ||
813 | u16 *data) | ||
814 | { | ||
815 | struct i2c_client *client = to_i2c_client(chip->dev); | ||
816 | int ret = 0; | ||
817 | |||
818 | ret = i2c_smbus_read_word_data(client, reg); | ||
819 | if (ret < 0) { | ||
820 | dev_err(&client->dev, "I2C read error\n"); | ||
821 | return ret; | ||
822 | } | ||
823 | |||
824 | *data = swab16((u16)ret); | ||
825 | |||
826 | return 0; | ||
827 | } | ||
828 | |||
829 | static int adt7410_i2c_write_word(struct adt7410_chip_info *chip, u8 reg, | ||
830 | u16 data) | ||
831 | { | ||
832 | struct i2c_client *client = to_i2c_client(chip->dev); | ||
833 | int ret = 0; | ||
834 | |||
835 | ret = i2c_smbus_write_word_data(client, reg, swab16(data)); | ||
836 | if (ret < 0) | ||
837 | dev_err(&client->dev, "I2C write error\n"); | ||
838 | |||
839 | return ret; | ||
840 | } | ||
841 | |||
842 | static int adt7410_i2c_read_byte(struct adt7410_chip_info *chip, u8 reg, | ||
843 | u8 *data) | ||
844 | { | ||
845 | struct i2c_client *client = to_i2c_client(chip->dev); | ||
846 | int ret = 0; | ||
847 | |||
848 | ret = i2c_smbus_read_byte_data(client, reg); | ||
849 | if (ret < 0) { | ||
850 | dev_err(&client->dev, "I2C read error\n"); | ||
851 | return ret; | ||
852 | } | ||
853 | |||
854 | *data = (u8)ret; | ||
855 | |||
856 | return 0; | ||
857 | } | ||
858 | |||
859 | static int adt7410_i2c_write_byte(struct adt7410_chip_info *chip, u8 reg, | ||
860 | u8 data) | ||
861 | { | ||
862 | struct i2c_client *client = to_i2c_client(chip->dev); | ||
863 | int ret = 0; | ||
864 | |||
865 | ret = i2c_smbus_write_byte_data(client, reg, data); | ||
866 | if (ret < 0) | ||
867 | dev_err(&client->dev, "I2C write error\n"); | ||
868 | |||
869 | return ret; | ||
870 | } | ||
871 | |||
872 | static const struct adt7410_ops adt7410_i2c_ops = { | ||
873 | .read_word = adt7410_i2c_read_word, | ||
874 | .write_word = adt7410_i2c_write_word, | ||
875 | .read_byte = adt7410_i2c_read_byte, | ||
876 | .write_byte = adt7410_i2c_write_byte, | ||
877 | }; | ||
878 | |||
879 | static int __devinit adt7410_i2c_probe(struct i2c_client *client, | ||
880 | const struct i2c_device_id *id) | ||
881 | { | ||
882 | return adt7410_probe(&client->dev, client->irq, id->name, | ||
883 | &adt7410_i2c_ops); | ||
884 | } | ||
885 | |||
886 | static int __devexit adt7410_i2c_remove(struct i2c_client *client) | ||
887 | { | ||
888 | return adt7410_remove(&client->dev, client->irq); | ||
889 | } | ||
890 | |||
818 | static const struct i2c_device_id adt7410_id[] = { | 891 | static const struct i2c_device_id adt7410_id[] = { |
819 | { "adt7410", 0 }, | 892 | { "adt7410", 0 }, |
820 | {} | 893 | {} |
@@ -826,13 +899,204 @@ static struct i2c_driver adt7410_driver = { | |||
826 | .driver = { | 899 | .driver = { |
827 | .name = "adt7410", | 900 | .name = "adt7410", |
828 | }, | 901 | }, |
829 | .probe = adt7410_probe, | 902 | .probe = adt7410_i2c_probe, |
830 | .remove = __devexit_p(adt7410_remove), | 903 | .remove = __devexit_p(adt7410_i2c_remove), |
831 | .id_table = adt7410_id, | 904 | .id_table = adt7410_id, |
832 | }; | 905 | }; |
833 | module_i2c_driver(adt7410_driver); | 906 | |
907 | static int __init adt7410_i2c_init(void) | ||
908 | { | ||
909 | return i2c_add_driver(&adt7410_driver); | ||
910 | } | ||
911 | |||
912 | static void __exit adt7410_i2c_exit(void) | ||
913 | { | ||
914 | i2c_del_driver(&adt7410_driver); | ||
915 | } | ||
916 | |||
917 | #else | ||
918 | |||
919 | static int __init adt7410_i2c_init(void) { return 0; }; | ||
920 | static void __exit adt7410_i2c_exit(void) {}; | ||
921 | |||
922 | #endif | ||
923 | |||
924 | #if IS_ENABLED(CONFIG_SPI_MASTER) | ||
925 | |||
926 | static const u8 adt7371_reg_table[] = { | ||
927 | [ADT7410_TEMPERATURE] = ADT7310_TEMPERATURE, | ||
928 | [ADT7410_STATUS] = ADT7310_STATUS, | ||
929 | [ADT7410_CONFIG] = ADT7310_CONFIG, | ||
930 | [ADT7410_T_ALARM_HIGH] = ADT7310_T_ALARM_HIGH, | ||
931 | [ADT7410_T_ALARM_LOW] = ADT7310_T_ALARM_LOW, | ||
932 | [ADT7410_T_CRIT] = ADT7310_T_CRIT, | ||
933 | [ADT7410_T_HYST] = ADT7310_T_HYST, | ||
934 | [ADT7410_ID] = ADT7310_ID, | ||
935 | }; | ||
936 | |||
937 | #define AD7310_COMMAND(reg) (adt7371_reg_table[(reg)] << ADT7310_CMD_REG_OFFSET) | ||
938 | |||
939 | static int adt7310_spi_read_word(struct adt7410_chip_info *chip, | ||
940 | u8 reg, u16 *data) | ||
941 | { | ||
942 | struct spi_device *spi = to_spi_device(chip->dev); | ||
943 | u8 command = AD7310_COMMAND(reg); | ||
944 | int ret = 0; | ||
945 | |||
946 | command |= ADT7310_CMD_READ; | ||
947 | ret = spi_write(spi, &command, sizeof(command)); | ||
948 | if (ret < 0) { | ||
949 | dev_err(&spi->dev, "SPI write command error\n"); | ||
950 | return ret; | ||
951 | } | ||
952 | |||
953 | ret = spi_read(spi, (u8 *)data, sizeof(*data)); | ||
954 | if (ret < 0) { | ||
955 | dev_err(&spi->dev, "SPI read word error\n"); | ||
956 | return ret; | ||
957 | } | ||
958 | |||
959 | *data = be16_to_cpu(*data); | ||
960 | |||
961 | return 0; | ||
962 | } | ||
963 | |||
964 | static int adt7310_spi_write_word(struct adt7410_chip_info *chip, u8 reg, | ||
965 | u16 data) | ||
966 | { | ||
967 | struct spi_device *spi = to_spi_device(chip->dev); | ||
968 | u8 buf[3]; | ||
969 | int ret = 0; | ||
970 | |||
971 | buf[0] = AD7310_COMMAND(reg); | ||
972 | buf[1] = (u8)(data >> 8); | ||
973 | buf[2] = (u8)(data & 0xFF); | ||
974 | |||
975 | ret = spi_write(spi, buf, 3); | ||
976 | if (ret < 0) { | ||
977 | dev_err(&spi->dev, "SPI write word error\n"); | ||
978 | return ret; | ||
979 | } | ||
980 | |||
981 | return ret; | ||
982 | } | ||
983 | |||
984 | static int adt7310_spi_read_byte(struct adt7410_chip_info *chip, u8 reg, | ||
985 | u8 *data) | ||
986 | { | ||
987 | struct spi_device *spi = to_spi_device(chip->dev); | ||
988 | u8 command = AD7310_COMMAND(reg); | ||
989 | int ret = 0; | ||
990 | |||
991 | command |= ADT7310_CMD_READ; | ||
992 | ret = spi_write(spi, &command, sizeof(command)); | ||
993 | if (ret < 0) { | ||
994 | dev_err(&spi->dev, "SPI write command error\n"); | ||
995 | return ret; | ||
996 | } | ||
997 | |||
998 | ret = spi_read(spi, data, sizeof(*data)); | ||
999 | if (ret < 0) { | ||
1000 | dev_err(&spi->dev, "SPI read byte error\n"); | ||
1001 | return ret; | ||
1002 | } | ||
1003 | |||
1004 | return 0; | ||
1005 | } | ||
1006 | |||
1007 | static int adt7310_spi_write_byte(struct adt7410_chip_info *chip, u8 reg, | ||
1008 | u8 data) | ||
1009 | { | ||
1010 | struct spi_device *spi = to_spi_device(chip->dev); | ||
1011 | u8 buf[2]; | ||
1012 | int ret = 0; | ||
1013 | |||
1014 | buf[0] = AD7310_COMMAND(reg); | ||
1015 | buf[1] = data; | ||
1016 | |||
1017 | ret = spi_write(spi, buf, 2); | ||
1018 | if (ret < 0) { | ||
1019 | dev_err(&spi->dev, "SPI write byte error\n"); | ||
1020 | return ret; | ||
1021 | } | ||
1022 | |||
1023 | return ret; | ||
1024 | } | ||
1025 | |||
1026 | static const struct adt7410_ops adt7310_spi_ops = { | ||
1027 | .read_word = adt7310_spi_read_word, | ||
1028 | .write_word = adt7310_spi_write_word, | ||
1029 | .read_byte = adt7310_spi_read_byte, | ||
1030 | .write_byte = adt7310_spi_write_byte, | ||
1031 | }; | ||
1032 | |||
1033 | static int __devinit adt7310_spi_probe(struct spi_device *spi) | ||
1034 | { | ||
1035 | return adt7410_probe(&spi->dev, spi->irq, | ||
1036 | spi_get_device_id(spi)->name, &adt7310_spi_ops); | ||
1037 | } | ||
1038 | |||
1039 | static int __devexit adt7310_spi_remove(struct spi_device *spi) | ||
1040 | { | ||
1041 | return adt7410_remove(&spi->dev, spi->irq); | ||
1042 | } | ||
1043 | |||
1044 | static const struct spi_device_id adt7310_id[] = { | ||
1045 | { "adt7310", 0 }, | ||
1046 | {} | ||
1047 | }; | ||
1048 | MODULE_DEVICE_TABLE(spi, adt7310_id); | ||
1049 | |||
1050 | static struct spi_driver adt7310_driver = { | ||
1051 | .driver = { | ||
1052 | .name = "adt7310", | ||
1053 | .owner = THIS_MODULE, | ||
1054 | }, | ||
1055 | .probe = adt7310_spi_probe, | ||
1056 | .remove = __devexit_p(adt7310_spi_remove), | ||
1057 | .id_table = adt7310_id, | ||
1058 | }; | ||
1059 | |||
1060 | static int __init adt7310_spi_init(void) | ||
1061 | { | ||
1062 | return spi_register_driver(&adt7310_driver); | ||
1063 | } | ||
1064 | |||
1065 | static void adt7310_spi_exit(void) | ||
1066 | { | ||
1067 | spi_unregister_driver(&adt7310_driver); | ||
1068 | } | ||
1069 | |||
1070 | #else | ||
1071 | |||
1072 | static int __init adt7310_spi_init(void) { return 0; }; | ||
1073 | static void adt7310_spi_exit(void) {}; | ||
1074 | |||
1075 | #endif | ||
1076 | |||
1077 | static int __init adt7410_init(void) | ||
1078 | { | ||
1079 | int ret; | ||
1080 | |||
1081 | ret = adt7310_spi_init(); | ||
1082 | if (ret) | ||
1083 | return ret; | ||
1084 | |||
1085 | ret = adt7410_i2c_init(); | ||
1086 | if (ret) | ||
1087 | adt7310_spi_exit(); | ||
1088 | |||
1089 | return ret; | ||
1090 | } | ||
1091 | module_init(adt7410_init); | ||
1092 | |||
1093 | static void __exit adt7410_exit(void) | ||
1094 | { | ||
1095 | adt7410_i2c_exit(); | ||
1096 | adt7310_spi_exit(); | ||
1097 | } | ||
1098 | module_exit(adt7410_exit); | ||
834 | 1099 | ||
835 | MODULE_AUTHOR("Sonic Zhang <sonic.zhang@analog.com>"); | 1100 | MODULE_AUTHOR("Sonic Zhang <sonic.zhang@analog.com>"); |
836 | MODULE_DESCRIPTION("Analog Devices ADT7410 digital" | 1101 | MODULE_DESCRIPTION("Analog Devices ADT7310/ADT7410 digital temperature sensor driver"); |
837 | " temperature sensor driver"); | ||
838 | MODULE_LICENSE("GPL v2"); | 1102 | MODULE_LICENSE("GPL v2"); |