summaryrefslogtreecommitdiffstats
path: root/sound/pci/oxygen
diff options
context:
space:
mode:
authorClemens Ladisch <clemens@ladisch.de>2008-04-09 09:16:14 +0200
committerTakashi Iwai <tiwai@suse.de>2008-04-24 12:00:32 +0200
commit11864b4b84194b459fc20e0ec47906885bddb12e (patch)
treecd50f762af2aa05c25657ee7d5486a2b67d66a52 /sound/pci/oxygen
parenta9d3cc485e65a56edc9ef78c034146cc8a5b3101 (diff)
downloadlinux-11864b4b84194b459fc20e0ec47906885bddb12e.tar.bz2
[ALSA] virtuoso: correctly switch input jack on Xonar DX
When selecting the capture source on the Xonar DX, the input jack must be routed to either the line input or the microphone input by setting a GPIO pin. This requires an additional callback so that the model driver can hook into the toggling of AC97 switches. Signed-off-by: Clemens Ladisch <clemens@ladisch.de> Signed-off-by: Takashi Iwai <tiwai@suse.de>
Diffstat (limited to 'sound/pci/oxygen')
-rw-r--r--sound/pci/oxygen/oxygen.h2
-rw-r--r--sound/pci/oxygen/oxygen_mixer.c4
-rw-r--r--sound/pci/oxygen/virtuoso.c22
3 files changed, 24 insertions, 4 deletions
diff --git a/sound/pci/oxygen/oxygen.h b/sound/pci/oxygen/oxygen.h
index d53c18c6fcd8..7efbf54bc4ec 100644
--- a/sound/pci/oxygen/oxygen.h
+++ b/sound/pci/oxygen/oxygen.h
@@ -98,6 +98,8 @@ struct oxygen_model {
void (*update_dac_volume)(struct oxygen *chip);
void (*update_dac_mute)(struct oxygen *chip);
void (*gpio_changed)(struct oxygen *chip);
+ void (*ac97_switch)(struct oxygen *chip,
+ unsigned int reg, unsigned int mute);
size_t model_data_size;
unsigned int pcm_dev_cfg;
u8 dac_channels;
diff --git a/sound/pci/oxygen/oxygen_mixer.c b/sound/pci/oxygen/oxygen_mixer.c
index 9a7c880eddbd..d0bef09a6999 100644
--- a/sound/pci/oxygen/oxygen_mixer.c
+++ b/sound/pci/oxygen/oxygen_mixer.c
@@ -518,6 +518,8 @@ static void mute_ac97_ctl(struct oxygen *chip, unsigned int control)
value = oxygen_read_ac97(chip, 0, priv_idx);
if (!(value & 0x8000)) {
oxygen_write_ac97(chip, 0, priv_idx, value | 0x8000);
+ if (chip->model->ac97_switch)
+ chip->model->ac97_switch(chip, priv_idx, 0x8000);
snd_ctl_notify(chip->card, SNDRV_CTL_EVENT_MASK_VALUE,
&chip->controls[control]->id);
}
@@ -544,6 +546,8 @@ static int ac97_switch_put(struct snd_kcontrol *ctl,
change = newreg != oldreg;
if (change) {
oxygen_write_ac97(chip, codec, index, newreg);
+ if (codec == 0 && chip->model->ac97_switch)
+ chip->model->ac97_switch(chip, index, newreg & 0x8000);
if (index == AC97_LINE) {
oxygen_write_ac97_masked(chip, 0, CM9780_GPIO_STATUS,
newreg & 0x8000 ?
diff --git a/sound/pci/oxygen/virtuoso.c b/sound/pci/oxygen/virtuoso.c
index 1db4aa5dfad4..b678e2de4adf 100644
--- a/sound/pci/oxygen/virtuoso.c
+++ b/sound/pci/oxygen/virtuoso.c
@@ -47,10 +47,10 @@
* GPI 0 <- external power present
*
* GPIO 0 -> enable output to speakers
- * GPIO 1 -> ALT?
+ * GPIO 1 -> ?
* GPIO 2 -> M0 of CS5361
* GPIO 3 -> M1 of CS5361
- * GPIO 8 -> line-in/mic-in/digital-out switch?
+ * GPIO 8 -> route input jack to line-in (0) or mic-in (1)
*
* CS4398:
*
@@ -120,7 +120,7 @@ MODULE_DEVICE_TABLE(pci, xonar_ids);
#define GPI_DX_EXT_POWER 0x01
#define GPIO_DX_OUTPUT_ENABLE 0x0001
#define GPIO_DX_UNKNOWN1 0x0002
-#define GPIO_DX_UNKNOWN2 0x0100
+#define GPIO_DX_INPUT_ROUTE 0x0100
#define I2C_DEVICE_CS4398 0x9e /* 10011, AD1=1, AD0=1, /W=0 */
#define I2C_DEVICE_CS4362A 0x30 /* 001100, AD0=0, /W=0 */
@@ -267,7 +267,8 @@ static void xonar_dx_init(struct oxygen *chip)
cs4362a_write(chip, 0x01, CS4362A_CPEN);
oxygen_set_bits16(chip, OXYGEN_GPIO_CONTROL,
- GPIO_DX_UNKNOWN1 | GPIO_DX_UNKNOWN2);
+ GPIO_DX_UNKNOWN1 | GPIO_DX_INPUT_ROUTE);
+ oxygen_clear_bits16(chip, OXYGEN_GPIO_DATA, GPIO_DX_INPUT_ROUTE);
xonar_common_init(chip);
@@ -469,6 +470,18 @@ static const struct snd_kcontrol_new alt_switch = {
.put = alt_switch_put,
};
+static void xonar_dx_ac97_switch(struct oxygen *chip,
+ unsigned int reg, unsigned int mute)
+{
+ if (reg == AC97_LINE) {
+ spin_lock_irq(&chip->reg_lock);
+ oxygen_write16_masked(chip, OXYGEN_GPIO_DATA,
+ mute ? GPIO_DX_INPUT_ROUTE : 0,
+ GPIO_DX_INPUT_ROUTE);
+ spin_unlock_irq(&chip->reg_lock);
+ }
+}
+
static const DECLARE_TLV_DB_SCALE(pcm1796_db_scale, -12000, 50, 0);
static const DECLARE_TLV_DB_SCALE(cs4362a_db_scale, -12700, 100, 0);
@@ -572,6 +585,7 @@ static const struct oxygen_model xonar_models[] = {
.update_dac_volume = update_cs43xx_volume,
.update_dac_mute = update_cs43xx_mute,
.gpio_changed = xonar_gpio_changed,
+ .ac97_switch = xonar_dx_ac97_switch,
.model_data_size = sizeof(struct xonar_data),
.pcm_dev_cfg = PLAYBACK_0_TO_I2S |
PLAYBACK_1_TO_SPDIF |