#include <linux/i2c.h>

#include "dibx000_common.h"

static int debug;
module_param(debug, int, 0644);
MODULE_PARM_DESC(debug, "turn on debugging (default: 0)");

#define dprintk(args...) do { if (debug) { printk(KERN_DEBUG "DiBX000: "); printk(args); printk("\n"); } } while (0)

static int dibx000_write_word(struct dibx000_i2c_master *mst, u16 reg, u16 val)
{
	u8 b[4] = {
		(reg >> 8) & 0xff, reg & 0xff,
		(val >> 8) & 0xff, val & 0xff,
	};
	struct i2c_msg msg = {
		.addr = mst->i2c_addr,.flags = 0,.buf = b,.len = 4
	};
	return i2c_transfer(mst->i2c_adap, &msg, 1) != 1 ? -EREMOTEIO : 0;
}


static int dibx000_i2c_select_interface(struct dibx000_i2c_master *mst,
					enum dibx000_i2c_interface intf)
{
	if (mst->device_rev > DIB3000MC && mst->selected_interface != intf) {
		dprintk("selecting interface: %d", intf);
		mst->selected_interface = intf;
		return dibx000_write_word(mst, mst->base_reg + 4, intf);
	}
	return 0;
}

static int dibx000_i2c_gate_ctrl(struct dibx000_i2c_master *mst, u8 tx[4],
				 u8 addr, int onoff)
{
	u16 val;


	if (onoff)
		val = addr << 8;	// bit 7 = use master or not, if 0, the gate is open
	else
		val = 1 << 7;

	if (mst->device_rev > DIB7000)
		val <<= 1;

	tx[0] = (((mst->base_reg + 1) >> 8) & 0xff);
	tx[1] = ((mst->base_reg + 1) & 0xff);
	tx[2] = val >> 8;
	tx[3] = val & 0xff;

	return 0;
}

static u32 dibx000_i2c_func(struct i2c_adapter *adapter)
{
	return I2C_FUNC_I2C;
}

static int dibx000_i2c_gated_tuner_xfer(struct i2c_adapter *i2c_adap,
					struct i2c_msg msg[], int num)
{
	struct dibx000_i2c_master *mst = i2c_get_adapdata(i2c_adap);
	struct i2c_msg m[2 + num];
	u8 tx_open[4], tx_close[4];

	memset(m, 0, sizeof(struct i2c_msg) * (2 + num));

	dibx000_i2c_select_interface(mst, DIBX000_I2C_INTERFACE_TUNER);

	dibx000_i2c_gate_ctrl(mst, tx_open, msg[0].addr, 1);
	m[0].addr = mst->i2c_addr;
	m[0].buf = tx_open;
	m[0].len = 4;

	memcpy(&m[1], msg, sizeof(struct i2c_msg) * num);

	dibx000_i2c_gate_ctrl(mst, tx_close, 0, 0);
	m[num + 1].addr = mst->i2c_addr;
	m[num + 1].buf = tx_close;
	m[num + 1].len = 4;

	return i2c_transfer(mst->i2c_adap, m, 2 + num) == 2 + num ? num : -EIO;
}

static struct i2c_algorithm dibx000_i2c_gated_tuner_algo = {
	.master_xfer = dibx000_i2c_gated_tuner_xfer,
	.functionality = dibx000_i2c_func,
};

struct i2c_adapter *dibx000_get_i2c_adapter(struct dibx000_i2c_master *mst,
					    enum dibx000_i2c_interface intf,
					    int gating)
{
	struct i2c_adapter *i2c = NULL;

	switch (intf) {
	case DIBX000_I2C_INTERFACE_TUNER:
		if (gating)
			i2c = &mst->gated_tuner_i2c_adap;
		break;
	default:
		printk(KERN_ERR "DiBX000: incorrect I2C interface selected\n");
		break;
	}

	return i2c;
}

EXPORT_SYMBOL(dibx000_get_i2c_adapter);

void dibx000_reset_i2c_master(struct dibx000_i2c_master *mst)
{
	/* initialize the i2c-master by closing the gate */
	u8 tx[4];
	struct i2c_msg m = {.addr = mst->i2c_addr,.buf = tx,.len = 4 };

	dibx000_i2c_gate_ctrl(mst, tx, 0, 0);
	i2c_transfer(mst->i2c_adap, &m, 1);
	mst->selected_interface = 0xff;	// the first time force a select of the I2C
	dibx000_i2c_select_interface(mst, DIBX000_I2C_INTERFACE_TUNER);
}

EXPORT_SYMBOL(dibx000_reset_i2c_master);

static int i2c_adapter_init(struct i2c_adapter *i2c_adap,
			    struct i2c_algorithm *algo, const char *name,
			    struct dibx000_i2c_master *mst)
{
	strncpy(i2c_adap->name, name, sizeof(i2c_adap->name));
	i2c_adap->algo = algo;
	i2c_adap->algo_data = NULL;
	i2c_set_adapdata(i2c_adap, mst);
	if (i2c_add_adapter(i2c_adap) < 0)
		return -ENODEV;
	return 0;
}

int dibx000_init_i2c_master(struct dibx000_i2c_master *mst, u16 device_rev,
			    struct i2c_adapter *i2c_adap, u8 i2c_addr)
{
	u8 tx[4];
	struct i2c_msg m = {.addr = i2c_addr >> 1,.buf = tx,.len = 4 };

	mst->device_rev = device_rev;
	mst->i2c_adap = i2c_adap;
	mst->i2c_addr = i2c_addr >> 1;

	if (device_rev == DIB7000P || device_rev == DIB8000)
		mst->base_reg = 1024;
	else
		mst->base_reg = 768;

	if (i2c_adapter_init
	    (&mst->gated_tuner_i2c_adap, &dibx000_i2c_gated_tuner_algo,
	     "DiBX000 tuner I2C bus", mst) != 0)
		printk(KERN_ERR
		       "DiBX000: could not initialize the tuner i2c_adapter\n");

	/* initialize the i2c-master by closing the gate */
	dibx000_i2c_gate_ctrl(mst, tx, 0, 0);

	return i2c_transfer(i2c_adap, &m, 1) == 1;
}

EXPORT_SYMBOL(dibx000_init_i2c_master);

void dibx000_exit_i2c_master(struct dibx000_i2c_master *mst)
{
	i2c_del_adapter(&mst->gated_tuner_i2c_adap);
}
EXPORT_SYMBOL(dibx000_exit_i2c_master);


u32 systime(void)
{
    struct timespec t;

    t = current_kernel_time();
    return (t.tv_sec * 10000) + (t.tv_nsec / 100000);
}
EXPORT_SYMBOL(systime);

MODULE_AUTHOR("Patrick Boettcher <pboettcher@dibcom.fr>");
MODULE_DESCRIPTION("Common function the DiBcom demodulator family");
MODULE_LICENSE("GPL");
