X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=drivers%2Fmedia%2Fvideo%2Fsaa7134%2Fsaa7134-tvaudio.c;h=0db53d192b2a2b1d40f975b63256066982ba1e3e;hb=43bc926fffd92024b46cafaf7350d669ba9ca884;hp=ecac13c006d513b61ba6350f2cd04723fcfb9fef;hpb=cee37fe97739d85991964371c1f3a745c00dd236;p=linux-2.6.git diff --git a/drivers/media/video/saa7134/saa7134-tvaudio.c b/drivers/media/video/saa7134/saa7134-tvaudio.c index ecac13c00..0db53d192 100644 --- a/drivers/media/video/saa7134/saa7134-tvaudio.c +++ b/drivers/media/video/saa7134/saa7134-tvaudio.c @@ -1,5 +1,4 @@ /* - * $Id: saa7134-tvaudio.c,v 1.22 2005/01/07 13:11:19 kraxel Exp $ * * device driver for philips saa7134 based TV cards * tv audio decoder (fm stereo, nicam, ...) @@ -140,6 +139,12 @@ static struct saa7134_tvaudio tvaudio[] = { .carr1 = 6500, .carr2 = 5850, .mode = TVAUDIO_NICAM_AM, + },{ + .name = "SECAM-L MONO", + .std = V4L2_STD_SECAM, + .carr1 = 6500, + .carr2 = -1, + .mode = TVAUDIO_AM_MONO, },{ .name = "SECAM-D/K", .std = V4L2_STD_SECAM, @@ -169,7 +174,7 @@ static void tvaudio_init(struct saa7134_dev *dev) int clock = saa7134_boards[dev->board].audio_clock; if (UNSET != audio_clock_override) - clock = audio_clock_override; + clock = audio_clock_override; /* init all audio registers */ saa_writeb(SAA7134_AUDIO_PLL_CTRL, 0x00); @@ -181,6 +186,7 @@ static void tvaudio_init(struct saa7134_dev *dev) saa_writeb(SAA7134_AUDIO_CLOCK0, clock & 0xff); saa_writeb(SAA7134_AUDIO_CLOCK1, (clock >> 8) & 0xff); saa_writeb(SAA7134_AUDIO_CLOCK2, (clock >> 16) & 0xff); + /* frame locked audio is mandatory for NICAM */ saa_writeb(SAA7134_AUDIO_PLL_CTRL, 0x01); saa_writeb(SAA7134_NICAM_ERROR_LOW, 0x14); @@ -207,6 +213,10 @@ static void tvaudio_setcarrier(struct saa7134_dev *dev, saa_writel(SAA7134_CARRIER2_FREQ0 >> 2, tvaudio_carr2reg(secondary)); } +#define SAA7134_MUTE_MASK 0xbb +#define SAA7134_MUTE_ANALOG 0x04 +#define SAA7134_MUTE_I2S 0x40 + static void mute_input_7134(struct saa7134_dev *dev) { unsigned int mute; @@ -218,14 +228,17 @@ static void mute_input_7134(struct saa7134_dev *dev) in = dev->input; mute = (dev->ctl_mute || (dev->automute && (&card(dev).radio) != in)); - if (PCI_DEVICE_ID_PHILIPS_SAA7130 == dev->pci->device && - card(dev).mute.name) { - /* 7130 - we'll mute using some unconnected audio input */ + if (card(dev).mute.name) { + /* + * 7130 - we'll mute using some unconnected audio input + * 7134 - we'll probably should switch external mux with gpio + */ if (mute) in = &card(dev).mute; } + if (dev->hw_mute == mute && - dev->hw_input == in) { + dev->hw_input == in) { dprintk("mute/input: nothing to do [mute=%d,input=%s]\n", mute,in->name); return; @@ -238,7 +251,11 @@ static void mute_input_7134(struct saa7134_dev *dev) if (PCI_DEVICE_ID_PHILIPS_SAA7134 == dev->pci->device) /* 7134 mute */ - saa_writeb(SAA7134_AUDIO_MUTE_CTRL, mute ? 0xbf : 0xbb); + saa_writeb(SAA7134_AUDIO_MUTE_CTRL, mute ? + SAA7134_MUTE_MASK | + SAA7134_MUTE_ANALOG | + SAA7134_MUTE_I2S : + SAA7134_MUTE_MASK); /* switch internal audio mux */ switch (in->amux) { @@ -250,10 +267,16 @@ static void mute_input_7134(struct saa7134_dev *dev) saa_andorb(SAA7134_AUDIO_FORMAT_CTRL, 0xc0, ausel); saa_andorb(SAA7134_ANALOG_IO_SELECT, 0x08, ics); saa_andorb(SAA7134_ANALOG_IO_SELECT, 0x07, ocs); + // for oss, we need to change the clock configuration + if (in->amux == TV) + saa_andorb(SAA7134_SIF_SAMPLE_FREQ, 0x03, 0x00); + else + saa_andorb(SAA7134_SIF_SAMPLE_FREQ, 0x03, 0x01); /* switch gpio-connected external audio mux */ if (0 == card(dev).gpiomask) return; + mask = card(dev).gpiomask; saa_andorl(SAA7134_GPIO_GPMODE0 >> 2, mask, mask); saa_andorl(SAA7134_GPIO_GPSTATUS0 >> 2, mask, in->gpio); @@ -317,6 +340,12 @@ static void tvaudio_setmode(struct saa7134_dev *dev, saa_writeb(SAA7134_STEREO_DAC_OUTPUT_SELECT, 0xa1); saa_writeb(SAA7134_NICAM_CONFIG, 0x00); break; + case TVAUDIO_AM_MONO: + saa_writeb(SAA7134_DEMODULATOR, 0x12); + saa_writeb(SAA7134_DCXO_IDENT_CTRL, 0x00); + saa_writeb(SAA7134_FM_DEEMPHASIS, 0x44); + saa_writeb(SAA7134_STEREO_DAC_OUTPUT_SELECT, 0xa0); + break; case TVAUDIO_FM_SAT_STEREO: /* not implemented (yet) */ break; @@ -333,13 +362,8 @@ static int tvaudio_sleep(struct saa7134_dev *dev, int timeout) set_current_state(TASK_INTERRUPTIBLE); schedule(); } else { -#if 0 - /* hmm, that one doesn't return on wakeup ... */ - msleep_interruptible(timeout); -#else - set_current_state(TASK_INTERRUPTIBLE); - schedule_timeout(msecs_to_jiffies(timeout)); -#endif + schedule_timeout_interruptible + (msecs_to_jiffies(timeout)); } } remove_wait_queue(&dev->thread.wq, &wait); @@ -394,31 +418,15 @@ static int tvaudio_checkcarrier(struct saa7134_dev *dev, struct mainscan *scan) return value; } -#if 0 -static void sifdebug_dump_regs(struct saa7134_dev *dev) -{ - print_regb(AUDIO_STATUS); - print_regb(IDENT_SIF); - print_regb(LEVEL_READOUT1); - print_regb(LEVEL_READOUT2); - print_regb(DCXO_IDENT_CTRL); - print_regb(DEMODULATOR); - print_regb(AGC_GAIN_SELECT); - print_regb(MONITOR_SELECT); - print_regb(FM_DEEMPHASIS); - print_regb(FM_DEMATRIX); - print_regb(SIF_SAMPLE_FREQ); - print_regb(ANALOG_IO_SELECT); -} -#endif static int tvaudio_getstereo(struct saa7134_dev *dev, struct saa7134_tvaudio *audio) { - __u32 idp,nicam; + __u32 idp, nicam, nicam_status; int retval = -1; switch (audio->mode) { case TVAUDIO_FM_MONO: + case TVAUDIO_AM_MONO: return V4L2_TUNER_SUB_MONO; case TVAUDIO_FM_K_STEREO: case TVAUDIO_FM_BG_STEREO: @@ -436,19 +444,24 @@ static int tvaudio_getstereo(struct saa7134_dev *dev, struct saa7134_tvaudio *au break; case TVAUDIO_NICAM_FM: case TVAUDIO_NICAM_AM: - nicam = saa_readb(SAA7134_NICAM_STATUS); + nicam = saa_readb(SAA7134_AUDIO_STATUS); dprintk("getstereo: nicam=0x%x\n",nicam); - switch (nicam & 0x0b) { - case 0x09: - retval = V4L2_TUNER_SUB_LANG1 | V4L2_TUNER_SUB_LANG2; - break; - case 0x0a: - retval = V4L2_TUNER_SUB_MONO | V4L2_TUNER_SUB_STEREO; - break; - case 0x08: - default: - retval = V4L2_TUNER_SUB_MONO; - break; + if (nicam & 0x1) { + nicam_status = saa_readb(SAA7134_NICAM_STATUS); + dprintk("getstereo: nicam_status=0x%x\n", nicam_status); + + switch (nicam_status & 0x03) { + case 0x01: + retval = V4L2_TUNER_SUB_LANG1 | V4L2_TUNER_SUB_LANG2; + break; + case 0x02: + retval = V4L2_TUNER_SUB_MONO | V4L2_TUNER_SUB_STEREO; + break; + default: + retval = V4L2_TUNER_SUB_MONO; + } + } else { + /* No nicam detected */ } break; } @@ -469,30 +482,33 @@ static int tvaudio_setstereo(struct saa7134_dev *dev, struct saa7134_tvaudio *au [ V4L2_TUNER_MODE_STEREO ] = "stereo", [ V4L2_TUNER_MODE_LANG1 ] = "lang1", [ V4L2_TUNER_MODE_LANG2 ] = "lang2", + [ V4L2_TUNER_MODE_LANG1_LANG2 ] = "lang1+lang2", }; static u32 fm[] = { [ V4L2_TUNER_MODE_MONO ] = 0x00, /* ch1 */ [ V4L2_TUNER_MODE_STEREO ] = 0x80, /* auto */ [ V4L2_TUNER_MODE_LANG1 ] = 0x00, /* ch1 */ [ V4L2_TUNER_MODE_LANG2 ] = 0x01, /* ch2 */ + [ V4L2_TUNER_MODE_LANG1_LANG2 ] = 0x80, /* auto */ }; u32 reg; switch (audio->mode) { case TVAUDIO_FM_MONO: + case TVAUDIO_AM_MONO: /* nothing to do ... */ break; case TVAUDIO_FM_K_STEREO: case TVAUDIO_FM_BG_STEREO: + case TVAUDIO_NICAM_AM: + case TVAUDIO_NICAM_FM: dprintk("setstereo [fm] => %s\n", name[ mode % ARRAY_SIZE(name) ]); reg = fm[ mode % ARRAY_SIZE(fm) ]; saa_writeb(SAA7134_FM_DEMATRIX, reg); break; case TVAUDIO_FM_SAT_STEREO: - case TVAUDIO_NICAM_AM: - case TVAUDIO_NICAM_FM: - /* FIXME */ + /* Not implemented */ break; } return 0; @@ -572,14 +588,14 @@ static int tvaudio_thread(void *data) } else if (0 != dev->last_carrier) { /* no carrier -- try last detected one as fallback */ carrier = dev->last_carrier; - printk(KERN_WARNING "%s/audio: audio carrier scan failed, " + dprintk(KERN_WARNING "%s/audio: audio carrier scan failed, " "using %d.%03d MHz [last detected]\n", dev->name, carrier/1000, carrier%1000); } else { /* no carrier + no fallback -- use default */ carrier = default_carrier; - printk(KERN_WARNING "%s/audio: audio carrier scan failed, " + dprintk(KERN_WARNING "%s/audio: audio carrier scan failed, " "using %d.%03d MHz [default]\n", dev->name, carrier/1000, carrier%1000); } @@ -591,7 +607,7 @@ static int tvaudio_thread(void *data) /* find the exact tv audio norm */ for (audio = UNSET, i = 0; i < TVAUDIO; i++) { if (dev->tvnorm->id != UNSET && - !(dev->tvnorm->id & tvaudio[i].std)) + !(dev->tvnorm->id & tvaudio[i].std)) continue; if (tvaudio[i].carr1 != carrier) continue; @@ -698,24 +714,6 @@ static inline int saa_dsp_wait_bit(struct saa7134_dev *dev, int bit) return 0; } -#if 0 -static int saa_dsp_readl(struct saa7134_dev *dev, int reg, u32 *value) -{ - int err; - - d2printk("dsp read reg 0x%x\n", reg<<2); - saa_readl(reg); - err = saa_dsp_wait_bit(dev,SAA7135_DSP_RWSTATE_RDB); - if (err < 0) - return err; - *value = saa_readl(reg); - d2printk("dsp read => 0x%06x\n", *value & 0xffffff); - err = saa_dsp_wait_bit(dev,SAA7135_DSP_RWSTATE_IDA); - if (err < 0) - return err; - return 0; -} -#endif int saa_dsp_writel(struct saa7134_dev *dev, int reg, u32 value) { @@ -748,31 +746,50 @@ static int getstereo_7133(struct saa7134_dev *dev) static int mute_input_7133(struct saa7134_dev *dev) { u32 reg = 0; + u32 xbarin, xbarout; int mask; + struct saa7134_input *in; + /* Hac 0506 route OSS sound simultanously */ + xbarin = 0x03; switch (dev->input->amux) { case TV: reg = 0x02; + xbarin = 0; break; case LINE1: reg = 0x00; break; case LINE2: case LINE2_LEFT: - reg = 0x01; + reg = 0x09; break; } - if (dev->ctl_mute) + saa_dsp_writel(dev, 0x464 >> 2, xbarin); + if (dev->ctl_mute) { reg = 0x07; + xbarout = 0xbbbbbb; + } else + xbarout = 0xbbbb10; + saa_dsp_writel(dev, 0x46c >> 2, xbarout); + saa_writel(0x594 >> 2, reg); + /* switch gpio-connected external audio mux */ - if (0 != card(dev).gpiomask) { - mask = card(dev).gpiomask; - saa_andorl(SAA7134_GPIO_GPMODE0 >> 2, mask, mask); - saa_andorl(SAA7134_GPIO_GPSTATUS0 >> 2, mask, dev->input->gpio); - saa7134_track_gpio(dev,dev->input->name); + if (0 != card(dev).gpiomask) { + mask = card(dev).gpiomask; + + if (card(dev).mute.name && dev->ctl_mute) + in = &card(dev).mute; + else + in = dev->input; + + saa_andorl(SAA7134_GPIO_GPMODE0 >> 2, mask, mask); + saa_andorl(SAA7134_GPIO_GPSTATUS0 >> 2, mask, in->gpio); + saa7134_track_gpio(dev,in->name); } + return 0; } @@ -808,7 +825,12 @@ static int tvaudio_thread_ddep(void *data) dprintk("ddep override: %s\n",stdres[audio_ddep]); } else if (&card(dev).radio == dev->input) { dprintk("FM Radio\n"); - norms = (0x0f << 2) | 0x01; + if (dev->tuner_type == TUNER_PHILIPS_TDA8290) { + norms = (0x11 << 2) | 0x01; + saa_dsp_writel(dev, 0x42c >> 2, 0x729555); + } else { + norms = (0x0f << 2) | 0x01; + } } else { /* (let chip) scan for sound carrier */ norms = 0; @@ -1023,9 +1045,12 @@ int saa7134_tvaudio_do_scan(struct saa7134_dev *dev) return 0; } +EXPORT_SYMBOL(saa_dsp_writel); + /* ----------------------------------------------------------- */ /* * Local variables: * c-basic-offset: 8 * End: */ +