blob: a2e61c2fc8d19a319aa1d29e4bfadc7866d6c3f3 [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
Jonathan Cameron06458e22012-04-25 15:54:58 +010020#include <linux/iio/iio.h>
21#include <linux/iio/sysfs.h>
22#include <linux/iio/events.h>
Sonic Zhangddaecd52010-10-27 21:43:55 -040023
Lars-Peter Clausen1df9d1d2013-06-14 16:58:00 +010024#include "ad7291.h"
25
Sonic Zhangddaecd52010-10-27 21:43:55 -040026/*
Jonathan Cameron4fd24242011-09-02 17:25:32 +010027 * Simplified handling
28 *
29 * If no events enabled - single polled channel read
30 * If event enabled direct reads disable unless channel
31 * is in the read mask.
32 *
33 * The noise-delayed bit as per datasheet suggestion is always enabled.
34 *
Jonathan Cameron4fd24242011-09-02 17:25:32 +010035 */
Michael Hennerich3b424f32011-09-02 17:25:39 +010036
Jonathan Cameron4fd24242011-09-02 17:25:32 +010037/*
Sonic Zhangddaecd52010-10-27 21:43:55 -040038 * AD7291 registers definition
39 */
Michael Hennerich81e2edb2011-09-02 17:25:40 +010040#define AD7291_COMMAND 0x00
41#define AD7291_VOLTAGE 0x01
42#define AD7291_T_SENSE 0x02
43#define AD7291_T_AVERAGE 0x03
Lars-Peter Clausen3f8db0d2013-06-14 16:58:00 +010044#define AD7291_DATA_HIGH(x) ((x) * 3 + 0x4)
45#define AD7291_DATA_LOW(x) ((x) * 3 + 0x5)
46#define AD7291_HYST(x) ((x) * 3 + 0x6)
Michael Hennerich00feefb2011-09-02 17:25:38 +010047#define AD7291_VOLTAGE_ALERT_STATUS 0x1F
Sonic Zhangddaecd52010-10-27 21:43:55 -040048#define AD7291_T_ALERT_STATUS 0x20
49
Michael Hennerich81e2edb2011-09-02 17:25:40 +010050#define AD7291_VOLTAGE_LIMIT_COUNT 8
51
52
Sonic Zhangddaecd52010-10-27 21:43:55 -040053/*
54 * AD7291 command
55 */
Michael Hennerich00feefb2011-09-02 17:25:38 +010056#define AD7291_AUTOCYCLE (1 << 0)
57#define AD7291_RESET (1 << 1)
58#define AD7291_ALERT_CLEAR (1 << 2)
59#define AD7291_ALERT_POLARITY (1 << 3)
60#define AD7291_EXT_REF (1 << 4)
61#define AD7291_NOISE_DELAY (1 << 5)
62#define AD7291_T_SENSE_MASK (1 << 7)
63#define AD7291_VOLTAGE_MASK 0xFF00
Sonic Zhangddaecd52010-10-27 21:43:55 -040064#define AD7291_VOLTAGE_OFFSET 0x8
65
66/*
67 * AD7291 value masks
68 */
Michael Hennerich00feefb2011-09-02 17:25:38 +010069#define AD7291_CHANNEL_MASK 0xF000
Michael Hennerich3b424f32011-09-02 17:25:39 +010070#define AD7291_BITS 12
Michael Hennerich00feefb2011-09-02 17:25:38 +010071#define AD7291_VALUE_MASK 0xFFF
Sonic Zhangddaecd52010-10-27 21:43:55 -040072#define AD7291_T_VALUE_SIGN 0x400
73#define AD7291_T_VALUE_FLOAT_OFFSET 2
74#define AD7291_T_VALUE_FLOAT_MASK 0x2
75
Michael Hennerich3b424f32011-09-02 17:25:39 +010076#define AD7291_BITS 12
77
Sonic Zhangddaecd52010-10-27 21:43:55 -040078struct ad7291_chip_info {
Michael Hennerich3b424f32011-09-02 17:25:39 +010079 struct i2c_client *client;
80 struct regulator *reg;
Michael Hennerich3b424f32011-09-02 17:25:39 +010081 u16 command;
Michael Hennerich06420c22011-09-02 17:25:43 +010082 u16 c_mask; /* Active voltage channels for events */
Michael Henneriche68b1db2011-09-02 17:25:45 +010083 struct mutex state_lock;
Sonic Zhangddaecd52010-10-27 21:43:55 -040084};
85
Sonic Zhangddaecd52010-10-27 21:43:55 -040086static int ad7291_i2c_read(struct ad7291_chip_info *chip, u8 reg, u16 *data)
87{
88 struct i2c_client *client = chip->client;
89 int ret = 0;
90
Lars-Peter Clausen7bd49fe12013-06-14 16:58:00 +010091 ret = i2c_smbus_read_word_swapped(client, reg);
Sonic Zhangddaecd52010-10-27 21:43:55 -040092 if (ret < 0) {
93 dev_err(&client->dev, "I2C read error\n");
94 return ret;
95 }
96
Lars-Peter Clausen7bd49fe12013-06-14 16:58:00 +010097 *data = ret;
Sonic Zhangddaecd52010-10-27 21:43:55 -040098
99 return 0;
100}
101
102static int ad7291_i2c_write(struct ad7291_chip_info *chip, u8 reg, u16 data)
103{
Lars-Peter Clausen7bd49fe12013-06-14 16:58:00 +0100104 return i2c_smbus_write_word_swapped(chip->client, reg, data);
Sonic Zhangddaecd52010-10-27 21:43:55 -0400105}
106
Jonathan Cameron58c03232011-05-18 14:41:11 +0100107static irqreturn_t ad7291_event_handler(int irq, void *private)
Sonic Zhangddaecd52010-10-27 21:43:55 -0400108{
Jonathan Cameron58c03232011-05-18 14:41:11 +0100109 struct iio_dev *indio_dev = private;
Jonathan Camerond4397972011-06-27 13:07:23 +0100110 struct ad7291_chip_info *chip = iio_priv(private);
Sonic Zhangddaecd52010-10-27 21:43:55 -0400111 u16 t_status, v_status;
112 u16 command;
113 int i;
Jonathan Cameron58c03232011-05-18 14:41:11 +0100114 s64 timestamp = iio_get_time_ns();
Sonic Zhangddaecd52010-10-27 21:43:55 -0400115
116 if (ad7291_i2c_read(chip, AD7291_T_ALERT_STATUS, &t_status))
Jonathan Cameron58c03232011-05-18 14:41:11 +0100117 return IRQ_HANDLED;
Sonic Zhangddaecd52010-10-27 21:43:55 -0400118
119 if (ad7291_i2c_read(chip, AD7291_VOLTAGE_ALERT_STATUS, &v_status))
Jonathan Cameron58c03232011-05-18 14:41:11 +0100120 return IRQ_HANDLED;
Sonic Zhangddaecd52010-10-27 21:43:55 -0400121
122 if (!(t_status || v_status))
Jonathan Cameron58c03232011-05-18 14:41:11 +0100123 return IRQ_HANDLED;
Sonic Zhangddaecd52010-10-27 21:43:55 -0400124
Michael Hennerichf22c1cf2011-09-02 17:25:37 +0100125 command = chip->command | AD7291_ALERT_CLEAR;
Sonic Zhangddaecd52010-10-27 21:43:55 -0400126 ad7291_i2c_write(chip, AD7291_COMMAND, command);
127
Michael Hennerichf22c1cf2011-09-02 17:25:37 +0100128 command = chip->command & ~AD7291_ALERT_CLEAR;
Sonic Zhangddaecd52010-10-27 21:43:55 -0400129 ad7291_i2c_write(chip, AD7291_COMMAND, command);
130
Jonathan Cameron4fd24242011-09-02 17:25:32 +0100131 /* For now treat t_sense and t_sense_average the same */
132 if ((t_status & (1 << 0)) || (t_status & (1 << 2)))
Jonathan Cameron5aa96182011-08-30 12:41:06 +0100133 iio_push_event(indio_dev,
Jonathan Cameronb206c3b2011-05-18 14:42:15 +0100134 IIO_UNMOD_EVENT_CODE(IIO_TEMP,
135 0,
136 IIO_EV_TYPE_THRESH,
137 IIO_EV_DIR_FALLING),
138 timestamp);
Jonathan Cameron4fd24242011-09-02 17:25:32 +0100139 if ((t_status & (1 << 1)) || (t_status & (1 << 3)))
Jonathan Cameron5aa96182011-08-30 12:41:06 +0100140 iio_push_event(indio_dev,
Jonathan Cameronb206c3b2011-05-18 14:42:15 +0100141 IIO_UNMOD_EVENT_CODE(IIO_TEMP,
142 0,
143 IIO_EV_TYPE_THRESH,
144 IIO_EV_DIR_RISING),
145 timestamp);
Sonic Zhangddaecd52010-10-27 21:43:55 -0400146
Jonathan Cameronb206c3b2011-05-18 14:42:15 +0100147 for (i = 0; i < AD7291_VOLTAGE_LIMIT_COUNT*2; i += 2) {
Sonic Zhangddaecd52010-10-27 21:43:55 -0400148 if (v_status & (1 << i))
Jonathan Cameron5aa96182011-08-30 12:41:06 +0100149 iio_push_event(indio_dev,
Jonathan Cameron6835cb62011-09-27 09:56:41 +0100150 IIO_UNMOD_EVENT_CODE(IIO_VOLTAGE,
Jonathan Cameronb206c3b2011-05-18 14:42:15 +0100151 i/2,
152 IIO_EV_TYPE_THRESH,
153 IIO_EV_DIR_FALLING),
154 timestamp);
155 if (v_status & (1 << (i + 1)))
Jonathan Cameron5aa96182011-08-30 12:41:06 +0100156 iio_push_event(indio_dev,
Jonathan Cameron6835cb62011-09-27 09:56:41 +0100157 IIO_UNMOD_EVENT_CODE(IIO_VOLTAGE,
Jonathan Cameronb206c3b2011-05-18 14:42:15 +0100158 i/2,
159 IIO_EV_TYPE_THRESH,
160 IIO_EV_DIR_RISING),
161 timestamp);
Sonic Zhangddaecd52010-10-27 21:43:55 -0400162 }
Jonathan Cameron58c03232011-05-18 14:41:11 +0100163
164 return IRQ_HANDLED;
Sonic Zhangddaecd52010-10-27 21:43:55 -0400165}
166
Jonathan Cameron4fd24242011-09-02 17:25:32 +0100167static inline ssize_t ad7291_show_hyst(struct device *dev,
Sonic Zhangddaecd52010-10-27 21:43:55 -0400168 struct device_attribute *attr,
Sonic Zhangddaecd52010-10-27 21:43:55 -0400169 char *buf)
170{
Lars-Peter Clausen62c51832012-05-12 15:39:42 +0200171 struct iio_dev *indio_dev = dev_to_iio_dev(dev);
Jonathan Cameron84f79ec2011-10-06 17:14:37 +0100172 struct ad7291_chip_info *chip = iio_priv(indio_dev);
Jonathan Cameron58c03232011-05-18 14:41:11 +0100173 struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
Sonic Zhangddaecd52010-10-27 21:43:55 -0400174 u16 data;
Sonic Zhangddaecd52010-10-27 21:43:55 -0400175 int ret;
176
Jonathan Cameron58c03232011-05-18 14:41:11 +0100177 ret = ad7291_i2c_read(chip, this_attr->address, &data);
Jonathan Cameron4fd24242011-09-02 17:25:32 +0100178 if (ret < 0)
179 return ret;
Sonic Zhangddaecd52010-10-27 21:43:55 -0400180
Michael Hennerich81e2edb2011-09-02 17:25:40 +0100181 return sprintf(buf, "%d\n", data & AD7291_VALUE_MASK);
Sonic Zhangddaecd52010-10-27 21:43:55 -0400182}
183
Jonathan Cameron4fd24242011-09-02 17:25:32 +0100184static inline ssize_t ad7291_set_hyst(struct device *dev,
185 struct device_attribute *attr,
186 const char *buf,
187 size_t len)
Sonic Zhangddaecd52010-10-27 21:43:55 -0400188{
Lars-Peter Clausen62c51832012-05-12 15:39:42 +0200189 struct iio_dev *indio_dev = dev_to_iio_dev(dev);
Jonathan Cameron84f79ec2011-10-06 17:14:37 +0100190 struct ad7291_chip_info *chip = iio_priv(indio_dev);
Jonathan Cameron58c03232011-05-18 14:41:11 +0100191 struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
Sonic Zhangddaecd52010-10-27 21:43:55 -0400192 u16 data;
193 int ret;
194
Jonathan Cameron4fd24242011-09-02 17:25:32 +0100195 ret = kstrtou16(buf, 10, &data);
196
197 if (ret < 0)
198 return ret;
Michael Hennericha3ef65d2011-09-02 17:25:46 +0100199 if (data > AD7291_VALUE_MASK)
Sonic Zhangddaecd52010-10-27 21:43:55 -0400200 return -EINVAL;
201
Michael Hennericha3ef65d2011-09-02 17:25:46 +0100202 ret = ad7291_i2c_write(chip, this_attr->address, data);
203 if (ret < 0)
204 return ret;
205
206 return len;
Sonic Zhangddaecd52010-10-27 21:43:55 -0400207}
208
Jonathan Cameron4fd24242011-09-02 17:25:32 +0100209static IIO_DEVICE_ATTR(in_temp0_thresh_both_hyst_raw,
Jonathan Cameron58c03232011-05-18 14:41:11 +0100210 S_IRUGO | S_IWUSR,
Jonathan Cameron4fd24242011-09-02 17:25:32 +0100211 ad7291_show_hyst, ad7291_set_hyst,
Lars-Peter Clausen3f8db0d2013-06-14 16:58:00 +0100212 AD7291_HYST(8));
Jonathan Cameron4fd24242011-09-02 17:25:32 +0100213static IIO_DEVICE_ATTR(in_voltage0_thresh_both_hyst_raw,
Jonathan Cameron58c03232011-05-18 14:41:11 +0100214 S_IRUGO | S_IWUSR,
Lars-Peter Clausen3f8db0d2013-06-14 16:58:00 +0100215 ad7291_show_hyst, ad7291_set_hyst, AD7291_HYST(0));
Jonathan Cameron4fd24242011-09-02 17:25:32 +0100216static IIO_DEVICE_ATTR(in_voltage1_thresh_both_hyst_raw,
Jonathan Cameron58c03232011-05-18 14:41:11 +0100217 S_IRUGO | S_IWUSR,
Lars-Peter Clausen3f8db0d2013-06-14 16:58:00 +0100218 ad7291_show_hyst, ad7291_set_hyst, AD7291_HYST(1));
Jonathan Cameron4fd24242011-09-02 17:25:32 +0100219static IIO_DEVICE_ATTR(in_voltage2_thresh_both_hyst_raw,
Jonathan Cameron58c03232011-05-18 14:41:11 +0100220 S_IRUGO | S_IWUSR,
Lars-Peter Clausen3f8db0d2013-06-14 16:58:00 +0100221 ad7291_show_hyst, ad7291_set_hyst, AD7291_HYST(2));
Jonathan Cameron4fd24242011-09-02 17:25:32 +0100222static IIO_DEVICE_ATTR(in_voltage3_thresh_both_hyst_raw,
Jonathan Cameron58c03232011-05-18 14:41:11 +0100223 S_IRUGO | S_IWUSR,
Lars-Peter Clausen3f8db0d2013-06-14 16:58:00 +0100224 ad7291_show_hyst, ad7291_set_hyst, AD7291_HYST(3));
Jonathan Cameron4fd24242011-09-02 17:25:32 +0100225static IIO_DEVICE_ATTR(in_voltage4_thresh_both_hyst_raw,
Jonathan Cameron58c03232011-05-18 14:41:11 +0100226 S_IRUGO | S_IWUSR,
Lars-Peter Clausen3f8db0d2013-06-14 16:58:00 +0100227 ad7291_show_hyst, ad7291_set_hyst, AD7291_HYST(4));
Jonathan Cameron4fd24242011-09-02 17:25:32 +0100228static IIO_DEVICE_ATTR(in_voltage5_thresh_both_hyst_raw,
Jonathan Cameron58c03232011-05-18 14:41:11 +0100229 S_IRUGO | S_IWUSR,
Lars-Peter Clausen3f8db0d2013-06-14 16:58:00 +0100230 ad7291_show_hyst, ad7291_set_hyst, AD7291_HYST(5));
Jonathan Cameron4fd24242011-09-02 17:25:32 +0100231static IIO_DEVICE_ATTR(in_voltage6_thresh_both_hyst_raw,
Jonathan Cameron58c03232011-05-18 14:41:11 +0100232 S_IRUGO | S_IWUSR,
Lars-Peter Clausen3f8db0d2013-06-14 16:58:00 +0100233 ad7291_show_hyst, ad7291_set_hyst, AD7291_HYST(6));
Jonathan Cameron4fd24242011-09-02 17:25:32 +0100234static IIO_DEVICE_ATTR(in_voltage7_thresh_both_hyst_raw,
Jonathan Cameron58c03232011-05-18 14:41:11 +0100235 S_IRUGO | S_IWUSR,
Lars-Peter Clausen3f8db0d2013-06-14 16:58:00 +0100236 ad7291_show_hyst, ad7291_set_hyst, AD7291_HYST(7));
Sonic Zhangddaecd52010-10-27 21:43:55 -0400237
238static struct attribute *ad7291_event_attributes[] = {
Jonathan Cameron4fd24242011-09-02 17:25:32 +0100239 &iio_dev_attr_in_temp0_thresh_both_hyst_raw.dev_attr.attr,
240 &iio_dev_attr_in_voltage0_thresh_both_hyst_raw.dev_attr.attr,
241 &iio_dev_attr_in_voltage1_thresh_both_hyst_raw.dev_attr.attr,
242 &iio_dev_attr_in_voltage2_thresh_both_hyst_raw.dev_attr.attr,
243 &iio_dev_attr_in_voltage3_thresh_both_hyst_raw.dev_attr.attr,
244 &iio_dev_attr_in_voltage4_thresh_both_hyst_raw.dev_attr.attr,
245 &iio_dev_attr_in_voltage5_thresh_both_hyst_raw.dev_attr.attr,
246 &iio_dev_attr_in_voltage6_thresh_both_hyst_raw.dev_attr.attr,
247 &iio_dev_attr_in_voltage7_thresh_both_hyst_raw.dev_attr.attr,
Sonic Zhangddaecd52010-10-27 21:43:55 -0400248 NULL,
249};
250
Lars-Peter Clausen3f8db0d2013-06-14 16:58:00 +0100251static unsigned int ad7291_threshold_reg(u64 event_code)
252{
253 unsigned int offset;
254
255 switch (IIO_EVENT_CODE_EXTRACT_CHAN_TYPE(event_code)) {
256 case IIO_VOLTAGE:
257 offset = IIO_EVENT_CODE_EXTRACT_CHAN(event_code);
258 break;
259 case IIO_TEMP:
260 offset = 8;
261 break;
262 default:
263 return 0;
264 }
265
266 if (IIO_EVENT_CODE_EXTRACT_DIR(event_code) == IIO_EV_DIR_FALLING)
267 return AD7291_DATA_LOW(offset);
268 else
269 return AD7291_DATA_HIGH(offset);
270}
Jonathan Cameron4fd24242011-09-02 17:25:32 +0100271
272static int ad7291_read_event_value(struct iio_dev *indio_dev,
273 u64 event_code,
274 int *val)
275{
276 struct ad7291_chip_info *chip = iio_priv(indio_dev);
Jonathan Cameron4fd24242011-09-02 17:25:32 +0100277 int ret;
Jonathan Cameron4fd24242011-09-02 17:25:32 +0100278 u16 uval;
Jonathan Cameron4fd24242011-09-02 17:25:32 +0100279
Lars-Peter Clausen3f8db0d2013-06-14 16:58:00 +0100280 ret = ad7291_i2c_read(chip, ad7291_threshold_reg(event_code), &uval);
281 if (ret < 0)
282 return ret;
283
Michael Hennerichb5765902011-09-02 17:25:42 +0100284 switch (IIO_EVENT_CODE_EXTRACT_CHAN_TYPE(event_code)) {
Jonathan Cameron4fd24242011-09-02 17:25:32 +0100285 case IIO_VOLTAGE:
Michael Hennerich81e2edb2011-09-02 17:25:40 +0100286 *val = uval & AD7291_VALUE_MASK;
Jonathan Cameron4fd24242011-09-02 17:25:32 +0100287 return 0;
Jonathan Cameron4fd24242011-09-02 17:25:32 +0100288 case IIO_TEMP:
Lars-Peter Clausen88198d22013-06-14 16:58:00 +0100289 *val = sign_extend32(uval, 11);
Jonathan Cameron4fd24242011-09-02 17:25:32 +0100290 return 0;
291 default:
292 return -EINVAL;
293 };
294}
295
296static int ad7291_write_event_value(struct iio_dev *indio_dev,
297 u64 event_code,
298 int val)
299{
300 struct ad7291_chip_info *chip = iio_priv(indio_dev);
Jonathan Cameron4fd24242011-09-02 17:25:32 +0100301
Michael Hennerichb5765902011-09-02 17:25:42 +0100302 switch (IIO_EVENT_CODE_EXTRACT_CHAN_TYPE(event_code)) {
Jonathan Cameron4fd24242011-09-02 17:25:32 +0100303 case IIO_VOLTAGE:
Michael Hennericha3ef65d2011-09-02 17:25:46 +0100304 if (val > AD7291_VALUE_MASK || val < 0)
Jonathan Cameron4fd24242011-09-02 17:25:32 +0100305 return -EINVAL;
Lars-Peter Clausen3f8db0d2013-06-14 16:58:00 +0100306 break;
Jonathan Cameron4fd24242011-09-02 17:25:32 +0100307 case IIO_TEMP:
308 if (val > 2047 || val < -2048)
309 return -EINVAL;
Lars-Peter Clausen3f8db0d2013-06-14 16:58:00 +0100310 break;
Jonathan Cameron4fd24242011-09-02 17:25:32 +0100311 default:
312 return -EINVAL;
Lars-Peter Clausen3f8db0d2013-06-14 16:58:00 +0100313 }
314
315 return ad7291_i2c_write(chip, ad7291_threshold_reg(event_code), val);
Jonathan Cameron4fd24242011-09-02 17:25:32 +0100316}
317
318static int ad7291_read_event_config(struct iio_dev *indio_dev,
319 u64 event_code)
320{
321 struct ad7291_chip_info *chip = iio_priv(indio_dev);
322 /* To be enabled the channel must simply be on. If any are enabled
323 we are in continuous sampling mode */
324
Michael Hennerichb5765902011-09-02 17:25:42 +0100325 switch (IIO_EVENT_CODE_EXTRACT_CHAN_TYPE(event_code)) {
Jonathan Cameron4fd24242011-09-02 17:25:32 +0100326 case IIO_VOLTAGE:
327 if (chip->c_mask &
Lars-Peter Clausenda367162012-02-13 10:25:32 +0100328 (1 << (15 - IIO_EVENT_CODE_EXTRACT_CHAN(event_code))))
Jonathan Cameron4fd24242011-09-02 17:25:32 +0100329 return 1;
330 else
331 return 0;
332 case IIO_TEMP:
333 /* always on */
334 return 1;
335 default:
336 return -EINVAL;
337 }
338
339}
340
341static int ad7291_write_event_config(struct iio_dev *indio_dev,
342 u64 event_code,
343 int state)
344{
345 int ret = 0;
346 struct ad7291_chip_info *chip = iio_priv(indio_dev);
347 u16 regval;
348
349 mutex_lock(&chip->state_lock);
350 regval = chip->command;
351 /*
352 * To be enabled the channel must simply be on. If any are enabled
353 * use continuous sampling mode.
354 * Possible to disable temp as well but that makes single read tricky.
355 */
Michael Hennerich81e2edb2011-09-02 17:25:40 +0100356
Jonathan Cameron4fd24242011-09-02 17:25:32 +0100357 switch (IIO_EVENT_CODE_EXTRACT_TYPE(event_code)) {
358 case IIO_VOLTAGE:
Michael Hennerich06420c22011-09-02 17:25:43 +0100359 if ((!state) && (chip->c_mask & (1 << (15 -
Lars-Peter Clausenda367162012-02-13 10:25:32 +0100360 IIO_EVENT_CODE_EXTRACT_CHAN(event_code)))))
361 chip->c_mask &= ~(1 << (15 - IIO_EVENT_CODE_EXTRACT_CHAN
Michael Hennerich06420c22011-09-02 17:25:43 +0100362 (event_code)));
363 else if (state && (!(chip->c_mask & (1 << (15 -
Lars-Peter Clausenda367162012-02-13 10:25:32 +0100364 IIO_EVENT_CODE_EXTRACT_CHAN(event_code))))))
365 chip->c_mask |= (1 << (15 - IIO_EVENT_CODE_EXTRACT_CHAN
Michael Hennerich06420c22011-09-02 17:25:43 +0100366 (event_code)));
Jonathan Cameron4fd24242011-09-02 17:25:32 +0100367 else
368 break;
369
Michael Hennerich81e2edb2011-09-02 17:25:40 +0100370 regval &= ~AD7291_AUTOCYCLE;
Michael Hennerich06420c22011-09-02 17:25:43 +0100371 regval |= chip->c_mask;
Jonathan Cameron4fd24242011-09-02 17:25:32 +0100372 if (chip->c_mask) /* Enable autocycle? */
373 regval |= AD7291_AUTOCYCLE;
374
375 ret = ad7291_i2c_write(chip, AD7291_COMMAND, regval);
376 if (ret < 0)
377 goto error_ret;
378
379 chip->command = regval;
380 break;
381 default:
382 ret = -EINVAL;
383 }
384
385error_ret:
386 mutex_unlock(&chip->state_lock);
387 return ret;
388}
389
390static int ad7291_read_raw(struct iio_dev *indio_dev,
391 struct iio_chan_spec const *chan,
392 int *val,
393 int *val2,
394 long mask)
395{
396 int ret;
397 struct ad7291_chip_info *chip = iio_priv(indio_dev);
398 u16 regval;
Jonathan Cameron4fd24242011-09-02 17:25:32 +0100399
400 switch (mask) {
Jonathan Cameronb11f98f2012-04-15 17:41:18 +0100401 case IIO_CHAN_INFO_RAW:
Jonathan Cameron4fd24242011-09-02 17:25:32 +0100402 switch (chan->type) {
403 case IIO_VOLTAGE:
404 mutex_lock(&chip->state_lock);
405 /* If in autocycle mode drop through */
Michael Hennerich06420c22011-09-02 17:25:43 +0100406 if (chip->command & AD7291_AUTOCYCLE) {
Jonathan Cameron4fd24242011-09-02 17:25:32 +0100407 mutex_unlock(&chip->state_lock);
408 return -EBUSY;
409 }
410 /* Enable this channel alone */
411 regval = chip->command & (~AD7291_VOLTAGE_MASK);
Michael Henneriche70ab212011-09-02 17:25:36 +0100412 regval |= 1 << (15 - chan->channel);
Jonathan Cameron4fd24242011-09-02 17:25:32 +0100413 ret = ad7291_i2c_write(chip, AD7291_COMMAND, regval);
414 if (ret < 0) {
415 mutex_unlock(&chip->state_lock);
416 return ret;
417 }
418 /* Read voltage */
Lars-Peter Clausen7bd49fe12013-06-14 16:58:00 +0100419 ret = i2c_smbus_read_word_swapped(chip->client,
Jonathan Cameron4fd24242011-09-02 17:25:32 +0100420 AD7291_VOLTAGE);
421 if (ret < 0) {
422 mutex_unlock(&chip->state_lock);
423 return ret;
424 }
Lars-Peter Clausen7bd49fe12013-06-14 16:58:00 +0100425 *val = ret & AD7291_VALUE_MASK;
Jonathan Cameron4fd24242011-09-02 17:25:32 +0100426 mutex_unlock(&chip->state_lock);
427 return IIO_VAL_INT;
428 case IIO_TEMP:
429 /* Assumes tsense bit of command register always set */
Lars-Peter Clausen7bd49fe12013-06-14 16:58:00 +0100430 ret = i2c_smbus_read_word_swapped(chip->client,
Jonathan Cameron4fd24242011-09-02 17:25:32 +0100431 AD7291_T_SENSE);
432 if (ret < 0)
433 return ret;
Lars-Peter Clausen88198d22013-06-14 16:58:00 +0100434 *val = sign_extend32(ret, 11);
Jonathan Cameron4fd24242011-09-02 17:25:32 +0100435 return IIO_VAL_INT;
436 default:
437 return -EINVAL;
438 }
Jonathan Cameronc8a9f802011-10-26 17:41:36 +0100439 case IIO_CHAN_INFO_AVERAGE_RAW:
Lars-Peter Clausen7bd49fe12013-06-14 16:58:00 +0100440 ret = i2c_smbus_read_word_swapped(chip->client,
Jonathan Cameron4fd24242011-09-02 17:25:32 +0100441 AD7291_T_AVERAGE);
442 if (ret < 0)
443 return ret;
Lars-Peter Clausen88198d22013-06-14 16:58:00 +0100444 *val = sign_extend32(ret, 11);
Jonathan Cameron4fd24242011-09-02 17:25:32 +0100445 return IIO_VAL_INT;
Jonathan Cameronc8a9f802011-10-26 17:41:36 +0100446 case IIO_CHAN_INFO_SCALE:
447 switch (chan->type) {
448 case IIO_VOLTAGE:
Lars-Peter Clausen1df9d1d2013-06-14 16:58:00 +0100449 if (chip->reg) {
450 int vref;
451 vref = regulator_get_voltage(chip->reg);
452 if (vref < 0)
453 return vref;
454 *val = vref / 1000;
455 } else {
456 *val = 2500;
457 }
Lars-Peter Clausen73a44452013-06-14 16:58:00 +0100458 *val2 = AD7291_BITS;
459 return IIO_VAL_FRACTIONAL_LOG2;
Jonathan Cameronc8a9f802011-10-26 17:41:36 +0100460 case IIO_TEMP:
461 /*
462 * One LSB of the ADC corresponds to 0.25 deg C.
463 * The temperature reading is in 12-bit twos
464 * complement format
465 */
466 *val = 250;
467 return IIO_VAL_INT;
468 default:
469 return -EINVAL;
470 }
Jonathan Cameron4fd24242011-09-02 17:25:32 +0100471 default:
472 return -EINVAL;
473 }
474}
475
476#define AD7291_VOLTAGE_CHAN(_chan) \
477{ \
478 .type = IIO_VOLTAGE, \
Jonathan Cameron03259482013-02-27 19:37:16 +0000479 .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), \
480 .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE), \
Jonathan Cameron4fd24242011-09-02 17:25:32 +0100481 .indexed = 1, \
482 .channel = _chan, \
483 .event_mask = IIO_EV_BIT(IIO_EV_TYPE_THRESH, IIO_EV_DIR_RISING)|\
484 IIO_EV_BIT(IIO_EV_TYPE_THRESH, IIO_EV_DIR_FALLING) \
485}
486
487static const struct iio_chan_spec ad7291_channels[] = {
488 AD7291_VOLTAGE_CHAN(0),
489 AD7291_VOLTAGE_CHAN(1),
490 AD7291_VOLTAGE_CHAN(2),
491 AD7291_VOLTAGE_CHAN(3),
492 AD7291_VOLTAGE_CHAN(4),
493 AD7291_VOLTAGE_CHAN(5),
494 AD7291_VOLTAGE_CHAN(6),
495 AD7291_VOLTAGE_CHAN(7),
496 {
497 .type = IIO_TEMP,
Jonathan Cameron03259482013-02-27 19:37:16 +0000498 .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
499 BIT(IIO_CHAN_INFO_AVERAGE_RAW) |
500 BIT(IIO_CHAN_INFO_SCALE),
Jonathan Cameron4fd24242011-09-02 17:25:32 +0100501 .indexed = 1,
502 .channel = 0,
503 .event_mask =
504 IIO_EV_BIT(IIO_EV_TYPE_THRESH, IIO_EV_DIR_RISING)|
505 IIO_EV_BIT(IIO_EV_TYPE_THRESH, IIO_EV_DIR_FALLING)
506 }
507};
508
Sonic Zhangddaecd52010-10-27 21:43:55 -0400509static struct attribute_group ad7291_event_attribute_group = {
510 .attrs = ad7291_event_attributes,
511};
512
Jonathan Cameron6fe81352011-05-18 14:42:37 +0100513static const struct iio_info ad7291_info = {
Jonathan Cameron4fd24242011-09-02 17:25:32 +0100514 .read_raw = &ad7291_read_raw,
515 .read_event_config = &ad7291_read_event_config,
516 .write_event_config = &ad7291_write_event_config,
517 .read_event_value = &ad7291_read_event_value,
518 .write_event_value = &ad7291_write_event_value,
Jonathan Cameron6fe81352011-05-18 14:42:37 +0100519 .event_attrs = &ad7291_event_attribute_group,
Wei Yongjunbb377962013-07-04 14:46:00 +0100520 .driver_module = THIS_MODULE,
Jonathan Cameron6fe81352011-05-18 14:42:37 +0100521};
522
Bill Pemberton4ae1c612012-11-19 13:21:57 -0500523static int ad7291_probe(struct i2c_client *client,
Sonic Zhangddaecd52010-10-27 21:43:55 -0400524 const struct i2c_device_id *id)
525{
Lars-Peter Clausen1df9d1d2013-06-14 16:58:00 +0100526 struct ad7291_platform_data *pdata = client->dev.platform_data;
Sonic Zhangddaecd52010-10-27 21:43:55 -0400527 struct ad7291_chip_info *chip;
Jonathan Camerond4397972011-06-27 13:07:23 +0100528 struct iio_dev *indio_dev;
Lars-Peter Clausen1df9d1d2013-06-14 16:58:00 +0100529 int ret = 0;
Sonic Zhangddaecd52010-10-27 21:43:55 -0400530
Lars-Peter Clausen7cbb7532012-04-26 13:35:01 +0200531 indio_dev = iio_device_alloc(sizeof(*chip));
Jonathan Camerond4397972011-06-27 13:07:23 +0100532 if (indio_dev == NULL) {
533 ret = -ENOMEM;
534 goto error_ret;
535 }
Dan Carpenter03bda052011-06-29 22:50:48 +0300536 chip = iio_priv(indio_dev);
Michael Hennerich3b424f32011-09-02 17:25:39 +0100537
Lars-Peter Clausen1df9d1d2013-06-14 16:58:00 +0100538 if (pdata && pdata->use_external_ref) {
539 chip->reg = regulator_get(&client->dev, "vref");
540 if (IS_ERR(chip->reg))
541 goto error_free;
542
Michael Hennerich3b424f32011-09-02 17:25:39 +0100543 ret = regulator_enable(chip->reg);
544 if (ret)
545 goto error_put_reg;
Michael Hennerich3b424f32011-09-02 17:25:39 +0100546 }
547
Jonathan Cameron4fd24242011-09-02 17:25:32 +0100548 mutex_init(&chip->state_lock);
Sonic Zhangddaecd52010-10-27 21:43:55 -0400549 /* this is only used for device removal purposes */
Jonathan Camerond4397972011-06-27 13:07:23 +0100550 i2c_set_clientdata(client, indio_dev);
Sonic Zhangddaecd52010-10-27 21:43:55 -0400551
552 chip->client = client;
Michael Hennerichc11f02e2011-09-02 17:25:44 +0100553
554 chip->command = AD7291_NOISE_DELAY |
555 AD7291_T_SENSE_MASK | /* Tsense always enabled */
556 AD7291_ALERT_POLARITY; /* set irq polarity low level */
Sonic Zhangddaecd52010-10-27 21:43:55 -0400557
Lars-Peter Clausen1df9d1d2013-06-14 16:58:00 +0100558 if (pdata && pdata->use_external_ref)
Michael Hennerich3b424f32011-09-02 17:25:39 +0100559 chip->command |= AD7291_EXT_REF;
Michael Hennerich3b424f32011-09-02 17:25:39 +0100560
Jonathan Camerond4397972011-06-27 13:07:23 +0100561 indio_dev->name = id->name;
Jonathan Cameron4fd24242011-09-02 17:25:32 +0100562 indio_dev->channels = ad7291_channels;
563 indio_dev->num_channels = ARRAY_SIZE(ad7291_channels);
564
Jonathan Camerond4397972011-06-27 13:07:23 +0100565 indio_dev->dev.parent = &client->dev;
566 indio_dev->info = &ad7291_info;
567 indio_dev->modes = INDIO_DIRECT_MODE;
Sonic Zhangddaecd52010-10-27 21:43:55 -0400568
Michael Hennerichc11f02e2011-09-02 17:25:44 +0100569 ret = ad7291_i2c_write(chip, AD7291_COMMAND, AD7291_RESET);
570 if (ret) {
571 ret = -EIO;
572 goto error_disable_reg;
573 }
574
575 ret = ad7291_i2c_write(chip, AD7291_COMMAND, chip->command);
576 if (ret) {
577 ret = -EIO;
578 goto error_disable_reg;
579 }
580
Sonic Zhangddaecd52010-10-27 21:43:55 -0400581 if (client->irq > 0) {
Jonathan Cameron58c03232011-05-18 14:41:11 +0100582 ret = request_threaded_irq(client->irq,
583 NULL,
584 &ad7291_event_handler,
585 IRQF_TRIGGER_LOW | IRQF_ONESHOT,
Jonathan Cameron845bd122011-05-18 14:41:44 +0100586 id->name,
Jonathan Camerond4397972011-06-27 13:07:23 +0100587 indio_dev);
Sonic Zhangddaecd52010-10-27 21:43:55 -0400588 if (ret)
Michael Hennerich3b424f32011-09-02 17:25:39 +0100589 goto error_disable_reg;
Sonic Zhangddaecd52010-10-27 21:43:55 -0400590 }
591
Jonathan Cameron26d25ae2011-09-02 17:14:40 +0100592 ret = iio_device_register(indio_dev);
593 if (ret)
594 goto error_unreg_irq;
595
Sonic Zhangddaecd52010-10-27 21:43:55 -0400596 return 0;
597
598error_unreg_irq:
Jonathan Cameron4fd24242011-09-02 17:25:32 +0100599 if (client->irq)
600 free_irq(client->irq, indio_dev);
Michael Hennerich3b424f32011-09-02 17:25:39 +0100601error_disable_reg:
Lars-Peter Clausen1df9d1d2013-06-14 16:58:00 +0100602 if (chip->reg)
Michael Hennerich3b424f32011-09-02 17:25:39 +0100603 regulator_disable(chip->reg);
604error_put_reg:
Lars-Peter Clausen1df9d1d2013-06-14 16:58:00 +0100605 if (chip->reg)
Michael Hennerich3b424f32011-09-02 17:25:39 +0100606 regulator_put(chip->reg);
Lars-Peter Clausen1df9d1d2013-06-14 16:58:00 +0100607error_free:
Lars-Peter Clausen7cbb7532012-04-26 13:35:01 +0200608 iio_device_free(indio_dev);
Jonathan Camerond4397972011-06-27 13:07:23 +0100609error_ret:
Sonic Zhangddaecd52010-10-27 21:43:55 -0400610 return ret;
611}
612
Bill Pemberton447d4f22012-11-19 13:26:37 -0500613static int ad7291_remove(struct i2c_client *client)
Sonic Zhangddaecd52010-10-27 21:43:55 -0400614{
Jonathan Camerond4397972011-06-27 13:07:23 +0100615 struct iio_dev *indio_dev = i2c_get_clientdata(client);
Michael Hennerich3b424f32011-09-02 17:25:39 +0100616 struct ad7291_chip_info *chip = iio_priv(indio_dev);
Sonic Zhangddaecd52010-10-27 21:43:55 -0400617
Jonathan Camerond2fffd62011-10-14 14:46:58 +0100618 iio_device_unregister(indio_dev);
619
Sonic Zhangddaecd52010-10-27 21:43:55 -0400620 if (client->irq)
Jonathan Camerond4397972011-06-27 13:07:23 +0100621 free_irq(client->irq, indio_dev);
Michael Hennerich3b424f32011-09-02 17:25:39 +0100622
Lars-Peter Clausen1df9d1d2013-06-14 16:58:00 +0100623 if (chip->reg) {
Michael Hennerich3b424f32011-09-02 17:25:39 +0100624 regulator_disable(chip->reg);
625 regulator_put(chip->reg);
626 }
627
Lars-Peter Clausen7cbb7532012-04-26 13:35:01 +0200628 iio_device_free(indio_dev);
Sonic Zhangddaecd52010-10-27 21:43:55 -0400629
630 return 0;
631}
632
633static const struct i2c_device_id ad7291_id[] = {
634 { "ad7291", 0 },
635 {}
636};
637
638MODULE_DEVICE_TABLE(i2c, ad7291_id);
639
640static struct i2c_driver ad7291_driver = {
641 .driver = {
Michael Henneriche68b1db2011-09-02 17:25:45 +0100642 .name = KBUILD_MODNAME,
Sonic Zhangddaecd52010-10-27 21:43:55 -0400643 },
644 .probe = ad7291_probe,
Bill Pembertone543acf2012-11-19 13:21:38 -0500645 .remove = ad7291_remove,
Sonic Zhangddaecd52010-10-27 21:43:55 -0400646 .id_table = ad7291_id,
647};
Lars-Peter Clausen6e5af182011-11-16 10:13:38 +0100648module_i2c_driver(ad7291_driver);
Sonic Zhangddaecd52010-10-27 21:43:55 -0400649
650MODULE_AUTHOR("Sonic Zhang <sonic.zhang@analog.com>");
Michael Henneriche68b1db2011-09-02 17:25:45 +0100651MODULE_DESCRIPTION("Analog Devices AD7291 ADC driver");
Sonic Zhangddaecd52010-10-27 21:43:55 -0400652MODULE_LICENSE("GPL v2");