/*
 * ADE7754 Polyphase Multifunction Energy Metering IC Driver
 *
 * Copyright 2010 Analog Devices Inc.
 *
 * 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/kernel.h>
#include <linux/spi/spi.h>
#include <linux/slab.h>
#include <linux/sysfs.h>
#include <linux/list.h>
#include <linux/module.h>

#include "../iio.h"
#include "../sysfs.h"
#include "meter.h"
#include "ade7754.h"

static int ade7754_spi_write_reg_8(struct device *dev,
		u8 reg_address,
		u8 val)
{
	int ret;
	struct iio_dev *indio_dev = dev_get_drvdata(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;

	ret = spi_write(st->us, st->tx, 2);
	mutex_unlock(&st->buf_lock);

	return ret;
}

static int ade7754_spi_write_reg_16(struct device *dev,
		u8 reg_address,
		u16 value)
{
	int ret;
	struct iio_dev *indio_dev = dev_get_drvdata(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] = (value >> 8) & 0xFF;
	st->tx[2] = value & 0xFF;
	ret = spi_write(st->us, st->tx, 3);
	mutex_unlock(&st->buf_lock);

	return ret;
}

static int ade7754_spi_read_reg_8(struct device *dev,
		u8 reg_address,
		u8 *val)
{
	struct iio_dev *indio_dev = dev_get_drvdata(dev);
	struct ade7754_state *st = iio_priv(indio_dev);
	int ret;

	ret = spi_w8r8(st->us, ADE7754_READ_REG(reg_address));
	if (ret < 0) {
		dev_err(&st->us->dev, "problem when reading 8 bit register 0x%02X",
				reg_address);
		return ret;
	}
	*val = ret;

	return 0;
}

static int ade7754_spi_read_reg_16(struct device *dev,
		u8 reg_address,
		u16 *val)
{
	struct iio_dev *indio_dev = dev_get_drvdata(dev);
	struct ade7754_state *st = iio_priv(indio_dev);
	int ret;

	ret = spi_w8r16(st->us, ADE7754_READ_REG(reg_address));
	if (ret < 0) {
		dev_err(&st->us->dev, "problem when reading 16 bit register 0x%02X",
			reg_address);
		return ret;
	}

	*val = ret;
	*val = be16_to_cpup(val);

	return 0;
}

static int ade7754_spi_read_reg_24(struct device *dev,
		u8 reg_address,
		u32 *val)
{
	struct spi_message msg;
	struct iio_dev *indio_dev = dev_get_drvdata(dev);
	struct ade7754_state *st = iio_priv(indio_dev);
	int ret;
	struct spi_transfer xfers[] = {
		{
			.tx_buf = st->tx,
			.rx_buf = st->rx,
			.bits_per_word = 8,
			.len = 4,
		},
	};

	mutex_lock(&st->buf_lock);
	st->tx[0] = ADE7754_READ_REG(reg_address);
	st->tx[1] = 0;
	st->tx[2] = 0;
	st->tx[3] = 0;

	spi_message_init(&msg);
	spi_message_add_tail(xfers, &msg);
	ret = spi_sync(st->us, &msg);
	if (ret) {
		dev_err(&st->us->dev, "problem when reading 24 bit register 0x%02X",
				reg_address);
		goto error_ret;
	}
	*val = (st->rx[1] << 16) | (st->rx[2] << 8) | st->rx[3];

error_ret:
	mutex_unlock(&st->buf_lock);
	return ret;
}

static ssize_t ade7754_read_8bit(struct device *dev,
		struct device_attribute *attr,
		char *buf)
{
	int ret;
	u8 val = 0;
	struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);

	ret = ade7754_spi_read_reg_8(dev, this_attr->address, &val);
	if (ret)
		return ret;

	return sprintf(buf, "%u\n", val);
}

static ssize_t ade7754_read_16bit(struct device *dev,
		struct device_attribute *attr,
		char *buf)
{
	int ret;
	u16 val = 0;
	struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);

	ret = ade7754_spi_read_reg_16(dev, this_attr->address, &val);
	if (ret)
		return ret;

	return sprintf(buf, "%u\n", val);
}

static ssize_t ade7754_read_24bit(struct device *dev,
		struct device_attribute *attr,
		char *buf)
{
	int ret;
	u32 val = 0;
	struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);

	ret = ade7754_spi_read_reg_24(dev, this_attr->address, &val);
	if (ret)
		return ret;

	return sprintf(buf, "%u\n", val & 0xFFFFFF);
}

static ssize_t ade7754_write_8bit(struct device *dev,
		struct device_attribute *attr,
		const char *buf,
		size_t len)
{
	struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
	int ret;
	long val;

	ret = strict_strtol(buf, 10, &val);
	if (ret)
		goto error_ret;
	ret = ade7754_spi_write_reg_8(dev, this_attr->address, val);

error_ret:
	return ret ? ret : len;
}

static ssize_t ade7754_write_16bit(struct device *dev,
		struct device_attribute *attr,
		const char *buf,
		size_t len)
{
	struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
	int ret;
	long val;

	ret = strict_strtol(buf, 10, &val);
	if (ret)
		goto error_ret;
	ret = ade7754_spi_write_reg_16(dev, this_attr->address, val);

error_ret:
	return ret ? ret : len;
}

static int ade7754_reset(struct device *dev)
{
	u8 val;

	ade7754_spi_read_reg_8(dev, ADE7754_OPMODE, &val);
	val |= 1 << 6; /* Software Chip Reset */
	return ade7754_spi_write_reg_8(dev, ADE7754_OPMODE, val);
}


static ssize_t ade7754_write_reset(struct device *dev,
		struct device_attribute *attr,
		const char *buf, size_t len)
{
	if (len < 1)
		return -1;
	switch (buf[0]) {
	case '1':
	case 'y':
	case 'Y':
		return ade7754_reset(dev);
	}
	return -1;
}

static IIO_DEV_ATTR_AENERGY(ade7754_read_24bit, ADE7754_AENERGY);
static IIO_DEV_ATTR_LAENERGY(ade7754_read_24bit, ADE7754_LAENERGY);
static IIO_DEV_ATTR_VAENERGY(ade7754_read_24bit, ADE7754_VAENERGY);
static IIO_DEV_ATTR_LVAENERGY(ade7754_read_24bit, ADE7754_LVAENERGY);
static IIO_DEV_ATTR_VPEAK(S_IWUSR | S_IRUGO,
		ade7754_read_8bit,
		ade7754_write_8bit,
		ADE7754_VPEAK);
static IIO_DEV_ATTR_IPEAK(S_IWUSR | S_IRUGO,
		ade7754_read_8bit,
		ade7754_write_8bit,
		ADE7754_VPEAK);
static IIO_DEV_ATTR_APHCAL(S_IWUSR | S_IRUGO,
		ade7754_read_8bit,
		ade7754_write_8bit,
		ADE7754_APHCAL);
static IIO_DEV_ATTR_BPHCAL(S_IWUSR | S_IRUGO,
		ade7754_read_8bit,
		ade7754_write_8bit,
		ADE7754_BPHCAL);
static IIO_DEV_ATTR_CPHCAL(S_IWUSR | S_IRUGO,
		ade7754_read_8bit,
		ade7754_write_8bit,
		ADE7754_CPHCAL);
static IIO_DEV_ATTR_AAPOS(S_IWUSR | S_IRUGO,
		ade7754_read_16bit,
		ade7754_write_16bit,
		ADE7754_AAPOS);
static IIO_DEV_ATTR_BAPOS(S_IWUSR | S_IRUGO,
		ade7754_read_16bit,
		ade7754_write_16bit,
		ADE7754_BAPOS);
static IIO_DEV_ATTR_CAPOS(S_IWUSR | S_IRUGO,
		ade7754_read_16bit,
		ade7754_write_16bit,
		ADE7754_CAPOS);
static IIO_DEV_ATTR_WDIV(S_IWUSR | S_IRUGO,
		ade7754_read_8bit,
		ade7754_write_8bit,
		ADE7754_WDIV);
static IIO_DEV_ATTR_VADIV(S_IWUSR | S_IRUGO,
		ade7754_read_8bit,
		ade7754_write_8bit,
		ADE7754_VADIV);
static IIO_DEV_ATTR_CFNUM(S_IWUSR | S_IRUGO,
		ade7754_read_16bit,
		ade7754_write_16bit,
		ADE7754_CFNUM);
static IIO_DEV_ATTR_CFDEN(S_IWUSR | S_IRUGO,
		ade7754_read_16bit,
		ade7754_write_16bit,
		ADE7754_CFDEN);
static IIO_DEV_ATTR_ACTIVE_POWER_A_GAIN(S_IWUSR | S_IRUGO,
		ade7754_read_16bit,
		ade7754_write_16bit,
		ADE7754_AAPGAIN);
static IIO_DEV_ATTR_ACTIVE_POWER_B_GAIN(S_IWUSR | S_IRUGO,
		ade7754_read_16bit,
		ade7754_write_16bit,
		ADE7754_BAPGAIN);
static IIO_DEV_ATTR_ACTIVE_POWER_C_GAIN(S_IWUSR | S_IRUGO,
		ade7754_read_16bit,
		ade7754_write_16bit,
		ADE7754_CAPGAIN);
static IIO_DEV_ATTR_AIRMS(S_IRUGO,
		ade7754_read_24bit,
		NULL,
		ADE7754_AIRMS);
static IIO_DEV_ATTR_BIRMS(S_IRUGO,
		ade7754_read_24bit,
		NULL,
		ADE7754_BIRMS);
static IIO_DEV_ATTR_CIRMS(S_IRUGO,
		ade7754_read_24bit,
		NULL,
		ADE7754_CIRMS);
static IIO_DEV_ATTR_AVRMS(S_IRUGO,
		ade7754_read_24bit,
		NULL,
		ADE7754_AVRMS);
static IIO_DEV_ATTR_BVRMS(S_IRUGO,
		ade7754_read_24bit,
		NULL,
		ADE7754_BVRMS);
static IIO_DEV_ATTR_CVRMS(S_IRUGO,
		ade7754_read_24bit,
		NULL,
		ADE7754_CVRMS);
static IIO_DEV_ATTR_AIRMSOS(S_IRUGO,
		ade7754_read_16bit,
		ade7754_write_16bit,
		ADE7754_AIRMSOS);
static IIO_DEV_ATTR_BIRMSOS(S_IRUGO,
		ade7754_read_16bit,
		ade7754_write_16bit,
		ADE7754_BIRMSOS);
static IIO_DEV_ATTR_CIRMSOS(S_IRUGO,
		ade7754_read_16bit,
		ade7754_write_16bit,
		ADE7754_CIRMSOS);
static IIO_DEV_ATTR_AVRMSOS(S_IRUGO,
		ade7754_read_16bit,
		ade7754_write_16bit,
		ADE7754_AVRMSOS);
static IIO_DEV_ATTR_BVRMSOS(S_IRUGO,
		ade7754_read_16bit,
		ade7754_write_16bit,
		ADE7754_BVRMSOS);
static IIO_DEV_ATTR_CVRMSOS(S_IRUGO,
		ade7754_read_16bit,
		ade7754_write_16bit,
		ADE7754_CVRMSOS);

static int ade7754_set_irq(struct device *dev, bool enable)
{
	int ret;
	u16 irqen;
	ret = ade7754_spi_read_reg_16(dev, ADE7754_IRQEN, &irqen);
	if (ret)
		goto error_ret;

	if (enable)
		irqen |= 1 << 14; /* Enables an interrupt when a data is
				     present in the waveform register */
	else
		irqen &= ~(1 << 14);

	ret = ade7754_spi_write_reg_16(dev, ADE7754_IRQEN, irqen);
	if (ret)
		goto error_ret;

error_ret:
	return ret;
}

/* Power down the device */
static int ade7754_stop_device(struct device *dev)
{
	u8 val;

	ade7754_spi_read_reg_8(dev, ADE7754_OPMODE, &val);
	val |= 7 << 3;  /* ADE7754 powered down */
	return ade7754_spi_write_reg_8(dev, ADE7754_OPMODE, val);
}

static int ade7754_initial_setup(struct iio_dev *indio_dev)
{
	int ret;
	struct ade7754_state *st = iio_priv(indio_dev);
	struct device *dev = &indio_dev->dev;

	/* use low spi speed for init */
	st->us->mode = SPI_MODE_3;
	spi_setup(st->us);

	/* Disable IRQ */
	ret = ade7754_set_irq(dev, false);
	if (ret) {
		dev_err(dev, "disable irq failed");
		goto err_ret;
	}

	ade7754_reset(dev);
	msleep(ADE7754_STARTUP_DELAY);

err_ret:
	return ret;
}

static ssize_t ade7754_read_frequency(struct device *dev,
		struct device_attribute *attr,
		char *buf)
{
	int ret;
	u8 t;
	int sps;
	ret = ade7754_spi_read_reg_8(dev,
			ADE7754_WAVMODE,
			&t);
	if (ret)
		return ret;

	t = (t >> 3) & 0x3;
	sps = 26000 / (1 + t);

	return sprintf(buf, "%d\n", sps);
}

static ssize_t ade7754_write_frequency(struct device *dev,
		struct device_attribute *attr,
		const char *buf,
		size_t len)
{
	struct iio_dev *indio_dev = dev_get_drvdata(dev);
	struct ade7754_state *st = iio_priv(indio_dev);
	unsigned long val;
	int ret;
	u8 reg, t;

	ret = strict_strtol(buf, 10, &val);
	if (ret)
		return ret;

	mutex_lock(&indio_dev->mlock);

	t = (26000 / val);
	if (t > 0)
		t--;

	if (t > 1)
		st->us->max_speed_hz = ADE7754_SPI_SLOW;
	else
		st->us->max_speed_hz = ADE7754_SPI_FAST;

	ret = ade7754_spi_read_reg_8(dev, ADE7754_WAVMODE, &reg);
	if (ret)
		goto out;

	reg &= ~(3 << 3);
	reg |= t << 3;

	ret = ade7754_spi_write_reg_8(dev, ADE7754_WAVMODE, reg);

out:
	mutex_unlock(&indio_dev->mlock);

	return ret ? ret : len;
}
static IIO_DEV_ATTR_TEMP_RAW(ade7754_read_8bit);
static IIO_CONST_ATTR(in_temp_offset, "129 C");
static IIO_CONST_ATTR(in_temp_scale, "4 C");

static IIO_DEV_ATTR_SAMP_FREQ(S_IWUSR | S_IRUGO,
		ade7754_read_frequency,
		ade7754_write_frequency);

static IIO_DEV_ATTR_RESET(ade7754_write_reset);

static IIO_CONST_ATTR_SAMP_FREQ_AVAIL("26000 13000 65000 33000");

static struct attribute *ade7754_attributes[] = {
	&iio_dev_attr_in_temp_raw.dev_attr.attr,
	&iio_const_attr_in_temp_offset.dev_attr.attr,
	&iio_const_attr_in_temp_scale.dev_attr.attr,
	&iio_dev_attr_sampling_frequency.dev_attr.attr,
	&iio_const_attr_sampling_frequency_available.dev_attr.attr,
	&iio_dev_attr_reset.dev_attr.attr,
	&iio_dev_attr_aenergy.dev_attr.attr,
	&iio_dev_attr_laenergy.dev_attr.attr,
	&iio_dev_attr_vaenergy.dev_attr.attr,
	&iio_dev_attr_lvaenergy.dev_attr.attr,
	&iio_dev_attr_vpeak.dev_attr.attr,
	&iio_dev_attr_ipeak.dev_attr.attr,
	&iio_dev_attr_aphcal.dev_attr.attr,
	&iio_dev_attr_bphcal.dev_attr.attr,
	&iio_dev_attr_cphcal.dev_attr.attr,
	&iio_dev_attr_aapos.dev_attr.attr,
	&iio_dev_attr_bapos.dev_attr.attr,
	&iio_dev_attr_capos.dev_attr.attr,
	&iio_dev_attr_wdiv.dev_attr.attr,
	&iio_dev_attr_vadiv.dev_attr.attr,
	&iio_dev_attr_cfnum.dev_attr.attr,
	&iio_dev_attr_cfden.dev_attr.attr,
	&iio_dev_attr_active_power_a_gain.dev_attr.attr,
	&iio_dev_attr_active_power_b_gain.dev_attr.attr,
	&iio_dev_attr_active_power_c_gain.dev_attr.attr,
	&iio_dev_attr_airms.dev_attr.attr,
	&iio_dev_attr_birms.dev_attr.attr,
	&iio_dev_attr_cirms.dev_attr.attr,
	&iio_dev_attr_avrms.dev_attr.attr,
	&iio_dev_attr_bvrms.dev_attr.attr,
	&iio_dev_attr_cvrms.dev_attr.attr,
	&iio_dev_attr_airmsos.dev_attr.attr,
	&iio_dev_attr_birmsos.dev_attr.attr,
	&iio_dev_attr_cirmsos.dev_attr.attr,
	&iio_dev_attr_avrmsos.dev_attr.attr,
	&iio_dev_attr_bvrmsos.dev_attr.attr,
	&iio_dev_attr_cvrmsos.dev_attr.attr,
	NULL,
};

static const struct attribute_group ade7754_attribute_group = {
	.attrs = ade7754_attributes,
};

static const struct iio_info ade7754_info = {
	.attrs = &ade7754_attribute_group,
	.driver_module = THIS_MODULE,
};

static int __devinit ade7754_probe(struct spi_device *spi)
{
	int ret;
	struct ade7754_state *st;
	struct iio_dev *indio_dev;

	/* setup the industrialio driver allocated elements */
	indio_dev = iio_allocate_device(sizeof(*st));
	if (indio_dev == NULL) {
		ret = -ENOMEM;
		goto error_ret;
	}
	/* this is only used for removal purposes */
	spi_set_drvdata(spi, indio_dev);

	st = iio_priv(indio_dev);
	st->us = spi;
	mutex_init(&st->buf_lock);

	indio_dev->name = spi->dev.driver->name;
	indio_dev->dev.parent = &spi->dev;
	indio_dev->info = &ade7754_info;
	indio_dev->modes = INDIO_DIRECT_MODE;

	/* Get the device into a sane initial state */
	ret = ade7754_initial_setup(indio_dev);
	if (ret)
		goto error_free_dev;
	ret = iio_device_register(indio_dev);
	if (ret)
		goto error_free_dev;

	return 0;

error_free_dev:
	iio_free_device(indio_dev);

error_ret:
	return ret;
}

/* fixme, confirm ordering in this function */
static int ade7754_remove(struct spi_device *spi)
{
	int ret;
	struct iio_dev *indio_dev = spi_get_drvdata(spi);

	iio_device_unregister(indio_dev);
	ret = ade7754_stop_device(&(indio_dev->dev));
	if (ret)
		goto err_ret;

	iio_free_device(indio_dev);

err_ret:
	return ret;

}

static struct spi_driver ade7754_driver = {
	.driver = {
		.name = "ade7754",
		.owner = THIS_MODULE,
	},
	.probe = ade7754_probe,
	.remove = __devexit_p(ade7754_remove),
};
module_spi_driver(ade7754_driver);

MODULE_AUTHOR("Barry Song <21cnbao@gmail.com>");
MODULE_DESCRIPTION("Analog Devices ADE7754 Polyphase Multifunction Energy Metering IC Driver");
MODULE_LICENSE("GPL v2");
MODULE_ALIAS("spi:ad7754");
