staging: iio: remove use of __devexit_p
[linux-2.6-block.git] / drivers / staging / iio / cdc / ad7746.c
CommitLineData
83e416f4
MH
1/*
2 * AD7746 capacitive sensor driver supporting AD7745, AD7746 and AD7747
3 *
4 * Copyright 2011 Analog Devices Inc.
5 *
6 * Licensed under the GPL-2.
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/i2c.h>
15#include <linux/delay.h>
6a37b041
SR
16#include <linux/module.h>
17#include <linux/stat.h>
83e416f4 18
06458e27
JC
19#include <linux/iio/iio.h>
20#include <linux/iio/sysfs.h>
83e416f4
MH
21
22#include "ad7746.h"
23
24/*
25 * AD7746 Register Definition
26 */
27
28#define AD7746_REG_STATUS 0
29#define AD7746_REG_CAP_DATA_HIGH 1
30#define AD7746_REG_CAP_DATA_MID 2
31#define AD7746_REG_CAP_DATA_LOW 3
32#define AD7746_REG_VT_DATA_HIGH 4
33#define AD7746_REG_VT_DATA_MID 5
34#define AD7746_REG_VT_DATA_LOW 6
35#define AD7746_REG_CAP_SETUP 7
36#define AD7746_REG_VT_SETUP 8
37#define AD7746_REG_EXC_SETUP 9
38#define AD7746_REG_CFG 10
39#define AD7746_REG_CAPDACA 11
40#define AD7746_REG_CAPDACB 12
41#define AD7746_REG_CAP_OFFH 13
42#define AD7746_REG_CAP_OFFL 14
43#define AD7746_REG_CAP_GAINH 15
44#define AD7746_REG_CAP_GAINL 16
45#define AD7746_REG_VOLT_GAINH 17
46#define AD7746_REG_VOLT_GAINL 18
47
48/* Status Register Bit Designations (AD7746_REG_STATUS) */
49#define AD7746_STATUS_EXCERR (1 << 3)
50#define AD7746_STATUS_RDY (1 << 2)
51#define AD7746_STATUS_RDYVT (1 << 1)
52#define AD7746_STATUS_RDYCAP (1 << 0)
53
54/* Capacitive Channel Setup Register Bit Designations (AD7746_REG_CAP_SETUP) */
55#define AD7746_CAPSETUP_CAPEN (1 << 7)
56#define AD7746_CAPSETUP_CIN2 (1 << 6) /* AD7746 only */
57#define AD7746_CAPSETUP_CAPDIFF (1 << 5)
58#define AD7746_CAPSETUP_CACHOP (1 << 0)
59
60/* Voltage/Temperature Setup Register Bit Designations (AD7746_REG_VT_SETUP) */
61#define AD7746_VTSETUP_VTEN (1 << 7)
62#define AD7746_VTSETUP_VTMD_INT_TEMP (0 << 5)
63#define AD7746_VTSETUP_VTMD_EXT_TEMP (1 << 5)
64#define AD7746_VTSETUP_VTMD_VDD_MON (2 << 5)
65#define AD7746_VTSETUP_VTMD_EXT_VIN (3 << 5)
66#define AD7746_VTSETUP_EXTREF (1 << 4)
67#define AD7746_VTSETUP_VTSHORT (1 << 1)
68#define AD7746_VTSETUP_VTCHOP (1 << 0)
69
70/* Excitation Setup Register Bit Designations (AD7746_REG_EXC_SETUP) */
71#define AD7746_EXCSETUP_CLKCTRL (1 << 7)
72#define AD7746_EXCSETUP_EXCON (1 << 6)
73#define AD7746_EXCSETUP_EXCB (1 << 5)
74#define AD7746_EXCSETUP_NEXCB (1 << 4)
75#define AD7746_EXCSETUP_EXCA (1 << 3)
76#define AD7746_EXCSETUP_NEXCA (1 << 2)
77#define AD7746_EXCSETUP_EXCLVL(x) (((x) & 0x3) << 0)
78
79/* Config Register Bit Designations (AD7746_REG_CFG) */
80#define AD7746_CONF_VTFS(x) ((x) << 6)
81#define AD7746_CONF_CAPFS(x) ((x) << 3)
82#define AD7746_CONF_MODE_IDLE (0 << 0)
83#define AD7746_CONF_MODE_CONT_CONV (1 << 0)
84#define AD7746_CONF_MODE_SINGLE_CONV (2 << 0)
85#define AD7746_CONF_MODE_PWRDN (3 << 0)
86#define AD7746_CONF_MODE_OFFS_CAL (5 << 0)
87#define AD7746_CONF_MODE_GAIN_CAL (6 << 0)
88
89/* CAPDAC Register Bit Designations (AD7746_REG_CAPDACx) */
90#define AD7746_CAPDAC_DACEN (1 << 7)
91#define AD7746_CAPDAC_DACP(x) ((x) & 0x7F)
92
93/*
94 * struct ad7746_chip_info - chip specifc information
95 */
96
97struct ad7746_chip_info {
98 struct i2c_client *client;
99 /*
100 * Capacitive channel digital filter setup;
101 * conversion time/update rate setup per channel
102 */
103 u8 config;
104 u8 cap_setup;
105 u8 vt_setup;
106 u8 capdac[2][2];
107 s8 capdac_set;
108};
109
110enum ad7746_chan {
111 VIN,
112 VIN_VDD,
113 TEMP_INT,
114 TEMP_EXT,
115 CIN1,
116 CIN1_DIFF,
117 CIN2,
118 CIN2_DIFF,
119};
120
121static const struct iio_chan_spec ad7746_channels[] = {
122 [VIN] = {
123 .type = IIO_VOLTAGE,
124 .indexed = 1,
125 .channel = 0,
e33e0750
JC
126 .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT |
127 IIO_CHAN_INFO_SCALE_SHARED_BIT,
83e416f4
MH
128 .address = AD7746_REG_VT_DATA_HIGH << 8 |
129 AD7746_VTSETUP_VTMD_EXT_VIN,
130 },
131 [VIN_VDD] = {
132 .type = IIO_VOLTAGE,
133 .indexed = 1,
134 .channel = 1,
135 .extend_name = "supply",
e33e0750
JC
136 .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT |
137 IIO_CHAN_INFO_SCALE_SHARED_BIT,
83e416f4
MH
138 .address = AD7746_REG_VT_DATA_HIGH << 8 |
139 AD7746_VTSETUP_VTMD_VDD_MON,
140 },
141 [TEMP_INT] = {
142 .type = IIO_TEMP,
143 .indexed = 1,
144 .channel = 0,
e33e0750 145 .info_mask = IIO_CHAN_INFO_PROCESSED_SEPARATE_BIT,
83e416f4
MH
146 .address = AD7746_REG_VT_DATA_HIGH << 8 |
147 AD7746_VTSETUP_VTMD_INT_TEMP,
148 },
149 [TEMP_EXT] = {
150 .type = IIO_TEMP,
151 .indexed = 1,
152 .channel = 1,
e33e0750 153 .info_mask = IIO_CHAN_INFO_PROCESSED_SEPARATE_BIT,
83e416f4
MH
154 .address = AD7746_REG_VT_DATA_HIGH << 8 |
155 AD7746_VTSETUP_VTMD_EXT_TEMP,
156 },
157 [CIN1] = {
158 .type = IIO_CAPACITANCE,
159 .indexed = 1,
160 .channel = 0,
e33e0750
JC
161 .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT |
162 IIO_CHAN_INFO_CALIBSCALE_SEPARATE_BIT |
c8a9f805
JC
163 IIO_CHAN_INFO_CALIBBIAS_SHARED_BIT |
164 IIO_CHAN_INFO_OFFSET_SEPARATE_BIT |
165 IIO_CHAN_INFO_SCALE_SHARED_BIT,
83e416f4
MH
166 .address = AD7746_REG_CAP_DATA_HIGH << 8,
167 },
168 [CIN1_DIFF] = {
169 .type = IIO_CAPACITANCE,
170 .differential = 1,
171 .indexed = 1,
172 .channel = 0,
173 .channel2 = 2,
e33e0750
JC
174 .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT |
175 IIO_CHAN_INFO_CALIBSCALE_SEPARATE_BIT |
c8a9f805
JC
176 IIO_CHAN_INFO_CALIBBIAS_SHARED_BIT |
177 IIO_CHAN_INFO_OFFSET_SEPARATE_BIT |
178 IIO_CHAN_INFO_SCALE_SHARED_BIT,
83e416f4
MH
179 .address = AD7746_REG_CAP_DATA_HIGH << 8 |
180 AD7746_CAPSETUP_CAPDIFF
181 },
182 [CIN2] = {
183 .type = IIO_CAPACITANCE,
184 .indexed = 1,
185 .channel = 1,
e33e0750
JC
186 .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT |
187 IIO_CHAN_INFO_CALIBSCALE_SEPARATE_BIT |
c8a9f805
JC
188 IIO_CHAN_INFO_CALIBBIAS_SHARED_BIT |
189 IIO_CHAN_INFO_OFFSET_SEPARATE_BIT |
190 IIO_CHAN_INFO_SCALE_SHARED_BIT,
83e416f4
MH
191 .address = AD7746_REG_CAP_DATA_HIGH << 8 |
192 AD7746_CAPSETUP_CIN2,
193 },
194 [CIN2_DIFF] = {
195 .type = IIO_CAPACITANCE,
196 .differential = 1,
197 .indexed = 1,
198 .channel = 1,
199 .channel2 = 3,
e33e0750
JC
200 .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT |
201 IIO_CHAN_INFO_CALIBSCALE_SEPARATE_BIT |
c8a9f805
JC
202 IIO_CHAN_INFO_CALIBBIAS_SHARED_BIT |
203 IIO_CHAN_INFO_OFFSET_SEPARATE_BIT |
204 IIO_CHAN_INFO_SCALE_SHARED_BIT,
83e416f4
MH
205 .address = AD7746_REG_CAP_DATA_HIGH << 8 |
206 AD7746_CAPSETUP_CAPDIFF | AD7746_CAPSETUP_CIN2,
207 }
208};
209
210/* Values are Update Rate (Hz), Conversion Time (ms) + 1*/
211static const unsigned char ad7746_vt_filter_rate_table[][2] = {
212 {50, 20 + 1}, {31, 32 + 1}, {16, 62 + 1}, {8, 122 + 1},
213};
214
215static const unsigned char ad7746_cap_filter_rate_table[][2] = {
216 {91, 11 + 1}, {84, 12 + 1}, {50, 20 + 1}, {26, 38 + 1},
217 {16, 62 + 1}, {13, 77 + 1}, {11, 92 + 1}, {9, 110 + 1},
218};
219
220static int ad7746_select_channel(struct iio_dev *indio_dev,
221 struct iio_chan_spec const *chan)
222{
223 struct ad7746_chip_info *chip = iio_priv(indio_dev);
224 int ret, delay;
225 u8 vt_setup, cap_setup;
226
227 switch (chan->type) {
228 case IIO_CAPACITANCE:
229 cap_setup = (chan->address & 0xFF) | AD7746_CAPSETUP_CAPEN;
230 vt_setup = chip->vt_setup & ~AD7746_VTSETUP_VTEN;
231 delay = ad7746_cap_filter_rate_table[(chip->config >> 3) &
232 0x7][1];
233
234 if (chip->capdac_set != chan->channel) {
235 ret = i2c_smbus_write_byte_data(chip->client,
236 AD7746_REG_CAPDACA,
237 chip->capdac[chan->channel][0]);
238 if (ret < 0)
239 return ret;
240 ret = i2c_smbus_write_byte_data(chip->client,
241 AD7746_REG_CAPDACB,
242 chip->capdac[chan->channel][1]);
243 if (ret < 0)
244 return ret;
245
246 chip->capdac_set = chan->channel;
247 }
248 break;
249 case IIO_VOLTAGE:
250 case IIO_TEMP:
251 vt_setup = (chan->address & 0xFF) | AD7746_VTSETUP_VTEN;
252 cap_setup = chip->cap_setup & ~AD7746_CAPSETUP_CAPEN;
253 delay = ad7746_cap_filter_rate_table[(chip->config >> 6) &
254 0x3][1];
255 break;
256 default:
257 return -EINVAL;
258 }
259
260 if (chip->cap_setup != cap_setup) {
261 ret = i2c_smbus_write_byte_data(chip->client,
262 AD7746_REG_CAP_SETUP,
263 cap_setup);
264 if (ret < 0)
265 return ret;
266
267 chip->cap_setup = cap_setup;
268 }
269
270 if (chip->vt_setup != vt_setup) {
271 ret = i2c_smbus_write_byte_data(chip->client,
272 AD7746_REG_VT_SETUP,
273 vt_setup);
274 if (ret < 0)
275 return ret;
276
277 chip->vt_setup = vt_setup;
278 }
279
280 return delay;
281}
282
283static inline ssize_t ad7746_start_calib(struct device *dev,
284 struct device_attribute *attr,
285 const char *buf,
286 size_t len,
287 u8 regval)
288{
d30a7f9d 289 struct iio_dev *indio_dev = dev_to_iio_dev(dev);
83e416f4
MH
290 struct ad7746_chip_info *chip = iio_priv(indio_dev);
291 bool doit;
292 int ret, timeout = 10;
293
294 ret = strtobool(buf, &doit);
295 if (ret < 0)
296 return ret;
297
298 if (!doit)
299 return 0;
300
301 mutex_lock(&indio_dev->mlock);
302 regval |= chip->config;
303 ret = i2c_smbus_write_byte_data(chip->client, AD7746_REG_CFG, regval);
304 if (ret < 0) {
305 mutex_unlock(&indio_dev->mlock);
306 return ret;
307 }
308
309 do {
310 msleep(20);
311 ret = i2c_smbus_read_byte_data(chip->client, AD7746_REG_CFG);
312 if (ret < 0) {
313 mutex_unlock(&indio_dev->mlock);
314 return ret;
315 }
316 } while ((ret == regval) && timeout--);
317
318 mutex_unlock(&indio_dev->mlock);
319
320 return len;
321}
322
323static ssize_t ad7746_start_offset_calib(struct device *dev,
324 struct device_attribute *attr,
325 const char *buf,
326 size_t len)
327{
d30a7f9d 328 struct iio_dev *indio_dev = dev_to_iio_dev(dev);
83e416f4
MH
329 int ret = ad7746_select_channel(indio_dev,
330 &ad7746_channels[to_iio_dev_attr(attr)->address]);
331 if (ret < 0)
332 return ret;
333
334 return ad7746_start_calib(dev, attr, buf, len,
335 AD7746_CONF_MODE_OFFS_CAL);
336}
337
338static ssize_t ad7746_start_gain_calib(struct device *dev,
339 struct device_attribute *attr,
340 const char *buf,
341 size_t len)
342{
d30a7f9d 343 struct iio_dev *indio_dev = dev_to_iio_dev(dev);
83e416f4
MH
344 int ret = ad7746_select_channel(indio_dev,
345 &ad7746_channels[to_iio_dev_attr(attr)->address]);
346 if (ret < 0)
347 return ret;
348
349 return ad7746_start_calib(dev, attr, buf, len,
350 AD7746_CONF_MODE_GAIN_CAL);
351}
352
353static IIO_DEVICE_ATTR(in_capacitance0_calibbias_calibration,
354 S_IWUSR, NULL, ad7746_start_offset_calib, CIN1);
355static IIO_DEVICE_ATTR(in_capacitance1_calibbias_calibration,
356 S_IWUSR, NULL, ad7746_start_offset_calib, CIN2);
357static IIO_DEVICE_ATTR(in_capacitance0_calibscale_calibration,
358 S_IWUSR, NULL, ad7746_start_gain_calib, CIN1);
359static IIO_DEVICE_ATTR(in_capacitance1_calibscale_calibration,
360 S_IWUSR, NULL, ad7746_start_gain_calib, CIN2);
361static IIO_DEVICE_ATTR(in_voltage0_calibscale_calibration,
362 S_IWUSR, NULL, ad7746_start_gain_calib, VIN);
363
364static ssize_t ad7746_show_cap_filter_rate_setup(struct device *dev,
365 struct device_attribute *attr,
366 char *buf)
367{
d30a7f9d 368 struct iio_dev *indio_dev = dev_to_iio_dev(dev);
83e416f4
MH
369 struct ad7746_chip_info *chip = iio_priv(indio_dev);
370
371 return sprintf(buf, "%d\n", ad7746_cap_filter_rate_table[
372 (chip->config >> 3) & 0x7][0]);
373}
374
375static ssize_t ad7746_store_cap_filter_rate_setup(struct device *dev,
376 struct device_attribute *attr,
377 const char *buf,
378 size_t len)
379{
d30a7f9d 380 struct iio_dev *indio_dev = dev_to_iio_dev(dev);
83e416f4
MH
381 struct ad7746_chip_info *chip = iio_priv(indio_dev);
382 u8 data;
383 int ret, i;
384
385 ret = kstrtou8(buf, 10, &data);
386 if (ret < 0)
387 return ret;
388
389 for (i = 0; i < ARRAY_SIZE(ad7746_cap_filter_rate_table); i++)
390 if (data >= ad7746_cap_filter_rate_table[i][0])
391 break;
392
393 if (i >= ARRAY_SIZE(ad7746_cap_filter_rate_table))
394 i = ARRAY_SIZE(ad7746_cap_filter_rate_table) - 1;
395
396 mutex_lock(&indio_dev->mlock);
397 chip->config &= ~AD7746_CONF_CAPFS(0x7);
398 chip->config |= AD7746_CONF_CAPFS(i);
399 mutex_unlock(&indio_dev->mlock);
400
401 return len;
402}
403
404static ssize_t ad7746_show_vt_filter_rate_setup(struct device *dev,
405 struct device_attribute *attr,
406 char *buf)
407{
d30a7f9d 408 struct iio_dev *indio_dev = dev_to_iio_dev(dev);
83e416f4
MH
409 struct ad7746_chip_info *chip = iio_priv(indio_dev);
410
411 return sprintf(buf, "%d\n", ad7746_vt_filter_rate_table[
412 (chip->config >> 6) & 0x3][0]);
413}
414
415static ssize_t ad7746_store_vt_filter_rate_setup(struct device *dev,
416 struct device_attribute *attr,
417 const char *buf,
418 size_t len)
419{
d30a7f9d 420 struct iio_dev *indio_dev = dev_to_iio_dev(dev);
83e416f4
MH
421 struct ad7746_chip_info *chip = iio_priv(indio_dev);
422 u8 data;
423 int ret, i;
424
425 ret = kstrtou8(buf, 10, &data);
426 if (ret < 0)
427 return ret;
428
429 for (i = 0; i < ARRAY_SIZE(ad7746_vt_filter_rate_table); i++)
430 if (data >= ad7746_vt_filter_rate_table[i][0])
431 break;
432
433 if (i >= ARRAY_SIZE(ad7746_vt_filter_rate_table))
434 i = ARRAY_SIZE(ad7746_vt_filter_rate_table) - 1;
435
436 mutex_lock(&indio_dev->mlock);
437 chip->config &= ~AD7746_CONF_VTFS(0x3);
438 chip->config |= AD7746_CONF_VTFS(i);
439 mutex_unlock(&indio_dev->mlock);
440
441 return len;
442}
443
444static IIO_DEVICE_ATTR(in_capacitance_sampling_frequency,
445 S_IRUGO | S_IWUSR, ad7746_show_cap_filter_rate_setup,
446 ad7746_store_cap_filter_rate_setup, 0);
447
448static IIO_DEVICE_ATTR(in_voltage_sampling_frequency,
449 S_IRUGO | S_IWUSR, ad7746_show_vt_filter_rate_setup,
450 ad7746_store_vt_filter_rate_setup, 0);
451
452static IIO_CONST_ATTR(in_voltage_sampling_frequency_available, "50 31 16 8");
453static IIO_CONST_ATTR(in_capacitance_sampling_frequency_available,
454 "91 84 50 26 16 13 11 9");
455
456static struct attribute *ad7746_attributes[] = {
457 &iio_dev_attr_in_capacitance_sampling_frequency.dev_attr.attr,
458 &iio_dev_attr_in_voltage_sampling_frequency.dev_attr.attr,
459 &iio_dev_attr_in_capacitance0_calibbias_calibration.dev_attr.attr,
460 &iio_dev_attr_in_capacitance0_calibscale_calibration.dev_attr.attr,
461 &iio_dev_attr_in_capacitance1_calibscale_calibration.dev_attr.attr,
462 &iio_dev_attr_in_capacitance1_calibbias_calibration.dev_attr.attr,
463 &iio_dev_attr_in_voltage0_calibscale_calibration.dev_attr.attr,
464 &iio_const_attr_in_voltage_sampling_frequency_available.dev_attr.attr,
465 &iio_const_attr_in_capacitance_sampling_frequency_available.
466 dev_attr.attr,
467 NULL,
468};
469
470static const struct attribute_group ad7746_attribute_group = {
471 .attrs = ad7746_attributes,
472};
473
474static int ad7746_write_raw(struct iio_dev *indio_dev,
475 struct iio_chan_spec const *chan,
476 int val,
477 int val2,
478 long mask)
479{
480 struct ad7746_chip_info *chip = iio_priv(indio_dev);
481 int ret, reg;
482
483 mutex_lock(&indio_dev->mlock);
484
485 switch (mask) {
c8a9f805 486 case IIO_CHAN_INFO_CALIBSCALE:
83e416f4
MH
487 if (val != 1) {
488 ret = -EINVAL;
489 goto out;
490 }
491
492 val = (val2 * 1024) / 15625;
493
494 switch (chan->type) {
495 case IIO_CAPACITANCE:
496 reg = AD7746_REG_CAP_GAINH;
497 break;
498 case IIO_VOLTAGE:
499 reg = AD7746_REG_VOLT_GAINH;
500 break;
501 default:
502 ret = -EINVAL;
503 goto out;
504 }
505
506 ret = i2c_smbus_write_word_data(chip->client, reg, swab16(val));
507 if (ret < 0)
508 goto out;
509
510 ret = 0;
511 break;
c8a9f805 512 case IIO_CHAN_INFO_CALIBBIAS:
83e416f4
MH
513 if ((val < 0) | (val > 0xFFFF)) {
514 ret = -EINVAL;
515 goto out;
516 }
517 ret = i2c_smbus_write_word_data(chip->client,
518 AD7746_REG_CAP_OFFH, swab16(val));
519 if (ret < 0)
520 goto out;
521
522 ret = 0;
523 break;
c8a9f805 524 case IIO_CHAN_INFO_OFFSET:
83e416f4
MH
525 if ((val < 0) | (val > 43008000)) { /* 21pF */
526 ret = -EINVAL;
527 goto out;
528 }
529
530 /* CAPDAC Scale = 21pF_typ / 127
531 * CIN Scale = 8.192pF / 2^24
532 * Offset Scale = CAPDAC Scale / CIN Scale = 338646
533 * */
534
535 val /= 338646;
536
537 chip->capdac[chan->channel][chan->differential] = (val > 0 ?
538 AD7746_CAPDAC_DACP(val) | AD7746_CAPDAC_DACEN : 0);
539
540 ret = i2c_smbus_write_byte_data(chip->client,
541 AD7746_REG_CAPDACA,
542 chip->capdac[chan->channel][0]);
543 if (ret < 0)
544 goto out;
545 ret = i2c_smbus_write_byte_data(chip->client,
546 AD7746_REG_CAPDACB,
547 chip->capdac[chan->channel][1]);
548 if (ret < 0)
549 goto out;
550
551 chip->capdac_set = chan->channel;
552
553 ret = 0;
554 break;
555 default:
556 ret = -EINVAL;
557 }
558
559out:
560 mutex_unlock(&indio_dev->mlock);
561 return ret;
562}
563
564static int ad7746_read_raw(struct iio_dev *indio_dev,
565 struct iio_chan_spec const *chan,
566 int *val, int *val2,
567 long mask)
568{
569 struct ad7746_chip_info *chip = iio_priv(indio_dev);
570 int ret, delay;
571 u8 regval, reg;
572
573 union {
574 u32 d32;
575 u8 d8[4];
576 } data;
577
578 mutex_lock(&indio_dev->mlock);
579
580 switch (mask) {
e33e0750
JC
581 case IIO_CHAN_INFO_RAW:
582 case IIO_CHAN_INFO_PROCESSED:
83e416f4
MH
583 ret = ad7746_select_channel(indio_dev, chan);
584 if (ret < 0)
585 goto out;
586 delay = ret;
587
588 regval = chip->config | AD7746_CONF_MODE_SINGLE_CONV;
589 ret = i2c_smbus_write_byte_data(chip->client, AD7746_REG_CFG,
590 regval);
591 if (ret < 0)
592 goto out;
593
594 msleep(delay);
595 /* Now read the actual register */
596
597 ret = i2c_smbus_read_i2c_block_data(chip->client,
598 chan->address >> 8, 3, &data.d8[1]);
599
600 if (ret < 0)
601 goto out;
602
603 *val = (be32_to_cpu(data.d32) & 0xFFFFFF) - 0x800000;
604
605 switch (chan->type) {
606 case IIO_TEMP:
607 /* temperature in milli degrees Celsius
608 * T = ((*val / 2048) - 4096) * 1000
609 */
610 *val = (*val * 125) / 256;
611 break;
612 case IIO_VOLTAGE:
613 if (chan->channel == 1) /* supply_raw*/
614 *val = *val * 6;
615 break;
616 default:
617 break;
618 }
619
620 ret = IIO_VAL_INT;
621 break;
c8a9f805 622 case IIO_CHAN_INFO_CALIBSCALE:
83e416f4
MH
623 switch (chan->type) {
624 case IIO_CAPACITANCE:
625 reg = AD7746_REG_CAP_GAINH;
626 break;
627 case IIO_VOLTAGE:
628 reg = AD7746_REG_VOLT_GAINH;
629 break;
630 default:
631 ret = -EINVAL;
632 goto out;
633 }
634
635 ret = i2c_smbus_read_word_data(chip->client, reg);
636 if (ret < 0)
637 goto out;
638 /* 1 + gain_val / 2^16 */
639 *val = 1;
640 *val2 = (15625 * swab16(ret)) / 1024;
641
642 ret = IIO_VAL_INT_PLUS_MICRO;
643 break;
c8a9f805 644 case IIO_CHAN_INFO_CALIBBIAS:
83e416f4
MH
645 ret = i2c_smbus_read_word_data(chip->client,
646 AD7746_REG_CAP_OFFH);
647 if (ret < 0)
648 goto out;
649 *val = swab16(ret);
650
651 ret = IIO_VAL_INT;
652 break;
c8a9f805 653 case IIO_CHAN_INFO_OFFSET:
83e416f4
MH
654 *val = AD7746_CAPDAC_DACP(chip->capdac[chan->channel]
655 [chan->differential]) * 338646;
656
657 ret = IIO_VAL_INT;
658 break;
c8a9f805 659 case IIO_CHAN_INFO_SCALE:
83e416f4
MH
660 switch (chan->type) {
661 case IIO_CAPACITANCE:
662 /* 8.192pf / 2^24 */
663 *val2 = 488;
664 *val = 0;
665 break;
666 case IIO_VOLTAGE:
667 /* 1170mV / 2^23 */
668 *val2 = 139475;
669 *val = 0;
670 break;
671 default:
672 ret = -EINVAL;
673 goto out;
674 }
675
676 ret = IIO_VAL_INT_PLUS_NANO;
677 break;
678 default:
679 ret = -EINVAL;
73327b4c 680 }
83e416f4
MH
681out:
682 mutex_unlock(&indio_dev->mlock);
683 return ret;
684}
685
686static const struct iio_info ad7746_info = {
687 .attrs = &ad7746_attribute_group,
688 .read_raw = &ad7746_read_raw,
689 .write_raw = &ad7746_write_raw,
690 .driver_module = THIS_MODULE,
691};
692
693/*
694 * device probe and remove
695 */
696
4ae1c61f 697static int ad7746_probe(struct i2c_client *client,
83e416f4
MH
698 const struct i2c_device_id *id)
699{
700 struct ad7746_platform_data *pdata = client->dev.platform_data;
701 struct ad7746_chip_info *chip;
702 struct iio_dev *indio_dev;
703 int ret = 0;
704 unsigned char regval = 0;
705
7cbb7537 706 indio_dev = iio_device_alloc(sizeof(*chip));
83e416f4
MH
707 if (indio_dev == NULL) {
708 ret = -ENOMEM;
709 goto error_ret;
710 }
711 chip = iio_priv(indio_dev);
712 /* this is only used for device removal purposes */
713 i2c_set_clientdata(client, indio_dev);
714
715 chip->client = client;
716 chip->capdac_set = -1;
717
718 /* Establish that the iio_dev is a child of the i2c device */
719 indio_dev->name = id->name;
720 indio_dev->dev.parent = &client->dev;
721 indio_dev->info = &ad7746_info;
722 indio_dev->channels = ad7746_channels;
723 if (id->driver_data == 7746)
724 indio_dev->num_channels = ARRAY_SIZE(ad7746_channels);
725 else
726 indio_dev->num_channels = ARRAY_SIZE(ad7746_channels) - 2;
727 indio_dev->num_channels = ARRAY_SIZE(ad7746_channels);
728 indio_dev->modes = INDIO_DIRECT_MODE;
729
730 if (pdata) {
731 if (pdata->exca_en) {
732 if (pdata->exca_inv_en)
733 regval |= AD7746_EXCSETUP_NEXCA;
734 else
735 regval |= AD7746_EXCSETUP_EXCA;
736 }
737
738 if (pdata->excb_en) {
739 if (pdata->excb_inv_en)
740 regval |= AD7746_EXCSETUP_NEXCB;
741 else
742 regval |= AD7746_EXCSETUP_EXCB;
743 }
744
745 regval |= AD7746_EXCSETUP_EXCLVL(pdata->exclvl);
746 } else {
747 dev_warn(&client->dev, "No platform data? using default\n");
748 regval = AD7746_EXCSETUP_EXCA | AD7746_EXCSETUP_EXCB |
749 AD7746_EXCSETUP_EXCLVL(3);
750 }
751
752 ret = i2c_smbus_write_byte_data(chip->client,
753 AD7746_REG_EXC_SETUP, regval);
754 if (ret < 0)
755 goto error_free_dev;
756
757 ret = iio_device_register(indio_dev);
758 if (ret)
759 goto error_free_dev;
760
761 dev_info(&client->dev, "%s capacitive sensor registered\n", id->name);
762
763 return 0;
764
765error_free_dev:
7cbb7537 766 iio_device_free(indio_dev);
83e416f4
MH
767error_ret:
768 return ret;
769}
770
447d4f29 771static int ad7746_remove(struct i2c_client *client)
83e416f4
MH
772{
773 struct iio_dev *indio_dev = i2c_get_clientdata(client);
774
775 iio_device_unregister(indio_dev);
7cbb7537 776 iio_device_free(indio_dev);
83e416f4
MH
777
778 return 0;
779}
780
781static const struct i2c_device_id ad7746_id[] = {
782 { "ad7745", 7745 },
783 { "ad7746", 7746 },
784 { "ad7747", 7747 },
785 {}
786};
787
788MODULE_DEVICE_TABLE(i2c, ad7746_id);
789
790static struct i2c_driver ad7746_driver = {
791 .driver = {
792 .name = KBUILD_MODNAME,
793 },
794 .probe = ad7746_probe,
e543acf0 795 .remove = ad7746_remove,
83e416f4
MH
796 .id_table = ad7746_id,
797};
6e5af184 798module_i2c_driver(ad7746_driver);
83e416f4
MH
799
800MODULE_AUTHOR("Michael Hennerich <hennerich@blackfin.uclinux.org>");
801MODULE_DESCRIPTION("Analog Devices AD7746/5/7 capacitive sensor driver");
802MODULE_LICENSE("GPL v2");