// SPDX-License-Identifier: GPL-2.0
/*
 * Copyright 2021 Google LLC.
 *
 * Common part of most Semtech SAR sensor.
 */

#include <linux/acpi.h>
#include <linux/bitops.h>
#include <linux/byteorder/generic.h>
#include <linux/delay.h>
#include <linux/device.h>
#include <linux/err.h>
#include <linux/export.h>
#include <linux/interrupt.h>
#include <linux/irqreturn.h>
#include <linux/i2c.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/regmap.h>
#include <linux/regulator/consumer.h>
#include <vdso/bits.h>

#include <linux/iio/buffer.h>
#include <linux/iio/events.h>
#include <linux/iio/iio.h>
#include <linux/iio/trigger.h>
#include <linux/iio/triggered_buffer.h>
#include <linux/iio/trigger_consumer.h>

#include "sx_common.h"

/* All Semtech SAR sensors have IRQ bit in the same order. */
#define   SX_COMMON_CONVDONE_IRQ			BIT(0)
#define   SX_COMMON_FAR_IRQ				BIT(2)
#define   SX_COMMON_CLOSE_IRQ				BIT(3)

const struct iio_event_spec sx_common_events[3] = {
	{
		.type = IIO_EV_TYPE_THRESH,
		.dir = IIO_EV_DIR_RISING,
		.mask_shared_by_all = BIT(IIO_EV_INFO_PERIOD),
	},
	{
		.type = IIO_EV_TYPE_THRESH,
		.dir = IIO_EV_DIR_FALLING,
		.mask_shared_by_all = BIT(IIO_EV_INFO_PERIOD),
	},
	{
		.type = IIO_EV_TYPE_THRESH,
		.dir = IIO_EV_DIR_EITHER,
		.mask_separate = BIT(IIO_EV_INFO_ENABLE) |
				 BIT(IIO_EV_INFO_HYSTERESIS) |
				 BIT(IIO_EV_INFO_VALUE),
	},
};
EXPORT_SYMBOL_GPL(sx_common_events);

static irqreturn_t sx_common_irq_handler(int irq, void *private)
{
	struct iio_dev *indio_dev = private;
	struct sx_common_data *data = iio_priv(indio_dev);

	if (data->trigger_enabled)
		iio_trigger_poll(data->trig);

	/*
	 * Even if no event is enabled, we need to wake the thread to clear the
	 * interrupt state by reading SX_COMMON_REG_IRQ_SRC.
	 * It is not possible to do that here because regmap_read takes a mutex.
	 */
	return IRQ_WAKE_THREAD;
}

static void sx_common_push_events(struct iio_dev *indio_dev)
{
	int ret;
	unsigned int val, chan;
	struct sx_common_data *data = iio_priv(indio_dev);
	s64 timestamp = iio_get_time_ns(indio_dev);
	unsigned long prox_changed;

	/* Read proximity state on all channels */
	ret = regmap_read(data->regmap, data->chip_info->reg_stat, &val);
	if (ret) {
		dev_err(&data->client->dev, "i2c transfer error in irq\n");
		return;
	}

	val >>= data->chip_info->stat_offset;

	/*
	 * Only iterate over channels with changes on proximity status that have
	 * events enabled.
	 */
	prox_changed = (data->chan_prox_stat ^ val) & data->chan_event;

	for_each_set_bit(chan, &prox_changed, data->chip_info->num_channels) {
		int dir;
		u64 ev;

		dir = (val & BIT(chan)) ? IIO_EV_DIR_FALLING : IIO_EV_DIR_RISING;
		ev = IIO_UNMOD_EVENT_CODE(IIO_PROXIMITY, chan,
					  IIO_EV_TYPE_THRESH, dir);

		iio_push_event(indio_dev, ev, timestamp);
	}
	data->chan_prox_stat = val;
}

static int sx_common_enable_irq(struct sx_common_data *data, unsigned int irq)
{
	if (!data->client->irq)
		return 0;
	return regmap_update_bits(data->regmap, data->chip_info->reg_irq_msk,
				  irq << data->chip_info->irq_msk_offset,
				  irq << data->chip_info->irq_msk_offset);
}

static int sx_common_disable_irq(struct sx_common_data *data, unsigned int irq)
{
	if (!data->client->irq)
		return 0;
	return regmap_update_bits(data->regmap, data->chip_info->reg_irq_msk,
				  irq << data->chip_info->irq_msk_offset, 0);
}

static int sx_common_update_chan_en(struct sx_common_data *data,
				    unsigned long chan_read,
				    unsigned long chan_event)
{
	int ret;
	unsigned long channels = chan_read | chan_event;

	if ((data->chan_read | data->chan_event) != channels) {
		ret = regmap_update_bits(data->regmap,
					 data->chip_info->reg_enable_chan,
					 data->chip_info->mask_enable_chan,
					 channels);
		if (ret)
			return ret;
	}
	data->chan_read = chan_read;
	data->chan_event = chan_event;
	return 0;
}

static int sx_common_get_read_channel(struct sx_common_data *data, int channel)
{
	return sx_common_update_chan_en(data, data->chan_read | BIT(channel),
				     data->chan_event);
}

static int sx_common_put_read_channel(struct sx_common_data *data, int channel)
{
	return sx_common_update_chan_en(data, data->chan_read & ~BIT(channel),
				     data->chan_event);
}

static int sx_common_get_event_channel(struct sx_common_data *data, int channel)
{
	return sx_common_update_chan_en(data, data->chan_read,
				     data->chan_event | BIT(channel));
}

static int sx_common_put_event_channel(struct sx_common_data *data, int channel)
{
	return sx_common_update_chan_en(data, data->chan_read,
				     data->chan_event & ~BIT(channel));
}

/**
 * sx_common_read_proximity() - Read raw proximity value.
 * @data:	Internal data
 * @chan:	Channel to read
 * @val:	pointer to return read value.
 *
 * Request a conversion, wait for the sensor to be ready and
 * return the raw proximity value.
 */
int sx_common_read_proximity(struct sx_common_data *data,
			     const struct iio_chan_spec *chan, int *val)
{
	int ret;
	__be16 rawval;

	mutex_lock(&data->mutex);

	ret = sx_common_get_read_channel(data, chan->channel);
	if (ret)
		goto out;

	ret = sx_common_enable_irq(data, SX_COMMON_CONVDONE_IRQ);
	if (ret)
		goto out_put_channel;

	mutex_unlock(&data->mutex);

	if (data->client->irq) {
		ret = wait_for_completion_interruptible(&data->completion);
		reinit_completion(&data->completion);
	} else {
		ret = data->chip_info->ops.wait_for_sample(data);
	}

	mutex_lock(&data->mutex);

	if (ret)
		goto out_disable_irq;

	ret = data->chip_info->ops.read_prox_data(data, chan, &rawval);
	if (ret)
		goto out_disable_irq;

	*val = sign_extend32(be16_to_cpu(rawval), chan->scan_type.realbits - 1);

	ret = sx_common_disable_irq(data, SX_COMMON_CONVDONE_IRQ);
	if (ret)
		goto out_put_channel;

	ret = sx_common_put_read_channel(data, chan->channel);
	if (ret)
		goto out;

	mutex_unlock(&data->mutex);

	return IIO_VAL_INT;

out_disable_irq:
	sx_common_disable_irq(data, SX_COMMON_CONVDONE_IRQ);
out_put_channel:
	sx_common_put_read_channel(data, chan->channel);
out:
	mutex_unlock(&data->mutex);

	return ret;
}
EXPORT_SYMBOL_GPL(sx_common_read_proximity);

/**
 * sx_common_read_event_config() - Configure event setting.
 * @indio_dev:	iio device object
 * @chan:	Channel to read
 * @type:	Type of event (unused)
 * @dir:	Direction of event (unused)
 *
 * return if the given channel is used for event gathering.
 */
int sx_common_read_event_config(struct iio_dev *indio_dev,
				const struct iio_chan_spec *chan,
				enum iio_event_type type,
				enum iio_event_direction dir)
{
	struct sx_common_data *data = iio_priv(indio_dev);

	return !!(data->chan_event & BIT(chan->channel));
}
EXPORT_SYMBOL_GPL(sx_common_read_event_config);

/**
 * sx_common_write_event_config() - Configure event setting.
 * @indio_dev:	iio device object
 * @chan:	Channel to enable
 * @type:	Type of event (unused)
 * @dir:	Direction of event (unused)
 * @state:	State of the event.
 *
 * Enable/Disable event on a given channel.
 */
int sx_common_write_event_config(struct iio_dev *indio_dev,
				 const struct iio_chan_spec *chan,
				 enum iio_event_type type,
				 enum iio_event_direction dir, int state)
{
	struct sx_common_data *data = iio_priv(indio_dev);
	unsigned int eventirq = SX_COMMON_FAR_IRQ | SX_COMMON_CLOSE_IRQ;
	int ret;

	/* If the state hasn't changed, there's nothing to do. */
	if (!!(data->chan_event & BIT(chan->channel)) == state)
		return 0;

	mutex_lock(&data->mutex);
	if (state) {
		ret = sx_common_get_event_channel(data, chan->channel);
		if (ret)
			goto out_unlock;
		if (!(data->chan_event & ~BIT(chan->channel))) {
			ret = sx_common_enable_irq(data, eventirq);
			if (ret)
				sx_common_put_event_channel(data, chan->channel);
		}
	} else {
		ret = sx_common_put_event_channel(data, chan->channel);
		if (ret)
			goto out_unlock;
		if (!data->chan_event) {
			ret = sx_common_disable_irq(data, eventirq);
			if (ret)
				sx_common_get_event_channel(data, chan->channel);
		}
	}

out_unlock:
	mutex_unlock(&data->mutex);
	return ret;
}
EXPORT_SYMBOL_GPL(sx_common_write_event_config);

static int sx_common_set_trigger_state(struct iio_trigger *trig, bool state)
{
	struct iio_dev *indio_dev = iio_trigger_get_drvdata(trig);
	struct sx_common_data *data = iio_priv(indio_dev);
	int ret = 0;

	mutex_lock(&data->mutex);

	if (state)
		ret = sx_common_enable_irq(data, SX_COMMON_CONVDONE_IRQ);
	else if (!data->chan_read)
		ret = sx_common_disable_irq(data, SX_COMMON_CONVDONE_IRQ);
	if (ret)
		goto out;

	data->trigger_enabled = state;

out:
	mutex_unlock(&data->mutex);

	return ret;
}

static const struct iio_trigger_ops sx_common_trigger_ops = {
	.set_trigger_state = sx_common_set_trigger_state,
};

static irqreturn_t sx_common_irq_thread_handler(int irq, void *private)
{
	struct iio_dev *indio_dev = private;
	struct sx_common_data *data = iio_priv(indio_dev);
	int ret;
	unsigned int val;

	mutex_lock(&data->mutex);

	ret = regmap_read(data->regmap, SX_COMMON_REG_IRQ_SRC, &val);
	if (ret) {
		dev_err(&data->client->dev, "i2c transfer error in irq\n");
		goto out;
	}

	if (val & ((SX_COMMON_FAR_IRQ | SX_COMMON_CLOSE_IRQ) << data->chip_info->irq_msk_offset))
		sx_common_push_events(indio_dev);

	if (val & (SX_COMMON_CONVDONE_IRQ << data->chip_info->irq_msk_offset))
		complete(&data->completion);

out:
	mutex_unlock(&data->mutex);

	return IRQ_HANDLED;
}

static irqreturn_t sx_common_trigger_handler(int irq, void *private)
{
	struct iio_poll_func *pf = private;
	struct iio_dev *indio_dev = pf->indio_dev;
	struct sx_common_data *data = iio_priv(indio_dev);
	__be16 val;
	int bit, ret, i = 0;

	mutex_lock(&data->mutex);

	for_each_set_bit(bit, indio_dev->active_scan_mask,
			 indio_dev->masklength) {
		ret = data->chip_info->ops.read_prox_data(data,
						     &indio_dev->channels[bit],
						     &val);
		if (ret)
			goto out;

		data->buffer.channels[i++] = val;
	}

	iio_push_to_buffers_with_timestamp(indio_dev, &data->buffer,
					   pf->timestamp);

out:
	mutex_unlock(&data->mutex);

	iio_trigger_notify_done(indio_dev->trig);

	return IRQ_HANDLED;
}

static int sx_common_buffer_preenable(struct iio_dev *indio_dev)
{
	struct sx_common_data *data = iio_priv(indio_dev);
	unsigned long channels = 0;
	int bit, ret;

	mutex_lock(&data->mutex);
	for_each_set_bit(bit, indio_dev->active_scan_mask,
			 indio_dev->masklength)
		__set_bit(indio_dev->channels[bit].channel, &channels);

	ret = sx_common_update_chan_en(data, channels, data->chan_event);
	mutex_unlock(&data->mutex);
	return ret;
}

static int sx_common_buffer_postdisable(struct iio_dev *indio_dev)
{
	struct sx_common_data *data = iio_priv(indio_dev);
	int ret;

	mutex_lock(&data->mutex);
	ret = sx_common_update_chan_en(data, 0, data->chan_event);
	mutex_unlock(&data->mutex);
	return ret;
}

static const struct iio_buffer_setup_ops sx_common_buffer_setup_ops = {
	.preenable = sx_common_buffer_preenable,
	.postenable = iio_triggered_buffer_postenable,
	.predisable = iio_triggered_buffer_predisable,
	.postdisable = sx_common_buffer_postdisable,
};

static void sx_common_regulator_disable(void *_data)
{
	struct sx_common_data *data = _data;

	regulator_bulk_disable(ARRAY_SIZE(data->supplies), data->supplies);
}

#define SX_COMMON_SOFT_RESET				0xde

static int sx_common_init_device(struct iio_dev *indio_dev)
{
	struct sx_common_data *data = iio_priv(indio_dev);
	struct sx_common_reg_default tmp;
	const struct sx_common_reg_default *initval;
	int ret;
	unsigned int i, val;

	ret = regmap_write(data->regmap, data->chip_info->reg_reset,
			   SX_COMMON_SOFT_RESET);
	if (ret)
		return ret;

	usleep_range(1000, 2000); /* power-up time is ~1ms. */

	/* Clear reset interrupt state by reading SX_COMMON_REG_IRQ_SRC. */
	ret = regmap_read(data->regmap, SX_COMMON_REG_IRQ_SRC, &val);
	if (ret)
		return ret;

	/* Program defaults from constant or BIOS. */
	for (i = 0; i < data->chip_info->num_default_regs; i++) {
		initval = data->chip_info->ops.get_default_reg(&indio_dev->dev,
							       i, &tmp);
		ret = regmap_write(data->regmap, initval->reg, initval->def);
		if (ret)
			return ret;
	}

	return data->chip_info->ops.init_compensation(indio_dev);
}

/**
 * sx_common_probe() - Common setup for Semtech SAR sensor
 * @client:		I2C client object
 * @chip_info:		Semtech sensor chip information.
 * @regmap_config:	Sensor registers map configuration.
 */
int sx_common_probe(struct i2c_client *client,
		    const struct sx_common_chip_info *chip_info,
		    const struct regmap_config *regmap_config)
{
	struct device *dev = &client->dev;
	struct iio_dev *indio_dev;
	struct sx_common_data *data;
	int ret;

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

	data = iio_priv(indio_dev);

	data->chip_info = chip_info;
	data->client = client;
	data->supplies[0].supply = "vdd";
	data->supplies[1].supply = "svdd";
	mutex_init(&data->mutex);
	init_completion(&data->completion);

	data->regmap = devm_regmap_init_i2c(client, regmap_config);
	if (IS_ERR(data->regmap))
		return dev_err_probe(dev, PTR_ERR(data->regmap),
				     "Could init register map\n");

	ret = devm_regulator_bulk_get(dev, ARRAY_SIZE(data->supplies),
				      data->supplies);
	if (ret)
		return dev_err_probe(dev, ret, "Unable to get regulators\n");

	ret = regulator_bulk_enable(ARRAY_SIZE(data->supplies), data->supplies);
	if (ret)
		return dev_err_probe(dev, ret, "Unable to enable regulators\n");

	/* Must wait for Tpor time after initial power up */
	usleep_range(1000, 1100);

	ret = devm_add_action_or_reset(dev, sx_common_regulator_disable, data);
	if (ret)
		return dev_err_probe(dev, ret,
				     "Unable to register regulators deleter\n");

	ret = data->chip_info->ops.check_whoami(dev, indio_dev);
	if (ret)
		return dev_err_probe(dev, ret, "error reading WHOAMI\n");

	ACPI_COMPANION_SET(&indio_dev->dev, ACPI_COMPANION(dev));
	indio_dev->dev.of_node = client->dev.of_node;
	indio_dev->modes = INDIO_DIRECT_MODE;

	indio_dev->channels =  data->chip_info->iio_channels;
	indio_dev->num_channels = data->chip_info->num_iio_channels;
	indio_dev->info = &data->chip_info->iio_info;

	i2c_set_clientdata(client, indio_dev);

	ret = sx_common_init_device(indio_dev);
	if (ret)
		return dev_err_probe(dev, ret, "Unable to initialize sensor\n");

	if (client->irq) {
		ret = devm_request_threaded_irq(dev, client->irq,
						sx_common_irq_handler,
						sx_common_irq_thread_handler,
						IRQF_ONESHOT,
						"sx_event", indio_dev);
		if (ret)
			return dev_err_probe(dev, ret, "No IRQ\n");

		data->trig = devm_iio_trigger_alloc(dev, "%s-dev%d",
						    indio_dev->name,
						    indio_dev->id);
		if (!data->trig)
			return -ENOMEM;

		data->trig->dev.parent = dev;
		data->trig->ops = &sx_common_trigger_ops;
		iio_trigger_set_drvdata(data->trig, indio_dev);

		ret = devm_iio_trigger_register(dev, data->trig);
		if (ret)
			return ret;
	}

	ret = devm_iio_triggered_buffer_setup(dev, indio_dev,
					      iio_pollfunc_store_time,
					      sx_common_trigger_handler,
					      &sx_common_buffer_setup_ops);
	if (ret)
		return ret;

	return devm_iio_device_register(dev, indio_dev);
}
EXPORT_SYMBOL_GPL(sx_common_probe);

MODULE_AUTHOR("Gwendal Grignou <gwendal@chromium.org>");
MODULE_DESCRIPTION("Common functions and structures for Semtech sensor");
MODULE_LICENSE("GPL v2");
