/* DVB USB framework compliant Linux driver for the Opera1 DVB-S Card
*
* Copyright (C) 2006 Mario Hlawitschka (dh1pa@amsat.org)
* Copyright (C) 2006 Marco Gittler (g.marco@freenet.de)
*
*	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
*/

#define DVB_USB_LOG_PREFIX "opera"

#include "dvb-usb.h"
#include "stv0299.h"

#define OPERA_READ_MSG 0
#define OPERA_WRITE_MSG 1
#define OPERA_I2C_TUNER 0xd1

#define READ_FX2_REG_REQ  0xba
#define READ_MAC_ADDR 0x08
#define OPERA_WRITE_FX2 0xbb
#define OPERA_TUNER_REQ 0xb1
#define REG_1F_SYMBOLRATE_BYTE0 0x1f
#define REG_20_SYMBOLRATE_BYTE1 0x20
#define REG_21_SYMBOLRATE_BYTE2 0x21

#define ADDR_B600_VOLTAGE_13V (0x02)
#define ADDR_B601_VOLTAGE_18V (0x03)
#define ADDR_B1A6_STREAM_CTRL (0x04)
#define ADDR_B880_READ_REMOTE (0x05)

struct opera1_state {
	u32 last_key_pressed;
};
struct opera_rc_keys {
	u32 keycode;
	u32 event;
};

static int dvb_usb_opera1_debug;
module_param_named(debug, dvb_usb_opera1_debug, int, 0644);
MODULE_PARM_DESC(debug,
		 "set debugging level (1=info,xfer=2,pll=4,ts=8,err=16,rc=32,fw=64 (or-able))."
		 DVB_USB_DEBUG_STATUS);

DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);


static int opera1_xilinx_rw(struct usb_device *dev, u8 request, u16 value,
			    u8 * data, u16 len, int flags)
{
	int ret;
	u8 r;
	u8 u8buf[len];

	unsigned int pipe = (flags == OPERA_READ_MSG) ?
		usb_rcvctrlpipe(dev,0) : usb_sndctrlpipe(dev, 0);
	u8 request_type = (flags == OPERA_READ_MSG) ? USB_DIR_IN : USB_DIR_OUT;

	if (flags == OPERA_WRITE_MSG)
		memcpy(u8buf, data, len);
	ret =
		usb_control_msg(dev, pipe, request, request_type | USB_TYPE_VENDOR,
			value, 0x0, u8buf, len, 2000);

	if (request == OPERA_TUNER_REQ) {
		if (usb_control_msg(dev, usb_rcvctrlpipe(dev, 0),
				OPERA_TUNER_REQ, USB_DIR_IN | USB_TYPE_VENDOR,
				0x01, 0x0, &r, 1, 2000)<1 || r!=0x08)
					return 0;
	}
	if (flags == OPERA_READ_MSG)
		memcpy(data, u8buf, len);
	return ret;
}

/* I2C */

static int opera1_usb_i2c_msgxfer(struct dvb_usb_device *dev, u16 addr,
				  u8 * buf, u16 len)
{
	int ret = 0;
	u8 request;
	u16 value;

	if (!dev) {
		info("no usb_device");
		return -EINVAL;
	}
	if (mutex_lock_interruptible(&dev->usb_mutex) < 0)
		return -EAGAIN;

	switch (addr>>1){
		case ADDR_B600_VOLTAGE_13V:
			request=0xb6;
			value=0x00;
			break;
		case ADDR_B601_VOLTAGE_18V:
			request=0xb6;
			value=0x01;
			break;
		case ADDR_B1A6_STREAM_CTRL:
			request=0xb1;
			value=0xa6;
			break;
		case ADDR_B880_READ_REMOTE:
			request=0xb8;
			value=0x80;
			break;
		default:
			request=0xb1;
			value=addr;
	}
	ret = opera1_xilinx_rw(dev->udev, request,
		value, buf, len,
		addr&0x01?OPERA_READ_MSG:OPERA_WRITE_MSG);

	mutex_unlock(&dev->usb_mutex);
	return ret;
}

static int opera1_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msg[],
			   int num)
{
	struct dvb_usb_device *d = i2c_get_adapdata(adap);
	int i = 0, tmp = 0;

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

	for (i = 0; i < num; i++) {
		if ((tmp = opera1_usb_i2c_msgxfer(d,
					(msg[i].addr<<1)|(msg[i].flags&I2C_M_RD?0x01:0),
					msg[i].buf,
					msg[i].len
					)!= msg[i].len)) {
			break;
		}
		if (dvb_usb_opera1_debug & 0x10)
			info("sending i2c mesage %d %d", tmp, msg[i].len);
	}
	mutex_unlock(&d->i2c_mutex);
	return num;
}

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

static struct i2c_algorithm opera1_i2c_algo = {
	.master_xfer = opera1_i2c_xfer,
	.functionality = opera1_i2c_func,
};

static int opera1_set_voltage(struct dvb_frontend *fe, fe_sec_voltage_t voltage)
{
	static u8 command_13v[1]={0x00};
	static u8 command_18v[1]={0x01};
	struct i2c_msg msg[] = {
		{.addr = ADDR_B600_VOLTAGE_13V,.flags = 0,.buf = command_13v,.len = 1},
	};
	struct dvb_usb_adapter *udev_adap =
	    (struct dvb_usb_adapter *)(fe->dvb->priv);
	if (voltage == SEC_VOLTAGE_18) {
		msg[0].addr = ADDR_B601_VOLTAGE_18V;
		msg[0].buf = command_18v;
	}
	i2c_transfer(&udev_adap->dev->i2c_adap, msg, 1);
	return 0;
}

static int opera1_stv0299_set_symbol_rate(struct dvb_frontend *fe, u32 srate,
					  u32 ratio)
{
	stv0299_writereg(fe, 0x13, 0x98);
	stv0299_writereg(fe, 0x14, 0x95);
	stv0299_writereg(fe, REG_1F_SYMBOLRATE_BYTE0, (ratio >> 16) & 0xff);
	stv0299_writereg(fe, REG_20_SYMBOLRATE_BYTE1, (ratio >> 8) & 0xff);
	stv0299_writereg(fe, REG_21_SYMBOLRATE_BYTE2, (ratio) & 0xf0);
	return 0;

}
static u8 opera1_inittab[] = {
	0x00, 0xa1,
	0x01, 0x15,
	0x02, 0x00,
	0x03, 0x00,
	0x04, 0x7d,
	0x05, 0x05,
	0x06, 0x02,
	0x07, 0x00,
	0x0b, 0x00,
	0x0c, 0x01,
	0x0d, 0x81,
	0x0e, 0x44,
	0x0f, 0x19,
	0x10, 0x3f,
	0x11, 0x84,
	0x12, 0xda,
	0x13, 0x98,
	0x14, 0x95,
	0x15, 0xc9,
	0x16, 0xeb,
	0x17, 0x00,
	0x18, 0x19,
	0x19, 0x8b,
	0x1a, 0x00,
	0x1b, 0x82,
	0x1c, 0x7f,
	0x1d, 0x00,
	0x1e, 0x00,
	REG_1F_SYMBOLRATE_BYTE0, 0x06,
	REG_20_SYMBOLRATE_BYTE1, 0x50,
	REG_21_SYMBOLRATE_BYTE2, 0x10,
	0x22, 0x00,
	0x23, 0x00,
	0x24, 0x37,
	0x25, 0xbc,
	0x26, 0x00,
	0x27, 0x00,
	0x28, 0x00,
	0x29, 0x1e,
	0x2a, 0x14,
	0x2b, 0x1f,
	0x2c, 0x09,
	0x2d, 0x0a,
	0x2e, 0x00,
	0x2f, 0x00,
	0x30, 0x00,
	0x31, 0x1f,
	0x32, 0x19,
	0x33, 0xfc,
	0x34, 0x13,
	0xff, 0xff,
};

static struct stv0299_config opera1_stv0299_config = {
	.demod_address = 0xd0>>1,
	.min_delay_ms = 100,
	.mclk = 88000000UL,
	.invert = 1,
	.skip_reinit = 0,
	.lock_output = STV0299_LOCKOUTPUT_0,
	.volt13_op0_op1 = STV0299_VOLT13_OP0,
	.inittab = opera1_inittab,
	.set_symbol_rate = opera1_stv0299_set_symbol_rate,
};

static int opera1_frontend_attach(struct dvb_usb_adapter *d)
{
	if ((d->fe =
	     dvb_attach(stv0299_attach, &opera1_stv0299_config,
			&d->dev->i2c_adap)) != NULL) {
		d->fe->ops.set_voltage = opera1_set_voltage;
		return 0;
	}
	info("not attached stv0299");
	return -EIO;
}

static int opera1_tuner_attach(struct dvb_usb_adapter *adap)
{
	dvb_attach(
		dvb_pll_attach, adap->fe, 0xc0>>1,
		&adap->dev->i2c_adap, DVB_PLL_OPERA1
	);
	return 0;
}

static int opera1_power_ctrl(struct dvb_usb_device *d, int onoff)
{
	u8 val = onoff ? 0x01 : 0x00;

	if (dvb_usb_opera1_debug)
		info("power %s", onoff ? "on" : "off");
	return opera1_xilinx_rw(d->udev, 0xb7, val,
				&val, 1, OPERA_WRITE_MSG);
}

static int opera1_streaming_ctrl(struct dvb_usb_adapter *adap, int onoff)
{
	static u8 buf_start[2] = { 0xff, 0x03 };
	static u8 buf_stop[2] = { 0xff, 0x00 };
	struct i2c_msg start_tuner[] = {
		{.addr = ADDR_B1A6_STREAM_CTRL,.buf = onoff ? buf_start : buf_stop,.len = 2},
	};
	if (dvb_usb_opera1_debug)
		info("streaming %s", onoff ? "on" : "off");
	i2c_transfer(&adap->dev->i2c_adap, start_tuner, 1);
	return 0;
}

static int opera1_pid_filter(struct dvb_usb_adapter *adap, int index, u16 pid,
			     int onoff)
{
	u8 b_pid[3];
	struct i2c_msg msg[] = {
		{.addr = ADDR_B1A6_STREAM_CTRL,.buf = b_pid,.len = 3},
	};
	if (dvb_usb_opera1_debug)
		info("pidfilter index: %d pid: %d %s", index, pid,
			onoff ? "on" : "off");
	b_pid[0] = (2 * index) + 4;
	b_pid[1] = onoff ? (pid & 0xff) : (0x00);
	b_pid[2] = onoff ? ((pid >> 8) & 0xff) : (0x00);
	i2c_transfer(&adap->dev->i2c_adap, msg, 1);
	return 0;
}

static int opera1_pid_filter_control(struct dvb_usb_adapter *adap, int onoff)
{
	int u = 0x04;
	u8 b_pid[3];
	struct i2c_msg msg[] = {
		{.addr = ADDR_B1A6_STREAM_CTRL,.buf = b_pid,.len = 3},
	};
	if (dvb_usb_opera1_debug)
		info("%s hw-pidfilter", onoff ? "enable" : "disable");
	for (; u < 0x7e; u += 2) {
		b_pid[0] = u;
		b_pid[1] = 0;
		b_pid[2] = 0x80;
		i2c_transfer(&adap->dev->i2c_adap, msg, 1);
	}
	return 0;
}

static struct dvb_usb_rc_key opera1_rc_keys[] = {
	{0x5fa0, KEY_1},
	{0x51af, KEY_2},
	{0x5da2, KEY_3},
	{0x41be, KEY_4},
	{0x0bf5, KEY_5},
	{0x43bd, KEY_6},
	{0x47b8, KEY_7},
	{0x49b6, KEY_8},
	{0x05fa, KEY_9},
	{0x45ba, KEY_0},
	{0x09f6, KEY_UP},	/*chanup */
	{0x1be5, KEY_DOWN},	/*chandown */
	{0x5da3, KEY_LEFT},	/*voldown */
	{0x5fa1, KEY_RIGHT},	/*volup */
	{0x07f8, KEY_SPACE},	/*tab */
	{0x1fe1, KEY_ENTER},	/*play ok */
	{0x1be4, KEY_Z},	/*zoom */
	{0x59a6, KEY_M},	/*mute */
	{0x5ba5, KEY_F},	/*tv/f */
	{0x19e7, KEY_R},	/*rec */
	{0x01fe, KEY_S},	/*Stop */
	{0x03fd, KEY_P},	/*pause */
	{0x03fc, KEY_W},	/*<- -> */
	{0x07f9, KEY_C},	/*capture */
	{0x47b9, KEY_Q},	/*exit */
	{0x43bc, KEY_O},	/*power */

};

static int opera1_rc_query(struct dvb_usb_device *dev, u32 * event, int *state)
{
	struct opera1_state *opst = dev->priv;
	u8 rcbuffer[32];
	const u16 startmarker1 = 0x10ed;
	const u16 startmarker2 = 0x11ec;
	struct i2c_msg read_remote[] = {
		{.addr = ADDR_B880_READ_REMOTE,.buf = rcbuffer,.flags = I2C_M_RD,.len = 32},
	};
	int i = 0;
	u32 send_key = 0;

	if (i2c_transfer(&dev->i2c_adap, read_remote, 1) == 1) {
		for (i = 0; i < 32; i++) {
			if (rcbuffer[i])
				send_key |= 1;
			if (i < 31)
				send_key = send_key << 1;
		}
		if (send_key & 0x8000)
			send_key = (send_key << 1) | (send_key >> 15 & 0x01);

		if (send_key == 0xffff && opst->last_key_pressed != 0) {
			*state = REMOTE_KEY_REPEAT;
			*event = opst->last_key_pressed;
			return 0;
		}
		for (; send_key != 0;) {
			if (send_key >> 16 == startmarker2) {
				break;
			} else if (send_key >> 16 == startmarker1) {
				send_key =
					(send_key & 0xfffeffff) | (startmarker1 << 16);
				break;
			} else
				send_key >>= 1;
		}

		if (send_key == 0)
			return 0;

		send_key = (send_key & 0xffff) | 0x0100;

		for (i = 0; i < ARRAY_SIZE(opera1_rc_keys); i++) {
			if (rc5_scan(&opera1_rc_keys[i]) == (send_key & 0xffff)) {
				*state = REMOTE_KEY_PRESSED;
				*event = opera1_rc_keys[i].event;
				opst->last_key_pressed =
					opera1_rc_keys[i].event;
				break;
			}
			opst->last_key_pressed = 0;
		}
	} else
		*state = REMOTE_NO_KEY_PRESSED;
	return 0;
}

static struct usb_device_id opera1_table[] = {
	{USB_DEVICE(USB_VID_CYPRESS, USB_PID_OPERA1_COLD)},
	{USB_DEVICE(USB_VID_OPERA1, USB_PID_OPERA1_WARM)},
	{}
};

MODULE_DEVICE_TABLE(usb, opera1_table);

static int opera1_read_mac_address(struct dvb_usb_device *d, u8 mac[6])
{
	u8 command[] = { READ_MAC_ADDR };
	opera1_xilinx_rw(d->udev, 0xb1, 0xa0, command, 1, OPERA_WRITE_MSG);
	opera1_xilinx_rw(d->udev, 0xb1, 0xa1, mac, 6, OPERA_READ_MSG);
	return 0;
}
static int opera1_xilinx_load_firmware(struct usb_device *dev,
				       const char *filename)
{
	const struct firmware *fw = NULL;
	u8 *b, *p;
	int ret = 0, i,fpgasize=40;
	u8 testval;
	info("start downloading fpga firmware %s",filename);

	if ((ret = request_firmware(&fw, filename, &dev->dev)) != 0) {
		err("did not find the firmware file. (%s) "
			"Please see linux/Documentation/dvb/ for more details on firmware-problems.",
			filename);
		return ret;
	} else {
		p = kmalloc(fw->size, GFP_KERNEL);
		opera1_xilinx_rw(dev, 0xbc, 0x00, &testval, 1, OPERA_READ_MSG);
		if (p != NULL && testval != 0x67) {

			u8 reset = 0, fpga_command = 0;
			memcpy(p, fw->data, fw->size);
			/* clear fpga ? */
			opera1_xilinx_rw(dev, 0xbc, 0xaa, &fpga_command, 1,
					 OPERA_WRITE_MSG);
			for (i = 0; i < fw->size;) {
				if ( (fw->size - i) <fpgasize){
				    fpgasize=fw->size-i;
				}
				b = (u8 *) p + i;
				if (opera1_xilinx_rw
					(dev, OPERA_WRITE_FX2, 0x0, b , fpgasize,
						OPERA_WRITE_MSG) != fpgasize
					) {
					err("error while transferring firmware");
					ret = -EINVAL;
					break;
				}
				i = i + fpgasize;
			}
			/* restart the CPU */
			if (ret || opera1_xilinx_rw
					(dev, 0xa0, 0xe600, &reset, 1,
					OPERA_WRITE_MSG) != 1) {
				err("could not restart the USB controller CPU.");
				ret = -EINVAL;
			}
		}
	}
	kfree(p);
	if (fw) {
		release_firmware(fw);
	}
	return ret;
}

static struct dvb_usb_device_properties opera1_properties = {
	.caps = DVB_USB_IS_AN_I2C_ADAPTER,
	.usb_ctrl = CYPRESS_FX2,
	.firmware = "dvb-usb-opera-01.fw",
	.size_of_priv = sizeof(struct opera1_state),

	.power_ctrl = opera1_power_ctrl,
	.i2c_algo = &opera1_i2c_algo,

	.rc_key_map = opera1_rc_keys,
	.rc_key_map_size = ARRAY_SIZE(opera1_rc_keys),
	.rc_interval = 200,
	.rc_query = opera1_rc_query,
	.read_mac_address = opera1_read_mac_address,
	.generic_bulk_ctrl_endpoint = 0x00,
	/* parameter for the MPEG2-data transfer */
	.num_adapters = 1,
	.adapter = {
		{
			.frontend_attach = opera1_frontend_attach,
			.streaming_ctrl = opera1_streaming_ctrl,
			.tuner_attach = opera1_tuner_attach,
			.caps =
				DVB_USB_ADAP_HAS_PID_FILTER |
				DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF,
			.pid_filter = opera1_pid_filter,
			.pid_filter_ctrl = opera1_pid_filter_control,
			.pid_filter_count = 252,
			.stream = {
				.type = USB_BULK,
				.count = 10,
				.endpoint = 0x82,
				.u = {
					.bulk = {
						.buffersize = 4096,
					}
				}
			},
		}
	},
	.num_device_descs = 1,
	.devices = {
		{"Opera1 DVB-S USB2.0",
			{&opera1_table[0], NULL},
			{&opera1_table[1], NULL},
		},
	}
};

static int opera1_probe(struct usb_interface *intf,
			const struct usb_device_id *id)
{
	struct usb_device *udev = interface_to_usbdev(intf);

	if (udev->descriptor.idProduct == USB_PID_OPERA1_WARM &&
		udev->descriptor.idVendor == USB_VID_OPERA1 &&
		opera1_xilinx_load_firmware(udev, "dvb-usb-opera1-fpga-01.fw") != 0
	    ) {
		return -EINVAL;
	}

	if (0 != dvb_usb_device_init(intf, &opera1_properties,
				     THIS_MODULE, NULL, adapter_nr))
		return -EINVAL;
	return 0;
}

static struct usb_driver opera1_driver = {
	.name = "opera1",
	.probe = opera1_probe,
	.disconnect = dvb_usb_device_exit,
	.id_table = opera1_table,
};

static int __init opera1_module_init(void)
{
	int result = 0;
	if ((result = usb_register(&opera1_driver))) {
		err("usb_register failed. Error number %d", result);
	}
	return result;
}

static void __exit opera1_module_exit(void)
{
	usb_deregister(&opera1_driver);
}

module_init(opera1_module_init);
module_exit(opera1_module_exit);

MODULE_AUTHOR("Mario Hlawitschka (c) dh1pa@amsat.org");
MODULE_AUTHOR("Marco Gittler (c) g.marco@freenet.de");
MODULE_DESCRIPTION("Driver for Opera1 DVB-S device");
MODULE_VERSION("0.1");
MODULE_LICENSE("GPL");
