Merge branch 'release' of git://git.kernel.org/pub/scm/linux/kernel/git/aegl/linux-2.6
[pandora-kernel.git] / drivers / media / video / saa7134 / saa7134-tvaudio.c
index f8e304c..c5d0b44 100644 (file)
 
 /* ------------------------------------------------------------------ */
 
-static unsigned int audio_debug = 0;
+static unsigned int audio_debug;
 module_param(audio_debug, int, 0644);
 MODULE_PARM_DESC(audio_debug,"enable debug messages [tv audio]");
 
-static unsigned int audio_ddep = 0;
+static unsigned int audio_ddep;
 module_param(audio_ddep, int, 0644);
 MODULE_PARM_DESC(audio_ddep,"audio ddep overwrite");
 
 static int audio_clock_override = UNSET;
 module_param(audio_clock_override, int, 0644);
 
-static int audio_clock_tweak = 0;
+static int audio_clock_tweak;
 module_param(audio_clock_tweak, int, 0644);
 MODULE_PARM_DESC(audio_clock_tweak, "Audio clock tick fine tuning for cards with audio crystal that's slightly off (range [-1024 .. 1024])");
 
@@ -163,32 +163,6 @@ static struct saa7134_tvaudio tvaudio[] = {
 
 /* ------------------------------------------------------------------ */
 
-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;
-
-       /* init all audio registers */
-       saa_writeb(SAA7134_AUDIO_PLL_CTRL,   0x00);
-       if (need_resched())
-               schedule();
-       else
-               udelay(10);
-
-       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);
-       saa_writeb(SAA7134_NICAM_ERROR_HIGH, 0x50);
-       saa_writeb(SAA7134_MONITOR_SELECT,   0xa0);
-       saa_writeb(SAA7134_FM_DEMATRIX,      0x80);
-}
-
 static u32 tvaudio_carr2reg(u32 carrier)
 {
        u64 a = carrier;
@@ -503,7 +477,6 @@ static int tvaudio_thread(void *data)
        unsigned int i, audio, nscan;
        int max1,max2,carrier,rx,mode,lastmode,default_carrier;
 
-
        set_freezable();
 
        for (;;) {
@@ -517,9 +490,13 @@ static int tvaudio_thread(void *data)
                dev->thread.scan1 = dev->thread.scan2;
                dprintk("tvaudio thread scan start [%d]\n",dev->thread.scan1);
                dev->tvaudio  = NULL;
-               tvaudio_init(dev);
+
+               saa_writeb(SAA7134_MONITOR_SELECT,   0xa0);
+               saa_writeb(SAA7134_FM_DEMATRIX,      0x80);
+
                if (dev->ctl_automute)
                        dev->automute = 1;
+
                mute_input_7134(dev);
 
                /* give the tuner some time */
@@ -675,6 +652,17 @@ static char *stdres[0x20] = {
 
 #define DSP_RETRY 32
 #define DSP_DELAY 16
+#define SAA7135_DSP_RWCLEAR_RERR 1
+
+static inline int saa_dsp_reset_error_bit(struct saa7134_dev *dev)
+{
+       int state = saa_readb(SAA7135_DSP_RWSTATE);
+       if (unlikely(state & SAA7135_DSP_RWSTATE_ERR)) {
+               d2printk("%s: resetting error bit\n", dev->name);
+               saa_writeb(SAA7135_DSP_RWCLEAR, SAA7135_DSP_RWCLEAR_RERR);
+       }
+       return 0;
+}
 
 static inline int saa_dsp_wait_bit(struct saa7134_dev *dev, int bit)
 {
@@ -682,8 +670,8 @@ static inline int saa_dsp_wait_bit(struct saa7134_dev *dev, int bit)
 
        state = saa_readb(SAA7135_DSP_RWSTATE);
        if (unlikely(state & SAA7135_DSP_RWSTATE_ERR)) {
-               printk("%s: dsp access error\n",dev->name);
-               /* FIXME: send ack ... */
+               printk(KERN_WARNING "%s: dsp access error\n", dev->name);
+               saa_dsp_reset_error_bit(dev);
                return -EIO;
        }
        while (0 == (state & bit)) {
@@ -784,27 +772,14 @@ static int mute_input_7133(struct saa7134_dev *dev)
 static int tvaudio_thread_ddep(void *data)
 {
        struct saa7134_dev *dev = data;
-       u32 value, norms, clock;
-
+       u32 value, norms;
 
        set_freezable();
-
-       clock = saa7134_boards[dev->board].audio_clock;
-       if (UNSET != audio_clock_override)
-               clock = audio_clock_override;
-       saa_writel(0x598 >> 2, clock);
-
-       /* unmute */
-       saa_dsp_writel(dev, 0x474 >> 2, 0x00);
-       saa_dsp_writel(dev, 0x450 >> 2, 0x00);
-
        for (;;) {
                tvaudio_sleep(dev,-1);
                if (kthread_should_stop())
                        goto done;
-
        restart:
-
                try_to_freeze();
 
                dev->thread.scan1 = dev->thread.scan2;
@@ -896,13 +871,34 @@ void saa7134_enable_i2s(struct saa7134_dev *dev)
 
        if (!card_is_empress(dev))
                return;
-       i2s_format = (dev->input->amux == TV) ? 0x00 : 0x01;
 
-       /* enable I2S audio output for the mpeg encoder */
-       saa_writeb(SAA7134_I2S_OUTPUT_SELECT,  0x80);
-       saa_writeb(SAA7134_I2S_OUTPUT_FORMAT,  i2s_format);
-       saa_writeb(SAA7134_I2S_OUTPUT_LEVEL,   0x0F);
-       saa_writeb(SAA7134_I2S_AUDIO_OUTPUT,   0x01);
+       if (dev->pci->device == PCI_DEVICE_ID_PHILIPS_SAA7130)
+               return;
+
+       /* configure GPIO for out */
+       saa_andorl(SAA7134_GPIO_GPMODE0 >> 2, 0x0E000000, 0x00000000);
+
+       switch (dev->pci->device) {
+       case PCI_DEVICE_ID_PHILIPS_SAA7133:
+       case PCI_DEVICE_ID_PHILIPS_SAA7135:
+           /* Set I2S format (SONY)  */
+           saa_writeb(SAA7133_I2S_AUDIO_CONTROL, 0x00);
+           /* Start I2S */
+           saa_writeb(SAA7134_I2S_AUDIO_OUTPUT, 0x11);
+           break;
+
+       case PCI_DEVICE_ID_PHILIPS_SAA7134:
+           i2s_format = (dev->input->amux == TV) ? 0x00 : 0x01;
+
+           /* enable I2S audio output for the mpeg encoder */
+           saa_writeb(SAA7134_I2S_OUTPUT_SELECT, 0x80);
+           saa_writeb(SAA7134_I2S_OUTPUT_FORMAT, i2s_format);
+           saa_writeb(SAA7134_I2S_OUTPUT_LEVEL,  0x0F);
+           saa_writeb(SAA7134_I2S_AUDIO_OUTPUT,  0x01);
+
+       default:
+           break;
+       }
 }
 
 int saa7134_tvaudio_rx2mode(u32 rx)
@@ -978,6 +974,38 @@ int saa7134_tvaudio_getstereo(struct saa7134_dev *dev)
        return retval;
 }
 
+void saa7134_tvaudio_init(struct saa7134_dev *dev)
+{
+       int clock = saa7134_boards[dev->board].audio_clock;
+
+       if (UNSET != audio_clock_override)
+               clock = audio_clock_override;
+
+       switch (dev->pci->device) {
+       case PCI_DEVICE_ID_PHILIPS_SAA7134:
+               /* init all audio registers */
+               saa_writeb(SAA7134_AUDIO_PLL_CTRL,   0x00);
+               if (need_resched())
+                       schedule();
+               else
+                       udelay(10);
+
+               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);
+               saa_writeb(SAA7134_NICAM_ERROR_HIGH, 0x50);
+               break;
+       case PCI_DEVICE_ID_PHILIPS_SAA7133:
+       case PCI_DEVICE_ID_PHILIPS_SAA7135:
+               saa_writel(0x598 >> 2, clock);
+               saa_dsp_writel(dev, 0x474 >> 2, 0x00);
+               saa_dsp_writel(dev, 0x450 >> 2, 0x00);
+       }
+}
+
 int saa7134_tvaudio_init2(struct saa7134_dev *dev)
 {
        int (*my_thread)(void *data) = NULL;
@@ -994,6 +1022,7 @@ int saa7134_tvaudio_init2(struct saa7134_dev *dev)
 
        dev->thread.thread = NULL;
        if (my_thread) {
+               saa7134_tvaudio_init(dev);
                /* start tvaudio thread */
                dev->thread.thread = kthread_run(my_thread, dev, "%s", dev->name);
                if (IS_ERR(dev->thread.thread)) {