Mailing List archive

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

[linux-dvb] Nexus CA Patches for analogue sound



Hi!

The digital part runs quite good over months now, but there are a few
limitations and bugs.

Limitations of the current driver:

--Analog sound output (needed for analog TV but fine for digitalTV, too) is
*not* supported and *never* initialized.

Reason:
 TT uses a different chip compared with Siemens DVB-C card.
Siemens: MSP3400G
TT on NexusCA: MSP 3415G

Difference:
The MSP3915G is with lower functionality, but compatible to the MSP3400G.
 Some registers are not supported on MSP3415G. In fact that means for
linuxtv.org-driver MSP3415G has no headphone output, but this register is
written for Siemens card in av7110_v4l.c. I've tested what happens, when this
register is written on MSP3415G-->nothing, no problem to use the Siemens code
in AV7110_v4l.c

Problem:
TT uses a different I2C-address compared to Siemens. The *complet*(inclusive
analog TV!!!) analog part is never initialized.
Siemens I2C-address: 0x80
NexusCA I2C-address: 0x84

My Solution:
Define in "av7110.h" a new audio DAC type:
---------------------------------------------------
Rename "DVB_ADAC_MSP" to "DVB_ADAC_MSP34x0"
add new defintion to enumeration:
#define "DVB_ADAC_MSP34x5" 3

In "av7110_v4l.c": detection of the analog part
---------------------------------------------------------
in function "av7110_init_analog_module":
 add detection of MSP34x5G by a second if-statement

In function "msp_readreg" and "msp_writereg":
add if-statement to decide which address is to be written

See my patch for av7110_v4l.c, please

In "av7110_av.c": volume regulation support for new state "DVB_ADAC_MSP34x5":
(Works fine with VDR)
See my patch for av7110_av.c
----------------------------------------------------

===============================================================

Limitatation:
Sound over analog is bad (I'm sure for Siemens DVB-C as well):

Problem:
The MSP is configured strange on one register.

My Solution:
The problem is, that the Chip is set to maximum amplification!!!!!!!
The result is clipping and the automatic modes to
prevent that are switched off!!!!

I made a work around about the MSP. Amplification is set to 0dB.
I will made a patch with this workaround soon! Just want to wait for fixing
the first more important MSP support.

=============================================================================
The analog TV part will still not run with all that stuff, but is
 needed for the next steps.
Actually I changed the address for the analog chip saa7114 just for me. It's
 a different address compared with Siemens DVB-C card.
(Address 0x42 for Nexus, but 0x48 for Siemens)
I am able to communicate with the chip and try to find a valid
 initialization. Analog tuning is broken: When i switch on the tuning i get
 crashes or monitor flickering. Xawtv gives errors about invalid frequencies.
 Actually i have no idea howto solve that. Will go on triing :-)
I've started to try initializing the saa7114.
=============================================================================
The existing code makes trouble with SPDIF output.
Some users have no problems, others (like me) have sometimes no sound when
zapping. One user has never (!!!) sound over SPDIF. With my patches he is
able to use the analog sound output.

The problems of my patches are: 
After switching on the MSP35x5G support on, the Spdif is/maybe(???) broken. 
Maybe a lot of users will be unhappy with this, but some have no sound 
actually.
I will try to find out, what the problem is.

In fact i made no change what could break the SPDIF normally, or..?!?!
 I'm _guessing_ it's around the limited I2C-speed.
Ideas are welcome around that problem!

Best regards

Tim

-------------------------------------------------------
? build-2.6/.tmp_versions
Index: linux/drivers/media/dvb/ttpci/av7110.c
===================================================================
RCS file: /cvs/linuxtv/dvb-kernel/linux/drivers/media/dvb/ttpci/av7110.c,v
retrieving revision 1.170
diff -U3 -r1.170 av7110.c
--- linux/drivers/media/dvb/ttpci/av7110.c	9 Jan 2005 22:05:24 -0000	1.170
+++ linux/drivers/media/dvb/ttpci/av7110.c	6 Feb 2005 14:12:15 -0000
@@ -154,7 +154,7 @@
 			av7110->dvb_adapter->num, av7110->adac_type);
 	}
 
-	if (av7110->adac_type == DVB_ADAC_NONE || av7110->adac_type == DVB_ADAC_MSP) {
+	if (av7110->adac_type == DVB_ADAC_NONE || av7110->adac_type == DVB_ADAC_MSP34x0 || av7110->adac_type == DVB_ADAC_MSP34x5) {
 		// switch DVB SCART on
 		av7110_fw_cmd(av7110, COMTYPE_AUDIODAC, MainSwitch, 1, 0);
 		av7110_fw_cmd(av7110, COMTYPE_AUDIODAC, ADSwitch, 1, 1);
Index: linux/drivers/media/dvb/ttpci/av7110.h
===================================================================
RCS file: /cvs/linuxtv/dvb-kernel/linux/drivers/media/dvb/ttpci/av7110.h,v
retrieving revision 1.36
diff -U3 -r1.36 av7110.h
--- linux/drivers/media/dvb/ttpci/av7110.h	8 Jan 2005 19:34:29 -0000	1.36
+++ linux/drivers/media/dvb/ttpci/av7110.h	6 Feb 2005 14:12:15 -0000
@@ -97,7 +97,8 @@
 	int adac_type;	       /* audio DAC type */
 #define DVB_ADAC_TI	  0
 #define DVB_ADAC_CRYSTAL  1
-#define DVB_ADAC_MSP	  2
+#define DVB_ADAC_MSP34x0  2
+#define DVB_ADAC_MSP34x5  3
 #define DVB_ADAC_NONE	 -1
 
 
Index: linux/drivers/media/dvb/ttpci/av7110_av.c
===================================================================
RCS file: /cvs/linuxtv/dvb-kernel/linux/drivers/media/dvb/ttpci/av7110_av.c,v
retrieving revision 1.12
diff -U3 -r1.12 av7110_av.c
--- linux/drivers/media/dvb/ttpci/av7110_av.c	8 Nov 2004 08:42:00 -0000	1.12
+++ linux/drivers/media/dvb/ttpci/av7110_av.c	6 Feb 2005 14:12:18 -0000
@@ -302,7 +302,7 @@
 		i2c_writereg(av7110, 0x20, 0x04, volright);
 		return 0;
 
-	case DVB_ADAC_MSP:
+	case DVB_ADAC_MSP34x0:
 		vol  = (volleft > volright) ? volleft : volright;
 		val	= (vol * 0x73 / 255) << 8;
 		if (vol > 0)
@@ -311,6 +311,14 @@
 		msp_writereg(av7110, MSP_WR_DSP, 0x0000, val); /* loudspeaker */
 		msp_writereg(av7110, MSP_WR_DSP, 0x0006, val); /* headphonesr */
 		return 0;
+        case DVB_ADAC_MSP34x5:
+		vol  = (volleft > volright) ? volleft : volright;
+		val	= (vol * 0x73 / 255) << 8;
+		if (vol > 0)
+		       balance = ((volright - volleft) * 127) / vol;
+		msp_writereg(av7110, MSP_WR_DSP, 0x0001, balance << 8);
+		msp_writereg(av7110, MSP_WR_DSP, 0x0000, val); /* loudspeaker */
+		return 0; 
 	}
 	return 0;
 }
Index: linux/drivers/media/dvb/ttpci/av7110_v4l.c
===================================================================
RCS file: /cvs/linuxtv/dvb-kernel/linux/drivers/media/dvb/ttpci/av7110_v4l.c,v
retrieving revision 1.20
diff -U3 -r1.20 av7110_v4l.c
--- linux/drivers/media/dvb/ttpci/av7110_v4l.c	21 Dec 2004 02:44:05 -0000	1.20
+++ linux/drivers/media/dvb/ttpci/av7110_v4l.c	6 Feb 2005 14:12:19 -0000
@@ -43,7 +43,8 @@
 {
 	u8 msg[5] = { dev, reg >> 8, reg & 0xff, val >> 8 , val & 0xff };
 	struct i2c_msg msgs = { .flags = 0, .addr = 0x40, .len = 5, .buf = msg };
-
+        if (av7110->adac_type == DVB_ADAC_MSP34x5)
+	   msgs.addr =0x42;
 	if (i2c_transfer(&av7110->i2c_adap, &msgs, 1) != 1) {
 		dprintk(1, "dvb-ttpci: failed @ card %d, %u = %u\n",
 		       av7110->dvb_adapter->num, reg, val);
@@ -60,7 +61,10 @@
 		{ .flags = 0,	     .addr = 0x40, .len = 3, .buf = msg1 },
 		{ .flags = I2C_M_RD, .addr = 0x40, .len = 2, .buf = msg2 }
 	};
-
+        if (av7110->adac_type == DVB_ADAC_MSP34x5){
+	   msgs[0].addr = 0x42;
+           msgs[1].addr = 0x42;
+        };
 	if (i2c_transfer(&av7110->i2c_adap, &msgs[0], 2) != 2) {
 		dprintk(1, "dvb-ttpci: failed @ card %d, %u\n",
 		       av7110->dvb_adapter->num, reg);
@@ -546,21 +550,27 @@
 int av7110_init_analog_module(struct av7110 *av7110)
 {
 	u16 version1, version2;
-
-	if (i2c_writereg(av7110, 0x80, 0x0, 0x80) != 1
-	    || i2c_writereg(av7110, 0x80, 0x0, 0) != 1)
-		return -ENODEV;
-
-	printk("dvb-ttpci: DVB-C analog module @ card %d detected, initializing MSP3400\n",
-		av7110->dvb_adapter->num);
-	av7110->adac_type = DVB_ADAC_MSP;
+        if (i2c_writereg(av7110, 0x84, 0x0, 0x80) == 1
+	    || i2c_writereg(av7110, 0x84, 0x0, 0) == 1){  //MSP34x5 check and reset
+             av7110->adac_type = DVB_ADAC_MSP34x5;
+             printk("dvb-ttpci: DVB-C analog module @ card %d detected, initializing MSP34x5\n",
+	       	av7110->dvb_adapter->num);
+	}
+        else if (i2c_writereg(av7110, 0x80, 0x0, 0x80) == 1
+		 || i2c_writereg(av7110, 0x80, 0x0, 0) == 1){  //MSP34x0 check and reset
+             av7110->adac_type = DVB_ADAC_MSP34x0; 
+             printk("dvb-ttpci: DVB-C analog module @ card %d detected, initializing MSP34x0\n",
+	       	av7110->dvb_adapter->num);
+	}
+        else return -ENODEV;  //no MSP present
+	
 	msleep(100); // the probing above resets the msp...
 	msp_readreg(av7110, MSP_RD_DSP, 0x001e, &version1);
 	msp_readreg(av7110, MSP_RD_DSP, 0x001f, &version2);
-	dprintk(1, "dvb-ttpci: @ card %d MSP3400 version 0x%04x 0x%04x\n",
+	dprintk(1, "dvb-ttpci: @ card %d MSP34xx version 0x%04x 0x%04x\n",
 		av7110->dvb_adapter->num, version1, version2);
-	msp_writereg(av7110, MSP_WR_DSP, 0x0013, 0x0c00);
-	msp_writereg(av7110, MSP_WR_DSP, 0x0000, 0x7f00); // loudspeaker + headphone
+	msp_writereg(av7110, MSP_WR_DSP, 0x0013, 0x0c00); // scart 1 DA in->scart 1 out
+	msp_writereg(av7110, MSP_WR_DSP, 0x0000, 0x7f00); // loudspeaker volume +3dB
 	msp_writereg(av7110, MSP_WR_DSP, 0x0008, 0x0220); // loudspeaker source
 	msp_writereg(av7110, MSP_WR_DSP, 0x0009, 0x0220); // headphone source
 	msp_writereg(av7110, MSP_WR_DSP, 0x0004, 0x7f00); // loudspeaker volume

Home | Main Index | Thread Index