V4L/DVB (4701): Saa713x audio fixes

This change fixes the following issues:
- resolve the SECAM D/K vs SECAM-L sound conflict
  It is now possible to select the SECAM version either by the VIDEOIOC_S_STD
  IO control or by the new secam= insmod option.
  The driver now adapts its audio standard search list to the selected
  standard.
- don't trigger a sound standard search when a LINE input is selected.

Signed-off-by: Hartmut Hackmann <hartmut.hackmann@t-online.de>
Signed-off-by: Mauro Carvalho Chehab <mchehab@infradead.org>
This commit is contained in:
Hartmut Hackmann 2006-10-02 19:55:07 -03:00 committed by Mauro Carvalho Chehab
parent 39666962a3
commit 17b10a73e6
3 changed files with 96 additions and 57 deletions

View file

@ -72,12 +72,12 @@ static struct mainscan {
int carr;
} mainscan[] = {
{
.name = "M",
.std = V4L2_STD_NTSC | V4L2_STD_PAL_M,
.name = "MN",
.std = V4L2_STD_MN,
.carr = 4500,
},{
.name = "BG",
.std = V4L2_STD_PAL_BG,
.name = "BGH",
.std = V4L2_STD_B | V4L2_STD_GH,
.carr = 5500,
},{
.name = "I",
@ -85,7 +85,7 @@ static struct mainscan {
.carr = 6000,
},{
.name = "DKL",
.std = V4L2_STD_PAL_DK | V4L2_STD_SECAM,
.std = V4L2_STD_DK | V4L2_STD_SECAM_L | V4L2_STD_SECAM_LC,
.carr = 6500,
}
};
@ -93,76 +93,70 @@ static struct mainscan {
static struct saa7134_tvaudio tvaudio[] = {
{
.name = "PAL-B/G FM-stereo",
.std = V4L2_STD_PAL,
.std = V4L2_STD_PAL_BG,
.mode = TVAUDIO_FM_BG_STEREO,
.carr1 = 5500,
.carr2 = 5742,
},{
.name = "PAL-D/K1 FM-stereo",
.std = V4L2_STD_PAL,
.std = V4L2_STD_PAL_DK,
.carr1 = 6500,
.carr2 = 6258,
.mode = TVAUDIO_FM_BG_STEREO,
},{
.name = "PAL-D/K2 FM-stereo",
.std = V4L2_STD_PAL,
.std = V4L2_STD_PAL_DK,
.carr1 = 6500,
.carr2 = 6742,
.mode = TVAUDIO_FM_BG_STEREO,
},{
.name = "PAL-D/K3 FM-stereo",
.std = V4L2_STD_PAL,
.std = V4L2_STD_PAL_DK,
.carr1 = 6500,
.carr2 = 5742,
.mode = TVAUDIO_FM_BG_STEREO,
},{
.name = "PAL-B/G NICAM",
.std = V4L2_STD_PAL,
.std = V4L2_STD_PAL_BG,
.carr1 = 5500,
.carr2 = 5850,
.mode = TVAUDIO_NICAM_FM,
},{
.name = "PAL-I NICAM",
.std = V4L2_STD_PAL,
.std = V4L2_STD_PAL_I,
.carr1 = 6000,
.carr2 = 6552,
.mode = TVAUDIO_NICAM_FM,
},{
.name = "PAL-D/K NICAM",
.std = V4L2_STD_PAL,
.std = V4L2_STD_PAL_DK,
.carr1 = 6500,
.carr2 = 5850,
.mode = TVAUDIO_NICAM_FM,
},{
.name = "SECAM-L NICAM",
.std = V4L2_STD_SECAM,
.std = V4L2_STD_SECAM_L,
.carr1 = 6500,
.carr2 = 5850,
.mode = TVAUDIO_NICAM_AM,
},{
.name = "SECAM-L MONO",
.std = V4L2_STD_SECAM,
.name = "SECAM-D/K NICAM",
.std = V4L2_STD_SECAM_DK,
.carr1 = 6500,
.carr2 = -1,
.mode = TVAUDIO_AM_MONO,
},{
.name = "SECAM-D/K",
.std = V4L2_STD_SECAM,
.carr1 = 6500,
.carr2 = -1,
.mode = TVAUDIO_FM_MONO,
},{
.name = "NTSC-M",
.std = V4L2_STD_NTSC,
.carr1 = 4500,
.carr2 = -1,
.mode = TVAUDIO_FM_MONO,
.carr2 = 5850,
.mode = TVAUDIO_NICAM_FM,
},{
.name = "NTSC-A2 FM-stereo",
.std = V4L2_STD_NTSC,
.carr1 = 4500,
.carr2 = 4724,
.mode = TVAUDIO_FM_K_STEREO,
},{
.name = "NTSC-M",
.std = V4L2_STD_NTSC,
.carr1 = 4500,
.carr2 = -1,
.mode = TVAUDIO_FM_MONO,
}
};
#define TVAUDIO (sizeof(tvaudio)/sizeof(struct saa7134_tvaudio))
@ -340,12 +334,6 @@ 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;
@ -390,7 +378,6 @@ static int tvaudio_checkcarrier(struct saa7134_dev *dev, struct mainscan *scan)
}
printk("\n");
}
if (dev->tvnorm->id & scan->std) {
tvaudio_setcarrier(dev,scan->carr-90,scan->carr-90);
saa_readl(SAA7134_LEVEL_READOUT1 >> 2);
@ -426,7 +413,6 @@ static int tvaudio_getstereo(struct saa7134_dev *dev, struct saa7134_tvaudio *au
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:
@ -495,7 +481,6 @@ static int tvaudio_setstereo(struct saa7134_dev *dev, struct saa7134_tvaudio *au
switch (audio->mode) {
case TVAUDIO_FM_MONO:
case TVAUDIO_AM_MONO:
/* nothing to do ... */
break;
case TVAUDIO_FM_K_STEREO:
@ -556,6 +541,7 @@ static int tvaudio_thread(void *data)
if (1 == nscan) {
/* only one candidate -- skip scan ;) */
dprintk("only one main carrier candidate - skipping scan\n");
max1 = 12345;
carrier = default_carrier;
} else {
@ -603,7 +589,6 @@ static int tvaudio_thread(void *data)
dev->automute = 0;
saa_andorb(SAA7134_STEREO_DAC_OUTPUT_SELECT, 0x30, 0x00);
saa7134_tvaudio_setmute(dev);
/* find the exact tv audio norm */
for (audio = UNSET, i = 0; i < TVAUDIO; i++) {
if (dev->tvnorm->id != UNSET &&
@ -611,7 +596,7 @@ static int tvaudio_thread(void *data)
continue;
if (tvaudio[i].carr1 != carrier)
continue;
/* Note: at least the primary carrier is right here */
if (UNSET == audio)
audio = i;
tvaudio_setmode(dev,&tvaudio[i],"trying");
@ -626,6 +611,7 @@ static int tvaudio_thread(void *data)
if (UNSET == audio)
continue;
tvaudio_setmode(dev,&tvaudio[audio],"using");
tvaudio_setstereo(dev,&tvaudio[audio],V4L2_TUNER_MODE_MONO);
dev->tvaudio = &tvaudio[audio];
@ -750,7 +736,6 @@ static int mute_input_7133(struct saa7134_dev *dev)
int mask;
struct saa7134_input *in;
/* Hac 0506 route OSS sound simultanously */
xbarin = 0x03;
switch (dev->input->amux) {
case TV:
@ -834,18 +819,16 @@ static int tvaudio_thread_ddep(void *data)
} else {
/* (let chip) scan for sound carrier */
norms = 0;
if (dev->tvnorm->id & V4L2_STD_PAL) {
dprintk("PAL scan\n");
norms |= 0x2c; /* B/G + D/K + I */
}
if (dev->tvnorm->id & V4L2_STD_NTSC) {
dprintk("NTSC scan\n");
norms |= 0x40; /* M */
}
if (dev->tvnorm->id & V4L2_STD_SECAM) {
dprintk("SECAM scan\n");
norms |= 0x18; /* L + D/K */
}
if (dev->tvnorm->id & (V4L2_STD_B | V4L2_STD_GH))
norms |= 0x04;
if (dev->tvnorm->id & V4L2_STD_PAL_I)
norms |= 0x20;
if (dev->tvnorm->id & V4L2_STD_DK)
norms |= 0x08;
if (dev->tvnorm->id & V4L2_STD_MN)
norms |= 0x40;
if (dev->tvnorm->id & (V4L2_STD_SECAM_L | V4L2_STD_SECAM_LC))
norms |= 0x10;
if (0 == norms)
norms = 0x7c; /* all */
dprintk("scanning:%s%s%s%s%s\n",
@ -1034,7 +1017,11 @@ int saa7134_tvaudio_fini(struct saa7134_dev *dev)
int saa7134_tvaudio_do_scan(struct saa7134_dev *dev)
{
if (dev->thread.pid >= 0) {
if (dev->input->amux != TV) {
dprintk("sound IF not in use, skipping scan\n");
dev->automute = 0;
saa7134_tvaudio_setmute(dev);
} else if (dev->thread.pid >= 0) {
dev->thread.mode = UNSET;
dev->thread.scan2++;
wake_up_interruptible(&dev->thread.wq);

View file

@ -43,12 +43,16 @@ static unsigned int gbuffers = 8;
static unsigned int noninterlaced = 1;
static unsigned int gbufsize = 720*576*4;
static unsigned int gbufsize_max = 720*576*4;
static char secam[] = "--";
module_param(video_debug, int, 0644);
MODULE_PARM_DESC(video_debug,"enable debug messages [video]");
module_param(gbuffers, int, 0444);
MODULE_PARM_DESC(gbuffers,"number of capture buffers, range 2-32");
module_param(noninterlaced, int, 0644);
MODULE_PARM_DESC(noninterlaced,"capture non interlaced video");
module_param_string(secam, secam, sizeof(secam), 0644);
MODULE_PARM_DESC(secam, "force SECAM variant, either DK,L or Lc");
#define dprintk(fmt, arg...) if (video_debug) \
printk(KERN_DEBUG "%s/video: " fmt, dev->name , ## arg)
@ -279,7 +283,43 @@ static struct saa7134_tvnorm tvnorms[] = {
.id = V4L2_STD_SECAM,
NORM_625_50,
.sync_control = 0x18, /* old: 0x58, */
.sync_control = 0x18,
.luma_control = 0x1b,
.chroma_ctrl1 = 0xd1,
.chroma_gain = 0x80,
.chroma_ctrl2 = 0x00,
.vgate_misc = 0x1c,
},{
.name = "SECAM-DK",
.id = V4L2_STD_SECAM_DK,
NORM_625_50,
.sync_control = 0x18,
.luma_control = 0x1b,
.chroma_ctrl1 = 0xd1,
.chroma_gain = 0x80,
.chroma_ctrl2 = 0x00,
.vgate_misc = 0x1c,
},{
.name = "SECAM-L",
.id = V4L2_STD_SECAM_L,
NORM_625_50,
.sync_control = 0x18,
.luma_control = 0x1b,
.chroma_ctrl1 = 0xd1,
.chroma_gain = 0x80,
.chroma_ctrl2 = 0x00,
.vgate_misc = 0x1c,
},{
.name = "SECAM-Lc",
.id = V4L2_STD_SECAM_LC,
NORM_625_50,
.sync_control = 0x18,
.luma_control = 0x1b,
.chroma_ctrl1 = 0xd1,
.chroma_gain = 0x80,
@ -1769,6 +1809,7 @@ static int video_do_ioctl(struct inode *inode, struct file *file,
{
v4l2_std_id *id = arg;
unsigned int i;
v4l2_std_id fixup;
for (i = 0; i < TVNORMS; i++)
if (*id == tvnorms[i].id)
@ -1779,7 +1820,19 @@ static int video_do_ioctl(struct inode *inode, struct file *file,
break;
if (i == TVNORMS)
return -EINVAL;
if (*id & V4L2_STD_SECAM) {
if (secam[0] == 'L' || secam[0] == 'l')
if (secam[1] == 'C' || secam[1] == 'c')
fixup = V4L2_STD_SECAM_LC;
else
fixup = V4L2_STD_SECAM_L;
else
if (secam[0] == 'D' || secam[0] == 'd')
fixup = V4L2_STD_SECAM_DK;
for (i = 0; i < TVNORMS; i++)
if (fixup == tvnorms[i].id)
break;
}
mutex_lock(&dev->lock);
if (res_check(fh, RESOURCE_OVERLAY)) {
spin_lock_irqsave(&dev->slock,flags);

View file

@ -61,7 +61,6 @@ enum saa7134_tvaudio_mode {
TVAUDIO_FM_K_STEREO = 4,
TVAUDIO_NICAM_AM = 5,
TVAUDIO_NICAM_FM = 6,
TVAUDIO_AM_MONO = 7
};
enum saa7134_audio_in {