Merge master.kernel.org:/home/rmk/linux-2.6-arm
[pandora-kernel.git] / drivers / media / video / saa7134 / saa7134-tvaudio.c
index 3617e7f..badf2f9 100644 (file)
@@ -1,5 +1,4 @@
 /*
- * $Id: saa7134-tvaudio.c,v 1.25 2005/06/07 19:00:38 nsh Exp $
  *
  * device driver for philips saa7134 based TV cards
  * tv audio decoder (fm stereo, nicam, ...)
@@ -169,7 +168,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);
@@ -219,14 +218,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;
@@ -260,6 +262,7 @@ static void mute_input_7134(struct saa7134_dev *dev)
        /* 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);
@@ -339,13 +342,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
                }
        }
        remove_wait_queue(&dev->thread.wq, &wait);
@@ -400,27 +398,10 @@ 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) {
@@ -442,18 +423,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 0x08:
-                       retval = V4L2_TUNER_SUB_MONO;
-                       break;
-               case 0x09:
-                       retval = V4L2_TUNER_SUB_LANG1 | V4L2_TUNER_SUB_LANG2;
-                       break;
-               case 0x0a:
-                       retval = V4L2_TUNER_SUB_MONO | V4L2_TUNER_SUB_STEREO;
-                       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;
        }
@@ -489,15 +476,15 @@ static int tvaudio_setstereo(struct saa7134_dev *dev, struct saa7134_tvaudio *au
                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;
@@ -596,7 +583,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;
@@ -703,24 +690,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)
 {
@@ -753,31 +722,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;
+
+               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, dev->input->gpio);
-               saa7134_track_gpio(dev,dev->input->name);
+               saa_andorl(SAA7134_GPIO_GPSTATUS0 >> 2, mask, in->gpio);
+               saa7134_track_gpio(dev,in->name);
        }
+
        return 0;
 }