Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

iio: impedance-analyzer: New driver for AD5933/4 Impedance Converter, Network Analyzer

The AD5933 is a high precision impedance converter system solution
that combines an on-board frequency generator with a 12-bit, 1 MSPS,
analog-to-digital converter (ADC). The frequency generator allows an
external complex impedance to be excited with a known frequency.

The response signal from the impedance is sampled by the on-board ADC
and a discrete Fourier transform (DFT) is processed by an on-chip DSP engine.
The DFT algorithm returns a real (R) and imaginary (I) data-word at each
output frequency.

Changes since V1:

Apply list review feedback:
Consistently use poll_time_jiffies.
Use be|le cpu endian helpers where applicable.
Add various comments.

Changes since V2:

Fix KernelVersion tag in Documentation.
Declare ad5933_default_pdata static.
Fix typos.

Signed-off-by: Michael Hennerich <michael.hennerich@analog.com>
Acked-by: Jonathan Cameron <jic23@cam.ac.uk>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>

authored by

Michael Hennerich and committed by
Greg Kroah-Hartman
f94aa354 2051f25d

+899
+30
drivers/staging/iio/Documentation/sysfs-bus-iio-impedance-analyzer-ad5933
··· 1 + What: /sys/bus/iio/devices/iio:deviceX/outY_freq_start 2 + KernelVersion: 3.1.0 3 + Contact: linux-iio@vger.kernel.org 4 + Description: 5 + Frequency sweep start frequency in Hz. 6 + 7 + What: /sys/bus/iio/devices/iio:deviceX/outY_freq_increment 8 + KernelVersion: 3.1.0 9 + Contact: linux-iio@vger.kernel.org 10 + Description: 11 + Frequency increment in Hz (step size) between consecutive 12 + frequency points along the sweep. 13 + 14 + What: /sys/bus/iio/devices/iio:deviceX/outY_freq_points 15 + KernelVersion: 3.1.0 16 + Contact: linux-iio@vger.kernel.org 17 + Description: 18 + Number of frequency points (steps) in the frequency sweep. 19 + This value, in conjunction with the outY_freq_start and the 20 + outY_freq_increment, determines the frequency sweep range 21 + for the sweep operation. 22 + 23 + What: /sys/bus/iio/devices/iio:deviceX/outY_settling_cycles 24 + KernelVersion: 3.1.0 25 + Contact: linux-iio@vger.kernel.org 26 + Description: 27 + Number of output excitation cycles (settling time cycles) 28 + that are allowed to pass through the unknown impedance, 29 + after each frequency increment, and before the ADC is triggered 30 + to perform a conversion sequence of the response signal.
+1
drivers/staging/iio/Kconfig
··· 62 62 source "drivers/staging/iio/dac/Kconfig" 63 63 source "drivers/staging/iio/dds/Kconfig" 64 64 source "drivers/staging/iio/gyro/Kconfig" 65 + source "drivers/staging/iio/impedance-analyzer/Kconfig" 65 66 source "drivers/staging/iio/imu/Kconfig" 66 67 source "drivers/staging/iio/light/Kconfig" 67 68 source "drivers/staging/iio/magnetometer/Kconfig"
+1
drivers/staging/iio/Makefile
··· 16 16 obj-y += dac/ 17 17 obj-y += dds/ 18 18 obj-y += gyro/ 19 + obj-y += impedance-analyzer/ 19 20 obj-y += imu/ 20 21 obj-y += light/ 21 22 obj-y += magnetometer/
+16
drivers/staging/iio/impedance-analyzer/Kconfig
··· 1 + # 2 + # Impedance Converter, Network Analyzer drivers 3 + # 4 + comment "Network Analyzer, Impedance Converters" 5 + 6 + config AD5933 7 + tristate "Analog Devices AD5933, AD5934 driver" 8 + depends on I2C 9 + select IIO_RING_BUFFER 10 + select IIO_SW_RING 11 + help 12 + Say yes here to build support for Analog Devices Impedance Converter, 13 + Network Analyzer, AD5933/4, provides direct access via sysfs. 14 + 15 + To compile this driver as a module, choose M here: the 16 + module will be called ad5933.
+5
drivers/staging/iio/impedance-analyzer/Makefile
··· 1 + # 2 + # Makefile for Impedance Converter, Network Analyzer drivers 3 + # 4 + 5 + obj-$(CONFIG_AD5933) += ad5933.o
+818
drivers/staging/iio/impedance-analyzer/ad5933.c
··· 1 + /* 2 + * AD5933 AD5934 Impedance Converter, Network Analyzer 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/sysfs.h> 13 + #include <linux/i2c.h> 14 + #include <linux/regulator/consumer.h> 15 + #include <linux/slab.h> 16 + #include <linux/types.h> 17 + #include <linux/err.h> 18 + #include <linux/delay.h> 19 + #include <asm/div64.h> 20 + 21 + #include "../iio.h" 22 + #include "../sysfs.h" 23 + #include "../ring_generic.h" 24 + #include "../ring_sw.h" 25 + 26 + #include "ad5933.h" 27 + 28 + /* AD5933/AD5934 Registers */ 29 + #define AD5933_REG_CONTROL_HB 0x80 /* R/W, 2 bytes */ 30 + #define AD5933_REG_CONTROL_LB 0x81 /* R/W, 2 bytes */ 31 + #define AD5933_REG_FREQ_START 0x82 /* R/W, 3 bytes */ 32 + #define AD5933_REG_FREQ_INC 0x85 /* R/W, 3 bytes */ 33 + #define AD5933_REG_INC_NUM 0x88 /* R/W, 2 bytes, 9 bit */ 34 + #define AD5933_REG_SETTLING_CYCLES 0x8A /* R/W, 2 bytes */ 35 + #define AD5933_REG_STATUS 0x8F /* R, 1 byte */ 36 + #define AD5933_REG_TEMP_DATA 0x92 /* R, 2 bytes*/ 37 + #define AD5933_REG_REAL_DATA 0x94 /* R, 2 bytes*/ 38 + #define AD5933_REG_IMAG_DATA 0x96 /* R, 2 bytes*/ 39 + 40 + /* AD5933_REG_CONTROL_HB Bits */ 41 + #define AD5933_CTRL_INIT_START_FREQ (0x1 << 4) 42 + #define AD5933_CTRL_START_SWEEP (0x2 << 4) 43 + #define AD5933_CTRL_INC_FREQ (0x3 << 4) 44 + #define AD5933_CTRL_REPEAT_FREQ (0x4 << 4) 45 + #define AD5933_CTRL_MEASURE_TEMP (0x9 << 4) 46 + #define AD5933_CTRL_POWER_DOWN (0xA << 4) 47 + #define AD5933_CTRL_STANDBY (0xB << 4) 48 + 49 + #define AD5933_CTRL_RANGE_2000mVpp (0x0 << 1) 50 + #define AD5933_CTRL_RANGE_200mVpp (0x1 << 1) 51 + #define AD5933_CTRL_RANGE_400mVpp (0x2 << 1) 52 + #define AD5933_CTRL_RANGE_1000mVpp (0x3 << 1) 53 + #define AD5933_CTRL_RANGE(x) ((x) << 1) 54 + 55 + #define AD5933_CTRL_PGA_GAIN_1 (0x1 << 0) 56 + #define AD5933_CTRL_PGA_GAIN_5 (0x0 << 0) 57 + 58 + /* AD5933_REG_CONTROL_LB Bits */ 59 + #define AD5933_CTRL_RESET (0x1 << 4) 60 + #define AD5933_CTRL_INT_SYSCLK (0x0 << 3) 61 + #define AD5933_CTRL_EXT_SYSCLK (0x1 << 3) 62 + 63 + /* AD5933_REG_STATUS Bits */ 64 + #define AD5933_STAT_TEMP_VALID (0x1 << 0) 65 + #define AD5933_STAT_DATA_VALID (0x1 << 1) 66 + #define AD5933_STAT_SWEEP_DONE (0x1 << 2) 67 + 68 + /* I2C Block Commands */ 69 + #define AD5933_I2C_BLOCK_WRITE 0xA0 70 + #define AD5933_I2C_BLOCK_READ 0xA1 71 + #define AD5933_I2C_ADDR_POINTER 0xB0 72 + 73 + /* Device Specs */ 74 + #define AD5933_INT_OSC_FREQ_Hz 16776000 75 + #define AD5933_MAX_OUTPUT_FREQ_Hz 100000 76 + #define AD5933_MAX_RETRIES 100 77 + 78 + #define AD5933_OUT_RANGE 1 79 + #define AD5933_OUT_RANGE_AVAIL 2 80 + #define AD5933_OUT_SETTLING_CYCLES 3 81 + #define AD5933_IN_PGA_GAIN 4 82 + #define AD5933_IN_PGA_GAIN_AVAIL 5 83 + #define AD5933_FREQ_POINTS 6 84 + 85 + #define AD5933_POLL_TIME_ms 10 86 + #define AD5933_INIT_EXCITATION_TIME_ms 100 87 + 88 + struct ad5933_state { 89 + struct i2c_client *client; 90 + struct regulator *reg; 91 + struct ad5933_platform_data *pdata; 92 + struct delayed_work work; 93 + unsigned long mclk_hz; 94 + unsigned char ctrl_hb; 95 + unsigned char ctrl_lb; 96 + unsigned range_avail[4]; 97 + unsigned short vref_mv; 98 + unsigned short settling_cycles; 99 + unsigned short freq_points; 100 + unsigned freq_start; 101 + unsigned freq_inc; 102 + unsigned state; 103 + unsigned poll_time_jiffies; 104 + }; 105 + 106 + static struct ad5933_platform_data ad5933_default_pdata = { 107 + .vref_mv = 3300, 108 + }; 109 + 110 + static struct iio_chan_spec ad5933_channels[] = { 111 + IIO_CHAN(IIO_TEMP, 0, 1, 1, NULL, 0, 0, 0, 112 + 0, AD5933_REG_TEMP_DATA, IIO_ST('s', 14, 16, 0), 0), 113 + /* Ring Channels */ 114 + IIO_CHAN(IIO_IN, 0, 1, 0, "real_raw", 0, 0, 115 + (1 << IIO_CHAN_INFO_SCALE_SEPARATE), 116 + AD5933_REG_REAL_DATA, 0, IIO_ST('s', 16, 16, 0), 0), 117 + IIO_CHAN(IIO_IN, 0, 1, 0, "imag_raw", 0, 0, 118 + (1 << IIO_CHAN_INFO_SCALE_SEPARATE), 119 + AD5933_REG_IMAG_DATA, 1, IIO_ST('s', 16, 16, 0), 0), 120 + }; 121 + 122 + static int ad5933_i2c_write(struct i2c_client *client, 123 + u8 reg, u8 len, u8 *data) 124 + { 125 + int ret; 126 + 127 + while (len--) { 128 + ret = i2c_smbus_write_byte_data(client, reg++, *data++); 129 + if (ret < 0) { 130 + dev_err(&client->dev, "I2C write error\n"); 131 + return ret; 132 + } 133 + } 134 + return 0; 135 + } 136 + 137 + static int ad5933_i2c_read(struct i2c_client *client, 138 + u8 reg, u8 len, u8 *data) 139 + { 140 + int ret; 141 + 142 + while (len--) { 143 + ret = i2c_smbus_read_byte_data(client, reg++); 144 + if (ret < 0) { 145 + dev_err(&client->dev, "I2C read error\n"); 146 + return ret; 147 + } 148 + *data++ = ret; 149 + } 150 + return 0; 151 + } 152 + 153 + static int ad5933_cmd(struct ad5933_state *st, unsigned char cmd) 154 + { 155 + unsigned char dat = st->ctrl_hb | cmd; 156 + 157 + return ad5933_i2c_write(st->client, 158 + AD5933_REG_CONTROL_HB, 1, &dat); 159 + } 160 + 161 + static int ad5933_reset(struct ad5933_state *st) 162 + { 163 + unsigned char dat = st->ctrl_lb | AD5933_CTRL_RESET; 164 + return ad5933_i2c_write(st->client, 165 + AD5933_REG_CONTROL_LB, 1, &dat); 166 + } 167 + 168 + static int ad5933_wait_busy(struct ad5933_state *st, unsigned char event) 169 + { 170 + unsigned char val, timeout = AD5933_MAX_RETRIES; 171 + int ret; 172 + 173 + while (timeout--) { 174 + ret = ad5933_i2c_read(st->client, AD5933_REG_STATUS, 1, &val); 175 + if (ret < 0) 176 + return ret; 177 + if (val & event) 178 + return val; 179 + cpu_relax(); 180 + mdelay(1); 181 + } 182 + 183 + return -EAGAIN; 184 + } 185 + 186 + static int ad5933_set_freq(struct ad5933_state *st, 187 + unsigned reg, unsigned long freq) 188 + { 189 + unsigned long long freqreg; 190 + union { 191 + u32 d32; 192 + u8 d8[4]; 193 + } dat; 194 + 195 + freqreg = (u64) freq * (u64) (1 << 27); 196 + do_div(freqreg, st->mclk_hz / 4); 197 + 198 + switch (reg) { 199 + case AD5933_REG_FREQ_START: 200 + st->freq_start = freq; 201 + break; 202 + case AD5933_REG_FREQ_INC: 203 + st->freq_inc = freq; 204 + break; 205 + default: 206 + return -EINVAL; 207 + } 208 + 209 + dat.d32 = cpu_to_be32(freqreg); 210 + return ad5933_i2c_write(st->client, reg, 3, &dat.d8[1]); 211 + } 212 + 213 + static int ad5933_setup(struct ad5933_state *st) 214 + { 215 + unsigned short dat; 216 + int ret; 217 + 218 + ret = ad5933_reset(st); 219 + if (ret < 0) 220 + return ret; 221 + 222 + ret = ad5933_set_freq(st, AD5933_REG_FREQ_START, 10000); 223 + if (ret < 0) 224 + return ret; 225 + 226 + ret = ad5933_set_freq(st, AD5933_REG_FREQ_INC, 200); 227 + if (ret < 0) 228 + return ret; 229 + 230 + st->settling_cycles = 10; 231 + dat = cpu_to_be16(st->settling_cycles); 232 + 233 + ret = ad5933_i2c_write(st->client, 234 + AD5933_REG_SETTLING_CYCLES, 2, (u8 *)&dat); 235 + if (ret < 0) 236 + return ret; 237 + 238 + st->freq_points = 100; 239 + dat = cpu_to_be16(st->freq_points); 240 + 241 + return ad5933_i2c_write(st->client, AD5933_REG_INC_NUM, 2, (u8 *)&dat); 242 + } 243 + 244 + static void ad5933_calc_out_ranges(struct ad5933_state *st) 245 + { 246 + int i; 247 + unsigned normalized_3v3[4] = {1980, 198, 383, 970}; 248 + 249 + for (i = 0; i < 4; i++) 250 + st->range_avail[i] = normalized_3v3[i] * st->vref_mv / 3300; 251 + 252 + } 253 + 254 + /* 255 + * handles: AD5933_REG_FREQ_START and AD5933_REG_FREQ_INC 256 + */ 257 + 258 + static ssize_t ad5933_show_frequency(struct device *dev, 259 + struct device_attribute *attr, 260 + char *buf) 261 + { 262 + struct iio_dev *dev_info = dev_get_drvdata(dev); 263 + struct ad5933_state *st = iio_priv(dev_info); 264 + struct iio_dev_attr *this_attr = to_iio_dev_attr(attr); 265 + int ret; 266 + unsigned long long freqreg; 267 + union { 268 + u32 d32; 269 + u8 d8[4]; 270 + } dat; 271 + 272 + mutex_lock(&dev_info->mlock); 273 + ret = ad5933_i2c_read(st->client, this_attr->address, 3, &dat.d8[1]); 274 + mutex_unlock(&dev_info->mlock); 275 + if (ret < 0) 276 + return ret; 277 + 278 + freqreg = be32_to_cpu(dat.d32) & 0xFFFFFF; 279 + 280 + freqreg = (u64) freqreg * (u64) (st->mclk_hz / 4); 281 + do_div(freqreg, 1 << 27); 282 + 283 + return sprintf(buf, "%d\n", (int) freqreg); 284 + } 285 + 286 + static ssize_t ad5933_store_frequency(struct device *dev, 287 + struct device_attribute *attr, 288 + const char *buf, 289 + size_t len) 290 + { 291 + struct iio_dev *dev_info = dev_get_drvdata(dev); 292 + struct ad5933_state *st = iio_priv(dev_info); 293 + struct iio_dev_attr *this_attr = to_iio_dev_attr(attr); 294 + long val; 295 + int ret; 296 + 297 + ret = strict_strtoul(buf, 10, &val); 298 + if (ret) 299 + return ret; 300 + 301 + if (val > AD5933_MAX_OUTPUT_FREQ_Hz) 302 + return -EINVAL; 303 + 304 + mutex_lock(&dev_info->mlock); 305 + ret = ad5933_set_freq(st, this_attr->address, val); 306 + mutex_unlock(&dev_info->mlock); 307 + 308 + return ret ? ret : len; 309 + } 310 + 311 + static IIO_DEVICE_ATTR(out0_freq_start, S_IRUGO | S_IWUSR, 312 + ad5933_show_frequency, 313 + ad5933_store_frequency, 314 + AD5933_REG_FREQ_START); 315 + 316 + static IIO_DEVICE_ATTR(out0_freq_increment, S_IRUGO | S_IWUSR, 317 + ad5933_show_frequency, 318 + ad5933_store_frequency, 319 + AD5933_REG_FREQ_INC); 320 + 321 + static ssize_t ad5933_show(struct device *dev, 322 + struct device_attribute *attr, 323 + char *buf) 324 + { 325 + struct iio_dev *dev_info = dev_get_drvdata(dev); 326 + struct ad5933_state *st = iio_priv(dev_info); 327 + struct iio_dev_attr *this_attr = to_iio_dev_attr(attr); 328 + int ret = 0, len = 0; 329 + 330 + mutex_lock(&dev_info->mlock); 331 + switch (this_attr->address) { 332 + case AD5933_OUT_RANGE: 333 + len = sprintf(buf, "%d\n", 334 + st->range_avail[(st->ctrl_hb >> 1) & 0x3]); 335 + break; 336 + case AD5933_OUT_RANGE_AVAIL: 337 + len = sprintf(buf, "%d %d %d %d\n", st->range_avail[0], 338 + st->range_avail[3], st->range_avail[2], 339 + st->range_avail[1]); 340 + break; 341 + case AD5933_OUT_SETTLING_CYCLES: 342 + len = sprintf(buf, "%d\n", st->settling_cycles); 343 + break; 344 + case AD5933_IN_PGA_GAIN: 345 + len = sprintf(buf, "%s\n", 346 + (st->ctrl_hb & AD5933_CTRL_PGA_GAIN_1) ? 347 + "1" : "0.2"); 348 + break; 349 + case AD5933_IN_PGA_GAIN_AVAIL: 350 + len = sprintf(buf, "1 0.2\n"); 351 + break; 352 + case AD5933_FREQ_POINTS: 353 + len = sprintf(buf, "%d\n", st->freq_points); 354 + break; 355 + default: 356 + ret = -EINVAL; 357 + } 358 + 359 + mutex_unlock(&dev_info->mlock); 360 + return ret ? ret : len; 361 + } 362 + 363 + static ssize_t ad5933_store(struct device *dev, 364 + struct device_attribute *attr, 365 + const char *buf, 366 + size_t len) 367 + { 368 + struct iio_dev *dev_info = dev_get_drvdata(dev); 369 + struct ad5933_state *st = iio_priv(dev_info); 370 + struct iio_dev_attr *this_attr = to_iio_dev_attr(attr); 371 + long val; 372 + int i, ret = 0; 373 + unsigned short dat; 374 + 375 + if (this_attr->address != AD5933_IN_PGA_GAIN) { 376 + ret = strict_strtol(buf, 10, &val); 377 + if (ret) 378 + return ret; 379 + } 380 + 381 + mutex_lock(&dev_info->mlock); 382 + switch (this_attr->address) { 383 + case AD5933_OUT_RANGE: 384 + for (i = 0; i < 4; i++) 385 + if (val == st->range_avail[i]) { 386 + st->ctrl_hb &= ~AD5933_CTRL_RANGE(0x3); 387 + st->ctrl_hb |= AD5933_CTRL_RANGE(i); 388 + ret = ad5933_cmd(st, 0); 389 + break; 390 + } 391 + ret = -EINVAL; 392 + break; 393 + case AD5933_IN_PGA_GAIN: 394 + if (sysfs_streq(buf, "1")) { 395 + st->ctrl_hb |= AD5933_CTRL_PGA_GAIN_1; 396 + } else if (sysfs_streq(buf, "0.2")) { 397 + st->ctrl_hb &= ~AD5933_CTRL_PGA_GAIN_1; 398 + } else { 399 + ret = -EINVAL; 400 + break; 401 + } 402 + ret = ad5933_cmd(st, 0); 403 + break; 404 + case AD5933_OUT_SETTLING_CYCLES: 405 + val = clamp(val, 0L, 0x7FFL); 406 + st->settling_cycles = val; 407 + 408 + /* 2x, 4x handling, see datasheet */ 409 + if (val > 511) 410 + val = (val >> 1) | (1 << 9); 411 + else if (val > 1022) 412 + val = (val >> 2) | (3 << 9); 413 + 414 + dat = cpu_to_be16(val); 415 + ret = ad5933_i2c_write(st->client, 416 + AD5933_REG_SETTLING_CYCLES, 2, (u8 *)&dat); 417 + break; 418 + case AD5933_FREQ_POINTS: 419 + val = clamp(val, 0L, 511L); 420 + st->freq_points = val; 421 + 422 + dat = cpu_to_be16(val); 423 + ret = ad5933_i2c_write(st->client, AD5933_REG_INC_NUM, 2, 424 + (u8 *)&dat); 425 + break; 426 + default: 427 + ret = -EINVAL; 428 + } 429 + 430 + mutex_unlock(&dev_info->mlock); 431 + return ret ? ret : len; 432 + } 433 + 434 + static IIO_DEVICE_ATTR(out0_scale, S_IRUGO | S_IWUSR, 435 + ad5933_show, 436 + ad5933_store, 437 + AD5933_OUT_RANGE); 438 + 439 + static IIO_DEVICE_ATTR(out0_scale_available, S_IRUGO, 440 + ad5933_show, 441 + NULL, 442 + AD5933_OUT_RANGE_AVAIL); 443 + 444 + static IIO_DEVICE_ATTR(in0_scale, S_IRUGO | S_IWUSR, 445 + ad5933_show, 446 + ad5933_store, 447 + AD5933_IN_PGA_GAIN); 448 + 449 + static IIO_DEVICE_ATTR(in0_scale_available, S_IRUGO, 450 + ad5933_show, 451 + NULL, 452 + AD5933_IN_PGA_GAIN_AVAIL); 453 + 454 + static IIO_DEVICE_ATTR(out0_freq_points, S_IRUGO | S_IWUSR, 455 + ad5933_show, 456 + ad5933_store, 457 + AD5933_FREQ_POINTS); 458 + 459 + static IIO_DEVICE_ATTR(out0_settling_cycles, S_IRUGO | S_IWUSR, 460 + ad5933_show, 461 + ad5933_store, 462 + AD5933_OUT_SETTLING_CYCLES); 463 + 464 + /* note: 465 + * ideally we would handle the scale attributes via the iio_info 466 + * (read|write)_raw methods, however this part is a untypical since we 467 + * don't create dedicated sysfs channel attributes for out0 and in0. 468 + */ 469 + static struct attribute *ad5933_attributes[] = { 470 + &iio_dev_attr_out0_scale.dev_attr.attr, 471 + &iio_dev_attr_out0_scale_available.dev_attr.attr, 472 + &iio_dev_attr_out0_freq_start.dev_attr.attr, 473 + &iio_dev_attr_out0_freq_increment.dev_attr.attr, 474 + &iio_dev_attr_out0_freq_points.dev_attr.attr, 475 + &iio_dev_attr_out0_settling_cycles.dev_attr.attr, 476 + &iio_dev_attr_in0_scale.dev_attr.attr, 477 + &iio_dev_attr_in0_scale_available.dev_attr.attr, 478 + NULL 479 + }; 480 + 481 + static const struct attribute_group ad5933_attribute_group = { 482 + .attrs = ad5933_attributes, 483 + }; 484 + 485 + static int ad5933_read_raw(struct iio_dev *dev_info, 486 + struct iio_chan_spec const *chan, 487 + int *val, 488 + int *val2, 489 + long m) 490 + { 491 + struct ad5933_state *st = iio_priv(dev_info); 492 + unsigned short dat; 493 + int ret = -EINVAL; 494 + 495 + mutex_lock(&dev_info->mlock); 496 + switch (m) { 497 + case 0: 498 + if (iio_ring_enabled(dev_info)) { 499 + ret = -EBUSY; 500 + goto out; 501 + } 502 + ret = ad5933_cmd(st, AD5933_CTRL_MEASURE_TEMP); 503 + if (ret < 0) 504 + goto out; 505 + ret = ad5933_wait_busy(st, AD5933_STAT_TEMP_VALID); 506 + if (ret < 0) 507 + goto out; 508 + 509 + ret = ad5933_i2c_read(st->client, 510 + AD5933_REG_TEMP_DATA, 2, 511 + (u8 *)&dat); 512 + if (ret < 0) 513 + goto out; 514 + mutex_unlock(&dev_info->mlock); 515 + ret = be16_to_cpu(dat); 516 + /* Temp in Milli degrees Celsius */ 517 + if (ret < 8192) 518 + *val = ret * 1000 / 32; 519 + else 520 + *val = (ret - 16384) * 1000 / 32; 521 + 522 + return IIO_VAL_INT; 523 + } 524 + 525 + out: 526 + mutex_unlock(&dev_info->mlock); 527 + return ret; 528 + } 529 + 530 + static const struct iio_info ad5933_info = { 531 + .read_raw = &ad5933_read_raw, 532 + .attrs = &ad5933_attribute_group, 533 + .driver_module = THIS_MODULE, 534 + }; 535 + 536 + static int ad5933_ring_preenable(struct iio_dev *indio_dev) 537 + { 538 + struct ad5933_state *st = iio_priv(indio_dev); 539 + struct iio_ring_buffer *ring = indio_dev->ring; 540 + size_t d_size; 541 + int ret; 542 + 543 + if (!ring->scan_count) 544 + return -EINVAL; 545 + 546 + d_size = ring->scan_count * 547 + ad5933_channels[1].scan_type.storagebits / 8; 548 + 549 + if (indio_dev->ring->access->set_bytes_per_datum) 550 + indio_dev->ring->access->set_bytes_per_datum(indio_dev->ring, 551 + d_size); 552 + 553 + ret = ad5933_reset(st); 554 + if (ret < 0) 555 + return ret; 556 + 557 + ret = ad5933_cmd(st, AD5933_CTRL_STANDBY); 558 + if (ret < 0) 559 + return ret; 560 + 561 + ret = ad5933_cmd(st, AD5933_CTRL_INIT_START_FREQ); 562 + if (ret < 0) 563 + return ret; 564 + 565 + st->state = AD5933_CTRL_INIT_START_FREQ; 566 + 567 + return 0; 568 + } 569 + 570 + static int ad5933_ring_postenable(struct iio_dev *indio_dev) 571 + { 572 + struct ad5933_state *st = iio_priv(indio_dev); 573 + 574 + /* AD5933_CTRL_INIT_START_FREQ: 575 + * High Q complex circuits require a long time to reach steady state. 576 + * To facilitate the measurement of such impedances, this mode allows 577 + * the user full control of the settling time requirement before 578 + * entering start frequency sweep mode where the impedance measurement 579 + * takes place. In this mode the impedance is excited with the 580 + * programmed start frequency (ad5933_ring_preenable), 581 + * but no measurement takes place. 582 + */ 583 + 584 + schedule_delayed_work(&st->work, 585 + msecs_to_jiffies(AD5933_INIT_EXCITATION_TIME_ms)); 586 + return 0; 587 + } 588 + 589 + static int ad5933_ring_postdisable(struct iio_dev *indio_dev) 590 + { 591 + struct ad5933_state *st = iio_priv(indio_dev); 592 + 593 + cancel_delayed_work_sync(&st->work); 594 + return ad5933_cmd(st, AD5933_CTRL_POWER_DOWN); 595 + } 596 + 597 + static const struct iio_ring_setup_ops ad5933_ring_setup_ops = { 598 + .preenable = &ad5933_ring_preenable, 599 + .postenable = &ad5933_ring_postenable, 600 + .postdisable = &ad5933_ring_postdisable, 601 + }; 602 + 603 + static int ad5933_register_ring_funcs_and_init(struct iio_dev *indio_dev) 604 + { 605 + indio_dev->ring = iio_sw_rb_allocate(indio_dev); 606 + if (!indio_dev->ring) 607 + return -ENOMEM; 608 + 609 + /* Effectively select the ring buffer implementation */ 610 + indio_dev->ring->access = &ring_sw_access_funcs; 611 + 612 + /* Ring buffer functions - here trigger setup related */ 613 + indio_dev->ring->setup_ops = &ad5933_ring_setup_ops; 614 + 615 + indio_dev->modes |= INDIO_RING_HARDWARE_BUFFER; 616 + 617 + return 0; 618 + } 619 + 620 + static void ad5933_work(struct work_struct *work) 621 + { 622 + struct ad5933_state *st = container_of(work, 623 + struct ad5933_state, work.work); 624 + struct iio_dev *indio_dev = i2c_get_clientdata(st->client); 625 + struct iio_ring_buffer *ring = indio_dev->ring; 626 + signed short buf[2]; 627 + unsigned char status; 628 + 629 + mutex_lock(&indio_dev->mlock); 630 + if (st->state == AD5933_CTRL_INIT_START_FREQ) { 631 + /* start sweep */ 632 + ad5933_cmd(st, AD5933_CTRL_START_SWEEP); 633 + st->state = AD5933_CTRL_START_SWEEP; 634 + schedule_delayed_work(&st->work, st->poll_time_jiffies); 635 + mutex_unlock(&indio_dev->mlock); 636 + return; 637 + } 638 + 639 + ad5933_i2c_read(st->client, AD5933_REG_STATUS, 1, &status); 640 + 641 + if (status & AD5933_STAT_DATA_VALID) { 642 + ad5933_i2c_read(st->client, 643 + (ring->scan_mask & (1 << 0)) ? 644 + AD5933_REG_REAL_DATA : AD5933_REG_IMAG_DATA, 645 + ring->scan_count * 2, (u8 *)buf); 646 + 647 + if (ring->scan_count == 2) { 648 + buf[0] = be16_to_cpu(buf[0]); 649 + buf[1] = be16_to_cpu(buf[1]); 650 + } else { 651 + buf[0] = be16_to_cpu(buf[0]); 652 + } 653 + /* save datum to the ring */ 654 + ring->access->store_to(ring, (u8 *)buf, iio_get_time_ns()); 655 + } else { 656 + /* no data available - try again later */ 657 + schedule_delayed_work(&st->work, st->poll_time_jiffies); 658 + mutex_unlock(&indio_dev->mlock); 659 + return; 660 + } 661 + 662 + if (status & AD5933_STAT_SWEEP_DONE) { 663 + /* last sample received - power down do nothing until 664 + * the ring enable is toggled */ 665 + ad5933_cmd(st, AD5933_CTRL_POWER_DOWN); 666 + } else { 667 + /* we just received a valid datum, move on to the next */ 668 + ad5933_cmd(st, AD5933_CTRL_INC_FREQ); 669 + schedule_delayed_work(&st->work, st->poll_time_jiffies); 670 + } 671 + 672 + mutex_unlock(&indio_dev->mlock); 673 + } 674 + 675 + static int __devinit ad5933_probe(struct i2c_client *client, 676 + const struct i2c_device_id *id) 677 + { 678 + int ret, regdone = 0, voltage_uv = 0; 679 + struct ad5933_platform_data *pdata = client->dev.platform_data; 680 + struct ad5933_state *st; 681 + struct iio_dev *indio_dev = iio_allocate_device(sizeof(*st)); 682 + if (indio_dev == NULL) 683 + return -ENOMEM; 684 + 685 + st = iio_priv(indio_dev); 686 + i2c_set_clientdata(client, indio_dev); 687 + st->client = client; 688 + 689 + if (!pdata) 690 + st->pdata = &ad5933_default_pdata; 691 + else 692 + st->pdata = pdata; 693 + 694 + st->reg = regulator_get(&client->dev, "vcc"); 695 + if (!IS_ERR(st->reg)) { 696 + ret = regulator_enable(st->reg); 697 + if (ret) 698 + goto error_put_reg; 699 + voltage_uv = regulator_get_voltage(st->reg); 700 + } 701 + 702 + if (voltage_uv) 703 + st->vref_mv = voltage_uv / 1000; 704 + else 705 + st->vref_mv = st->pdata->vref_mv; 706 + 707 + if (st->pdata->ext_clk_Hz) { 708 + st->mclk_hz = st->pdata->ext_clk_Hz; 709 + st->ctrl_lb = AD5933_CTRL_EXT_SYSCLK; 710 + } else { 711 + st->mclk_hz = AD5933_INT_OSC_FREQ_Hz; 712 + st->ctrl_lb = AD5933_CTRL_INT_SYSCLK; 713 + } 714 + 715 + ad5933_calc_out_ranges(st); 716 + INIT_DELAYED_WORK(&st->work, ad5933_work); 717 + st->poll_time_jiffies = msecs_to_jiffies(AD5933_POLL_TIME_ms); 718 + 719 + indio_dev->dev.parent = &client->dev; 720 + indio_dev->info = &ad5933_info; 721 + indio_dev->name = id->name; 722 + indio_dev->modes = INDIO_DIRECT_MODE; 723 + indio_dev->channels = ad5933_channels; 724 + indio_dev->num_channels = 1; /* only register temp0_input */ 725 + 726 + ret = ad5933_register_ring_funcs_and_init(indio_dev); 727 + if (ret) 728 + goto error_disable_reg; 729 + 730 + ret = iio_device_register(indio_dev); 731 + if (ret) 732 + goto error_unreg_ring; 733 + regdone = 1; 734 + 735 + /* skip temp0_input, register in0_(real|imag)_raw */ 736 + ret = iio_ring_buffer_register_ex(indio_dev->ring, 0, 737 + &ad5933_channels[1], 738 + 2); 739 + if (ret) 740 + goto error_unreg_ring; 741 + 742 + /* enable both REAL and IMAG channels by default */ 743 + iio_scan_mask_set(indio_dev->ring, 0); 744 + iio_scan_mask_set(indio_dev->ring, 1); 745 + 746 + ret = ad5933_setup(st); 747 + if (ret) 748 + goto error_uninitialize_ring; 749 + 750 + return 0; 751 + 752 + error_uninitialize_ring: 753 + iio_ring_buffer_unregister(indio_dev->ring); 754 + error_unreg_ring: 755 + iio_sw_rb_free(indio_dev->ring); 756 + error_disable_reg: 757 + if (!IS_ERR(st->reg)) 758 + regulator_disable(st->reg); 759 + error_put_reg: 760 + if (!IS_ERR(st->reg)) 761 + regulator_put(st->reg); 762 + 763 + if (regdone) 764 + iio_device_unregister(indio_dev); 765 + else 766 + iio_free_device(indio_dev); 767 + 768 + return ret; 769 + } 770 + 771 + static __devexit int ad5933_remove(struct i2c_client *client) 772 + { 773 + struct iio_dev *indio_dev = i2c_get_clientdata(client); 774 + struct ad5933_state *st = iio_priv(indio_dev); 775 + 776 + iio_ring_buffer_unregister(indio_dev->ring); 777 + iio_sw_rb_free(indio_dev->ring); 778 + if (!IS_ERR(st->reg)) { 779 + regulator_disable(st->reg); 780 + regulator_put(st->reg); 781 + } 782 + iio_device_unregister(indio_dev); 783 + 784 + return 0; 785 + } 786 + 787 + static const struct i2c_device_id ad5933_id[] = { 788 + { "ad5933", 0 }, 789 + { "ad5934", 0 }, 790 + {} 791 + }; 792 + 793 + MODULE_DEVICE_TABLE(i2c, ad5933_id); 794 + 795 + static struct i2c_driver ad5933_driver = { 796 + .driver = { 797 + .name = "ad5933", 798 + }, 799 + .probe = ad5933_probe, 800 + .remove = __devexit_p(ad5933_remove), 801 + .id_table = ad5933_id, 802 + }; 803 + 804 + static __init int ad5933_init(void) 805 + { 806 + return i2c_add_driver(&ad5933_driver); 807 + } 808 + module_init(ad5933_init); 809 + 810 + static __exit void ad5933_exit(void) 811 + { 812 + i2c_del_driver(&ad5933_driver); 813 + } 814 + module_exit(ad5933_exit); 815 + 816 + MODULE_AUTHOR("Michael Hennerich <hennerich@blackfin.uclinux.org>"); 817 + MODULE_DESCRIPTION("Analog Devices AD5933 Impedance Conv. Network Analyzer"); 818 + MODULE_LICENSE("GPL v2");
+28
drivers/staging/iio/impedance-analyzer/ad5933.h
··· 1 + /* 2 + * AD5933 AD5934 Impedance Converter, Network Analyzer 3 + * 4 + * Copyright 2011 Analog Devices Inc. 5 + * 6 + * Licensed under the GPL-2. 7 + */ 8 + 9 + #ifndef IIO_ADC_AD5933_H_ 10 + #define IIO_ADC_AD5933_H_ 11 + 12 + /* 13 + * TODO: struct ad5933_platform_data needs to go into include/linux/iio 14 + */ 15 + 16 + /** 17 + * struct ad5933_platform_data - platform specific data 18 + * @ext_clk_Hz: the external clock frequency in Hz, if not set 19 + * the driver uses the internal clock (16.776 MHz) 20 + * @vref_mv: the external reference voltage in millivolt 21 + */ 22 + 23 + struct ad5933_platform_data { 24 + unsigned long ext_clk_Hz; 25 + unsigned short vref_mv; 26 + }; 27 + 28 + #endif /* IIO_ADC_AD5933_H_ */