From: Gerd Knorr <kraxel@bytesex.org>
To: Andrew Morton <akpm@osdl.org>,
Kernel List <linux-kernel@vger.kernel.org>
Subject: [patch] v4l: cx88 driver update
Date: Fri, 18 Jun 2004 12:02:29 +0200 [thread overview]
Message-ID: <20040618100229.GA24865@bytesex.org> (raw)
Hi,
This is a update for the cx88 tv card driver. Changes:
* finally make it build with gcc 2.95 ;)
* add new tv cards.
* plenty of fixes for the TV sound code.
* use v4l2 API for communication with tuner + tda9887
* misc other minor stuff.
please apply,
Gerd
diff -up linux-2.6.7/drivers/media/video/cx88/cx88-cards.c linux/drivers/media/video/cx88/cx88-cards.c
--- linux-2.6.7/drivers/media/video/cx88/cx88-cards.c 2004-06-17 10:30:25.000000000 +0200
+++ linux/drivers/media/video/cx88/cx88-cards.c 2004-06-17 13:47:59.785272417 +0200
@@ -99,6 +99,10 @@ struct cx88_board cx88_boards[] = {
.input = {{
.type = CX88_VMUX_TELEVISION,
.vmux = 0,
+ .gpio0 = 0x000003ff,
+ .gpio1 = 0x000000ff,
+ .gpio2 = 0x000000ff,
+ .gpio3 = 0x00000000,
},{
.type = CX88_VMUX_COMPOSITE1,
.vmux = 1,
@@ -111,6 +115,7 @@ struct cx88_board cx88_boards[] = {
[CX88_BOARD_WINFAST2000XP] = {
.name = "Leadtek Winfast 2000XP Expert",
.tuner_type = 44,
+ .needs_tda9887 = 1,
.input = {{
.type = CX88_VMUX_TELEVISION,
.vmux = 0,
@@ -149,22 +154,33 @@ struct cx88_board cx88_boards[] = {
.vmux = 0,
}},
},
- [CX88_BOARD_MSI_TVANYWHERE] = {
+ [CX88_BOARD_MSI_TVANYWHERE_MASTER] = {
+ //added gpio values thanks to Torsten Seeboth
+ //values for PAL from DScaler
.name = "MSI TV-@nywhere Master",
.tuner_type = 33,
+ .needs_tda9887 = 1,
.input = {{
.type = CX88_VMUX_TELEVISION,
.vmux = 0,
+ .gpio0 = 0x000040bf,
+ .gpio1 = 0x000080c0,
+ .gpio2 = 0x0000ff40,
+ .gpio3 = 0x00000000,
},{
.type = CX88_VMUX_COMPOSITE1,
.vmux = 1,
- },{
- // temporarly for testing ...
- .type = CX88_VMUX_COMPOSITE2,
- .vmux = 2,
+ .gpio0 = 0x000040bf,
+ .gpio1 = 0x000080c0,
+ .gpio2 = 0x0000ff40,
+ .gpio3 = 0x00000000,
},{
.type = CX88_VMUX_SVIDEO,
.vmux = 2,
+ .gpio0 = 0x000040bf,
+ .gpio1 = 0x000080c0,
+ .gpio2 = 0x0000ff40,
+ .gpio3 = 0x00000000,
}},
.radio = {
.type = CX88_RADIO,
@@ -199,8 +215,97 @@ struct cx88_board cx88_boards[] = {
.type = CX88_RADIO,
},
},
-
-
+ [CX88_BOARD_IODATA_GVVCP3PCI] = {
+ .name = "IODATA GV-VCP3/PCI",
+ .tuner_type = TUNER_ABSENT,
+ .needs_tda9887 = 0,
+ .input = {{
+ .type = CX88_VMUX_COMPOSITE1,
+ .vmux = 0,
+ },{
+ .type = CX88_VMUX_COMPOSITE2,
+ .vmux = 1,
+ },{
+ .type = CX88_VMUX_SVIDEO,
+ .vmux = 2,
+ }},
+ },
+ [CX88_BOARD_PROLINK_PLAYTVPVR] = {
+ .name = "Prolink PlayTV PVR",
+ .tuner_type = 43,
+ .needs_tda9887 = 1,
+ .input = {{
+ .type = CX88_VMUX_TELEVISION,
+ .vmux = 0,
+ .gpio0 = 0xff00,
+ },{
+ .type = CX88_VMUX_COMPOSITE1,
+ .vmux = 1,
+ .gpio0 = 0xff03,
+ },{
+ .type = CX88_VMUX_SVIDEO,
+ .vmux = 2,
+ .gpio0 = 0xff03,
+ }},
+ .radio = {
+ .type = CX88_RADIO,
+ .gpio0 = 0xff00,
+ },
+ },
+ [CX88_BOARD_ASUS_PVR_416] = {
+ .name = "ASUS PVR-416",
+ .tuner_type = 43,
+ .needs_tda9887 = 1,
+ .input = {{
+ .type = CX88_VMUX_TELEVISION,
+ .vmux = 0,
+ .gpio0 = 0x0000fde6,
+ .gpio1 = 0x00000000, // possibly for mpeg data
+ .gpio2 = 0x000000e9,
+ .gpio3 = 0x00000000,
+ },{
+ .type = CX88_VMUX_SVIDEO,
+ .vmux = 2,
+ .gpio0 = 0x0000fde6, // 0x0000fda6 L,R RCA audio in?
+ .gpio1 = 0x00000000, // possibly for mpeg data
+ .gpio2 = 0x000000e9,
+ .gpio3 = 0x00000000,
+ }},
+ .radio = {
+ .type = CX88_RADIO,
+ .gpio0 = 0x0000fde2,
+ .gpio1 = 0x00000000,
+ .gpio2 = 0x000000e9,
+ .gpio3 = 0x00000000,
+ },
+ },
+ [CX88_BOARD_MSI_TVANYWHERE] = {
+ .name = "MSI TV-@nywhere",
+ .tuner_type = 33,
+ .needs_tda9887 = 1,
+ .input = {{
+ .type = CX88_VMUX_TELEVISION,
+ .vmux = 0,
+ .gpio0 = 0x00000fbf,
+ .gpio1 = 0x000000c0,
+ .gpio2 = 0x0000fc08,
+ .gpio3 = 0x00000000,
+ },{
+ .type = CX88_VMUX_COMPOSITE1,
+ .vmux = 1,
+ .gpio0 = 0x00000fbf,
+ .gpio1 = 0x000000c0,
+ .gpio2 = 0x0000fc68,
+ .gpio3 = 0x00000000,
+ },{
+ .type = CX88_VMUX_SVIDEO,
+ .vmux = 2,
+ .gpio0 = 0x00000fbf,
+ .gpio1 = 0x000000c0,
+ .gpio2 = 0x0000fc68,
+ .gpio3 = 0x00000000,
+ }},
+ },
};
const unsigned int cx88_bcount = ARRAY_SIZE(cx88_boards);
@@ -242,6 +347,10 @@ struct cx88_subid cx88_subids[] = {
.card = CX88_BOARD_WINFAST_DV2000,
},{
.subvendor = 0x107d,
+ .subdevice = 0x663b,
+ .card = CX88_BOARD_LEADTEK_PVR2000,
+ },{
+ .subvendor = 0x107d,
.subdevice = 0x663C,
.card = CX88_BOARD_LEADTEK_PVR2000,
},{
@@ -251,12 +360,19 @@ struct cx88_subid cx88_subids[] = {
},{
.subvendor = 0x1462,
.subdevice = 0x8606,
- .card = CX88_BOARD_MSI_TVANYWHERE,
- }
+ .card = CX88_BOARD_MSI_TVANYWHERE_MASTER,
+ },{
+ .subvendor = 0x10fc,
+ .subdevice = 0xd003,
+ .card = CX88_BOARD_IODATA_GVVCP3PCI,
+ },{
+ .subvendor = 0x1043,
+ .subdevice = 0x4823, /* with mpeg encoder */
+ .card = CX88_BOARD_ASUS_PVR_416,
+ }
};
const unsigned int cx88_idcount = ARRAY_SIZE(cx88_subids);
-
/* ----------------------------------------------------------------------- */
/* some leadtek specific stuff */
@@ -269,7 +385,7 @@ static void __devinit leadtek_eeprom(str
*/
if (eeprom_data[4] != 0x7d ||
- eeprom_data[5] != 0x10 ||
+ eeprom_data[5] != 0x10 ||
eeprom_data[7] != 0x66) {
printk(KERN_WARNING "%s Leadtek eeprom invalid.\n", dev->name);
return;
@@ -277,7 +393,7 @@ static void __devinit leadtek_eeprom(str
dev->has_radio = 1;
dev->tuner_type = (eeprom_data[6] == 0x13) ? 43 : 38;
-
+
printk(KERN_INFO "%s: Leadtek Winfast 2000 XP config: "
"tuner=%d, eeprom[0]=0x%02x\n",
dev->name, dev->tuner_type, eeprom_data[0]);
@@ -386,20 +502,22 @@ static struct {
[ 0x02 ] = { .id = TUNER_ABSENT,
.name = "PAL_B" },
[ 0x03 ] = { .id = TUNER_ABSENT,
- .name = "BAL_I" },
+ .name = "PAL_I" },
[ 0x04 ] = { .id = TUNER_ABSENT,
.name = "PAL_D" },
[ 0x05 ] = { .id = TUNER_ABSENT,
.name = "SECAM" },
- [ 0x10 ] = { .id = TUNER_ABSENT, .fm = 1,
+ [ 0x10 ] = { .id = TUNER_ABSENT,
+ .fm = 1,
.name = "TEMIC_4049" },
[ 0x11 ] = { .id = TUNER_TEMIC_4136FY5,
.name = "TEMIC_4136" },
[ 0x12 ] = { .id = TUNER_ABSENT,
.name = "TEMIC_4146" },
- [ 0x20 ] = { .id = TUNER_PHILIPS_FQ1216ME, .fm = 1,
+ [ 0x20 ] = { .id = TUNER_PHILIPS_FQ1216ME,
+ .fm = 1,
.name = "PHILIPS_FQ1216_MK3" },
[ 0x21 ] = { .id = TUNER_ABSENT, .fm = 1,
.name = "PHILIPS_FQ1236_MK3" },
@@ -454,7 +572,33 @@ i2c_eeprom(struct i2c_client *c, unsigne
return 0;
}
-void __devinit cx88_card_setup(struct cx8800_dev *dev)
+void cx88_card_list(struct cx8800_dev *dev)
+{
+ int i;
+
+ if (0 == dev->pci->subsystem_vendor &&
+ 0 == dev->pci->subsystem_device) {
+ printk("%s: Your board has no valid PCI Subsystem ID and thus can't\n"
+ "%s: be autodetected. Please pass card=<n> insmod option to\n"
+ "%s: workaround that. Redirect complaints to the vendor of\n"
+ "%s: the TV card. Best regards,\n"
+ "%s: -- tux\n",
+ dev->name,dev->name,dev->name,dev->name,dev->name);
+ } else {
+ printk("%s: Your board isn't known (yet) to the driver. You can\n"
+ "%s: try to pick one of the existing card configs via\n"
+ "%s: card=<n> insmod option. Updating to the latest\n"
+ "%s: version might help as well.\n",
+ dev->name,dev->name,dev->name,dev->name);
+ }
+ printk("%s: Here is a list of valid choices for the card=<n> insmod option:\n",
+ dev->name);
+ for (i = 0; i < cx88_bcount; i++)
+ printk("%s: card=%d -> %s\n",
+ dev->name, i, cx88_boards[i].name);
+}
+
+void cx88_card_setup(struct cx8800_dev *dev)
{
static u8 eeprom[128];
@@ -474,6 +618,9 @@ void __devinit cx88_card_setup(struct cx
i2c_eeprom(&dev->i2c_client,eeprom,sizeof(eeprom));
leadtek_eeprom(dev,eeprom);
break;
+ case CX88_BOARD_ASUS_PVR_416:
+ dev->has_radio = 1;
+ break;
}
}
@@ -483,6 +630,7 @@ EXPORT_SYMBOL(cx88_boards);
EXPORT_SYMBOL(cx88_bcount);
EXPORT_SYMBOL(cx88_subids);
EXPORT_SYMBOL(cx88_idcount);
+EXPORT_SYMBOL(cx88_card_list);
EXPORT_SYMBOL(cx88_card_setup);
/*
diff -up linux-2.6.7/drivers/media/video/cx88/cx88-i2c.c linux/drivers/media/video/cx88/cx88-i2c.c
--- linux-2.6.7/drivers/media/video/cx88/cx88-i2c.c 2004-06-17 10:28:38.000000000 +0200
+++ linux/drivers/media/video/cx88/cx88-i2c.c 2004-06-17 13:47:59.787272041 +0200
@@ -22,8 +22,6 @@
*/
-#define __NO_VERSION__ 1
-
#include <linux/module.h>
#include <linux/init.h>
diff -up linux-2.6.7/drivers/media/video/cx88/cx88-reg.h linux/drivers/media/video/cx88/cx88-reg.h
--- linux-2.6.7/drivers/media/video/cx88/cx88-reg.h 2004-06-17 10:28:53.000000000 +0200
+++ linux/drivers/media/video/cx88/cx88-reg.h 2004-06-17 13:47:59.790271476 +0200
@@ -599,10 +599,20 @@
#define EN_I2SIN_STR2DAC 0x00004000
#define EN_I2SIN_ENABLE 0x00008000
+#if 0
+/* old */
#define EN_DMTRX_SUMDIFF 0x00000800
#define EN_DMTRX_SUMR 0x00000880
#define EN_DMTRX_LR 0x00000900
#define EN_DMTRX_MONO 0x00000980
+#else
+/* dscaler cvs */
+#define EN_DMTRX_SUMDIFF (0 << 7)
+#define EN_DMTRX_SUMR (1 << 7)
+#define EN_DMTRX_LR (2 << 7)
+#define EN_DMTRX_MONO (3 << 7)
+#define EN_DMTRX_BYPASS (1 << 11)
+#endif
// Video
#define VID_CAPTURE_CONTROL 0x310180
diff -up linux-2.6.7/drivers/media/video/cx88/cx88-tvaudio.c linux/drivers/media/video/cx88/cx88-tvaudio.c
--- linux-2.6.7/drivers/media/video/cx88/cx88-tvaudio.c 2004-06-17 10:28:49.000000000 +0200
+++ linux/drivers/media/video/cx88/cx88-tvaudio.c 2004-06-17 13:47:59.794270724 +0200
@@ -48,6 +48,7 @@
#include <linux/interrupt.h>
#include <linux/vmalloc.h>
#include <linux/init.h>
+#include <linux/smp_lock.h>
#include "cx88.h"
@@ -60,6 +61,33 @@ MODULE_PARM_DESC(audio_debug,"enable deb
/* ----------------------------------------------------------- */
+static char *aud_ctl_names[64] =
+{
+ [ EN_BTSC_FORCE_MONO ] = "BTSC_FORCE_MONO",
+ [ EN_BTSC_FORCE_STEREO ] = "BTSC_FORCE_STEREO",
+ [ EN_BTSC_FORCE_SAP ] = "BTSC_FORCE_SAP",
+ [ EN_BTSC_AUTO_STEREO ] = "BTSC_AUTO_STEREO",
+ [ EN_BTSC_AUTO_SAP ] = "BTSC_AUTO_SAP",
+ [ EN_A2_FORCE_MONO1 ] = "A2_FORCE_MONO1",
+ [ EN_A2_FORCE_MONO2 ] = "A2_FORCE_MONO2",
+ [ EN_A2_FORCE_STEREO ] = "A2_FORCE_STEREO",
+ [ EN_A2_AUTO_MONO2 ] = "A2_AUTO_MONO2",
+ [ EN_A2_AUTO_STEREO ] = "A2_AUTO_STEREO",
+ [ EN_EIAJ_FORCE_MONO1 ] = "EIAJ_FORCE_MONO1",
+ [ EN_EIAJ_FORCE_MONO2 ] = "EIAJ_FORCE_MONO2",
+ [ EN_EIAJ_FORCE_STEREO ] = "EIAJ_FORCE_STEREO",
+ [ EN_EIAJ_AUTO_MONO2 ] = "EIAJ_AUTO_MONO2",
+ [ EN_EIAJ_AUTO_STEREO ] = "EIAJ_AUTO_STEREO",
+ [ EN_NICAM_FORCE_MONO1 ] = "NICAM_FORCE_MONO1",
+ [ EN_NICAM_FORCE_MONO2 ] = "NICAM_FORCE_MONO2",
+ [ EN_NICAM_FORCE_STEREO ] = "NICAM_FORCE_STEREO",
+ [ EN_NICAM_AUTO_MONO2 ] = "NICAM_AUTO_MONO2",
+ [ EN_NICAM_AUTO_STEREO ] = "NICAM_AUTO_STEREO",
+ [ EN_FMRADIO_FORCE_MONO ] = "FMRADIO_FORCE_MONO",
+ [ EN_FMRADIO_FORCE_STEREO ] = "FMRADIO_FORCE_STEREO",
+ [ EN_FMRADIO_AUTO_STEREO ] = "FMRADIO_AUTO_STEREO",
+};
+
struct rlist {
u32 reg;
u32 val;
@@ -125,26 +153,116 @@ static void set_audio_finish(struct cx88
static void set_audio_standard_BTSC(struct cx8800_dev *dev, unsigned int sap)
{
static const struct rlist btsc[] = {
- /* Magic stuff from leadtek driver + datasheet.*/
- { AUD_DBX_IN_GAIN, 0x4734 },
- { AUD_DBX_WBE_GAIN, 0x4640 },
- { AUD_DBX_SE_GAIN, 0x8D31 },
- { AUD_DEEMPH0_G0, 0x1604 },
- { AUD_PHASE_FIX_CTL, 0x0020 },
-
+ /* from dscaler */
+ { AUD_OUT1_SEL, 0x00000013 },
+ { AUD_OUT1_SHIFT, 0x00000000 },
+ { AUD_POLY0_DDS_CONSTANT, 0x0012010c },
+ { AUD_DMD_RA_DDS, 0x00c3e7aa },
+ { AUD_DBX_IN_GAIN, 0x00004734 },
+ { AUD_DBX_WBE_GAIN, 0x00004640 },
+ { AUD_DBX_SE_GAIN, 0x00008d31 },
+ { AUD_DCOC_0_SRC, 0x0000001a },
+ { AUD_IIR1_4_SEL, 0x00000021 },
+ { AUD_DCOC_PASS_IN, 0x00000003 },
+ { AUD_DCOC_0_SHIFT_IN0, 0x0000000a },
+ { AUD_DCOC_0_SHIFT_IN1, 0x00000008 },
+ { AUD_DCOC_1_SHIFT_IN0, 0x0000000a },
+ { AUD_DCOC_1_SHIFT_IN1, 0x00000008 },
+ { AUD_DN0_FREQ, 0x0000283b },
+ { AUD_DN2_SRC_SEL, 0x00000008 },
+ { AUD_DN2_FREQ, 0x00003000 },
+ { AUD_DN2_AFC, 0x00000002 },
+ { AUD_DN2_SHFT, 0x00000000 },
+ { AUD_IIR2_2_SEL, 0x00000020 },
+ { AUD_IIR2_2_SHIFT, 0x00000000 },
+ { AUD_IIR2_3_SEL, 0x0000001f },
+ { AUD_IIR2_3_SHIFT, 0x00000000 },
+ { AUD_CRDC1_SRC_SEL, 0x000003ce },
+ { AUD_CRDC1_SHIFT, 0x00000000 },
+ { AUD_CORDIC_SHIFT_1, 0x00000007 },
+ { AUD_DCOC_1_SRC, 0x0000001b },
+ { AUD_DCOC1_SHIFT, 0x00000000 },
+ { AUD_RDSI_SEL, 0x00000008 },
+ { AUD_RDSQ_SEL, 0x00000008 },
+ { AUD_RDSI_SHIFT, 0x00000000 },
+ { AUD_RDSQ_SHIFT, 0x00000000 },
+ { AUD_POLYPH80SCALEFAC, 0x00000003 },
{ /* end of list */ },
};
-
- dprintk("%s (status: unknown)\n",__FUNCTION__);
- set_audio_start(dev, 0x0001,
- EN_BTSC_AUTO_STEREO);
- set_audio_registers(dev, btsc);
+ static const struct rlist btsc_sap[] = {
+ { AUD_DBX_IN_GAIN, 0x00007200 },
+ { AUD_DBX_WBE_GAIN, 0x00006200 },
+ { AUD_DBX_SE_GAIN, 0x00006200 },
+ { AUD_IIR1_1_SEL, 0x00000000 },
+ { AUD_IIR1_3_SEL, 0x00000001 },
+ { AUD_DN1_SRC_SEL, 0x00000007 },
+ { AUD_IIR1_4_SHIFT, 0x00000006 },
+ { AUD_IIR2_1_SHIFT, 0x00000000 },
+ { AUD_IIR2_2_SHIFT, 0x00000000 },
+ { AUD_IIR3_0_SHIFT, 0x00000000 },
+ { AUD_IIR3_1_SHIFT, 0x00000000 },
+ { AUD_IIR3_0_SEL, 0x0000000d },
+ { AUD_IIR3_1_SEL, 0x0000000e },
+ { AUD_DEEMPH1_SRC_SEL, 0x00000014 },
+ { AUD_DEEMPH1_SHIFT, 0x00000000 },
+ { AUD_DEEMPH1_G0, 0x00004000 },
+ { AUD_DEEMPH1_A0, 0x00000000 },
+ { AUD_DEEMPH1_B0, 0x00000000 },
+ { AUD_DEEMPH1_A1, 0x00000000 },
+ { AUD_DEEMPH1_B1, 0x00000000 },
+ { AUD_OUT0_SEL, 0x0000003f },
+ { AUD_OUT1_SEL, 0x0000003f },
+ { AUD_DN1_AFC, 0x00000002 },
+ { AUD_DCOC_0_SHIFT_IN0, 0x0000000a },
+ { AUD_DCOC_0_SHIFT_IN1, 0x00000008 },
+ { AUD_DCOC_1_SHIFT_IN0, 0x0000000a },
+ { AUD_DCOC_1_SHIFT_IN1, 0x00000008 },
+ { AUD_IIR1_0_SEL, 0x0000001d },
+ { AUD_IIR1_2_SEL, 0x0000001e },
+ { AUD_IIR2_1_SEL, 0x00000002 },
+ { AUD_IIR2_2_SEL, 0x00000004 },
+ { AUD_IIR3_2_SEL, 0x0000000f },
+ { AUD_DCOC2_SHIFT, 0x00000001 },
+ { AUD_IIR3_2_SHIFT, 0x00000001 },
+ { AUD_DEEMPH0_SRC_SEL, 0x00000014 },
+ { AUD_CORDIC_SHIFT_1, 0x00000006 },
+ { AUD_POLY0_DDS_CONSTANT, 0x000e4db2 },
+ { AUD_DMD_RA_DDS, 0x00f696e6 },
+ { AUD_IIR2_3_SEL, 0x00000025 },
+ { AUD_IIR1_4_SEL, 0x00000021 },
+ { AUD_DN1_FREQ, 0x0000c965 },
+ { AUD_DCOC_PASS_IN, 0x00000003 },
+ { AUD_DCOC_0_SRC, 0x0000001a },
+ { AUD_DCOC_1_SRC, 0x0000001b },
+ { AUD_DCOC1_SHIFT, 0x00000000 },
+ { AUD_RDSI_SEL, 0x00000009 },
+ { AUD_RDSQ_SEL, 0x00000009 },
+ { AUD_RDSI_SHIFT, 0x00000000 },
+ { AUD_RDSQ_SHIFT, 0x00000000 },
+ { AUD_POLYPH80SCALEFAC, 0x00000003 },
+ { /* end of list */ },
+ };
+
+ // dscaler: exactly taken from driver,
+ // dscaler: don't know why to set EN_FMRADIO_EN_RDS
+ if (sap) {
+ dprintk("%s SAP (status: unknown)\n",__FUNCTION__);
+ set_audio_start(dev, 0x0001,
+ EN_FMRADIO_EN_RDS | EN_BTSC_FORCE_SAP);
+ set_audio_registers(dev, btsc_sap);
+ } else {
+ dprintk("%s (status: known-good)\n",__FUNCTION__);
+ set_audio_start(dev, 0x0001,
+ EN_FMRADIO_EN_RDS | EN_BTSC_AUTO_STEREO);
+ set_audio_registers(dev, btsc);
+ }
set_audio_finish(dev);
}
static void set_audio_standard_NICAM(struct cx8800_dev *dev)
{
- static const struct rlist nicam[] = {
+ static const struct rlist nicam_common[] = {
+ /* from dscaler */
{ AUD_RATE_ADJ1, 0x00000010 },
{ AUD_RATE_ADJ2, 0x00000040 },
{ AUD_RATE_ADJ3, 0x00000100 },
@@ -152,21 +270,64 @@ static void set_audio_standard_NICAM(str
{ AUD_RATE_ADJ5, 0x00001000 },
// { AUD_DMD_RA_DDS, 0x00c0d5ce },
+ // Deemphasis 1:
+ { AUD_DEEMPHGAIN_R, 0x000023c2 },
+ { AUD_DEEMPHNUMER1_R, 0x0002a7bc },
+ { AUD_DEEMPHNUMER2_R, 0x0003023e },
+ { AUD_DEEMPHDENOM1_R, 0x0000f3d0 },
+ { AUD_DEEMPHDENOM2_R, 0x00000000 },
+
+#if 0
+ // Deemphasis 2: (other tv norm?)
+ { AUD_DEEMPHGAIN_R, 0x0000c600 },
+ { AUD_DEEMPHNUMER1_R, 0x00066738 },
+ { AUD_DEEMPHNUMER2_R, 0x00066739 },
+ { AUD_DEEMPHDENOM1_R, 0x0001e88c },
+ { AUD_DEEMPHDENOM2_R, 0x0001e88c },
+#endif
+
+ { AUD_DEEMPHDENOM2_R, 0x00000000 },
+ { AUD_ERRLOGPERIOD_R, 0x00000fff },
+ { AUD_ERRINTRPTTHSHLD1_R, 0x000003ff },
+ { AUD_ERRINTRPTTHSHLD2_R, 0x000000ff },
+ { AUD_ERRINTRPTTHSHLD3_R, 0x0000003f },
+ { AUD_POLYPH80SCALEFAC, 0x00000003 },
+
// setup QAM registers
{ AUD_PDF_DDS_CNST_BYTE2, 0x06 },
{ AUD_PDF_DDS_CNST_BYTE1, 0x82 },
{ AUD_PDF_DDS_CNST_BYTE0, 0x16 },
{ AUD_QAM_MODE, 0x05 },
+
+ { /* end of list */ },
+ };
+ static const struct rlist nicam_pal_i[] = {
+ { AUD_PDF_DDS_CNST_BYTE0, 0x12 },
+ { AUD_PHACC_FREQ_8MSB, 0x3a },
+ { AUD_PHACC_FREQ_8LSB, 0x93 },
+
+ { /* end of list */ },
+ };
+ static const struct rlist nicam_default[] = {
+ { AUD_PDF_DDS_CNST_BYTE0, 0x16 },
{ AUD_PHACC_FREQ_8MSB, 0x34 },
{ AUD_PHACC_FREQ_8LSB, 0x4c },
{ /* end of list */ },
- };
+ };
- dprintk("%s (status: unknown)\n",__FUNCTION__);
set_audio_start(dev, 0x0010,
- EN_DMTRX_LR | EN_NICAM_FORCE_STEREO);
- set_audio_registers(dev, nicam);
+ EN_DMTRX_LR | EN_DMTRX_BYPASS | EN_NICAM_AUTO_STEREO);
+ set_audio_registers(dev, nicam_common);
+ switch (dev->tvaudio) {
+ case WW_NICAM_I:
+ dprintk("%s PAL-I NICAM (status: unknown)\n",__FUNCTION__);
+ set_audio_registers(dev, nicam_pal_i);
+ case WW_NICAM_BGDKL:
+ dprintk("%s PAL NICAM (status: unknown)\n",__FUNCTION__);
+ set_audio_registers(dev, nicam_default);
+ break;
+ };
set_audio_finish(dev);
}
@@ -185,104 +346,104 @@ static void set_audio_standard_NICAM_L(s
{ AUD_PHACC_FREQ_8LSB, 0x4a },
{ AUD_POLY0_DDS_CONSTANT, 0x000e4db2 },
- { AUD_IIR1_0_SEL, 0x00000000 },
- { AUD_IIR1_1_SEL, 0x00000002 },
- { AUD_IIR1_2_SEL, 0x00000023 },
- { AUD_IIR1_3_SEL, 0x00000004 },
- { AUD_IIR1_4_SEL, 0x00000005 },
- { AUD_IIR1_5_SEL, 0x00000007 },
- { AUD_IIR1_0_SHIFT, 0x00000007 },
- { AUD_IIR1_1_SHIFT, 0x00000000 },
- { AUD_IIR1_2_SHIFT, 0x00000000 },
- { AUD_IIR1_3_SHIFT, 0x00000007 },
- { AUD_IIR1_4_SHIFT, 0x00000007 },
- { AUD_IIR1_5_SHIFT, 0x00000007 },
- { AUD_IIR2_0_SEL, 0x00000002 },
+ { AUD_IIR1_0_SEL, 0x00000000 },
+ { AUD_IIR1_1_SEL, 0x00000002 },
+ { AUD_IIR1_2_SEL, 0x00000023 },
+ { AUD_IIR1_3_SEL, 0x00000004 },
+ { AUD_IIR1_4_SEL, 0x00000005 },
+ { AUD_IIR1_5_SEL, 0x00000007 },
+ { AUD_IIR1_0_SHIFT, 0x00000007 },
+ { AUD_IIR1_1_SHIFT, 0x00000000 },
+ { AUD_IIR1_2_SHIFT, 0x00000000 },
+ { AUD_IIR1_3_SHIFT, 0x00000007 },
+ { AUD_IIR1_4_SHIFT, 0x00000007 },
+ { AUD_IIR1_5_SHIFT, 0x00000007 },
+ { AUD_IIR2_0_SEL, 0x00000002 },
{ AUD_IIR2_1_SEL, 0x00000003 },
{ AUD_IIR2_2_SEL, 0x00000004 },
- { AUD_IIR2_3_SEL, 0x00000005 },
- { AUD_IIR3_0_SEL, 0x00000007 },
- { AUD_IIR3_1_SEL, 0x00000023 },
- { AUD_IIR3_2_SEL, 0x00000016 },
- { AUD_IIR4_0_SHIFT, 0x00000000 },
- { AUD_IIR4_1_SHIFT, 0x00000000 },
- { AUD_IIR3_2_SHIFT, 0x00000002 },
- { AUD_IIR4_0_SEL, 0x0000001d },
- { AUD_IIR4_1_SEL, 0x00000019 },
- { AUD_IIR4_2_SEL, 0x00000008 },
- { AUD_IIR4_0_SHIFT, 0x00000000 },
- { AUD_IIR4_1_SHIFT, 0x00000007 },
- { AUD_IIR4_2_SHIFT, 0x00000007 },
- { AUD_IIR4_0_CA0, 0x0003e57e },
- { AUD_IIR4_0_CA1, 0x00005e11 },
- { AUD_IIR4_0_CA2, 0x0003a7cf },
- { AUD_IIR4_0_CB0, 0x00002368 },
- { AUD_IIR4_0_CB1, 0x0003bf1b },
- { AUD_IIR4_1_CA0, 0x00006349 },
- { AUD_IIR4_1_CA1, 0x00006f27 },
- { AUD_IIR4_1_CA2, 0x0000e7a3 },
+ { AUD_IIR2_3_SEL, 0x00000005 },
+ { AUD_IIR3_0_SEL, 0x00000007 },
+ { AUD_IIR3_1_SEL, 0x00000023 },
+ { AUD_IIR3_2_SEL, 0x00000016 },
+ { AUD_IIR4_0_SHIFT, 0x00000000 },
+ { AUD_IIR4_1_SHIFT, 0x00000000 },
+ { AUD_IIR3_2_SHIFT, 0x00000002 },
+ { AUD_IIR4_0_SEL, 0x0000001d },
+ { AUD_IIR4_1_SEL, 0x00000019 },
+ { AUD_IIR4_2_SEL, 0x00000008 },
+ { AUD_IIR4_0_SHIFT, 0x00000000 },
+ { AUD_IIR4_1_SHIFT, 0x00000007 },
+ { AUD_IIR4_2_SHIFT, 0x00000007 },
+ { AUD_IIR4_0_CA0, 0x0003e57e },
+ { AUD_IIR4_0_CA1, 0x00005e11 },
+ { AUD_IIR4_0_CA2, 0x0003a7cf },
+ { AUD_IIR4_0_CB0, 0x00002368 },
+ { AUD_IIR4_0_CB1, 0x0003bf1b },
+ { AUD_IIR4_1_CA0, 0x00006349 },
+ { AUD_IIR4_1_CA1, 0x00006f27 },
+ { AUD_IIR4_1_CA2, 0x0000e7a3 },
{ AUD_IIR4_1_CB0, 0x00005653 },
- { AUD_IIR4_1_CB1, 0x0000cf97 },
- { AUD_IIR4_2_CA0, 0x00006349 },
- { AUD_IIR4_2_CA1, 0x00006f27 },
- { AUD_IIR4_2_CA2, 0x0000e7a3 },
- { AUD_IIR4_2_CB0, 0x00005653 },
- { AUD_IIR4_2_CB1, 0x0000cf97 },
- { AUD_HP_MD_IIR4_1, 0x00000001 },
- { AUD_HP_PROG_IIR4_1, 0x0000001a },
+ { AUD_IIR4_1_CB1, 0x0000cf97 },
+ { AUD_IIR4_2_CA0, 0x00006349 },
+ { AUD_IIR4_2_CA1, 0x00006f27 },
+ { AUD_IIR4_2_CA2, 0x0000e7a3 },
+ { AUD_IIR4_2_CB0, 0x00005653 },
+ { AUD_IIR4_2_CB1, 0x0000cf97 },
+ { AUD_HP_MD_IIR4_1, 0x00000001 },
+ { AUD_HP_PROG_IIR4_1, 0x0000001a },
{ AUD_DN0_FREQ, 0x00000000 },
- { AUD_DN1_FREQ, 0x00003318 },
- { AUD_DN1_SRC_SEL, 0x00000017 },
- { AUD_DN1_SHFT, 0x00000007 },
- { AUD_DN1_AFC, 0x00000000 },
- { AUD_DN1_FREQ_SHIFT, 0x00000000 },
- { AUD_DN2_FREQ, 0x00003551 },
- { AUD_DN2_SRC_SEL, 0x00000001 },
- { AUD_DN2_SHFT, 0x00000000 },
- { AUD_DN2_AFC, 0x00000002 },
- { AUD_DN2_FREQ_SHIFT, 0x00000000 },
- { AUD_PDET_SRC, 0x00000014 },
- { AUD_PDET_SHIFT, 0x00000000 },
- { AUD_DEEMPH0_SRC_SEL, 0x00000011 },
- { AUD_DEEMPH1_SRC_SEL, 0x00000011 },
- { AUD_DEEMPH0_SHIFT, 0x00000000 },
- { AUD_DEEMPH1_SHIFT, 0x00000000 },
- { AUD_DEEMPH0_G0, 0x00007000 },
- { AUD_DEEMPH0_A0, 0x00000000 },
- { AUD_DEEMPH0_B0, 0x00000000 },
- { AUD_DEEMPH0_A1, 0x00000000 },
- { AUD_DEEMPH0_B1, 0x00000000 },
- { AUD_DEEMPH1_G0, 0x00007000 },
- { AUD_DEEMPH1_A0, 0x00000000 },
- { AUD_DEEMPH1_B0, 0x00000000 },
- { AUD_DEEMPH1_A1, 0x00000000 },
- { AUD_DEEMPH1_B1, 0x00000000 },
- { AUD_DMD_RA_DDS, 0x00f5c285 },
- { AUD_RATE_ADJ1, 0x00000100 },
- { AUD_RATE_ADJ2, 0x00000200 },
- { AUD_RATE_ADJ3, 0x00000300 },
- { AUD_RATE_ADJ4, 0x00000400 },
- { AUD_RATE_ADJ5, 0x00000500 },
- { AUD_C2_UP_THR, 0x00005400 },
- { AUD_C2_LO_THR, 0x00003000 },
- { AUD_C1_UP_THR, 0x00007000 },
- { AUD_C2_LO_THR, 0x00005400 },
- { AUD_CTL, 0x0000100c },
- { AUD_DCOC_0_SRC, 0x00000021 },
- { AUD_DCOC_1_SRC, 0x00000003 },
- { AUD_DCOC1_SHIFT, 0x00000000 },
- { AUD_DCOC_1_SHIFT_IN0, 0x0000000a },
- { AUD_DCOC_1_SHIFT_IN1, 0x00000008 },
- { AUD_DCOC_PASS_IN, 0x00000000 },
- { AUD_DCOC_2_SRC, 0x0000001b },
- { AUD_IIR4_0_SEL, 0x0000001d },
- { AUD_POLY0_DDS_CONSTANT, 0x000e4db2 },
- { AUD_PHASE_FIX_CTL, 0x00000000 },
+ { AUD_DN1_FREQ, 0x00003318 },
+ { AUD_DN1_SRC_SEL, 0x00000017 },
+ { AUD_DN1_SHFT, 0x00000007 },
+ { AUD_DN1_AFC, 0x00000000 },
+ { AUD_DN1_FREQ_SHIFT, 0x00000000 },
+ { AUD_DN2_FREQ, 0x00003551 },
+ { AUD_DN2_SRC_SEL, 0x00000001 },
+ { AUD_DN2_SHFT, 0x00000000 },
+ { AUD_DN2_AFC, 0x00000002 },
+ { AUD_DN2_FREQ_SHIFT, 0x00000000 },
+ { AUD_PDET_SRC, 0x00000014 },
+ { AUD_PDET_SHIFT, 0x00000000 },
+ { AUD_DEEMPH0_SRC_SEL, 0x00000011 },
+ { AUD_DEEMPH1_SRC_SEL, 0x00000011 },
+ { AUD_DEEMPH0_SHIFT, 0x00000000 },
+ { AUD_DEEMPH1_SHIFT, 0x00000000 },
+ { AUD_DEEMPH0_G0, 0x00007000 },
+ { AUD_DEEMPH0_A0, 0x00000000 },
+ { AUD_DEEMPH0_B0, 0x00000000 },
+ { AUD_DEEMPH0_A1, 0x00000000 },
+ { AUD_DEEMPH0_B1, 0x00000000 },
+ { AUD_DEEMPH1_G0, 0x00007000 },
+ { AUD_DEEMPH1_A0, 0x00000000 },
+ { AUD_DEEMPH1_B0, 0x00000000 },
+ { AUD_DEEMPH1_A1, 0x00000000 },
+ { AUD_DEEMPH1_B1, 0x00000000 },
+ { AUD_DMD_RA_DDS, 0x00f5c285 },
+ { AUD_RATE_ADJ1, 0x00000100 },
+ { AUD_RATE_ADJ2, 0x00000200 },
+ { AUD_RATE_ADJ3, 0x00000300 },
+ { AUD_RATE_ADJ4, 0x00000400 },
+ { AUD_RATE_ADJ5, 0x00000500 },
+ { AUD_C2_UP_THR, 0x00005400 },
+ { AUD_C2_LO_THR, 0x00003000 },
+ { AUD_C1_UP_THR, 0x00007000 },
+ { AUD_C2_LO_THR, 0x00005400 },
+ { AUD_CTL, 0x0000100c },
+ { AUD_DCOC_0_SRC, 0x00000021 },
+ { AUD_DCOC_1_SRC, 0x00000003 },
+ { AUD_DCOC1_SHIFT, 0x00000000 },
+ { AUD_DCOC_1_SHIFT_IN0, 0x0000000a },
+ { AUD_DCOC_1_SHIFT_IN1, 0x00000008 },
+ { AUD_DCOC_PASS_IN, 0x00000000 },
+ { AUD_DCOC_2_SRC, 0x0000001b },
+ { AUD_IIR4_0_SEL, 0x0000001d },
+ { AUD_POLY0_DDS_CONSTANT, 0x000e4db2 },
+ { AUD_PHASE_FIX_CTL, 0x00000000 },
{ AUD_CORDIC_SHIFT_1, 0x00000007 },
- { AUD_PLL_EN, 0x00000000 },
+ { AUD_PLL_EN, 0x00000000 },
{ AUD_PLL_PRESCALE, 0x00000002 },
- { AUD_PLL_INT, 0x0000001e },
- { AUD_OUT1_SHIFT, 0x00000000 },
+ { AUD_PLL_INT, 0x0000001e },
+ { AUD_OUT1_SHIFT, 0x00000000 },
{ /* end of list */ },
};
@@ -297,14 +458,14 @@ static void set_audio_standard_NICAM_L(s
static void set_audio_standard_A2(struct cx8800_dev *dev)
{
/* from dscaler cvs */
- static const struct rlist a2[] = {
+ static const struct rlist a2_common[] = {
{ AUD_PDF_DDS_CNST_BYTE2, 0x06 },
{ AUD_PDF_DDS_CNST_BYTE1, 0x82 },
{ AUD_PDF_DDS_CNST_BYTE0, 0x12 },
{ AUD_QAM_MODE, 0x05 },
{ AUD_PHACC_FREQ_8MSB, 0x34 },
{ AUD_PHACC_FREQ_8LSB, 0x4c },
-
+
{ AUD_RATE_ADJ1, 0x00001000 },
{ AUD_RATE_ADJ2, 0x00002000 },
{ AUD_RATE_ADJ3, 0x00003000 },
@@ -347,16 +508,20 @@ static void set_audio_standard_A2(struct
{ AUD_RDSQ_SHIFT, 0x00000000 },
{ AUD_POLYPH80SCALEFAC, 0x00000001 },
- // Table 1
+ { /* end of list */ },
+ };
+
+ static const struct rlist a2_table1[] = {
+ // PAL-BG
{ AUD_DMD_RA_DDS, 0x002a73bd },
{ AUD_C1_UP_THR, 0x00007000 },
{ AUD_C1_LO_THR, 0x00005400 },
{ AUD_C2_UP_THR, 0x00005400 },
{ AUD_C2_LO_THR, 0x00003000 },
-
-#if 0
- // found this in WDM-driver for A2, must country spec.
- // Table 2
+ { /* end of list */ },
+ };
+ static const struct rlist a2_table2[] = {
+ // PAL-DK
{ AUD_DMD_RA_DDS, 0x002a73bd },
{ AUD_C1_UP_THR, 0x00007000 },
{ AUD_C1_LO_THR, 0x00005400 },
@@ -364,8 +529,10 @@ static void set_audio_standard_A2(struct
{ AUD_C2_LO_THR, 0x00003000 },
{ AUD_DN0_FREQ, 0x00003a1c },
{ AUD_DN2_FREQ, 0x0000d2e0 },
-
- // Table 3
+ { /* end of list */ },
+ };
+ static const struct rlist a2_table3[] = {
+ // unknown, probably NTSC-M
{ AUD_DMD_RA_DDS, 0x002a2873 },
{ AUD_C1_UP_THR, 0x00003c00 },
{ AUD_C1_LO_THR, 0x00003000 },
@@ -375,140 +542,26 @@ static void set_audio_standard_A2(struct
{ AUD_DN1_FREQ, 0x00003418 },
{ AUD_DN2_FREQ, 0x000029c7 },
{ AUD_POLY0_DDS_CONSTANT, 0x000a7540 },
-#endif
-
{ /* end of list */ },
};
- static const struct rlist a2_old[] = {
- { AUD_DN0_FREQ, 0x0000312b },
- { AUD_POLY0_DDS_CONSTANT, 0x000a62b4 },
- { AUD_IIR1_0_SEL, 0x00000000 },
- { AUD_IIR1_1_SEL, 0x00000001 },
- { AUD_IIR1_2_SEL, 0x0000001f },
- { AUD_IIR1_3_SEL, 0x00000020 },
- { AUD_IIR1_4_SEL, 0x00000023 },
- { AUD_IIR1_5_SEL, 0x00000007 },
- { AUD_IIR1_0_SHIFT, 0x00000000 },
- { AUD_IIR1_1_SHIFT, 0x00000000 },
- { AUD_IIR1_2_SHIFT, 0x00000007 },
- { AUD_IIR1_3_SHIFT, 0x00000007 },
- { AUD_IIR1_4_SHIFT, 0x00000007 },
- { AUD_IIR1_5_SHIFT, 0x00000000 },
- { AUD_IIR2_0_SEL, 0x00000002 },
- { AUD_IIR2_1_SEL, 0x00000003 },
- { AUD_IIR2_2_SEL, 0x00000004 },
- { AUD_IIR2_3_SEL, 0x00000005 },
- { AUD_IIR3_0_SEL, 0x00000021 },
- { AUD_IIR3_1_SEL, 0x00000023 },
- { AUD_IIR3_2_SEL, 0x00000016 },
- { AUD_IIR3_0_SHIFT, 0x00000000 },
- { AUD_IIR3_1_SHIFT, 0x00000000 },
- { AUD_IIR3_2_SHIFT, 0x00000000 },
- { AUD_IIR4_0_SEL, 0x0000001d },
- { AUD_IIR4_1_SEL, 0x00000019 },
- { AUD_IIR4_2_SEL, 0x00000008 },
- { AUD_IIR4_0_SHIFT, 0x00000000 },
- { AUD_IIR4_1_SHIFT, 0x00000000 },
- { AUD_IIR4_2_SHIFT, 0x00000001 },
- { AUD_IIR4_0_CA0, 0x0003e57e },
- { AUD_IIR4_0_CA1, 0x00005e11 },
- { AUD_IIR4_0_CA2, 0x0003a7cf },
- { AUD_IIR4_0_CB0, 0x00002368 },
- { AUD_IIR4_0_CB1, 0x0003bf1b },
- { AUD_IIR4_1_CA0, 0x00006349 },
- { AUD_IIR4_1_CA1, 0x00006f27 },
- { AUD_IIR4_1_CA2, 0x0000e7a3 },
- { AUD_IIR4_1_CB0, 0x00005653 },
- { AUD_IIR4_1_CB1, 0x0000cf97 },
- { AUD_IIR4_2_CA0, 0x00006349 },
- { AUD_IIR4_2_CA1, 0x00006f27 },
- { AUD_IIR4_2_CA2, 0x0000e7a3 },
- { AUD_IIR4_2_CB0, 0x00005653 },
- { AUD_IIR4_2_CB1, 0x0000cf97 },
- { AUD_HP_MD_IIR4_1, 0x00000001 },
- { AUD_HP_PROG_IIR4_1, 0x00000017 },
- { AUD_DN1_FREQ, 0x00003618 },
- { AUD_DN1_SRC_SEL, 0x00000017 },
- { AUD_DN1_SHFT, 0x00000007 },
- { AUD_DN1_AFC, 0x00000000 },
- { AUD_DN1_FREQ_SHIFT, 0x00000000 },
- { AUD_DN2_SRC_SEL, 0x00000040 },
- { AUD_DN2_SHFT, 0x00000000 },
- { AUD_DN2_AFC, 0x00000002 },
- { AUD_DN2_FREQ, 0x0000caaf },
- { AUD_DN2_FREQ_SHIFT, 0x00000000 },
- { AUD_PDET_SRC, 0x00000014 },
- { AUD_PDET_SHIFT, 0x00000000 },
- { AUD_DEEMPH0_SRC_SEL, 0x00000011 },
- { AUD_DEEMPH1_SRC_SEL, 0x00000013 },
- { AUD_DEEMPH0_SHIFT, 0x00000000 },
- { AUD_DEEMPH1_SHIFT, 0x00000000 },
- { AUD_DEEMPH0_G0, 0x000004da },
- { AUD_DEEMPH0_A0, 0x0000777a },
- { AUD_DEEMPH0_B0, 0x00000000 },
- { AUD_DEEMPH0_A1, 0x0003f062 },
- { AUD_DEEMPH0_B1, 0x00000000 },
- { AUD_DEEMPH1_G0, 0x000004da },
- { AUD_DEEMPH1_A0, 0x0000777a },
- { AUD_DEEMPH1_B0, 0x00000000 },
- { AUD_DEEMPH1_A1, 0x0003f062 },
- { AUD_DEEMPH1_B1, 0x00000000 },
- { AUD_PLL_EN, 0x00000000 },
- { AUD_DMD_RA_DDS, 0x002a4efb },
- { AUD_RATE_ADJ1, 0x00001000 },
- { AUD_RATE_ADJ2, 0x00002000 },
- { AUD_RATE_ADJ3, 0x00003000 },
- { AUD_RATE_ADJ4, 0x00004000 },
- { AUD_RATE_ADJ5, 0x00005000 },
- { AUD_C2_UP_THR, 0x0000ffff },
- { AUD_C2_LO_THR, 0x0000e800 },
- { AUD_C1_UP_THR, 0x00008c00 },
- { AUD_C1_LO_THR, 0x00006c00 },
-
- // ; Completely ditch AFC feedback
- { AUD_DCOC_0_SRC, 0x00000021 },
- { AUD_DCOC_1_SRC, 0x0000001a },
- { AUD_DCOC1_SHIFT, 0x00000000 },
- { AUD_DCOC_1_SHIFT_IN0, 0x0000000a },
- { AUD_DCOC_1_SHIFT_IN1, 0x00000008 },
- { AUD_DCOC_PASS_IN, 0x00000000 },
- { AUD_IIR4_0_SEL, 0x00000023 },
-
- // ; Completely ditc FM-2 AFC feedback
- { AUD_DN1_AFC, 0x00000000 },
- { AUD_DCOC_2_SRC, 0x0000001b },
- { AUD_IIR4_1_SEL, 0x00000025 },
-
- // ; WARNING!!! THIS CHANGE WAS NOT EXPECTED!!!
- // ; Swap I & Q inputs into second rotator
- // ; to reverse frequency and therefor invert
- // ; phase from the cordic FM demodulator
- // ; (frequency rotation must also be reversed
- { AUD_DN2_SRC_SEL, 0x00000001 },
- { AUD_DN2_FREQ, 0x00003551 },
-
- // setup Audio PLL
- { AUD_PLL_PRESCALE, 0x00000002 },
- { AUD_PLL_INT, 0x0000001f },
-
- { /* end of list */ },
+ set_audio_start(dev, 0x0004, EN_DMTRX_SUMDIFF | EN_A2_AUTO_STEREO);
+ set_audio_registers(dev, a2_common);
+ switch (dev->tvaudio) {
+ case WW_A2_BG:
+ dprintk("%s PAL-BG A2 (status: known-good)\n",__FUNCTION__);
+ set_audio_registers(dev, a2_table1);
+ break;
+ case WW_A2_DK:
+ dprintk("%s PAL-DK A2 (status: known-good)\n",__FUNCTION__);
+ set_audio_registers(dev, a2_table2);
+ break;
+ case WW_A2_M:
+ dprintk("%s NTSC-M A2 (status: unknown)\n",__FUNCTION__);
+ set_audio_registers(dev, a2_table3);
+ break;
};
-
-
- dprintk("%s (status: WorksForMe[tm])\n",__FUNCTION__);
-
- if (0) {
- /* old code */
- set_audio_start(dev, 0x0004, EN_DMTRX_SUMR | EN_A2_AUTO_STEREO);
- set_audio_registers(dev, a2_old);
- set_audio_finish(dev);
- } else {
- /* new code */
- set_audio_start(dev, 0x0004, EN_DMTRX_LR | EN_A2_AUTO_STEREO);
- set_audio_registers(dev, a2);
- set_audio_finish(dev);
- }
+ set_audio_finish(dev);
}
static void set_audio_standard_EIAJ(struct cx8800_dev *dev)
@@ -617,9 +670,9 @@ void cx88_get_stereo(struct cx8800_dev *
reg = cx_read(AUD_STATUS);
mode = reg & 0x03;
pilot = (reg >> 2) & 0x03;
- dprintk("AUD_STATUS: %s / %s [status=0x%x,ctl=0x%x,vol=0x%x]\n",
- m[mode], p[pilot], reg,
- cx_read(AUD_CTL), cx_sread(SHADOW_AUD_VOL_CTL));
+ dprintk("AUD_STATUS: 0x%x [%s/%s] ctl=%s\n",
+ reg, m[mode], p[pilot],
+ aud_ctl_names[cx_read(AUD_CTL) & 63]);
t->capability = V4L2_TUNER_CAP_STEREO | V4L2_TUNER_CAP_SAP |
V4L2_TUNER_CAP_LANG1 | V4L2_TUNER_CAP_LANG2;
@@ -628,6 +681,8 @@ void cx88_get_stereo(struct cx8800_dev *
switch (dev->tvaudio) {
case WW_A2_BG:
+ case WW_A2_DK:
+ case WW_A2_M:
if (1 == pilot) {
/* stereo */
t->rxsubchans = V4L2_TUNER_SUB_MONO | V4L2_TUNER_SUB_STEREO;
@@ -659,6 +714,8 @@ void cx88_set_stereo(struct cx8800_dev *
switch (dev->tvaudio) {
case WW_A2_BG:
+ case WW_A2_DK:
+ case WW_A2_M:
switch (mode) {
case V4L2_TUNER_MODE_MONO:
case V4L2_TUNER_MODE_LANG1:
@@ -717,6 +774,32 @@ void cx88_set_stereo(struct cx8800_dev *
return;
}
+/* just monitor the audio status for now ... */
+int cx88_audio_thread(void *data)
+{
+ struct cx8800_dev *dev = data;
+ struct v4l2_tuner t;
+
+ daemonize("msp3400");
+ allow_signal(SIGTERM);
+ dprintk("cx88: tvaudio thread started\n");
+
+ for (;;) {
+ set_current_state(TASK_INTERRUPTIBLE);
+ schedule_timeout(HZ*3);
+ if (signal_pending(current))
+ break;
+ if (dev->shutdown)
+ break;
+
+ memset(&t,0,sizeof(t));
+ cx88_get_stereo(dev,&t);
+ }
+
+ dprintk("cx88: tvaudio thread exiting\n");
+ complete_and_exit(&dev->texit, 0);
+}
+
/*
* Local variables:
* c-basic-offset: 8
diff -up linux-2.6.7/drivers/media/video/cx88/cx88-vbi.c linux/drivers/media/video/cx88/cx88-vbi.c
--- linux-2.6.7/drivers/media/video/cx88/cx88-vbi.c 2004-06-17 10:28:57.000000000 +0200
+++ linux/drivers/media/video/cx88/cx88-vbi.c 2004-06-17 13:47:59.797270159 +0200
@@ -28,17 +28,14 @@ void cx8800_vbi_fmt(struct cx8800_dev *d
f->fmt.vbi.count[0] = VBI_LINE_COUNT;
f->fmt.vbi.count[1] = VBI_LINE_COUNT;
- switch (dev->tvnorm->id) {
- case V4L2_STD_NTSC_M:
- case V4L2_STD_NTSC_M_JP:
+ if (dev->tvnorm->id & V4L2_STD_525_60) {
+ /* ntsc */
f->fmt.vbi.sampling_rate = 28636363;
f->fmt.vbi.start[0] = 10 -1;
f->fmt.vbi.start[1] = 273 -1;
- break;
- case V4L2_STD_PAL_BG:
- case V4L2_STD_PAL_DK:
- case V4L2_STD_PAL_I:
- case V4L2_STD_SECAM:
+
+ } else if (V4L2_STD_625_50) {
+ /* pal */
f->fmt.vbi.sampling_rate = 35468950;
f->fmt.vbi.start[0] = 7 -1;
f->fmt.vbi.start[1] = 319 -1;
@@ -64,10 +61,10 @@ int cx8800_start_vbi_dma(struct cx8800_d
/* enable irqs */
cx_set(MO_PCI_INTMSK, 0x00fc01);
cx_set(MO_VID_INTMSK, 0x0f0088);
-
+
/* enable capture */
cx_set(VID_CAPTURE_CONTROL,0x18);
-
+
/* start dma */
cx_set(MO_DEV_CNTRL2, (1<<5));
cx_set(MO_VID_DMACNTRL, 0x88);
@@ -80,7 +77,7 @@ int cx8800_restart_vbi_queue(struct cx88
{
struct cx88_buffer *buf;
struct list_head *item;
-
+
if (list_empty(&q->active))
return 0;
@@ -104,7 +101,7 @@ void cx8800_vbi_timeout(unsigned long da
unsigned long flags;
cx88_sram_channel_dump(dev, &cx88_sram_channels[SRAM_CH24]);
-
+
cx_clear(MO_VID_DMACNTRL, 0x88);
cx_clear(VID_CAPTURE_CONTROL, 0x18);
@@ -161,7 +158,7 @@ vbi_prepare(struct file *file, struct vi
cx88_risc_buffer(dev->pci, &buf->risc,
buf->vb.dma.sglist,
0, buf->vb.width * buf->vb.height,
- buf->vb.width, 0,
+ buf->vb.width, 0,
buf->vb.height);
}
buf->vb.state = STATE_PREPARED;
diff -up linux-2.6.7/drivers/media/video/cx88/cx88-video.c linux/drivers/media/video/cx88/cx88-video.c
--- linux-2.6.7/drivers/media/video/cx88/cx88-video.c 2004-06-17 10:29:27.000000000 +0200
+++ linux/drivers/media/video/cx88/cx88-video.c 2004-06-17 13:47:59.805268654 +0200
@@ -2,7 +2,7 @@
* device driver for Conexant 2388x based TV cards
* video4linux video interface
*
- * (c) 2003 Gerd Knorr <kraxel@bytesex.org> [SuSE Labs]
+ * (c) 2003-04 Gerd Knorr <kraxel@bytesex.org> [SuSE Labs]
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -19,8 +19,6 @@
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
-#define __NO_VERSION__ 1
-
#include <linux/init.h>
#include <linux/list.h>
#include <linux/module.h>
@@ -32,6 +30,8 @@
#include "cx88.h"
+#define V4L2_I2C_CLIENTS 1
+
MODULE_DESCRIPTION("v4l2 driver module for cx2388x based TV cards");
MODULE_AUTHOR("Gerd Knorr <kraxel@bytesex.org> [SuSE Labs]");
MODULE_LICENSE("GPL");
@@ -194,8 +194,13 @@ static struct cx8800_tvnorm tvnorms[] =
.cxiformat = VideoFormatPAL60,
.cxoformat = 0x181f0008,
},{
- .name = "SECAM",
- .id = V4L2_STD_SECAM,
+ .name = "SECAM-L",
+ .id = V4L2_STD_SECAM_L,
+ .cxiformat = VideoFormatSECAM,
+ .cxoformat = 0x181f0008,
+ },{
+ .name = "SECAM-DK",
+ .id = V4L2_STD_SECAM_DK,
.cxiformat = VideoFormatSECAM,
.cxoformat = 0x181f0008,
}
@@ -331,7 +336,7 @@ static struct cx88_ctrl cx8800_ctls[] =
*/
.v = {
.id = V4L2_CID_SATURATION,
- .name = "Saturation",
+ .name = "Saturation",
.minimum = 0,
.maximum = 0xff,
.step = 1,
@@ -483,35 +488,38 @@ static int set_tvaudio(struct cx8800_dev
if (CX88_VMUX_TELEVISION != INPUT(dev->input)->type)
return 0;
- switch (dev->tvnorm->id) {
- case V4L2_STD_PAL_BG:
+ if (V4L2_STD_PAL_BG & dev->tvnorm->id) {
dev->tvaudio = nicam ? WW_NICAM_BGDKL : WW_A2_BG;
- break;
- case V4L2_STD_PAL_DK:
+
+ } else if (V4L2_STD_PAL_DK & dev->tvnorm->id) {
dev->tvaudio = nicam ? WW_NICAM_BGDKL : WW_A2_DK;
- break;
- case V4L2_STD_PAL_I:
+
+ } else if (V4L2_STD_PAL_I & dev->tvnorm->id) {
dev->tvaudio = WW_NICAM_I;
- break;
- case V4L2_STD_SECAM:
- dev->tvaudio = WW_SYSTEM_L_AM; /* FIXME: fr != ru */
- break;
- case V4L2_STD_NTSC_M:
+
+ } else if (V4L2_STD_SECAM_L & dev->tvnorm->id) {
+ dev->tvaudio = WW_SYSTEM_L_AM;
+
+ } else if (V4L2_STD_SECAM_DK & dev->tvnorm->id) {
+ dev->tvaudio = WW_A2_DK;
+
+ } else if ((V4L2_STD_NTSC_M & dev->tvnorm->id) ||
+ (V4L2_STD_PAL_M & dev->tvnorm->id)) {
dev->tvaudio = WW_BTSC;
- break;
- case V4L2_STD_NTSC_M_JP:
+
+ } else if (V4L2_STD_NTSC_M_JP & dev->tvnorm->id) {
dev->tvaudio = WW_EIAJ;
- break;
- default:
- dprintk(1,"tvaudio support needs work for this tv norm [%s], sorry\n",
- dev->tvnorm->name);
+
+ } else {
+ printk("%s: tvaudio support needs work for this tv norm [%s], sorry\n",
+ dev->name, dev->tvnorm->name);
dev->tvaudio = 0;
return 0;
}
cx_andor(MO_AFECFG_IO, 0x1f, 0x0);
cx88_set_tvaudio(dev);
- cx88_set_stereo(dev,V4L2_TUNER_MODE_STEREO);
+ // cx88_set_stereo(dev,V4L2_TUNER_MODE_STEREO);
cx_write(MO_AUDD_LNGTH, 128/8); /* fifo size */
cx_write(MO_AUDR_LNGTH, 128/8); /* fifo size */
@@ -526,7 +534,6 @@ static int set_tvnorm(struct cx8800_dev
u32 vdec_clock;
u64 tmp64;
u32 bdelay,agcdelay,htotal;
- struct video_channel c;
dev->tvnorm = norm;
fsc8 = norm_fsc8(norm);
@@ -592,30 +599,43 @@ static int set_tvnorm(struct cx8800_dev
set_tvaudio(dev);
// tell i2c chips
- memset(&c,0,sizeof(c));
- c.channel = dev->input;
- c.norm = VIDEO_MODE_PAL;
- if ((norm->id & (V4L2_STD_NTSC_M|V4L2_STD_NTSC_M_JP)))
- c.norm = VIDEO_MODE_NTSC;
- if (norm->id & V4L2_STD_SECAM)
- c.norm = VIDEO_MODE_SECAM;
- cx8800_call_i2c_clients(dev,VIDIOCSCHAN,&c);
+#ifdef V4L2_I2C_CLIENTS
+ cx8800_call_i2c_clients(dev,VIDIOC_S_STD,&norm->id);
+#else
+ {
+ struct video_channel c;
+ memset(&c,0,sizeof(c));
+ c.channel = dev->input;
+ c.norm = VIDEO_MODE_PAL;
+ if ((norm->id & (V4L2_STD_NTSC_M|V4L2_STD_NTSC_M_JP)))
+ c.norm = VIDEO_MODE_NTSC;
+ if (norm->id & V4L2_STD_SECAM)
+ c.norm = VIDEO_MODE_SECAM;
+ cx8800_call_i2c_clients(dev,VIDIOCSCHAN,&c);
+ }
+#endif
// done
return 0;
}
static int set_scale(struct cx8800_dev *dev, unsigned int width, unsigned int height,
- int interlaced)
+ enum v4l2_field field)
{
unsigned int swidth = norm_swidth(dev->tvnorm);
unsigned int sheight = norm_maxh(dev->tvnorm);
u32 value;
- dprintk(1,"set_scale: %dx%d [%s]\n", width, height, dev->tvnorm->name);
+ dprintk(1,"set_scale: %dx%d [%s%s,%s]\n", width, height,
+ V4L2_FIELD_HAS_TOP(field) ? "T" : "",
+ V4L2_FIELD_HAS_BOTTOM(field) ? "B" : "",
+ dev->tvnorm->name);
+ if (!V4L2_FIELD_HAS_BOTH(field))
+ height *= 2;
// recalc H delay and scale registers
value = (width * norm_hdelay(dev->tvnorm)) / swidth;
+ value &= 0x3fe;
cx_write(MO_HDELAY_EVEN, value);
cx_write(MO_HDELAY_ODD, value);
dprintk(1,"set_scale: hdelay 0x%04x\n", value);
@@ -646,7 +666,7 @@ static int set_scale(struct cx8800_dev *
// setup filters
value = 0;
value |= (1 << 19); // CFILT (default)
- if (interlaced)
+ if (V4L2_FIELD_INTERLACED == field)
value |= (1 << 3); // VINT (interlaced vertical scaling)
if (width < 385)
value |= (1 << 0); // 3-tap interpolation
@@ -675,10 +695,12 @@ static int video_mux(struct cx8800_dev *
switch (INPUT(input)->type) {
case CX88_VMUX_SVIDEO:
- cx_andor(MO_AFECFG_IO, 0x01, 0x01);
+ cx_set(MO_AFECFG_IO, 0x00000001);
+ cx_set(MO_INPUT_FORMAT, 0x00010010);
break;
default:
- cx_andor(MO_AFECFG_IO, 0x01, 0x00);
+ cx_clear(MO_AFECFG_IO, 0x00000001);
+ cx_clear(MO_INPUT_FORMAT, 0x00010010);
break;
}
return 0;
@@ -693,7 +715,7 @@ static int start_video_dma(struct cx8800
/* setup fifo + format */
cx88_sram_channel_setup(dev, &cx88_sram_channels[SRAM_CH21],
buf->bpl, buf->risc.dma);
- set_scale(dev, buf->vb.width, buf->vb.height, 1);
+ set_scale(dev, buf->vb.width, buf->vb.height, buf->vb.field);
cx_write(MO_COLOR_CTRL, buf->fmt->cxformat | ColorFormatGamma);
/* reset counter */
@@ -1350,6 +1372,9 @@ static int get_control(struct cx8800_dev
case V4L2_CID_AUDIO_BALANCE:
ctl->value = (value & 0x40) ? (value & 0x3f) : (0x40 - (value & 0x3f));
break;
+ case V4L2_CID_AUDIO_VOLUME:
+ ctl->value = 0x3f - (value & 0x3f);
+ break;
default:
ctl->value = ((value + (c->off << c->shift)) & c->mask) >> c->shift;
break;
@@ -1378,6 +1403,9 @@ static int set_control(struct cx8800_dev
case V4L2_CID_AUDIO_BALANCE:
value = (ctl->value < 0x40) ? (0x40 - ctl->value) : ctl->value;
break;
+ case V4L2_CID_AUDIO_VOLUME:
+ value = 0x3f - (ctl->value & 0x3f);
+ break;
case V4L2_CID_SATURATION:
/* special v_sat handling */
v_sat_value = ctl->value - (0x7f - 0x5a);
@@ -1409,7 +1437,7 @@ static void init_controls(struct cx8800_
};
static struct v4l2_control volume = {
.id = V4L2_CID_AUDIO_VOLUME,
- .value = 0,
+ .value = 0x3f,
};
set_control(dev,&mute);
@@ -1459,15 +1487,12 @@ static int cx8800_try_fmt(struct cx8800_
maxw = norm_maxw(dev->tvnorm);
maxh = norm_maxh(dev->tvnorm);
-#if 0
if (V4L2_FIELD_ANY == field) {
field = (f->fmt.pix.height > maxh/2)
? V4L2_FIELD_INTERLACED
: V4L2_FIELD_BOTTOM;
}
-#else
- field = V4L2_FIELD_INTERLACED;
-#endif
+
switch (field) {
case V4L2_FIELD_TOP:
case V4L2_FIELD_BOTTOM:
@@ -1480,14 +1505,15 @@ static int cx8800_try_fmt(struct cx8800_
}
f->fmt.pix.field = field;
- if (f->fmt.pix.width < 48)
- f->fmt.pix.width = 48;
if (f->fmt.pix.height < 32)
f->fmt.pix.height = 32;
- if (f->fmt.pix.width > maxw)
- f->fmt.pix.width = maxw;
if (f->fmt.pix.height > maxh)
f->fmt.pix.height = maxh;
+ if (f->fmt.pix.width < 48)
+ f->fmt.pix.width = 48;
+ if (f->fmt.pix.width > maxw)
+ f->fmt.pix.width = maxw;
+ f->fmt.pix.width &= ~0x03;
f->fmt.pix.bytesperline =
(f->fmt.pix.width * fmt->depth) >> 3;
f->fmt.pix.sizeimage =
@@ -1783,7 +1809,11 @@ static int video_do_ioctl(struct inode *
return -EINVAL;
down(&dev->lock);
dev->freq = f->frequency;
+#ifdef V4L2_I2C_CLIENTS
+ cx8800_call_i2c_clients(dev,VIDIOC_S_FREQUENCY,f);
+#else
cx8800_call_i2c_clients(dev,VIDIOCSFREQ,&dev->freq);
+#endif
up(&dev->lock);
return 0;
}
@@ -1836,7 +1866,7 @@ static int video_do_ioctl(struct inode *
case VIDIOC_STREAMOFF:
{
int res = get_ressource(fh);
-
+
err = videobuf_streamoff(file, get_queue(fh));
if (err < 0)
return err;
@@ -1885,7 +1915,6 @@ static int radio_do_ioctl(struct inode *
case VIDIOC_G_TUNER:
{
struct v4l2_tuner *t = arg;
- struct video_tuner vt;
if (t->index > 0)
return -EINVAL;
@@ -1895,9 +1924,16 @@ static int radio_do_ioctl(struct inode *
t->rangelow = (int)(65*16);
t->rangehigh = (int)(108*16);
- memset(&vt,0,sizeof(vt));
- cx8800_call_i2c_clients(dev,VIDIOCGTUNER,&vt);
- t->signal = vt.signal;
+#ifdef V4L2_I2C_CLIENTS
+ cx8800_call_i2c_clients(dev,VIDIOC_G_TUNER,t);
+#else
+ {
+ struct video_tuner vt;
+ memset(&vt,0,sizeof(vt));
+ cx8800_call_i2c_clients(dev,VIDIOCGTUNER,&vt);
+ t->signal = vt.signal;
+ }
+#endif
return 0;
}
case VIDIOC_ENUMINPUT:
@@ -2281,11 +2317,6 @@ static void cx8800_unregister_video(stru
}
}
-/* debug that damn oops ... */
-static unsigned int oops = 0;
-MODULE_PARM(oops,"i");
-#define OOPS(msg) if (oops) printk("%s: %s\n",__FUNCTION__,msg);
-
static int __devinit cx8800_initdev(struct pci_dev *pci_dev,
const struct pci_device_id *pci_id)
{
@@ -2299,7 +2330,6 @@ static int __devinit cx8800_initdev(stru
memset(dev,0,sizeof(*dev));
/* pci init */
- OOPS("pci init");
dev->pci = pci_dev;
if (pci_enable_device(pci_dev)) {
err = -EIO;
@@ -2308,7 +2338,6 @@ static int __devinit cx8800_initdev(stru
sprintf(dev->name,"cx%x[%d]",pci_dev->device,cx8800_devcount);
/* pci quirks */
- OOPS("pci quirks");
cx88_pci_quirks(dev->name, dev->pci, &latency);
if (UNSET != latency) {
printk(KERN_INFO "%s: setting pci latency timer to %d\n",
@@ -2317,7 +2346,6 @@ static int __devinit cx8800_initdev(stru
}
/* print pci info */
- OOPS("pci info");
pci_read_config_byte(pci_dev, PCI_CLASS_REVISION, &dev->pci_rev);
pci_read_config_byte(pci_dev, PCI_LATENCY_TIMER, &dev->pci_lat);
printk(KERN_INFO "%s: found at %s, rev: %d, irq: %d, "
@@ -2333,14 +2361,15 @@ static int __devinit cx8800_initdev(stru
}
/* board config */
- OOPS("board config");
dev->board = card[cx8800_devcount];
for (i = 0; UNSET == dev->board && i < cx88_idcount; i++)
if (pci_dev->subsystem_vendor == cx88_subids[i].subvendor &&
pci_dev->subsystem_device == cx88_subids[i].subdevice)
dev->board = cx88_subids[i].card;
- if (UNSET == dev->board)
+ if (UNSET == dev->board) {
dev->board = CX88_BOARD_UNKNOWN;
+ cx88_card_list(dev);
+ }
printk(KERN_INFO "%s: subsystem: %04x:%04x, board: %s [card=%d,%s]\n",
dev->name,pci_dev->subsystem_vendor,
pci_dev->subsystem_device,cx88_boards[dev->board].name,
@@ -2352,7 +2381,6 @@ static int __devinit cx8800_initdev(stru
dev->tuner_type = cx88_boards[dev->board].tuner_type;
/* get mmio */
- OOPS("get mmio");
if (!request_mem_region(pci_resource_start(pci_dev,0),
pci_resource_len(pci_dev,0),
dev->name)) {
@@ -2366,7 +2394,6 @@ static int __devinit cx8800_initdev(stru
dev->bmmio = (u8*)dev->lmmio;
/* initialize driver struct */
- OOPS("init structs");
init_MUTEX(&dev->lock);
dev->slock = SPIN_LOCK_UNLOCKED;
dev->tvnorm = tvnorms;
@@ -2390,11 +2417,9 @@ static int __devinit cx8800_initdev(stru
MO_VID_DMACNTRL,0x88,0x00);
/* initialize hardware */
- OOPS("reset hardware");
cx8800_reset(dev);
/* get irq */
- OOPS("install irq handler");
err = request_irq(pci_dev->irq, cx8800_irq,
SA_SHIRQ | SA_INTERRUPT, dev->name, dev);
if (err < 0) {
@@ -2404,13 +2429,10 @@ static int __devinit cx8800_initdev(stru
}
/* register i2c bus + load i2c helpers */
- OOPS("i2c setup");
cx8800_i2c_init(dev);
- OOPS("card setup");
cx88_card_setup(dev);
/* load and configure helper modules */
- OOPS("configure i2c clients");
if (TUNER_ABSENT != dev->tuner_type)
request_module("tuner");
if (cx88_boards[dev->board].needs_tda9887)
@@ -2419,7 +2441,6 @@ static int __devinit cx8800_initdev(stru
cx8800_call_i2c_clients(dev,TUNER_SET_TYPE,&dev->tuner_type);
/* register v4l devices */
- OOPS("register video");
dev->video_dev = vdev_init(dev,&cx8800_video_template,"video");
err = video_register_device(dev->video_dev,VFL_TYPE_GRABBER,
video_nr[cx8800_devcount]);
@@ -2431,7 +2452,6 @@ static int __devinit cx8800_initdev(stru
printk(KERN_INFO "%s: registered device video%d [v4l2]\n",
dev->name,dev->video_dev->minor & 0x1f);
- OOPS("register vbi");
dev->vbi_dev = vdev_init(dev,&cx8800_vbi_template,"vbi");
err = video_register_device(dev->vbi_dev,VFL_TYPE_VBI,
vbi_nr[cx8800_devcount]);
@@ -2444,7 +2464,6 @@ static int __devinit cx8800_initdev(stru
dev->name,dev->vbi_dev->minor & 0x1f);
if (dev->has_radio) {
- OOPS("register radio");
dev->radio_dev = vdev_init(dev,&cx8800_radio_template,"radio");
err = video_register_device(dev->radio_dev,VFL_TYPE_RADIO,
radio_nr[cx8800_devcount]);
@@ -2458,32 +2477,31 @@ static int __devinit cx8800_initdev(stru
}
/* everything worked */
- OOPS("finalize");
list_add_tail(&dev->devlist,&cx8800_devlist);
pci_set_drvdata(pci_dev,dev);
cx8800_devcount++;
/* initial device configuration */
- OOPS("init device");
down(&dev->lock);
init_controls(dev);
set_tvnorm(dev,tvnorms);
video_mux(dev,0);
up(&dev->lock);
+
+ /* start tvaudio thread */
+ init_completion(&dev->texit);
+ dev->tpid = kernel_thread(cx88_audio_thread, dev, 0);
return 0;
fail3:
- OOPS("fail3");
cx8800_unregister_video(dev);
if (0 == dev->i2c_rc)
i2c_bit_del_bus(&dev->i2c_adap);
free_irq(pci_dev->irq, dev);
fail2:
- OOPS("fail2");
release_mem_region(pci_resource_start(pci_dev,0),
pci_resource_len(pci_dev,0));
fail1:
- OOPS("fail1");
kfree(dev);
return err;
}
@@ -2492,6 +2510,11 @@ static void __devexit cx8800_finidev(str
{
struct cx8800_dev *dev = pci_get_drvdata(pci_dev);
+ /* stop thread */
+ dev->shutdown = 1;
+ if (dev->tpid >= 0)
+ wait_for_completion(&dev->texit);
+
cx8800_shutdown(dev);
pci_disable_device(pci_dev);
diff -up linux-2.6.7/drivers/media/video/cx88/cx88.h linux/drivers/media/video/cx88/cx88.h
--- linux-2.6.7/drivers/media/video/cx88/cx88.h 2004-06-17 10:31:18.000000000 +0200
+++ linux/drivers/media/video/cx88/cx88.h 2004-06-17 13:47:59.807268278 +0200
@@ -32,7 +32,7 @@
#include "cx88-reg.h"
#include <linux/version.h>
-#define CX88_VERSION_CODE KERNEL_VERSION(0,0,3)
+#define CX88_VERSION_CODE KERNEL_VERSION(0,0,4)
#ifndef TRUE
# define TRUE (1==1)
@@ -114,17 +114,20 @@ extern struct sram_channel cx88_sram_cha
/* card configuration */
#define CX88_BOARD_NOAUTO UNSET
-#define CX88_BOARD_UNKNOWN 0
-#define CX88_BOARD_HAUPPAUGE 1
-#define CX88_BOARD_GDI 2
-#define CX88_BOARD_PIXELVIEW 3
-#define CX88_BOARD_ATI_WONDER_PRO 4
-#define CX88_BOARD_WINFAST2000XP 5
-#define CX88_BOARD_AVERTV_303 6
-#define CX88_BOARD_MSI_TVANYWHERE 7
-#define CX88_BOARD_WINFAST_DV2000 8
-#define CX88_BOARD_LEADTEK_PVR2000 9
-
+#define CX88_BOARD_UNKNOWN 0
+#define CX88_BOARD_HAUPPAUGE 1
+#define CX88_BOARD_GDI 2
+#define CX88_BOARD_PIXELVIEW 3
+#define CX88_BOARD_ATI_WONDER_PRO 4
+#define CX88_BOARD_WINFAST2000XP 5
+#define CX88_BOARD_AVERTV_303 6
+#define CX88_BOARD_MSI_TVANYWHERE_MASTER 7
+#define CX88_BOARD_WINFAST_DV2000 8
+#define CX88_BOARD_LEADTEK_PVR2000 9
+#define CX88_BOARD_IODATA_GVVCP3PCI 10
+#define CX88_BOARD_PROLINK_PLAYTVPVR 11
+#define CX88_BOARD_ASUS_PVR_416 12
+#define CX88_BOARD_MSI_TVANYWHERE 13
enum cx88_itype {
CX88_VMUX_COMPOSITE1 = 1,
@@ -263,6 +266,9 @@ struct cx8800_dev {
/* other global state info */
u32 shadow[SHADOW_MAX];
+ int shutdown;
+ pid_t tpid;
+ struct completion texit;
struct cx8800_suspend_state state;
};
@@ -351,7 +357,8 @@ extern const unsigned int cx88_bcount;
extern struct cx88_subid cx88_subids[];
extern const unsigned int cx88_idcount;
-extern void __devinit cx88_card_setup(struct cx8800_dev *dev);
+extern void cx88_card_list(struct cx8800_dev *dev);
+extern void cx88_card_setup(struct cx8800_dev *dev);
/* ----------------------------------------------------------- */
/* cx88-tvaudio.c */
@@ -372,6 +379,7 @@ extern void __devinit cx88_card_setup(st
void cx88_set_tvaudio(struct cx8800_dev *dev);
void cx88_get_stereo(struct cx8800_dev *dev, struct v4l2_tuner *t);
void cx88_set_stereo(struct cx8800_dev *dev, u32 mode);
+int cx88_audio_thread(void *data);
/*
* Local variables:
--
Smoking Crack Organization
next reply other threads:[~2004-06-18 10:25 UTC|newest]
Thread overview: 2+ messages / expand[flat|nested] mbox.gz Atom feed top
2004-06-18 10:02 Gerd Knorr [this message]
-- strict thread matches above, loose matches on Subject: below --
2005-03-08 11:00 [patch] v4l: cx88 driver update Gerd Knorr
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20040618100229.GA24865@bytesex.org \
--to=kraxel@bytesex.org \
--cc=akpm@osdl.org \
--cc=linux-kernel@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.