/* DVB USB compliant linux driver for Nebula Electronics uDigiTV DVB-T USB2.0
 * receiver
 *
 * Copyright (C) 2005 Patrick Boettcher (patrick.boettcher@desy.de)
 *
 * partly based on the SDK published by Nebula Electronics
 *
 *	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 "digitv.h"

#include "mt352.h"
#include "nxt6000.h"

/* debug */
int dvb_usb_digitv_debug;
module_param_named(debug,dvb_usb_digitv_debug, int, 0644);
MODULE_PARM_DESC(debug, "set debugging level (1=rc (or-able))." DVB_USB_DEBUG_STATUS);

static int digitv_ctrl_msg(struct dvb_usb_device *d,
		u8 cmd, u8 vv, u8 *wbuf, int wlen, u8 *rbuf, int rlen)
{
	int wo = (rbuf == NULL || rlen == 0); /* write-only */
	u8 sndbuf[7],rcvbuf[7];
	memset(sndbuf,0,7); memset(rcvbuf,0,7);

	sndbuf[0] = cmd;
	sndbuf[1] = vv;
	sndbuf[2] = wo ? wlen : rlen;

	if (wo) {
		memcpy(&sndbuf[3],wbuf,wlen);
		dvb_usb_generic_write(d,sndbuf,7);
	} else {
		dvb_usb_generic_rw(d,sndbuf,7,rcvbuf,7,10);
		memcpy(rbuf,&rcvbuf[3],rlen);
	}
	return 0;
}

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

	if (down_interruptible(&d->i2c_sem) < 0)
		return -EAGAIN;

	if (num > 2)
		warn("more than 2 i2c messages at a time is not handled yet. TODO.");

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

	up(&d->i2c_sem);
	return i;
}

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

static struct i2c_algorithm digitv_i2c_algo = {
	.master_xfer   = digitv_i2c_xfer,
	.functionality = digitv_i2c_func,
};

/* Callbacks for DVB USB */
static int digitv_identify_state (struct usb_device *udev, struct
		dvb_usb_properties *props, struct dvb_usb_device_description **desc,
		int *cold)
{
	*cold = udev->descriptor.iManufacturer == 0 && udev->descriptor.iProduct == 0;
	return 0;
}

static int digitv_mt352_demod_init(struct dvb_frontend *fe)
{
	static u8 reset_buf[] = { 0x89, 0x38,  0x8a, 0x2d, 0x50, 0x80 };
	static u8 init_buf[] = { 0x68, 0xa0,  0x8e, 0x40,  0x53, 0x50,
			0x67, 0x20,  0x7d, 0x01,  0x7c, 0x00,  0x7a, 0x00,
			0x79, 0x20,  0x57, 0x05,  0x56, 0x31,  0x88, 0x0f,
			0x75, 0x32 };
	int i;

	for (i = 0; i < ARRAY_SIZE(reset_buf); i += 2)
		mt352_write(fe, &reset_buf[i], 2);

	msleep(1);

	for (i = 0; i < ARRAY_SIZE(init_buf); i += 2)
		mt352_write(fe, &init_buf[i], 2);

	return 0;
}

static struct mt352_config digitv_mt352_config = {
	.demod_init = digitv_mt352_demod_init,
	.pll_set = dvb_usb_pll_set,
};

static int digitv_nxt6000_pll_set(struct dvb_frontend *fe, struct dvb_frontend_parameters *fep)
{
	struct dvb_usb_device *d = fe->dvb->priv;
	u8 b[5];
	dvb_usb_pll_set(fe,fep,b);
	return digitv_ctrl_msg(d,USB_WRITE_TUNER,0,&b[1],4,NULL,0);
}

static struct nxt6000_config digitv_nxt6000_config = {
	.clock_inversion = 1,
	.pll_set = digitv_nxt6000_pll_set,
};

static int digitv_frontend_attach(struct dvb_usb_device *d)
{
	if ((d->fe = mt352_attach(&digitv_mt352_config, &d->i2c_adap)) != NULL ||
		(d->fe = nxt6000_attach(&digitv_nxt6000_config, &d->i2c_adap)) != NULL)
		return 0;
	return -EIO;
}

static int digitv_tuner_attach(struct dvb_usb_device *d)
{
	d->pll_addr = 0x60;
	d->pll_desc = &dvb_pll_tded4;
	return 0;
}

static struct dvb_usb_rc_key digitv_rc_keys[] = {
	{ 0x00, 0x16, KEY_POWER }, /* dummy key */
};

/* TODO is it really the NEC protocol ? */
static int digitv_rc_query(struct dvb_usb_device *d, u32 *event, int *state)
{
	u8 key[5];

	digitv_ctrl_msg(d,USB_READ_REMOTE,0,NULL,0,&key[1],4);
	/* TODO state, maybe it is VV ? */
	if (key[1] != 0)
		key[0] = 0x01; /* if something is inside the buffer, simulate key press */

	/* call the universal NEC remote processor, to find out the key's state and event */
	dvb_usb_nec_rc_key_to_event(d,key,event,state);
	if (key[0] != 0)
		deb_rc("key: %x %x %x %x %x\n",key[0],key[1],key[2],key[3],key[4]);
	return 0;
}

/* DVB USB Driver stuff */
static struct dvb_usb_properties digitv_properties;

static int digitv_probe(struct usb_interface *intf,
		const struct usb_device_id *id)
{
	struct dvb_usb_device *d;
	int ret;
	if ((ret = dvb_usb_device_init(intf,&digitv_properties,THIS_MODULE,&d)) == 0) {
		u8 b[4] = { 0 };

		if (d != NULL) { /* do that only when the firmware is loaded */
			b[0] = 1;
			digitv_ctrl_msg(d,USB_WRITE_REMOTE_TYPE,0,b,4,NULL,0);

			b[0] = 0;
			digitv_ctrl_msg(d,USB_WRITE_REMOTE,0,b,4,NULL,0);
		}
	}
	return ret;
}

static struct usb_device_id digitv_table [] = {
		{ USB_DEVICE(USB_VID_ANCHOR, USB_PID_NEBULA_DIGITV) },
		{ }		/* Terminating entry */
};
MODULE_DEVICE_TABLE (usb, digitv_table);

static struct dvb_usb_properties digitv_properties = {
	.caps = DVB_USB_IS_AN_I2C_ADAPTER,

	.usb_ctrl = CYPRESS_FX2,
	.firmware = "dvb-usb-digitv-02.fw",

	.size_of_priv     = 0,

	.frontend_attach  = digitv_frontend_attach,
	.tuner_attach     = digitv_tuner_attach,

	.rc_interval      = 1000,
	.rc_key_map       = digitv_rc_keys,
	.rc_key_map_size  = ARRAY_SIZE(digitv_rc_keys),
	.rc_query         = digitv_rc_query,

	.identify_state   = digitv_identify_state,

	.i2c_algo         = &digitv_i2c_algo,

	.generic_bulk_ctrl_endpoint = 0x01,
	/* parameter for the MPEG2-data transfer */
	.urb = {
		.type = DVB_USB_BULK,
		.count = 7,
		.endpoint = 0x02,
		.u = {
			.bulk = {
				.buffersize = 4096,
			}
		}
	},

	.num_device_descs = 1,
	.devices = {
		{   "Nebula Electronics uDigiTV DVB-T USB2.0)",
			{ &digitv_table[0], NULL },
			{ NULL },
		},
		{ NULL },
	}
};

static struct usb_driver digitv_driver = {
	.name		= "dvb_usb_digitv",
	.probe		= digitv_probe,
	.disconnect = dvb_usb_device_exit,
	.id_table	= digitv_table,
};

/* module stuff */
static int __init digitv_module_init(void)
{
	int result;
	if ((result = usb_register(&digitv_driver))) {
		err("usb_register failed. Error number %d",result);
		return result;
	}

	return 0;
}

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

module_init (digitv_module_init);
module_exit (digitv_module_exit);

MODULE_AUTHOR("Patrick Boettcher <patrick.boettcher@desy.de>");
MODULE_DESCRIPTION("Driver for Nebula Electronics uDigiTV DVB-T USB2.0");
MODULE_VERSION("1.0-alpha");
MODULE_LICENSE("GPL");
