blob: 9d1af0e9cc0febf474372b9b857936dc5c03becc [file] [log] [blame]
Sonic Zhangddaecd52010-10-27 21:43:55 -04001/*
Michael Hennerichf22c1cf2011-09-02 17:25:37 +01002 * AD7291 8-Channel, I2C, 12-Bit SAR ADC with Temperature Sensor
Sonic Zhangddaecd52010-10-27 21:43:55 -04003 *
Michael Hennerichf22c1cf2011-09-02 17:25:37 +01004 * Copyright 2010-2011 Analog Devices Inc.
Sonic Zhangddaecd52010-10-27 21:43:55 -04005 *
6 * Licensed under the GPL-2 or later.
7 */
8
9#include <linux/interrupt.h>
Sonic Zhangddaecd52010-10-27 21:43:55 -040010#include <linux/device.h>
11#include <linux/kernel.h>
12#include <linux/slab.h>
13#include <linux/sysfs.h>
Sonic Zhangddaecd52010-10-27 21:43:55 -040014#include <linux/i2c.h>
Paul Gortmaker99c97852011-07-03 15:49:50 -040015#include <linux/module.h>
Jonathan Cameron4fd24242011-09-02 17:25:32 +010016#include <linux/mutex.h>
Michael Hennerich3b424f32011-09-02 17:25:39 +010017#include <linux/regulator/consumer.h>
18#include <linux/err.h>
Sonic Zhangddaecd52010-10-27 21:43:55 -040019
20#include "../iio.h"
21#include "../sysfs.h"
22
23/*
Jonathan Cameron4fd24242011-09-02 17:25:32 +010024 * Simplified handling
25 *
26 * If no events enabled - single polled channel read
27 * If event enabled direct reads disable unless channel
28 * is in the read mask.
29 *
30 * The noise-delayed bit as per datasheet suggestion is always enabled.
31 *
Jonathan Cameron4fd24242011-09-02 17:25:32 +010032 */
Michael Hennerich3b424f32011-09-02 17:25:39 +010033
Jonathan Cameron4fd24242011-09-02 17:25:32 +010034/*
Sonic Zhangddaecd52010-10-27 21:43:55 -040035 * AD7291 registers definition
36 */
Michael Hennerich81e2edb2011-09-02 17:25:40 +010037#define AD7291_COMMAND 0x00
38#define AD7291_VOLTAGE 0x01
39#define AD7291_T_SENSE 0x02
40#define AD7291_T_AVERAGE 0x03
41#define AD7291_CH0_DATA_HIGH 0x04
42#define AD7291_CH0_DATA_LOW 0x05
43#define AD7291_CH0_HYST 0x06
44#define AD7291_CH1_DATA_HIGH 0x07
45#define AD7291_CH1_DATA_LOW 0x08
46#define AD7291_CH1_HYST 0x09
47#define AD7291_CH2_DATA_HIGH 0x0A
48#define AD7291_CH2_DATA_LOW 0x0B
49#define AD7291_CH2_HYST 0x0C
50#define AD7291_CH3_DATA_HIGH 0x0D
51#define AD7291_CH3_DATA_LOW 0x0E
52#define AD7291_CH3_HYST 0x0F
53#define AD7291_CH4_DATA_HIGH 0x10
54#define AD7291_CH4_DATA_LOW 0x11
55#define AD7291_CH4_HYST 0x12
56#define AD7291_CH5_DATA_HIGH 0x13
57#define AD7291_CH5_DATA_LOW 0x14
58#define AD7291_CH5_HYST 0x15
59#define AD7291_CH6_DATA_HIGH 0x16
60#define AD7291_CH6_DATA_LOW 0x17
61#define AD7291_CH6_HYST 0x18
62#define AD7291_CH7_DATA_HIGH 0x19
63#define AD7291_CH7_DATA_LOW 0x1A
64#define AD7291_CH7_HYST 0x2B
Michael Hennerich00feefb2011-09-02 17:25:38 +010065#define AD7291_T_SENSE_HIGH 0x1C
66#define AD7291_T_SENSE_LOW 0x1D
67#define AD7291_T_SENSE_HYST 0x1E
68#define AD7291_VOLTAGE_ALERT_STATUS 0x1F
Sonic Zhangddaecd52010-10-27 21:43:55 -040069#define AD7291_T_ALERT_STATUS 0x20
70
Michael Hennerich81e2edb2011-09-02 17:25:40 +010071#define AD7291_VOLTAGE_LIMIT_COUNT 8
72
73
Sonic Zhangddaecd52010-10-27 21:43:55 -040074/*
75 * AD7291 command
76 */
Michael Hennerich00feefb2011-09-02 17:25:38 +010077#define AD7291_AUTOCYCLE (1 << 0)
78#define AD7291_RESET (1 << 1)
79#define AD7291_ALERT_CLEAR (1 << 2)
80#define AD7291_ALERT_POLARITY (1 << 3)
81#define AD7291_EXT_REF (1 << 4)
82#define AD7291_NOISE_DELAY (1 << 5)
83#define AD7291_T_SENSE_MASK (1 << 7)
84#define AD7291_VOLTAGE_MASK 0xFF00
Sonic Zhangddaecd52010-10-27 21:43:55 -040085#define AD7291_VOLTAGE_OFFSET 0x8
86
87/*
88 * AD7291 value masks
89 */
Michael Hennerich00feefb2011-09-02 17:25:38 +010090#define AD7291_CHANNEL_MASK 0xF000
Michael Hennerich3b424f32011-09-02 17:25:39 +010091#define AD7291_BITS 12
Michael Hennerich00feefb2011-09-02 17:25:38 +010092#define AD7291_VALUE_MASK 0xFFF
Sonic Zhangddaecd52010-10-27 21:43:55 -040093#define AD7291_T_VALUE_SIGN 0x400
94#define AD7291_T_VALUE_FLOAT_OFFSET 2
95#define AD7291_T_VALUE_FLOAT_MASK 0x2
96
Michael Hennerich3b424f32011-09-02 17:25:39 +010097#define AD7291_BITS 12
98
Sonic Zhangddaecd52010-10-27 21:43:55 -040099struct ad7291_chip_info {
Michael Hennerich3b424f32011-09-02 17:25:39 +0100100 struct i2c_client *client;
101 struct regulator *reg;
102 u16 int_vref_mv;
103 u16 command;
104 u8 c_mask; /* Active voltage channels for events */
105 struct mutex state_lock;
Sonic Zhangddaecd52010-10-27 21:43:55 -0400106};
107
Sonic Zhangddaecd52010-10-27 21:43:55 -0400108static int ad7291_i2c_read(struct ad7291_chip_info *chip, u8 reg, u16 *data)
109{
110 struct i2c_client *client = chip->client;
111 int ret = 0;
112
113 ret = i2c_smbus_read_word_data(client, reg);
114 if (ret < 0) {
115 dev_err(&client->dev, "I2C read error\n");
116 return ret;
117 }
118
119 *data = swab16((u16)ret);
120
121 return 0;
122}
123
124static int ad7291_i2c_write(struct ad7291_chip_info *chip, u8 reg, u16 data)
125{
Jonathan Cameron4fd24242011-09-02 17:25:32 +0100126 return i2c_smbus_write_word_data(chip->client, reg, swab16(data));
Sonic Zhangddaecd52010-10-27 21:43:55 -0400127}
128
Sonic Zhangddaecd52010-10-27 21:43:55 -0400129static ssize_t ad7291_store_reset(struct device *dev,
130 struct device_attribute *attr,
131 const char *buf,
132 size_t len)
133{
134 struct iio_dev *dev_info = dev_get_drvdata(dev);
Jonathan Camerond4397972011-06-27 13:07:23 +0100135 struct ad7291_chip_info *chip = iio_priv(dev_info);
Sonic Zhangddaecd52010-10-27 21:43:55 -0400136
Jonathan Cameron4fd24242011-09-02 17:25:32 +0100137 return ad7291_i2c_write(chip, AD7291_COMMAND,
138 chip->command | AD7291_RESET);
Sonic Zhangddaecd52010-10-27 21:43:55 -0400139}
140
Jonathan Cameron4fd24242011-09-02 17:25:32 +0100141static IIO_DEVICE_ATTR(reset, S_IWUSR, NULL, ad7291_store_reset, 0);
Sonic Zhangddaecd52010-10-27 21:43:55 -0400142
Sonic Zhangddaecd52010-10-27 21:43:55 -0400143static struct attribute *ad7291_attributes[] = {
Sonic Zhangddaecd52010-10-27 21:43:55 -0400144 &iio_dev_attr_reset.dev_attr.attr,
Sonic Zhangddaecd52010-10-27 21:43:55 -0400145 NULL,
146};
147
148static const struct attribute_group ad7291_attribute_group = {
149 .attrs = ad7291_attributes,
150};
151
Jonathan Cameron58c03232011-05-18 14:41:11 +0100152static irqreturn_t ad7291_event_handler(int irq, void *private)
Sonic Zhangddaecd52010-10-27 21:43:55 -0400153{
Jonathan Cameron58c03232011-05-18 14:41:11 +0100154 struct iio_dev *indio_dev = private;
Jonathan Camerond4397972011-06-27 13:07:23 +0100155 struct ad7291_chip_info *chip = iio_priv(private);
Sonic Zhangddaecd52010-10-27 21:43:55 -0400156 u16 t_status, v_status;
157 u16 command;
158 int i;
Jonathan Cameron58c03232011-05-18 14:41:11 +0100159 s64 timestamp = iio_get_time_ns();
Sonic Zhangddaecd52010-10-27 21:43:55 -0400160
161 if (ad7291_i2c_read(chip, AD7291_T_ALERT_STATUS, &t_status))
Jonathan Cameron58c03232011-05-18 14:41:11 +0100162 return IRQ_HANDLED;
Sonic Zhangddaecd52010-10-27 21:43:55 -0400163
164 if (ad7291_i2c_read(chip, AD7291_VOLTAGE_ALERT_STATUS, &v_status))
Jonathan Cameron58c03232011-05-18 14:41:11 +0100165 return IRQ_HANDLED;
Sonic Zhangddaecd52010-10-27 21:43:55 -0400166
167 if (!(t_status || v_status))
Jonathan Cameron58c03232011-05-18 14:41:11 +0100168 return IRQ_HANDLED;
Sonic Zhangddaecd52010-10-27 21:43:55 -0400169
Michael Hennerichf22c1cf2011-09-02 17:25:37 +0100170 command = chip->command | AD7291_ALERT_CLEAR;
Sonic Zhangddaecd52010-10-27 21:43:55 -0400171 ad7291_i2c_write(chip, AD7291_COMMAND, command);
172
Michael Hennerichf22c1cf2011-09-02 17:25:37 +0100173 command = chip->command & ~AD7291_ALERT_CLEAR;
Sonic Zhangddaecd52010-10-27 21:43:55 -0400174 ad7291_i2c_write(chip, AD7291_COMMAND, command);
175
Jonathan Cameron4fd24242011-09-02 17:25:32 +0100176 /* For now treat t_sense and t_sense_average the same */
177 if ((t_status & (1 << 0)) || (t_status & (1 << 2)))
Jonathan Cameron5aa96182011-08-30 12:41:06 +0100178 iio_push_event(indio_dev,
Jonathan Cameronb206c3b2011-05-18 14:42:15 +0100179 IIO_UNMOD_EVENT_CODE(IIO_TEMP,
180 0,
181 IIO_EV_TYPE_THRESH,
182 IIO_EV_DIR_FALLING),
183 timestamp);
Jonathan Cameron4fd24242011-09-02 17:25:32 +0100184 if ((t_status & (1 << 1)) || (t_status & (1 << 3)))
Jonathan Cameron5aa96182011-08-30 12:41:06 +0100185 iio_push_event(indio_dev,
Jonathan Cameronb206c3b2011-05-18 14:42:15 +0100186 IIO_UNMOD_EVENT_CODE(IIO_TEMP,
187 0,
188 IIO_EV_TYPE_THRESH,
189 IIO_EV_DIR_RISING),
190 timestamp);
Sonic Zhangddaecd52010-10-27 21:43:55 -0400191
Jonathan Cameronb206c3b2011-05-18 14:42:15 +0100192 for (i = 0; i < AD7291_VOLTAGE_LIMIT_COUNT*2; i += 2) {
Sonic Zhangddaecd52010-10-27 21:43:55 -0400193 if (v_status & (1 << i))
Jonathan Cameron5aa96182011-08-30 12:41:06 +0100194 iio_push_event(indio_dev,
Jonathan Cameronb206c3b2011-05-18 14:42:15 +0100195 IIO_UNMOD_EVENT_CODE(IIO_IN,
196 i/2,
197 IIO_EV_TYPE_THRESH,
198 IIO_EV_DIR_FALLING),
199 timestamp);
200 if (v_status & (1 << (i + 1)))
Jonathan Cameron5aa96182011-08-30 12:41:06 +0100201 iio_push_event(indio_dev,
Jonathan Cameronb206c3b2011-05-18 14:42:15 +0100202 IIO_UNMOD_EVENT_CODE(IIO_IN,
203 i/2,
204 IIO_EV_TYPE_THRESH,
205 IIO_EV_DIR_RISING),
206 timestamp);
Sonic Zhangddaecd52010-10-27 21:43:55 -0400207 }
Jonathan Cameron58c03232011-05-18 14:41:11 +0100208
209 return IRQ_HANDLED;
Sonic Zhangddaecd52010-10-27 21:43:55 -0400210}
211
Jonathan Cameron4fd24242011-09-02 17:25:32 +0100212static inline ssize_t ad7291_show_hyst(struct device *dev,
Sonic Zhangddaecd52010-10-27 21:43:55 -0400213 struct device_attribute *attr,
Sonic Zhangddaecd52010-10-27 21:43:55 -0400214 char *buf)
215{
216 struct iio_dev *dev_info = dev_get_drvdata(dev);
Jonathan Camerond4397972011-06-27 13:07:23 +0100217 struct ad7291_chip_info *chip = iio_priv(dev_info);
Jonathan Cameron58c03232011-05-18 14:41:11 +0100218 struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
Sonic Zhangddaecd52010-10-27 21:43:55 -0400219 u16 data;
Sonic Zhangddaecd52010-10-27 21:43:55 -0400220 int ret;
221
Jonathan Cameron58c03232011-05-18 14:41:11 +0100222 ret = ad7291_i2c_read(chip, this_attr->address, &data);
Jonathan Cameron4fd24242011-09-02 17:25:32 +0100223 if (ret < 0)
224 return ret;
Sonic Zhangddaecd52010-10-27 21:43:55 -0400225
Michael Hennerich81e2edb2011-09-02 17:25:40 +0100226 return sprintf(buf, "%d\n", data & AD7291_VALUE_MASK);
Sonic Zhangddaecd52010-10-27 21:43:55 -0400227}
228
Jonathan Cameron4fd24242011-09-02 17:25:32 +0100229static inline ssize_t ad7291_set_hyst(struct device *dev,
230 struct device_attribute *attr,
231 const char *buf,
232 size_t len)
Sonic Zhangddaecd52010-10-27 21:43:55 -0400233{
234 struct iio_dev *dev_info = dev_get_drvdata(dev);
Jonathan Camerond4397972011-06-27 13:07:23 +0100235 struct ad7291_chip_info *chip = iio_priv(dev_info);
Jonathan Cameron58c03232011-05-18 14:41:11 +0100236 struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
Sonic Zhangddaecd52010-10-27 21:43:55 -0400237 u16 data;
238 int ret;
239
Jonathan Cameron4fd24242011-09-02 17:25:32 +0100240 ret = kstrtou16(buf, 10, &data);
241
242 if (ret < 0)
243 return ret;
244 if (data < 4096)
Sonic Zhangddaecd52010-10-27 21:43:55 -0400245 return -EINVAL;
246
Jonathan Cameron4fd24242011-09-02 17:25:32 +0100247 return ad7291_i2c_write(chip, this_attr->address, data);
Sonic Zhangddaecd52010-10-27 21:43:55 -0400248}
249
Jonathan Cameron4fd24242011-09-02 17:25:32 +0100250static IIO_DEVICE_ATTR(in_temp0_thresh_both_hyst_raw,
Jonathan Cameron58c03232011-05-18 14:41:11 +0100251 S_IRUGO | S_IWUSR,
Jonathan Cameron4fd24242011-09-02 17:25:32 +0100252 ad7291_show_hyst, ad7291_set_hyst,
Jonathan Cameron58c03232011-05-18 14:41:11 +0100253 AD7291_T_SENSE_HYST);
Jonathan Cameron4fd24242011-09-02 17:25:32 +0100254static IIO_DEVICE_ATTR(in_voltage0_thresh_both_hyst_raw,
Jonathan Cameron58c03232011-05-18 14:41:11 +0100255 S_IRUGO | S_IWUSR,
Michael Hennerich81e2edb2011-09-02 17:25:40 +0100256 ad7291_show_hyst, ad7291_set_hyst, AD7291_CH0_HYST);
Jonathan Cameron4fd24242011-09-02 17:25:32 +0100257static IIO_DEVICE_ATTR(in_voltage1_thresh_both_hyst_raw,
Jonathan Cameron58c03232011-05-18 14:41:11 +0100258 S_IRUGO | S_IWUSR,
Michael Hennerich81e2edb2011-09-02 17:25:40 +0100259 ad7291_show_hyst, ad7291_set_hyst, AD7291_CH1_HYST);
Jonathan Cameron4fd24242011-09-02 17:25:32 +0100260static IIO_DEVICE_ATTR(in_voltage2_thresh_both_hyst_raw,
Jonathan Cameron58c03232011-05-18 14:41:11 +0100261 S_IRUGO | S_IWUSR,
Michael Hennerich81e2edb2011-09-02 17:25:40 +0100262 ad7291_show_hyst, ad7291_set_hyst, AD7291_CH2_HYST);
Jonathan Cameron4fd24242011-09-02 17:25:32 +0100263static IIO_DEVICE_ATTR(in_voltage3_thresh_both_hyst_raw,
Jonathan Cameron58c03232011-05-18 14:41:11 +0100264 S_IRUGO | S_IWUSR,
Michael Hennerich81e2edb2011-09-02 17:25:40 +0100265 ad7291_show_hyst, ad7291_set_hyst, AD7291_CH3_HYST);
Jonathan Cameron4fd24242011-09-02 17:25:32 +0100266static IIO_DEVICE_ATTR(in_voltage4_thresh_both_hyst_raw,
Jonathan Cameron58c03232011-05-18 14:41:11 +0100267 S_IRUGO | S_IWUSR,
Michael Hennerich81e2edb2011-09-02 17:25:40 +0100268 ad7291_show_hyst, ad7291_set_hyst, AD7291_CH4_HYST);
Jonathan Cameron4fd24242011-09-02 17:25:32 +0100269static IIO_DEVICE_ATTR(in_voltage5_thresh_both_hyst_raw,
Jonathan Cameron58c03232011-05-18 14:41:11 +0100270 S_IRUGO | S_IWUSR,
Michael Hennerich81e2edb2011-09-02 17:25:40 +0100271 ad7291_show_hyst, ad7291_set_hyst, AD7291_CH5_HYST);
Jonathan Cameron4fd24242011-09-02 17:25:32 +0100272static IIO_DEVICE_ATTR(in_voltage6_thresh_both_hyst_raw,
Jonathan Cameron58c03232011-05-18 14:41:11 +0100273 S_IRUGO | S_IWUSR,
Michael Hennerich81e2edb2011-09-02 17:25:40 +0100274 ad7291_show_hyst, ad7291_set_hyst, AD7291_CH6_HYST);
Jonathan Cameron4fd24242011-09-02 17:25:32 +0100275static IIO_DEVICE_ATTR(in_voltage7_thresh_both_hyst_raw,
Jonathan Cameron58c03232011-05-18 14:41:11 +0100276 S_IRUGO | S_IWUSR,
Michael Hennerich81e2edb2011-09-02 17:25:40 +0100277 ad7291_show_hyst, ad7291_set_hyst, AD7291_CH7_HYST);
Sonic Zhangddaecd52010-10-27 21:43:55 -0400278
279static struct attribute *ad7291_event_attributes[] = {
Jonathan Cameron4fd24242011-09-02 17:25:32 +0100280 &iio_dev_attr_in_temp0_thresh_both_hyst_raw.dev_attr.attr,
281 &iio_dev_attr_in_voltage0_thresh_both_hyst_raw.dev_attr.attr,
282 &iio_dev_attr_in_voltage1_thresh_both_hyst_raw.dev_attr.attr,
283 &iio_dev_attr_in_voltage2_thresh_both_hyst_raw.dev_attr.attr,
284 &iio_dev_attr_in_voltage3_thresh_both_hyst_raw.dev_attr.attr,
285 &iio_dev_attr_in_voltage4_thresh_both_hyst_raw.dev_attr.attr,
286 &iio_dev_attr_in_voltage5_thresh_both_hyst_raw.dev_attr.attr,
287 &iio_dev_attr_in_voltage6_thresh_both_hyst_raw.dev_attr.attr,
288 &iio_dev_attr_in_voltage7_thresh_both_hyst_raw.dev_attr.attr,
Sonic Zhangddaecd52010-10-27 21:43:55 -0400289 NULL,
290};
291
Jonathan Cameron4fd24242011-09-02 17:25:32 +0100292/* high / low */
293static u8 ad7291_limit_regs[9][2] = {
Michael Hennerich81e2edb2011-09-02 17:25:40 +0100294 { AD7291_CH0_DATA_HIGH, AD7291_CH0_DATA_LOW },
295 { AD7291_CH1_DATA_HIGH, AD7291_CH1_DATA_LOW },
296 { AD7291_CH2_DATA_HIGH, AD7291_CH2_DATA_LOW },
297 { AD7291_CH3_DATA_HIGH, AD7291_CH3_DATA_LOW }, /* FIXME: ? */
298 { AD7291_CH4_DATA_HIGH, AD7291_CH4_DATA_LOW },
299 { AD7291_CH5_DATA_HIGH, AD7291_CH5_DATA_LOW },
300 { AD7291_CH6_DATA_HIGH, AD7291_CH6_DATA_LOW },
301 { AD7291_CH7_DATA_HIGH, AD7291_CH7_DATA_LOW },
Jonathan Cameron4fd24242011-09-02 17:25:32 +0100302 /* temp */
Michael Hennerich81e2edb2011-09-02 17:25:40 +0100303 { AD7291_T_SENSE_HIGH, AD7291_T_SENSE_LOW },
Jonathan Cameron4fd24242011-09-02 17:25:32 +0100304};
305
306static int ad7291_read_event_value(struct iio_dev *indio_dev,
307 u64 event_code,
308 int *val)
309{
310 struct ad7291_chip_info *chip = iio_priv(indio_dev);
311
312 int ret;
313 u8 reg;
314 u16 uval;
315 s16 signval;
316
317 switch (IIO_EVENT_CODE_EXTRACT_TYPE(event_code)) {
318 case IIO_VOLTAGE:
319 reg = ad7291_limit_regs[IIO_EVENT_CODE_EXTRACT_NUM(event_code)]
320 [!(IIO_EVENT_CODE_EXTRACT_DIR(event_code) ==
321 IIO_EV_DIR_RISING)];
322
323 ret = ad7291_i2c_read(chip, reg, &uval);
324 if (ret < 0)
325 return ret;
Michael Hennerich81e2edb2011-09-02 17:25:40 +0100326 *val = uval & AD7291_VALUE_MASK;
Jonathan Cameron4fd24242011-09-02 17:25:32 +0100327 return 0;
328
329 case IIO_TEMP:
330 reg = ad7291_limit_regs[8]
331 [!(IIO_EVENT_CODE_EXTRACT_DIR(event_code) ==
332 IIO_EV_DIR_RISING)];
333
334 ret = ad7291_i2c_read(chip, reg, &signval);
335 if (ret < 0)
336 return ret;
Michael Hennerich81e2edb2011-09-02 17:25:40 +0100337 signval = (s16)((signval & AD7291_VALUE_MASK) << 4) >> 4;
Jonathan Cameron4fd24242011-09-02 17:25:32 +0100338 *val = signval;
339 return 0;
340 default:
341 return -EINVAL;
342 };
343}
344
345static int ad7291_write_event_value(struct iio_dev *indio_dev,
346 u64 event_code,
347 int val)
348{
349 struct ad7291_chip_info *chip = iio_priv(indio_dev);
350 u8 reg;
351 s16 signval;
352
353 switch (IIO_EVENT_CODE_EXTRACT_TYPE(event_code)) {
354 case IIO_VOLTAGE:
355 if (val > 0xFFF || val < 0)
356 return -EINVAL;
357 reg = ad7291_limit_regs[IIO_EVENT_CODE_EXTRACT_NUM(event_code)]
358 [!(IIO_EVENT_CODE_EXTRACT_DIR(event_code) ==
359 IIO_EV_DIR_RISING)];
Jonathan Cameron4fd24242011-09-02 17:25:32 +0100360 return ad7291_i2c_write(chip, reg, val);
Jonathan Cameron4fd24242011-09-02 17:25:32 +0100361 case IIO_TEMP:
362 if (val > 2047 || val < -2048)
363 return -EINVAL;
364 reg = ad7291_limit_regs[8]
365 [!(IIO_EVENT_CODE_EXTRACT_DIR(event_code) ==
366 IIO_EV_DIR_RISING)];
367 signval = val;
368 return ad7291_i2c_write(chip, reg, *(u16 *)&signval);
369 default:
370 return -EINVAL;
371 };
372}
373
374static int ad7291_read_event_config(struct iio_dev *indio_dev,
375 u64 event_code)
376{
377 struct ad7291_chip_info *chip = iio_priv(indio_dev);
378 /* To be enabled the channel must simply be on. If any are enabled
379 we are in continuous sampling mode */
380
381 switch (IIO_EVENT_CODE_EXTRACT_TYPE(event_code)) {
382 case IIO_VOLTAGE:
383 if (chip->c_mask &
384 (1 << IIO_EVENT_CODE_EXTRACT_NUM(event_code)))
385 return 1;
386 else
387 return 0;
388 case IIO_TEMP:
389 /* always on */
390 return 1;
391 default:
392 return -EINVAL;
393 }
394
395}
396
397static int ad7291_write_event_config(struct iio_dev *indio_dev,
398 u64 event_code,
399 int state)
400{
401 int ret = 0;
402 struct ad7291_chip_info *chip = iio_priv(indio_dev);
403 u16 regval;
404
405 mutex_lock(&chip->state_lock);
406 regval = chip->command;
407 /*
408 * To be enabled the channel must simply be on. If any are enabled
409 * use continuous sampling mode.
410 * Possible to disable temp as well but that makes single read tricky.
411 */
Michael Hennerich81e2edb2011-09-02 17:25:40 +0100412
Jonathan Cameron4fd24242011-09-02 17:25:32 +0100413 switch (IIO_EVENT_CODE_EXTRACT_TYPE(event_code)) {
414 case IIO_VOLTAGE:
415 if ((!state) && (chip->c_mask &
416 (1 << IIO_EVENT_CODE_EXTRACT_NUM(event_code))))
417 chip->c_mask &=
418 ~(1 << IIO_EVENT_CODE_EXTRACT_NUM(event_code));
419 else if (state && (!(chip->c_mask &
420 (1 << IIO_EVENT_CODE_EXTRACT_NUM(event_code)))))
421 chip->c_mask &=
422 (1 << IIO_EVENT_CODE_EXTRACT_NUM(event_code));
423 else
424 break;
425
Michael Hennerich81e2edb2011-09-02 17:25:40 +0100426 regval &= ~AD7291_AUTOCYCLE;
Jonathan Cameron4fd24242011-09-02 17:25:32 +0100427 regval |= ((u16)chip->c_mask << 8);
428 if (chip->c_mask) /* Enable autocycle? */
429 regval |= AD7291_AUTOCYCLE;
430
431 ret = ad7291_i2c_write(chip, AD7291_COMMAND, regval);
432 if (ret < 0)
433 goto error_ret;
434
435 chip->command = regval;
436 break;
437 default:
438 ret = -EINVAL;
439 }
440
441error_ret:
442 mutex_unlock(&chip->state_lock);
443 return ret;
444}
445
446static int ad7291_read_raw(struct iio_dev *indio_dev,
447 struct iio_chan_spec const *chan,
448 int *val,
449 int *val2,
450 long mask)
451{
452 int ret;
453 struct ad7291_chip_info *chip = iio_priv(indio_dev);
Michael Hennerich3b424f32011-09-02 17:25:39 +0100454 unsigned int scale_uv;
Jonathan Cameron4fd24242011-09-02 17:25:32 +0100455 u16 regval;
456 s16 signval;
457
458 switch (mask) {
459 case 0:
460 switch (chan->type) {
461 case IIO_VOLTAGE:
462 mutex_lock(&chip->state_lock);
463 /* If in autocycle mode drop through */
464 if (chip->command & 0x1) {
465 mutex_unlock(&chip->state_lock);
466 return -EBUSY;
467 }
468 /* Enable this channel alone */
469 regval = chip->command & (~AD7291_VOLTAGE_MASK);
Michael Henneriche70ab212011-09-02 17:25:36 +0100470 regval |= 1 << (15 - chan->channel);
Jonathan Cameron4fd24242011-09-02 17:25:32 +0100471 ret = ad7291_i2c_write(chip, AD7291_COMMAND, regval);
472 if (ret < 0) {
473 mutex_unlock(&chip->state_lock);
474 return ret;
475 }
476 /* Read voltage */
477 ret = i2c_smbus_read_word_data(chip->client,
478 AD7291_VOLTAGE);
479 if (ret < 0) {
480 mutex_unlock(&chip->state_lock);
481 return ret;
482 }
Michael Hennerich81e2edb2011-09-02 17:25:40 +0100483 *val = swab16((u16)ret) & AD7291_VALUE_MASK;
Jonathan Cameron4fd24242011-09-02 17:25:32 +0100484 mutex_unlock(&chip->state_lock);
485 return IIO_VAL_INT;
486 case IIO_TEMP:
487 /* Assumes tsense bit of command register always set */
488 ret = i2c_smbus_read_word_data(chip->client,
489 AD7291_T_SENSE);
490 if (ret < 0)
491 return ret;
Michael Hennerich81e2edb2011-09-02 17:25:40 +0100492 signval = (s16)((swab16((u16)ret) &
493 AD7291_VALUE_MASK) << 4) >> 4;
Jonathan Cameron4fd24242011-09-02 17:25:32 +0100494 *val = signval;
495 return IIO_VAL_INT;
496 default:
497 return -EINVAL;
498 }
499 case (1 << IIO_CHAN_INFO_AVERAGE_RAW_SEPARATE):
500 ret = i2c_smbus_read_word_data(chip->client,
501 AD7291_T_AVERAGE);
502 if (ret < 0)
503 return ret;
Michael Hennerich81e2edb2011-09-02 17:25:40 +0100504 signval = (s16)((swab16((u16)ret) &
505 AD7291_VALUE_MASK) << 4) >> 4;
Jonathan Cameron4fd24242011-09-02 17:25:32 +0100506 *val = signval;
507 return IIO_VAL_INT;
Michael Hennerich3b424f32011-09-02 17:25:39 +0100508 case (1 << IIO_CHAN_INFO_SCALE_SHARED):
509 scale_uv = (chip->int_vref_mv * 1000) >> AD7291_BITS;
510 *val = scale_uv / 1000;
511 *val2 = (scale_uv % 1000) * 1000;
512 return IIO_VAL_INT_PLUS_MICRO;
Jonathan Cameron4fd24242011-09-02 17:25:32 +0100513 default:
514 return -EINVAL;
515 }
516}
517
518#define AD7291_VOLTAGE_CHAN(_chan) \
519{ \
520 .type = IIO_VOLTAGE, \
Michael Hennerich3b424f32011-09-02 17:25:39 +0100521 .info_mask = (1 << IIO_CHAN_INFO_SCALE_SHARED), \
Jonathan Cameron4fd24242011-09-02 17:25:32 +0100522 .indexed = 1, \
523 .channel = _chan, \
524 .event_mask = IIO_EV_BIT(IIO_EV_TYPE_THRESH, IIO_EV_DIR_RISING)|\
525 IIO_EV_BIT(IIO_EV_TYPE_THRESH, IIO_EV_DIR_FALLING) \
526}
527
528static const struct iio_chan_spec ad7291_channels[] = {
529 AD7291_VOLTAGE_CHAN(0),
530 AD7291_VOLTAGE_CHAN(1),
531 AD7291_VOLTAGE_CHAN(2),
532 AD7291_VOLTAGE_CHAN(3),
533 AD7291_VOLTAGE_CHAN(4),
534 AD7291_VOLTAGE_CHAN(5),
535 AD7291_VOLTAGE_CHAN(6),
536 AD7291_VOLTAGE_CHAN(7),
537 {
538 .type = IIO_TEMP,
539 .info_mask = (1 << IIO_CHAN_INFO_AVERAGE_RAW_SEPARATE),
540 .indexed = 1,
541 .channel = 0,
542 .event_mask =
543 IIO_EV_BIT(IIO_EV_TYPE_THRESH, IIO_EV_DIR_RISING)|
544 IIO_EV_BIT(IIO_EV_TYPE_THRESH, IIO_EV_DIR_FALLING)
545 }
546};
547
Sonic Zhangddaecd52010-10-27 21:43:55 -0400548static struct attribute_group ad7291_event_attribute_group = {
549 .attrs = ad7291_event_attributes,
550};
551
Jonathan Cameron6fe81352011-05-18 14:42:37 +0100552static const struct iio_info ad7291_info = {
553 .attrs = &ad7291_attribute_group,
Jonathan Cameron4fd24242011-09-02 17:25:32 +0100554 .read_raw = &ad7291_read_raw,
555 .read_event_config = &ad7291_read_event_config,
556 .write_event_config = &ad7291_write_event_config,
557 .read_event_value = &ad7291_read_event_value,
558 .write_event_value = &ad7291_write_event_value,
Jonathan Cameron6fe81352011-05-18 14:42:37 +0100559 .event_attrs = &ad7291_event_attribute_group,
560};
561
Sonic Zhangddaecd52010-10-27 21:43:55 -0400562static int __devinit ad7291_probe(struct i2c_client *client,
563 const struct i2c_device_id *id)
564{
565 struct ad7291_chip_info *chip;
Jonathan Camerond4397972011-06-27 13:07:23 +0100566 struct iio_dev *indio_dev;
Michael Hennerich3b424f32011-09-02 17:25:39 +0100567 int ret = 0, voltage_uv = 0;
Sonic Zhangddaecd52010-10-27 21:43:55 -0400568
Jonathan Camerond4397972011-06-27 13:07:23 +0100569 indio_dev = iio_allocate_device(sizeof(*chip));
570 if (indio_dev == NULL) {
571 ret = -ENOMEM;
572 goto error_ret;
573 }
Dan Carpenter03bda052011-06-29 22:50:48 +0300574 chip = iio_priv(indio_dev);
Michael Hennerich3b424f32011-09-02 17:25:39 +0100575
576 chip->reg = regulator_get(&client->dev, "vcc");
577 if (!IS_ERR(chip->reg)) {
578 ret = regulator_enable(chip->reg);
579 if (ret)
580 goto error_put_reg;
581 voltage_uv = regulator_get_voltage(chip->reg);
582 }
583
Jonathan Cameron4fd24242011-09-02 17:25:32 +0100584 mutex_init(&chip->state_lock);
Sonic Zhangddaecd52010-10-27 21:43:55 -0400585 /* this is only used for device removal purposes */
Jonathan Camerond4397972011-06-27 13:07:23 +0100586 i2c_set_clientdata(client, indio_dev);
Sonic Zhangddaecd52010-10-27 21:43:55 -0400587
588 chip->client = client;
Jonathan Cameron4fd24242011-09-02 17:25:32 +0100589 /* Tsense always enabled */
Sonic Zhangddaecd52010-10-27 21:43:55 -0400590 chip->command = AD7291_NOISE_DELAY | AD7291_T_SENSE_MASK;
591
Michael Hennerich3b424f32011-09-02 17:25:39 +0100592 if (voltage_uv) {
593 chip->int_vref_mv = voltage_uv / 1000;
594 chip->command |= AD7291_EXT_REF;
595 } else {
596 chip->int_vref_mv = 2500; /* Build-in ref */
597 }
598
Jonathan Camerond4397972011-06-27 13:07:23 +0100599 indio_dev->name = id->name;
Jonathan Cameron4fd24242011-09-02 17:25:32 +0100600 indio_dev->channels = ad7291_channels;
601 indio_dev->num_channels = ARRAY_SIZE(ad7291_channels);
602
Jonathan Camerond4397972011-06-27 13:07:23 +0100603 indio_dev->dev.parent = &client->dev;
604 indio_dev->info = &ad7291_info;
605 indio_dev->modes = INDIO_DIRECT_MODE;
Sonic Zhangddaecd52010-10-27 21:43:55 -0400606
Sonic Zhangddaecd52010-10-27 21:43:55 -0400607 if (client->irq > 0) {
Jonathan Cameron58c03232011-05-18 14:41:11 +0100608 ret = request_threaded_irq(client->irq,
609 NULL,
610 &ad7291_event_handler,
611 IRQF_TRIGGER_LOW | IRQF_ONESHOT,
Jonathan Cameron845bd122011-05-18 14:41:44 +0100612 id->name,
Jonathan Camerond4397972011-06-27 13:07:23 +0100613 indio_dev);
Sonic Zhangddaecd52010-10-27 21:43:55 -0400614 if (ret)
Michael Hennerich3b424f32011-09-02 17:25:39 +0100615 goto error_disable_reg;
Sonic Zhangddaecd52010-10-27 21:43:55 -0400616
Sonic Zhangddaecd52010-10-27 21:43:55 -0400617 /* set irq polarity low level */
Michael Hennerichf22c1cf2011-09-02 17:25:37 +0100618 chip->command |= AD7291_ALERT_POLARITY;
Sonic Zhangddaecd52010-10-27 21:43:55 -0400619 }
620
621 ret = ad7291_i2c_write(chip, AD7291_COMMAND, chip->command);
622 if (ret) {
623 ret = -EIO;
624 goto error_unreg_irq;
625 }
626
Jonathan Cameron26d25ae2011-09-02 17:14:40 +0100627 ret = iio_device_register(indio_dev);
628 if (ret)
629 goto error_unreg_irq;
630
Michael Hennerich3b424f32011-09-02 17:25:39 +0100631 dev_info(&client->dev, "%s ADC registered.\n",
Sonic Zhangddaecd52010-10-27 21:43:55 -0400632 id->name);
633
634 return 0;
635
636error_unreg_irq:
Jonathan Cameron4fd24242011-09-02 17:25:32 +0100637 if (client->irq)
638 free_irq(client->irq, indio_dev);
Michael Hennerich3b424f32011-09-02 17:25:39 +0100639error_disable_reg:
640 if (!IS_ERR(chip->reg))
641 regulator_disable(chip->reg);
642error_put_reg:
643 if (!IS_ERR(chip->reg))
644 regulator_put(chip->reg);
645
Jonathan Camerond4397972011-06-27 13:07:23 +0100646 iio_free_device(indio_dev);
647error_ret:
Sonic Zhangddaecd52010-10-27 21:43:55 -0400648 return ret;
649}
650
651static int __devexit ad7291_remove(struct i2c_client *client)
652{
Jonathan Camerond4397972011-06-27 13:07:23 +0100653 struct iio_dev *indio_dev = i2c_get_clientdata(client);
Michael Hennerich3b424f32011-09-02 17:25:39 +0100654 struct ad7291_chip_info *chip = iio_priv(indio_dev);
Sonic Zhangddaecd52010-10-27 21:43:55 -0400655
656 if (client->irq)
Jonathan Camerond4397972011-06-27 13:07:23 +0100657 free_irq(client->irq, indio_dev);
Michael Hennerich3b424f32011-09-02 17:25:39 +0100658
659 if (!IS_ERR(chip->reg)) {
660 regulator_disable(chip->reg);
661 regulator_put(chip->reg);
662 }
663
Sonic Zhangddaecd52010-10-27 21:43:55 -0400664 iio_device_unregister(indio_dev);
Sonic Zhangddaecd52010-10-27 21:43:55 -0400665
666 return 0;
667}
668
669static const struct i2c_device_id ad7291_id[] = {
670 { "ad7291", 0 },
671 {}
672};
673
674MODULE_DEVICE_TABLE(i2c, ad7291_id);
675
676static struct i2c_driver ad7291_driver = {
677 .driver = {
678 .name = "ad7291",
679 },
680 .probe = ad7291_probe,
681 .remove = __devexit_p(ad7291_remove),
682 .id_table = ad7291_id,
683};
684
685static __init int ad7291_init(void)
686{
687 return i2c_add_driver(&ad7291_driver);
688}
689
690static __exit void ad7291_exit(void)
691{
692 i2c_del_driver(&ad7291_driver);
693}
694
695MODULE_AUTHOR("Sonic Zhang <sonic.zhang@analog.com>");
696MODULE_DESCRIPTION("Analog Devices AD7291 digital"
697 " temperature sensor driver");
698MODULE_LICENSE("GPL v2");
699
700module_init(ad7291_init);
701module_exit(ad7291_exit);