diff options
Diffstat (limited to 'drivers/staging/iio/meter/ade7754.c')
-rw-r--r-- | drivers/staging/iio/meter/ade7754.c | 124 |
1 files changed, 107 insertions, 17 deletions
diff --git a/drivers/staging/iio/meter/ade7754.c b/drivers/staging/iio/meter/ade7754.c index 024463a11c47..32dc50341746 100644 --- a/drivers/staging/iio/meter/ade7754.c +++ b/drivers/staging/iio/meter/ade7754.c @@ -6,34 +6,126 @@ * Licensed under the GPL-2 or later. */ -#include <linux/interrupt.h> -#include <linux/irq.h> #include <linux/delay.h> -#include <linux/mutex.h> #include <linux/device.h> +#include <linux/interrupt.h> +#include <linux/irq.h> #include <linux/kernel.h> +#include <linux/list.h> +#include <linux/module.h> +#include <linux/mutex.h> #include <linux/spi/spi.h> #include <linux/slab.h> #include <linux/sysfs.h> -#include <linux/list.h> -#include <linux/module.h> - #include <linux/iio/iio.h> #include <linux/iio/sysfs.h> #include "meter.h" -#include "ade7754.h" -static int ade7754_spi_write_reg_8(struct device *dev, u8 reg_address, u8 val) +#define ADE7754_AENERGY 0x01 +#define ADE7754_RAENERGY 0x02 +#define ADE7754_LAENERGY 0x03 +#define ADE7754_VAENERGY 0x04 +#define ADE7754_RVAENERGY 0x05 +#define ADE7754_LVAENERGY 0x06 +#define ADE7754_PERIOD 0x07 +#define ADE7754_TEMP 0x08 +#define ADE7754_WFORM 0x09 +#define ADE7754_OPMODE 0x0A +#define ADE7754_MMODE 0x0B +#define ADE7754_WAVMODE 0x0C +#define ADE7754_WATMODE 0x0D +#define ADE7754_VAMODE 0x0E +#define ADE7754_IRQEN 0x0F +#define ADE7754_STATUS 0x10 +#define ADE7754_RSTATUS 0x11 +#define ADE7754_ZXTOUT 0x12 +#define ADE7754_LINCYC 0x13 +#define ADE7754_SAGCYC 0x14 +#define ADE7754_SAGLVL 0x15 +#define ADE7754_VPEAK 0x16 +#define ADE7754_IPEAK 0x17 +#define ADE7754_GAIN 0x18 +#define ADE7754_AWG 0x19 +#define ADE7754_BWG 0x1A +#define ADE7754_CWG 0x1B +#define ADE7754_AVAG 0x1C +#define ADE7754_BVAG 0x1D +#define ADE7754_CVAG 0x1E +#define ADE7754_APHCAL 0x1F +#define ADE7754_BPHCAL 0x20 +#define ADE7754_CPHCAL 0x21 +#define ADE7754_AAPOS 0x22 +#define ADE7754_BAPOS 0x23 +#define ADE7754_CAPOS 0x24 +#define ADE7754_CFNUM 0x25 +#define ADE7754_CFDEN 0x26 +#define ADE7754_WDIV 0x27 +#define ADE7754_VADIV 0x28 +#define ADE7754_AIRMS 0x29 +#define ADE7754_BIRMS 0x2A +#define ADE7754_CIRMS 0x2B +#define ADE7754_AVRMS 0x2C +#define ADE7754_BVRMS 0x2D +#define ADE7754_CVRMS 0x2E +#define ADE7754_AIRMSOS 0x2F +#define ADE7754_BIRMSOS 0x30 +#define ADE7754_CIRMSOS 0x31 +#define ADE7754_AVRMSOS 0x32 +#define ADE7754_BVRMSOS 0x33 +#define ADE7754_CVRMSOS 0x34 +#define ADE7754_AAPGAIN 0x35 +#define ADE7754_BAPGAIN 0x36 +#define ADE7754_CAPGAIN 0x37 +#define ADE7754_AVGAIN 0x38 +#define ADE7754_BVGAIN 0x39 +#define ADE7754_CVGAIN 0x3A +#define ADE7754_CHKSUM 0x3E +#define ADE7754_VERSION 0x3F + +#define ADE7754_READ_REG(a) a +#define ADE7754_WRITE_REG(a) ((a) | 0x80) + +#define ADE7754_MAX_TX 4 +#define ADE7754_MAX_RX 4 +#define ADE7754_STARTUP_DELAY 1000 + +#define ADE7754_SPI_SLOW (u32)(300 * 1000) +#define ADE7754_SPI_BURST (u32)(1000 * 1000) +#define ADE7754_SPI_FAST (u32)(2000 * 1000) + +/** + * struct ade7754_state - device instance specific data + * @us: actual spi_device + * @buf_lock: mutex to protect tx, rx and write frequency + * @tx: transmit buffer + * @rx: receive buffer + **/ +struct ade7754_state { + struct spi_device *us; + struct mutex buf_lock; + u8 tx[ADE7754_MAX_TX] ____cacheline_aligned; + u8 rx[ADE7754_MAX_RX]; +}; + +/* Unlocked version of ade7754_spi_write_reg_8 function */ +static int __ade7754_spi_write_reg_8(struct device *dev, u8 reg_address, u8 val) { - int ret; struct iio_dev *indio_dev = dev_to_iio_dev(dev); struct ade7754_state *st = iio_priv(indio_dev); - mutex_lock(&st->buf_lock); st->tx[0] = ADE7754_WRITE_REG(reg_address); st->tx[1] = val; + return spi_write(st->us, st->tx, 2); +} + +static int ade7754_spi_write_reg_8(struct device *dev, u8 reg_address, u8 val) +{ + int ret; + struct iio_dev *indio_dev = dev_to_iio_dev(dev); + struct ade7754_state *st = iio_priv(indio_dev); - ret = spi_write(st->us, st->tx, 2); + mutex_lock(&st->buf_lock); + ret = __ade7754_spi_write_reg_8(dev, reg_address, val); mutex_unlock(&st->buf_lock); return ret; @@ -349,9 +441,7 @@ static int ade7754_set_irq(struct device *dev, bool enable) else irqen &= ~BIT(14); - ret = ade7754_spi_write_reg_16(dev, ADE7754_IRQEN, irqen); - - return ret; + return ade7754_spi_write_reg_16(dev, ADE7754_IRQEN, irqen); } /* Power down the device */ @@ -430,7 +520,7 @@ static ssize_t ade7754_write_frequency(struct device *dev, if (!val) return -EINVAL; - mutex_lock(&indio_dev->mlock); + mutex_lock(&st->buf_lock); t = 26000 / val; if (t > 0) @@ -448,10 +538,10 @@ static ssize_t ade7754_write_frequency(struct device *dev, reg &= ~(3 << 3); reg |= t << 3; - ret = ade7754_spi_write_reg_8(dev, ADE7754_WAVMODE, reg); + ret = __ade7754_spi_write_reg_8(dev, ADE7754_WAVMODE, reg); out: - mutex_unlock(&indio_dev->mlock); + mutex_unlock(&st->buf_lock); return ret ? ret : len; } |