// SPDX-License-Identifier: GPL-2.0+
/*
 * as3935.c - Support for AS3935 Franklin lightning sensor
 *
 * Copyright (C) 2014, 2017-2018
 * Author: Matt Ranostay <matt.ranostay@konsulko.com>
 */

#include <linux/module.h>
#include <linux/mod_devicetable.h>
#include <linux/init.h>
#include <linux/interrupt.h>
#include <linux/delay.h>
#include <linux/workqueue.h>
#include <linux/mutex.h>
#include <linux/err.h>
#include <linux/irq.h>
#include <linux/spi/spi.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/buffer.h>
#include <linux/iio/triggered_buffer.h>

#define AS3935_AFE_GAIN		0x00
#define AS3935_AFE_MASK		0x3F
#define AS3935_AFE_GAIN_MAX	0x1F
#define AS3935_AFE_PWR_BIT	BIT(0)

#define AS3935_NFLWDTH		0x01
#define AS3935_NFLWDTH_MASK	0x7f

#define AS3935_INT		0x03
#define AS3935_INT_MASK		0x0f
#define AS3935_DISTURB_INT	BIT(2)
#define AS3935_EVENT_INT	BIT(3)
#define AS3935_NOISE_INT	BIT(0)

#define AS3935_DATA		0x07
#define AS3935_DATA_MASK	0x3F

#define AS3935_TUNE_CAP		0x08
#define AS3935_DEFAULTS		0x3C
#define AS3935_CALIBRATE	0x3D

#define AS3935_READ_DATA	BIT(14)
#define AS3935_ADDRESS(x)	((x) << 8)

#define MAX_PF_CAP		120
#define TUNE_CAP_DIV		8

struct as3935_state {
	struct spi_device *spi;
	struct iio_trigger *trig;
	struct mutex lock;
	struct delayed_work work;

	unsigned long noise_tripped;
	u32 tune_cap;
	u32 nflwdth_reg;
	u8 buffer[16]; /* 8-bit data + 56-bit padding + 64-bit timestamp */
	u8 buf[2] ____cacheline_aligned;
};

static const struct iio_chan_spec as3935_channels[] = {
	{
		.type           = IIO_PROXIMITY,
		.info_mask_separate =
			BIT(IIO_CHAN_INFO_RAW) |
			BIT(IIO_CHAN_INFO_PROCESSED) |
			BIT(IIO_CHAN_INFO_SCALE),
		.scan_index     = 0,
		.scan_type = {
			.sign           = 'u',
			.realbits       = 6,
			.storagebits    = 8,
		},
	},
	IIO_CHAN_SOFT_TIMESTAMP(1),
};

static int as3935_read(struct as3935_state *st, unsigned int reg, int *val)
{
	u8 cmd;
	int ret;

	cmd = (AS3935_READ_DATA | AS3935_ADDRESS(reg)) >> 8;
	ret = spi_w8r8(st->spi, cmd);
	if (ret < 0)
		return ret;
	*val = ret;

	return 0;
}

static int as3935_write(struct as3935_state *st,
				unsigned int reg,
				unsigned int val)
{
	u8 *buf = st->buf;

	buf[0] = AS3935_ADDRESS(reg) >> 8;
	buf[1] = val;

	return spi_write(st->spi, buf, 2);
}

static ssize_t as3935_sensor_sensitivity_show(struct device *dev,
					struct device_attribute *attr,
					char *buf)
{
	struct as3935_state *st = iio_priv(dev_to_iio_dev(dev));
	int val, ret;

	ret = as3935_read(st, AS3935_AFE_GAIN, &val);
	if (ret)
		return ret;
	val = (val & AS3935_AFE_MASK) >> 1;

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

static ssize_t as3935_sensor_sensitivity_store(struct device *dev,
					struct device_attribute *attr,
					const char *buf, size_t len)
{
	struct as3935_state *st = iio_priv(dev_to_iio_dev(dev));
	unsigned long val;
	int ret;

	ret = kstrtoul((const char *) buf, 10, &val);
	if (ret)
		return -EINVAL;

	if (val > AS3935_AFE_GAIN_MAX)
		return -EINVAL;

	as3935_write(st, AS3935_AFE_GAIN, val << 1);

	return len;
}

static ssize_t as3935_noise_level_tripped_show(struct device *dev,
					struct device_attribute *attr,
					char *buf)
{
	struct as3935_state *st = iio_priv(dev_to_iio_dev(dev));
	int ret;

	mutex_lock(&st->lock);
	ret = sprintf(buf, "%d\n", !time_after(jiffies, st->noise_tripped + HZ));
	mutex_unlock(&st->lock);

	return ret;
}

static IIO_DEVICE_ATTR(sensor_sensitivity, S_IRUGO | S_IWUSR,
	as3935_sensor_sensitivity_show, as3935_sensor_sensitivity_store, 0);

static IIO_DEVICE_ATTR(noise_level_tripped, S_IRUGO,
	as3935_noise_level_tripped_show, NULL, 0);

static struct attribute *as3935_attributes[] = {
	&iio_dev_attr_sensor_sensitivity.dev_attr.attr,
	&iio_dev_attr_noise_level_tripped.dev_attr.attr,
	NULL,
};

static const struct attribute_group as3935_attribute_group = {
	.attrs = as3935_attributes,
};

static int as3935_read_raw(struct iio_dev *indio_dev,
			   struct iio_chan_spec const *chan,
			   int *val,
			   int *val2,
			   long m)
{
	struct as3935_state *st = iio_priv(indio_dev);
	int ret;


	switch (m) {
	case IIO_CHAN_INFO_PROCESSED:
	case IIO_CHAN_INFO_RAW:
		*val2 = 0;
		ret = as3935_read(st, AS3935_DATA, val);
		if (ret)
			return ret;

		/* storm out of range */
		if (*val == AS3935_DATA_MASK)
			return -EINVAL;

		if (m == IIO_CHAN_INFO_RAW)
			return IIO_VAL_INT;

		if (m == IIO_CHAN_INFO_PROCESSED)
			*val *= 1000;
		break;
	case IIO_CHAN_INFO_SCALE:
		*val = 1000;
		break;
	default:
		return -EINVAL;
	}

	return IIO_VAL_INT;
}

static const struct iio_info as3935_info = {
	.attrs = &as3935_attribute_group,
	.read_raw = &as3935_read_raw,
};

static irqreturn_t as3935_trigger_handler(int irq, void *private)
{
	struct iio_poll_func *pf = private;
	struct iio_dev *indio_dev = pf->indio_dev;
	struct as3935_state *st = iio_priv(indio_dev);
	int val, ret;

	ret = as3935_read(st, AS3935_DATA, &val);
	if (ret)
		goto err_read;

	st->buffer[0] = val & AS3935_DATA_MASK;
	iio_push_to_buffers_with_timestamp(indio_dev, &st->buffer,
					   iio_get_time_ns(indio_dev));
err_read:
	iio_trigger_notify_done(indio_dev->trig);

	return IRQ_HANDLED;
}

static const struct iio_trigger_ops iio_interrupt_trigger_ops = {
};

static void as3935_event_work(struct work_struct *work)
{
	struct as3935_state *st;
	int val;
	int ret;

	st = container_of(work, struct as3935_state, work.work);

	ret = as3935_read(st, AS3935_INT, &val);
	if (ret) {
		dev_warn(&st->spi->dev, "read error\n");
		return;
	}

	val &= AS3935_INT_MASK;

	switch (val) {
	case AS3935_EVENT_INT:
		iio_trigger_poll_chained(st->trig);
		break;
	case AS3935_DISTURB_INT:
	case AS3935_NOISE_INT:
		mutex_lock(&st->lock);
		st->noise_tripped = jiffies;
		mutex_unlock(&st->lock);
		dev_warn(&st->spi->dev, "noise level is too high\n");
		break;
	}
}

static irqreturn_t as3935_interrupt_handler(int irq, void *private)
{
	struct iio_dev *indio_dev = private;
	struct as3935_state *st = iio_priv(indio_dev);

	/*
	 * Delay work for >2 milliseconds after an interrupt to allow
	 * estimated distance to recalculated.
	 */

	schedule_delayed_work(&st->work, msecs_to_jiffies(3));

	return IRQ_HANDLED;
}

static void calibrate_as3935(struct as3935_state *st)
{
	as3935_write(st, AS3935_DEFAULTS, 0x96);
	as3935_write(st, AS3935_CALIBRATE, 0x96);
	as3935_write(st, AS3935_TUNE_CAP,
		BIT(5) | (st->tune_cap / TUNE_CAP_DIV));

	mdelay(2);
	as3935_write(st, AS3935_TUNE_CAP, (st->tune_cap / TUNE_CAP_DIV));
	as3935_write(st, AS3935_NFLWDTH, st->nflwdth_reg);
}

#ifdef CONFIG_PM_SLEEP
static int as3935_suspend(struct device *dev)
{
	struct iio_dev *indio_dev = dev_get_drvdata(dev);
	struct as3935_state *st = iio_priv(indio_dev);
	int val, ret;

	mutex_lock(&st->lock);
	ret = as3935_read(st, AS3935_AFE_GAIN, &val);
	if (ret)
		goto err_suspend;
	val |= AS3935_AFE_PWR_BIT;

	ret = as3935_write(st, AS3935_AFE_GAIN, val);

err_suspend:
	mutex_unlock(&st->lock);

	return ret;
}

static int as3935_resume(struct device *dev)
{
	struct iio_dev *indio_dev = dev_get_drvdata(dev);
	struct as3935_state *st = iio_priv(indio_dev);
	int val, ret;

	mutex_lock(&st->lock);
	ret = as3935_read(st, AS3935_AFE_GAIN, &val);
	if (ret)
		goto err_resume;
	val &= ~AS3935_AFE_PWR_BIT;
	ret = as3935_write(st, AS3935_AFE_GAIN, val);

	calibrate_as3935(st);

err_resume:
	mutex_unlock(&st->lock);

	return ret;
}

static SIMPLE_DEV_PM_OPS(as3935_pm_ops, as3935_suspend, as3935_resume);
#define AS3935_PM_OPS (&as3935_pm_ops)

#else
#define AS3935_PM_OPS NULL
#endif

static void as3935_stop_work(void *data)
{
	struct iio_dev *indio_dev = data;
	struct as3935_state *st = iio_priv(indio_dev);

	cancel_delayed_work_sync(&st->work);
}

static int as3935_probe(struct spi_device *spi)
{
	struct device *dev = &spi->dev;
	struct iio_dev *indio_dev;
	struct iio_trigger *trig;
	struct as3935_state *st;
	int ret;

	/* Be sure lightning event interrupt is specified */
	if (!spi->irq) {
		dev_err(dev, "unable to get event interrupt\n");
		return -EINVAL;
	}

	indio_dev = devm_iio_device_alloc(dev, sizeof(*st));
	if (!indio_dev)
		return -ENOMEM;

	st = iio_priv(indio_dev);
	st->spi = spi;

	spi_set_drvdata(spi, indio_dev);
	mutex_init(&st->lock);

	ret = device_property_read_u32(dev,
			"ams,tuning-capacitor-pf", &st->tune_cap);
	if (ret) {
		st->tune_cap = 0;
		dev_warn(dev, "no tuning-capacitor-pf set, defaulting to %d",
			st->tune_cap);
	}

	if (st->tune_cap > MAX_PF_CAP) {
		dev_err(dev, "wrong tuning-capacitor-pf setting of %d\n",
			st->tune_cap);
		return -EINVAL;
	}

	ret = device_property_read_u32(dev,
			"ams,nflwdth", &st->nflwdth_reg);
	if (!ret && st->nflwdth_reg > AS3935_NFLWDTH_MASK) {
		dev_err(dev, "invalid nflwdth setting of %d\n",
			st->nflwdth_reg);
		return -EINVAL;
	}

	indio_dev->name = spi_get_device_id(spi)->name;
	indio_dev->channels = as3935_channels;
	indio_dev->num_channels = ARRAY_SIZE(as3935_channels);
	indio_dev->modes = INDIO_DIRECT_MODE;
	indio_dev->info = &as3935_info;

	trig = devm_iio_trigger_alloc(dev, "%s-dev%d",
				      indio_dev->name, indio_dev->id);

	if (!trig)
		return -ENOMEM;

	st->trig = trig;
	st->noise_tripped = jiffies - HZ;
	trig->dev.parent = indio_dev->dev.parent;
	iio_trigger_set_drvdata(trig, indio_dev);
	trig->ops = &iio_interrupt_trigger_ops;

	ret = devm_iio_trigger_register(dev, trig);
	if (ret) {
		dev_err(dev, "failed to register trigger\n");
		return ret;
	}

	ret = devm_iio_triggered_buffer_setup(dev, indio_dev,
					      iio_pollfunc_store_time,
					      as3935_trigger_handler, NULL);

	if (ret) {
		dev_err(dev, "cannot setup iio trigger\n");
		return ret;
	}

	calibrate_as3935(st);

	INIT_DELAYED_WORK(&st->work, as3935_event_work);
	ret = devm_add_action(dev, as3935_stop_work, indio_dev);
	if (ret)
		return ret;

	ret = devm_request_irq(dev, spi->irq,
				&as3935_interrupt_handler,
				IRQF_TRIGGER_RISING,
				dev_name(dev),
				indio_dev);

	if (ret) {
		dev_err(dev, "unable to request irq\n");
		return ret;
	}

	ret = devm_iio_device_register(dev, indio_dev);
	if (ret < 0) {
		dev_err(dev, "unable to register device\n");
		return ret;
	}
	return 0;
}

static const struct of_device_id as3935_of_match[] = {
	{ .compatible = "ams,as3935", },
	{ /* sentinel */ },
};
MODULE_DEVICE_TABLE(of, as3935_of_match);

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

static struct spi_driver as3935_driver = {
	.driver = {
		.name	= "as3935",
		.of_match_table = as3935_of_match,
		.pm	= AS3935_PM_OPS,
	},
	.probe		= as3935_probe,
	.id_table	= as3935_id,
};
module_spi_driver(as3935_driver);

MODULE_AUTHOR("Matt Ranostay <matt.ranostay@konsulko.com>");
MODULE_DESCRIPTION("AS3935 lightning sensor");
MODULE_LICENSE("GPL");
