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

#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_NS_GPL(sx_common_events, SEMTECH_PROX);

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_set_bits(data->regmap, data->chip_info->reg_irq_msk,
			       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_clear_bits(data->regmap, data->chip_info->reg_irq_msk,
				 irq << data->chip_info->irq_msk_offset);
}

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_NS_GPL(sx_common_read_proximity, SEMTECH_PROX);

/**
 * 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_NS_GPL(sx_common_read_event_config, SEMTECH_PROX);

/**
 * 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_NS_GPL(sx_common_write_event_config, SEMTECH_PROX);

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);

	iio_for_each_active_channel(indio_dev, bit) {
		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);
	iio_for_each_active_channel(indio_dev, bit)
		__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,
	.postdisable = sx_common_buffer_postdisable,
};

void sx_common_get_raw_register_config(struct device *dev,
				       struct sx_common_reg_default *reg_def)
{
#ifdef CONFIG_ACPI
	struct acpi_device *adev = ACPI_COMPANION(dev);
	u32 raw = 0, ret;
	char prop[80];

	if (!reg_def->property || !adev)
		return;

	snprintf(prop, ARRAY_SIZE(prop), "%s,reg_%s", acpi_device_hid(adev), reg_def->property);
	ret = device_property_read_u32(dev, prop, &raw);
	if (ret)
		return;

	reg_def->def = raw;
#endif
}
EXPORT_SYMBOL_NS_GPL(sx_common_get_raw_register_config, SEMTECH_PROX);

#define SX_COMMON_SOFT_RESET				0xde

static int sx_common_init_device(struct device *dev, 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(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)
{
	static const char * const regulator_names[] = { "vdd", "svdd" };
	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;
	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_enable(dev, ARRAY_SIZE(regulator_names),
					     regulator_names);
	if (ret)
		return dev_err_probe(dev, ret, "Unable to get regulators\n");

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

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

	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(dev, 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,
						    iio_device_id(indio_dev));
		if (!data->trig)
			return -ENOMEM;

		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_NS_GPL(sx_common_probe, SEMTECH_PROX);

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