Skip to contentSkip to conversation

XC4000 patches for kernel 2.6.37.2

linux-dvb Mirek Slugeň 6 participants 39 messages Mar 8, 2011 – Jun 5, 2011 2 messages not in the archive Media (V4L/DVB)

lore
Share & tools
lore
#0 lore raw

Hi Istvan

I am sending you modified patches for kernel 2.6.37.2, they works as
expected.

First apply kernel_xc4000.diff (your patch) then kernel_dtv3200h.diff for Leadtek DTV3200 XC4000 support.

Mirek

/drivers/media/video/cx23885/cx23885-cards.c +37 -0
diff -Naur linux-2.6.37.2.old//drivers/media/video/cx23885/cx23885-cards.c linux-2.6.37.2//drivers/media/video/cx23885/cx23885-cards.c
@@ -29,6 +29,7 @@
 #include "tuner-xc2028.h"
 #include "netup-init.h"
 #include "cx23888-ir.h"
+#include "xc4000.h"
 
 static unsigned int enable_885_ir;
 module_param(enable_885_ir, int, 0644);
@@ -170,6 +171,34 @@
 		.name		= "Leadtek Winfast PxDVR3200 H",
 		.portc		= CX23885_MPEG_DVB,
 	},
+	[CX23885_BOARD_LEADTEK_WINFAST_PXDVR3200_H_XC4000] = {
+		.name		= "Leadtek Winfast PxDVR3200 H (XC4000)",
+		.porta		= CX23885_ANALOG_VIDEO,
+		.portc		= CX23885_MPEG_DVB,
+		.tuner_type	= TUNER_XC4000,
+		.tuner_addr	= 0x61,
+		.radio_type	= TUNER_XC4000,
+		.radio_addr	= 0x61,
+		.input		= {{
+			.type   = CX23885_VMUX_TELEVISION,
+			.vmux   = CX25840_VIN2_CH1 |
+				  CX25840_VIN5_CH2 |
+				  CX25840_NONE0_CH3,
+		}, {
+			.type   = CX23885_VMUX_COMPOSITE1,
+			.vmux   = CX25840_COMPOSITE1,
+		}, {
+			.type   = CX23885_VMUX_SVIDEO,
+			.vmux   = CX25840_SVIDEO_LUMA3 |
+				  CX25840_SVIDEO_CHROMA4,
+		}, {
+			.type   = CX23885_VMUX_COMPONENT,
+			.vmux   = CX25840_VIN7_CH1 |
+				  CX25840_VIN6_CH2 |
+				  CX25840_VIN8_CH3 |
+				  CX25840_COMPONENT_ON,
+		} },
+	},
 	[CX23885_BOARD_COMPRO_VIDEOMATE_E650F] = {
 		.name		= "Compro VideoMate E650F",
 		.portc		= CX23885_MPEG_DVB,
@@ -389,6 +418,10 @@
 		.subdevice = 0x6681,
 		.card      = CX23885_BOARD_LEADTEK_WINFAST_PXDVR3200_H,
 	}, {
+		.subvendor = 0x107d,
+		.subdevice = 0x6f39,
+		.card      = CX23885_BOARD_LEADTEK_WINFAST_PXDVR3200_H_XC4000,
+	}, {
 		.subvendor = 0x185b,
 		.subdevice = 0xe800,
 		.card      = CX23885_BOARD_COMPRO_VIDEOMATE_E650F,
@@ -697,6 +730,7 @@
 	case CX23885_BOARD_HAUPPAUGE_HVR1500:
 	case CX23885_BOARD_HAUPPAUGE_HVR1500Q:
 	case CX23885_BOARD_LEADTEK_WINFAST_PXDVR3200_H:
+	case CX23885_BOARD_LEADTEK_WINFAST_PXDVR3200_H_XC4000:
 	case CX23885_BOARD_COMPRO_VIDEOMATE_E650F:
 	case CX23885_BOARD_COMPRO_VIDEOMATE_E800:
 	case CX23885_BOARD_LEADTEK_WINFAST_PXTV1200:
@@ -850,6 +884,7 @@
 		cx_set(GP0_IO, 0x000f000f);
 		break;
 	case CX23885_BOARD_LEADTEK_WINFAST_PXDVR3200_H:
+	case CX23885_BOARD_LEADTEK_WINFAST_PXDVR3200_H_XC4000:
 	case CX23885_BOARD_COMPRO_VIDEOMATE_E650F:
 	case CX23885_BOARD_COMPRO_VIDEOMATE_E800:
 	case CX23885_BOARD_LEADTEK_WINFAST_PXTV1200:
@@ -1210,6 +1245,7 @@
 	case CX23885_BOARD_HAUPPAUGE_HVR1700:
 	case CX23885_BOARD_HAUPPAUGE_HVR1400:
 	case CX23885_BOARD_LEADTEK_WINFAST_PXDVR3200_H:
+	case CX23885_BOARD_LEADTEK_WINFAST_PXDVR3200_H_XC4000:
 	case CX23885_BOARD_COMPRO_VIDEOMATE_E650F:
 	case CX23885_BOARD_HAUPPAUGE_HVR1270:
 	case CX23885_BOARD_HAUPPAUGE_HVR1275:
@@ -1237,6 +1273,7 @@
 	case CX23885_BOARD_HAUPPAUGE_HVR1800lp:
 	case CX23885_BOARD_HAUPPAUGE_HVR1700:
 	case CX23885_BOARD_LEADTEK_WINFAST_PXDVR3200_H:
+	case CX23885_BOARD_LEADTEK_WINFAST_PXDVR3200_H_XC4000:
 	case CX23885_BOARD_COMPRO_VIDEOMATE_E650F:
 	case CX23885_BOARD_NETUP_DUAL_DVBS2_CI:
 	case CX23885_BOARD_COMPRO_VIDEOMATE_E800:
/drivers/media/video/cx23885/cx23885-dvb.c +17 -0
diff -Naur linux-2.6.37.2.old//drivers/media/video/cx23885/cx23885-dvb.c linux-2.6.37.2//drivers/media/video/cx23885/cx23885-dvb.c
@@ -38,6 +38,7 @@
 #include "tda18271.h"
 #include "lgdt330x.h"
 #include "xc5000.h"
+#include "xc4000.h"
 #include "max2165.h"
 #include "tda10048.h"
 #include "tuner-xc2028.h"
@@ -825,6 +826,22 @@
 				fe->ops.tuner_ops.set_config(fe, &ctl);
 		}
 		break;
+	case CX23885_BOARD_LEADTEK_WINFAST_PXDVR3200_H_XC4000:
+		i2c_bus = &dev->i2c_bus[0];
+
+		fe0->dvb.frontend = dvb_attach(zl10353_attach, &dvico_fusionhdtv_xc3028, &i2c_bus->i2c_adap);
+
+		if (fe0->dvb.frontend != NULL) {
+			struct dvb_frontend *fe;
+			struct xc4000_config cfg = {
+				.card_type   = XC4000_CARD_WINFAST_CX88,
+				.i2c_address = 0x61,
+				.if_khz      = 5400,
+			};
+
+			fe = dvb_attach(xc4000_attach, fe0->dvb.frontend, &dev->i2c_bus[1].i2c_adap, &cfg);
+		}
+		break;
 	case CX23885_BOARD_TBS_6920:
 		i2c_bus = &dev->i2c_bus[1];
 
/drivers/media/video/cx23885/cx23885.h +1 -0
diff -Naur linux-2.6.37.2.old//drivers/media/video/cx23885/cx23885.h linux-2.6.37.2//drivers/media/video/cx23885/cx23885.h
@@ -84,6 +84,7 @@
 #define CX23885_BOARD_HAUPPAUGE_HVR1290        26
 #define CX23885_BOARD_MYGICA_X8558PRO          27
 #define CX23885_BOARD_LEADTEK_WINFAST_PXTV1200 28
+#define CX23885_BOARD_LEADTEK_WINFAST_PXDVR3200_H_XC4000 29
 
 #define GPIO_0 0x00000001
 #define GPIO_1 0x00000002
/drivers/media/common/tuners/Kconfig +10 -0
diff -Naur linux-2.6.37.2.old//drivers/media/common/tuners/Kconfig linux-2.6.37.2//drivers/media/common/tuners/Kconfig
@@ -23,6 +23,7 @@
 	depends on VIDEO_MEDIA && I2C
 	select MEDIA_TUNER_XC2028 if !MEDIA_TUNER_CUSTOMISE
 	select MEDIA_TUNER_XC5000 if !MEDIA_TUNER_CUSTOMISE
+	select MEDIA_TUNER_XC4000 if !MEDIA_TUNER_CUSTOMISE
 	select MEDIA_TUNER_MT20XX if !MEDIA_TUNER_CUSTOMISE
 	select MEDIA_TUNER_TDA8290 if !MEDIA_TUNER_CUSTOMISE
 	select MEDIA_TUNER_TEA5761 if !MEDIA_TUNER_CUSTOMISE
@@ -152,6 +153,15 @@
 	  This device is only used inside a SiP called together with a
 	  demodulator for now.
 
+config MEDIA_TUNER_XC4000
+	tristate "Xceive XC4000 silicon tuner"
+	depends on VIDEO_MEDIA && I2C
+	default m if MEDIA_TUNER_CUSTOMISE
+	help
+	  A driver for the silicon tuner XC4000 from Xceive.
+	  This device is only used inside a SiP called together with a
+	  demodulator for now.
+
 config MEDIA_TUNER_MXL5005S
 	tristate "MaxLinear MSL5005S silicon tuner"
 	depends on VIDEO_MEDIA && I2C
/drivers/media/common/tuners/Makefile +1 -0
diff -Naur linux-2.6.37.2.old//drivers/media/common/tuners/Makefile linux-2.6.37.2//drivers/media/common/tuners/Makefile
@@ -16,6 +16,7 @@
 obj-$(CONFIG_MEDIA_TUNER_TDA827X) += tda827x.o
 obj-$(CONFIG_MEDIA_TUNER_TDA18271) += tda18271.o
 obj-$(CONFIG_MEDIA_TUNER_XC5000) += xc5000.o
+obj-$(CONFIG_MEDIA_TUNER_XC4000) += xc4000.o
 obj-$(CONFIG_MEDIA_TUNER_MT2060) += mt2060.o
 obj-$(CONFIG_MEDIA_TUNER_MT2266) += mt2266.o
 obj-$(CONFIG_MEDIA_TUNER_QT1010) += qt1010.o
/drivers/media/common/tuners/tuner-types.c +4 -0
diff -Naur linux-2.6.37.2.old//drivers/media/common/tuners/tuner-types.c linux-2.6.37.2//drivers/media/common/tuners/tuner-types.c
@@ -1789,6 +1789,10 @@
 		.name   = "Xceive 5000 tuner",
 		/* see xc5000.c for details */
 	},
+	[TUNER_XC4000] = { /* Xceive 4000 */
+		.name   = "Xceive 4000 tuner",
+		/* see xc4000.c for details */
+	},
 	[TUNER_TCL_MF02GIP_5N] = { /* TCL tuner MF02GIP-5N-E */
 		.name   = "TCL tuner MF02GIP-5N-E",
 		.params = tuner_tcl_mf02gip_5n_params,
/drivers/media/common/tuners/xc4000.c +1731 -0

1,731 lines not on this page · raw message

/drivers/media/common/tuners/xc4000.h +66 -0

66 lines not on this page · raw message

/drivers/media/video/cx88/cx88-cards.c +242 -7

315 lines not on this page · raw message

/drivers/media/video/cx88/cx88-dvb.c +55 -0

79 lines not on this page · raw message

/drivers/media/video/cx88/cx88.h +4 -0
diff -Naur linux-2.6.37.2.old//drivers/media/video/cx88/cx88.h linux-2.6.37.2//drivers/media/video/cx88/cx88.h
@@ -240,6 +240,10 @@
 #define CX88_BOARD_PROF_7301               83
 #define CX88_BOARD_SAMSUNG_SMT_7020        84
 #define CX88_BOARD_TWINHAN_VP1027_DVBS     85
+#define CX88_BOARD_WINFAST_DTV2000H_PLUS   86
+#define CX88_BOARD_WINFAST_DTV1800H_XC4000 87
+#define CX88_BOARD_WINFAST_TV2000_XP_GLOBAL_6F36 88
+#define CX88_BOARD_WINFAST_TV2000_XP_GLOBAL_6F43 89
 
 enum cx88_itype {
 	CX88_VMUX_COMPOSITE1 = 1,
/drivers/media/video/cx88/cx88-input.c +8 -0
diff -Naur linux-2.6.37.2.old//drivers/media/video/cx88/cx88-input.c linux-2.6.37.2//drivers/media/video/cx88/cx88-input.c
@@ -99,7 +99,11 @@
 		break;
 	case CX88_BOARD_WINFAST_DTV1000:
 	case CX88_BOARD_WINFAST_DTV1800H:
+	case CX88_BOARD_WINFAST_DTV1800H_XC4000:
+	case CX88_BOARD_WINFAST_DTV2000H_PLUS:
 	case CX88_BOARD_WINFAST_TV2000_XP_GLOBAL:
+	case CX88_BOARD_WINFAST_TV2000_XP_GLOBAL_6F36:
+	case CX88_BOARD_WINFAST_TV2000_XP_GLOBAL_6F43:
 		gpio = (gpio & 0x6ff) | ((cx_read(MO_GP1_IO) << 8) & 0x900);
 		auxgpio = gpio;
 		break;
@@ -285,6 +289,8 @@
 	case CX88_BOARD_WINFAST_DTV2000H:
 	case CX88_BOARD_WINFAST_DTV2000H_J:
 	case CX88_BOARD_WINFAST_DTV1800H:
+	case CX88_BOARD_WINFAST_DTV1800H_XC4000:
+	case CX88_BOARD_WINFAST_DTV2000H_PLUS:
 		ir_codes = RC_MAP_WINFAST;
 		ir->gpio_addr = MO_GP0_IO;
 		ir->mask_keycode = 0x8f8;
@@ -294,6 +300,8 @@
 	case CX88_BOARD_WINFAST2000XP_EXPERT:
 	case CX88_BOARD_WINFAST_DTV1000:
 	case CX88_BOARD_WINFAST_TV2000_XP_GLOBAL:
+	case CX88_BOARD_WINFAST_TV2000_XP_GLOBAL_6F36:
+	case CX88_BOARD_WINFAST_TV2000_XP_GLOBAL_6F43:
 		ir_codes = RC_MAP_WINFAST;
 		ir->gpio_addr = MO_GP0_IO;
 		ir->mask_keycode = 0x8f8;
/drivers/media/video/cx88/cx88-video.c +29 -0
diff -Naur linux-2.6.37.2.old//drivers/media/video/cx88/cx88-video.c linux-2.6.37.2//drivers/media/video/cx88/cx88-video.c
@@ -221,6 +221,21 @@
 		.shift                 = 0,
 	},{
 		.v = {
+			.id            = V4L2_CID_SHARPNESS,
+			.name          = "Sharpness",
+			.minimum       = 0,
+			.maximum       = 9,
+			.default_value = 0x0,
+			.type          = V4L2_CTRL_TYPE_INTEGER,
+		},
+		.off                   = 0,
+		/* NOTE: the value is converted and written to both even
+		   and odd registers in the code */
+		.reg                   = MO_FILTER_ODD,
+		.mask                  = 7 << 7,
+		.shift                 = 7,
+	},{
+		.v = {
 			.id            = V4L2_CID_CHROMA_AGC,
 			.name          = "Chroma AGC",
 			.minimum       = 0,
@@ -299,6 +314,7 @@
 	V4L2_CID_AUDIO_VOLUME,
 	V4L2_CID_AUDIO_BALANCE,
 	V4L2_CID_AUDIO_MUTE,
+	V4L2_CID_SHARPNESS,
 	V4L2_CID_CHROMA_AGC,
 	V4L2_CID_COLOR_KILLER,
 	0
@@ -960,6 +976,11 @@
 	case V4L2_CID_AUDIO_VOLUME:
 		ctl->value = 0x3f - (value & 0x3f);
 		break;
+	case V4L2_CID_SHARPNESS:
+		ctl->value = (value & 0x0380) >> 6;
+		ctl->value = (ctl->value < 8 ? 0 : (ctl->value - 6))
+			     | ((cx_read(MO_HTOTAL) & 0x0800) >> 11);
+		break;
 	default:
 		ctl->value = ((value + (c->off << c->shift)) & c->mask) >> c->shift;
 		break;
@@ -1011,6 +1032,14 @@
 		}
 		mask=0xffff;
 		break;
+	case V4L2_CID_SHARPNESS:
+		/* use 4xFsc or square pixel notch filter */
+		cx_andor(MO_HTOTAL, 0x1800, (ctl->value & 1) << 11);
+		/* 0b000, 0b100, 0b101, 0b110, or 0b111 */
+		value = (ctl->value < 2 ? 0 : (((ctl->value + 6) & 0x0E) << 6));
+		/* needs to be set for both fields */
+		cx_andor(MO_FILTER_EVEN, mask, value);
+		break;
 	case V4L2_CID_CHROMA_AGC:
 		/* Do not allow chroma AGC to be enabled for SECAM */
 		value = ((ctl->value - c->off) << c->shift) & c->mask;
/drivers/media/video/tuner-core.c +15 -0
diff -Naur linux-2.6.37.2.old//drivers/media/video/tuner-core.c linux-2.6.37.2//drivers/media/video/tuner-core.c
@@ -28,6 +28,7 @@
 #include "tuner-simple.h"
 #include "tda9887.h"
 #include "xc5000.h"
+#include "xc4000.h"
 #include "tda18271.h"
 
 #define UNSET (-1U)
@@ -310,6 +311,7 @@
 }
 
 static struct xc5000_config xc5000_cfg;
+static struct xc4000_config xc4000_cfg;
 
 static void set_type(struct i2c_client *c, unsigned int type,
 		     unsigned int new_mode_mask, unsigned int new_config,
@@ -422,6 +424,19 @@
 			goto attach_failed;
 		tune_now = 0;
 		break;
+	}
+	case TUNER_XC4000:
+	{
+		/* card_type and if_khz will be set when the digital
+		   dvb_attach() occurs */
+		xc4000_cfg.card_type	  = XC4000_CARD_WINFAST_CX88;
+		xc4000_cfg.i2c_address	  = t->i2c->addr;
+		xc4000_cfg.if_khz	  = 0;
+		if (!dvb_attach(xc4000_attach,
+				&t->fe, t->i2c->adapter, &xc4000_cfg))
+			goto attach_failed;
+		tune_now = 0;
+		break;
 	}
 	case TUNER_NXP_TDA18271:
 	{
/include/media/tuner.h +1 -0
diff -Naur linux-2.6.37.2.old//include/media/tuner.h linux-2.6.37.2//include/media/tuner.h
@@ -131,6 +131,7 @@
 #define TUNER_NXP_TDA18271		83
 #define TUNER_SONY_BTF_PXN01Z		84
 #define TUNER_PHILIPS_FQ1236_MK5	85	/* NTSC, TDA9885, no FM radio */
+#define TUNER_XC4000			86	/* Xceive Silicon Tuner */
 
 /* tv card specific */
 #define TDA9887_PRESENT 		(1<<0)

_______________________________________________
linux-dvb users mailing list
For V4L/DVB development, please use instead [email protected] [email protected]
http://www.linuxtv.org/cgi-bin/mailman/listinfo/linux-dvb

#1 lore raw

Hi

Quoted 7 lines

Hi Istvan

I am sending you modified patches for kernel 2.6.37.2, they
works as expected.

First apply kernel_xc4000.diff (your patch) then kernel_dtv3200h.diff for Leadtek DTV3200 XC4000 support.

Can you resend your patches with right Signed-Off string for commit into kernel?

With my best regards, Dmitry.

#2 lore raw
Quoted 7 lines · Dmitri Belimov

Hi

Quoted 5 lines

Hi Istvan

      I am sending you modified patches for kernel 2.6.37.2, they works as expected.

Quoted 6 lines
Quoted 2 lines

First apply kernel_xc4000.diff (your patch) then kernel_dtv3200h.diff for Leadtek DTV3200 XC4000 support.

Can you resend your patches with right Signed-Off string for commit into kernel?

With my best regards, Dmitry.

He cannot offer a Signed-off-by for the entire patch - it's not his code. The patches are based on the work that Davide Ferri and I did about 17 months ago:

http://kernellabs.com/hg/~dheitmueller/pctv-340e-2/shortlog

I'm not against seeing the xc4000 support going in, but the history needs to be preserved, which means it needs to be broken in to a patch series that properly credits my and Davide's work.

Devin

Signature · 2 lines
Devin J. Heitmueller - Kernel Labs
http://www.kernellabs.com
#3 lore raw

Hi Devin

Quoted 21 lines
Quoted 7 lines · Dmitri Belimov

Hi

Quoted 5 lines

Hi Istvan

      I am sending you modified patches for kernel 2.6.37.2, they works as expected.

Quoted 7 lines
Quoted 2 lines

First apply kernel_xc4000.diff (your patch) then kernel_dtv3200h.diff for Leadtek DTV3200 XC4000 support.

Can you resend your patches with right Signed-Off string for commit into kernel?

With my best regards, Dmitry.

He cannot offer a Signed-off-by for the entire patch - it's not his code. The patches are based on the work that Davide Ferri and I did about 17 months ago:

Quoted 5 lines

http://kernellabs.com/hg/~dheitmueller/pctv-340e-2/shortlog

I'm not against seeing the xc4000 support going in, but the history needs to be preserved, which means it needs to be broken in to a patch series that properly credits my and Davide's work.

Is it possible make some patches and add support xc4000 into kernel?

With my best regards, Dmitry.

Quoted 5 lines

Devin

Signature · 2 lines
Devin J. Heitmueller - Kernel Labs
http://www.kernellabs.com
#4 lore raw

2011/5/31 Dmitri Belimov <[email protected]>:

Quoted 3 lines

Is it possible make some patches and add support xc4000 into kernel?

With my best regards, Dmitry.

What needs to happen here is somebody needs to prepare a patch series which contains all the relevant patches, including the SOBs. This is entirely an janitorial task which can be done by anyone and frankly I don't have time for this sort of crap anymore.

Any volunteers?

All my patches have my SOB attached. I explicitly got Davide's permission to add his SOB to his original patch, but it's not in the HG tree since I got the permission after I committed his change to my repo. I can forward the email with his SOB so the person constructing the tree can add it on (as well as my SOB to preserve the chain of custody).

Secondly, we need to build a firmware image which is based off of the *actual* xceive firmware sources, so that we can be confident that all the blobs are from the same firmware revision and so that we can maintain them going forward. I can provide them off-list to someone willing to do this work and testing. Istann_v's firmware image is based off of i2c dumps and extracted by hand from disassembled firmware, which is less than ideal from an ongoing maintenance perspective.

And of course it's worth mentioning that the driver itself still needs a ton of cleanup, doesn't meet the coding standards, and wouldn't be accepted upstream in its current state. Somebody will need to do the work to clean up the driver, as well as testing to make sure he/she didn't cause any regressions.

In summary, here are the four things that need to happen:

1.  Assemble tree with current patches
2.  Construct valid firmware image off of current sources
3.  Cleanup/coding style
4.  Testing

Now that we've got a bunch of people who are interested in seeing this upstream, who is going to volunteer to do which items in the above list?

Devin

Signature · 2 lines
Devin J. Heitmueller - Kernel Labs
http://www.kernellabs.com
#5 lore raw

Em 02-06-2011 07:52, Devin Heitmueller escreveu:

Quoted 34 lines

2011/5/31 Dmitri Belimov <[email protected]>:

Quoted 3 lines

Is it possible make some patches and add support xc4000 into kernel?

With my best regards, Dmitry.

What needs to happen here is somebody needs to prepare a patch series which contains all the relevant patches, including the SOBs. This is entirely an janitorial task which can be done by anyone and frankly I don't have time for this sort of crap anymore.

Any volunteers?

All my patches have my SOB attached. I explicitly got Davide's permission to add his SOB to his original patch, but it's not in the HG tree since I got the permission after I committed his change to my repo. I can forward the email with his SOB so the person constructing the tree can add it on (as well as my SOB to preserve the chain of custody).

Secondly, we need to build a firmware image which is based off of the *actual* xceive firmware sources, so that we can be confident that all the blobs are from the same firmware revision and so that we can maintain them going forward. I can provide them off-list to someone willing to do this work and testing. Istann_v's firmware image is based off of i2c dumps and extracted by hand from disassembled firmware, which is less than ideal from an ongoing maintenance perspective.

And of course it's worth mentioning that the driver itself still needs a ton of cleanup, doesn't meet the coding standards, and wouldn't be accepted upstream in its current state. Somebody will need to do the work to clean up the driver, as well as testing to make sure he/she didn't cause any regressions.

Quoted 3 lines

In summary, here are the four things that need to happen:

1. Assemble tree with current patches

It is probably easier for me to do this step, as I have my hg import scripts. However, as I don't have the PCTV devices added at dib0700, I can't test.

OK, I did this work, as it just took me a few minutes to rebase patches 1 and 2. I didn't apply the patches that started with "djh" since they seemed to be a few hacks during the development time.

The tree is at:

git://linuxtv.org/mchehab/experimental.git branch xc4000

There are two warnings there that needs to be fixed:

drivers/media/common/tuners/xc4000.c:1293: warning: ‘xc4000_is_firmware_loaded’ defined but not used drivers/media/common/tuners/xc4000.c: In function ‘check_firmware.clone.0’:
drivers/media/common/tuners/xc4000.c:1107: warning: ‘version’ may be used uninitialized in this function

Both seems to be trivial.

A disclaimer notice here: I didn't make any cleanup at the code, (except by running a whitespace cleanup script) nor I've reviewed it.

IMO, the next step is to test the rebases against a real hardware, and adding a few patches fixing it, if the rebases broke.

The next step would be fix the CodingStyle, and run checkpatch.pl. There aren't many CodingStyle warnings/errors (13 errors, 28 warnings). Most of the errors are due to the excess usage of printk's for debug, and due to some obsolete code commented with //.

Quoted 10 lines
2.  Construct valid firmware image off of current sources
3.  Cleanup/coding style
4.  Testing

Now that we've got a bunch of people who are interested in seeing this upstream, who is going to volunteer to do which items in the above list?

Devin

#6 lore raw
Quoted 25 lines · Mauro Carvalho Chehab
Quoted 1 line

1.  Assemble tree with current patches

It is probably easier for me to do this step, as I have my hg import scripts. However, as I don't have the PCTV devices added at dib0700, I can't test.

OK, I did this work, as it just took me a few minutes to rebase patches 1 and 2. I didn't apply the patches that started with "djh" since they seemed to be a few hacks during the development time.

The tree is at:

git://linuxtv.org/mchehab/experimental.git branch xc4000

There are two warnings there that needs to be fixed:

drivers/media/common/tuners/xc4000.c:1293: warning: ‘xc4000_is_firmware_loaded’ defined but not used drivers/media/common/tuners/xc4000.c: In function ‘check_firmware.clone.0’:
drivers/media/common/tuners/xc4000.c:1107: warning: ‘version’ may be used uninitialized in this function

Both seems to be trivial.

A disclaimer notice here: I didn't make any cleanup at the code, (except by running a whitespace cleanup script) nor I've reviewed it.

Quoted 7 lines

IMO, the next step is to test the rebases against a real hardware, and adding a few patches fixing it, if the rebases broke.

The next step would be fix the CodingStyle, and run checkpatch.pl. There aren't many CodingStyle warnings/errors (13 errors, 28 warnings). Most of the errors are due to the excess usage of printk's for debug, and due to some obsolete code commented with //.

Hi Mauro,

Thanks for taking this on. The tree you posted looks like a pretty reasonable start. I agree that the "djh - " commits probably aren't required as they are most just from rebasing the tree. We'll find out from testing though whether this is true. There's one patch with subject "djh - more debugging" might actually be needed, but we'll see when users try the tree.

This provides a pretty good base for istan_v to work off of, since he did a rather large amount of refactoring to get analog to work - which I was unable to even try given the two devices I had can't do analog support due to limitations in the dvb-usb framework.

Mohammad, it would be great if you could try out Mauro's tree, since it should work as-is for the 340e.

Devin

Signature · 2 lines
Devin J. Heitmueller - Kernel Labs
http://www.kernellabs.com
#7 lore raw

Em 02-06-2011 12:17, Devin Heitmueller escreveu:

Quoted 35 lines
Quoted 25 lines · Mauro Carvalho Chehab
Quoted 1 line

1. Assemble tree with current patches

It is probably easier for me to do this step, as I have my hg import scripts. However, as I don't have the PCTV devices added at dib0700, I can't test.

OK, I did this work, as it just took me a few minutes to rebase patches 1 and 2. I didn't apply the patches that started with "djh" since they seemed to be a few hacks during the development time.

The tree is at:

git://linuxtv.org/mchehab/experimental.git branch xc4000

There are two warnings there that needs to be fixed:

drivers/media/common/tuners/xc4000.c:1293: warning: ‘xc4000_is_firmware_loaded’ defined but not used drivers/media/common/tuners/xc4000.c: In function ‘check_firmware.clone.0’:
drivers/media/common/tuners/xc4000.c:1107: warning: ‘version’ may be used uninitialized in this function

Both seems to be trivial.

A disclaimer notice here: I didn't make any cleanup at the code, (except by running a whitespace cleanup script) nor I've reviewed it.

Quoted 7 lines

IMO, the next step is to test the rebases against a real hardware, and adding a few patches fixing it, if the rebases broke.

The next step would be fix the CodingStyle, and run checkpatch.pl. There aren't many CodingStyle warnings/errors (13 errors, 28 warnings). Most of the errors are due to the excess usage of printk's for debug, and due to some obsolete code commented with //.

Quoted 8 lines

Hi Mauro,

Thanks for taking this on. The tree you posted looks like a pretty reasonable start. I agree that the "djh - " commits probably aren't required as they are most just from rebasing the tree. We'll find out from testing though whether this is true. There's one patch with subject "djh - more debugging" might actually be needed, but we'll see when users try the tree.

I was in doubt and I almost backported that one too, but it seemed better to not add it to just remove it at the end.

Btw, it seems that a latter patch on your tree removed it. The only difference between the git tree and your tree at xc4000.c/xc4000.h is:

$ diff -uprBw drivers/media/common/tuners/xc4000.c /home/v4l/tmp/linux/drivers/media/common/tuners/xc4000.c
--- drivers/media/common/tuners/xc4000.c	2011-06-02 11:36:19.000000000 -0300
+++ /home/v4l/tmp/linux/drivers/media/common/tuners/xc4000.c	2011-06-02 10:48:34.000000000 -0300
@@ -1272,7 +1272,8 @@ static int xc4000_set_params(struct dvb_
 		XC4000_Standard[priv->video_standard].AudioMode);
 	if (ret != XC_RESULT_SUCCESS) {
 		printk(KERN_ERR "xc4000: xc_SetTVStandard failed\n");
-		return -EREMOTEIO;
+		/* DJH - do not return when it fails... */
+		//return -EREMOTEIO;
 	}
 #ifdef DJH_DEBUG
 	ret = xc_set_IF_frequency(priv, priv->if_khz);

So, maybe the above patch also needs to be added there.

Quoted 7 lines

This provides a pretty good base for istan_v to work off of, since he did a rather large amount of refactoring to get analog to work - which I was unable to even try given the two devices I had can't do analog support due to limitations in the dvb-usb framework.

Mohammad, it would be great if you could try out Mauro's tree, since it should work as-is for the 340e.

If it doesn't, please try to apply the above patch.

Thanks,
Mauro

#8 lore raw
In reply to Mauro Carvalho Chehab
Quoted 65 lines · On Thu, 02 Jun 2011 11:41:53 -0300 Mauro Carvalho Chehab <[email protected]>…

Em 02-06-2011 07:52, Devin Heitmueller escreveu:

Quoted 35 lines

2011/5/31 Dmitri Belimov <[email protected]>:

Quoted 4 lines

Is it possible make some patches and add support xc4000 into kernel?

With my best regards, Dmitry.

What needs to happen here is somebody needs to prepare a patch series which contains all the relevant patches, including the SOBs. This is entirely an janitorial task which can be done by anyone and frankly I don't have time for this sort of crap anymore.

Any volunteers?

All my patches have my SOB attached. I explicitly got Davide's permission to add his SOB to his original patch, but it's not in the HG tree since I got the permission after I committed his change to my repo. I can forward the email with his SOB so the person constructing the tree can add it on (as well as my SOB to preserve the chain of custody).

Secondly, we need to build a firmware image which is based off of the *actual* xceive firmware sources, so that we can be confident that all the blobs are from the same firmware revision and so that we can maintain them going forward. I can provide them off-list to someone willing to do this work and testing. Istann_v's firmware image is based off of i2c dumps and extracted by hand from disassembled firmware, which is less than ideal from an ongoing maintenance perspective.

And of course it's worth mentioning that the driver itself still needs a ton of cleanup, doesn't meet the coding standards, and wouldn't be accepted upstream in its current state. Somebody will need to do the work to clean up the driver, as well as testing to make sure he/she didn't cause any regressions.

Quoted 3 lines

In summary, here are the four things that need to happen:

1. Assemble tree with current patches

It is probably easier for me to do this step, as I have my hg import scripts. However, as I don't have the PCTV devices added at dib0700, I can't test.

OK, I did this work, as it just took me a few minutes to rebase patches 1 and 2. I didn't apply the patches that started with "djh" since they seemed to be a few hacks during the development time.

The tree is at:

git://linuxtv.org/mchehab/experimental.git branch xc4000

There are two warnings there that needs to be fixed:

drivers/media/common/tuners/xc4000.c:1293: warning:
‘xc4000_is_firmware_loaded’ defined but not used drivers/media/common/tuners/xc4000.c: In function ‘check_firmware.clone.0’: drivers/media/common/tuners/xc4000.c:1107:
warning: ‘version’ may be used uninitialized in this function

Both seems to be trivial.

A disclaimer notice here: I didn't make any cleanup at the code, (except by running a whitespace cleanup script) nor I've reviewed it.

Quoted 19 lines

IMO, the next step is to test the rebases against a real hardware, and adding a few patches fixing it, if the rebases broke.

The next step would be fix the CodingStyle, and run checkpatch.pl. There aren't many CodingStyle warnings/errors (13 errors, 28 warnings). Most of the errors are due to the excess usage of printk's for debug, and due to some obsolete code commented with //.

Quoted 10 lines
2.  Construct valid firmware image off of current sources
3.  Cleanup/coding style
4.  Testing

Now that we've got a bunch of people who are interested in seeing this upstream, who is going to volunteer to do which items in the above list?

Devin

One of our TV card has this tuner. It works in analog mode. I try get right firmware cleanup and test.

Can I use
git://linuxtv.org/mchehab/experimental.git branch xc4000 for do it?

With my best regards, Dmitry.

#9 lore raw

Em 02-06-2011 22:41, Dmitri Belimov escreveu:

Quoted 9 lines

On Thu, 02 Jun 2011 11:41:53 -0300
Mauro Carvalho Chehab <[email protected]> wrote:

One of our TV card has this tuner. It works in analog mode. I try get right firmware cleanup and test.

Can I use
git://linuxtv.org/mchehab/experimental.git branch xc4000 for do it?

Sure. Feel free to use it. I'll be adding there the xc4000-related patches until they're ok for review.

Thanks,
Mauro

#10 lore raw
In reply to Devin Heitmueller

Now I understood how thing works here, and it clear to me, why the xc4000 driver is not being included in mainline V4L2.

It will be lots of commitments and hard work to be the maintainer, and I respect Mr. Devin's choice and decisions. There are several peoples that are interested in this driver, such as Mr. Istvan. I realized this driver does not have huge users/audiences, but still there are peoples who really need it. But, yeah, not everybody can 'port' the driver each time Linux kernel or V4L2 version being updated.

In this case, IF no one is able to maintains the driver, how others can benefit the 'updated' driver or patches for the new V4L2 or Linux releases?

At the moment I still be able to port and test it for my private use. Sometime I sent the patches to Mr. Istvan to be included in his xc4000 driver's website, for other users to use it.

BTW, I am not a programmer. I am just a system administrator, who only like to use shell scripts, awk, sed and grep. I only know how 'read' C, and can do SIMPLE 'porting' and testing tasks :). Still I really hope other developers able to include the analog TV/FM tuning and S-Video input feature to PCTV-340e.

Anyway, if this driver is not elligible to be included in V4L2 mainline, I know where to 'push' my patches. :)

Thank you.

Quoted 47 lines · Devin Heitmueller

2011/5/31 Dmitri Belimov <[email protected]>:

Quoted 3 lines

Is it possible make some patches and add support xc4000 into kernel?

With my best regards, Dmitry.

What needs to happen here is somebody needs to prepare a patch series which contains all the relevant patches, including the SOBs. This is entirely an janitorial task which can be done by anyone and frankly I don't have time for this sort of crap anymore.

Any volunteers?

All my patches have my SOB attached. I explicitly got Davide's permission to add his SOB to his original patch, but it's not in the HG tree since I got the permission after I committed his change to my repo. I can forward the email with his SOB so the person constructing the tree can add it on (as well as my SOB to preserve the chain of custody).

Secondly, we need to build a firmware image which is based off of the *actual* xceive firmware sources, so that we can be confident that all the blobs are from the same firmware revision and so that we can maintain them going forward. I can provide them off-list to someone willing to do this work and testing. Istann_v's firmware image is based off of i2c dumps and extracted by hand from disassembled firmware, which is less than ideal from an ongoing maintenance perspective.

And of course it's worth mentioning that the driver itself still needs a ton of cleanup, doesn't meet the coding standards, and wouldn't be accepted upstream in its current state. Somebody will need to do the work to clean up the driver, as well as testing to make sure he/she didn't cause any regressions.

In summary, here are the four things that need to happen:

1.  Assemble tree with current patches
2.  Construct valid firmware image off of current sources
3.  Cleanup/coding style
4.  Testing

Now that we've got a bunch of people who are interested in seeing this upstream, who is going to volunteer to do which items in the above list?

Devin

#11 lore raw

Em 02-06-2011 12:53, Mohammad Bahathir Hashim escreveu:

Quoted 10 lines

Now I understood how thing works here, and it clear to me, why the xc4000 driver is not being included in mainline V4L2.

It will be lots of commitments and hard work to be the maintainer, and I respect Mr. Devin's choice and decisions. There are several peoples that are interested in this driver, such as Mr. Istvan. I realized this driver does not have huge users/audiences, but still there are peoples who really need it. But, yeah, not everybody can 'port' the driver each time Linux kernel or V4L2 version being updated.

Quoted 4 lines

In this case, IF no one is able to maintains the driver, how others can benefit the 'updated' driver or patches for the new V4L2 or Linux releases?

Out of tree drivers tend to become obsolete on a few kernel releases, as the internal kernel API's were not designed to be stable, as we want innovation inside the kernel. So, people are free to change the internal APIs when needed.

That's why the best way is to submit patches upstream as they're ready for it.

Quoted 4 lines

At the moment I still be able to port and test it for my private use. Sometime I sent the patches to Mr. Istvan to be included in his xc4000 driver's website, for other users to use it.

Quoted 8 lines

BTW, I am not a programmer. I am just a system administrator, who only like to use shell scripts, awk, sed and grep. I only know how 'read' C, and can do SIMPLE 'porting' and testing tasks :). Still I really hope other developers able to include the analog TV/FM tuning and S-Video input feature to PCTV-340e.

Anyway, if this driver is not elligible to be included in V4L2 mainline, I know where to 'push' my patches. :)

Almost all drivers are eligible to be included, but the author needs to submit them, or someone on their behalf. If the driver doesn't have enough quality or needs some fixes, the submitter may need to fix it or, eventually, move it to staging.

With respect to xc4000, we need someone to test if the driver works after the backports. Please test it and answer to us with a "Tested-by" tag.

After the tests, it would be great to apply any pending patches for xc4000 before cleaning it, as if we do the reverse, existing patches won't apply.

Cheers,
Mauro

#12 lore raw

Thank you for the comments and pointers. I am happy, at least there are peoples who want to see the xc4000 driver alive.

Quoted 51 lines · Mauro Carvalho Chehab

Em 02-06-2011 12:53, Mohammad Bahathir Hashim escreveu:

Quoted 10 lines

Now I understood how thing works here, and it clear to me, why the xc4000 driver is not being included in mainline V4L2.

It will be lots of commitments and hard work to be the maintainer, and I respect Mr. Devin's choice and decisions. There are several peoples that are interested in this driver, such as Mr. Istvan. I realized this driver does not have huge users/audiences, but still there are peoples who really need it. But, yeah, not everybody can 'port' the driver each time Linux kernel or V4L2 version being updated.

Quoted 4 lines

In this case, IF no one is able to maintains the driver, how others can benefit the 'updated' driver or patches for the new V4L2 or Linux releases?

Out of tree drivers tend to become obsolete on a few kernel releases, as the internal kernel API's were not designed to be stable, as we want innovation inside the kernel. So, people are free to change the internal APIs when needed.

That's why the best way is to submit patches upstream as they're ready for it.

Quoted 4 lines

At the moment I still be able to port and test it for my private use. Sometime I sent the patches to Mr. Istvan to be included in his xc4000 driver's website, for other users to use it.

Quoted 8 lines

BTW, I am not a programmer. I am just a system administrator, who only like to use shell scripts, awk, sed and grep. I only know how 'read' C, and can do SIMPLE 'porting' and testing tasks :). Still I really hope other developers able to include the analog TV/FM tuning and S-Video input feature to PCTV-340e.

Anyway, if this driver is not elligible to be included in V4L2 mainline, I know where to 'push' my patches. :)

Almost all drivers are eligible to be included, but the author needs to submit them, or someone on their behalf. If the driver doesn't have enough quality or needs some fixes, the submitter may need to fix it or, eventually, move it to staging.

With respect to xc4000, we need someone to test if the driver works after the backports. Please test it and answer to us with a "Tested-by" tag.

After the tests, it would be great to apply any pending patches for xc4000 before cleaning it, as if we do the reverse, existing patches won't apply.

Cheers,
Mauro

A message that is not in the archive (sent off-list or not yet received): [email protected]

#14 lore raw

Re: [linux-dvb] XC4000: added card_type

Quoted 5 lines · On Fri, Jun 3, 2011 at 8:38 AM, [email protected] <[email protected]> wrote:

This patch adds support for selecting a card type in struct xc4000_config, to allow for implementing some card specific code in the driver.

Hi Istan,

I understand what you're trying to do here, but this is not a good approach. We do not want to be littering tuner drivers with card-specific if() statements. Also, this is inconsistent with the way all other tuner drivers work.

The approach you are attempting may seem easier at first, but it gets very difficult to manage over time as the number of boards that use the driver increases.

You should have the bridge driver be setting up the cfg structure and passing it to the xc4000 driver, just like the xc5000 and xc3028 do.

Devin

Signature · 8 lines
Devin J. Heitmueller - Kernel Labs
http://www.kernellabs.com

_______________________________________________
linux-dvb users mailing list
For V4L/DVB development, please use instead [email protected]
[email protected]
http://www.linuxtv.org/cgi-bin/mailman/listinfo/linux-dvb

A message that is not in the archive (sent off-list or not yet received): [email protected]

#16 lore raw

Re: XC4000: added card_type

Em 03-06-2011 10:16, [email protected] escreveu:

Quoted 19 lines · Devin Heitmueller
Quoted 6 lines

I understand what you're trying to do here, but this is not a good approach. We do not want to be littering tuner drivers with card-specific if() statements. Also, this is inconsistent with the way all other tuner drivers work.

Quoted 6 lines

The approach you are attempting may seem easier at first, but it gets very difficult to manage over time as the number of boards that use the driver increases.

You should have the bridge driver be setting up the cfg structure and passing it to the xc4000 driver, just like the xc5000 and xc3028 do.

Well, for now, I just create patches that reproduce all the changes I have made to the driver. Of course, these may not always be the best or most elegant possible solutions, and I expect many will not be accepted, or further changes/cleanup will be needed later.

Quoted 4 lines

I do not think the number of boards that use this tuner is likely to increase much in the future, though, since the XC4000 seems to be a discontinued product (at least it no longer appears anywhere on the Xceive web site).

While the xc4000 is not merged upstream, we may have such hack, but before merging, this issue should be solved.

However, it seems better to just do the right thing since the beginning:

just add a patch for cx88 adding the xc4000 boards there and filling the config stuff inside cx88 driver.

Cheers,
Mauro

#17 lore raw

Re: XC4000: added card_type

Quoted 7 lines · Mauro Carvalho Chehab

While the xc4000 is not merged upstream, we may have such hack, but before merging, this issue should be solved.

However, it seems better to just do the right thing since the beginning:

just add a patch for cx88 adding the xc4000 boards there and filling the config stuff inside cx88 driver.

I do intend to remove the card_type code later, and only send cx88 patches once the interface is cleaned up. It is only included for now to have a working code without conflicting patches, and I do not know exactly what the config structure should eventually contain, that is, some of the current board-specific 'if' statements may actually turn out to be unnecessary and can be made the same for all cards.

#18 lore raw

Re: XC4000: added card_type

In reply to a message not in the archive

Em 03-06-2011 09:38, [email protected] escreveu:

Quoted 3 lines

This patch adds support for selecting a card type in struct xc4000_config, to allow for implementing some card specific code in the driver.

Hi Istvan,

Please send your patches to [email protected]. The linux-dvb ML is obsolete. I didn't remove it from the server just to avoid loosing the mail history.

With respect to this specific patch, as Devin pointed, the proper way is to set the configurable data via the boards entries, and not inside xc4000.

So, feel free to send us patches to cx88 and other bridge drivers whose boards require different configs, in order to work with xc4000.

Thanks,
Mauro

Quoted 71 lines

xc4000_card_type.patch

diff -uNr xc4000_orig/drivers/media/common/tuners/xc4000.c xc4000/drivers/media/common/tuners/xc4000.c

drivers/media/common/tuners/xc4000.c +14 -1
@@ -85,6 +85,7 @@
 	u32	bandwidth;
 	u8	video_standard;
 	u8	rf_mode;
+	u8	card_type;
 	u8	ignore_i2c_write_errors;
  /*	struct xc2028_ctrl	ctrl; */
 	struct firmware_properties cur_fw;
@@ -1426,6 +1427,16 @@
 	int	instance;
 	u16	id = 0;
 
+	if (cfg->card_type != XC4000_CARD_GENERIC) {
+		if (cfg->card_type == XC4000_CARD_WINFAST_CX88) {
+			cfg->i2c_address = 0x61;
+			cfg->if_khz = 4560;
+		} else {			/* default to PCTV 340E */
+			cfg->i2c_address = 0x61;
+			cfg->if_khz = 5400;
+		}
+	}
+
 	dprintk(1, "%s(%d-%04x)\n", __func__,
 		i2c ? i2c_adapter_id(i2c) : -1,
 		cfg ? cfg->i2c_address : -1);
@@ -1435,6 +1446,8 @@
 	instance = hybrid_tuner_request_state(struct xc4000_priv, priv,
 					      hybrid_tuner_instance_list,
 					      i2c, cfg->i2c_address, "xc4000");
+	if (cfg->card_type != XC4000_CARD_GENERIC)
+		priv->card_type = cfg->card_type;
 	switch (instance) {
 	case 0:
 		goto fail;
@@ -1450,7 +1463,7 @@
 		break;
 	}
 
-	if (priv->if_khz == 0) {
+	if (cfg->if_khz != 0) {
 		/* If the IF hasn't been set yet, use the value provided by
 		   the caller (occurs in hybrid devices where the analog
 		   call to xc4000_attach occurs before the digital side) */

diff -uNr xc4000_orig/drivers/media/common/tuners/xc4000.h xc4000/drivers/media/common/tuners/xc4000.h

drivers/media/common/tuners/xc4000.h +6 -1
@@ -27,8 +27,13 @@
 struct dvb_frontend;
 struct i2c_adapter;
 
+#define XC4000_CARD_GENERIC		0
+#define XC4000_CARD_PCTV_340E		1
+#define XC4000_CARD_WINFAST_CX88	2
+
 struct xc4000_config {
-	u8	i2c_address;
+	u8	card_type;	/* if card type is not generic, all other */
+	u8	i2c_address;	/* parameters are automatically set */
 	u32	if_khz;
 };
 
#19 lore raw

XC4000: updated standards table

In reply to Devin Heitmueller

This patch makes the following changes to the standards table:
- added 'u16 int_freq' to struct XC_TV_STANDARD (needed for analog TV and radio, 0 for DVB-T)
- added new standard for SECAM-D/K video with PAL-D/K audio
- the 'int_freq' values are now specified in the table
- changed VideoMode for NTSC and PAL-B/G standards

drivers/media/common/tuners/xc4000.c +35 -32
diff -uNr xc4000_orig/drivers/media/common/tuners/xc4000.c xc4000/drivers/media/common/tuners/xc4000.c
@@ -94,7 +94,7 @@
 };
 
 /* Misc Defines */
-#define MAX_TV_STANDARD			23
+#define MAX_TV_STANDARD			24
 #define XC_MAX_I2C_WRITE_LENGTH		64
 
 /* Signal Types */
@@ -172,6 +172,7 @@
 	const char  *Name;
 	u16	    AudioMode;
 	u16	    VideoMode;
+	u16	    int_freq;
 };
 
 /* Tuner standards */
@@ -190,39 +191,41 @@
 #define XC4000_DK_SECAM_A2DK1		12
 #define XC4000_DK_SECAM_A2LDK3		13
 #define XC4000_DK_SECAM_A2MONO		14
-#define XC4000_L_SECAM_NICAM		15
-#define XC4000_LC_SECAM_NICAM		16
-#define XC4000_DTV6			17
-#define XC4000_DTV8			18
-#define XC4000_DTV7_8			19
-#define XC4000_DTV7			20
-#define XC4000_FM_Radio_INPUT2		21
-#define XC4000_FM_Radio_INPUT1	22
+#define XC4000_DK_SECAM_NICAM		15
+#define XC4000_L_SECAM_NICAM		16
+#define XC4000_LC_SECAM_NICAM		17
+#define XC4000_DTV6			18
+#define XC4000_DTV8			19
+#define XC4000_DTV7_8			20
+#define XC4000_DTV7			21
+#define XC4000_FM_Radio_INPUT2		22
+#define XC4000_FM_Radio_INPUT1		23
 
 static struct XC_TV_STANDARD XC4000_Standard[MAX_TV_STANDARD] = {
-	{"M/N-NTSC/PAL-BTSC", 0x0000, 0x8020},
-	{"M/N-NTSC/PAL-A2",   0x0000, 0x8020},
-	{"M/N-NTSC/PAL-EIAJ", 0x0040, 0x8020},
-	{"M/N-NTSC/PAL-Mono", 0x0078, 0x8020},
-	{"B/G-PAL-A2",        0x0000, 0x8059},
-	{"B/G-PAL-NICAM",     0x0004, 0x8059},
-	{"B/G-PAL-MONO",      0x0078, 0x8059},
-	{"I-PAL-NICAM",       0x0080, 0x8049},
-	{"I-PAL-NICAM-MONO",  0x0078, 0x8049},
-	{"D/K-PAL-A2",        0x0000, 0x8049},
-	{"D/K-PAL-NICAM",     0x0080, 0x8049},
-	{"D/K-PAL-MONO",      0x0078, 0x8049},
-	{"D/K-SECAM-A2 DK1",  0x0000, 0x8049},
-	{"D/K-SECAM-A2 L/DK3", 0x0000, 0x8049},
-	{"D/K-SECAM-A2 MONO", 0x0078, 0x8049},
-	{"L-SECAM-NICAM",     0x8080, 0x0009},
-	{"L'-SECAM-NICAM",    0x8080, 0x4009},
-	{"DTV6",              0x00C0, 0x8002},
-	{"DTV8",              0x00C0, 0x800B},
-	{"DTV7/8",            0x00C0, 0x801B},
-	{"DTV7",              0x00C0, 0x8007},
-	{"FM Radio-INPUT2",   0x0008, 0x9800},
-	{"FM Radio-INPUT1",   0x0008, 0x9000}
+	{"M/N-NTSC/PAL-BTSC",	0x0000, 0x80A0, 4500},
+	{"M/N-NTSC/PAL-A2",	0x0000, 0x80A0, 4600},
+	{"M/N-NTSC/PAL-EIAJ",	0x0040, 0x80A0, 4500},
+	{"M/N-NTSC/PAL-Mono",	0x0078, 0x80A0, 4500},
+	{"B/G-PAL-A2",		0x0000, 0x8159, 5640},
+	{"B/G-PAL-NICAM",	0x0004, 0x8159, 5740},
+	{"B/G-PAL-MONO",	0x0078, 0x8159, 5500},
+	{"I-PAL-NICAM",		0x0080, 0x8049, 6240},
+	{"I-PAL-NICAM-MONO",	0x0078, 0x8049, 6000},
+	{"D/K-PAL-A2",		0x0000, 0x8049, 6380},
+	{"D/K-PAL-NICAM",	0x0080, 0x8049, 6200},
+	{"D/K-PAL-MONO",	0x0078, 0x8049, 6500},
+	{"D/K-SECAM-A2 DK1",	0x0000, 0x8049, 6340},
+	{"D/K-SECAM-A2 L/DK3",	0x0000, 0x8049, 6000},
+	{"D/K-SECAM-A2 MONO",	0x0078, 0x8049, 6500},
+	{"D/K-SECAM-NICAM",	0x0080, 0x8049, 6200},
+	{"L-SECAM-NICAM",	0x8080, 0x0009, 6200},
+	{"L'-SECAM-NICAM",	0x8080, 0x4009, 6200},
+	{"DTV6",		0x00C0, 0x8002,    0},
+	{"DTV8",		0x00C0, 0x800B,    0},
+	{"DTV7/8",		0x00C0, 0x801B,    0},
+	{"DTV7",		0x00C0, 0x8007,    0},
+	{"FM Radio-INPUT2",	0x0008, 0x9800,10700},
+	{"FM Radio-INPUT1",	0x0008, 0x9000,10700}
 };
 
 static int xc4000_readreg(struct xc4000_priv *priv, u16 reg, u16 *val);
#20 lore raw

XC4000: added support for 7 MHz DVB-T

In reply to Devin Heitmueller

The following patch implements support for DVB-T with 7 MHz bandwidth.

drivers/media/common/tuners/xc4000.c +15 -2
diff -uNr xc4000_orig/drivers/media/common/tuners/xc4000.c xc4000/drivers/media/common/tuners/xc4000.c
@@ -1183,15 +1183,28 @@
 			type = DTV6;
 			break;
 		case BANDWIDTH_7_MHZ:
-			printk(KERN_ERR "xc4000 bandwidth 7MHz not supported\n");
+			priv->bandwidth = BANDWIDTH_7_MHZ;
+			priv->video_standard = XC4000_DTV7;
+			priv->freq_hz = params->frequency - 2250000;
 			type = DTV7;
-			return -EINVAL;
+			break;
 		case BANDWIDTH_8_MHZ:
 			priv->bandwidth = BANDWIDTH_8_MHZ;
 			priv->video_standard = XC4000_DTV8;
 			priv->freq_hz = params->frequency - 2750000;
 			type = DTV8;
 			break;
+		case BANDWIDTH_AUTO:
+			if (params->frequency < 400000000) {
+				priv->bandwidth = BANDWIDTH_7_MHZ;
+				priv->freq_hz = params->frequency - 2250000;
+			} else {
+				priv->bandwidth = BANDWIDTH_8_MHZ;
+				priv->freq_hz = params->frequency - 2750000;
+			}
+			priv->video_standard = XC4000_DTV7_8;
+			type = DTV78;
+			break;
 		default:
 			printk(KERN_ERR "xc4000 bandwidth not set!\n");
 			return -EINVAL;
#21 lore raw

XC4000: added mutex

In reply to Devin Heitmueller

This patch adds a mutex to xc4000_priv, to protect the driver from being accessed by multiple processes at the same time.

drivers/media/common/tuners/xc4000.c +50 -30
diff -uNr xc4000_orig/drivers/media/common/tuners/xc4000.c xc4000/drivers/media/common/tuners/xc4000.c
@@ -28,6 +28,7 @@
 #include <linux/delay.h>
 #include <linux/dvb/frontend.h>
 #include <linux/i2c.h>
+#include <linux/mutex.h>
 #include <asm/unaligned.h>
 
 #include "dvb_frontend.h"
@@ -91,6 +92,7 @@
 	struct firmware_properties cur_fw;
 	__u16	hwmodel;
 	__u16	hwvers;
+	struct mutex	lock;
 };
 
 /* Misc Defines */
@@ -1144,10 +1146,12 @@
 {
 	struct xc4000_priv *priv = fe->tuner_priv;
 	unsigned int type;
-	int	ret;
+	int	ret = -EREMOTEIO;
 
 	dprintk(1, "%s() frequency=%d (Hz)\n", __func__, params->frequency);
 
+	mutex_lock(&priv->lock);
+
 	if (fe->ops.info.type == FE_ATSC) {
 		dprintk(1, "%s() ATSC\n", __func__);
 		switch (params->u.vsb.modulation) {
@@ -1171,7 +1175,8 @@
 			type = DTV6;
 			break;
 		default:
-			return -EINVAL;
+			ret = -EINVAL;
+			goto fail;
 		}
 	} else if (fe->ops.info.type == FE_OFDM) {
 		dprintk(1, "%s() OFDM\n", __func__);
@@ -1207,28 +1212,29 @@
 			break;
 		default:
 			printk(KERN_ERR "xc4000 bandwidth not set!\n");
-			return -EINVAL;
+			ret = -EINVAL;
+			goto fail;
 		}
 		priv->rf_mode = XC_RF_MODE_AIR;
 	} else {
 		printk(KERN_ERR "xc4000 modulation type not supported!\n");
-		return -EINVAL;
+		ret = -EINVAL;
+		goto fail;
 	}
 
 	dprintk(1, "%s() frequency=%d (compensated)\n",
 		__func__, priv->freq_hz);
 
 	/* Make sure the correct firmware type is loaded */
-	if (check_firmware(fe, type, 0, priv->if_khz) != XC_RESULT_SUCCESS) {
-		return -EREMOTEIO;
-	}
+	if (check_firmware(fe, type, 0, priv->if_khz) != XC_RESULT_SUCCESS)
+		goto fail;
 
 	ret = xc_SetSignalSource(priv, priv->rf_mode);
 	if (ret != XC_RESULT_SUCCESS) {
 		printk(KERN_ERR
-			"xc4000: xc_SetSignalSource(%d) failed\n",
-			priv->rf_mode);
-		return -EREMOTEIO;
+		       "xc4000: xc_SetSignalSource(%d) failed\n",
+		       priv->rf_mode);
+		goto fail;
 	}
 
 	ret = xc_SetTVStandard(priv,
@@ -1236,33 +1242,32 @@
 		XC4000_Standard[priv->video_standard].AudioMode);
 	if (ret != XC_RESULT_SUCCESS) {
 		printk(KERN_ERR "xc4000: xc_SetTVStandard failed\n");
-		return -EREMOTEIO;
-	}
-#ifdef DJH_DEBUG
-	ret = xc_set_IF_frequency(priv, priv->if_khz);
-	if (ret != XC_RESULT_SUCCESS) {
-		printk(KERN_ERR "xc4000: xc_Set_IF_frequency(%d) failed\n",
-		       priv->if_khz);
-		return -EIO;
+		goto fail;
 	}
-#endif
 	xc_tune_channel(priv, priv->freq_hz, XC_TUNE_DIGITAL);
 
 	if (debug)
 		xc_debug_dump(priv);
 
-	return 0;
+	ret = 0;
+
+fail:
+	mutex_unlock(&priv->lock);
+
+	return ret;
 }
 
 static int xc4000_set_analog_params(struct dvb_frontend *fe,
 	struct analog_parameters *params)
 {
 	struct xc4000_priv *priv = fe->tuner_priv;
-	int	ret;
+	int	ret = -EREMOTEIO;
 
 	dprintk(1, "%s() frequency=%d (in units of 62.5khz)\n",
 		__func__, params->frequency);
 
+	mutex_lock(&priv->lock);
+
 	/* Fix me: it could be air. */
 	priv->rf_mode = params->mode;
 	if (params->mode > XC_RF_MODE_CABLE)
@@ -1317,16 +1322,15 @@
 tune_channel:
 
 	/* FIXME - firmware type not being set properly */
-	if (check_firmware(fe, DTV8, 0, priv->if_khz) != XC_RESULT_SUCCESS) {
-		return -EREMOTEIO;
-	}
+	if (check_firmware(fe, DTV8, 0, priv->if_khz) != XC_RESULT_SUCCESS)
+		goto fail;
 
 	ret = xc_SetSignalSource(priv, priv->rf_mode);
 	if (ret != XC_RESULT_SUCCESS) {
 		printk(KERN_ERR
-			"xc4000: xc_SetSignalSource(%d) failed\n",
-			priv->rf_mode);
-		return -EREMOTEIO;
+		       "xc4000: xc_SetSignalSource(%d) failed\n",
+		       priv->rf_mode);
+		goto fail;
 	}
 
 	ret = xc_SetTVStandard(priv,
@@ -1334,7 +1338,7 @@
 		XC4000_Standard[priv->video_standard].AudioMode);
 	if (ret != XC_RESULT_SUCCESS) {
 		printk(KERN_ERR "xc4000: xc_SetTVStandard failed\n");
-		return -EREMOTEIO;
+		goto fail;
 	}
 
 	xc_tune_channel(priv, priv->freq_hz, XC_TUNE_ANALOG);
@@ -1342,7 +1346,12 @@
 	if (debug)
 		xc_debug_dump(priv);
 
-	return 0;
+	ret = 0;
+
+fail:
+	mutex_unlock(&priv->lock);
+
+	return ret;
 }
 
 static int xc4000_get_frequency(struct dvb_frontend *fe, u32 *freq)
@@ -1367,8 +1376,12 @@
 	struct xc4000_priv *priv = fe->tuner_priv;
 	u16	lock_status = 0;
 
+	mutex_lock(&priv->lock);
+
 	xc_get_lock_status(priv, &lock_status);
 
+	mutex_unlock(&priv->lock);
+
 	dprintk(1, "%s() lock_status = 0x%08x\n", __func__, lock_status);
 
 	*status = lock_status;
@@ -1385,9 +1398,13 @@
 static int xc4000_init(struct dvb_frontend *fe)
 {
 	struct xc4000_priv *priv = fe->tuner_priv;
+	int	ret;
 	dprintk(1, "%s()\n", __func__);
 
-	if (check_firmware(fe, DTV8, 0, priv->if_khz) != XC_RESULT_SUCCESS) {
+	mutex_lock(&priv->lock);
+	ret = check_firmware(fe, DTV8, 0, priv->if_khz);
+	mutex_unlock(&priv->lock);
+	if (ret != XC_RESULT_SUCCESS) {
 		printk(KERN_ERR "xc4000: Unable to initialise tuner\n");
 		return -EREMOTEIO;
 	}
@@ -1471,6 +1488,7 @@
 	case 1:
 		/* new tuner instance */
 		priv->bandwidth = BANDWIDTH_6_MHZ;
+		mutex_init(&priv->lock);
 		fe->tuner_priv = priv;
 		break;
 	default:
@@ -1522,7 +1540,9 @@
 
 	/* FIXME: For now, load the firmware at startup.  We will remove this
 	   before the code goes to production... */
+	mutex_lock(&priv->lock);
 	check_firmware(fe, DTV8, 0, priv->if_khz);
+	mutex_unlock(&priv->lock);
 
 	return fe;
 fail:
#22 lore raw

XC4000: fixed frequency error

In reply to Devin Heitmueller

The xc_get_frequency_error() function reported the frequency error incorrectly. The data read from the hardware is a signed integer, in 15625 Hz units. The attached patch fixes the bug.

drivers/media/common/tuners/xc4000.c +3 -2
diff -uNr xc4000_orig/drivers/media/common/tuners/xc4000.c xc4000/drivers/media/common/tuners/xc4000.c
@@ -418,8 +418,9 @@
 	if (result != XC_RESULT_SUCCESS)
 		return result;
 
-	tmp = (u32)regData;
-	(*freq_error_hz) = (tmp * 15625) / 1000;
+	tmp = (u32)regData & 0xFFFFU;
+	tmp = (tmp < 0x8000U ? tmp : 0x10000U - tmp);
+	(*freq_error_hz) = tmp * 15625;
 	return result;
 }
 
#23 lore raw

XC4000: added firmware_name parameter

In reply to Devin Heitmueller

The firmware_name module parameter makes it possible to set the firmware file name. It defaults to "xc4000.fw" if not specified.

drivers/media/common/tuners/xc4000.c +12 -5
diff -uNr xc4000_orig/drivers/media/common/tuners/xc4000.c xc4000/drivers/media/common/tuners/xc4000.c
@@ -47,16 +47,20 @@
 	"\t\t1 keep device energized and with tuner ready all the times.\n"
 	"\t\tFaster, but consumes more power and keeps the device hotter");
 
+#define XC4000_DEFAULT_FIRMWARE "xc4000.fw"
+
+static char firmware_name[30];
+module_param_string(firmware_name, firmware_name, sizeof(firmware_name), 0);
+MODULE_PARM_DESC(firmware_name, "\n\t\tFirmware file name. Allows overriding "
+	"the default firmware\n"
+	"\t\tname.");
+
 static DEFINE_MUTEX(xc4000_list_mutex);
 static LIST_HEAD(hybrid_tuner_instance_list);
 
 #define dprintk(level, fmt, arg...) if (debug >= level) \
 	printk(KERN_INFO "%s: " fmt, "xc4000", ## arg)
 
-/* Note that the last version digit is my internal build number (so I can
-   rev the firmware even if the core Xceive firmware was unchanged) */
-#define XC4000_DEFAULT_FIRMWARE "dvb-fe-xc4000-1.4.1.fw"
-
 /* struct for storing firmware table */
 struct firmware_description {
 	unsigned int  type;
@@ -714,7 +718,10 @@
 	char		      name[33];
 	const char	      *fname;
 
-	fname = XC4000_DEFAULT_FIRMWARE;
+	if (firmware_name[0] != '\0')
+		fname = firmware_name;
+	else
+		fname = XC4000_DEFAULT_FIRMWARE;
 
 	printk("Reading firmware %s\n",  fname);
 	rc = request_firmware(&fw, fname, priv->i2c_props.adap->dev.parent);
#24 lore raw

XC4000: simplified seek_firmware()

In reply to Devin Heitmueller

This patch simplifies the code in seek_firmware().

drivers/media/common/tuners/xc4000.c +24 -45
diff -uNr xc4000_orig/drivers/media/common/tuners/xc4000.c xc4000/drivers/media/common/tuners/xc4000.c
@@ -606,8 +606,8 @@
 			 v4l2_std_id *id)
 {
 	struct xc4000_priv *priv = fe->tuner_priv;
-	int                 i, best_i = -1, best_nr_matches = 0;
-	unsigned int        type_mask = 0;
+	int		i, best_i = -1;
+	unsigned int	best_nr_diffs = 255U;
 
 	if (!priv->firm) {
 		printk("Error! firmware not loaded\n");
@@ -617,63 +617,42 @@
 	if (((type & ~SCODE) == 0) && (*id == 0))
 		*id = V4L2_STD_PAL;
 
-	if (type & BASE)
-		type_mask = BASE_TYPES;
-	else if (type & SCODE) {
-		type &= SCODE_TYPES;
-		type_mask = SCODE_TYPES & ~HAS_IF;
-	} else if (type & DTV_TYPES)
-		type_mask = DTV_TYPES;
-	else if (type & STD_SPECIFIC_TYPES)
-		type_mask = STD_SPECIFIC_TYPES;
-
-	type &= type_mask;
-
-	if (!(type & SCODE))
-		type_mask = ~0;
-
-	/* Seek for exact match */
-	for (i = 0; i < priv->firm_size; i++) {
-		if ((type == (priv->firm[i].type & type_mask)) &&
-		    (*id == priv->firm[i].id))
-			goto found;
-	}
-
 	/* Seek for generic video standard match */
 	for (i = 0; i < priv->firm_size; i++) {
-		v4l2_std_id match_mask;
-		int nr_matches;
+		v4l2_std_id	id_diff_mask =
+			(priv->firm[i].id ^ (*id)) & (*id);
+		unsigned int	type_diff_mask =
+			(priv->firm[i].type ^ type)
+			& (BASE_TYPES | DTV_TYPES | LCD | NOGD | MONO | SCODE);
+		unsigned int	nr_diffs;
 
-		if (type != (priv->firm[i].type & type_mask))
+		if (type_diff_mask
+		    & (BASE | INIT1 | FM | DTV6 | DTV7 | DTV78 | DTV8 | SCODE))
 			continue;
 
-		match_mask = *id & priv->firm[i].id;
-		if (!match_mask)
-			continue;
-
-		if ((*id & match_mask) == *id)
-			goto found; /* Supports all the requested standards */
+		nr_diffs = hweight64(id_diff_mask) + hweight32(type_diff_mask);
+		if (!nr_diffs)	/* Supports all the requested standards */
+			goto found;
 
-		nr_matches = hweight64(match_mask);
-		if (nr_matches > best_nr_matches) {
-			best_nr_matches = nr_matches;
+		if (nr_diffs < best_nr_diffs) {
+			best_nr_diffs = nr_diffs;
 			best_i = i;
 		}
 	}
 
-	if (best_nr_matches > 0) {
-		printk("Selecting best matching firmware (%d bits) for "
-			  "type=", best_nr_matches);
+	/* FIXME: Would make sense to seek for type "hint" match ? */
+	if (best_i < 0) {
+		i = -ENOENT;
+		goto ret;
+	}
+
+	if (best_nr_diffs > 0U) {
+		printk("Selecting best matching firmware (%u bits differ) for "
+		       "type=", best_nr_diffs);
 		printk("(%x), id %016llx:\n", type, (unsigned long long)*id);
 		i = best_i;
-		goto found;
 	}
 
-	/*FIXME: Would make sense to seek for type "hint" match ? */
-
-	i = -ENOENT;
-	goto ret;
-
 found:
 	*id = priv->firm[i].id;
 
#25 lore raw

XC4000: simplified load_scode

In reply to Devin Heitmueller

Removed unused code from load_scode() (all SCODE firmwares are assumed to have the HAS_IF bit set).

drivers/media/common/tuners/xc4000.c +8 -18
diff -uNr xc4000_orig/drivers/media/common/tuners/xc4000.c xc4000/drivers/media/common/tuners/xc4000.c
@@ -781,8 +781,7 @@
 		p += sizeof(size);
 
 		if (!size || size > endp - p) {
-			printk("Firmware type ");
-			printk("(%x), id %llx is corrupted "
+			printk("Firmware type (%x), id %llx is corrupted "
 			       "(size=%d, expected %d)\n",
 			       type, (unsigned long long)id,
 			       (unsigned)(endp - p), size);
@@ -840,10 +839,10 @@
 			 v4l2_std_id *id, __u16 int_freq, int scode)
 {
 	struct xc4000_priv *priv = fe->tuner_priv;
-	int                pos, rc;
-	unsigned char	   *p;
-	u8 scode_buf[13];
-	u8 indirect_mode[5];
+	int		pos, rc;
+	unsigned char	*p;
+	u8		scode_buf[13];
+	u8		indirect_mode[5];
 
 	dprintk(1, "%s called int_freq=%d\n", __func__, int_freq);
 
@@ -863,18 +862,9 @@
 
 	p = priv->firm[pos].ptr;
 
-	if (priv->firm[pos].type & HAS_IF) {
-		if (priv->firm[pos].size != 12 * 16 || scode >= 16)
-			return -EINVAL;
-		p += 12 * scode;
-	} else {
-		/* 16 SCODE entries per file; each SCODE entry is 12 bytes and
-		 * has a 2-byte size header in the firmware format. */
-		if (priv->firm[pos].size != 14 * 16 || scode >= 16 ||
-		    le16_to_cpu(*(__u16 *)(p + 14 * scode)) != 12)
-			return -EINVAL;
-		p += 14 * scode + 2;
-	}
+	if (priv->firm[pos].size != 12 * 16 || scode >= 16)
+		return -EINVAL;
+	p += 12 * scode;
 
 	tuner_info("Loading SCODE for type=");
 	dump_firm_type_and_int_freq(priv->firm[pos].type,
#26 lore raw

XC4000: check_firmware() cleanup

In reply to Devin Heitmueller

This patch makes the following fixes in check_firmware():
- there is only one BASE and INIT1 firmware for XC4000
- loading SCODE is needed also for FM radio

drivers/media/common/tuners/xc4000.c +5 -10
diff -uNr xc4000_orig/drivers/media/common/tuners/xc4000.c xc4000/drivers/media/common/tuners/xc4000.c
@@ -904,7 +904,7 @@
 	struct xc4000_priv         *priv = fe->tuner_priv;
 	struct firmware_properties new_fw;
 	int			   rc = 0, is_retry = 0;
-	u16			   version, hwmodel;
+	u16			   version = 0, hwmodel;
 	v4l2_std_id		   std0;
 	u8			   hw_major, hw_minor, fw_major, fw_minor;
 
@@ -946,8 +946,7 @@
 	}
 
 	/* No need to reload base firmware if it matches */
-	if (((BASE | new_fw.type) & BASE_TYPES) ==
-	    (priv->cur_fw.type & BASE_TYPES)) {
+	if (priv->cur_fw.type & BASE) {
 		dprintk(1, "BASE firmware not changed.\n");
 		goto skip_base;
 	}
@@ -962,7 +961,7 @@
 
 	/* BASE firmwares are all std0 */
 	std0 = 0;
-	rc = load_firmware(fe, BASE | new_fw.type, &std0);
+	rc = load_firmware(fe, BASE, &std0);
 	if (rc < 0) {
 		printk("Error %d while loading base firmware\n", rc);
 		goto fail;
@@ -971,10 +970,9 @@
 	/* Load INIT1, if needed */
 	dprintk(1, "Load init1 firmware, if exists\n");
 
-	rc = load_firmware(fe, BASE | INIT1 | new_fw.type, &std0);
+	rc = load_firmware(fe, BASE | INIT1, &std0);
 	if (rc == -ENOENT)
-		rc = load_firmware(fe, (BASE | INIT1 | new_fw.type) & ~F8MHZ,
-				   &std0);
+		rc = load_firmware(fe, BASE | INIT1, &std0);
 	if (rc < 0 && rc != -ENOENT) {
 		tuner_err("Error %d while loading init1 firmware\n",
 			  rc);
@@ -1008,9 +1006,6 @@
 		goto check_device;
 	}
 
-	if (new_fw.type & FM)
-		goto check_device;
-
 	/* Load SCODE firmware, if exists */
 	rc = load_scode(fe, new_fw.type | new_fw.scode_table, &new_fw.id,
 			new_fw.int_freq, new_fw.scode_nr);
#27 lore raw

XC4000: implemented power management

In reply to Devin Heitmueller

The following patch implements the xc4000_sleep() function. The 'no_powerdown' module parameter is now interpreted differently:
- 0 uses a device-specific default
- 1 disables power management like before
- 2 enables power management

drivers/media/common/tuners/xc4000.c +34 -5
diff -uNr xc4000_orig/drivers/media/common/tuners/xc4000.c xc4000/drivers/media/common/tuners/xc4000.c
@@ -43,9 +43,11 @@
 
 static int no_poweroff;
 module_param(no_poweroff, int, 0644);
-MODULE_PARM_DESC(no_poweroff, "0 (default) powers device off when not used.\n"
-	"\t\t1 keep device energized and with tuner ready all the times.\n"
-	"\t\tFaster, but consumes more power and keeps the device hotter");
+MODULE_PARM_DESC(no_poweroff, "\n\t\t1: keep device energized and with tuner "
+	"ready all the times.\n"
+	"\t\tFaster, but consumes more power and keeps the device hotter.\n"
+	"\t\t2: powers device off when not used.\n"
+	"\t\t0 (default): use device-specific default mode.");
 
 #define XC4000_DEFAULT_FIRMWARE "xc4000.fw"
 
@@ -102,6 +104,7 @@
 /* Misc Defines */
 #define MAX_TV_STANDARD			24
 #define XC_MAX_I2C_WRITE_LENGTH		64
+#define XC_POWERED_DOWN			0x80000000U
 
 /* Signal Types */
 #define XC_RF_MODE_AIR			0
@@ -1365,8 +1368,34 @@
 
 static int xc4000_sleep(struct dvb_frontend *fe)
 {
-	/* FIXME: djh disable this for now... */
-	return XC_RESULT_SUCCESS;
+	struct xc4000_priv *priv = fe->tuner_priv;
+	int	ret = XC_RESULT_SUCCESS;
+
+	dprintk(1, "%s()\n", __func__);
+
+	mutex_lock(&priv->lock);
+
+	/* Avoid firmware reload on slow devices */
+	if ((no_poweroff == 2 ||
+	     (no_poweroff == 0 &&
+	      priv->card_type != XC4000_CARD_WINFAST_CX88)) &&
+	    (priv->cur_fw.type & BASE) != 0) {
+		/* force reset and firmware reload */
+		priv->cur_fw.type = XC_POWERED_DOWN;
+
+		if (xc_write_reg(priv, XREG_POWER_DOWN, 0)
+		    != XC_RESULT_SUCCESS) {
+			printk(KERN_ERR
+			       "xc4000: %s() unable to shutdown tuner\n",
+			       __func__);
+			ret = -EREMOTEIO;
+		}
+		xc_wait(20);
+	}
+
+	mutex_unlock(&priv->lock);
+
+	return ret;
 }
 
 static int xc4000_init(struct dvb_frontend *fe)
#28 lore raw

XC4000: firmware initialization

In reply to Devin Heitmueller

This patch fixes/cleans up the loading of the firmware file when the driver is loaded and initialized.

drivers/media/common/tuners/xc4000.c +16 -20
diff -uNr xc4000_orig/drivers/media/common/tuners/xc4000.c xc4000/drivers/media/common/tuners/xc4000.c
@@ -1400,21 +1400,8 @@
 
 static int xc4000_init(struct dvb_frontend *fe)
 {
-	struct xc4000_priv *priv = fe->tuner_priv;
-	int	ret;
 	dprintk(1, "%s()\n", __func__);
 
-	mutex_lock(&priv->lock);
-	ret = check_firmware(fe, DTV8, 0, priv->if_khz);
-	mutex_unlock(&priv->lock);
-	if (ret != XC_RESULT_SUCCESS) {
-		printk(KERN_ERR "xc4000: Unable to initialise tuner\n");
-		return -EREMOTEIO;
-	}
-
-	if (debug)
-		xc_debug_dump(priv);
-
 	return 0;
 }
 
@@ -1511,8 +1498,14 @@
 	   instance of the driver has loaded the firmware.
 	 */
 
-	if (xc4000_readreg(priv, XREG_PRODUCT_ID, &id) != XC_RESULT_SUCCESS)
+	if (instance == 1) {
+		if (xc4000_readreg(priv, XREG_PRODUCT_ID, &id)
+		    != XC_RESULT_SUCCESS)
 			goto fail;
+	} else {
+		id = ((priv->cur_fw.type & BASE) != 0 ?
+		      priv->hwmodel : XC_PRODUCT_ID_FW_NOT_LOADED);
+	}
 
 	switch (id) {
 	case XC_PRODUCT_ID_FW_LOADED:
@@ -1541,16 +1534,19 @@
 	memcpy(&fe->ops.tuner_ops, &xc4000_tuner_ops,
 		sizeof(struct dvb_tuner_ops));
 
-	/* FIXME: For now, load the firmware at startup.  We will remove this
-	   before the code goes to production... */
-	mutex_lock(&priv->lock);
-	check_firmware(fe, DTV8, 0, priv->if_khz);
-	mutex_unlock(&priv->lock);
+	if (instance == 1) {
+		int	ret;
+		mutex_lock(&priv->lock);
+		ret = xc4000_fwupload(fe);
+		mutex_unlock(&priv->lock);
+		if (ret != XC_RESULT_SUCCESS)
+			goto fail2;
+	}
 
 	return fe;
 fail:
 	mutex_unlock(&xc4000_list_mutex);
-
+fail2:
 	xc4000_release(fe);
 	return NULL;
 }
#29 lore raw

XC4000: debug message improvements

In reply to Devin Heitmueller

The following patch makes a few minor changes to the printing of debug messages, and reporting the tuner status. The 'debug' module parameter can now be set from 0 to 2 to control the verbosity of debug messages.

drivers/media/common/tuners/xc4000.c +45 -23
diff -uNr xc4000_orig/drivers/media/common/tuners/xc4000.c xc4000/drivers/media/common/tuners/xc4000.c
@@ -39,7 +39,7 @@
 
 static int debug;
 module_param(debug, int, 0644);
-MODULE_PARM_DESC(debug, "Turn on/off debugging (default:off).");
+MODULE_PARM_DESC(debug, "\n\t\tDebugging level (0 to 2, default: 0 (off)).");
 
 static int no_poweroff;
 module_param(no_poweroff, int, 0644);
@@ -239,6 +239,7 @@
 
 static int xc4000_readreg(struct xc4000_priv *priv, u16 reg, u16 *val);
 static int xc4000_TunerReset(struct dvb_frontend *fe);
+static void xc_debug_dump(struct xc4000_priv *priv);
 
 static int xc_send_i2c_data(struct xc4000_priv *priv, u8 *buf, int len)
 {
@@ -515,6 +516,15 @@
 			found = 1;
 	}
 
+	/* Wait for stats to stabilize.
+	 * Frame Lines needs two frame times after initial lock
+	 * before it is valid.
+	 */
+	xc_wait(debug ? 100 : 10);
+
+	if (debug)
+		xc_debug_dump(priv);
+
 	return found;
 }
 
@@ -1085,12 +1095,6 @@
 	u8	hw_majorversion = 0, hw_minorversion = 0;
 	u8	fw_majorversion = 0, fw_minorversion = 0;
 
-	/* Wait for stats to stabilize.
-	 * Frame Lines needs two frame times after initial lock
-	 * before it is valid.
-	 */
-	xc_wait(100);
-
 	xc_get_ADC_Envelope(priv, &adc_envelope);
 	dprintk(1, "*** ADC envelope (0-1023) = %d\n", adc_envelope);
 
@@ -1103,16 +1107,18 @@
 
 	xc_get_version(priv, &hw_majorversion, &hw_minorversion,
 		       &fw_majorversion, &fw_minorversion);
-
 	dprintk(1, "*** HW: V%02x.%02x, FW: V%02x.%02x\n",
 		hw_majorversion, hw_minorversion,
 		fw_majorversion, fw_minorversion);
 
-	xc_get_hsync_freq(priv, &hsync_freq_hz);
-	dprintk(1, "*** Horizontal sync frequency = %d Hz\n", hsync_freq_hz);
+	if (priv->video_standard < XC4000_DTV6) {
+		xc_get_hsync_freq(priv, &hsync_freq_hz);
+		dprintk(1, "*** Horizontal sync frequency = %d Hz\n",
+			hsync_freq_hz);
 
-	xc_get_frame_lines(priv, &frame_lines);
-	dprintk(1, "*** Frame lines = %d\n", frame_lines);
+		xc_get_frame_lines(priv, &frame_lines);
+		dprintk(1, "*** Frame lines = %d\n", frame_lines);
+	}
 
 	xc_get_quality(priv, &quality);
 	dprintk(1, "*** Quality (0:<8dB, 7:>56dB) = %d\n", quality);
@@ -1223,9 +1229,6 @@
 	}
 	xc_tune_channel(priv, priv->freq_hz, XC_TUNE_DIGITAL);
 
-	if (debug)
-		xc_debug_dump(priv);
-
 	ret = 0;
 
 fail:
@@ -1320,9 +1323,6 @@
 
 	xc_tune_channel(priv, priv->freq_hz, XC_TUNE_ANALOG);
 
-	if (debug)
-		xc_debug_dump(priv);
-
 	ret = 0;
 
 fail:
@@ -1334,8 +1334,26 @@
 static int xc4000_get_frequency(struct dvb_frontend *fe, u32 *freq)
 {
 	struct xc4000_priv *priv = fe->tuner_priv;
-	dprintk(1, "%s()\n", __func__);
+
 	*freq = priv->freq_hz;
+
+	if (debug) {
+		mutex_lock(&priv->lock);
+		if ((priv->cur_fw.type
+		     & (BASE | FM | DTV6 | DTV7 | DTV78 | DTV8)) == BASE) {
+			u16	snr = 0;
+			if (xc4000_readreg(priv, XREG_SNR, &snr) == 0) {
+				mutex_unlock(&priv->lock);
+				dprintk(1, "%s() freq = %u, SNR = %d\n",
+					__func__, *freq, snr);
+				return 0;
+			}
+		}
+		mutex_unlock(&priv->lock);
+	}
+
+	dprintk(1, "%s()\n", __func__);
+
 	return 0;
 }
 
@@ -1355,13 +1373,17 @@
 
 	mutex_lock(&priv->lock);
 
-	xc_get_lock_status(priv, &lock_status);
+	if (priv->cur_fw.type & BASE)
+		xc_get_lock_status(priv, &lock_status);
 
-	mutex_unlock(&priv->lock);
+	*status = (lock_status == 1 ?
+		   TUNER_STATUS_LOCKED | TUNER_STATUS_STEREO : 0);
+	if (priv->cur_fw.type & (DTV6 | DTV7 | DTV78 | DTV8))
+		*status &= (~TUNER_STATUS_STEREO);
 
-	dprintk(1, "%s() lock_status = 0x%08x\n", __func__, lock_status);
+	mutex_unlock(&priv->lock);
 
-	*status = lock_status;
+	dprintk(2, "%s() lock_status = %d\n", __func__, lock_status);
 
 	return 0;
 }
#30 lore raw

XC4000: setting registers

In reply to Devin Heitmueller

This patch implements setting the registers in xc4000_set_params() and xc4000_set_analog_params(). A new register is defined which enables filtering of the composite video output (this is needed to avoid bad picture quality with some boards).

drivers/media/common/tuners/xc4000.c +55 -12
diff -uNr xc4000_orig/drivers/media/common/tuners/xc4000.c xc4000/drivers/media/common/tuners/xc4000.c
@@ -131,6 +131,7 @@
 #define XREG_SEEK_MODE    0x06
 #define XREG_POWER_DOWN   0x08
 #define XREG_SIGNALSOURCE 0x0A
+#define XREG_SMOOTHEDCVBS 0x0E
 #define XREG_AMPLITUDE    0x10
 
 /* Registers (Read-only) */
@@ -1218,15 +1219,35 @@
 		       "xc4000: xc_SetSignalSource(%d) failed\n",
 		       priv->rf_mode);
 		goto fail;
+	} else {
+		u16	video_mode, audio_mode;
+		video_mode = XC4000_Standard[priv->video_standard].VideoMode;
+		audio_mode = XC4000_Standard[priv->video_standard].AudioMode;
+		if (type == DTV6 && priv->firm_version != 0x0102)
+			video_mode |= 0x0001;
+		ret = xc_SetTVStandard(priv, video_mode, audio_mode);
+		if (ret != XC_RESULT_SUCCESS) {
+			printk(KERN_ERR "xc4000: xc_SetTVStandard failed\n");
+			/* DJH - do not return when it fails... */
+			/* goto fail; */
+		}
 	}
 
-	ret = xc_SetTVStandard(priv,
-		XC4000_Standard[priv->video_standard].VideoMode,
-		XC4000_Standard[priv->video_standard].AudioMode);
-	if (ret != XC_RESULT_SUCCESS) {
-		printk(KERN_ERR "xc4000: xc_SetTVStandard failed\n");
-		goto fail;
+	if (priv->card_type == XC4000_CARD_WINFAST_CX88) {
+		if (xc_write_reg(priv, XREG_D_CODE, 0) == 0)
+			ret = 0;
+		if (xc_write_reg(priv, XREG_AMPLITUDE,
+				 (priv->firm_version == 0x0102 ? 132 : 134))
+		    != 0)
+			ret = -EREMOTEIO;
+		if (xc_write_reg(priv, XREG_SMOOTHEDCVBS, 1) != 0)
+			ret = -EREMOTEIO;
+		if (ret != 0) {
+			printk(KERN_ERR "xc4000: setting registers failed\n");
+			/* goto fail; */
+		}
 	}
+
 	xc_tune_channel(priv, priv->freq_hz, XC_TUNE_DIGITAL);
 
 	ret = 0;
@@ -1311,14 +1332,36 @@
 		       "xc4000: xc_SetSignalSource(%d) failed\n",
 		       priv->rf_mode);
 		goto fail;
+	} else {
+		u16	video_mode, audio_mode;
+		video_mode = XC4000_Standard[priv->video_standard].VideoMode;
+		audio_mode = XC4000_Standard[priv->video_standard].AudioMode;
+		if (priv->video_standard < XC4000_BG_PAL_A2) {
+			if (type & NOGD)
+				video_mode &= 0xFF7F;
+		} else if (priv->video_standard < XC4000_I_PAL_NICAM) {
+			if (priv->card_type == XC4000_CARD_WINFAST_CX88 &&
+			    priv->firm_version == 0x0102)
+				video_mode &= 0xFEFF;
+		}
+		ret = xc_SetTVStandard(priv, video_mode, audio_mode);
+		if (ret != XC_RESULT_SUCCESS) {
+			printk(KERN_ERR "xc4000: xc_SetTVStandard failed\n");
+			goto fail;
+		}
 	}
 
-	ret = xc_SetTVStandard(priv,
-		XC4000_Standard[priv->video_standard].VideoMode,
-		XC4000_Standard[priv->video_standard].AudioMode);
-	if (ret != XC_RESULT_SUCCESS) {
-		printk(KERN_ERR "xc4000: xc_SetTVStandard failed\n");
-		goto fail;
+	if (priv->card_type == XC4000_CARD_WINFAST_CX88) {
+		if (xc_write_reg(priv, XREG_D_CODE, 0) == 0)
+			ret = 0;
+		if (xc_write_reg(priv, XREG_AMPLITUDE, 1) != 0)
+			ret = -EREMOTEIO;
+		if (xc_write_reg(priv, XREG_SMOOTHEDCVBS, 1) != 0)
+			ret = -EREMOTEIO;
+		if (ret != 0) {
+			printk(KERN_ERR "xc4000: setting registers failed\n");
+			goto fail;
+		}
 	}
 
 	xc_tune_channel(priv, priv->freq_hz, XC_TUNE_ANALOG);
#31 lore raw

Re: XC4000: setting registers

Hi Istvan,

Em 04-06-2011 12:12, [email protected] escreveu:

Quoted 7 lines

This patch implements setting the registers in xc4000_set_params() and xc4000_set_analog_params(). A new register is defined which enables filtering of the composite video output (this is needed to avoid bad picture quality with some boards).

This one breaks compilation:

drivers/media/common/tuners/xc4000.c: In function ‘xc4000_set_analog_params’:
drivers/media/common/tuners/xc4000.c:1340: error: ‘type’ undeclared (first use in this function) drivers/media/common/tuners/xc4000.c:1340: error: (Each undeclared identifier is reported only once drivers/media/common/tuners/xc4000.c:1340: error: for each function it appears in.) make[3]: ** [drivers/media/common/tuners/xc4000.o] Erro 1
make[2]: ** [drivers/media/common/tuners] Erro 2
make[1]: ** [drivers/media/common] Erro 2
make: ** [drivers/media/] Erro 2

We should not allow that a patch in the middle of a series to break the compilation, as this breaks git bisect command. I fixed it with a hack.

All patches you've sent were added at my experimental tree, including the one that added a card type inside the struct.

I had to rebase the tree with:

git filter-branch -f --env-filter '{ GIT_AUTHOR_NAME="Istvan Varga"; GIT_AUTHOR_EMAIL="[email protected]"; export GIT_AUTHOR_NAME;}' ^3be84e2e789af734a35ad0559c2d7c4931d0fe91^ HEAD

As your emails are being sent without your name on it (from is: [email protected] <[email protected]>).

I didn't made any review of them. Please let me know when you finish submitting the patches for me to do a review at the resulting code.

Ah, I'd appreciate if you could fix your emails. It takes me some time to reformat the patches, as you're sending the patches as attachments, but my email scripts aren't ready for patches with multiple mime types. Patchwork might help, but it also got only 4 patches from you (not sure if this is due to patchwork bugs or due to the attachments). It also helps if you could add [PATCH] at the email subject. I'm setting a backup process due to the constant patchwork failures, but my alternative logic relies on having [PATCH] at the subject logic, to move the patches into a separate mail directory.

thanks,
Mauro.

#32 lore raw

Re: XC4000: setting registers

Quoted 3 lines · Mauro Carvalho Chehab

This one breaks compilation:

drivers/media/common/tuners/xc4000.c: In function

‘xc4000_set_analog_params’:

Quoted 1 line

drivers/media/common/tuners/xc4000.c:1340: error: ‘type’ undeclared

(first use in this function)

Quoted 1 line

drivers/media/common/tuners/xc4000.c:1340: error: (Each undeclared

identifier is reported only once

Quoted 1 line

drivers/media/common/tuners/xc4000.c:1340: error: for each function it

appears in.)

Quoted 4 lines

make[3]: ** [drivers/media/common/tuners/xc4000.o] Erro 1 make[2]: ** [drivers/media/common/tuners] Erro 2 make[1]: ** [drivers/media/common] Erro 2
make: ** [drivers/media/] Erro 2

Yes, it depends on the 'unsigned int type = 0;' declaration that is in the xc4000_analog.patch posted later. Sorry for this mistake. Although perhaps it would have been a better idea to make all the changes to xc4000_set_analog_params() in the analog patch as well, since the function does not work correctly until that is applied.

Quoted 2 lines

I didn't made any review of them. Please let me know when you finish submitting the patches for me to do a review at the resulting code.

For now, I do not have more patches. I will wait for the modified code to appear on GIT, and use that as a base for further patches.

Quoted 9 lines

Ah, I'd appreciate if you could fix your emails. It takes me some time to reformat the patches, as you're sending the patches as attachments, but my email scripts aren't ready for patches with multiple mime types. Patchwork might help, but it also got only 4 patches from you (not sure if this is due to patchwork bugs or due to the attachments). It also helps if you could add [PATCH] at the email subject. I'm setting a backup process due to the constant patchwork failures, but my alternative logic relies on having [PATCH] at the subject logic, to move the patches into a separate mail directory.

OK, I have changed the name in "from", and will send any later patches as plain text with [PATCH] in the subject. Should I re-send the previous patches in this format ?

#33 lore raw

Re: XC4000: setting registers

Em 05-06-2011 09:28, Istvan Varga escreveu:

Quoted 17 lines · Mauro Carvalho Chehab
Quoted 4 lines

This one breaks compilation:

drivers/media/common/tuners/xc4000.c: In function

‘xc4000_set_analog_params’:

Quoted 1 line

drivers/media/common/tuners/xc4000.c:1340: error: ‘type’ undeclared

(first use in this function)

Quoted 1 line

drivers/media/common/tuners/xc4000.c:1340: error: (Each undeclared

identifier is reported only once

Quoted 1 line

drivers/media/common/tuners/xc4000.c:1340: error: for each function it

appears in.)

Quoted 4 lines

make[3]: ** [drivers/media/common/tuners/xc4000.o] Erro 1 make[2]: ** [drivers/media/common/tuners] Erro 2 make[1]: ** [drivers/media/common] Erro 2
make: ** [drivers/media/] Erro 2

Quoted 5 lines

Yes, it depends on the 'unsigned int type = 0;' declaration that is in the xc4000_analog.patch posted later. Sorry for this mistake. Although perhaps it would have been a better idea to make all the changes to xc4000_set_analog_params() in the analog patch as well, since the function does not work correctly until that is applied.

Ok.

It is a good idea to number a series of patches, for me to apply them at the right order ;)

Quoted 6 lines
Quoted 3 lines

I didn't made any review of them. Please let me know when you finish submitting the patches for me to do a review at the resulting code.

For now, I do not have more patches. I will wait for the modified code to appear on GIT, and use that as a base for further patches.

Ok, just pushed it (I forgot to use the -f tag). Please double check if the code is working on the devices you have.

Quoted 10 lines
Quoted 9 lines

Ah, I'd appreciate if you could fix your emails. It takes me some time to reformat the patches, as you're sending the patches as attachments, but my email scripts aren't ready for patches with multiple mime types. Patchwork might help, but it also got only 4 patches from you (not sure if this is due to patchwork bugs or due to the attachments). It also helps if you could add [PATCH] at the email subject. I'm setting a backup process due to the constant patchwork failures, but my alternative logic relies on having [PATCH] at the subject logic, to move the patches into a separate mail directory.

Quoted 3 lines

OK, I have changed the name in "from", and will send any later patches as plain text with [PATCH] in the subject. Should I re-send the previous patches in this format ?

No, there's no need. I'll get a diff from all those x4000 series any post a review about the entire series, as if it were just one big patch.

Cheers,
Mauro

#34 lore raw

Re: XC4000: setting registers

Quoted 2 lines · Mauro Carvalho Chehab

Ok, just pushed it (I forgot to use the -f tag). Please double check if the code is working on the devices you have.

I did not try building it, but the code now seems to be identical to the xc4000.c/h driver I am currently using. There is one minor difference:
at line 1446, the use of the 'type' variable is still commented out; it does not actually affect the operation of the driver, though, since the NOGD bit is currently never set.

#35 lore raw

XC4000: added audio_std module parameter

In reply to Devin Heitmueller

The 'audio_std' module parameter makes it possible to fine tune some audio related aspects of the driver, like setting the exact audio standard (NICAM, A2, etc.) to be used for some video standards.

drivers/media/common/tuners/xc4000.c +23 -0
diff -uNr xc4000_orig/drivers/media/common/tuners/xc4000.c xc4000/drivers/media/common/tuners/xc4000.c
@@ -49,6 +49,27 @@
 	"\t\t2: powers device off when not used.\n"
 	"\t\t0 (default): use device-specific default mode.");
 
+#define XC4000_AUDIO_STD_B		 1
+#define XC4000_AUDIO_STD_A2		 2
+#define XC4000_AUDIO_STD_K3		 4
+#define XC4000_AUDIO_STD_L		 8
+#define XC4000_AUDIO_STD_INPUT1		16
+#define XC4000_AUDIO_STD_MONO		32
+
+static int audio_std;
+module_param(audio_std, int, 0644);
+MODULE_PARM_DESC(audio_std, "\n\t\tAudio standard. XC4000 audio decoder "
+	"explicitly needs to know\n"
+	"\t\twhat audio standard is needed for some video standards with\n"
+	"\t\taudio A2 or NICAM.\n"
+	"\t\tThe valid settings are a sum of:\n"
+	"\t\t 1: use NICAM/B or A2/B instead of NICAM/A or A2/A\n"
+	"\t\t 2: use A2 instead of NICAM or BTSC\n"
+	"\t\t 4: use SECAM/K3 instead of K1\n"
+	"\t\t 8: use PAL-D/K audio for SECAM-D/K\n"
+	"\t\t16: use FM radio input 1 instead of input 2\n"
+	"\t\t32: use mono audio (the lower three bits are ignored)");
+
 #define XC4000_DEFAULT_FIRMWARE "xc4000.fw"
 
 static char firmware_name[30];
@@ -1343,6 +1364,8 @@
 			if (priv->card_type == XC4000_CARD_WINFAST_CX88 &&
 			    priv->firm_version == 0x0102)
 				video_mode &= 0xFEFF;
+			if (audio_std & XC4000_AUDIO_STD_B)
+				video_mode |= 0x0080;
 		}
 		ret = xc_SetTVStandard(priv, video_mode, audio_mode);
 		if (ret != XC_RESULT_SUCCESS) {
#36 lore raw

XC4000: implemented analog TV and radio

In reply to Devin Heitmueller

The following patch implements support for analog TV and FM radio.

drivers/media/common/tuners/xc4000.c +100 -19
diff -uNr xc4000_orig/drivers/media/common/tuners/xc4000.c xc4000/drivers/media/common/tuners/xc4000.c
@@ -1283,69 +1283,150 @@
 	struct analog_parameters *params)
 {
 	struct xc4000_priv *priv = fe->tuner_priv;
+	unsigned int type = 0;
 	int	ret = -EREMOTEIO;
 
+	if (params->mode == V4L2_TUNER_RADIO) {
+		dprintk(1, "%s() frequency=%d (in units of 62.5Hz)\n",
+			__func__, params->frequency);
+
+		mutex_lock(&priv->lock);
+
+		params->std = 0;
+		priv->freq_hz = params->frequency * 125L / 2;
+
+		if (audio_std & XC4000_AUDIO_STD_INPUT1) {
+			priv->video_standard = XC4000_FM_Radio_INPUT1;
+			type = FM | INPUT1;
+		} else {
+			priv->video_standard = XC4000_FM_Radio_INPUT2;
+			type = FM | INPUT2;
+		}
+
+		goto tune_channel;
+	}
+
 	dprintk(1, "%s() frequency=%d (in units of 62.5khz)\n",
 		__func__, params->frequency);
 
 	mutex_lock(&priv->lock);
 
-	/* Fix me: it could be air. */
-	priv->rf_mode = params->mode;
-	if (params->mode > XC_RF_MODE_CABLE)
-		priv->rf_mode = XC_RF_MODE_CABLE;
-
 	/* params->frequency is in units of 62.5khz */
 	priv->freq_hz = params->frequency * 62500;
 
-	/* FIX ME: Some video standards may have several possible audio
-		   standards. We simply default to one of them here.
-	 */
+	params->std &= V4L2_STD_ALL;
+	/* if std is not defined, choose one */
+	if (!params->std)
+		params->std = V4L2_STD_PAL_BG;
+
+	if (audio_std & XC4000_AUDIO_STD_MONO)
+		type = MONO;
+
 	if (params->std & V4L2_STD_MN) {
-		/* default to BTSC audio standard */
-		priv->video_standard = XC4000_MN_NTSC_PAL_BTSC;
+		params->std = V4L2_STD_MN;
+		if (audio_std & XC4000_AUDIO_STD_MONO) {
+			priv->video_standard = XC4000_MN_NTSC_PAL_Mono;
+		} else if (audio_std & XC4000_AUDIO_STD_A2) {
+			params->std |= V4L2_STD_A2;
+			priv->video_standard = XC4000_MN_NTSC_PAL_A2;
+		} else {
+			params->std |= V4L2_STD_BTSC;
+			priv->video_standard = XC4000_MN_NTSC_PAL_BTSC;
+		}
 		goto tune_channel;
 	}
 
 	if (params->std & V4L2_STD_PAL_BG) {
-		/* default to NICAM audio standard */
-		priv->video_standard = XC4000_BG_PAL_NICAM;
+		params->std = V4L2_STD_PAL_BG;
+		if (audio_std & XC4000_AUDIO_STD_MONO) {
+			priv->video_standard = XC4000_BG_PAL_MONO;
+		} else if (!(audio_std & XC4000_AUDIO_STD_A2)) {
+			if (!(audio_std & XC4000_AUDIO_STD_B)) {
+				params->std |= V4L2_STD_NICAM_A;
+				priv->video_standard = XC4000_BG_PAL_NICAM;
+			} else {
+				params->std |= V4L2_STD_NICAM_B;
+				priv->video_standard = XC4000_BG_PAL_NICAM;
+			}
+		} else {
+			if (!(audio_std & XC4000_AUDIO_STD_B)) {
+				params->std |= V4L2_STD_A2_A;
+				priv->video_standard = XC4000_BG_PAL_A2;
+			} else {
+				params->std |= V4L2_STD_A2_B;
+				priv->video_standard = XC4000_BG_PAL_A2;
+			}
+		}
 		goto tune_channel;
 	}
 
 	if (params->std & V4L2_STD_PAL_I) {
 		/* default to NICAM audio standard */
-		priv->video_standard = XC4000_I_PAL_NICAM;
+		params->std = V4L2_STD_PAL_I | V4L2_STD_NICAM;
+		if (audio_std & XC4000_AUDIO_STD_MONO) {
+			priv->video_standard = XC4000_I_PAL_NICAM_MONO;
+		} else {
+			priv->video_standard = XC4000_I_PAL_NICAM;
+		}
 		goto tune_channel;
 	}
 
 	if (params->std & V4L2_STD_PAL_DK) {
-		/* default to NICAM audio standard */
-		priv->video_standard = XC4000_DK_PAL_NICAM;
+		params->std = V4L2_STD_PAL_DK;
+		if (audio_std & XC4000_AUDIO_STD_MONO) {
+			priv->video_standard = XC4000_DK_PAL_MONO;
+		} else if (audio_std & XC4000_AUDIO_STD_A2) {
+			params->std |= V4L2_STD_A2;
+			priv->video_standard = XC4000_DK_PAL_A2;
+		} else {
+			params->std |= V4L2_STD_NICAM;
+			priv->video_standard = XC4000_DK_PAL_NICAM;
+		}
 		goto tune_channel;
 	}
 
 	if (params->std & V4L2_STD_SECAM_DK) {
-		/* default to A2 DK1 audio standard */
-		priv->video_standard = XC4000_DK_SECAM_A2DK1;
+		/* default to A2 audio standard */
+		params->std = V4L2_STD_SECAM_DK | V4L2_STD_A2;
+		if (audio_std & XC4000_AUDIO_STD_L) {
+			type = 0;
+			priv->video_standard = XC4000_DK_SECAM_NICAM;
+		} else if (audio_std & XC4000_AUDIO_STD_MONO) {
+			priv->video_standard = XC4000_DK_SECAM_A2MONO;
+		} else if (audio_std & XC4000_AUDIO_STD_K3) {
+			params->std |= V4L2_STD_SECAM_K3;
+			priv->video_standard = XC4000_DK_SECAM_A2LDK3;
+		} else {
+			priv->video_standard = XC4000_DK_SECAM_A2DK1;
+		}
 		goto tune_channel;
 	}
 
 	if (params->std & V4L2_STD_SECAM_L) {
+		/* default to NICAM audio standard */
+		type = 0;
+		params->std = V4L2_STD_SECAM_L | V4L2_STD_NICAM;
 		priv->video_standard = XC4000_L_SECAM_NICAM;
 		goto tune_channel;
 	}
 
 	if (params->std & V4L2_STD_SECAM_LC) {
+		/* default to NICAM audio standard */
+		type = 0;
+		params->std = V4L2_STD_SECAM_LC | V4L2_STD_NICAM;
 		priv->video_standard = XC4000_LC_SECAM_NICAM;
 		goto tune_channel;
 	}
 
 tune_channel:
+	/* Fix me: it could be air. */
+	priv->rf_mode = XC_RF_MODE_CABLE;
 
-	/* FIXME - firmware type not being set properly */
-	if (check_firmware(fe, DTV8, 0, priv->if_khz) != XC_RESULT_SUCCESS)
+	if (check_firmware(fe, type, params->std,
+			   XC4000_Standard[priv->video_standard].int_freq)
+	    != XC_RESULT_SUCCESS) {
 		goto fail;
+	}
 
 	ret = xc_SetSignalSource(priv, priv->rf_mode);
 	if (ret != XC_RESULT_SUCCESS) {
#37 lore raw

XC4000: xc_tune_channel() cleanup

In reply to Devin Heitmueller

Minor coding changes related to the xc_tune_channel() function.

drivers/media/common/tuners/xc4000.c +9 -10
diff -uNr xc4000_orig/drivers/media/common/tuners/xc4000.c xc4000/drivers/media/common/tuners/xc4000.c
@@ -516,12 +516,10 @@
 	return lockState;
 }
 
-#define XC_TUNE_ANALOG  0
-#define XC_TUNE_DIGITAL 1
-static int xc_tune_channel(struct xc4000_priv *priv, u32 freq_hz, int mode)
+static int xc_tune_channel(struct xc4000_priv *priv, u32 freq_hz)
 {
-	int	found = 0;
-	int	result = 0;
+	int	found = 1;
+	int	result;
 
 	dprintk(1, "%s(%u)\n", __func__, freq_hz);
 
@@ -533,9 +531,10 @@
 	if (result != XC_RESULT_SUCCESS)
 		return 0;
 
-	if (mode == XC_TUNE_ANALOG) {
-		if (WaitForLock(priv) == 1)
-			found = 1;
+	/* wait for lock only in analog TV mode */
+	if ((priv->cur_fw.type & (FM | DTV6 | DTV7 | DTV78 | DTV8)) == 0) {
+		if (WaitForLock(priv) != 1)
+			found = 0;
 	}
 
 	/* Wait for stats to stabilize.
@@ -1269,7 +1268,7 @@
 		}
 	}
 
-	xc_tune_channel(priv, priv->freq_hz, XC_TUNE_DIGITAL);
+	xc_tune_channel(priv, priv->freq_hz);
 
 	ret = 0;
 
@@ -1468,7 +1467,7 @@
 		}
 	}
 
-	xc_tune_channel(priv, priv->freq_hz, XC_TUNE_ANALOG);
+	xc_tune_channel(priv, priv->freq_hz);
 
 	ret = 0;
 
#38 lore raw

XC4000: removed redundant tuner reset

In reply to Devin Heitmueller

This patch causes the tuner reset command to be ignored in the firmware code, since this only happens when the BASE/INIT1 firmware is loaded by check_firmware(), and in that case check_firmware() already calls the reset callback before starting to load the firmware.

drivers/media/common/tuners/xc4000.c +3 -1
diff -uNr xc4000_orig/drivers/media/common/tuners/xc4000.c xc4000/drivers/media/common/tuners/xc4000.c
@@ -338,10 +338,12 @@
 		len = i2c_sequence[index] * 256 + i2c_sequence[index+1];
 		if (len == 0x0000) {
 			/* RESET command */
-			result = xc4000_TunerReset(fe);
 			index += 2;
+#if 0			/* not needed, as already called by check_firmware() */
+			result = xc4000_TunerReset(fe);
 			if (result != XC_RESULT_SUCCESS)
 				return result;
+#endif
 		} else if (len & 0x8000) {
 			/* WAIT command */
 			xc_wait(len & 0x7FFF);
#39 lore raw

XC4000: detect XC4100

In reply to Devin Heitmueller

Added code to detect the XC4100 chip, which is presumably an analog-only "value" version of the XC4000. It is not sure, however, if any devices using this have actually been produced and sold, so the patch may be unneeded.

drivers/media/common/tuners/xc4000.c +7 -3
diff -uNr xc4000_orig/drivers/media/common/tuners/xc4000.c xc4000/drivers/media/common/tuners/xc4000.c
@@ -140,7 +140,8 @@
 
 /* Product id */
 #define XC_PRODUCT_ID_FW_NOT_LOADED	0x2000
-#define XC_PRODUCT_ID_FW_LOADED	0x0FA0
+#define XC_PRODUCT_ID_XC4000		0x0FA0
+#define XC_PRODUCT_ID_XC4100		0x1004
 
 /* Registers (Write-only) */
 #define XREG_INIT         0x00
@@ -1071,7 +1072,9 @@
 #endif
 
 	/* Check that the tuner hardware model remains consistent over time. */
-	if (priv->hwmodel == 0 && hwmodel == 4000) {
+	if (priv->hwmodel == 0 &&
+	    (hwmodel == XC_PRODUCT_ID_XC4000 ||
+	     hwmodel == XC_PRODUCT_ID_XC4100)) {
 		priv->hwmodel = hwmodel;
 		priv->hwvers  = version & 0xff00;
 	} else if (priv->hwmodel == 0 || priv->hwmodel != hwmodel ||
@@ -1678,7 +1681,8 @@
 	}
 
 	switch (id) {
-	case XC_PRODUCT_ID_FW_LOADED:
+	case XC_PRODUCT_ID_XC4000:
+	case XC_PRODUCT_ID_XC4100:
 		printk(KERN_INFO
 			"xc4000: Successfully identified at address 0x%02x\n",
 			cfg->i2c_address);
#40 lore raw
In reply to Devin Heitmueller

I am a Pinnacle PCTV 340e user for 2 years. Since the release of "Christmast Gift" in kernellabs.org, I privately made patches to ports the driver until the latest vanilla 2.6.39. I have no problem using the driver for my daily DVB-T viewing usage.

Since it is open sourced, I also want to publish my patches here too. Please consider to incluge it in main-line V4L2. It is up to users or maintainers to acceept it or not.

Anyway, thank you Devin for your initial driver.

TQ

###
### thi patch is NOT includes the xv4000.[ch].

drivers/media/common/tuners/Kconfig +10 -0
diff -urw a/drivers/media/common/tuners/Kconfig b/drivers/media/common/tuners/Kconfig
@@ -23,6 +23,7 @@
 	depends on VIDEO_MEDIA && I2C
 	select MEDIA_TUNER_XC2028 if !MEDIA_TUNER_CUSTOMISE
 	select MEDIA_TUNER_XC5000 if !MEDIA_TUNER_CUSTOMISE
+	select MEDIA_TUNER_XC4000 if !MEDIA_TUNER_CUSTOMISE
 	select MEDIA_TUNER_MT20XX if !MEDIA_TUNER_CUSTOMISE
 	select MEDIA_TUNER_TDA8290 if !MEDIA_TUNER_CUSTOMISE
 	select MEDIA_TUNER_TEA5761 if !MEDIA_TUNER_CUSTOMISE
@@ -152,6 +153,15 @@
 	  This device is only used inside a SiP called together with a
 	  demodulator for now.
 
+config MEDIA_TUNER_XC4000
+	tristate "Xceive XC4000 silicon tuner"
+	depends on VIDEO_MEDIA && I2C
+	default m if MEDIA_TUNER_CUSTOMISE
+	help
+	  A driver for the silicon tuner XC4000 from Xceive.
+	  This device is only used inside a SiP called together with a
+	  demodulator for now.
+
 config MEDIA_TUNER_MXL5005S
 	tristate "MaxLinear MSL5005S silicon tuner"
 	depends on VIDEO_MEDIA && I2C
drivers/media/common/tuners/Makefile +1 -0
diff -urw a/drivers/media/common/tuners/Makefile b/drivers/media/common/tuners/Makefile
@@ -16,6 +16,7 @@
 obj-$(CONFIG_MEDIA_TUNER_TDA827X) += tda827x.o
 obj-$(CONFIG_MEDIA_TUNER_TDA18271) += tda18271.o
 obj-$(CONFIG_MEDIA_TUNER_XC5000) += xc5000.o
+obj-$(CONFIG_MEDIA_TUNER_XC4000) += xc4000.o
 obj-$(CONFIG_MEDIA_TUNER_MT2060) += mt2060.o
 obj-$(CONFIG_MEDIA_TUNER_MT2266) += mt2266.o
 obj-$(CONFIG_MEDIA_TUNER_QT1010) += qt1010.o
drivers/media/common/tuners/tuner-types.c +4 -0
diff -urw a/drivers/media/common/tuners/tuner-types.c b/drivers/media/common/tuners/tuner-types.c
@@ -1805,6 +1805,10 @@
 		.name   = "Xceive 5000 tuner",
 		/* see xc5000.c for details */
 	},
+	[TUNER_XC4000] = { /* Xceive 4000 */
+		.name   = "Xceive 4000 tuner",
+		/* see xc4000.c for details */
+	},
 	[TUNER_TCL_MF02GIP_5N] = { /* TCL tuner MF02GIP-5N-E */
 		.name   = "TCL tuner MF02GIP-5N-E",
 		.params = tuner_tcl_mf02gip_5n_params,
drivers/media/dvb/dvb-usb/Kconfig +1 -0
diff -urw a/drivers/media/dvb/dvb-usb/Kconfig b/drivers/media/dvb/dvb-usb/Kconfig
@@ -81,6 +81,7 @@
 	select MEDIA_TUNER_MT2266 if !MEDIA_TUNER_CUSTOMISE
 	select MEDIA_TUNER_XC2028 if !MEDIA_TUNER_CUSTOMISE
 	select MEDIA_TUNER_XC5000 if !MEDIA_TUNER_CUSTOMISE
+	select MEDIA_TUNER_XC4000 if !MEDIA_TUNER_CUSTOMISE
 	select MEDIA_TUNER_MXL5007T if !MEDIA_TUNER_CUSTOMISE
 	help
 	  Support for USB2.0/1.1 DVB receivers based on the DiB0700 USB bridge. The
drivers/media/dvb/dvb-usb/dib0700_devices.c +179 -0

203 lines not on this page · raw message

drivers/media/dvb/dvb-usb/dvb-usb-ids.h +2 -0
diff -urw a/drivers/media/dvb/dvb-usb/dvb-usb-ids.h b/drivers/media/dvb/dvb-usb/dvb-usb-ids.h
@@ -233,6 +233,8 @@
 #define USB_PID_PINNACLE_PCTV73ESE			0x0245
 #define USB_PID_PINNACLE_PCTV74E			0x0246
 #define USB_PID_PINNACLE_PCTV282E			0x0248
+#define USB_PID_PINNACLE_PCTV340E			0x023d
+#define USB_PID_PINNACLE_PCTV340E_SE			0x023e
 #define USB_PID_PIXELVIEW_SBTVD				0x5010
 #define USB_PID_PCTV_200E				0x020e
 #define USB_PID_PCTV_400E				0x020f
drivers/media/video/tuner-core.c +14 -0
diff -urw a/drivers/media/video/tuner-core.c b/drivers/media/video/tuner-core.c
@@ -38,6 +38,7 @@
 #include "tuner-simple.h"
 #include "tda9887.h"
 #include "xc5000.h"
+#include "xc4000.h"
 #include "tda18271.h"
 
 #define UNSET (-1U)
@@ -377,6 +378,19 @@
 			goto attach_failed;
 		tune_now = 0;
 		break;
+	}
+	case TUNER_XC4000:
+	{
+		struct xc4000_config xc4000_cfg = {
+			.i2c_address = t->i2c->addr,
+		/* if_khz will be set when the digital dvb_attach() occurs */
+			.if_khz	  = 0,
+	};
+		if (!dvb_attach(xc4000_attach,
+				&t->fe, t->i2c->adapter, &xc4000_cfg))
+			goto attach_failed;
+		tune_now = 0;
+		break;
 	}
 	case TUNER_NXP_TDA18271:
 	{
drivers/media/video/tveeprom.c +1 -1
diff -urw a/drivers/media/video/tveeprom.c b/drivers/media/video/tveeprom.c
@@ -264,7 +264,7 @@
 	{ TUNER_XC5000,                 "Xceive XC5000"},
 	{ TUNER_ABSENT,                 "Xceive XC3028L"},
 	{ TUNER_ABSENT,                 "NXP 18271C2_716x"},
-	{ TUNER_ABSENT,                 "Xceive XC4000"},
+	{ TUNER_XC4000,                 "Xceive XC4000"},
 	{ TUNER_ABSENT,                 "Dibcom 7070"},
 	{ TUNER_PHILIPS_TDA8290,        "NXP 18271C2"},
 	{ TUNER_ABSENT,			"unknown"},

####

Quoted 27 lines · Devin Heitmueller
Quoted 7 lines · Dmitri Belimov

Hi

Quoted 5 lines

Hi Istvan

      I am sending you modified patches for kernel 2.6.37.2, they works as expected.

Quoted 6 lines
Quoted 2 lines

First apply kernel_xc4000.diff (your patch) then kernel_dtv3200h.diff for Leadtek DTV3200 XC4000 support.

Can you resend your patches with right Signed-Off string for commit into kernel?

With my best regards, Dmitry.

He cannot offer a Signed-off-by for the entire patch - it's not his code. The patches are based on the work that Davide Ferri and I did about 17 months ago:

http://kernellabs.com/hg/~dheitmueller/pctv-340e-2/shortlog

I'm not against seeing the xc4000 support going in, but the history needs to be preserved, which means it needs to be broken in to a patch series that properly credits my and Davide's work.

Devin