/* DVB USB compliant Linux driver for the Friio USB2.0 ISDB-T receiver.
 *
 * Copyright (C) 2009 Akihiro Tsukada <tskd2@yahoo.co.jp>
 *
 * This module is based off the the gl861 and vp702x modules.
 *
 * This program is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by the Free
 * Software Foundation, version 2.
 *
 * see Documentation/dvb/README.dvb-usb for more information
 */
#include "friio.h"

/* debug */
int dvb_usb_friio_debug;
module_param_named(debug, dvb_usb_friio_debug, int, 0644);
MODULE_PARM_DESC(debug,
		 "set debugging level (1=info,2=xfer,4=rc,8=fe (or-able))."
		 DVB_USB_DEBUG_STATUS);

DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);

/**
 * Indirect I2C access to the PLL via FE.
 * whole I2C protocol data to the PLL is sent via the FE's I2C register.
 * This is done by a control msg to the FE with the I2C data accompanied, and
 * a specific USB request number is assigned for that purpose.
 *
 * this func sends wbuf[1..] to the I2C register wbuf[0] at addr (= at FE).
 * TODO: refoctored, smarter i2c functions.
 */
static int gl861_i2c_ctrlmsg_data(struct dvb_usb_device *d, u8 addr,
				  u8 *wbuf, u16 wlen, u8 *rbuf, u16 rlen)
{
	u16 index = wbuf[0];	/* must be JDVBT90502_2ND_I2C_REG(=0xFE) */
	u16 value = addr << (8 + 1);
	int wo = (rbuf == NULL || rlen == 0);	/* write only */
	u8 req, type;

	deb_xfer("write to PLL:0x%02x via FE reg:0x%02x, len:%d\n",
		 wbuf[1], wbuf[0], wlen - 1);

	if (wo && wlen >= 2) {
		req = GL861_REQ_I2C_DATA_CTRL_WRITE;
		type = GL861_WRITE;
		udelay(20);
		return usb_control_msg(d->udev, usb_sndctrlpipe(d->udev, 0),
				       req, type, value, index,
				       &wbuf[1], wlen - 1, 2000);
	}

	deb_xfer("not supported ctrl-msg, aborting.");
	return -EINVAL;
}

/* normal I2C access (without extra data arguments).
 * write to the register wbuf[0] at I2C address addr with the value wbuf[1],
 *  or read from the register wbuf[0].
 * register address can be 16bit (wbuf[2]<<8 | wbuf[0]) if wlen==3
 */
static int gl861_i2c_msg(struct dvb_usb_device *d, u8 addr,
			 u8 *wbuf, u16 wlen, u8 *rbuf, u16 rlen)
{
	u16 index;
	u16 value = addr << (8 + 1);
	int wo = (rbuf == NULL || rlen == 0);	/* write-only */
	u8 req, type;
	unsigned int pipe;

	/* special case for the indirect I2C access to the PLL via FE, */
	if (addr == friio_fe_config.demod_address &&
	    wbuf[0] == JDVBT90502_2ND_I2C_REG)
		return gl861_i2c_ctrlmsg_data(d, addr, wbuf, wlen, rbuf, rlen);

	if (wo) {
		req = GL861_REQ_I2C_WRITE;
		type = GL861_WRITE;
		pipe = usb_sndctrlpipe(d->udev, 0);
	} else {		/* rw */
		req = GL861_REQ_I2C_READ;
		type = GL861_READ;
		pipe = usb_rcvctrlpipe(d->udev, 0);
	}

	switch (wlen) {
	case 1:
		index = wbuf[0];
		break;
	case 2:
		index = wbuf[0];
		value = value + wbuf[1];
		break;
	case 3:
		/* special case for 16bit register-address */
		index = (wbuf[2] << 8) | wbuf[0];
		value = value + wbuf[1];
		break;
	default:
		deb_xfer("wlen = %x, aborting.", wlen);
		return -EINVAL;
	}
	msleep(1);
	return usb_control_msg(d->udev, pipe, req, type,
			       value, index, rbuf, rlen, 2000);
}

/* I2C */
static int gl861_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msg[],
			  int num)
{
	struct dvb_usb_device *d = i2c_get_adapdata(adap);
	int i;


	if (num > 2)
		return -EINVAL;

	if (mutex_lock_interruptible(&d->i2c_mutex) < 0)
		return -EAGAIN;

	for (i = 0; i < num; i++) {
		/* write/read request */
		if (i + 1 < num && (msg[i + 1].flags & I2C_M_RD)) {
			if (gl861_i2c_msg(d, msg[i].addr,
					  msg[i].buf, msg[i].len,
					  msg[i + 1].buf, msg[i + 1].len) < 0)
				break;
			i++;
		} else
			if (gl861_i2c_msg(d, msg[i].addr, msg[i].buf,
					  msg[i].len, NULL, 0) < 0)
				break;
	}

	mutex_unlock(&d->i2c_mutex);
	return i;
}

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


static int friio_ext_ctl(struct dvb_usb_adapter *adap,
			 u32 sat_color, int lnb_on)
{
	int i;
	int ret;
	struct i2c_msg msg;
	u8 buf[2];
	u32 mask;
	u8 lnb = (lnb_on) ? FRIIO_CTL_LNB : 0;

	msg.addr = 0x00;
	msg.flags = 0;
	msg.len = 2;
	msg.buf = buf;

	buf[0] = 0x00;

	/* send 2bit header (&B10) */
	buf[1] = lnb | FRIIO_CTL_LED | FRIIO_CTL_STROBE;
	ret = gl861_i2c_xfer(&adap->dev->i2c_adap, &msg, 1);
	buf[1] |= FRIIO_CTL_CLK;
	ret += gl861_i2c_xfer(&adap->dev->i2c_adap, &msg, 1);

	buf[1] = lnb | FRIIO_CTL_STROBE;
	ret += gl861_i2c_xfer(&adap->dev->i2c_adap, &msg, 1);
	buf[1] |= FRIIO_CTL_CLK;
	ret += gl861_i2c_xfer(&adap->dev->i2c_adap, &msg, 1);

	/* send 32bit(satur, R, G, B) data in serial */
	mask = 1 << 31;
	for (i = 0; i < 32; i++) {
		buf[1] = lnb | FRIIO_CTL_STROBE;
		if (sat_color & mask)
			buf[1] |= FRIIO_CTL_LED;
		ret += gl861_i2c_xfer(&adap->dev->i2c_adap, &msg, 1);
		buf[1] |= FRIIO_CTL_CLK;
		ret += gl861_i2c_xfer(&adap->dev->i2c_adap, &msg, 1);
		mask >>= 1;
	}

	/* set the strobe off */
	buf[1] = lnb;
	ret += gl861_i2c_xfer(&adap->dev->i2c_adap, &msg, 1);
	buf[1] |= FRIIO_CTL_CLK;
	ret += gl861_i2c_xfer(&adap->dev->i2c_adap, &msg, 1);

	return (ret == 70);
}


static int friio_streaming_ctrl(struct dvb_usb_adapter *adap, int onoff);

/* TODO: move these init cmds to the FE's init routine? */
static u8 streaming_init_cmds[][2] = {
	{0x33, 0x08},
	{0x37, 0x40},
	{0x3A, 0x1F},
	{0x3B, 0xFF},
	{0x3C, 0x1F},
	{0x3D, 0xFF},
	{0x38, 0x00},
	{0x35, 0x00},
	{0x39, 0x00},
	{0x36, 0x00},
};
static int cmdlen = sizeof(streaming_init_cmds) / 2;

/*
 * Command sequence in this init function is a replay
 *  of the captured USB commands from the Windows proprietary driver.
 */
static int friio_initialize(struct dvb_usb_device *d)
{
	int ret;
	int i;
	int retry = 0;
	u8 rbuf[2];
	u8 wbuf[3];

	deb_info("%s called.\n", __func__);

	/* use gl861_i2c_msg instead of gl861_i2c_xfer(), */
	/* because the i2c device is not set up yet. */
	wbuf[0] = 0x11;
	wbuf[1] = 0x02;
	ret = gl861_i2c_msg(d, 0x00, wbuf, 2, NULL, 0);
	if (ret < 0)
		goto error;
	msleep(2);

	wbuf[0] = 0x11;
	wbuf[1] = 0x00;
	ret = gl861_i2c_msg(d, 0x00, wbuf, 2, NULL, 0);
	if (ret < 0)
		goto error;
	msleep(1);

	/* following msgs should be in the FE's init code? */
	/* cmd sequence to identify the device type? (friio black/white) */
	wbuf[0] = 0x03;
	wbuf[1] = 0x80;
	/* can't use gl861_i2c_cmd, as the register-addr is 16bit(0x0100) */
	ret = usb_control_msg(d->udev, usb_sndctrlpipe(d->udev, 0),
			      GL861_REQ_I2C_DATA_CTRL_WRITE, GL861_WRITE,
			      0x1200, 0x0100, wbuf, 2, 2000);
	if (ret < 0)
		goto error;

	msleep(2);
	wbuf[0] = 0x00;
	wbuf[2] = 0x01;		/* reg.0x0100 */
	wbuf[1] = 0x00;
	ret = gl861_i2c_msg(d, 0x12 >> 1, wbuf, 3, rbuf, 2);
	/* my Friio White returns 0xffff. */
	if (ret < 0 || rbuf[0] != 0xff || rbuf[1] != 0xff)
		goto error;

	msleep(2);
	wbuf[0] = 0x03;
	wbuf[1] = 0x80;
	ret = usb_control_msg(d->udev, usb_sndctrlpipe(d->udev, 0),
			      GL861_REQ_I2C_DATA_CTRL_WRITE, GL861_WRITE,
			      0x9000, 0x0100, wbuf, 2, 2000);
	if (ret < 0)
		goto error;

	msleep(2);
	wbuf[0] = 0x00;
	wbuf[2] = 0x01;		/* reg.0x0100 */
	wbuf[1] = 0x00;
	ret = gl861_i2c_msg(d, 0x90 >> 1, wbuf, 3, rbuf, 2);
	/* my Friio White returns 0xffff again. */
	if (ret < 0 || rbuf[0] != 0xff || rbuf[1] != 0xff)
		goto error;

	msleep(1);

restart:
	/* ============ start DEMOD init cmds ================== */
	/* read PLL status to clear the POR bit */
	wbuf[0] = JDVBT90502_2ND_I2C_REG;
	wbuf[1] = (FRIIO_PLL_ADDR << 1) + 1;	/* +1 for reading */
	ret = gl861_i2c_msg(d, FRIIO_DEMOD_ADDR, wbuf, 2, NULL, 0);
	if (ret < 0)
		goto error;

	msleep(5);
	/* note: DEMODULATOR has 16bit register-address. */
	wbuf[0] = 0x00;
	wbuf[2] = 0x01;		/* reg addr: 0x0100 */
	wbuf[1] = 0x00;		/* val: not used */
	ret = gl861_i2c_msg(d, FRIIO_DEMOD_ADDR, wbuf, 3, rbuf, 1);
	if (ret < 0)
		goto error;
/*
	msleep(1);
	wbuf[0] = 0x80;
	wbuf[1] = 0x00;
	ret = gl861_i2c_msg(d, FRIIO_DEMOD_ADDR, wbuf, 2, rbuf, 1);
	if (ret < 0)
		goto error;
 */
	if (rbuf[0] & 0x80) {	/* still in PowerOnReset state? */
		if (++retry > 3) {
			deb_info("failed to get the correct"
				 " FE demod status:0x%02x\n", rbuf[0]);
			goto error;
		}
		msleep(100);
		goto restart;
	}

	/* TODO: check return value in rbuf */
	/* =========== end DEMOD init cmds ===================== */
	msleep(1);

	wbuf[0] = 0x30;
	wbuf[1] = 0x04;
	ret = gl861_i2c_msg(d, 0x00, wbuf, 2, NULL, 0);
	if (ret < 0)
		goto error;

	msleep(2);
	/* following 2 cmds unnecessary? */
	wbuf[0] = 0x00;
	wbuf[1] = 0x01;
	ret = gl861_i2c_msg(d, 0x00, wbuf, 2, NULL, 0);
	if (ret < 0)
		goto error;

	wbuf[0] = 0x06;
	wbuf[1] = 0x0F;
	ret = gl861_i2c_msg(d, 0x00, wbuf, 2, NULL, 0);
	if (ret < 0)
		goto error;

	/* some streaming ctl cmds (maybe) */
	msleep(10);
	for (i = 0; i < cmdlen; i++) {
		ret = gl861_i2c_msg(d, 0x00, streaming_init_cmds[i], 2,
				    NULL, 0);
		if (ret < 0)
			goto error;
		msleep(1);
	}
	msleep(20);

	/* change the LED color etc. */
	ret = friio_streaming_ctrl(&d->adapter[0], 0);
	if (ret < 0)
		goto error;

	return 0;

error:
	deb_info("%s:ret == %d\n", __func__, ret);
	return -EIO;
}

/* Callbacks for DVB USB */

static int friio_streaming_ctrl(struct dvb_usb_adapter *adap, int onoff)
{
	int ret;

	deb_info("%s called.(%d)\n", __func__, onoff);

	/* set the LED color and saturation (and LNB on) */
	if (onoff)
		ret = friio_ext_ctl(adap, 0x6400ff64, 1);
	else
		ret = friio_ext_ctl(adap, 0x96ff00ff, 1);

	if (ret != 1) {
		deb_info("%s failed to send cmdx. ret==%d\n", __func__, ret);
		return -EREMOTEIO;
	}
	return 0;
}

static int friio_frontend_attach(struct dvb_usb_adapter *adap)
{
	if (friio_initialize(adap->dev) < 0)
		return -EIO;

	adap->fe = jdvbt90502_attach(adap->dev);
	if (adap->fe == NULL)
		return -EIO;

	return 0;
}

/* DVB USB Driver stuff */
static struct dvb_usb_device_properties friio_properties;

static int friio_probe(struct usb_interface *intf,
		       const struct usb_device_id *id)
{
	struct dvb_usb_device *d;
	struct usb_host_interface *alt;
	int ret;

	if (intf->num_altsetting < GL861_ALTSETTING_COUNT)
		return -ENODEV;

	alt = usb_altnum_to_altsetting(intf, FRIIO_BULK_ALTSETTING);
	if (alt == NULL) {
		deb_rc("not alt found!\n");
		return -ENODEV;
	}
	ret = usb_set_interface(interface_to_usbdev(intf),
				alt->desc.bInterfaceNumber,
				alt->desc.bAlternateSetting);
	if (ret != 0) {
		deb_rc("failed to set alt-setting!\n");
		return ret;
	}

	ret = dvb_usb_device_init(intf, &friio_properties,
				  THIS_MODULE, &d, adapter_nr);
	if (ret == 0)
		friio_streaming_ctrl(&d->adapter[0], 1);

	return ret;
}


struct jdvbt90502_config friio_fe_config = {
	.demod_address = FRIIO_DEMOD_ADDR,
	.pll_address = FRIIO_PLL_ADDR,
};

static struct i2c_algorithm gl861_i2c_algo = {
	.master_xfer   = gl861_i2c_xfer,
	.functionality = gl861_i2c_func,
};

static struct usb_device_id friio_table[] = {
	{ USB_DEVICE(USB_VID_774, USB_PID_FRIIO_WHITE) },
	{ }		/* Terminating entry */
};
MODULE_DEVICE_TABLE(usb, friio_table);


static struct dvb_usb_device_properties friio_properties = {
	.caps = DVB_USB_IS_AN_I2C_ADAPTER,
	.usb_ctrl = DEVICE_SPECIFIC,

	.size_of_priv = 0,

	.num_adapters = 1,
	.adapter = {
		/* caps:0 =>  no pid filter, 188B TS packet */
		/* GL861 has a HW pid filter, but no info available. */
		{
			.caps  = 0,

			.frontend_attach  = friio_frontend_attach,
			.streaming_ctrl = friio_streaming_ctrl,

			.stream = {
				.type = USB_BULK,
				/* count <= MAX_NO_URBS_FOR_DATA_STREAM(10) */
				.count = 8,
				.endpoint = 0x01,
				.u = {
					/* GL861 has 6KB buf inside */
					.bulk = {
						.buffersize = 16384,
					}
				}
			},
		}
	},
	.i2c_algo = &gl861_i2c_algo,

	.num_device_descs = 1,
	.devices = {
		{
			.name = "774 Friio ISDB-T USB2.0",
			.cold_ids = { NULL },
			.warm_ids = { &friio_table[0], NULL },
		},
	}
};

static struct usb_driver friio_driver = {
	.name		= "dvb_usb_friio",
	.probe		= friio_probe,
	.disconnect	= dvb_usb_device_exit,
	.id_table	= friio_table,
};


/* module stuff */
static int __init friio_module_init(void)
{
	int ret;

	ret = usb_register(&friio_driver);
	if (ret)
		err("usb_register failed. Error number %d", ret);

	return ret;
}


static void __exit friio_module_exit(void)
{
	/* deregister this driver from the USB subsystem */
	usb_deregister(&friio_driver);
}

module_init(friio_module_init);
module_exit(friio_module_exit);

MODULE_AUTHOR("Akihiro Tsukada <tskd2@yahoo.co.jp>");
MODULE_DESCRIPTION("Driver for Friio ISDB-T USB2.0 Receiver");
MODULE_VERSION("0.2");
MODULE_LICENSE("GPL");
