[PATCH] Initial Support for Opera USB2.0 DVB-S Adapter

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hi

Attached is a patch for v4l-dvb , for the Opera DVB-S USB2.0 Adapter.
It should work for the dvb stuff 100% and for RC-Stuff nearly 100%(slow 
response to keys some times)
3 firmware files are needed which can be found after a search with google (or 
can i upload these files somwhere ?)


Signed-of-by: Marci Gittler <g.marco@xxxxxxxxxx>
Signed-of-by: Mario Hlawitschka <dh1pa@xxxxxxxxx>
diff -r 42b9d09cff15 linux/drivers/media/dvb/dvb-usb/Kconfig
--- a/linux/drivers/media/dvb/dvb-usb/Kconfig	Fri Feb 23 10:34:37 2007 -0200
+++ b/linux/drivers/media/dvb/dvb-usb/Kconfig	Sat Feb 24 14:04:44 2007 +0100
@@ -208,3 +208,12 @@ config DVB_USB_DTT200U
 	  The receivers are also known as DTT200U (Yakumo) and UB300 (Yuan).
 
 	  The WT-220U and its clones are pen-sized.
+
+config DVB_USB_OPERA1
+        tristate "Opera1 DVB-S USB2.0 receiver."
+        depends on DVB_USB
+        select DVB_STV0299
+        help
+	    Say Y here to support the Opera DVB-S  USB2.0 receiver.
+					  
+					  
\ No newline at end of file
diff -r 42b9d09cff15 linux/drivers/media/dvb/dvb-usb/Makefile
--- a/linux/drivers/media/dvb/dvb-usb/Makefile	Fri Feb 23 10:34:37 2007 -0200
+++ b/linux/drivers/media/dvb/dvb-usb/Makefile	Sat Feb 24 14:03:40 2007 +0100
@@ -51,4 +51,9 @@ dvb-usb-dib0700-objs = dib0700_core.o di
 dvb-usb-dib0700-objs = dib0700_core.o dib0700_devices.o
 obj-$(CONFIG_DVB_USB_DIB0700) += dvb-usb-dib0700.o
 
+dvb-opera-usb-objs = opera1.o
+
+obj-$(CONFIG_DVB_USB_OPERA1) += dvb-opera-usb.o
+
+
 EXTRA_CFLAGS = -Idrivers/media/dvb/dvb-core/ -Idrivers/media/dvb/frontends/
diff -r 42b9d09cff15 linux/drivers/media/dvb/dvb-usb/opera1.c
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/linux/drivers/media/dvb/dvb-usb/opera1.c	Sat Feb 24 14:00:55 2007 +0100
@@ -0,0 +1,631 @@
+/* DVB USB framework compliant Linux driver for the Opera1 DVB-S Card
+*
+* Copyright (C) 2006 Mario Hlawitschka (dh1pa@xxxxxxxxx)
+* Copyright (C) 2006 Marco Gittler (g.marco@xxxxxxxxxx)
+*
+*	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 "linux/module.h"
+#include "linux/init.h"
+#include "linux/firmware.h"
+#include "stv0299.h"
+
+#include "opera1.h"
+
+static u32 last_key_pressed=-1;
+
+static const char* xilinx_init="\x90\x6e\xc5\xfa\x32\xd0\x73\x23\x1e";
+static int opera1_xilinx_load_firmware(struct usb_device *dev, const char *filename);
+
+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);
+//struct mutex mymutex;
+
+int opera1_xilinx_rw(struct usb_device*dev, u8 request, u16 value, u8*data, u16 len,int flags){
+
+	int ret=0,t=0;
+	char r[10];
+	u8 u8buf[len];
+	unsigned int pipe=(flags==1)?usb_rcvctrlpipe(dev,0):usb_sndctrlpipe(dev,0);
+	u8 request_type=(flags==1)?USB_DIR_IN:USB_DIR_OUT;
+
+
+	//if (mutex_lock_interruptible(&mymutex)){
+	//    return -EAGAIN;
+	//}
+
+
+	if (flags==0)
+	    memcpy(u8buf,data,len);
+	ret=usb_control_msg(dev, pipe,request, request_type| USB_TYPE_VENDOR,value, 0x0 /*index*/, u8buf,len, 2000);
+	//msleep(20);
+	if (request==OPERA_TUNER_REQ){
+		t=usb_control_msg(dev, usb_rcvctrlpipe(dev,0),
+		OPERA_TUNER_REQ, USB_DIR_IN|USB_TYPE_VENDOR, 0x01,0x0/*index*/, r, 10, 2000);
+	}
+	if (flags==1)
+	    memcpy(data,u8buf,len);
+	//mutex_unlock(&mymutex);
+	return ret;
+	
+}
+int opera1_xilinx_read(struct usb_device*dev, u8 request, u16 value, u8*data, u16 len){
+    return opera1_xilinx_rw(dev,request,value,data,len,1);
+}
+int opera1_xilinx_send(struct usb_device*dev, u8 request, u16 value, u8*data, u16 len){
+    return opera1_xilinx_rw(dev,request,value,data,len,0);
+}
+
+/* I2C */
+
+static int opera1_usb_i2c_xfer(struct dvb_usb_device* dev,struct i2c_msg msg[],int num)
+{
+	int i;
+	u8 request;
+	u16 value;
+	//return 0;
+	if (dev==NULL){
+		info ("no usb_device");
+		return -EINVAL;
+	}
+	if (mutex_lock_interruptible(&dev->i2c_mutex) < 0)
+		return -EAGAIN;
+	for (i = 0; i < num; i++) {
+		//READ
+		request=(msg[i].addr&0xff00) >> 8;
+		if (!request)
+			request=0xb1;	
+		value=(msg[i].addr&0xff);
+		if (msg[i].flags & I2C_M_RD){
+			value|=0x01;
+		}
+		if (request==0xa0)
+			value=0xe600;
+		if ((msg[i].flags & I2C_M_RD)) {			
+			opera1_xilinx_read(dev->udev,request,value,msg[i].buf,msg[i].len);
+		}else{//WRITE
+			opera1_xilinx_send(dev->udev,request,value,msg[i].buf,msg[i].len);
+		}
+	}
+	mutex_unlock(&dev->i2c_mutex);
+	return i;
+}
+
+static int opera1_i2c_xfer(struct i2c_adapter *adap,struct i2c_msg msg[],int num)
+{
+	struct dvb_usb_device *d = i2c_get_adapdata(adap);
+	if (d)
+		return opera1_usb_i2c_xfer(d,msg,num);
+	return -EINVAL;
+}
+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_tuner_set_params(struct dvb_frontend *fe, struct dvb_frontend_parameters *params)
+{
+	int freq_add=0;
+	u8 tuner_buf[4];
+	struct dvb_usb_adapter* udev_adap=(struct dvb_usb_adapter*)(fe->dvb->priv);
+	
+	
+	struct i2c_msg tuner_msg = {.addr=0xc0, .flags=0, .buf=tuner_buf, .len=sizeof(tuner_buf) };
+	struct i2c_msg msg[]={
+		{.addr=0xb701,.flags=0,.buf="\x01",.len=1},
+		{.addr=0xb600,.flags=0,.buf="\x00",.len=1},
+	};
+	
+	u8 filter=0;
+
+	// setup PLL filter
+	switch (params->u.ofdm.bandwidth) {
+		case BANDWIDTH_6_MHZ: filter = 0;break;
+		case BANDWIDTH_7_MHZ: filter = 0;break;
+		case BANDWIDTH_8_MHZ: filter = 1;break;
+		default:	break; //INVAILD
+	}
+
+	freq_add=params->frequency/500;
+	tuner_buf[0]=(freq_add>>8) & 0xff;
+	tuner_buf[1]=freq_add & 0xff;
+	tuner_buf[2]=(filter==1) ? 0xed:0xe5;//symbolrate 0x500000 :0xed /0x400000 :exe5 ( e1/e5/ed)
+
+	if (freq_add/2<1100) tuner_buf[3]=0xe6;
+	if (freq_add/2>1100) tuner_buf[3]=0x24;
+	if (freq_add/2>1400) tuner_buf[3]=0x64;
+	if (freq_add/2>1666) tuner_buf[3]=0x84;
+	if (freq_add/2>1800) tuner_buf[3]=0xa4;
+	if (freq_add/2>1900) tuner_buf[3]=0xc4;
+
+	if (fe->ops.i2c_gate_ctrl)
+		fe->ops.i2c_gate_ctrl(fe, 1);
+
+	i2c_transfer(&udev_adap->dev->i2c_adap, msg, 1);
+	i2c_transfer(&udev_adap->dev->i2c_adap, &tuner_msg, 1);
+	msleep(1);
+	return 0;
+}
+static int opera1_set_voltage (struct dvb_frontend* fe, fe_sec_voltage_t voltage)
+{
+	struct i2c_msg msg[]={
+		{.addr=0xb600,.flags=0,.buf="\x00",.len=1}, //13 V
+	};
+	struct dvb_usb_adapter* udev_adap=(struct dvb_usb_adapter*)(fe->dvb->priv);
+	if (voltage==SEC_VOLTAGE_18){
+		msg[0].addr=0xb601;
+		msg[0].buf="\x01";	
+	}
+	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){
+	
+	u8 aclk = 0x98;
+	u8 bclk = 0x95;
+
+	if (srate < 1500000) {
+		aclk = 0xb7;
+		bclk = 0x47;
+	} else if (srate < 3000000) {
+		aclk = 0xb7;
+		bclk = 0x4b;
+	} else if (srate < 7000000) {
+		aclk = 0xb7;
+		bclk = 0x4f;
+	} else if (srate < 14000000) {
+		aclk = 0xb7;
+		bclk = 0x53;
+	} else if (srate < 30000000) {
+		aclk = 0xb6;
+		bclk = 0x53;
+	} else if (srate < 45000000) {
+		aclk = 0xb4;
+		bclk = 0x51;
+	}
+//info ("set symbol rate");
+	stv0299_writereg(fe, 0x13, aclk);
+	stv0299_writereg(fe, 0x14, bclk);
+	stv0299_writereg(fe, 0x1f, (ratio >> 16) & 0xff);
+	stv0299_writereg(fe, 0x20, (ratio >> 8) & 0xff);
+	stv0299_writereg(fe, 0x21, (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 ,
+	0x1f,0x06 ,
+	0x20,0x50 ,
+	0x21,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,
+	.min_delay_ms=100,
+	.mclk=88000000UL,
+	.invert=1,
+	.skip_reinit=0,
+	.lock_output=STV0229_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.tuner_ops.set_params=opera1_tuner_set_params;
+		d->fe->ops.set_voltage=opera1_set_voltage;
+		return 0;
+	}
+	info ("not attached stv0299");
+	return -EIO;
+}
+
+int opera1_power_ctrl(struct dvb_usb_device *d, int onoff)
+{
+	int ret=0;
+	struct i2c_msg power_on_mgs[]={
+		{.addr=0xb701,.buf="\x01",.len=1},
+  		{.addr=0xb601,.buf="\x01",.len=1},//set VOLTAGE setzen
+		{.addr=0xb1a6,.buf="\xff\x03",.len=2},
+	};
+
+	if (onoff){
+		opera1_usb_i2c_xfer(d,power_on_mgs,3);
+	}
+	
+	return ret;
+}
+static int opera1_streaming_ctrl(struct dvb_usb_adapter *adap, int onoff)
+{
+
+	struct i2c_msg start_tuner[]={
+		{.addr=0xb1d0,.buf="\x0c\x01",.len=2},
+		{.addr=0xb1a6,.buf="\xff\x00",.len=2},
+	};
+
+	if (!onoff){
+		start_tuner[0].buf[1]=0x03;
+	}
+	i2c_transfer(&adap->dev->i2c_adap,start_tuner,2);
+	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=0xb1a6,.buf=b_pid,.len=3},
+	};
+	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 struct dvb_usb_rc_key opera1_rc_keys[]={
+	{0x5f,0xa0,KEY_1},
+	{0x50,0xae,KEY_2},
+	{0x5d,0xa2,KEY_3},
+	{0x41,0xbe,KEY_4},
+	
+	{0x0a,0xf4,KEY_5},
+	{0x42,0xbc,KEY_6},
+	{0x47,0xb8,KEY_7},
+	{0x49,0xb6,KEY_8},
+	{0x05,0xfa,KEY_9},
+	{0x45,0xba,KEY_0},
+	
+	{0x09,0xf6,KEY_UP},//chanup
+	{0x1a,0xe4,KEY_DOWN},//chandown
+	{0x5c,0xa2,KEY_LEFT},//voldown
+	{0x5e,0xa0,KEY_RIGHT},//volup
+	{0x07,0xf8,KEY_SPACE},//tab
+	{0x1e,0xe0,KEY_ENTER},//play ok
+	{0x1b,0xe4,KEY_Z},//zoom
+	{0x59,0xa6,KEY_M},//mute
+	{0x5a,0xa4,KEY_F},//tv/f
+	{0x18,0xe6,KEY_R},//rec
+	{0x01,0xfe,KEY_S},//Stop
+	{0x02,0xfc,KEY_P},//pause 
+	{0x03,0xfc,KEY_W},//<- ->
+	{0x06,0xf8,KEY_C},//capture
+	{0x46,0xb8,KEY_Q},//exit
+	{0x43,0xbc,KEY_O},//power7
+	
+};
+
+static int opera1_rc_query(struct dvb_usb_device *dev, u32 *event, int *state)
+{
+	// u8* search="0000000100000000010101000101000";
+	/**
+	startmarker 0001000011101101 or 0001000111101100
+	
+	*/
+	u8 rcbuffer[32];
+	const u8 startmarker1[16]="\x0\x0\x0\x1\x0\x0\x0\x0\x1\x1\x1\x0\x1\x1\x0\x1";
+	const u8 startmarker2[16]="\x0\x0\x0\x1\x0\x0\x0\x1\x1\x1\x1\x0\x1\x1\x0\x0";
+	struct i2c_msg read_remote[]={
+	    {.addr=0xb880,.buf=rcbuffer,.flags=I2C_M_RD,.len=32},
+	};
+	int i=0,b=0;
+	u32 send_key=0;
+	memset(rcbuffer,0,32);
+	
+	if (i2c_transfer(&dev->i2c_adap,read_remote,1)==1){
+		if (memcmp(rcbuffer,"\x1\x1\x1\x1\x1\x1\x1\x1\x1\x1\x1\x1\x1\x1\x1\x1\x1\x1\x1\x1\x1\x1\x1\x1",32)==0 && last_key_pressed!=-1){
+			*state=REMOTE_KEY_REPEAT;
+			*event=last_key_pressed;
+			return 0;
+		}
+		/*for (b=0;b<32;b++){
+			if (rcbuffer[b])
+				printk("1");
+			else
+				printk("0");
+		}
+		printk("\n");*/
+		for (b=0;b<32;b++){
+			if (b+16<32){
+				if (memcmp(rcbuffer+b,startmarker1,16)==0 || memcmp(rcbuffer+b,startmarker2,16)==0){
+					/*for (c=b+16;c<32;c++){
+						if (rcbuffer[c])
+							printk("1");
+						else
+							printk("0");
+
+					}
+					printk("\n");*/
+					break;
+				}
+			}
+		}
+		
+		//if ((b+15+16)==31)//only vaild sequences
+			
+		for (i=b+16;i<32 && i<b+15+16;i++)
+		{
+			if (rcbuffer[i] /*&& (i-b-2)!=6*/)
+				send_key|=1;
+			send_key =send_key << 1;
+		}
+		//printk("key code :%x\n",send_key);
+		if (send_key==0)
+		    return 0;
+		printk("key code :%x\n",send_key);
+
+		for (i=0;i< ARRAY_SIZE(opera1_rc_keys);i++){
+			if (	
+							send_key!=0x7efe &&
+							(send_key&0xff )==opera1_rc_keys[i].data && 
+							((send_key&0xff00) >>8)==opera1_rc_keys[i].custom
+				)
+			{
+				*state = REMOTE_KEY_PRESSED;
+				*event=opera1_rc_keys[i].event;
+				last_key_pressed=opera1_rc_keys[i].event;
+				break;
+			}
+			last_key_pressed=-1;
+		}
+	}else
+		*state = REMOTE_NO_KEY_PRESSED;
+
+		return 0;
+}
+
+
+/* do not change the order of the ID table */
+static struct usb_device_id opera1_table [] = {
+/* 00 */	{ USB_DEVICE(USB_VID_CYPRESS,		USB_PID_OPERA1_COLD         ) },
+			{ USB_DEVICE(USB_VID_OPERA1_WARM,	USB_PID_OPERA1_WARM         ) },
+/* 01 *//*{ USB_DEVICE(USB_VID_CYPRESS,		USB_PID_OPERA1_COLD2         ) },
+		  { USB_DEVICE(USB_VID_OPERA1_WARM,	USB_PID_OPERA1_WARM         ) },*/
+		  { }		/* Terminating entry */
+};
+MODULE_DEVICE_TABLE (usb, opera1_table);
+static int opera1_firmware_download(struct usb_device *udev, const struct firmware *fw)
+{
+	
+	int ret = usb_cypress_load_firmware(udev,fw,CYPRESS_FX2);
+	const struct firmware *fw1=NULL;
+
+	if(ret==0)
+	{
+		if ((ret = request_firmware(&fw1, "opera1-2.fw", &udev->dev)) != 0) {
+			err("did not find the firmware file. (%s) "
+					"Please see linux/Documentation/dvb/ for more details on firmware-problems. (%d)",
+			"opera1-2.fw",ret);
+			
+		}else{
+			ret = usb_cypress_load_firmware(udev,fw1,CYPRESS_FX2);
+			release_firmware(fw1);
+			if (ret!=0)
+				info("error loading firmware1 %d,%d",-EIO,ret);
+			
+		}
+	}
+	return ret;
+
+}
+
+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;
+	u8 dummydata[10],testval;
+	memcpy(dummydata, xilinx_init, 9);
+	info("start downloading fpga firmware");
+
+	opera1_xilinx_send(dev,0xb1,0xa0,dummydata,9);
+	opera1_xilinx_send(dev,0xb1,0xa0,dummydata,1);
+	opera1_xilinx_read(dev,0xb1,0xa1,dummydata,1);
+	opera1_xilinx_send(dev,0xbc,0xaa,"\x00",1);
+	opera1_xilinx_send(dev,0xbc,0x00,&testval,1);
+	opera1_xilinx_send(dev,0xbc,0x00,&testval,1);
+	opera1_xilinx_send(dev,0xbc,0x00,&testval,1);
+	opera1_xilinx_send(dev,0xbc,0x00,&testval,1);
+
+	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);
+		if (p != NULL) {
+			u8 reset;
+			memcpy(p,fw->data,fw->size);
+			for(i = 0; p[i] != 0 && i < fw->size; ) {
+				b = (u8 *) p+i;
+				if (
+					opera1_xilinx_send(dev,OPERA_WRITE_FX2,0x0, b+1, b[0]) != b[0]
+					) {
+					err("error while transferring firmware");
+					ret = -EINVAL;
+					break;
+				}
+				i = i+ 1 + b[0];
+			}
+			/* restart the CPU */
+			reset = 0;
+			if (ret || (opera1_xilinx_send(dev,0xa0,0xe600,&reset,1)!=1)) {
+				err("could not restart the USB controller CPU.");
+				ret = -EINVAL;
+			}
+			kfree(p);
+		}
+	}
+	if (fw){
+		release_firmware(fw);
+	}
+	info("done downloading fpga firmware");
+	return ret;
+}
+
+static struct dvb_usb_device_properties opera1_properties = {	
+	.caps = DVB_USB_IS_AN_I2C_ADAPTER,
+	.usb_ctrl = DEVICE_SPECIFIC,
+	.firmware = "opera1.fw",
+	.download_firmware = opera1_firmware_download,
+	.size_of_priv     = 0,
+
+	.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,
+	
+	.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,
+			
+			.caps=DVB_USB_ADAP_HAS_PID_FILTER | DVB_USB_ADAP_NEED_PID_FILTERING,
+			.pid_filter      = opera1_pid_filter,
+			.pid_filter_count = 252,
+			.stream = {
+				.type = USB_BULK,
+				.count = 10,
+				.endpoint = 0x82,
+				.u = {
+					.bulk = {
+						.buffersize = 0x200,
+					}
+				}
+			},
+		}
+	},
+
+	.num_device_descs = 1,
+	.devices = {
+		{	"Opera1 DVB-S USB2.0",
+		{ &opera1_table[0], NULL },
+		{ &opera1_table[1], NULL },
+		},
+	/*	{	"Opera1 DVB-S USB2.0 wrong product ID",
+		{ &opera1_table[2], NULL },
+		{ &opera1_table[3], NULL },
+		},*/
+	}
+};
+
+
+static int opera1_probe(struct usb_interface *intf,
+								const struct usb_device_id *id)
+{
+	struct dvb_usb_device *d;
+	struct usb_device* udev=interface_to_usbdev(intf);
+	
+	if (udev->descriptor.idProduct==USB_PID_OPERA1_WARM && 
+	    udev->descriptor.idVendor==USB_VID_OPERA1_WARM && 
+	    (d==NULL || opera1_xilinx_load_firmware(udev,"opera1-fpga.fw")!=0 )
+	){
+		return -EINVAL;
+	}
+
+	if (dvb_usb_device_init(intf,&opera1_properties,THIS_MODULE,&d) != 0)
+		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;
+//	mutex_init(&mymutex);
+	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@xxxxxxxxx");
+MODULE_AUTHOR("Marco Gittler (c) g.marco@xxxxxxxxxx");
+MODULE_DESCRIPTION("Driver for Opera1 DVB-S device");
+MODULE_VERSION("0.1");
+MODULE_LICENSE("GPL");
+
diff -r 42b9d09cff15 linux/drivers/media/dvb/dvb-usb/opera1.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/linux/drivers/media/dvb/dvb-usb/opera1.h	Sat Feb 24 14:02:20 2007 +0100
@@ -0,0 +1,38 @@
+#ifndef _OPERA1_H_
+#define _OPERA1_H_
+
+
+#define DVB_USB_LOG_PREFIX "opera"
+#include "dvb-usb.h"
+#include "dvb_frontend.h"
+#include <linux/version.h>
+extern int dvb_usb_opera1_debug;
+#define deb_xfer(args...) dprintk(dvb_usb_opera1_debug,0x02,args)
+
+struct opera_rc_keys {
+	u32 keycode;
+	u32 event;
+};
+///Send Querys
+
+#define QUERY_RC 0x01
+#define WAIT_FOR_COMPLETE 0x02
+
+///Register on Cypress
+
+#define READ_FX2_REG_REQ  0xBA
+#define OPERA_WRITE_FX2 0xBB
+
+#define OPERA_TUNER_REQ 0xB1
+#define OPERA_TUNER1_REQ 0xb6
+#define OPERA_TUNER2_REQ 0xb7
+#define OPERA_REMOTE 0xB8
+#define OPERA_TUNER4_REQ 0xbb
+#define OPERA_TUNER5_REQ 0xbc
+
+#define USB_VID_OPERA1_WARM                     0x695C /*do we have such a thing?*/
+#define USB_PID_OPERA1_COLD                     0x2830
+#define USB_PID_OPERA1_COLD2                     0x8613
+#define USB_PID_OPERA1_WARM                     0x3829 /*do we have such a thing?*/
+
+#endif
_______________________________________________
linux-dvb mailing list
linux-dvb@xxxxxxxxxxx
http://www.linuxtv.org/cgi-bin/mailman/listinfo/linux-dvb

[Index of Archives]     [Linux Media]     [Video 4 Linux]     [Asterisk]     [Samba]     [Xorg]     [Xfree86]     [Linux USB]

  Powered by Linux