diff --git a/drivers/media/video/cx88/cx88-core.c b/drivers/media/video/cx88/cx88-core.c index b18e7a33081a..bb6eb54e19ce 100644 --- a/drivers/media/video/cx88/cx88-core.c +++ b/drivers/media/video/cx88/cx88-core.c @@ -837,6 +837,29 @@ static int set_pll(struct cx88_core *core, int prescale, u32 ofreq) return -1; } +int cx88_start_audio_dma(struct cx88_core *core) +{ + /* setup fifo + format */ + cx88_sram_channel_setup(core, &cx88_sram_channels[SRAM_CH25], 128, 0); + cx88_sram_channel_setup(core, &cx88_sram_channels[SRAM_CH26], 128, 0); + + cx_write(MO_AUDD_LNGTH, 128); /* fifo bpl size */ + cx_write(MO_AUDR_LNGTH, 128); /* fifo bpl size */ + + /* start dma */ + cx_write(MO_AUD_DMACNTRL, 0x0003); /* Up and Down fifo enable */ + + return 0; +} + +int cx88_stop_audio_dma(struct cx88_core *core) +{ + /* stop dma */ + cx_write(MO_AUD_DMACNTRL, 0x0000); + + return 0; +} + static int set_tvaudio(struct cx88_core *core) { struct cx88_tvnorm *norm = core->tvnorm; @@ -877,9 +900,16 @@ static int set_tvaudio(struct cx88_core *core) cx88_set_tvaudio(core); /* cx88_set_stereo(dev,V4L2_TUNER_MODE_STEREO); */ +/* + This should be needed only on cx88-alsa. It seems that some cx88 chips have + bugs and does require DMA enabled for it to work. + */ + cx88_start_audio_dma(core); return 0; } + + int cx88_set_tvnorm(struct cx88_core *core, struct cx88_tvnorm *norm) { u32 fsc8; @@ -1201,6 +1231,8 @@ EXPORT_SYMBOL(cx88_set_scale); EXPORT_SYMBOL(cx88_vdev_init); EXPORT_SYMBOL(cx88_core_get); EXPORT_SYMBOL(cx88_core_put); +EXPORT_SYMBOL(cx88_start_audio_dma); +EXPORT_SYMBOL(cx88_stop_audio_dma); /* * Local variables: diff --git a/drivers/media/video/cx88/cx88-tvaudio.c b/drivers/media/video/cx88/cx88-tvaudio.c index a9059c53a418..a1b120c8a9b5 100644 --- a/drivers/media/video/cx88/cx88-tvaudio.c +++ b/drivers/media/video/cx88/cx88-tvaudio.c @@ -132,7 +132,10 @@ static void set_audio_finish(struct cx88_core *core, u32 ctl) { u32 volume; + /* restart dma; This avoids buzz in NICAM and is good in others */ + cx88_stop_audio_dma(core); cx_write(AUD_RATE_THRES_DMD, 0x000000C0); + cx88_start_audio_dma(core); if (cx88_boards[core->board].blackbird) { /* sets sound input from external adc */ diff --git a/drivers/media/video/cx88/cx88.h b/drivers/media/video/cx88/cx88.h index b19d3a9e2298..27fb080fd7aa 100644 --- a/drivers/media/video/cx88/cx88.h +++ b/drivers/media/video/cx88/cx88.h @@ -491,6 +491,10 @@ extern struct cx88_core* cx88_core_get(struct pci_dev *pci); extern void cx88_core_put(struct cx88_core *core, struct pci_dev *pci); +extern int cx88_start_audio_dma(struct cx88_core *core); +extern int cx88_stop_audio_dma(struct cx88_core *core); + + /* ----------------------------------------------------------- */ /* cx88-vbi.c */