// SPDX-License-Identifier: GPL-2.0-only
/*
 * Copyright (C) 2021-2023 Digiteq Automotive
 *     author: Martin Tuma <martin.tuma@digiteqautomotive.com>
 *
 * This module handles the IIO trigger device. The card has two signal inputs
 * for event triggers that can be used to record events related to the video
 * stream. A standard linux IIO device with triggered buffer capability is
 * created and configured that can be used to fetch the events with the same
 * clock source as the video frames.
 */

#include <linux/iio/iio.h>
#include <linux/iio/buffer.h>
#include <linux/iio/trigger.h>
#include <linux/iio/trigger_consumer.h>
#include <linux/iio/triggered_buffer.h>
#include <linux/pci.h>
#include <linux/dma/amd_xdma.h>
#include "mgb4_core.h"
#include "mgb4_trigger.h"

struct trigger_data {
	struct mgb4_dev *mgbdev;
	struct iio_trigger *trig;
};

static int trigger_read_raw(struct iio_dev *indio_dev,
			    struct iio_chan_spec const *chan, int *val,
			    int *val2, long mask)
{
	struct trigger_data *st = iio_priv(indio_dev);

	switch (mask) {
	case IIO_CHAN_INFO_RAW:
		if (iio_buffer_enabled(indio_dev))
			return -EBUSY;
		*val = mgb4_read_reg(&st->mgbdev->video, 0xA0);

		return IIO_VAL_INT;
	}

	return -EINVAL;
}

static int trigger_set_state(struct iio_trigger *trig, bool state)
{
	struct iio_dev *indio_dev = iio_trigger_get_drvdata(trig);
	struct trigger_data *st = iio_priv(indio_dev);
	int irq = xdma_get_user_irq(st->mgbdev->xdev, 11);

	if (state)
		xdma_enable_user_irq(st->mgbdev->xdev, irq);
	else
		xdma_disable_user_irq(st->mgbdev->xdev, irq);

	return 0;
}

static const struct iio_trigger_ops trigger_ops = {
	.set_trigger_state = &trigger_set_state,
};

static const struct iio_info trigger_info = {
	.read_raw         = trigger_read_raw,
};

#define TRIGGER_CHANNEL(_si) {                    \
	.type = IIO_ACTIVITY,                         \
	.info_mask_separate = BIT(IIO_CHAN_INFO_RAW), \
	.scan_index = _si,                            \
	.scan_type = {                                \
		.sign = 'u',                              \
		.realbits = 32,                           \
		.storagebits = 32,                        \
		.shift = 0,                               \
		.endianness = IIO_CPU                     \
	},                                            \
}

static const struct iio_chan_spec trigger_channels[] = {
	TRIGGER_CHANNEL(0),
	IIO_CHAN_SOFT_TIMESTAMP(1),
};

static irqreturn_t trigger_handler(int irq, void *p)
{
	struct iio_poll_func *pf = p;
	struct iio_dev *indio_dev = pf->indio_dev;
	struct trigger_data *st = iio_priv(indio_dev);
	struct {
		u32 data;
		s64 ts __aligned(8);
	} scan;

	scan.data = mgb4_read_reg(&st->mgbdev->video, 0xA0);
	mgb4_write_reg(&st->mgbdev->video, 0xA0, scan.data);

	iio_push_to_buffers_with_timestamp(indio_dev, &scan, pf->timestamp);
	iio_trigger_notify_done(indio_dev->trig);

	mgb4_write_reg(&st->mgbdev->video, 0xB4, 1U << 11);

	return IRQ_HANDLED;
}

static int probe_trigger(struct iio_dev *indio_dev, int irq)
{
	int ret;
	struct trigger_data *st = iio_priv(indio_dev);

	st->trig = iio_trigger_alloc(&st->mgbdev->pdev->dev, "%s-dev%d",
				     indio_dev->name, iio_device_id(indio_dev));
	if (!st->trig)
		return -ENOMEM;

	ret = request_irq(irq, &iio_trigger_generic_data_rdy_poll, 0,
			  "mgb4-trigger", st->trig);
	if (ret)
		goto error_free_trig;

	st->trig->ops = &trigger_ops;
	iio_trigger_set_drvdata(st->trig, indio_dev);
	ret = iio_trigger_register(st->trig);
	if (ret)
		goto error_free_irq;

	indio_dev->trig = iio_trigger_get(st->trig);

	return 0;

error_free_irq:
	free_irq(irq, st->trig);
error_free_trig:
	iio_trigger_free(st->trig);

	return ret;
}

static void remove_trigger(struct iio_dev *indio_dev, int irq)
{
	struct trigger_data *st = iio_priv(indio_dev);

	iio_trigger_unregister(st->trig);
	free_irq(irq, st->trig);
	iio_trigger_free(st->trig);
}

struct iio_dev *mgb4_trigger_create(struct mgb4_dev *mgbdev)
{
	struct iio_dev *indio_dev;
	struct trigger_data *data;
	struct pci_dev *pdev = mgbdev->pdev;
	struct device *dev = &pdev->dev;
	int rv, irq;

	indio_dev = iio_device_alloc(dev, sizeof(*data));
	if (!indio_dev)
		return NULL;

	indio_dev->info = &trigger_info;
	indio_dev->name = "mgb4";
	indio_dev->modes = INDIO_DIRECT_MODE;
	indio_dev->channels = trigger_channels;
	indio_dev->num_channels = ARRAY_SIZE(trigger_channels);

	data = iio_priv(indio_dev);
	data->mgbdev = mgbdev;

	irq = xdma_get_user_irq(mgbdev->xdev, 11);
	rv = probe_trigger(indio_dev, irq);
	if (rv < 0) {
		dev_err(dev, "iio triggered setup failed\n");
		goto error_alloc;
	}
	rv = iio_triggered_buffer_setup(indio_dev, &iio_pollfunc_store_time,
					trigger_handler, NULL);
	if (rv < 0) {
		dev_err(dev, "iio triggered buffer setup failed\n");
		goto error_trigger;
	}
	rv = iio_device_register(indio_dev);
	if (rv < 0) {
		dev_err(dev, "iio device register failed\n");
		goto error_buffer;
	}

	return indio_dev;

error_buffer:
	iio_triggered_buffer_cleanup(indio_dev);
error_trigger:
	remove_trigger(indio_dev, irq);
error_alloc:
	iio_device_free(indio_dev);

	return NULL;
}

void mgb4_trigger_free(struct iio_dev *indio_dev)
{
	struct trigger_data *st = iio_priv(indio_dev);

	iio_device_unregister(indio_dev);
	iio_triggered_buffer_cleanup(indio_dev);
	remove_trigger(indio_dev, xdma_get_user_irq(st->mgbdev->xdev, 11));
	iio_device_free(indio_dev);
}
