diff options
author | Gerd Knorr <devnull@localhost> | 2004-03-16 12:34:16 +0000 |
---|---|---|
committer | Gerd Knorr <devnull@localhost> | 2004-03-16 12:34:16 +0000 |
commit | 0936e8eeba58f9a7937356e3df175e4bf206ba08 (patch) | |
tree | 5045de8848517d4ca375f163d3d8de367a2fe18f /linux/drivers/media/video | |
parent | 1a7193208a5de7115bcd96806da8f77202cfbec4 (diff) | |
download | mediapointer-dvb-s2-0936e8eeba58f9a7937356e3df175e4bf206ba08.tar.gz mediapointer-dvb-s2-0936e8eeba58f9a7937356e3df175e4bf206ba08.tar.bz2 |
- plenty of cx88 audio fixes.
* grabbed some A2 code from dscaler cvs.
* merged patches by zarquon@earendel.org.
* code cleanups.
Diffstat (limited to 'linux/drivers/media/video')
-rw-r--r-- | linux/drivers/media/video/cx88/cx88-cards.c | 57 | ||||
-rw-r--r-- | linux/drivers/media/video/cx88/cx88-tvaudio.c | 358 | ||||
-rw-r--r-- | linux/drivers/media/video/cx88/cx88-video.c | 23 | ||||
-rw-r--r-- | linux/drivers/media/video/cx88/cx88.h | 4 |
4 files changed, 378 insertions, 64 deletions
diff --git a/linux/drivers/media/video/cx88/cx88-cards.c b/linux/drivers/media/video/cx88/cx88-cards.c index 1c1b18a6f..1cb7cd0e6 100644 --- a/linux/drivers/media/video/cx88/cx88-cards.c +++ b/linux/drivers/media/video/cx88/cx88-cards.c @@ -111,19 +111,35 @@ struct cx88_board cx88_boards[] = { }, [CX88_BOARD_WINFAST2000XP] = { .name = "Leadtek Winfast 2000XP Expert", - .tuner_type = 38, + .tuner_type = UNSET, .input = {{ .type = CX88_VMUX_TELEVISION, .vmux = 0, + .gpio0 = 0x00F5e700, + .gpio1 = 0x00003004, + .gpio2 = 0x00F5e700, + .gpio3 = 0x02000000, },{ .type = CX88_VMUX_COMPOSITE1, .vmux = 1, + .gpio0 = 0x00F5c700, + .gpio1 = 0x00003004, + .gpio2 = 0x00F5c700, + .gpio3 = 0x02000000, },{ .type = CX88_VMUX_SVIDEO, .vmux = 2, + .gpio0 = 0x00F5c700, + .gpio1 = 0x00003004, + .gpio2 = 0x00F5c700, + .gpio3 = 0x02000000, }}, .radio = { .type = CX88_RADIO, + .gpio0 = 0x00F5d700, + .gpio1 = 0x00003004, + .gpio2 = 0x00F5d700, + .gpio3 = 0x02000000, }, }, [CX88_BOARD_AVERTV_303] = { @@ -213,6 +229,10 @@ struct cx88_subid cx88_subids[] = { .subdevice = 0x6611, .card = CX88_BOARD_WINFAST2000XP, },{ + .subvendor = 0x107d, + .subdevice = 0x6613, /* NTSC */ + .card = CX88_BOARD_WINFAST2000XP, + },{ .subvendor = 0x107d, .subdevice = 0x6620, .card = CX88_BOARD_WINFAST_DV2000, @@ -232,6 +252,34 @@ struct cx88_subid cx88_subids[] = { }; const unsigned int cx88_idcount = ARRAY_SIZE(cx88_subids); + +/* ----------------------------------------------------------------------- */ +/* some leadtek specific stuff */ + +static void __devinit leadtek_eeprom(struct cx8800_dev *dev, u8 *eeprom_data) +{ + /* This is just for the Winfast 2000 XP board ATM; I don't have data on + * any others. + * + * Byte 0 is 1 on the NTSC board. + */ + + if (eeprom_data[4] != 0x7d || + eeprom_data[5] != 0x10 || + eeprom_data[7] != 0x66) { + printk(KERN_WARNING "%s Leadtek eeprom invalid.\n", dev->name); + return; + } + + 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]); +} + + /* ----------------------------------------------------------------------- */ /* some hauppauge specific stuff */ @@ -408,17 +456,20 @@ void __devinit cx88_card_setup(struct cx8800_dev *dev) switch (dev->board) { case CX88_BOARD_HAUPPAUGE: - printk("cx88_card_setup: Hauppauge\n"); if (0 == dev->i2c_rc) i2c_eeprom(&dev->i2c_client,eeprom,sizeof(eeprom)); hauppauge_eeprom(dev,eeprom+8); break; case CX88_BOARD_GDI: - printk("cx88_card_setup: GDI\n"); if (0 == dev->i2c_rc) i2c_eeprom(&dev->i2c_client,eeprom,sizeof(eeprom)); gdi_eeprom(dev,eeprom); break; + case CX88_BOARD_WINFAST2000XP: + if (0 == dev->i2c_rc) + i2c_eeprom(&dev->i2c_client,eeprom,sizeof(eeprom)); + leadtek_eeprom(dev,eeprom); + break; } } diff --git a/linux/drivers/media/video/cx88/cx88-tvaudio.c b/linux/drivers/media/video/cx88/cx88-tvaudio.c index e6b2f8f5f..d356d880f 100644 --- a/linux/drivers/media/video/cx88/cx88-tvaudio.c +++ b/linux/drivers/media/video/cx88/cx88-tvaudio.c @@ -14,7 +14,7 @@ Some of this comes from party done linux driver sources I got from [undocumented]. - Some comes from the dscaler sources, the dscaler driver guy works + Some comes from the dscaler sources, one of the dscaler driver guy works for Conexant ... ----------------------------------------------------------------------- @@ -74,26 +74,62 @@ static void set_audio_registers(struct cx8800_dev *dev, cx_write(l[i].reg, l[i].val); } +static void set_audio_start(struct cx8800_dev *dev, + u32 mode, u32 ctl) +{ + // mute + cx_write(AUD_VOL_CTL, (1 << 6)); + + // increase level of input by 12dB + cx_write(AUD_AFE_12DB_EN, 0x0001); + + // start programming + cx_write(AUD_CTL, 0x0000); + cx_write(AUD_INIT, mode); + cx_write(AUD_INIT_LD, 0x0001); + cx_write(AUD_SOFT_RESET, 0x0001); + + cx_write(AUD_CTL, ctl); +} + +static void set_audio_finish(struct cx8800_dev *dev) +{ + u32 volume; + + // finish programming + cx_write(AUD_SOFT_RESET, 0x0000); + + // start audio processing + cx_set(AUD_CTL, EN_DAC_ENABLE); + + // unmute + volume = cx_sread(SHADOW_AUD_VOL_CTL); + cx_swrite(SHADOW_AUD_VOL_CTL, AUD_VOL_CTL, volume); +} + +/* ----------------------------------------------------------- */ + static void set_audio_standard_BTSC(struct cx8800_dev *dev, unsigned int sap) { - dprintk("set_audio_standard_BTSC() [TODO]\n"); + 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 }, + }; + + dprintk("%s\n",__FUNCTION__); + set_audio_start(dev, 0x0001, + 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[] = { - // increase level of input by 12dB - { AUD_AFE_12DB_EN, 0x00000001 }, - - // initialize NICAM - { AUD_INIT, 0x00000010 }, - { AUD_INIT_LD, 0x00000001 }, - { AUD_SOFT_RESET, 0x00000001 }, - - // WARNING!!!! Stereo mode is FORCED!!!! - { AUD_CTL, EN_DAC_ENABLE | EN_DMTRX_LR | EN_NICAM_FORCE_STEREO }, - - { AUD_SOFT_RESET, 0x00000001 }, { AUD_RATE_ADJ1, 0x00000010 }, { AUD_RATE_ADJ2, 0x00000040 }, { AUD_RATE_ADJ3, 0x00000100 }, @@ -101,43 +137,228 @@ static void set_audio_standard_NICAM(struct cx8800_dev *dev) { AUD_RATE_ADJ5, 0x00001000 }, // { AUD_DMD_RA_DDS, 0x00c0d5ce }, + // setup QAM registers + { 0x320d01, 0x06 }, + { 0x320d02, 0x82 }, + { 0x320d03, 0x16 }, + { 0x320d04, 0x05 }, + { 0x320d2a, 0x34 }, + { 0x320d2b, 0x4c }, + { /* end of list */ }, }; - printk("set_audio_standard_NICAM()\n"); + dprintk("%s\n",__FUNCTION__); + set_audio_start(dev, 0x0010, + EN_DMTRX_LR | EN_NICAM_FORCE_STEREO); set_audio_registers(dev, nicam); + set_audio_finish(dev); +} - // setup QAM registers - cx_write(0x320d01, 0x06); - cx_write(0x320d02, 0x82); - cx_write(0x320d03, 0x16); - cx_write(0x320d04, 0x05); - cx_write(0x320d2a, 0x34); - cx_write(0x320d2b, 0x4c); +static void set_audio_standard_NICAM_L(struct cx8800_dev *dev) +{ + /* This is officially wierd.. register dumps indicate windows + * uses audio mode 4.. A2. Let's operate and find out. */ + + static const struct rlist nicam_l[] = { + // setup QAM registers + { 0x0320d01, 0x00000048 }, + { 0x0320d02, 0x0000003d }, + { 0x0320d03, 0x000000f5 }, + { 0x0320d04, 0x00000000 }, + { 0x0320d2a, 0x0033003a }, + { 0x0320d2b, 0x0000334a }, + + { 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_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_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_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_CORDIC_SHIFT_1, 0x00000007 }, + { AUD_PLL_EN, 0x00000000 }, + { AUD_PLL_PRESCALE, 0x00000002 }, + { AUD_PLL_INT, 0x0000001e }, + { AUD_OUT1_SHIFT, 0x00000000 }, - // setup Audio PLL - //cx_write(AUD_PLL_PRESCALE, 0x0002); - //cx_write(AUD_PLL_INT, 0x001f); + { /* end of list */ }, + }; - // de-assert Audio soft reset - cx_write(AUD_SOFT_RESET, 0x00000000); // Causes a pop every time + dprintk("%s\n",__FUNCTION__); + set_audio_start(dev, 0x0004, + 0 /* FIXME */); + set_audio_registers(dev, nicam_l); + set_audio_finish(dev); } static void set_audio_standard_A2(struct cx8800_dev *dev) { + /* from dscaler cvs */ static const struct rlist a2[] = { - // increase level of input by 12dB - { AUD_AFE_12DB_EN, 0x00000001 }, + { AUD_RATE_ADJ1, 0x00001000 }, + { AUD_RATE_ADJ2, 0x00002000 }, + { AUD_RATE_ADJ3, 0x00003000 }, + { AUD_RATE_ADJ4, 0x00004000 }, + { AUD_RATE_ADJ5, 0x00005000 }, + { AUD_THR_FR, 0x00000000 }, + { AAGC_HYST, 0x0000001a }, + { AUD_PILOT_BQD_1_K0, 0x0000755b }, + { AUD_PILOT_BQD_1_K1, 0x00551340 }, + { AUD_PILOT_BQD_1_K2, 0x006d30be }, + { AUD_PILOT_BQD_1_K3, 0xffd394af }, + { AUD_PILOT_BQD_1_K4, 0x00400000 }, + { AUD_PILOT_BQD_2_K0, 0x00040000 }, + { AUD_PILOT_BQD_2_K1, 0x002a4841 }, + { AUD_PILOT_BQD_2_K2, 0x00400000 }, + { AUD_PILOT_BQD_2_K3, 0x00000000 }, + { AUD_PILOT_BQD_2_K4, 0x00000000 }, + { AUD_MODE_CHG_TIMER, 0x00000040 }, + { AUD_START_TIMER, 0x00000200 }, + { AUD_AFE_12DB_EN, 0x00000000 }, + { AUD_CORDIC_SHIFT_0, 0x00000007 }, + { AUD_CORDIC_SHIFT_1, 0x00000007 }, + { AUD_DEEMPH0_G0, 0x00000380 }, + { AUD_DEEMPH1_G0, 0x00000380 }, + { AUD_DCOC_0_SRC, 0x0000001a }, + { AUD_DCOC0_SHIFT, 0x00000000 }, + { AUD_DCOC_0_SHIFT_IN0, 0x0000000a }, + { AUD_DCOC_0_SHIFT_IN1, 0x00000008 }, + { AUD_DCOC_PASS_IN, 0x00000003 }, + { AUD_IIR3_0_SEL, 0x00000021 }, + { AUD_DN2_AFC, 0x00000002 }, + { AUD_DCOC_1_SRC, 0x0000001b }, + { AUD_DCOC1_SHIFT, 0x00000000 }, + { AUD_DCOC_1_SHIFT_IN0, 0x0000000a }, + { AUD_DCOC_1_SHIFT_IN1, 0x00000008 }, + { AUD_IIR3_1_SEL, 0x00000023 }, + { AUD_RDSI_SEL, 0x00000017 }, + { AUD_RDSI_SHIFT, 0x00000000 }, + { AUD_RDSQ_SEL, 0x00000017 }, + { AUD_RDSQ_SHIFT, 0x00000000 }, + { AUD_POLYPH80SCALEFAC, 0x00000001 }, + + // Table 1 + { 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 + { 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 }, + { AUD_DN0_FREQ, 0x00003a1c }, + { AUD_DN2_FREQ, 0x0000d2e0 }, + + // Table 3 + { AUD_DMD_RA_DDS, 0x002a2873 }, + { AUD_C1_UP_THR, 0x00003c00 }, + { AUD_C1_LO_THR, 0x00003000 }, + { AUD_C2_UP_THR, 0x00006000 }, + { AUD_C2_LO_THR, 0x00003c00 }, + { AUD_DN0_FREQ, 0x00002836 }, + { AUD_DN1_FREQ, 0x00003418 }, + { AUD_DN2_FREQ, 0x000029c7 }, + { AUD_POLY0_DDS_CONSTANT, 0x000a7540 }, +#endif - // initialize A2 - { AUD_INIT, 0x00000004 }, - { AUD_INIT_LD, 0x00000001 }, - { AUD_SOFT_RESET, 0x00000001 }, - - // ; WARNING!!! A2 STEREO DEMATRIX HAS TO BE - // ; SET MANUALLY!!! Value sould be 0x100c - { AUD_CTL, EN_DAC_ENABLE | EN_DMTRX_SUMR | EN_A2_AUTO_STEREO }, + { /* end of list */ }, + }; + static const struct rlist a2_old[] = { { AUD_DN0_FREQ, 0x0000312b }, { AUD_POLY0_DDS_CONSTANT, 0x000a62b4 }, { AUD_IIR1_0_SEL, 0x00000000 }, @@ -245,35 +466,53 @@ static void set_audio_standard_A2(struct cx8800_dev *dev) { AUD_DN2_SRC_SEL, 0x00000001 }, { AUD_DN2_FREQ, 0x00003551 }, - // setup Audio PLL { AUD_PLL_PRESCALE, 0x00000002 }, { AUD_PLL_INT, 0x0000001f }, - // de-assert Audio soft reset - { AUD_SOFT_RESET, 0x00000000 }, - { /* end of list */ }, }; - dprintk("set_audio_standard_A2()\n"); - set_audio_registers(dev, a2); + + dprintk("%s\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); + + cx_writeb(AUD_PDF_DDS_CNST_BYTE2, 0x06); + cx_writeb(AUD_PDF_DDS_CNST_BYTE1, 0x82); + cx_writeb(AUD_PDF_DDS_CNST_BYTE0, 0x12); + cx_writeb(AUD_QAM_MODE, 0x05); + cx_writeb(AUD_PHACC_FREQ_8MSB, 0x34); + cx_writeb(AUD_PHACC_FREQ_8LSB, 0x4c); + + set_audio_registers(dev, a2); + set_audio_finish(dev); + } } static void set_audio_standard_EIAJ(struct cx8800_dev *dev) { - dprintk("set_audio_standard_EIAJ() [TODO]\n"); + static const struct rlist eiaj[] = { + /* TODO: eiaj register settings are not there yet ... */ + + { /* end of list */ }, + }; + dprintk("%s\n",__FUNCTION__); + + set_audio_start(dev, 0x0002, EN_EIAJ_AUTO_STEREO); + set_audio_registers(dev, eiaj); + set_audio_finish(dev); } static void set_audio_standard_FM(struct cx8800_dev *dev) { - dprintk("set_audio_standard_FM\n"); - - // initialize FM Radio - cx_write(AUD_INIT,0x0020); - cx_write(AUD_INIT_LD,0x0001); - cx_write(AUD_SOFT_RESET,0x0001); - #if 0 /* FIXME */ switch (dev->audio_properties.FM_deemphasis) { @@ -311,19 +550,19 @@ static void set_audio_standard_FM(struct cx8800_dev *dev) } #endif - // de-assert Audio soft reset - cx_write(AUD_SOFT_RESET,0x0000); + dprintk("%s\n",__FUNCTION__); + set_audio_start(dev, 0x0020, EN_FMRADIO_AUTO_STEREO); // AB: 10/2/01: this register is not being reset appropriately on occasion. cx_write(AUD_POLYPH80SCALEFAC,3); + + set_audio_finish(dev); } /* ----------------------------------------------------------- */ void cx88_set_tvaudio(struct cx8800_dev *dev) { - cx_write(AUD_CTL, 0x00); - switch (dev->tvaudio) { case WW_BTSC: set_audio_standard_BTSC(dev,0); @@ -343,16 +582,15 @@ void cx88_set_tvaudio(struct cx8800_dev *dev) case WW_FM: set_audio_standard_FM(dev); break; + case WW_SYSTEM_L_AM: + set_audio_standard_NICAM_L(dev); + break; case WW_NONE: default: printk("%s: unknown tv audio mode [%d]\n", dev->name, dev->tvaudio); break; } - - // unmute - cx_set(AUD_CTL, EN_DAC_ENABLE); - cx_swrite(SHADOW_AUD_VOL_CTL, AUD_VOL_CTL, 0x00); return; } @@ -455,7 +693,7 @@ void cx88_set_stereo(struct cx8800_dev *dev, u32 mode) if (UNSET != ctl) { cx_write(AUD_SOFT_RESET, 0x0001); - cx_andor(AUD_CTL, mask, ctl); + cx_andor(AUD_CTL, mask, ctl); cx_write(AUD_SOFT_RESET, 0x0000); dprintk("cx88_set_stereo: mask 0x%x, ctl 0x%x " "[status=0x%x,ctl=0x%x,vol=0x%x]\n", diff --git a/linux/drivers/media/video/cx88/cx88-video.c b/linux/drivers/media/video/cx88/cx88-video.c index 56b72e44d..109bdeb75 100644 --- a/linux/drivers/media/video/cx88/cx88-video.c +++ b/linux/drivers/media/video/cx88/cx88-video.c @@ -667,6 +667,9 @@ static int video_mux(struct cx8800_dev *dev, unsigned int input) dev->input = input; cx_andor(MO_INPUT_FORMAT, 0x03 << 14, INPUT(input)->vmux << 14); cx_write(MO_GP0_IO, INPUT(input)->gpio0); + cx_write(MO_GP1_IO, INPUT(input)->gpio1); + cx_write(MO_GP2_IO, INPUT(input)->gpio2); + cx_write(MO_GP3_IO, INPUT(input)->gpio3); return 0; } @@ -1230,6 +1233,9 @@ static int video_open(struct inode *inode, struct file *file) if (fh->radio) { dprintk(1,"video_open: setting radio device\n"); cx_write(MO_GP0_IO, cx88_boards[dev->board].radio.gpio0); + cx_write(MO_GP1_IO, cx88_boards[dev->board].radio.gpio1); + cx_write(MO_GP2_IO, cx88_boards[dev->board].radio.gpio2); + cx_write(MO_GP3_IO, cx88_boards[dev->board].radio.gpio3); dev->tvaudio = WW_FM; cx88_set_tvaudio(dev); cx88_set_stereo(dev,V4L2_TUNER_MODE_STEREO); @@ -1384,6 +1390,21 @@ static int set_control(struct cx8800_dev *dev, struct v4l2_control *ctl) return 0; } +static int init_controls(struct cx8800_dev *dev) +{ + static struct v4l2_control mute = { + .id = V4L2_CID_AUDIO_MUTE, + .value = 1, + }; + static struct v4l2_control volume = { + .id = V4L2_CID_AUDIO_VOLUME, + .value = 0, + }; + + set_control(dev,&mute); + set_control(dev,&volume); +} + /* ------------------------------------------------------------------ */ static int cx8800_g_fmt(struct cx8800_dev *dev, struct cx8800_fh *fh, @@ -2333,6 +2354,7 @@ static int __devinit cx8800_initdev(struct pci_dev *pci_dev, } dev->lmmio = ioremap(pci_resource_start(pci_dev,0), pci_resource_len(pci_dev,0)); + dev->bmmio = (u8*)dev->lmmio; /* initialize driver struct */ OOPS("init structs"); @@ -2435,6 +2457,7 @@ static int __devinit cx8800_initdev(struct pci_dev *pci_dev, down(&dev->lock); set_tvnorm(dev,tvnorms); video_mux(dev,0); + init_controls(dev); up(&dev->lock); return 0; diff --git a/linux/drivers/media/video/cx88/cx88.h b/linux/drivers/media/video/cx88/cx88.h index 97fae4ee1..5fadf124c 100644 --- a/linux/drivers/media/video/cx88/cx88.h +++ b/linux/drivers/media/video/cx88/cx88.h @@ -157,7 +157,7 @@ enum cx88_itype { struct cx88_input { enum cx88_itype type; unsigned int vmux; - u32 gpio0; + u32 gpio0, gpio1, gpio2, gpio3; }; struct cx88_board { @@ -250,6 +250,7 @@ struct cx8800_dev { struct pci_dev *pci; unsigned char pci_rev,pci_lat; u32 *lmmio; + u8 *bmmio; /* config info */ unsigned int board; @@ -285,6 +286,7 @@ struct cx8800_dev { #define cx_read(reg) readl(dev->lmmio + ((reg)>>2)) #define cx_write(reg,value) writel((value), dev->lmmio + ((reg)>>2)); +#define cx_writeb(reg,value) writeb((value), dev->bmmio + (reg)); #define cx_andor(reg,mask,value) \ writel((readl(dev->lmmio+((reg)>>2)) & ~(mask)) |\ |