[linux-dvb] Re: [video4linux-cvs] [hg:v4l-dvb] Add support for Opera S1- DVB-USB

Marco Gittler g.marco at freenet.de
Sat Apr 21 18:01:17 CEST 2007


here the new patch against main hg.
-the tuner i2c addr now without define (as wanted).
-now 7 bit addr are used (the power_ctrl fkt ist ok so, because this is 
a raw write)
-the addr >> 1 , addr << 1 is ok so, i think beause the read write is 
now taken from the last bit.
-now i have no datasheet for the device, all taken from usb-logs

i hope i answered all asked questions.

Signed-off-by: Marco Gittler <g.marco at freenet.de>


mkrufky at linuxtv.org schrieb:
> Marco Gittler wrote:
>   
>>>> +/* I2C */
>>>> +
>>>>     
>>>>         
>>> Looks like i2c is using the 8-bit addresses instead of 7-bit
>>> addresses, just
>>> like how m920x, gl861 and au6610 did at first...  This needs to be fixed.
>>>   
>>>       
>> this seem very difficult. the device uses 16 bit (or better 2 byte for
>> addressing something)
>> the big problem ist that f.e. 0xb880 must READ data (remote-code) and
>> another example
>> voltage switch: the adress changes from 0xb600 to 0xb601. (both write to
>> device)
>>
>> so is not using standard i2c addresses and must be complete other handled.
>> i mean a wrapper for the address stuff must be ni to make if full i2c
>> comaptible.
>>
>> the device is not the best i every saw ;), so the design is also not so
>> nice.
>>
>> any help how the convert from the addr to i2c addr can be done is welcome.
>>     
>
> OK.  We will have time to revisit this issue -- just try to keep it in the back
> of your mind.
>
>   
>>>  
>>>       
>>>> +static int opera1_usb_i2c_msgxfer(struct dvb_usb_device *dev, u16 addr,
>>>> +               u8 * buf, u16 len, int flag)
>>>> +{
>>>> + 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;
>>>> +
>>>> + request = (addr & 0xff00) >> 8;
>>>> + if (!request)
>>>> +     request = 0xb1;
>>>> + value = (addr & 0xff);
>>>> + if (flag & OPERA_READ_MSG) {
>>>> +     value |= 0x01;
>>>> + }
>>>> + if (request == 0xa0)
>>>> +     value = 0xe600;
>>>> + ret = opera1_xilinx_rw(dev->udev, request, value, buf, len, flag);
>>>> +
>>>> + mutex_unlock(&dev->usb_mutex);
>>>> + return ret;
>>>> +}
>>>> +
>>>>         
>
> [snip]
>
>   
>>>> +static int opera1_tuner_attach(struct dvb_usb_adapter *adap)
>>>> +{
>>>> + adap->pll_addr = 0xc0;
>>>> + adap->pll_desc = &dvb_pll_opera1;
>>>> + adap->fe->ops.tuner_ops.set_params = dvb_usb_tuner_set_params_i2c;
>>>>     
>>>>         
>>> We should be using "dvb_attach(dvb_pll_attach, adap->fe, 0x60,
>>> &adap->dev->i2c_adap, &dvb_pll_opera1)" here, instead.
>>>
>>> also, please note the usage of 8-bit i2c addr instead of standard 7-bit.
>>>
>>>
>>>   
>>>       
>> done, except the i2c addr (reason is like above)
>>     
>
> fine.  Once the i2c handling is converted, we'll change this as appropriate.
> This will be OK in the meantime.
>
>   
>>>> + return 0;
>>>> +}
>>>> +
>>>>         
>
> [snip]
>
>   
>>>> +static struct dvb_usb_device_properties opera1_properties = {
>>>> + .caps = DVB_USB_IS_AN_I2C_ADAPTER,
>>>> + .usb_ctrl = CYPRESS_FX2,
>>>> + .firmware = "opera.fw",
>>>>     
>>>>         
>>> Please see the other firmware names...  we should conform to the
>>> standard, and
>>> name it:
>>>
>>> "dvb-usb-opera-01.fw"
>>>   
>>>       
>> done
>> firmware extract utility is coming soon
>>     
>
> OK.
>
>
>   
>> ------------------------------------------------------------------------
>>
>>     
>
> Thanks for the patch....  Please remember that your sign-off is required with
> every patch, in order for us to apply it to the kernel source.
>
> For THIS patch below, I submit my own:
>
> Signed-off-by: Michael Krufky <mkrufky at linuxtv.org>
>
> Please respond to this email with yours.
>
> ...there is still one trivial whitespace problem, though.  see below:
>
>
>   
>> diff -r c8b73ec18b42 linux/drivers/media/dvb/dvb-usb/dvb-usb-ids.h
>> --- a/linux/drivers/media/dvb/dvb-usb/dvb-usb-ids.h   Thu Apr 19 12:04:50 2007 -0300
>> +++ b/linux/drivers/media/dvb/dvb-usb/dvb-usb-ids.h   Thu Apr 19 19:04:37 2007 +0200
>> @@ -32,13 +32,13 @@
>>  #define USB_VID_LITEON               0x04ca
>>  #define USB_VID_MEDION               0x1660
>>  #define USB_VID_MSI              0x0db0
>> +#define USB_VID_OPERA1               0x695c
>>  #define USB_VID_PINNACLE         0x2304
>>  #define USB_VID_VISIONPLUS           0x13d3
>>  #define USB_VID_TWINHAN              0x1822
>>  #define USB_VID_ULTIMA_ELECTRONIC        0x05d8
>>  #define USB_VID_UNIWILL              0x1584
>>  #define USB_VID_WIDEVIEW         0x14aa
>> -#define USB_VID_OPERA1               0x695c
>>  
>>  /* Product IDs */
>>  #define USB_PID_ADSTECH_USB2_COLD            0xa333
>> diff -r c8b73ec18b42 linux/drivers/media/dvb/dvb-usb/opera1.c
>> --- a/linux/drivers/media/dvb/dvb-usb/opera1.c    Thu Apr 19 12:04:50 2007 -0300
>> +++ b/linux/drivers/media/dvb/dvb-usb/opera1.c    Thu Apr 19 19:53:36 2007 +0200
>> @@ -256,9 +256,8 @@ static int opera1_frontend_attach(struct
>>  
>>  static int opera1_tuner_attach(struct dvb_usb_adapter *adap)
>>  {
>> - adap->pll_addr = 0xc0;
>> - adap->pll_desc = &dvb_pll_opera1;
>> - adap->fe->ops.tuner_ops.set_params = dvb_usb_tuner_set_params_i2c;
>> + dvb_attach(dvb_pll_attach, adap->fe, 0xc0,
>> +               &adap->dev->i2c_adap, &dvb_pll_opera1);
>>     
>
> the 1st char of "&adap->dev .......  "  should line up directly below the 1st
> char of "dvb_pll_attach".  not a big problem, but should be fixed before commit.
>
>   
>>   return 0;
>>  }
>>  
>> @@ -478,7 +477,7 @@ static struct dvb_usb_device_properties 
>>  static struct dvb_usb_device_properties opera1_properties = {
>>   .caps = DVB_USB_IS_AN_I2C_ADAPTER,
>>   .usb_ctrl = CYPRESS_FX2,
>> - .firmware = "opera.fw",
>> + .firmware = "dvb-usb-opera-01.fw",
>>   .size_of_priv = sizeof(struct opera1_state),
>>  
>>   .power_ctrl = opera1_power_ctrl,
>> @@ -533,7 +532,7 @@ static int opera1_probe(struct usb_inter
>>   if (udev->descriptor.idProduct == USB_PID_OPERA1_WARM &&
>>       udev->descriptor.idVendor == USB_VID_OPERA1 &&
>>       (d == NULL
>> -         || opera1_xilinx_load_firmware(udev, "opera1-fpga.fw") != 0)
>> +         || opera1_xilinx_load_firmware(udev, "dvb-usb-opera1-fpga.fw") != 0)
>>       ) {
>>       return -EINVAL;
>>   }
>>
>>
>> ------------------------------------------------------------------------
>>
>> _______________________________________________
>> linux-dvb mailing list
>> linux-dvb at linuxtv.org
>> http://www.linuxtv.org/cgi-bin/mailman/listinfo/linux-dvb
>>     
>
>
>   

-------------- next part --------------
diff -r 897a04d990b6 linux/drivers/media/dvb/dvb-usb/dvb-usb-ids.h
--- a/linux/drivers/media/dvb/dvb-usb/dvb-usb-ids.h	Fri Apr 20 18:23:38 2007 -0300
+++ b/linux/drivers/media/dvb/dvb-usb/dvb-usb-ids.h	Thu Apr 19 19:04:37 2007 +0200
@@ -32,13 +32,13 @@
 #define USB_VID_LITEON				0x04ca
 #define USB_VID_MEDION				0x1660
 #define USB_VID_MSI				0x0db0
+#define USB_VID_OPERA1				0x695c
 #define USB_VID_PINNACLE			0x2304
 #define USB_VID_VISIONPLUS			0x13d3
 #define USB_VID_TWINHAN				0x1822
 #define USB_VID_ULTIMA_ELECTRONIC		0x05d8
 #define USB_VID_UNIWILL				0x1584
 #define USB_VID_WIDEVIEW			0x14aa
-#define USB_VID_OPERA1				0x695c
 
 /* Product IDs */
 #define USB_PID_ADSTECH_USB2_COLD			0xa333
diff -r 897a04d990b6 linux/drivers/media/dvb/dvb-usb/opera1.c
--- a/linux/drivers/media/dvb/dvb-usb/opera1.c	Fri Apr 20 18:23:38 2007 -0300
+++ b/linux/drivers/media/dvb/dvb-usb/opera1.c	Sat Apr 21 17:56:57 2007 +0200
@@ -25,6 +25,11 @@
 #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;
 };
@@ -81,7 +86,7 @@ static int opera1_xilinx_rw(struct usb_d
 /* I2C */
 
 static int opera1_usb_i2c_msgxfer(struct dvb_usb_device *dev, u16 addr,
-				  u8 * buf, u16 len, int flag)
+				  u8 * buf, u16 len)
 {
 	int ret = 0;
 	u8 request;
@@ -93,17 +98,31 @@ static int opera1_usb_i2c_msgxfer(struct
 	}
 	if (mutex_lock_interruptible(&dev->usb_mutex) < 0)
 		return -EAGAIN;
-
-	request = (addr & 0xff00) >> 8;
-	if (!request)
-		request = 0xb1;
-	value = (addr & 0xff);
-	if (flag & OPERA_READ_MSG) {
-		value |= 0x01;
-	}
-	if (request == 0xa0)
-		value = 0xe600;
-	ret = opera1_xilinx_rw(dev->udev, request, value, buf, len, flag);
+	
+	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;
@@ -122,13 +141,10 @@ static int opera1_i2c_xfer(struct i2c_ad
 
 	for (i = 0; i < num; i++) {
 		if ((tmp = opera1_usb_i2c_msgxfer(d,
-					msg[i].addr,
+					(msg[i].addr<<1)|(msg[i].flags&I2C_M_RD?0x01:0),
 					msg[i].buf,
-					msg[i].len,
-					(msg[i].flags ==
-					I2C_M_RD ?
-					OPERA_READ_MSG :
-					OPERA_WRITE_MSG))!= msg[i].len)) {
+					msg[i].len
+					)!= msg[i].len)) {
 			break;
 		}
 		if (dvb_usb_opera1_debug & 0x10)
@@ -153,12 +169,12 @@ static int opera1_set_voltage(struct dvb
 	static u8 command_13v[1]={0x00};
 	static u8 command_18v[1]={0x01};
 	struct i2c_msg msg[] = {
-		{.addr = 0xb600,.flags = 0,.buf = command_13v,.len = 1},
+		{.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 = 0xb601;
+		msg[0].addr = ADDR_B601_VOLTAGE_18V;
 		msg[0].buf = command_18v;
 	}
 	i2c_transfer(&udev_adap->dev->i2c_adap, msg, 1);
@@ -231,7 +247,7 @@ static u8 opera1_inittab[] = {
 };
 
 static struct stv0299_config opera1_stv0299_config = {
-	.demod_address = 0xd0,
+	.demod_address = 0xd0>>1,
 	.min_delay_ms = 100,
 	.mclk = 88000000UL,
 	.invert = 1,
@@ -256,19 +272,21 @@ static int opera1_frontend_attach(struct
 
 static int opera1_tuner_attach(struct dvb_usb_adapter *adap)
 {
-	adap->pll_addr = 0xc0;
-	adap->pll_desc = &dvb_pll_opera1;
-	adap->fe->ops.tuner_ops.set_params = dvb_usb_tuner_set_params_i2c;
+	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)
 {
-	int addr = onoff ? 0xb701 : 0xb700;
 	u8 val = onoff ? 0x01 : 0x00;
+	
 	if (dvb_usb_opera1_debug)
 		info("power %s", onoff ? "on" : "off");
-	return opera1_usb_i2c_msgxfer(d, addr, &val, 1, OPERA_WRITE_MSG);
+	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)
@@ -276,7 +294,7 @@ static int opera1_streaming_ctrl(struct 
 	static u8 buf_start[2] = { 0xff, 0x03 };
 	static u8 buf_stop[2] = { 0xff, 0x00 };
 	struct i2c_msg start_tuner[] = {
-		{.addr = 0xb1a6,.buf = onoff ? buf_start : buf_stop,.len = 2},
+		{.addr = ADDR_B1A6_STREAM_CTRL,.buf = onoff ? buf_start : buf_stop,.len = 2},
 	};
 	if (dvb_usb_opera1_debug)
 		info("streaming %s", onoff ? "on" : "off");
@@ -289,7 +307,7 @@ static int opera1_pid_filter(struct dvb_
 {
 	u8 b_pid[3];
 	struct i2c_msg msg[] = {
-		{.addr = 0xb1a6,.buf = b_pid,.len = 3},
+		{.addr = ADDR_B1A6_STREAM_CTRL,.buf = b_pid,.len = 3},
 	};
 	if (dvb_usb_opera1_debug)
 		info("pidfilter index: %d pid: %d %s", index, pid,
@@ -306,7 +324,7 @@ static int opera1_pid_filter_control(str
 	int u = 0x04;
 	u8 b_pid[3];
 	struct i2c_msg msg[] = {
-		{.addr = 0xb1a6,.buf = b_pid,.len = 3},
+		{.addr = ADDR_B1A6_STREAM_CTRL,.buf = b_pid,.len = 3},
 	};
 	if (dvb_usb_opera1_debug)
 		info("%s hw-pidfilter", onoff ? "enable" : "disable");
@@ -356,7 +374,7 @@ static int opera1_rc_query(struct dvb_us
 	const u16 startmarker1 = 0x10ed;
 	const u16 startmarker2 = 0x11ec;
 	struct i2c_msg read_remote[] = {
-		{.addr = 0xb880,.buf = rcbuffer,.flags = I2C_M_RD,.len = 32},
+		{.addr = ADDR_B880_READ_REMOTE,.buf = rcbuffer,.flags = I2C_M_RD,.len = 32},
 	};
 	int i = 0;
 	u32 send_key = 0;
@@ -478,7 +496,7 @@ static struct dvb_usb_device_properties 
 static struct dvb_usb_device_properties opera1_properties = {
 	.caps = DVB_USB_IS_AN_I2C_ADAPTER,
 	.usb_ctrl = CYPRESS_FX2,
-	.firmware = "opera.fw",
+	.firmware = "dvb-usb-opera-01.fw",
 	.size_of_priv = sizeof(struct opera1_state),
 
 	.power_ctrl = opera1_power_ctrl,
@@ -533,7 +551,7 @@ static int opera1_probe(struct usb_inter
 	if (udev->descriptor.idProduct == USB_PID_OPERA1_WARM &&
 		udev->descriptor.idVendor == USB_VID_OPERA1 &&
 		(d == NULL
-			|| opera1_xilinx_load_firmware(udev, "opera1-fpga.fw") != 0)
+			|| opera1_xilinx_load_firmware(udev, "dvb-usb-opera1-fpga.fw") != 0)
 		) {
 		return -EINVAL;
 	}


More information about the linux-dvb mailing list