/* ------------------------------------------------------------------ */
-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])");
/* ------------------------------------------------------------------ */
-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;
unsigned int i, audio, nscan;
int max1,max2,carrier,rx,mode,lastmode,default_carrier;
-
set_freezable();
for (;;) {
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 */
#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)
{
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)) {
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;
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)
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;
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)) {