17a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich/* 27a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich * AD7190 AD7192 AD7195 SPI ADC driver 37a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich * 4f316983fe033ba090b2f82fb9912aae9412d2372Michael Hennerich * Copyright 2011-2012 Analog Devices Inc. 57a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich * 67a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich * Licensed under the GPL-2. 77a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich */ 87a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich 97a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich#include <linux/interrupt.h> 107a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich#include <linux/device.h> 117a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich#include <linux/kernel.h> 127a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich#include <linux/slab.h> 137a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich#include <linux/sysfs.h> 147a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich#include <linux/spi/spi.h> 157a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich#include <linux/regulator/consumer.h> 167a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich#include <linux/err.h> 177a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich#include <linux/sched.h> 187a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich#include <linux/delay.h> 197a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich 2006458e277eac2b8761b0a04d3c808d57be281a2eJonathan Cameron#include <linux/iio/iio.h> 2106458e277eac2b8761b0a04d3c808d57be281a2eJonathan Cameron#include <linux/iio/sysfs.h> 2206458e277eac2b8761b0a04d3c808d57be281a2eJonathan Cameron#include <linux/iio/buffer.h> 2306458e277eac2b8761b0a04d3c808d57be281a2eJonathan Cameron#include <linux/iio/trigger.h> 2406458e277eac2b8761b0a04d3c808d57be281a2eJonathan Cameron#include <linux/iio/trigger_consumer.h> 25a648232dc5ed840c6dab0a949450ee4cdf5830bdLars-Peter Clausen#include <linux/iio/triggered_buffer.h> 263f7c3306cf385d015d84c741e5433781f83d9254Lars-Peter Clausen#include <linux/iio/adc/ad_sigma_delta.h> 277a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich 287a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich#include "ad7192.h" 297a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich 307a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich/* Registers */ 317a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich#define AD7192_REG_COMM 0 /* Communications Register (WO, 8-bit) */ 327a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich#define AD7192_REG_STAT 0 /* Status Register (RO, 8-bit) */ 337a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich#define AD7192_REG_MODE 1 /* Mode Register (RW, 24-bit */ 347a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich#define AD7192_REG_CONF 2 /* Configuration Register (RW, 24-bit) */ 357a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich#define AD7192_REG_DATA 3 /* Data Register (RO, 24/32-bit) */ 367a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich#define AD7192_REG_ID 4 /* ID Register (RO, 8-bit) */ 377a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich#define AD7192_REG_GPOCON 5 /* GPOCON Register (RO, 8-bit) */ 387a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich#define AD7192_REG_OFFSET 6 /* Offset Register (RW, 16-bit 397a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich * (AD7792)/24-bit (AD7192)) */ 407a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich#define AD7192_REG_FULLSALE 7 /* Full-Scale Register 417a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich * (RW, 16-bit (AD7792)/24-bit (AD7192)) */ 427a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich 437a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich/* Communications Register Bit Designations (AD7192_REG_COMM) */ 447a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich#define AD7192_COMM_WEN (1 << 7) /* Write Enable */ 457a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich#define AD7192_COMM_WRITE (0 << 6) /* Write Operation */ 467a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich#define AD7192_COMM_READ (1 << 6) /* Read Operation */ 477a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich#define AD7192_COMM_ADDR(x) (((x) & 0x7) << 3) /* Register Address */ 487a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich#define AD7192_COMM_CREAD (1 << 2) /* Continuous Read of Data Register */ 497a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich 507a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich/* Status Register Bit Designations (AD7192_REG_STAT) */ 517a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich#define AD7192_STAT_RDY (1 << 7) /* Ready */ 527a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich#define AD7192_STAT_ERR (1 << 6) /* Error (Overrange, Underrange) */ 537a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich#define AD7192_STAT_NOREF (1 << 5) /* Error no external reference */ 547a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich#define AD7192_STAT_PARITY (1 << 4) /* Parity */ 557a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich#define AD7192_STAT_CH3 (1 << 2) /* Channel 3 */ 567a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich#define AD7192_STAT_CH2 (1 << 1) /* Channel 2 */ 577a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich#define AD7192_STAT_CH1 (1 << 0) /* Channel 1 */ 587a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich 597a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich/* Mode Register Bit Designations (AD7192_REG_MODE) */ 607a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich#define AD7192_MODE_SEL(x) (((x) & 0x7) << 21) /* Operation Mode Select */ 613f7c3306cf385d015d84c741e5433781f83d9254Lars-Peter Clausen#define AD7192_MODE_SEL_MASK (0x7 << 21) /* Operation Mode Select Mask */ 627a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich#define AD7192_MODE_DAT_STA (1 << 20) /* Status Register transmission */ 637a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich#define AD7192_MODE_CLKSRC(x) (((x) & 0x3) << 18) /* Clock Source Select */ 647a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich#define AD7192_MODE_SINC3 (1 << 15) /* SINC3 Filter Select */ 657a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich#define AD7192_MODE_ACX (1 << 14) /* AC excitation enable(AD7195 only)*/ 667a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich#define AD7192_MODE_ENPAR (1 << 13) /* Parity Enable */ 677a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich#define AD7192_MODE_CLKDIV (1 << 12) /* Clock divide by 2 (AD7190/2 only)*/ 687a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich#define AD7192_MODE_SCYCLE (1 << 11) /* Single cycle conversion */ 697a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich#define AD7192_MODE_REJ60 (1 << 10) /* 50/60Hz notch filter */ 707a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich#define AD7192_MODE_RATE(x) ((x) & 0x3FF) /* Filter Update Rate Select */ 717a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich 727a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich/* Mode Register: AD7192_MODE_SEL options */ 737a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich#define AD7192_MODE_CONT 0 /* Continuous Conversion Mode */ 747a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich#define AD7192_MODE_SINGLE 1 /* Single Conversion Mode */ 757a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich#define AD7192_MODE_IDLE 2 /* Idle Mode */ 767a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich#define AD7192_MODE_PWRDN 3 /* Power-Down Mode */ 777a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich#define AD7192_MODE_CAL_INT_ZERO 4 /* Internal Zero-Scale Calibration */ 787a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich#define AD7192_MODE_CAL_INT_FULL 5 /* Internal Full-Scale Calibration */ 797a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich#define AD7192_MODE_CAL_SYS_ZERO 6 /* System Zero-Scale Calibration */ 807a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich#define AD7192_MODE_CAL_SYS_FULL 7 /* System Full-Scale Calibration */ 817a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich 827a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich/* Mode Register: AD7192_MODE_CLKSRC options */ 837a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich#define AD7192_CLK_EXT_MCLK1_2 0 /* External 4.92 MHz Clock connected 847a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich * from MCLK1 to MCLK2 */ 857a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich#define AD7192_CLK_EXT_MCLK2 1 /* External Clock applied to MCLK2 */ 867a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich#define AD7192_CLK_INT 2 /* Internal 4.92 MHz Clock not 877a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich * available at the MCLK2 pin */ 887a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich#define AD7192_CLK_INT_CO 3 /* Internal 4.92 MHz Clock available 897a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich * at the MCLK2 pin */ 907a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich 917a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich 927a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich/* Configuration Register Bit Designations (AD7192_REG_CONF) */ 937a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich 947a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich#define AD7192_CONF_CHOP (1 << 23) /* CHOP enable */ 957a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich#define AD7192_CONF_REFSEL (1 << 20) /* REFIN1/REFIN2 Reference Select */ 963f7c3306cf385d015d84c741e5433781f83d9254Lars-Peter Clausen#define AD7192_CONF_CHAN(x) (((1 << (x)) & 0xFF) << 8) /* Channel select */ 973f7c3306cf385d015d84c741e5433781f83d9254Lars-Peter Clausen#define AD7192_CONF_CHAN_MASK (0xFF << 8) /* Channel select mask */ 987a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich#define AD7192_CONF_BURN (1 << 7) /* Burnout current enable */ 997a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich#define AD7192_CONF_REFDET (1 << 6) /* Reference detect enable */ 1007a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich#define AD7192_CONF_BUF (1 << 4) /* Buffered Mode Enable */ 1017a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich#define AD7192_CONF_UNIPOLAR (1 << 3) /* Unipolar/Bipolar Enable */ 1027a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich#define AD7192_CONF_GAIN(x) ((x) & 0x7) /* Gain Select */ 1037a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich 1047a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich#define AD7192_CH_AIN1P_AIN2M 0 /* AIN1(+) - AIN2(-) */ 1057a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich#define AD7192_CH_AIN3P_AIN4M 1 /* AIN3(+) - AIN4(-) */ 1067a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich#define AD7192_CH_TEMP 2 /* Temp Sensor */ 1077a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich#define AD7192_CH_AIN2P_AIN2M 3 /* AIN2(+) - AIN2(-) */ 1087a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich#define AD7192_CH_AIN1 4 /* AIN1 - AINCOM */ 1097a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich#define AD7192_CH_AIN2 5 /* AIN2 - AINCOM */ 1107a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich#define AD7192_CH_AIN3 6 /* AIN3 - AINCOM */ 1117a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich#define AD7192_CH_AIN4 7 /* AIN4 - AINCOM */ 1127a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich 1137a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich/* ID Register Bit Designations (AD7192_REG_ID) */ 1147a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich#define ID_AD7190 0x4 1157a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich#define ID_AD7192 0x0 1167a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich#define ID_AD7195 0x6 1177a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich#define AD7192_ID_MASK 0x0F 1187a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich 1197a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich/* GPOCON Register Bit Designations (AD7192_REG_GPOCON) */ 1207a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich#define AD7192_GPOCON_BPDSW (1 << 6) /* Bridge power-down switch enable */ 1217a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich#define AD7192_GPOCON_GP32EN (1 << 5) /* Digital Output P3 and P2 enable */ 1227a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich#define AD7192_GPOCON_GP10EN (1 << 4) /* Digital Output P1 and P0 enable */ 1237a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich#define AD7192_GPOCON_P3DAT (1 << 3) /* P3 state */ 1247a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich#define AD7192_GPOCON_P2DAT (1 << 2) /* P2 state */ 1257a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich#define AD7192_GPOCON_P1DAT (1 << 1) /* P1 state */ 1267a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich#define AD7192_GPOCON_P0DAT (1 << 0) /* P0 state */ 1277a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich 1287a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich#define AD7192_INT_FREQ_MHz 4915200 1297a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich 1307a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich/* NOTE: 1317a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich * The AD7190/2/5 features a dual use data out ready DOUT/RDY output. 1327a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich * In order to avoid contentions on the SPI bus, it's therefore necessary 1337a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich * to use spi bus locking. 1347a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich * 1357a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich * The DOUT/RDY output must also be wired to an interrupt capable GPIO. 1367a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich */ 1377a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich 1387a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerichstruct ad7192_state { 1397a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich struct regulator *reg; 1407a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich u16 int_vref_mv; 1417a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich u32 mclk; 1427a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich u32 f_order; 1437a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich u32 mode; 1447a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich u32 conf; 1457a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich u32 scale_avail[8][2]; 1467a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich u8 gpocon; 1477a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich u8 devid; 1487a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich 1493f7c3306cf385d015d84c741e5433781f83d9254Lars-Peter Clausen struct ad_sigma_delta sd; 1503f7c3306cf385d015d84c741e5433781f83d9254Lars-Peter Clausen}; 1517a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich 1523f7c3306cf385d015d84c741e5433781f83d9254Lars-Peter Clausenstatic struct ad7192_state *ad_sigma_delta_to_ad7192(struct ad_sigma_delta *sd) 1537a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich{ 1543f7c3306cf385d015d84c741e5433781f83d9254Lars-Peter Clausen return container_of(sd, struct ad7192_state, sd); 1557a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich} 1567a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich 1573f7c3306cf385d015d84c741e5433781f83d9254Lars-Peter Clausenstatic int ad7192_set_channel(struct ad_sigma_delta *sd, unsigned int channel) 1587a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich{ 1593f7c3306cf385d015d84c741e5433781f83d9254Lars-Peter Clausen struct ad7192_state *st = ad_sigma_delta_to_ad7192(sd); 1607a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich 1613f7c3306cf385d015d84c741e5433781f83d9254Lars-Peter Clausen st->conf &= ~AD7192_CONF_CHAN_MASK; 1623f7c3306cf385d015d84c741e5433781f83d9254Lars-Peter Clausen st->conf |= AD7192_CONF_CHAN(channel); 1637a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich 1643f7c3306cf385d015d84c741e5433781f83d9254Lars-Peter Clausen return ad_sd_write_reg(&st->sd, AD7192_REG_CONF, 3, st->conf); 1657a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich} 1667a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich 1673f7c3306cf385d015d84c741e5433781f83d9254Lars-Peter Clausenstatic int ad7192_set_mode(struct ad_sigma_delta *sd, 1683f7c3306cf385d015d84c741e5433781f83d9254Lars-Peter Clausen enum ad_sigma_delta_mode mode) 1697a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich{ 1703f7c3306cf385d015d84c741e5433781f83d9254Lars-Peter Clausen struct ad7192_state *st = ad_sigma_delta_to_ad7192(sd); 1717a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich 1723f7c3306cf385d015d84c741e5433781f83d9254Lars-Peter Clausen st->mode &= ~AD7192_MODE_SEL_MASK; 1733f7c3306cf385d015d84c741e5433781f83d9254Lars-Peter Clausen st->mode |= AD7192_MODE_SEL(mode); 1747a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich 1753f7c3306cf385d015d84c741e5433781f83d9254Lars-Peter Clausen return ad_sd_write_reg(&st->sd, AD7192_REG_MODE, 3, st->mode); 1767a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich} 1777a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich 1783f7c3306cf385d015d84c741e5433781f83d9254Lars-Peter Clausenstatic const struct ad_sigma_delta_info ad7192_sigma_delta_info = { 1793f7c3306cf385d015d84c741e5433781f83d9254Lars-Peter Clausen .set_channel = ad7192_set_channel, 1803f7c3306cf385d015d84c741e5433781f83d9254Lars-Peter Clausen .set_mode = ad7192_set_mode, 1813f7c3306cf385d015d84c741e5433781f83d9254Lars-Peter Clausen .has_registers = true, 1823f7c3306cf385d015d84c741e5433781f83d9254Lars-Peter Clausen .addr_shift = 3, 1833f7c3306cf385d015d84c741e5433781f83d9254Lars-Peter Clausen .read_mask = BIT(6), 1843f7c3306cf385d015d84c741e5433781f83d9254Lars-Peter Clausen}; 1857a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich 1863f7c3306cf385d015d84c741e5433781f83d9254Lars-Peter Clausenstatic const struct ad_sd_calib_data ad7192_calib_arr[8] = { 1877a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich {AD7192_MODE_CAL_INT_ZERO, AD7192_CH_AIN1}, 1887a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich {AD7192_MODE_CAL_INT_FULL, AD7192_CH_AIN1}, 1897a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich {AD7192_MODE_CAL_INT_ZERO, AD7192_CH_AIN2}, 1907a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich {AD7192_MODE_CAL_INT_FULL, AD7192_CH_AIN2}, 1917a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich {AD7192_MODE_CAL_INT_ZERO, AD7192_CH_AIN3}, 1927a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich {AD7192_MODE_CAL_INT_FULL, AD7192_CH_AIN3}, 1937a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich {AD7192_MODE_CAL_INT_ZERO, AD7192_CH_AIN4}, 1947a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich {AD7192_MODE_CAL_INT_FULL, AD7192_CH_AIN4} 1957a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich}; 1967a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich 1977a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerichstatic int ad7192_calibrate_all(struct ad7192_state *st) 1987a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich{ 1993f7c3306cf385d015d84c741e5433781f83d9254Lars-Peter Clausen return ad_sd_calibrate_all(&st->sd, ad7192_calib_arr, 2003f7c3306cf385d015d84c741e5433781f83d9254Lars-Peter Clausen ARRAY_SIZE(ad7192_calib_arr)); 2017a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich} 2027a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich 20349f8812e4d15970341f0ed320e78951cc16b596dLars-Peter Clausenstatic int ad7192_setup(struct ad7192_state *st, 20449f8812e4d15970341f0ed320e78951cc16b596dLars-Peter Clausen const struct ad7192_platform_data *pdata) 2057a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich{ 2063f7c3306cf385d015d84c741e5433781f83d9254Lars-Peter Clausen struct iio_dev *indio_dev = spi_get_drvdata(st->sd.spi); 2077a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich unsigned long long scale_uv; 2087a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich int i, ret, id; 2097a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich u8 ones[6]; 2107a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich 2117a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich /* reset the serial interface */ 2127a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich memset(&ones, 0xFF, 6); 2133f7c3306cf385d015d84c741e5433781f83d9254Lars-Peter Clausen ret = spi_write(st->sd.spi, &ones, 6); 2147a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich if (ret < 0) 2157a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich goto out; 216bb49a0f9b784d5ea872bf5fad8cf8964e243a216Vaishali Thakkar usleep_range(500, 1000); /* Wait for at least 500us */ 2177a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich 2187a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich /* write/read test for device presence */ 2193f7c3306cf385d015d84c741e5433781f83d9254Lars-Peter Clausen ret = ad_sd_read_reg(&st->sd, AD7192_REG_ID, 1, &id); 2207a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich if (ret) 2217a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich goto out; 2227a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich 2237a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich id &= AD7192_ID_MASK; 2247a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich 2257a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich if (id != st->devid) 2263f7c3306cf385d015d84c741e5433781f83d9254Lars-Peter Clausen dev_warn(&st->sd.spi->dev, "device ID query failed (0x%X)\n", id); 2277a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich 2287a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich switch (pdata->clock_source_sel) { 2297a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich case AD7192_CLK_EXT_MCLK1_2: 2307a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich case AD7192_CLK_EXT_MCLK2: 2317a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich st->mclk = AD7192_INT_FREQ_MHz; 2327a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich break; 2337a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich case AD7192_CLK_INT: 2347a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich case AD7192_CLK_INT_CO: 2357a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich if (pdata->ext_clk_Hz) 2367a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich st->mclk = pdata->ext_clk_Hz; 2377a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich else 2387a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich st->mclk = AD7192_INT_FREQ_MHz; 2397a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich break; 2407a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich default: 2417a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich ret = -EINVAL; 2427a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich goto out; 2437a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich } 2447a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich 2457a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich st->mode = AD7192_MODE_SEL(AD7192_MODE_IDLE) | 2467a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich AD7192_MODE_CLKSRC(pdata->clock_source_sel) | 2477a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich AD7192_MODE_RATE(480); 2487a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich 2497a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich st->conf = AD7192_CONF_GAIN(0); 2507a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich 2517a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich if (pdata->rej60_en) 2527a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich st->mode |= AD7192_MODE_REJ60; 2537a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich 2547a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich if (pdata->sinc3_en) 2557a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich st->mode |= AD7192_MODE_SINC3; 2567a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich 2577a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich if (pdata->refin2_en && (st->devid != ID_AD7195)) 2587a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich st->conf |= AD7192_CONF_REFSEL; 2597a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich 2607a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich if (pdata->chop_en) { 2617a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich st->conf |= AD7192_CONF_CHOP; 2627a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich if (pdata->sinc3_en) 2637a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich st->f_order = 3; /* SINC 3rd order */ 2647a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich else 2657a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich st->f_order = 4; /* SINC 4th order */ 2667a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich } else { 2677a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich st->f_order = 1; 2687a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich } 2697a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich 2707a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich if (pdata->buf_en) 2717a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich st->conf |= AD7192_CONF_BUF; 2727a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich 2737a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich if (pdata->unipolar_en) 2747a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich st->conf |= AD7192_CONF_UNIPOLAR; 2757a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich 2767a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich if (pdata->burnout_curr_en) 2777a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich st->conf |= AD7192_CONF_BURN; 2787a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich 2793f7c3306cf385d015d84c741e5433781f83d9254Lars-Peter Clausen ret = ad_sd_write_reg(&st->sd, AD7192_REG_MODE, 3, st->mode); 2807a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich if (ret) 2817a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich goto out; 2827a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich 2833f7c3306cf385d015d84c741e5433781f83d9254Lars-Peter Clausen ret = ad_sd_write_reg(&st->sd, AD7192_REG_CONF, 3, st->conf); 2847a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich if (ret) 2857a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich goto out; 2867a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich 2877a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich ret = ad7192_calibrate_all(st); 2887a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich if (ret) 2897a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich goto out; 2907a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich 2917a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich /* Populate available ADC input ranges */ 2927a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich for (i = 0; i < ARRAY_SIZE(st->scale_avail); i++) { 2937a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich scale_uv = ((u64)st->int_vref_mv * 100000000) 2947a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich >> (indio_dev->channels[0].scan_type.realbits - 2957a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich ((st->conf & AD7192_CONF_UNIPOLAR) ? 0 : 1)); 2967a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich scale_uv >>= i; 2977a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich 2987a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich st->scale_avail[i][1] = do_div(scale_uv, 100000000) * 10; 2997a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich st->scale_avail[i][0] = scale_uv; 3007a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich } 3017a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich 3027a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich return 0; 3037a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerichout: 3043f7c3306cf385d015d84c741e5433781f83d9254Lars-Peter Clausen dev_err(&st->sd.spi->dev, "setup failed\n"); 3057a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich return ret; 3067a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich} 3077a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich 3087a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerichstatic ssize_t ad7192_read_frequency(struct device *dev, 3097a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich struct device_attribute *attr, 3107a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich char *buf) 3117a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich{ 31262c5183971428a559b687fcb15f548df28dbe8dcLars-Peter Clausen struct iio_dev *indio_dev = dev_to_iio_dev(dev); 3137a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich struct ad7192_state *st = iio_priv(indio_dev); 3147a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich 3157a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich return sprintf(buf, "%d\n", st->mclk / 3167a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich (st->f_order * 1024 * AD7192_MODE_RATE(st->mode))); 3177a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich} 3187a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich 3197a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerichstatic ssize_t ad7192_write_frequency(struct device *dev, 3207a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich struct device_attribute *attr, 3217a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich const char *buf, 3227a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich size_t len) 3237a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich{ 32462c5183971428a559b687fcb15f548df28dbe8dcLars-Peter Clausen struct iio_dev *indio_dev = dev_to_iio_dev(dev); 3257a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich struct ad7192_state *st = iio_priv(indio_dev); 3267a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich unsigned long lval; 3277a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich int div, ret; 3287a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich 329f86f83622fe2c45d75f83a7db8d170da55b5b476Aida Mynzhasova ret = kstrtoul(buf, 10, &lval); 3307a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich if (ret) 3317a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich return ret; 33250d4b3062d6d4f165c76854a7644b1502836f9b9Dan Carpenter if (lval == 0) 33350d4b3062d6d4f165c76854a7644b1502836f9b9Dan Carpenter return -EINVAL; 3347a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich 3357a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich mutex_lock(&indio_dev->mlock); 33614555b14455f9acbdf0e500ae96140828a970796Jonathan Cameron if (iio_buffer_enabled(indio_dev)) { 3377a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich mutex_unlock(&indio_dev->mlock); 3387a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich return -EBUSY; 3397a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich } 3407a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich 3417a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich div = st->mclk / (lval * st->f_order * 1024); 3427a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich if (div < 1 || div > 1023) { 3437a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich ret = -EINVAL; 3447a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich goto out; 3457a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich } 3467a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich 3477a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich st->mode &= ~AD7192_MODE_RATE(-1); 3487a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich st->mode |= AD7192_MODE_RATE(div); 3493f7c3306cf385d015d84c741e5433781f83d9254Lars-Peter Clausen ad_sd_write_reg(&st->sd, AD7192_REG_MODE, 3, st->mode); 3507a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich 3517a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerichout: 3527a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich mutex_unlock(&indio_dev->mlock); 3537a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich 3547a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich return ret ? ret : len; 3557a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich} 3567a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich 3577a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerichstatic IIO_DEV_ATTR_SAMP_FREQ(S_IWUSR | S_IRUGO, 3587a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich ad7192_read_frequency, 3597a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich ad7192_write_frequency); 3607a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich 3617a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerichstatic ssize_t ad7192_show_scale_available(struct device *dev, 3627a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich struct device_attribute *attr, char *buf) 3637a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich{ 36462c5183971428a559b687fcb15f548df28dbe8dcLars-Peter Clausen struct iio_dev *indio_dev = dev_to_iio_dev(dev); 3657a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich struct ad7192_state *st = iio_priv(indio_dev); 3667a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich int i, len = 0; 3677a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich 3687a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich for (i = 0; i < ARRAY_SIZE(st->scale_avail); i++) 3697a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich len += sprintf(buf + len, "%d.%09u ", st->scale_avail[i][0], 3707a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich st->scale_avail[i][1]); 3717a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich 3727a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich len += sprintf(buf + len, "\n"); 3737a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich 3747a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich return len; 3757a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich} 3767a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich 377322c95636739420631e51f3d3f24132dc220762aJonathan Cameronstatic IIO_DEVICE_ATTR_NAMED(in_v_m_v_scale_available, 378322c95636739420631e51f3d3f24132dc220762aJonathan Cameron in_voltage-voltage_scale_available, 3797a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich S_IRUGO, ad7192_show_scale_available, NULL, 0); 3807a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich 381322c95636739420631e51f3d3f24132dc220762aJonathan Cameronstatic IIO_DEVICE_ATTR(in_voltage_scale_available, S_IRUGO, 3827a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich ad7192_show_scale_available, NULL, 0); 3837a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich 3847a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerichstatic ssize_t ad7192_show_ac_excitation(struct device *dev, 3857a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich struct device_attribute *attr, 3867a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich char *buf) 3877a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich{ 38862c5183971428a559b687fcb15f548df28dbe8dcLars-Peter Clausen struct iio_dev *indio_dev = dev_to_iio_dev(dev); 3897a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich struct ad7192_state *st = iio_priv(indio_dev); 3907a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich 3917a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich return sprintf(buf, "%d\n", !!(st->mode & AD7192_MODE_ACX)); 3927a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich} 3937a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich 3947a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerichstatic ssize_t ad7192_show_bridge_switch(struct device *dev, 3957a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich struct device_attribute *attr, 3967a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich char *buf) 3977a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich{ 39862c5183971428a559b687fcb15f548df28dbe8dcLars-Peter Clausen struct iio_dev *indio_dev = dev_to_iio_dev(dev); 3997a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich struct ad7192_state *st = iio_priv(indio_dev); 4007a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich 4017a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich return sprintf(buf, "%d\n", !!(st->gpocon & AD7192_GPOCON_BPDSW)); 4027a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich} 4037a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich 4047a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerichstatic ssize_t ad7192_set(struct device *dev, 4057a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich struct device_attribute *attr, 4067a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich const char *buf, 4077a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich size_t len) 4087a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich{ 40962c5183971428a559b687fcb15f548df28dbe8dcLars-Peter Clausen struct iio_dev *indio_dev = dev_to_iio_dev(dev); 4107a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich struct ad7192_state *st = iio_priv(indio_dev); 4117a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich struct iio_dev_attr *this_attr = to_iio_dev_attr(attr); 4127a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich int ret; 4137a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich bool val; 4147a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich 4157a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich ret = strtobool(buf, &val); 4167a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich if (ret < 0) 4177a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich return ret; 4187a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich 4197a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich mutex_lock(&indio_dev->mlock); 42014555b14455f9acbdf0e500ae96140828a970796Jonathan Cameron if (iio_buffer_enabled(indio_dev)) { 4217a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich mutex_unlock(&indio_dev->mlock); 4227a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich return -EBUSY; 4237a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich } 4247a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich 425e15fbc91a4304a977ed99c3eb21bab7015e86c11Michael Hennerich switch ((u32) this_attr->address) { 4267a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich case AD7192_REG_GPOCON: 4277a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich if (val) 4287a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich st->gpocon |= AD7192_GPOCON_BPDSW; 4297a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich else 4307a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich st->gpocon &= ~AD7192_GPOCON_BPDSW; 4317a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich 4323f7c3306cf385d015d84c741e5433781f83d9254Lars-Peter Clausen ad_sd_write_reg(&st->sd, AD7192_REG_GPOCON, 1, st->gpocon); 4337a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich break; 4347a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich case AD7192_REG_MODE: 4357a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich if (val) 4367a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich st->mode |= AD7192_MODE_ACX; 4377a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich else 4387a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich st->mode &= ~AD7192_MODE_ACX; 4397a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich 4403f7c3306cf385d015d84c741e5433781f83d9254Lars-Peter Clausen ad_sd_write_reg(&st->sd, AD7192_REG_MODE, 3, st->mode); 4417a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich break; 4427a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich default: 4437a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich ret = -EINVAL; 4447a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich } 4457a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich 4467a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich mutex_unlock(&indio_dev->mlock); 4477a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich 4487a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich return ret ? ret : len; 4497a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich} 4507a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich 4517a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerichstatic IIO_DEVICE_ATTR(bridge_switch_en, S_IRUGO | S_IWUSR, 4527a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich ad7192_show_bridge_switch, ad7192_set, 4537a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich AD7192_REG_GPOCON); 4547a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich 4557a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerichstatic IIO_DEVICE_ATTR(ac_excitation_en, S_IRUGO | S_IWUSR, 4567a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich ad7192_show_ac_excitation, ad7192_set, 4577a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich AD7192_REG_MODE); 4587a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich 4597a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerichstatic struct attribute *ad7192_attributes[] = { 4607a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich &iio_dev_attr_sampling_frequency.dev_attr.attr, 461322c95636739420631e51f3d3f24132dc220762aJonathan Cameron &iio_dev_attr_in_v_m_v_scale_available.dev_attr.attr, 462322c95636739420631e51f3d3f24132dc220762aJonathan Cameron &iio_dev_attr_in_voltage_scale_available.dev_attr.attr, 4637a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich &iio_dev_attr_bridge_switch_en.dev_attr.attr, 4647a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich &iio_dev_attr_ac_excitation_en.dev_attr.attr, 4657a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich NULL 4667a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich}; 4677a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich 4687a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerichstatic const struct attribute_group ad7192_attribute_group = { 4697a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich .attrs = ad7192_attributes, 47015bbb7793ad7f6f106ce09fdfa3956c5aff37cf1Jonathan Cameron}; 47115bbb7793ad7f6f106ce09fdfa3956c5aff37cf1Jonathan Cameron 47215bbb7793ad7f6f106ce09fdfa3956c5aff37cf1Jonathan Cameronstatic struct attribute *ad7195_attributes[] = { 47315bbb7793ad7f6f106ce09fdfa3956c5aff37cf1Jonathan Cameron &iio_dev_attr_sampling_frequency.dev_attr.attr, 47415bbb7793ad7f6f106ce09fdfa3956c5aff37cf1Jonathan Cameron &iio_dev_attr_in_v_m_v_scale_available.dev_attr.attr, 47515bbb7793ad7f6f106ce09fdfa3956c5aff37cf1Jonathan Cameron &iio_dev_attr_in_voltage_scale_available.dev_attr.attr, 47615bbb7793ad7f6f106ce09fdfa3956c5aff37cf1Jonathan Cameron &iio_dev_attr_bridge_switch_en.dev_attr.attr, 47715bbb7793ad7f6f106ce09fdfa3956c5aff37cf1Jonathan Cameron NULL 47815bbb7793ad7f6f106ce09fdfa3956c5aff37cf1Jonathan Cameron}; 47915bbb7793ad7f6f106ce09fdfa3956c5aff37cf1Jonathan Cameron 48015bbb7793ad7f6f106ce09fdfa3956c5aff37cf1Jonathan Cameronstatic const struct attribute_group ad7195_attribute_group = { 48115bbb7793ad7f6f106ce09fdfa3956c5aff37cf1Jonathan Cameron .attrs = ad7195_attributes, 4827a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich}; 4837a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich 4844fcbcf95b775acc430742a09fb3334dce08b6c10Lars-Peter Clausenstatic unsigned int ad7192_get_temp_scale(bool unipolar) 4854fcbcf95b775acc430742a09fb3334dce08b6c10Lars-Peter Clausen{ 4864fcbcf95b775acc430742a09fb3334dce08b6c10Lars-Peter Clausen return unipolar ? 2815 * 2 : 2815; 4874fcbcf95b775acc430742a09fb3334dce08b6c10Lars-Peter Clausen} 4884fcbcf95b775acc430742a09fb3334dce08b6c10Lars-Peter Clausen 4897a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerichstatic int ad7192_read_raw(struct iio_dev *indio_dev, 4907a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich struct iio_chan_spec const *chan, 4917a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich int *val, 4927a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich int *val2, 4937a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich long m) 4947a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich{ 4957a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich struct ad7192_state *st = iio_priv(indio_dev); 4967a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich bool unipolar = !!(st->conf & AD7192_CONF_UNIPOLAR); 4977a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich 4987a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich switch (m) { 499b11f98ff8c35d62523b2bfad07df3d756113aae3Jonathan Cameron case IIO_CHAN_INFO_RAW: 5003f7c3306cf385d015d84c741e5433781f83d9254Lars-Peter Clausen return ad_sigma_delta_single_conversion(indio_dev, chan, val); 501c8a9f8056f40f6201b84fdddb49a1c62630902c5Jonathan Cameron case IIO_CHAN_INFO_SCALE: 502c8a9f8056f40f6201b84fdddb49a1c62630902c5Jonathan Cameron switch (chan->type) { 503c8a9f8056f40f6201b84fdddb49a1c62630902c5Jonathan Cameron case IIO_VOLTAGE: 504c8a9f8056f40f6201b84fdddb49a1c62630902c5Jonathan Cameron mutex_lock(&indio_dev->mlock); 505c8a9f8056f40f6201b84fdddb49a1c62630902c5Jonathan Cameron *val = st->scale_avail[AD7192_CONF_GAIN(st->conf)][0]; 506c8a9f8056f40f6201b84fdddb49a1c62630902c5Jonathan Cameron *val2 = st->scale_avail[AD7192_CONF_GAIN(st->conf)][1]; 507c8a9f8056f40f6201b84fdddb49a1c62630902c5Jonathan Cameron mutex_unlock(&indio_dev->mlock); 508c8a9f8056f40f6201b84fdddb49a1c62630902c5Jonathan Cameron return IIO_VAL_INT_PLUS_NANO; 509c8a9f8056f40f6201b84fdddb49a1c62630902c5Jonathan Cameron case IIO_TEMP: 5104fcbcf95b775acc430742a09fb3334dce08b6c10Lars-Peter Clausen *val = 0; 5114fcbcf95b775acc430742a09fb3334dce08b6c10Lars-Peter Clausen *val2 = 1000000000 / ad7192_get_temp_scale(unipolar); 5124fcbcf95b775acc430742a09fb3334dce08b6c10Lars-Peter Clausen return IIO_VAL_INT_PLUS_NANO; 513c8a9f8056f40f6201b84fdddb49a1c62630902c5Jonathan Cameron default: 514c8a9f8056f40f6201b84fdddb49a1c62630902c5Jonathan Cameron return -EINVAL; 515c8a9f8056f40f6201b84fdddb49a1c62630902c5Jonathan Cameron } 51658cdff6ee71b4ea00a6b822a52ebf9ceb0b6a7d5Lars-Peter Clausen case IIO_CHAN_INFO_OFFSET: 51758cdff6ee71b4ea00a6b822a52ebf9ceb0b6a7d5Lars-Peter Clausen if (!unipolar) 5184fcbcf95b775acc430742a09fb3334dce08b6c10Lars-Peter Clausen *val = -(1 << (chan->scan_type.realbits - 1)); 51958cdff6ee71b4ea00a6b822a52ebf9ceb0b6a7d5Lars-Peter Clausen else 52058cdff6ee71b4ea00a6b822a52ebf9ceb0b6a7d5Lars-Peter Clausen *val = 0; 5214fcbcf95b775acc430742a09fb3334dce08b6c10Lars-Peter Clausen /* Kelvin to Celsius */ 5224fcbcf95b775acc430742a09fb3334dce08b6c10Lars-Peter Clausen if (chan->type == IIO_TEMP) 5234fcbcf95b775acc430742a09fb3334dce08b6c10Lars-Peter Clausen *val -= 273 * ad7192_get_temp_scale(unipolar); 52458cdff6ee71b4ea00a6b822a52ebf9ceb0b6a7d5Lars-Peter Clausen return IIO_VAL_INT; 5257a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich } 5267a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich 5277a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich return -EINVAL; 5287a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich} 5297a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich 5307a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerichstatic int ad7192_write_raw(struct iio_dev *indio_dev, 5317a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich struct iio_chan_spec const *chan, 5327a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich int val, 5337a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich int val2, 5347a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich long mask) 5357a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich{ 5367a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich struct ad7192_state *st = iio_priv(indio_dev); 5377a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich int ret, i; 5387a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich unsigned int tmp; 5397a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich 5407a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich mutex_lock(&indio_dev->mlock); 54114555b14455f9acbdf0e500ae96140828a970796Jonathan Cameron if (iio_buffer_enabled(indio_dev)) { 5427a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich mutex_unlock(&indio_dev->mlock); 5437a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich return -EBUSY; 5447a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich } 5457a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich 5467a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich switch (mask) { 547c8a9f8056f40f6201b84fdddb49a1c62630902c5Jonathan Cameron case IIO_CHAN_INFO_SCALE: 5487a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich ret = -EINVAL; 5497a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich for (i = 0; i < ARRAY_SIZE(st->scale_avail); i++) 5507a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich if (val2 == st->scale_avail[i][1]) { 5513f7c3306cf385d015d84c741e5433781f83d9254Lars-Peter Clausen ret = 0; 5527a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich tmp = st->conf; 5537a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich st->conf &= ~AD7192_CONF_GAIN(-1); 5547a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich st->conf |= AD7192_CONF_GAIN(i); 5553f7c3306cf385d015d84c741e5433781f83d9254Lars-Peter Clausen if (tmp == st->conf) 5563f7c3306cf385d015d84c741e5433781f83d9254Lars-Peter Clausen break; 5573f7c3306cf385d015d84c741e5433781f83d9254Lars-Peter Clausen ad_sd_write_reg(&st->sd, AD7192_REG_CONF, 5583f7c3306cf385d015d84c741e5433781f83d9254Lars-Peter Clausen 3, st->conf); 5593f7c3306cf385d015d84c741e5433781f83d9254Lars-Peter Clausen ad7192_calibrate_all(st); 5603f7c3306cf385d015d84c741e5433781f83d9254Lars-Peter Clausen break; 5617a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich } 562f09906f43b8a0d52e3321db7d6f9d031097b0bc9Lars-Peter Clausen break; 5637a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich default: 5647a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich ret = -EINVAL; 5657a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich } 5667a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich 5677a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich mutex_unlock(&indio_dev->mlock); 5687a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich 5697a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich return ret; 5707a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich} 5717a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich 5727a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerichstatic int ad7192_write_raw_get_fmt(struct iio_dev *indio_dev, 5737a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich struct iio_chan_spec const *chan, 5747a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich long mask) 5757a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich{ 5767a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich return IIO_VAL_INT_PLUS_NANO; 5777a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich} 5787a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich 5797a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerichstatic const struct iio_info ad7192_info = { 5807a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich .read_raw = &ad7192_read_raw, 5817a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich .write_raw = &ad7192_write_raw, 5827a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich .write_raw_get_fmt = &ad7192_write_raw_get_fmt, 5837a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich .attrs = &ad7192_attribute_group, 5843f7c3306cf385d015d84c741e5433781f83d9254Lars-Peter Clausen .validate_trigger = ad_sd_validate_trigger, 5857a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich .driver_module = THIS_MODULE, 5867a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich}; 5877a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich 58815bbb7793ad7f6f106ce09fdfa3956c5aff37cf1Jonathan Cameronstatic const struct iio_info ad7195_info = { 58915bbb7793ad7f6f106ce09fdfa3956c5aff37cf1Jonathan Cameron .read_raw = &ad7192_read_raw, 59015bbb7793ad7f6f106ce09fdfa3956c5aff37cf1Jonathan Cameron .write_raw = &ad7192_write_raw, 59115bbb7793ad7f6f106ce09fdfa3956c5aff37cf1Jonathan Cameron .write_raw_get_fmt = &ad7192_write_raw_get_fmt, 59215bbb7793ad7f6f106ce09fdfa3956c5aff37cf1Jonathan Cameron .attrs = &ad7195_attribute_group, 5933f7c3306cf385d015d84c741e5433781f83d9254Lars-Peter Clausen .validate_trigger = ad_sd_validate_trigger, 59415bbb7793ad7f6f106ce09fdfa3956c5aff37cf1Jonathan Cameron .driver_module = THIS_MODULE, 59515bbb7793ad7f6f106ce09fdfa3956c5aff37cf1Jonathan Cameron}; 59615bbb7793ad7f6f106ce09fdfa3956c5aff37cf1Jonathan Cameron 597f4e4b9558bc696cc89de460e754d3fecb50b13cbLars-Peter Clausenstatic const struct iio_chan_spec ad7192_channels[] = { 5983f7c3306cf385d015d84c741e5433781f83d9254Lars-Peter Clausen AD_SD_DIFF_CHANNEL(0, 1, 2, AD7192_CH_AIN1P_AIN2M, 24, 32, 0), 5993f7c3306cf385d015d84c741e5433781f83d9254Lars-Peter Clausen AD_SD_DIFF_CHANNEL(1, 3, 4, AD7192_CH_AIN3P_AIN4M, 24, 32, 0), 6003f7c3306cf385d015d84c741e5433781f83d9254Lars-Peter Clausen AD_SD_TEMP_CHANNEL(2, AD7192_CH_TEMP, 24, 32, 0), 6013f7c3306cf385d015d84c741e5433781f83d9254Lars-Peter Clausen AD_SD_SHORTED_CHANNEL(3, 2, AD7192_CH_AIN2P_AIN2M, 24, 32, 0), 6023f7c3306cf385d015d84c741e5433781f83d9254Lars-Peter Clausen AD_SD_CHANNEL(4, 1, AD7192_CH_AIN1, 24, 32, 0), 6033f7c3306cf385d015d84c741e5433781f83d9254Lars-Peter Clausen AD_SD_CHANNEL(5, 2, AD7192_CH_AIN2, 24, 32, 0), 6043f7c3306cf385d015d84c741e5433781f83d9254Lars-Peter Clausen AD_SD_CHANNEL(6, 3, AD7192_CH_AIN3, 24, 32, 0), 6053f7c3306cf385d015d84c741e5433781f83d9254Lars-Peter Clausen AD_SD_CHANNEL(7, 4, AD7192_CH_AIN4, 24, 32, 0), 6067a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich IIO_CHAN_SOFT_TIMESTAMP(8), 6077a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich}; 6087a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich 6094ae1c61ff2ba4fea4e4c1a045cb1f34520608789Bill Pembertonstatic int ad7192_probe(struct spi_device *spi) 6107a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich{ 61149f8812e4d15970341f0ed320e78951cc16b596dLars-Peter Clausen const struct ad7192_platform_data *pdata = spi->dev.platform_data; 6127a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich struct ad7192_state *st; 6137a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich struct iio_dev *indio_dev; 614f6aea5543021c341f0397b191243fecca98ac595Lars-Peter Clausen int ret , voltage_uv = 0; 6157a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich 6167a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich if (!pdata) { 6177a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich dev_err(&spi->dev, "no platform data?\n"); 6187a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich return -ENODEV; 6197a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich } 6207a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich 6217a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich if (!spi->irq) { 6227a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich dev_err(&spi->dev, "no IRQ?\n"); 6237a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich return -ENODEV; 6247a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich } 6257a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich 6261e319cecdb4800e03a803e96da63091de0165ecbSachin Kamat indio_dev = devm_iio_device_alloc(&spi->dev, sizeof(*st)); 6277a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich if (indio_dev == NULL) 6287a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich return -ENOMEM; 6297a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich 6307a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich st = iio_priv(indio_dev); 6317a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich 6321e319cecdb4800e03a803e96da63091de0165ecbSachin Kamat st->reg = devm_regulator_get(&spi->dev, "vcc"); 6337a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich if (!IS_ERR(st->reg)) { 6347a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich ret = regulator_enable(st->reg); 6357a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich if (ret) 6361e319cecdb4800e03a803e96da63091de0165ecbSachin Kamat return ret; 6377a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich 6387a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich voltage_uv = regulator_get_voltage(st->reg); 6397a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich } 6407a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich 6417a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich if (pdata && pdata->vref_mv) 6427a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich st->int_vref_mv = pdata->vref_mv; 6437a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich else if (voltage_uv) 6447a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich st->int_vref_mv = voltage_uv / 1000; 6457a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich else 6467a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich dev_warn(&spi->dev, "reference voltage undefined\n"); 6477a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich 6487a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich spi_set_drvdata(spi, indio_dev); 6497a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich st->devid = spi_get_device_id(spi)->driver_data; 6507a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich indio_dev->dev.parent = &spi->dev; 6517a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich indio_dev->name = spi_get_device_id(spi)->name; 6527a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich indio_dev->modes = INDIO_DIRECT_MODE; 6537a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich indio_dev->channels = ad7192_channels; 6547a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich indio_dev->num_channels = ARRAY_SIZE(ad7192_channels); 65515bbb7793ad7f6f106ce09fdfa3956c5aff37cf1Jonathan Cameron if (st->devid == ID_AD7195) 65615bbb7793ad7f6f106ce09fdfa3956c5aff37cf1Jonathan Cameron indio_dev->info = &ad7195_info; 65715bbb7793ad7f6f106ce09fdfa3956c5aff37cf1Jonathan Cameron else 65815bbb7793ad7f6f106ce09fdfa3956c5aff37cf1Jonathan Cameron indio_dev->info = &ad7192_info; 6597a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich 6603f7c3306cf385d015d84c741e5433781f83d9254Lars-Peter Clausen ad_sd_init(&st->sd, indio_dev, spi, &ad7192_sigma_delta_info); 6617a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich 6623f7c3306cf385d015d84c741e5433781f83d9254Lars-Peter Clausen ret = ad_sd_setup_buffer_and_trigger(indio_dev); 6637a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich if (ret) 6647a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich goto error_disable_reg; 6657a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich 66649f8812e4d15970341f0ed320e78951cc16b596dLars-Peter Clausen ret = ad7192_setup(st, pdata); 6677a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich if (ret) 668a648232dc5ed840c6dab0a949450ee4cdf5830bdLars-Peter Clausen goto error_remove_trigger; 6697a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich 670d2fffd6c2fd60fe9ab63ef30758d9d43a5057549Jonathan Cameron ret = iio_device_register(indio_dev); 671d2fffd6c2fd60fe9ab63ef30758d9d43a5057549Jonathan Cameron if (ret < 0) 672a648232dc5ed840c6dab0a949450ee4cdf5830bdLars-Peter Clausen goto error_remove_trigger; 6737a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich return 0; 6747a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich 6757a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennericherror_remove_trigger: 6763f7c3306cf385d015d84c741e5433781f83d9254Lars-Peter Clausen ad_sd_cleanup_buffer_and_trigger(indio_dev); 6777a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennericherror_disable_reg: 6787a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich if (!IS_ERR(st->reg)) 6797a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich regulator_disable(st->reg); 6807a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich 6817a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich return ret; 6827a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich} 6837a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich 684447d4f29ee3fa62f13c65688bb7b74d5a9a0d767Bill Pembertonstatic int ad7192_remove(struct spi_device *spi) 6857a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich{ 6867a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich struct iio_dev *indio_dev = spi_get_drvdata(spi); 6877a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich struct ad7192_state *st = iio_priv(indio_dev); 6887a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich 689d2fffd6c2fd60fe9ab63ef30758d9d43a5057549Jonathan Cameron iio_device_unregister(indio_dev); 6903f7c3306cf385d015d84c741e5433781f83d9254Lars-Peter Clausen ad_sd_cleanup_buffer_and_trigger(indio_dev); 6917a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich 6921e319cecdb4800e03a803e96da63091de0165ecbSachin Kamat if (!IS_ERR(st->reg)) 6937a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich regulator_disable(st->reg); 6947a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich 6957a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich return 0; 6967a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich} 6977a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich 6987a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerichstatic const struct spi_device_id ad7192_id[] = { 6997a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich {"ad7190", ID_AD7190}, 7007a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich {"ad7192", ID_AD7192}, 7017a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich {"ad7195", ID_AD7195}, 7027a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich {} 7037a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich}; 70455e4390cb04e8b0fbae8983c3494c9e24132db1bLars-Peter ClausenMODULE_DEVICE_TABLE(spi, ad7192_id); 7057a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich 7067a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerichstatic struct spi_driver ad7192_driver = { 7077a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich .driver = { 7087a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich .name = "ad7192", 7097a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich .owner = THIS_MODULE, 7107a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich }, 7117a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich .probe = ad7192_probe, 712e543acf07db78cfc135e45c4ce0ed26ccf774c37Bill Pemberton .remove = ad7192_remove, 7137a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich .id_table = ad7192_id, 7147a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich}; 715ae6ae6fec3f7d6919e0146996df37b665c75f662Lars-Peter Clausenmodule_spi_driver(ad7192_driver); 7167a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael Hennerich 7177a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael HennerichMODULE_AUTHOR("Michael Hennerich <hennerich@blackfin.uclinux.org>"); 7187a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael HennerichMODULE_DESCRIPTION("Analog Devices AD7190, AD7192, AD7195 ADC"); 7197a27b042f9cf6bd6e60c236a55d7a71a64287a84Michael HennerichMODULE_LICENSE("GPL v2"); 720