// SPDX-License-Identifier: GPL-2.0-or-later
/*
 * Holt Integrated Circuits HI-8435 threshold detector driver
 *
 * Copyright (C) 2015 Zodiac Inflight Innovations
 * Copyright (C) 2015 Cogent Embedded, Inc.
 */

#include <linux/delay.h>
#include <linux/iio/events.h>
#include <linux/iio/iio.h>
#include <linux/iio/sysfs.h>
#include <linux/iio/trigger.h>
#include <linux/iio/trigger_consumer.h>
#include <linux/iio/triggered_event.h>
#include <linux/interrupt.h>
#include <linux/module.h>
#include <linux/mod_devicetable.h>
#include <linux/spi/spi.h>
#include <linux/gpio/consumer.h>

#define DRV_NAME "hi8435"

/* Register offsets for HI-8435 */
#define HI8435_CTRL_REG		0x02
#define HI8435_PSEN_REG		0x04
#define HI8435_TMDATA_REG	0x1E
#define HI8435_GOCENHYS_REG	0x3A
#define HI8435_SOCENHYS_REG	0x3C
#define HI8435_SO7_0_REG	0x10
#define HI8435_SO15_8_REG	0x12
#define HI8435_SO23_16_REG	0x14
#define HI8435_SO31_24_REG	0x16
#define HI8435_SO31_0_REG	0x78

#define HI8435_WRITE_OPCODE	0x00
#define HI8435_READ_OPCODE	0x80

/* CTRL register bits */
#define HI8435_CTRL_TEST	0x01
#define HI8435_CTRL_SRST	0x02

struct hi8435_priv {
	struct spi_device *spi;
	struct mutex lock;

	unsigned long event_scan_mask; /* soft mask/unmask channels events */
	unsigned int event_prev_val;

	unsigned threshold_lo[2]; /* GND-Open and Supply-Open thresholds */
	unsigned threshold_hi[2]; /* GND-Open and Supply-Open thresholds */
	u8 reg_buffer[3] ____cacheline_aligned;
};

static int hi8435_readb(struct hi8435_priv *priv, u8 reg, u8 *val)
{
	reg |= HI8435_READ_OPCODE;
	return spi_write_then_read(priv->spi, &reg, 1, val, 1);
}

static int hi8435_readw(struct hi8435_priv *priv, u8 reg, u16 *val)
{
	int ret;
	__be16 be_val;

	reg |= HI8435_READ_OPCODE;
	ret = spi_write_then_read(priv->spi, &reg, 1, &be_val, 2);
	*val = be16_to_cpu(be_val);

	return ret;
}

static int hi8435_readl(struct hi8435_priv *priv, u8 reg, u32 *val)
{
	int ret;
	__be32 be_val;

	reg |= HI8435_READ_OPCODE;
	ret = spi_write_then_read(priv->spi, &reg, 1, &be_val, 4);
	*val = be32_to_cpu(be_val);

	return ret;
}

static int hi8435_writeb(struct hi8435_priv *priv, u8 reg, u8 val)
{
	priv->reg_buffer[0] = reg | HI8435_WRITE_OPCODE;
	priv->reg_buffer[1] = val;

	return spi_write(priv->spi, priv->reg_buffer, 2);
}

static int hi8435_writew(struct hi8435_priv *priv, u8 reg, u16 val)
{
	priv->reg_buffer[0] = reg | HI8435_WRITE_OPCODE;
	priv->reg_buffer[1] = (val >> 8) & 0xff;
	priv->reg_buffer[2] = val & 0xff;

	return spi_write(priv->spi, priv->reg_buffer, 3);
}

static int hi8435_read_raw(struct iio_dev *idev,
			   const struct iio_chan_spec *chan,
			   int *val, int *val2, long mask)
{
	struct hi8435_priv *priv = iio_priv(idev);
	u32 tmp;
	int ret;

	switch (mask) {
	case IIO_CHAN_INFO_RAW:
		ret = hi8435_readl(priv, HI8435_SO31_0_REG, &tmp);
		if (ret < 0)
			return ret;
		*val = !!(tmp & BIT(chan->channel));
		return IIO_VAL_INT;
	default:
		return -EINVAL;
	}
}

static int hi8435_read_event_config(struct iio_dev *idev,
				    const struct iio_chan_spec *chan,
				    enum iio_event_type type,
				    enum iio_event_direction dir)
{
	struct hi8435_priv *priv = iio_priv(idev);

	return !!(priv->event_scan_mask & BIT(chan->channel));
}

static int hi8435_write_event_config(struct iio_dev *idev,
				     const struct iio_chan_spec *chan,
				     enum iio_event_type type,
				     enum iio_event_direction dir, int state)
{
	struct hi8435_priv *priv = iio_priv(idev);
	int ret;
	u32 tmp;

	if (state) {
		ret = hi8435_readl(priv, HI8435_SO31_0_REG, &tmp);
		if (ret < 0)
			return ret;
		if (tmp & BIT(chan->channel))
			priv->event_prev_val |= BIT(chan->channel);
		else
			priv->event_prev_val &= ~BIT(chan->channel);

		priv->event_scan_mask |= BIT(chan->channel);
	} else
		priv->event_scan_mask &= ~BIT(chan->channel);

	return 0;
}

static int hi8435_read_event_value(struct iio_dev *idev,
				   const struct iio_chan_spec *chan,
				   enum iio_event_type type,
				   enum iio_event_direction dir,
				   enum iio_event_info info,
				   int *val, int *val2)
{
	struct hi8435_priv *priv = iio_priv(idev);
	int ret;
	u8 mode, psen;
	u16 reg;

	ret = hi8435_readb(priv, HI8435_PSEN_REG, &psen);
	if (ret < 0)
		return ret;

	/* Supply-Open or GND-Open sensing mode */
	mode = !!(psen & BIT(chan->channel / 8));

	ret = hi8435_readw(priv, mode ? HI8435_SOCENHYS_REG :
				 HI8435_GOCENHYS_REG, &reg);
	if (ret < 0)
		return ret;

	if (dir == IIO_EV_DIR_FALLING)
		*val = ((reg & 0xff) - (reg >> 8)) / 2;
	else if (dir == IIO_EV_DIR_RISING)
		*val = ((reg & 0xff) + (reg >> 8)) / 2;

	return IIO_VAL_INT;
}

static int hi8435_write_event_value(struct iio_dev *idev,
				    const struct iio_chan_spec *chan,
				    enum iio_event_type type,
				    enum iio_event_direction dir,
				    enum iio_event_info info,
				    int val, int val2)
{
	struct hi8435_priv *priv = iio_priv(idev);
	int ret;
	u8 mode, psen;
	u16 reg;

	ret = hi8435_readb(priv, HI8435_PSEN_REG, &psen);
	if (ret < 0)
		return ret;

	/* Supply-Open or GND-Open sensing mode */
	mode = !!(psen & BIT(chan->channel / 8));

	ret = hi8435_readw(priv, mode ? HI8435_SOCENHYS_REG :
				 HI8435_GOCENHYS_REG, &reg);
	if (ret < 0)
		return ret;

	if (dir == IIO_EV_DIR_FALLING) {
		/* falling threshold range 2..21V, hysteresis minimum 2V */
		if (val < 2 || val > 21 || (val + 2) > priv->threshold_hi[mode])
			return -EINVAL;

		if (val == priv->threshold_lo[mode])
			return 0;

		priv->threshold_lo[mode] = val;

		/* hysteresis must not be odd */
		if ((priv->threshold_hi[mode] - priv->threshold_lo[mode]) % 2)
			priv->threshold_hi[mode]--;
	} else if (dir == IIO_EV_DIR_RISING) {
		/* rising threshold range 3..22V, hysteresis minimum 2V */
		if (val < 3 || val > 22 || val < (priv->threshold_lo[mode] + 2))
			return -EINVAL;

		if (val == priv->threshold_hi[mode])
			return 0;

		priv->threshold_hi[mode] = val;

		/* hysteresis must not be odd */
		if ((priv->threshold_hi[mode] - priv->threshold_lo[mode]) % 2)
			priv->threshold_lo[mode]++;
	}

	/* program thresholds */
	mutex_lock(&priv->lock);

	ret = hi8435_readw(priv, mode ? HI8435_SOCENHYS_REG :
				 HI8435_GOCENHYS_REG, &reg);
	if (ret < 0) {
		mutex_unlock(&priv->lock);
		return ret;
	}

	/* hysteresis */
	reg = priv->threshold_hi[mode] - priv->threshold_lo[mode];
	reg <<= 8;
	/* threshold center */
	reg |= (priv->threshold_hi[mode] + priv->threshold_lo[mode]);

	ret = hi8435_writew(priv, mode ? HI8435_SOCENHYS_REG :
				  HI8435_GOCENHYS_REG, reg);

	mutex_unlock(&priv->lock);

	return ret;
}

static int hi8435_debugfs_reg_access(struct iio_dev *idev,
				     unsigned reg, unsigned writeval,
				     unsigned *readval)
{
	struct hi8435_priv *priv = iio_priv(idev);
	int ret;
	u8 val;

	if (readval != NULL) {
		ret = hi8435_readb(priv, reg, &val);
		*readval = val;
	} else {
		val = (u8)writeval;
		ret = hi8435_writeb(priv, reg, val);
	}

	return ret;
}

static const struct iio_event_spec hi8435_events[] = {
	{
		.type = IIO_EV_TYPE_THRESH,
		.dir = IIO_EV_DIR_RISING,
		.mask_separate = BIT(IIO_EV_INFO_VALUE),
	}, {
		.type = IIO_EV_TYPE_THRESH,
		.dir = IIO_EV_DIR_FALLING,
		.mask_separate = BIT(IIO_EV_INFO_VALUE),
	}, {
		.type = IIO_EV_TYPE_THRESH,
		.dir = IIO_EV_DIR_EITHER,
		.mask_separate = BIT(IIO_EV_INFO_ENABLE),
	},
};

static int hi8435_get_sensing_mode(struct iio_dev *idev,
				   const struct iio_chan_spec *chan)
{
	struct hi8435_priv *priv = iio_priv(idev);
	int ret;
	u8 reg;

	ret = hi8435_readb(priv, HI8435_PSEN_REG, &reg);
	if (ret < 0)
		return ret;

	return !!(reg & BIT(chan->channel / 8));
}

static int hi8435_set_sensing_mode(struct iio_dev *idev,
				   const struct iio_chan_spec *chan,
				   unsigned int mode)
{
	struct hi8435_priv *priv = iio_priv(idev);
	int ret;
	u8 reg;

	mutex_lock(&priv->lock);

	ret = hi8435_readb(priv, HI8435_PSEN_REG, &reg);
	if (ret < 0) {
		mutex_unlock(&priv->lock);
		return ret;
	}

	reg &= ~BIT(chan->channel / 8);
	if (mode)
		reg |= BIT(chan->channel / 8);

	ret = hi8435_writeb(priv, HI8435_PSEN_REG, reg);

	mutex_unlock(&priv->lock);

	return ret;
}

static const char * const hi8435_sensing_modes[] = { "GND-Open",
						     "Supply-Open" };

static const struct iio_enum hi8435_sensing_mode = {
	.items = hi8435_sensing_modes,
	.num_items = ARRAY_SIZE(hi8435_sensing_modes),
	.get = hi8435_get_sensing_mode,
	.set = hi8435_set_sensing_mode,
};

static const struct iio_chan_spec_ext_info hi8435_ext_info[] = {
	IIO_ENUM("sensing_mode", IIO_SEPARATE, &hi8435_sensing_mode),
	IIO_ENUM_AVAILABLE("sensing_mode", &hi8435_sensing_mode),
	{},
};

#define HI8435_VOLTAGE_CHANNEL(num)			\
{							\
	.type = IIO_VOLTAGE,				\
	.indexed = 1,					\
	.channel = num,					\
	.info_mask_separate = BIT(IIO_CHAN_INFO_RAW),	\
	.event_spec = hi8435_events,			\
	.num_event_specs = ARRAY_SIZE(hi8435_events),	\
	.ext_info = hi8435_ext_info,			\
}

static const struct iio_chan_spec hi8435_channels[] = {
	HI8435_VOLTAGE_CHANNEL(0),
	HI8435_VOLTAGE_CHANNEL(1),
	HI8435_VOLTAGE_CHANNEL(2),
	HI8435_VOLTAGE_CHANNEL(3),
	HI8435_VOLTAGE_CHANNEL(4),
	HI8435_VOLTAGE_CHANNEL(5),
	HI8435_VOLTAGE_CHANNEL(6),
	HI8435_VOLTAGE_CHANNEL(7),
	HI8435_VOLTAGE_CHANNEL(8),
	HI8435_VOLTAGE_CHANNEL(9),
	HI8435_VOLTAGE_CHANNEL(10),
	HI8435_VOLTAGE_CHANNEL(11),
	HI8435_VOLTAGE_CHANNEL(12),
	HI8435_VOLTAGE_CHANNEL(13),
	HI8435_VOLTAGE_CHANNEL(14),
	HI8435_VOLTAGE_CHANNEL(15),
	HI8435_VOLTAGE_CHANNEL(16),
	HI8435_VOLTAGE_CHANNEL(17),
	HI8435_VOLTAGE_CHANNEL(18),
	HI8435_VOLTAGE_CHANNEL(19),
	HI8435_VOLTAGE_CHANNEL(20),
	HI8435_VOLTAGE_CHANNEL(21),
	HI8435_VOLTAGE_CHANNEL(22),
	HI8435_VOLTAGE_CHANNEL(23),
	HI8435_VOLTAGE_CHANNEL(24),
	HI8435_VOLTAGE_CHANNEL(25),
	HI8435_VOLTAGE_CHANNEL(26),
	HI8435_VOLTAGE_CHANNEL(27),
	HI8435_VOLTAGE_CHANNEL(28),
	HI8435_VOLTAGE_CHANNEL(29),
	HI8435_VOLTAGE_CHANNEL(30),
	HI8435_VOLTAGE_CHANNEL(31),
	IIO_CHAN_SOFT_TIMESTAMP(32),
};

static const struct iio_info hi8435_info = {
	.read_raw = hi8435_read_raw,
	.read_event_config = hi8435_read_event_config,
	.write_event_config = hi8435_write_event_config,
	.read_event_value = hi8435_read_event_value,
	.write_event_value = hi8435_write_event_value,
	.debugfs_reg_access = hi8435_debugfs_reg_access,
};

static void hi8435_iio_push_event(struct iio_dev *idev, unsigned int val)
{
	struct hi8435_priv *priv = iio_priv(idev);
	enum iio_event_direction dir;
	unsigned int i;
	unsigned int status = priv->event_prev_val ^ val;

	if (!status)
		return;

	for_each_set_bit(i, &priv->event_scan_mask, 32) {
		if (status & BIT(i)) {
			dir = val & BIT(i) ? IIO_EV_DIR_RISING :
					     IIO_EV_DIR_FALLING;
			iio_push_event(idev,
				       IIO_UNMOD_EVENT_CODE(IIO_VOLTAGE, i,
						    IIO_EV_TYPE_THRESH, dir),
				       iio_get_time_ns(idev));
		}
	}

	priv->event_prev_val = val;
}

static irqreturn_t hi8435_trigger_handler(int irq, void *private)
{
	struct iio_poll_func *pf = private;
	struct iio_dev *idev = pf->indio_dev;
	struct hi8435_priv *priv = iio_priv(idev);
	u32 val;
	int ret;

	ret = hi8435_readl(priv, HI8435_SO31_0_REG, &val);
	if (ret < 0)
		goto err_read;

	hi8435_iio_push_event(idev, val);

err_read:
	iio_trigger_notify_done(idev->trig);

	return IRQ_HANDLED;
}

static void hi8435_triggered_event_cleanup(void *data)
{
	iio_triggered_event_cleanup(data);
}

static int hi8435_probe(struct spi_device *spi)
{
	struct iio_dev *idev;
	struct hi8435_priv *priv;
	struct gpio_desc *reset_gpio;
	int ret;

	idev = devm_iio_device_alloc(&spi->dev, sizeof(*priv));
	if (!idev)
		return -ENOMEM;

	priv = iio_priv(idev);
	priv->spi = spi;

	reset_gpio = devm_gpiod_get(&spi->dev, NULL, GPIOD_OUT_LOW);
	if (IS_ERR(reset_gpio)) {
		/* chip s/w reset if h/w reset failed */
		hi8435_writeb(priv, HI8435_CTRL_REG, HI8435_CTRL_SRST);
		hi8435_writeb(priv, HI8435_CTRL_REG, 0);
	} else {
		udelay(5);
		gpiod_set_value_cansleep(reset_gpio, 1);
	}

	mutex_init(&priv->lock);

	idev->name		= spi_get_device_id(spi)->name;
	idev->modes		= INDIO_DIRECT_MODE;
	idev->info		= &hi8435_info;
	idev->channels		= hi8435_channels;
	idev->num_channels	= ARRAY_SIZE(hi8435_channels);

	/* unmask all events */
	priv->event_scan_mask = ~(0);
	/*
	 * There is a restriction in the chip - the hysteresis can not be odd.
	 * If the hysteresis is set to odd value then chip gets into lock state
	 * and not functional anymore.
	 * After chip reset the thresholds are in undefined state, so we need to
	 * initialize thresholds to some initial values and then prevent
	 * userspace setting odd hysteresis.
	 *
	 * Set threshold low voltage to 2V, threshold high voltage to 4V
	 * for both GND-Open and Supply-Open sensing modes.
	 */
	priv->threshold_lo[0] = priv->threshold_lo[1] = 2;
	priv->threshold_hi[0] = priv->threshold_hi[1] = 4;
	hi8435_writew(priv, HI8435_GOCENHYS_REG, 0x206);
	hi8435_writew(priv, HI8435_SOCENHYS_REG, 0x206);

	ret = iio_triggered_event_setup(idev, NULL, hi8435_trigger_handler);
	if (ret)
		return ret;

	ret = devm_add_action_or_reset(&spi->dev,
				       hi8435_triggered_event_cleanup,
				       idev);
	if (ret)
		return ret;

	return devm_iio_device_register(&spi->dev, idev);
}

static const struct of_device_id hi8435_dt_ids[] = {
	{ .compatible = "holt,hi8435" },
	{},
};
MODULE_DEVICE_TABLE(of, hi8435_dt_ids);

static const struct spi_device_id hi8435_id[] = {
	{ "hi8435", 0},
	{ }
};
MODULE_DEVICE_TABLE(spi, hi8435_id);

static struct spi_driver hi8435_driver = {
	.driver	= {
		.name		= DRV_NAME,
		.of_match_table	= hi8435_dt_ids,
	},
	.probe		= hi8435_probe,
	.id_table	= hi8435_id,
};
module_spi_driver(hi8435_driver);

MODULE_LICENSE("GPL");
MODULE_AUTHOR("Vladimir Barinov");
MODULE_DESCRIPTION("HI-8435 threshold detector");
