Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 1f31ee35 authored by Jonathan Cameron's avatar Jonathan Cameron
Browse files

staging:iio:meter: Drop ADE7758 driver



I announced the intent to drop some of these meter drivers
on the IIO list last cycle. This device is obsolete and not easily
obtained.  No one has come forward with suitable test hardware and
the driver would need a lot of work to move out of staging.

As such I am dropping it.  We can always bring it back again
if a user / tester emerges in the future.

Signed-off-by: default avatarJonathan Cameron <Jonathan.Cameron@huawei.com>
parent d15d4be9
Loading
Loading
Loading
Loading
+0 −12
Original line number Diff line number Diff line
@@ -3,18 +3,6 @@
#
menu "Active energy metering IC"

config ADE7758
	tristate "Analog Devices ADE7758 Poly Phase Multifunction Energy Metering IC Driver"
	depends on SPI
	select IIO_TRIGGER if IIO_BUFFER
	select IIO_KFIFO_BUF if IIO_BUFFER
	help
	  Say yes here to build support for Analog Devices ADE7758 Polyphase
	  Multifunction Energy Metering IC with Per Phase Information Driver.

	  To compile this driver as a module, choose M here: the
	  module will be called ade7758.

config ADE7759
	tristate "Analog Devices ADE7759 Active Energy Metering IC Driver"
	depends on SPI
+0 −4
Original line number Diff line number Diff line
@@ -3,10 +3,6 @@
# Makefile for metering ic drivers
#

ade7758-y             := ade7758_core.o
ade7758-$(CONFIG_IIO_BUFFER) += ade7758_ring.o ade7758_trigger.o
obj-$(CONFIG_ADE7758) += ade7758.o

obj-$(CONFIG_ADE7759) += ade7759.o
obj-$(CONFIG_ADE7854) += ade7854.o
obj-$(CONFIG_ADE7854_I2C) += ade7854-i2c.o
+0 −183
Original line number Diff line number Diff line
/*
 * ADE7758 Poly Phase Multifunction Energy Metering IC driver
 *
 * Copyright 2010-2011 Analog Devices Inc.
 *
 * Licensed under the GPL-2.
 */

#ifndef _ADE7758_H
#define _ADE7758_H

#define ADE7758_AWATTHR   0x01
#define ADE7758_BWATTHR   0x02
#define ADE7758_CWATTHR   0x03
#define ADE7758_AVARHR    0x04
#define ADE7758_BVARHR    0x05
#define ADE7758_CVARHR    0x06
#define ADE7758_AVAHR     0x07
#define ADE7758_BVAHR     0x08
#define ADE7758_CVAHR     0x09
#define ADE7758_AIRMS     0x0A
#define ADE7758_BIRMS     0x0B
#define ADE7758_CIRMS     0x0C
#define ADE7758_AVRMS     0x0D
#define ADE7758_BVRMS     0x0E
#define ADE7758_CVRMS     0x0F
#define ADE7758_FREQ      0x10
#define ADE7758_TEMP      0x11
#define ADE7758_WFORM     0x12
#define ADE7758_OPMODE    0x13
#define ADE7758_MMODE     0x14
#define ADE7758_WAVMODE   0x15
#define ADE7758_COMPMODE  0x16
#define ADE7758_LCYCMODE  0x17
#define ADE7758_MASK      0x18
#define ADE7758_STATUS    0x19
#define ADE7758_RSTATUS   0x1A
#define ADE7758_ZXTOUT    0x1B
#define ADE7758_LINECYC   0x1C
#define ADE7758_SAGCYC    0x1D
#define ADE7758_SAGLVL    0x1E
#define ADE7758_VPINTLVL  0x1F
#define ADE7758_IPINTLVL  0x20
#define ADE7758_VPEAK     0x21
#define ADE7758_IPEAK     0x22
#define ADE7758_GAIN      0x23
#define ADE7758_AVRMSGAIN 0x24
#define ADE7758_BVRMSGAIN 0x25
#define ADE7758_CVRMSGAIN 0x26
#define ADE7758_AIGAIN    0x27
#define ADE7758_BIGAIN    0x28
#define ADE7758_CIGAIN    0x29
#define ADE7758_AWG       0x2A
#define ADE7758_BWG       0x2B
#define ADE7758_CWG       0x2C
#define ADE7758_AVARG     0x2D
#define ADE7758_BVARG     0x2E
#define ADE7758_CVARG     0x2F
#define ADE7758_AVAG      0x30
#define ADE7758_BVAG      0x31
#define ADE7758_CVAG      0x32
#define ADE7758_AVRMSOS   0x33
#define ADE7758_BVRMSOS   0x34
#define ADE7758_CVRMSOS   0x35
#define ADE7758_AIRMSOS   0x36
#define ADE7758_BIRMSOS   0x37
#define ADE7758_CIRMSOS   0x38
#define ADE7758_AWAITOS   0x39
#define ADE7758_BWAITOS   0x3A
#define ADE7758_CWAITOS   0x3B
#define ADE7758_AVAROS    0x3C
#define ADE7758_BVAROS    0x3D
#define ADE7758_CVAROS    0x3E
#define ADE7758_APHCAL    0x3F
#define ADE7758_BPHCAL    0x40
#define ADE7758_CPHCAL    0x41
#define ADE7758_WDIV      0x42
#define ADE7758_VADIV     0x44
#define ADE7758_VARDIV    0x43
#define ADE7758_APCFNUM   0x45
#define ADE7758_APCFDEN   0x46
#define ADE7758_VARCFNUM  0x47
#define ADE7758_VARCFDEN  0x48
#define ADE7758_CHKSUM    0x7E
#define ADE7758_VERSION   0x7F

#define ADE7758_READ_REG(a)    a
#define ADE7758_WRITE_REG(a) ((a) | 0x80)

#define ADE7758_MAX_TX    8
#define ADE7758_MAX_RX    4
#define ADE7758_STARTUP_DELAY 1000

#define AD7758_NUM_WAVSEL	5
#define AD7758_NUM_PHSEL	3
#define AD7758_NUM_WAVESRC	(AD7758_NUM_WAVSEL * AD7758_NUM_PHSEL)

#define AD7758_PHASE_A		0
#define AD7758_PHASE_B		1
#define AD7758_PHASE_C		2
#define AD7758_CURRENT		0
#define AD7758_VOLTAGE		1
#define AD7758_ACT_PWR		2
#define AD7758_REACT_PWR	3
#define AD7758_APP_PWR		4
#define AD7758_WT(p, w)		(((w) << 2) | (p))

/**
 * struct ade7758_state - device instance specific data
 * @us:			actual spi_device
 * @trig:		data ready trigger registered with iio
 * @tx:			transmit buffer
 * @rx:			receive buffer
 * @buf_lock:		mutex to protect tx, rx, read and write frequency
 **/
struct ade7758_state {
	struct spi_device	*us;
	struct iio_trigger	*trig;
	u8			*tx;
	u8			*rx;
	struct mutex		buf_lock;
	struct spi_transfer	ring_xfer[4];
	struct spi_message	ring_msg;
	/*
	 * DMA (thus cache coherency maintenance) requires the
	 * transfer buffers to live in their own cache lines.
	 */
	unsigned char		rx_buf[8] ____cacheline_aligned;
	unsigned char		tx_buf[8];

};

#ifdef CONFIG_IIO_BUFFER
/* At the moment triggers are only used for ring buffer
 * filling. This may change!
 */

void ade7758_remove_trigger(struct iio_dev *indio_dev);
int ade7758_probe_trigger(struct iio_dev *indio_dev);

ssize_t ade7758_read_data_from_ring(struct device *dev,
				    struct device_attribute *attr, char *buf);

int ade7758_configure_ring(struct iio_dev *indio_dev);
void ade7758_unconfigure_ring(struct iio_dev *indio_dev);

int ade7758_set_irq(struct device *dev, bool enable);

int ade7758_spi_write_reg_8(struct device *dev, u8 reg_address, u8 val);
int ade7758_spi_read_reg_8(struct device *dev, u8 reg_address, u8 *val);

#else /* CONFIG_IIO_BUFFER */

static inline void ade7758_remove_trigger(struct iio_dev *indio_dev)
{
}

static inline int ade7758_probe_trigger(struct iio_dev *indio_dev)
{
	return 0;
}

static int ade7758_configure_ring(struct iio_dev *indio_dev)
{
	return 0;
}

static inline void ade7758_unconfigure_ring(struct iio_dev *indio_dev)
{
}

static inline int ade7758_initialize_ring(struct iio_ring_buffer *ring)
{
	return 0;
}

static inline void ade7758_uninitialize_ring(struct iio_dev *indio_dev)
{
}

#endif /* CONFIG_IIO_BUFFER */

#endif
+0 −955

File deleted.

Preview size limit exceeded, changes collapsed.

+0 −177
Original line number Diff line number Diff line
/*
 * ADE7758 Poly Phase Multifunction Energy Metering IC driver
 *
 * Copyright 2010-2011 Analog Devices Inc.
 *
 * Licensed under the GPL-2.
 */
#include <linux/export.h>
#include <linux/interrupt.h>
#include <linux/kernel.h>
#include <linux/spi/spi.h>
#include <linux/slab.h>
#include <asm/unaligned.h>

#include <linux/iio/iio.h>
#include <linux/iio/buffer.h>
#include <linux/iio/kfifo_buf.h>
#include <linux/iio/trigger_consumer.h>
#include "ade7758.h"

/**
 * ade7758_spi_read_burst() - read data registers
 * @indio_dev: the IIO device
 **/
static int ade7758_spi_read_burst(struct iio_dev *indio_dev)
{
	struct ade7758_state *st = iio_priv(indio_dev);
	int ret;

	ret = spi_sync(st->us, &st->ring_msg);
	if (ret)
		dev_err(&st->us->dev, "problem when reading WFORM value\n");

	return ret;
}

static int ade7758_write_waveform_type(struct device *dev, unsigned int type)
{
	int ret;
	u8 reg;

	ret = ade7758_spi_read_reg_8(dev, ADE7758_WAVMODE, &reg);
	if (ret)
		goto out;

	reg &= ~0x1F;
	reg |= type & 0x1F;

	ret = ade7758_spi_write_reg_8(dev, ADE7758_WAVMODE, reg);
out:
	return ret;
}

/* Whilst this makes a lot of calls to iio_sw_ring functions - it is too device
 * specific to be rolled into the core.
 */
static irqreturn_t ade7758_trigger_handler(int irq, void *p)
{
	struct iio_poll_func *pf = p;
	struct iio_dev *indio_dev = pf->indio_dev;
	struct ade7758_state *st = iio_priv(indio_dev);
	s64 dat64[2];
	u32 *dat32 = (u32 *)dat64;

	if (!bitmap_empty(indio_dev->active_scan_mask, indio_dev->masklength))
		if (ade7758_spi_read_burst(indio_dev) >= 0)
			*dat32 = get_unaligned_be32(&st->rx_buf[5]) & 0xFFFFFF;

	iio_push_to_buffers_with_timestamp(indio_dev, dat64, pf->timestamp);

	iio_trigger_notify_done(indio_dev->trig);

	return IRQ_HANDLED;
}

/**
 * ade7758_ring_preenable() setup the parameters of the ring before enabling
 *
 * The complex nature of the setting of the number of bytes per datum is due
 * to this driver currently ensuring that the timestamp is stored at an 8
 * byte boundary.
 **/
static int ade7758_ring_preenable(struct iio_dev *indio_dev)
{
	unsigned int channel;

	if (bitmap_empty(indio_dev->active_scan_mask, indio_dev->masklength))
		return -EINVAL;

	channel = find_first_bit(indio_dev->active_scan_mask,
				 indio_dev->masklength);

	ade7758_write_waveform_type(&indio_dev->dev,
				    indio_dev->channels[channel].address);

	return 0;
}

static const struct iio_buffer_setup_ops ade7758_ring_setup_ops = {
	.preenable = &ade7758_ring_preenable,
	.postenable = &iio_triggered_buffer_postenable,
	.predisable = &iio_triggered_buffer_predisable,
	.validate_scan_mask = &iio_validate_scan_mask_onehot,
};

void ade7758_unconfigure_ring(struct iio_dev *indio_dev)
{
	iio_dealloc_pollfunc(indio_dev->pollfunc);
	iio_kfifo_free(indio_dev->buffer);
}

int ade7758_configure_ring(struct iio_dev *indio_dev)
{
	struct ade7758_state *st = iio_priv(indio_dev);
	struct iio_buffer *buffer;
	int ret = 0;

	buffer = iio_kfifo_allocate();
	if (!buffer)
		return -ENOMEM;

	iio_device_attach_buffer(indio_dev, buffer);

	indio_dev->setup_ops = &ade7758_ring_setup_ops;

	indio_dev->pollfunc = iio_alloc_pollfunc(&iio_pollfunc_store_time,
						 &ade7758_trigger_handler,
						 0,
						 indio_dev,
						 "ade7759_consumer%d",
						 indio_dev->id);
	if (!indio_dev->pollfunc) {
		ret = -ENOMEM;
		goto error_iio_kfifo_free;
	}

	indio_dev->modes |= INDIO_BUFFER_TRIGGERED;

	st->tx_buf[0] = ADE7758_READ_REG(ADE7758_RSTATUS);
	st->tx_buf[1] = 0;
	st->tx_buf[2] = 0;
	st->tx_buf[3] = 0;
	st->tx_buf[4] = ADE7758_READ_REG(ADE7758_WFORM);
	st->tx_buf[5] = 0;
	st->tx_buf[6] = 0;
	st->tx_buf[7] = 0;

	/* build spi ring message */
	st->ring_xfer[0].tx_buf = &st->tx_buf[0];
	st->ring_xfer[0].len = 1;
	st->ring_xfer[0].bits_per_word = 8;
	st->ring_xfer[0].delay_usecs = 4;
	st->ring_xfer[1].rx_buf = &st->rx_buf[1];
	st->ring_xfer[1].len = 3;
	st->ring_xfer[1].bits_per_word = 8;
	st->ring_xfer[1].cs_change = 1;

	st->ring_xfer[2].tx_buf = &st->tx_buf[4];
	st->ring_xfer[2].len = 1;
	st->ring_xfer[2].bits_per_word = 8;
	st->ring_xfer[2].delay_usecs = 1;
	st->ring_xfer[3].rx_buf = &st->rx_buf[5];
	st->ring_xfer[3].len = 3;
	st->ring_xfer[3].bits_per_word = 8;

	spi_message_init(&st->ring_msg);
	spi_message_add_tail(&st->ring_xfer[0], &st->ring_msg);
	spi_message_add_tail(&st->ring_xfer[1], &st->ring_msg);
	spi_message_add_tail(&st->ring_xfer[2], &st->ring_msg);
	spi_message_add_tail(&st->ring_xfer[3], &st->ring_msg);

	return 0;

error_iio_kfifo_free:
	iio_kfifo_free(indio_dev->buffer);
	return ret;
}
Loading