// SPDX-License-Identifier: GPL-2.0-or-later
/*
	Mantis PCI bridge driver

	Copyright (C) Manu Abraham (abraham.manu@gmail.com)

*/

#include <asm/io.h>
#include <linux/ioport.h>
#include <linux/pci.h>
#include <linux/i2c.h>

#include <media/dmxdev.h>
#include <media/dvbdev.h>
#include <media/dvb_demux.h>
#include <media/dvb_frontend.h>
#include <media/dvb_net.h>

#include "mantis_common.h"
#include "mantis_reg.h"
#include "mantis_i2c.h"

#define TRIALS			10000

static int mantis_i2c_read(struct mantis_pci *mantis, const struct i2c_msg *msg)
{
	u32 rxd, i, stat, trials;

	dprintk(MANTIS_INFO, 0, "        %s:  Address=[0x%02x] <R>[ ",
		__func__, msg->addr);

	for (i = 0; i < msg->len; i++) {
		rxd = (msg->addr << 25) | (1 << 24)
					| MANTIS_I2C_RATE_3
					| MANTIS_I2C_STOP
					| MANTIS_I2C_PGMODE;

		if (i == (msg->len - 1))
			rxd &= ~MANTIS_I2C_STOP;

		mmwrite(MANTIS_INT_I2CDONE, MANTIS_INT_STAT);
		mmwrite(rxd, MANTIS_I2CDATA_CTL);

		/* wait for xfer completion */
		for (trials = 0; trials < TRIALS; trials++) {
			stat = mmread(MANTIS_INT_STAT);
			if (stat & MANTIS_INT_I2CDONE)
				break;
		}

		dprintk(MANTIS_TMG, 0, "I2CDONE: trials=%d\n", trials);

		/* wait for xfer completion */
		for (trials = 0; trials < TRIALS; trials++) {
			stat = mmread(MANTIS_INT_STAT);
			if (stat & MANTIS_INT_I2CRACK)
				break;
		}

		dprintk(MANTIS_TMG, 0, "I2CRACK: trials=%d\n", trials);

		rxd = mmread(MANTIS_I2CDATA_CTL);
		msg->buf[i] = (u8)((rxd >> 8) & 0xFF);
		dprintk(MANTIS_INFO, 0, "%02x ", msg->buf[i]);
	}
	dprintk(MANTIS_INFO, 0, "]\n");

	return 0;
}

static int mantis_i2c_write(struct mantis_pci *mantis, const struct i2c_msg *msg)
{
	int i;
	u32 txd = 0, stat, trials;

	dprintk(MANTIS_INFO, 0, "        %s: Address=[0x%02x] <W>[ ",
		__func__, msg->addr);

	for (i = 0; i < msg->len; i++) {
		dprintk(MANTIS_INFO, 0, "%02x ", msg->buf[i]);
		txd = (msg->addr << 25) | (msg->buf[i] << 8)
					| MANTIS_I2C_RATE_3
					| MANTIS_I2C_STOP
					| MANTIS_I2C_PGMODE;

		if (i == (msg->len - 1))
			txd &= ~MANTIS_I2C_STOP;

		mmwrite(MANTIS_INT_I2CDONE, MANTIS_INT_STAT);
		mmwrite(txd, MANTIS_I2CDATA_CTL);

		/* wait for xfer completion */
		for (trials = 0; trials < TRIALS; trials++) {
			stat = mmread(MANTIS_INT_STAT);
			if (stat & MANTIS_INT_I2CDONE)
				break;
		}

		dprintk(MANTIS_TMG, 0, "I2CDONE: trials=%d\n", trials);

		/* wait for xfer completion */
		for (trials = 0; trials < TRIALS; trials++) {
			stat = mmread(MANTIS_INT_STAT);
			if (stat & MANTIS_INT_I2CRACK)
				break;
		}

		dprintk(MANTIS_TMG, 0, "I2CRACK: trials=%d\n", trials);
	}
	dprintk(MANTIS_INFO, 0, "]\n");

	return 0;
}

static int mantis_i2c_xfer(struct i2c_adapter *adapter, struct i2c_msg *msgs, int num)
{
	int ret = 0, i = 0, trials;
	u32 stat, data, txd;
	struct mantis_pci *mantis;
	struct mantis_hwconfig *config;

	mantis = i2c_get_adapdata(adapter);
	BUG_ON(!mantis);
	config = mantis->hwconfig;
	BUG_ON(!config);

	dprintk(MANTIS_DEBUG, 1, "Messages:%d", num);
	mutex_lock(&mantis->i2c_lock);

	while (i < num) {
		/* Byte MODE */
		if ((config->i2c_mode & MANTIS_BYTE_MODE) &&
		    ((i + 1) < num)			&&
		    (msgs[i].len < 2)			&&
		    (msgs[i + 1].len < 2)		&&
		    (msgs[i + 1].flags & I2C_M_RD)) {

			dprintk(MANTIS_DEBUG, 0, "        Byte MODE:\n");

			/* Read operation */
			txd = msgs[i].addr << 25 | (0x1 << 24)
						 | (msgs[i].buf[0] << 16)
						 | MANTIS_I2C_RATE_3;

			mmwrite(txd, MANTIS_I2CDATA_CTL);
			/* wait for xfer completion */
			for (trials = 0; trials < TRIALS; trials++) {
				stat = mmread(MANTIS_INT_STAT);
				if (stat & MANTIS_INT_I2CDONE)
					break;
			}

			/* check for xfer completion */
			if (stat & MANTIS_INT_I2CDONE) {
				/* check xfer was acknowledged */
				if (stat & MANTIS_INT_I2CRACK) {
					data = mmread(MANTIS_I2CDATA_CTL);
					msgs[i + 1].buf[0] = (data >> 8) & 0xff;
					dprintk(MANTIS_DEBUG, 0, "        Byte <%d> RXD=0x%02x  [%02x]\n", 0x0, data, msgs[i + 1].buf[0]);
				} else {
					/* I/O error */
					dprintk(MANTIS_ERROR, 1, "        I/O error, LINE:%d", __LINE__);
					ret = -EIO;
					break;
				}
			} else {
				/* I/O error */
				dprintk(MANTIS_ERROR, 1, "        I/O error, LINE:%d", __LINE__);
				ret = -EIO;
				break;
			}
			i += 2; /* Write/Read operation in one go */
		}

		if (i < num) {
			if (msgs[i].flags & I2C_M_RD)
				ret = mantis_i2c_read(mantis, &msgs[i]);
			else
				ret = mantis_i2c_write(mantis, &msgs[i]);

			i++;
			if (ret < 0)
				goto bail_out;
		}

	}

	mutex_unlock(&mantis->i2c_lock);

	return num;

bail_out:
	mutex_unlock(&mantis->i2c_lock);
	return ret;
}

static u32 mantis_i2c_func(struct i2c_adapter *adapter)
{
	return I2C_FUNC_SMBUS_EMUL;
}

static const struct i2c_algorithm mantis_algo = {
	.master_xfer		= mantis_i2c_xfer,
	.functionality		= mantis_i2c_func,
};

int mantis_i2c_init(struct mantis_pci *mantis)
{
	u32 intstat;
	struct i2c_adapter *i2c_adapter = &mantis->adapter;
	struct pci_dev *pdev		= mantis->pdev;

	init_waitqueue_head(&mantis->i2c_wq);
	mutex_init(&mantis->i2c_lock);
	strscpy(i2c_adapter->name, "Mantis I2C", sizeof(i2c_adapter->name));
	i2c_set_adapdata(i2c_adapter, mantis);

	i2c_adapter->owner	= THIS_MODULE;
	i2c_adapter->algo	= &mantis_algo;
	i2c_adapter->algo_data	= NULL;
	i2c_adapter->timeout	= 500;
	i2c_adapter->retries	= 3;
	i2c_adapter->dev.parent	= &pdev->dev;

	mantis->i2c_rc		= i2c_add_adapter(i2c_adapter);
	if (mantis->i2c_rc < 0)
		return mantis->i2c_rc;

	dprintk(MANTIS_DEBUG, 1, "Initializing I2C ..");

	intstat = mmread(MANTIS_INT_STAT);
	mmread(MANTIS_INT_MASK);
	mmwrite(intstat, MANTIS_INT_STAT);
	dprintk(MANTIS_DEBUG, 1, "Disabling I2C interrupt");
	mantis_mask_ints(mantis, MANTIS_INT_I2CDONE);

	return 0;
}
EXPORT_SYMBOL_GPL(mantis_i2c_init);

int mantis_i2c_exit(struct mantis_pci *mantis)
{
	dprintk(MANTIS_DEBUG, 1, "Disabling I2C interrupt");
	mantis_mask_ints(mantis, MANTIS_INT_I2CDONE);

	dprintk(MANTIS_DEBUG, 1, "Removing I2C adapter");
	i2c_del_adapter(&mantis->adapter);

	return 0;
}
EXPORT_SYMBOL_GPL(mantis_i2c_exit);
