forked from Minki/linux
V4L/DVB (12586): Update ALSA capture controls according to selected source.
The patch introduces new snd_saa7134_capsrc_set (code taken from snd_saa7134_capsrc_put) that updates also the ALSA capture controls during snd_card_saa7134_capture_prepare and snd_saa7134_capsrc_put. There can be much more work done in order to unify the control of the card (now the card's capture source is tuned/switched in saa7134-video.c too), but I don't have enough time. This work could be a starting point, but it can be applied as-is too (it doesn't need any further work to make it working). Signed-off-by: Oldřich Jedlička <oldium.pro@seznam.cz> Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
This commit is contained in:
parent
ed44f66e40
commit
736dadaa17
@ -40,6 +40,7 @@ MODULE_PARM_DESC(debug,"enable debug messages [alsa]");
|
||||
*/
|
||||
|
||||
/* defaults */
|
||||
#define MIXER_ADDR_UNSELECTED -1
|
||||
#define MIXER_ADDR_TVTUNER 0
|
||||
#define MIXER_ADDR_LINE1 1
|
||||
#define MIXER_ADDR_LINE2 2
|
||||
@ -68,7 +69,9 @@ typedef struct snd_card_saa7134 {
|
||||
struct snd_card *card;
|
||||
spinlock_t mixer_lock;
|
||||
int mixer_volume[MIXER_ADDR_LAST+1][2];
|
||||
int capture_source[MIXER_ADDR_LAST+1][2];
|
||||
int capture_source_addr;
|
||||
int capture_source[2];
|
||||
struct snd_kcontrol *capture_ctl[MIXER_ADDR_LAST+1];
|
||||
struct pci_dev *pci;
|
||||
struct saa7134_dev *dev;
|
||||
|
||||
@ -314,6 +317,115 @@ static int dsp_buffer_free(struct saa7134_dev *dev)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Setting the capture source and updating the ALSA controls
|
||||
*/
|
||||
static int snd_saa7134_capsrc_set(struct snd_kcontrol *kcontrol,
|
||||
int left, int right, bool force_notify)
|
||||
{
|
||||
snd_card_saa7134_t *chip = snd_kcontrol_chip(kcontrol);
|
||||
int change = 0, addr = kcontrol->private_value;
|
||||
int active, old_addr;
|
||||
u32 anabar, xbarin;
|
||||
int analog_io, rate;
|
||||
struct saa7134_dev *dev;
|
||||
|
||||
dev = chip->dev;
|
||||
|
||||
spin_lock_irq(&chip->mixer_lock);
|
||||
|
||||
active = left != 0 || right != 0;
|
||||
old_addr = chip->capture_source_addr;
|
||||
|
||||
/* The active capture source cannot be deactivated */
|
||||
if (active) {
|
||||
change = old_addr != addr ||
|
||||
chip->capture_source[0] != left ||
|
||||
chip->capture_source[1] != right;
|
||||
|
||||
chip->capture_source[0] = left;
|
||||
chip->capture_source[1] = right;
|
||||
chip->capture_source_addr = addr;
|
||||
dev->dmasound.input = addr;
|
||||
}
|
||||
spin_unlock_irq(&chip->mixer_lock);
|
||||
|
||||
if (change) {
|
||||
switch (dev->pci->device) {
|
||||
|
||||
case PCI_DEVICE_ID_PHILIPS_SAA7134:
|
||||
switch (addr) {
|
||||
case MIXER_ADDR_TVTUNER:
|
||||
saa_andorb(SAA7134_AUDIO_FORMAT_CTRL,
|
||||
0xc0, 0xc0);
|
||||
saa_andorb(SAA7134_SIF_SAMPLE_FREQ,
|
||||
0x03, 0x00);
|
||||
break;
|
||||
case MIXER_ADDR_LINE1:
|
||||
case MIXER_ADDR_LINE2:
|
||||
analog_io = (MIXER_ADDR_LINE1 == addr) ?
|
||||
0x00 : 0x08;
|
||||
rate = (32000 == dev->dmasound.rate) ?
|
||||
0x01 : 0x03;
|
||||
saa_andorb(SAA7134_ANALOG_IO_SELECT,
|
||||
0x08, analog_io);
|
||||
saa_andorb(SAA7134_AUDIO_FORMAT_CTRL,
|
||||
0xc0, 0x80);
|
||||
saa_andorb(SAA7134_SIF_SAMPLE_FREQ,
|
||||
0x03, rate);
|
||||
break;
|
||||
}
|
||||
|
||||
break;
|
||||
case PCI_DEVICE_ID_PHILIPS_SAA7133:
|
||||
case PCI_DEVICE_ID_PHILIPS_SAA7135:
|
||||
xbarin = 0x03; /* adc */
|
||||
anabar = 0;
|
||||
switch (addr) {
|
||||
case MIXER_ADDR_TVTUNER:
|
||||
xbarin = 0; /* Demodulator */
|
||||
anabar = 2; /* DACs */
|
||||
break;
|
||||
case MIXER_ADDR_LINE1:
|
||||
anabar = 0; /* aux1, aux1 */
|
||||
break;
|
||||
case MIXER_ADDR_LINE2:
|
||||
anabar = 9; /* aux2, aux2 */
|
||||
break;
|
||||
}
|
||||
|
||||
/* output xbar always main channel */
|
||||
saa_dsp_writel(dev, SAA7133_DIGITAL_OUTPUT_SEL1,
|
||||
0xbbbb10);
|
||||
|
||||
if (left || right) {
|
||||
/* We've got data, turn the input on */
|
||||
saa_dsp_writel(dev, SAA7133_DIGITAL_INPUT_XBAR1,
|
||||
xbarin);
|
||||
saa_writel(SAA7133_ANALOG_IO_SELECT, anabar);
|
||||
} else {
|
||||
saa_dsp_writel(dev, SAA7133_DIGITAL_INPUT_XBAR1,
|
||||
0);
|
||||
saa_writel(SAA7133_ANALOG_IO_SELECT, 0);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (change) {
|
||||
if (force_notify)
|
||||
snd_ctl_notify(chip->card,
|
||||
SNDRV_CTL_EVENT_MASK_VALUE,
|
||||
&chip->capture_ctl[addr]->id);
|
||||
|
||||
if (old_addr != MIXER_ADDR_UNSELECTED && old_addr != addr)
|
||||
snd_ctl_notify(chip->card,
|
||||
SNDRV_CTL_EVENT_MASK_VALUE,
|
||||
&chip->capture_ctl[old_addr]->id);
|
||||
}
|
||||
|
||||
return change;
|
||||
}
|
||||
|
||||
/*
|
||||
* ALSA PCM preparation
|
||||
@ -401,6 +513,10 @@ static int snd_card_saa7134_capture_prepare(struct snd_pcm_substream * substream
|
||||
|
||||
dev->dmasound.rate = runtime->rate;
|
||||
|
||||
/* Setup and update the card/ALSA controls */
|
||||
snd_saa7134_capsrc_set(saa7134->capture_ctl[dev->dmasound.input], 1, 1,
|
||||
true);
|
||||
|
||||
return 0;
|
||||
|
||||
}
|
||||
@ -846,8 +962,13 @@ static int snd_saa7134_capsrc_get(struct snd_kcontrol * kcontrol,
|
||||
int addr = kcontrol->private_value;
|
||||
|
||||
spin_lock_irq(&chip->mixer_lock);
|
||||
ucontrol->value.integer.value[0] = chip->capture_source[addr][0];
|
||||
ucontrol->value.integer.value[1] = chip->capture_source[addr][1];
|
||||
if (chip->capture_source_addr == addr) {
|
||||
ucontrol->value.integer.value[0] = chip->capture_source[0];
|
||||
ucontrol->value.integer.value[1] = chip->capture_source[1];
|
||||
} else {
|
||||
ucontrol->value.integer.value[0] = 0;
|
||||
ucontrol->value.integer.value[1] = 0;
|
||||
}
|
||||
spin_unlock_irq(&chip->mixer_lock);
|
||||
|
||||
return 0;
|
||||
@ -856,87 +977,22 @@ static int snd_saa7134_capsrc_get(struct snd_kcontrol * kcontrol,
|
||||
static int snd_saa7134_capsrc_put(struct snd_kcontrol * kcontrol,
|
||||
struct snd_ctl_elem_value * ucontrol)
|
||||
{
|
||||
snd_card_saa7134_t *chip = snd_kcontrol_chip(kcontrol);
|
||||
int change, addr = kcontrol->private_value;
|
||||
int left, right;
|
||||
u32 anabar, xbarin;
|
||||
int analog_io, rate;
|
||||
struct saa7134_dev *dev;
|
||||
|
||||
dev = chip->dev;
|
||||
|
||||
left = ucontrol->value.integer.value[0] & 1;
|
||||
right = ucontrol->value.integer.value[1] & 1;
|
||||
spin_lock_irq(&chip->mixer_lock);
|
||||
|
||||
change = chip->capture_source[addr][0] != left ||
|
||||
chip->capture_source[addr][1] != right;
|
||||
chip->capture_source[addr][0] = left;
|
||||
chip->capture_source[addr][1] = right;
|
||||
dev->dmasound.input=addr;
|
||||
spin_unlock_irq(&chip->mixer_lock);
|
||||
|
||||
|
||||
if (change) {
|
||||
switch (dev->pci->device) {
|
||||
|
||||
case PCI_DEVICE_ID_PHILIPS_SAA7134:
|
||||
switch (addr) {
|
||||
case MIXER_ADDR_TVTUNER:
|
||||
saa_andorb(SAA7134_AUDIO_FORMAT_CTRL, 0xc0, 0xc0);
|
||||
saa_andorb(SAA7134_SIF_SAMPLE_FREQ, 0x03, 0x00);
|
||||
break;
|
||||
case MIXER_ADDR_LINE1:
|
||||
case MIXER_ADDR_LINE2:
|
||||
analog_io = (MIXER_ADDR_LINE1 == addr) ? 0x00 : 0x08;
|
||||
rate = (32000 == dev->dmasound.rate) ? 0x01 : 0x03;
|
||||
saa_andorb(SAA7134_ANALOG_IO_SELECT, 0x08, analog_io);
|
||||
saa_andorb(SAA7134_AUDIO_FORMAT_CTRL, 0xc0, 0x80);
|
||||
saa_andorb(SAA7134_SIF_SAMPLE_FREQ, 0x03, rate);
|
||||
break;
|
||||
}
|
||||
|
||||
break;
|
||||
case PCI_DEVICE_ID_PHILIPS_SAA7133:
|
||||
case PCI_DEVICE_ID_PHILIPS_SAA7135:
|
||||
xbarin = 0x03; // adc
|
||||
anabar = 0;
|
||||
switch (addr) {
|
||||
case MIXER_ADDR_TVTUNER:
|
||||
xbarin = 0; // Demodulator
|
||||
anabar = 2; // DACs
|
||||
break;
|
||||
case MIXER_ADDR_LINE1:
|
||||
anabar = 0; // aux1, aux1
|
||||
break;
|
||||
case MIXER_ADDR_LINE2:
|
||||
anabar = 9; // aux2, aux2
|
||||
break;
|
||||
}
|
||||
|
||||
/* output xbar always main channel */
|
||||
saa_dsp_writel(dev, SAA7133_DIGITAL_OUTPUT_SEL1, 0xbbbb10);
|
||||
|
||||
if (left || right) { // We've got data, turn the input on
|
||||
saa_dsp_writel(dev, SAA7133_DIGITAL_INPUT_XBAR1, xbarin);
|
||||
saa_writel(SAA7133_ANALOG_IO_SELECT, anabar);
|
||||
} else {
|
||||
saa_dsp_writel(dev, SAA7133_DIGITAL_INPUT_XBAR1, 0);
|
||||
saa_writel(SAA7133_ANALOG_IO_SELECT, 0);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return change;
|
||||
return snd_saa7134_capsrc_set(kcontrol, left, right, false);
|
||||
}
|
||||
|
||||
static struct snd_kcontrol_new snd_saa7134_controls[] = {
|
||||
static struct snd_kcontrol_new snd_saa7134_volume_controls[] = {
|
||||
SAA713x_VOLUME("Video Volume", 0, MIXER_ADDR_TVTUNER),
|
||||
SAA713x_CAPSRC("Video Capture Switch", 0, MIXER_ADDR_TVTUNER),
|
||||
SAA713x_VOLUME("Line Volume", 1, MIXER_ADDR_LINE1),
|
||||
SAA713x_CAPSRC("Line Capture Switch", 1, MIXER_ADDR_LINE1),
|
||||
SAA713x_VOLUME("Line Volume", 2, MIXER_ADDR_LINE2),
|
||||
};
|
||||
|
||||
static struct snd_kcontrol_new snd_saa7134_capture_controls[] = {
|
||||
SAA713x_CAPSRC("Video Capture Switch", 0, MIXER_ADDR_TVTUNER),
|
||||
SAA713x_CAPSRC("Line Capture Switch", 1, MIXER_ADDR_LINE1),
|
||||
SAA713x_CAPSRC("Line Capture Switch", 2, MIXER_ADDR_LINE2),
|
||||
};
|
||||
|
||||
@ -951,17 +1007,33 @@ SAA713x_CAPSRC("Line Capture Switch", 2, MIXER_ADDR_LINE2),
|
||||
static int snd_card_saa7134_new_mixer(snd_card_saa7134_t * chip)
|
||||
{
|
||||
struct snd_card *card = chip->card;
|
||||
struct snd_kcontrol *kcontrol;
|
||||
unsigned int idx;
|
||||
int err;
|
||||
int err, addr;
|
||||
|
||||
if (snd_BUG_ON(!chip))
|
||||
return -EINVAL;
|
||||
strcpy(card->mixername, "SAA7134 Mixer");
|
||||
|
||||
for (idx = 0; idx < ARRAY_SIZE(snd_saa7134_controls); idx++) {
|
||||
if ((err = snd_ctl_add(card, snd_ctl_new1(&snd_saa7134_controls[idx], chip))) < 0)
|
||||
for (idx = 0; idx < ARRAY_SIZE(snd_saa7134_volume_controls); idx++) {
|
||||
kcontrol = snd_ctl_new1(&snd_saa7134_volume_controls[idx],
|
||||
chip);
|
||||
err = snd_ctl_add(card, kcontrol);
|
||||
if (err < 0)
|
||||
return err;
|
||||
}
|
||||
|
||||
for (idx = 0; idx < ARRAY_SIZE(snd_saa7134_capture_controls); idx++) {
|
||||
kcontrol = snd_ctl_new1(&snd_saa7134_capture_controls[idx],
|
||||
chip);
|
||||
addr = snd_saa7134_capture_controls[idx].private_value;
|
||||
chip->capture_ctl[addr] = kcontrol;
|
||||
err = snd_ctl_add(card, kcontrol);
|
||||
if (err < 0)
|
||||
return err;
|
||||
}
|
||||
|
||||
chip->capture_source_addr = MIXER_ADDR_UNSELECTED;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user