blob: 485d0a5af53c8ac1f4b74abdec236254de56ffdc [file] [log] [blame]
Barry Songa20ebd92010-10-27 21:43:54 -04001/*
2 * AD7152 capacitive sensor driver supporting AD7152/3
3 *
Michael Henneriche5664292011-09-02 17:25:26 +01004 * Copyright 2010-2011a Analog Devices Inc.
Barry Songa20ebd92010-10-27 21:43:54 -04005 *
6 * Licensed under the GPL-2 or later.
7 */
8
9#include <linux/interrupt.h>
Barry Songa20ebd92010-10-27 21:43:54 -040010#include <linux/device.h>
11#include <linux/kernel.h>
12#include <linux/slab.h>
13#include <linux/sysfs.h>
Barry Songa20ebd92010-10-27 21:43:54 -040014#include <linux/i2c.h>
Paul Gortmaker99c97852011-07-03 15:49:50 -040015#include <linux/module.h>
Jonathan Cameronea993a52011-09-02 17:25:25 +010016#include <linux/delay.h>
Barry Songa20ebd92010-10-27 21:43:54 -040017
Jonathan Cameron06458e22012-04-25 15:54:58 +010018#include <linux/iio/iio.h>
19#include <linux/iio/sysfs.h>
Barry Songa20ebd92010-10-27 21:43:54 -040020
21/*
Michael Hennerichbb90cf82011-09-02 17:25:29 +010022 * TODO: Check compliance of calibbias with abi (units)
Jonathan Cameron3995f912011-09-02 17:25:23 +010023 */
24/*
Barry Songa20ebd92010-10-27 21:43:54 -040025 * AD7152 registers definition
26 */
27
Michael Henneriche5664292011-09-02 17:25:26 +010028#define AD7152_REG_STATUS 0
29#define AD7152_REG_CH1_DATA_HIGH 1
30#define AD7152_REG_CH2_DATA_HIGH 3
31#define AD7152_REG_CH1_OFFS_HIGH 5
32#define AD7152_REG_CH2_OFFS_HIGH 7
33#define AD7152_REG_CH1_GAIN_HIGH 9
34#define AD7152_REG_CH1_SETUP 11
35#define AD7152_REG_CH2_GAIN_HIGH 12
36#define AD7152_REG_CH2_SETUP 14
37#define AD7152_REG_CFG 15
38#define AD7152_REG_RESEVERD 16
39#define AD7152_REG_CAPDAC_POS 17
40#define AD7152_REG_CAPDAC_NEG 18
41#define AD7152_REG_CFG2 26
Barry Songa20ebd92010-10-27 21:43:54 -040042
Michael Henneriche5664292011-09-02 17:25:26 +010043/* Status Register Bit Designations (AD7152_REG_STATUS) */
44#define AD7152_STATUS_RDY1 (1 << 0)
45#define AD7152_STATUS_RDY2 (1 << 1)
46#define AD7152_STATUS_C1C2 (1 << 2)
47#define AD7152_STATUS_PWDN (1 << 7)
48
49/* Setup Register Bit Designations (AD7152_REG_CHx_SETUP) */
50#define AD7152_SETUP_CAPDIFF (1 << 5)
51#define AD7152_SETUP_RANGE_2pF (0 << 6)
52#define AD7152_SETUP_RANGE_0_5pF (1 << 6)
53#define AD7152_SETUP_RANGE_1pF (2 << 6)
54#define AD7152_SETUP_RANGE_4pF (3 << 6)
Michael Hennerich2b8cb402011-09-02 17:25:27 +010055#define AD7152_SETUP_RANGE(x) ((x) << 6)
Michael Henneriche5664292011-09-02 17:25:26 +010056
57/* Config Register Bit Designations (AD7152_REG_CFG) */
58#define AD7152_CONF_CH2EN (1 << 3)
59#define AD7152_CONF_CH1EN (1 << 4)
60#define AD7152_CONF_MODE_IDLE (0 << 0)
61#define AD7152_CONF_MODE_CONT_CONV (1 << 0)
62#define AD7152_CONF_MODE_SINGLE_CONV (2 << 0)
63#define AD7152_CONF_MODE_OFFS_CAL (5 << 0)
64#define AD7152_CONF_MODE_GAIN_CAL (6 << 0)
65
66/* Capdac Register Bit Designations (AD7152_REG_CAPDAC_XXX) */
67#define AD7152_CAPDAC_DACEN (1 << 7)
68#define AD7152_CAPDAC_DACP(x) ((x) & 0x1F)
69
Michael Hennerichc3b79152011-09-02 17:25:30 +010070/* CFG2 Register Bit Designations (AD7152_REG_CFG2) */
71#define AD7152_CFG2_OSR(x) (((x) & 0x3) << 4)
72
Michael Henneriche5664292011-09-02 17:25:26 +010073enum {
74 AD7152_DATA,
75 AD7152_OFFS,
76 AD7152_GAIN,
77 AD7152_SETUP
78};
Barry Songa20ebd92010-10-27 21:43:54 -040079
80/*
Masanari Iidae3c5be22014-04-22 12:23:00 +010081 * struct ad7152_chip_info - chip specific information
Barry Songa20ebd92010-10-27 21:43:54 -040082 */
83
84struct ad7152_chip_info {
Barry Songa20ebd92010-10-27 21:43:54 -040085 struct i2c_client *client;
Jonathan Cameron3995f912011-09-02 17:25:23 +010086 /*
87 * Capacitive channel digital filter setup;
88 * conversion time/update rate setup per channel
89 */
Michael Hennerich2b8cb402011-09-02 17:25:27 +010090 u8 filter_rate_setup;
91 u8 setup[2];
Barry Songa20ebd92010-10-27 21:43:54 -040092};
93
Jonathan Cameronea993a52011-09-02 17:25:25 +010094static inline ssize_t ad7152_start_calib(struct device *dev,
95 struct device_attribute *attr,
96 const char *buf,
97 size_t len,
98 u8 regval)
99{
Lars-Peter Clausend30a7f92012-05-12 15:39:45 +0200100 struct iio_dev *indio_dev = dev_to_iio_dev(dev);
Michael Hennerichbb90cf82011-09-02 17:25:29 +0100101 struct ad7152_chip_info *chip = iio_priv(indio_dev);
Jonathan Cameronea993a52011-09-02 17:25:25 +0100102 struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
103 bool doit;
Michael Hennerich2b8cb402011-09-02 17:25:27 +0100104 int ret, timeout = 10;
Barry Songa20ebd92010-10-27 21:43:54 -0400105
Jonathan Cameronea993a52011-09-02 17:25:25 +0100106 ret = strtobool(buf, &doit);
107 if (ret < 0)
108 return ret;
Barry Songa20ebd92010-10-27 21:43:54 -0400109
Jonathan Cameronea993a52011-09-02 17:25:25 +0100110 if (!doit)
111 return 0;
Barry Songa20ebd92010-10-27 21:43:54 -0400112
Jonathan Cameronea993a52011-09-02 17:25:25 +0100113 if (this_attr->address == 0)
Michael Henneriche5664292011-09-02 17:25:26 +0100114 regval |= AD7152_CONF_CH1EN;
Jonathan Cameronea993a52011-09-02 17:25:25 +0100115 else
Michael Henneriche5664292011-09-02 17:25:26 +0100116 regval |= AD7152_CONF_CH2EN;
Jonathan Cameronea993a52011-09-02 17:25:25 +0100117
Michael Hennerichbb90cf82011-09-02 17:25:29 +0100118 mutex_lock(&indio_dev->mlock);
Michael Henneriche5664292011-09-02 17:25:26 +0100119 ret = i2c_smbus_write_byte_data(chip->client, AD7152_REG_CFG, regval);
Michael Hennerichbb90cf82011-09-02 17:25:29 +0100120 if (ret < 0) {
121 mutex_unlock(&indio_dev->mlock);
Jonathan Cameronea993a52011-09-02 17:25:25 +0100122 return ret;
Michael Hennerichbb90cf82011-09-02 17:25:29 +0100123 }
Michael Hennerich2b8cb402011-09-02 17:25:27 +0100124
125 do {
126 mdelay(20);
127 ret = i2c_smbus_read_byte_data(chip->client, AD7152_REG_CFG);
Michael Hennerichbb90cf82011-09-02 17:25:29 +0100128 if (ret < 0) {
129 mutex_unlock(&indio_dev->mlock);
Michael Hennerich2b8cb402011-09-02 17:25:27 +0100130 return ret;
Michael Hennerichbb90cf82011-09-02 17:25:29 +0100131 }
Michael Hennerich2b8cb402011-09-02 17:25:27 +0100132 } while ((ret == regval) && timeout--);
133
Michael Hennerichbb90cf82011-09-02 17:25:29 +0100134 mutex_unlock(&indio_dev->mlock);
Jonathan Cameronea993a52011-09-02 17:25:25 +0100135 return len;
136}
137static ssize_t ad7152_start_offset_calib(struct device *dev,
138 struct device_attribute *attr,
139 const char *buf,
140 size_t len)
141{
Michael Henneriche5664292011-09-02 17:25:26 +0100142 return ad7152_start_calib(dev, attr, buf, len,
143 AD7152_CONF_MODE_OFFS_CAL);
Jonathan Cameronea993a52011-09-02 17:25:25 +0100144}
145static ssize_t ad7152_start_gain_calib(struct device *dev,
146 struct device_attribute *attr,
147 const char *buf,
148 size_t len)
149{
Michael Henneriche5664292011-09-02 17:25:26 +0100150 return ad7152_start_calib(dev, attr, buf, len,
151 AD7152_CONF_MODE_GAIN_CAL);
Jonathan Cameronea993a52011-09-02 17:25:25 +0100152}
153
154static IIO_DEVICE_ATTR(in_capacitance0_calibbias_calibration,
155 S_IWUSR, NULL, ad7152_start_offset_calib, 0);
156static IIO_DEVICE_ATTR(in_capacitance1_calibbias_calibration,
157 S_IWUSR, NULL, ad7152_start_offset_calib, 1);
158static IIO_DEVICE_ATTR(in_capacitance0_calibscale_calibration,
159 S_IWUSR, NULL, ad7152_start_gain_calib, 0);
160static IIO_DEVICE_ATTR(in_capacitance1_calibscale_calibration,
161 S_IWUSR, NULL, ad7152_start_gain_calib, 1);
162
Michael Hennerichfe55a172011-09-02 17:25:31 +0100163/* Values are Update Rate (Hz), Conversion Time (ms) + 1*/
Michael Hennerichc3b79152011-09-02 17:25:30 +0100164static const unsigned char ad7152_filter_rate_table[][2] = {
Michael Hennerichfe55a172011-09-02 17:25:31 +0100165 {200, 5 + 1}, {50, 20 + 1}, {20, 50 + 1}, {17, 60 + 1},
Michael Hennerichc3b79152011-09-02 17:25:30 +0100166};
Barry Songa20ebd92010-10-27 21:43:54 -0400167
Barry Songa20ebd92010-10-27 21:43:54 -0400168static ssize_t ad7152_show_filter_rate_setup(struct device *dev,
169 struct device_attribute *attr,
170 char *buf)
171{
Lars-Peter Clausend30a7f92012-05-12 15:39:45 +0200172 struct iio_dev *indio_dev = dev_to_iio_dev(dev);
Michael Hennerichbb90cf82011-09-02 17:25:29 +0100173 struct ad7152_chip_info *chip = iio_priv(indio_dev);
Barry Songa20ebd92010-10-27 21:43:54 -0400174
Michael Hennerichc3b79152011-09-02 17:25:30 +0100175 return sprintf(buf, "%d\n",
176 ad7152_filter_rate_table[chip->filter_rate_setup][0]);
Barry Songa20ebd92010-10-27 21:43:54 -0400177}
178
179static ssize_t ad7152_store_filter_rate_setup(struct device *dev,
180 struct device_attribute *attr,
181 const char *buf,
182 size_t len)
183{
Lars-Peter Clausend30a7f92012-05-12 15:39:45 +0200184 struct iio_dev *indio_dev = dev_to_iio_dev(dev);
Michael Hennerichbb90cf82011-09-02 17:25:29 +0100185 struct ad7152_chip_info *chip = iio_priv(indio_dev);
Jonathan Cameron3995f912011-09-02 17:25:23 +0100186 u8 data;
Michael Hennerichc3b79152011-09-02 17:25:30 +0100187 int ret, i;
Barry Songa20ebd92010-10-27 21:43:54 -0400188
Jonathan Cameron3995f912011-09-02 17:25:23 +0100189 ret = kstrtou8(buf, 10, &data);
190 if (ret < 0)
191 return ret;
Barry Songa20ebd92010-10-27 21:43:54 -0400192
Michael Hennerichc3b79152011-09-02 17:25:30 +0100193 for (i = 0; i < ARRAY_SIZE(ad7152_filter_rate_table); i++)
194 if (data >= ad7152_filter_rate_table[i][0])
195 break;
Barry Songa20ebd92010-10-27 21:43:54 -0400196
Michael Hennerichc3b79152011-09-02 17:25:30 +0100197 if (i >= ARRAY_SIZE(ad7152_filter_rate_table))
198 i = ARRAY_SIZE(ad7152_filter_rate_table) - 1;
199
200 mutex_lock(&indio_dev->mlock);
201 ret = i2c_smbus_write_byte_data(chip->client,
202 AD7152_REG_CFG2, AD7152_CFG2_OSR(i));
203 if (ret < 0) {
204 mutex_unlock(&indio_dev->mlock);
205 return ret;
206 }
207
208 chip->filter_rate_setup = i;
Michael Hennerichbb90cf82011-09-02 17:25:29 +0100209 mutex_unlock(&indio_dev->mlock);
Jonathan Cameron3995f912011-09-02 17:25:23 +0100210
211 return len;
Barry Songa20ebd92010-10-27 21:43:54 -0400212}
213
Michael Hennerichc3b79152011-09-02 17:25:30 +0100214static IIO_DEV_ATTR_SAMP_FREQ(S_IRUGO | S_IWUSR,
Barry Songa20ebd92010-10-27 21:43:54 -0400215 ad7152_show_filter_rate_setup,
216 ad7152_store_filter_rate_setup);
217
Michael Hennerichc3b79152011-09-02 17:25:30 +0100218static IIO_CONST_ATTR_SAMP_FREQ_AVAIL("200 50 20 17");
219
Michael Hennerich9b724412011-09-02 17:25:28 +0100220static IIO_CONST_ATTR(in_capacitance_scale_available,
221 "0.000061050 0.000030525 0.000015263 0.000007631");
222
Barry Songa20ebd92010-10-27 21:43:54 -0400223static struct attribute *ad7152_attributes[] = {
Michael Hennerichc3b79152011-09-02 17:25:30 +0100224 &iio_dev_attr_sampling_frequency.dev_attr.attr,
Jonathan Cameronea993a52011-09-02 17:25:25 +0100225 &iio_dev_attr_in_capacitance0_calibbias_calibration.dev_attr.attr,
226 &iio_dev_attr_in_capacitance1_calibbias_calibration.dev_attr.attr,
227 &iio_dev_attr_in_capacitance0_calibscale_calibration.dev_attr.attr,
228 &iio_dev_attr_in_capacitance1_calibscale_calibration.dev_attr.attr,
Michael Hennerich9b724412011-09-02 17:25:28 +0100229 &iio_const_attr_in_capacitance_scale_available.dev_attr.attr,
Michael Hennerichc3b79152011-09-02 17:25:30 +0100230 &iio_const_attr_sampling_frequency_available.dev_attr.attr,
Barry Songa20ebd92010-10-27 21:43:54 -0400231 NULL,
232};
233
234static const struct attribute_group ad7152_attribute_group = {
235 .attrs = ad7152_attributes,
236};
237
Jonathan Cameronea993a52011-09-02 17:25:25 +0100238static const u8 ad7152_addresses[][4] = {
Michael Henneriche5664292011-09-02 17:25:26 +0100239 { AD7152_REG_CH1_DATA_HIGH, AD7152_REG_CH1_OFFS_HIGH,
240 AD7152_REG_CH1_GAIN_HIGH, AD7152_REG_CH1_SETUP },
241 { AD7152_REG_CH2_DATA_HIGH, AD7152_REG_CH2_OFFS_HIGH,
242 AD7152_REG_CH2_GAIN_HIGH, AD7152_REG_CH2_SETUP },
Jonathan Cameron3995f912011-09-02 17:25:23 +0100243};
Jonathan Cameronea993a52011-09-02 17:25:25 +0100244
Michael Hennerich9b724412011-09-02 17:25:28 +0100245/* Values are nano relative to pf base. */
Jonathan Cameronea993a52011-09-02 17:25:25 +0100246static const int ad7152_scale_table[] = {
Michael Hennerich9b724412011-09-02 17:25:28 +0100247 30525, 7631, 15263, 61050
Jonathan Cameronea993a52011-09-02 17:25:25 +0100248};
249
Michael Hennerichbb90cf82011-09-02 17:25:29 +0100250static int ad7152_write_raw(struct iio_dev *indio_dev,
Jonathan Cameron3995f912011-09-02 17:25:23 +0100251 struct iio_chan_spec const *chan,
252 int val,
253 int val2,
254 long mask)
255{
Michael Hennerichbb90cf82011-09-02 17:25:29 +0100256 struct ad7152_chip_info *chip = iio_priv(indio_dev);
Jonathan Cameronea993a52011-09-02 17:25:25 +0100257 int ret, i;
Jonathan Cameron3995f912011-09-02 17:25:23 +0100258
Michael Hennerichbb90cf82011-09-02 17:25:29 +0100259 mutex_lock(&indio_dev->mlock);
260
Jonathan Cameron3995f912011-09-02 17:25:23 +0100261 switch (mask) {
Jonathan Cameronc8a9f802011-10-26 17:41:36 +0100262 case IIO_CHAN_INFO_CALIBSCALE:
Michael Hennerichbb90cf82011-09-02 17:25:29 +0100263 if (val != 1) {
264 ret = -EINVAL;
265 goto out;
266 }
Michael Hennerich2b8cb402011-09-02 17:25:27 +0100267
268 val = (val2 * 1024) / 15625;
269
Jonathan Cameron3995f912011-09-02 17:25:23 +0100270 ret = i2c_smbus_write_word_data(chip->client,
Michael Henneriche5664292011-09-02 17:25:26 +0100271 ad7152_addresses[chan->channel][AD7152_GAIN],
Michael Hennerich2b8cb402011-09-02 17:25:27 +0100272 swab16(val));
Jonathan Cameron3995f912011-09-02 17:25:23 +0100273 if (ret < 0)
Michael Hennerichbb90cf82011-09-02 17:25:29 +0100274 goto out;
Jonathan Cameron3995f912011-09-02 17:25:23 +0100275
Michael Hennerichbb90cf82011-09-02 17:25:29 +0100276 ret = 0;
277 break;
Jonathan Cameron3995f912011-09-02 17:25:23 +0100278
Jonathan Cameronc8a9f802011-10-26 17:41:36 +0100279 case IIO_CHAN_INFO_CALIBBIAS:
Michael Hennerichbb90cf82011-09-02 17:25:29 +0100280 if ((val < 0) | (val > 0xFFFF)) {
281 ret = -EINVAL;
282 goto out;
283 }
Jonathan Cameron3995f912011-09-02 17:25:23 +0100284 ret = i2c_smbus_write_word_data(chip->client,
Michael Henneriche5664292011-09-02 17:25:26 +0100285 ad7152_addresses[chan->channel][AD7152_OFFS],
Michael Hennerich2b8cb402011-09-02 17:25:27 +0100286 swab16(val));
Jonathan Cameron3995f912011-09-02 17:25:23 +0100287 if (ret < 0)
Michael Hennerichbb90cf82011-09-02 17:25:29 +0100288 goto out;
Jonathan Cameron3995f912011-09-02 17:25:23 +0100289
Michael Hennerichbb90cf82011-09-02 17:25:29 +0100290 ret = 0;
291 break;
Jonathan Cameronc8a9f802011-10-26 17:41:36 +0100292 case IIO_CHAN_INFO_SCALE:
Cristina Morarue6e65f92015-10-20 22:55:43 +0300293 if (val) {
Michael Hennerichbb90cf82011-09-02 17:25:29 +0100294 ret = -EINVAL;
295 goto out;
296 }
Jonathan Cameronea993a52011-09-02 17:25:25 +0100297 for (i = 0; i < ARRAY_SIZE(ad7152_scale_table); i++)
Michael Hennerich9b724412011-09-02 17:25:28 +0100298 if (val2 == ad7152_scale_table[i])
Jonathan Cameronea993a52011-09-02 17:25:25 +0100299 break;
Michael Hennerich2b8cb402011-09-02 17:25:27 +0100300
301 chip->setup[chan->channel] &= ~AD7152_SETUP_RANGE_4pF;
302 chip->setup[chan->channel] |= AD7152_SETUP_RANGE(i);
303
304 ret = i2c_smbus_write_byte_data(chip->client,
Michael Henneriche5664292011-09-02 17:25:26 +0100305 ad7152_addresses[chan->channel][AD7152_SETUP],
Michael Hennerich2b8cb402011-09-02 17:25:27 +0100306 chip->setup[chan->channel]);
Jonathan Cameronea993a52011-09-02 17:25:25 +0100307 if (ret < 0)
Michael Hennerichbb90cf82011-09-02 17:25:29 +0100308 goto out;
309
310 ret = 0;
311 break;
Jonathan Cameron3995f912011-09-02 17:25:23 +0100312 default:
Michael Hennerichbb90cf82011-09-02 17:25:29 +0100313 ret = -EINVAL;
Jonathan Cameron3995f912011-09-02 17:25:23 +0100314 }
Michael Hennerichbb90cf82011-09-02 17:25:29 +0100315
316out:
317 mutex_unlock(&indio_dev->mlock);
318 return ret;
Jonathan Cameron3995f912011-09-02 17:25:23 +0100319}
Michael Hennerichbb90cf82011-09-02 17:25:29 +0100320static int ad7152_read_raw(struct iio_dev *indio_dev,
Jonathan Cameron3995f912011-09-02 17:25:23 +0100321 struct iio_chan_spec const *chan,
322 int *val, int *val2,
323 long mask)
324{
Michael Hennerichbb90cf82011-09-02 17:25:29 +0100325 struct ad7152_chip_info *chip = iio_priv(indio_dev);
Jonathan Cameron3995f912011-09-02 17:25:23 +0100326 int ret;
Jonathan Cameronea993a52011-09-02 17:25:25 +0100327 u8 regval = 0;
Michael Hennerichbb90cf82011-09-02 17:25:29 +0100328
329 mutex_lock(&indio_dev->mlock);
330
Jonathan Cameron3995f912011-09-02 17:25:23 +0100331 switch (mask) {
Jonathan Camerone33e0752012-04-15 17:41:26 +0100332 case IIO_CHAN_INFO_RAW:
Jonathan Cameronea993a52011-09-02 17:25:25 +0100333 /* First set whether in differential mode */
Jonathan Cameronea993a52011-09-02 17:25:25 +0100334
Michael Hennerich2b8cb402011-09-02 17:25:27 +0100335 regval = chip->setup[chan->channel];
336
337 if (chan->differential)
338 chip->setup[chan->channel] |= AD7152_SETUP_CAPDIFF;
Jonathan Cameronea993a52011-09-02 17:25:25 +0100339 else
Michael Hennerich2b8cb402011-09-02 17:25:27 +0100340 chip->setup[chan->channel] &= ~AD7152_SETUP_CAPDIFF;
341
342 if (regval != chip->setup[chan->channel]) {
343 ret = i2c_smbus_write_byte_data(chip->client,
344 ad7152_addresses[chan->channel][AD7152_SETUP],
345 chip->setup[chan->channel]);
346 if (ret < 0)
Michael Hennerichbb90cf82011-09-02 17:25:29 +0100347 goto out;
Michael Hennerich2b8cb402011-09-02 17:25:27 +0100348 }
349 /* Make sure the channel is enabled */
350 if (chan->channel == 0)
351 regval = AD7152_CONF_CH1EN;
352 else
353 regval = AD7152_CONF_CH2EN;
354
Jonathan Cameronea993a52011-09-02 17:25:25 +0100355 /* Trigger a single read */
Michael Henneriche5664292011-09-02 17:25:26 +0100356 regval |= AD7152_CONF_MODE_SINGLE_CONV;
Michael Hennerich2b8cb402011-09-02 17:25:27 +0100357 ret = i2c_smbus_write_byte_data(chip->client, AD7152_REG_CFG,
Michael Henneriche5664292011-09-02 17:25:26 +0100358 regval);
Jonathan Cameronea993a52011-09-02 17:25:25 +0100359 if (ret < 0)
Michael Hennerichbb90cf82011-09-02 17:25:29 +0100360 goto out;
Jonathan Cameronea993a52011-09-02 17:25:25 +0100361
Michael Hennerichc3b79152011-09-02 17:25:30 +0100362 msleep(ad7152_filter_rate_table[chip->filter_rate_setup][1]);
Jonathan Cameronea993a52011-09-02 17:25:25 +0100363 /* Now read the actual register */
Jonathan Cameron3995f912011-09-02 17:25:23 +0100364 ret = i2c_smbus_read_word_data(chip->client,
Michael Henneriche5664292011-09-02 17:25:26 +0100365 ad7152_addresses[chan->channel][AD7152_DATA]);
Jonathan Cameron3995f912011-09-02 17:25:23 +0100366 if (ret < 0)
Michael Hennerichbb90cf82011-09-02 17:25:29 +0100367 goto out;
Michael Hennerich2b8cb402011-09-02 17:25:27 +0100368 *val = swab16(ret);
Jonathan Cameronea993a52011-09-02 17:25:25 +0100369
Michael Hennerichfe55a172011-09-02 17:25:31 +0100370 if (chan->differential)
371 *val -= 0x8000;
372
Michael Hennerichbb90cf82011-09-02 17:25:29 +0100373 ret = IIO_VAL_INT;
374 break;
Jonathan Cameronc8a9f802011-10-26 17:41:36 +0100375 case IIO_CHAN_INFO_CALIBSCALE:
Michael Hennerich2b8cb402011-09-02 17:25:27 +0100376
Jonathan Cameron3995f912011-09-02 17:25:23 +0100377 ret = i2c_smbus_read_word_data(chip->client,
Michael Henneriche5664292011-09-02 17:25:26 +0100378 ad7152_addresses[chan->channel][AD7152_GAIN]);
Jonathan Cameron3995f912011-09-02 17:25:23 +0100379 if (ret < 0)
Michael Hennerichbb90cf82011-09-02 17:25:29 +0100380 goto out;
Michael Hennerich2b8cb402011-09-02 17:25:27 +0100381 /* 1 + gain_val / 2^16 */
382 *val = 1;
383 *val2 = (15625 * swab16(ret)) / 1024;
Jonathan Cameronea993a52011-09-02 17:25:25 +0100384
Michael Hennerichbb90cf82011-09-02 17:25:29 +0100385 ret = IIO_VAL_INT_PLUS_MICRO;
386 break;
Jonathan Cameronc8a9f802011-10-26 17:41:36 +0100387 case IIO_CHAN_INFO_CALIBBIAS:
Jonathan Cameron3995f912011-09-02 17:25:23 +0100388 ret = i2c_smbus_read_word_data(chip->client,
Michael Henneriche5664292011-09-02 17:25:26 +0100389 ad7152_addresses[chan->channel][AD7152_OFFS]);
Jonathan Cameron3995f912011-09-02 17:25:23 +0100390 if (ret < 0)
Michael Hennerichbb90cf82011-09-02 17:25:29 +0100391 goto out;
Michael Hennerich2b8cb402011-09-02 17:25:27 +0100392 *val = swab16(ret);
Jonathan Cameronea993a52011-09-02 17:25:25 +0100393
Michael Hennerichbb90cf82011-09-02 17:25:29 +0100394 ret = IIO_VAL_INT;
395 break;
Jonathan Cameronc8a9f802011-10-26 17:41:36 +0100396 case IIO_CHAN_INFO_SCALE:
Jonathan Cameronea993a52011-09-02 17:25:25 +0100397 ret = i2c_smbus_read_byte_data(chip->client,
Michael Henneriche5664292011-09-02 17:25:26 +0100398 ad7152_addresses[chan->channel][AD7152_SETUP]);
Jonathan Cameronea993a52011-09-02 17:25:25 +0100399 if (ret < 0)
Michael Hennerichbb90cf82011-09-02 17:25:29 +0100400 goto out;
Jonathan Cameronea993a52011-09-02 17:25:25 +0100401 *val = 0;
402 *val2 = ad7152_scale_table[ret >> 6];
403
Michael Hennerichbb90cf82011-09-02 17:25:29 +0100404 ret = IIO_VAL_INT_PLUS_NANO;
405 break;
Jonathan Cameron3995f912011-09-02 17:25:23 +0100406 default:
Michael Hennerichbb90cf82011-09-02 17:25:29 +0100407 ret = -EINVAL;
Peter Senna Tschudin73327b42012-09-28 10:57:00 +0100408 }
Michael Hennerichbb90cf82011-09-02 17:25:29 +0100409out:
410 mutex_unlock(&indio_dev->mlock);
411 return ret;
Jonathan Cameron3995f912011-09-02 17:25:23 +0100412}
Michael Hennerich9b724412011-09-02 17:25:28 +0100413
414static int ad7152_write_raw_get_fmt(struct iio_dev *indio_dev,
415 struct iio_chan_spec const *chan,
416 long mask)
417{
418 switch (mask) {
Jonathan Cameronc8a9f802011-10-26 17:41:36 +0100419 case IIO_CHAN_INFO_SCALE:
Michael Hennerich9b724412011-09-02 17:25:28 +0100420 return IIO_VAL_INT_PLUS_NANO;
421 default:
422 return IIO_VAL_INT_PLUS_MICRO;
423 }
424}
425
Jonathan Cameron6fe81352011-05-18 14:42:37 +0100426static const struct iio_info ad7152_info = {
427 .attrs = &ad7152_attribute_group,
Jonathan Cameron3995f912011-09-02 17:25:23 +0100428 .read_raw = &ad7152_read_raw,
429 .write_raw = &ad7152_write_raw,
Michael Hennerich9b724412011-09-02 17:25:28 +0100430 .write_raw_get_fmt = &ad7152_write_raw_get_fmt,
Jonathan Cameron6fe81352011-05-18 14:42:37 +0100431 .driver_module = THIS_MODULE,
432};
Jonathan Cameron3995f912011-09-02 17:25:23 +0100433
434static const struct iio_chan_spec ad7152_channels[] = {
435 {
436 .type = IIO_CAPACITANCE,
437 .indexed = 1,
438 .channel = 0,
Jonathan Cameronc24e97b2013-02-27 19:38:12 +0000439 .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
440 BIT(IIO_CHAN_INFO_CALIBSCALE) |
441 BIT(IIO_CHAN_INFO_CALIBBIAS) |
442 BIT(IIO_CHAN_INFO_SCALE),
Jonathan Cameron3995f912011-09-02 17:25:23 +0100443 }, {
444 .type = IIO_CAPACITANCE,
Michael Hennerich15e32762011-09-02 17:25:47 +0100445 .differential = 1,
Jonathan Cameron3995f912011-09-02 17:25:23 +0100446 .indexed = 1,
Michael Hennerich15e32762011-09-02 17:25:47 +0100447 .channel = 0,
448 .channel2 = 2,
Jonathan Cameronc24e97b2013-02-27 19:38:12 +0000449 .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
450 BIT(IIO_CHAN_INFO_CALIBSCALE) |
451 BIT(IIO_CHAN_INFO_CALIBBIAS) |
452 BIT(IIO_CHAN_INFO_SCALE),
Jonathan Cameronea993a52011-09-02 17:25:25 +0100453 }, {
454 .type = IIO_CAPACITANCE,
Jonathan Cameronea993a52011-09-02 17:25:25 +0100455 .indexed = 1,
Michael Hennerich15e32762011-09-02 17:25:47 +0100456 .channel = 1,
Jonathan Cameronc24e97b2013-02-27 19:38:12 +0000457 .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
458 BIT(IIO_CHAN_INFO_CALIBSCALE) |
459 BIT(IIO_CHAN_INFO_CALIBBIAS) |
460 BIT(IIO_CHAN_INFO_SCALE),
Jonathan Cameronea993a52011-09-02 17:25:25 +0100461 }, {
462 .type = IIO_CAPACITANCE,
463 .differential = 1,
464 .indexed = 1,
465 .channel = 1,
466 .channel2 = 3,
Jonathan Cameronc24e97b2013-02-27 19:38:12 +0000467 .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
468 BIT(IIO_CHAN_INFO_CALIBSCALE) |
469 BIT(IIO_CHAN_INFO_CALIBBIAS) |
470 BIT(IIO_CHAN_INFO_SCALE),
Jonathan Cameron3995f912011-09-02 17:25:23 +0100471 }
472};
Barry Songa20ebd92010-10-27 21:43:54 -0400473/*
474 * device probe and remove
475 */
476
Bill Pemberton4ae1c612012-11-19 13:21:57 -0500477static int ad7152_probe(struct i2c_client *client,
Barry Songa20ebd92010-10-27 21:43:54 -0400478 const struct i2c_device_id *id)
479{
480 int ret = 0;
Jonathan Cameronf4c794a2011-06-27 13:07:22 +0100481 struct ad7152_chip_info *chip;
482 struct iio_dev *indio_dev;
483
Sachin Kamat538ee7c2013-08-24 20:24:00 +0100484 indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*chip));
485 if (!indio_dev)
486 return -ENOMEM;
Jonathan Cameronf4c794a2011-06-27 13:07:22 +0100487 chip = iio_priv(indio_dev);
Barry Songa20ebd92010-10-27 21:43:54 -0400488 /* this is only used for device removal purposes */
Jonathan Cameronf4c794a2011-06-27 13:07:22 +0100489 i2c_set_clientdata(client, indio_dev);
Barry Songa20ebd92010-10-27 21:43:54 -0400490
491 chip->client = client;
Barry Songa20ebd92010-10-27 21:43:54 -0400492
Michael Henneriche5664292011-09-02 17:25:26 +0100493 /* Establish that the iio_dev is a child of the i2c device */
Jonathan Cameronf4c794a2011-06-27 13:07:22 +0100494 indio_dev->name = id->name;
495 indio_dev->dev.parent = &client->dev;
496 indio_dev->info = &ad7152_info;
Jonathan Cameron3995f912011-09-02 17:25:23 +0100497 indio_dev->channels = ad7152_channels;
Jonathan Cameron4050f492011-09-02 17:25:24 +0100498 if (id->driver_data == 0)
499 indio_dev->num_channels = ARRAY_SIZE(ad7152_channels);
500 else
Jonathan Cameronea993a52011-09-02 17:25:25 +0100501 indio_dev->num_channels = 2;
Jonathan Cameron3995f912011-09-02 17:25:23 +0100502 indio_dev->num_channels = ARRAY_SIZE(ad7152_channels);
Jonathan Cameronf4c794a2011-06-27 13:07:22 +0100503 indio_dev->modes = INDIO_DIRECT_MODE;
Barry Songa20ebd92010-10-27 21:43:54 -0400504
Ioana Ciornei252fb582015-10-02 13:37:48 +0300505 ret = devm_iio_device_register(indio_dev->dev.parent, indio_dev);
Barry Songa20ebd92010-10-27 21:43:54 -0400506 if (ret)
Sachin Kamat538ee7c2013-08-24 20:24:00 +0100507 return ret;
Barry Songa20ebd92010-10-27 21:43:54 -0400508
509 dev_err(&client->dev, "%s capacitive sensor registered\n", id->name);
510
511 return 0;
Barry Songa20ebd92010-10-27 21:43:54 -0400512}
513
Barry Songa20ebd92010-10-27 21:43:54 -0400514static const struct i2c_device_id ad7152_id[] = {
515 { "ad7152", 0 },
Jonathan Cameron4050f492011-09-02 17:25:24 +0100516 { "ad7153", 1 },
Barry Songa20ebd92010-10-27 21:43:54 -0400517 {}
518};
519
520MODULE_DEVICE_TABLE(i2c, ad7152_id);
521
522static struct i2c_driver ad7152_driver = {
523 .driver = {
Michael Henneriche5664292011-09-02 17:25:26 +0100524 .name = KBUILD_MODNAME,
Barry Songa20ebd92010-10-27 21:43:54 -0400525 },
526 .probe = ad7152_probe,
Barry Songa20ebd92010-10-27 21:43:54 -0400527 .id_table = ad7152_id,
528};
Lars-Peter Clausen6e5af182011-11-16 10:13:38 +0100529module_i2c_driver(ad7152_driver);
Barry Songa20ebd92010-10-27 21:43:54 -0400530
531MODULE_AUTHOR("Barry Song <21cnbao@gmail.com>");
Michael Henneriche5664292011-09-02 17:25:26 +0100532MODULE_DESCRIPTION("Analog Devices AD7152/3 capacitive sensor driver");
Barry Songa20ebd92010-10-27 21:43:54 -0400533MODULE_LICENSE("GPL v2");