aboutsummaryrefslogtreecommitdiff
path: root/sound/pci
diff options
context:
space:
mode:
Diffstat (limited to 'sound/pci')
-rw-r--r--sound/pci/Kconfig13
-rw-r--r--sound/pci/ac97/ac97_codec.c96
-rw-r--r--sound/pci/ac97/ac97_patch.c588
-rw-r--r--sound/pci/ac97/ac97_patch.h1
-rw-r--r--sound/pci/ali5451/ali5451.c287
-rw-r--r--sound/pci/als4000.c4
-rw-r--r--sound/pci/atiixp.c6
-rw-r--r--sound/pci/atiixp_modem.c43
-rw-r--r--sound/pci/au88x0/au88x0.c2
-rw-r--r--sound/pci/azt3328.c2
-rw-r--r--sound/pci/bt87x.c6
-rw-r--r--sound/pci/ca0106/ca0106.h70
-rw-r--r--sound/pci/ca0106/ca0106_main.c211
-rw-r--r--sound/pci/ca0106/ca0106_mixer.c76
-rw-r--r--sound/pci/ca0106/ca0106_proc.c31
-rw-r--r--sound/pci/cmipci.c182
-rw-r--r--sound/pci/cs4281.c17
-rw-r--r--sound/pci/cs46xx/cs46xx.c2
-rw-r--r--sound/pci/cs46xx/cs46xx_lib.c18
-rw-r--r--sound/pci/emu10k1/emu10k1.c12
-rw-r--r--sound/pci/emu10k1/emu10k1_main.c227
-rw-r--r--sound/pci/emu10k1/emu10k1x.c8
-rw-r--r--sound/pci/emu10k1/emufx.c56
-rw-r--r--sound/pci/emu10k1/emumixer.c14
-rw-r--r--sound/pci/emu10k1/emupcm.c6
-rw-r--r--sound/pci/emu10k1/emuproc.c89
-rw-r--r--sound/pci/emu10k1/irq.c46
-rw-r--r--sound/pci/emu10k1/memory.c2
-rw-r--r--sound/pci/emu10k1/p16v.c383
-rw-r--r--sound/pci/ens1370.c24
-rw-r--r--sound/pci/es1938.c2
-rw-r--r--sound/pci/es1968.c29
-rw-r--r--sound/pci/fm801.c3
-rw-r--r--sound/pci/hda/Makefile2
-rw-r--r--sound/pci/hda/hda_codec.c206
-rw-r--r--sound/pci/hda/hda_codec.h33
-rw-r--r--sound/pci/hda/hda_generic.c14
-rw-r--r--sound/pci/hda/hda_intel.c125
-rw-r--r--sound/pci/hda/hda_local.h37
-rw-r--r--sound/pci/hda/hda_patch.h3
-rw-r--r--sound/pci/hda/hda_proc.c56
-rw-r--r--sound/pci/hda/patch_analog.c693
-rw-r--r--sound/pci/hda/patch_cmedia.c215
-rw-r--r--sound/pci/hda/patch_realtek.c2519
-rw-r--r--sound/pci/hda/patch_sigmatel.c1004
-rw-r--r--sound/pci/ice1712/amp.c30
-rw-r--r--sound/pci/ice1712/amp.h16
-rw-r--r--sound/pci/ice1712/ice1712.c2
-rw-r--r--sound/pci/ice1712/ice1712.h5
-rw-r--r--sound/pci/ice1712/ice1724.c2
-rw-r--r--sound/pci/ice1712/phase.c728
-rw-r--r--sound/pci/ice1712/phase.h19
-rw-r--r--sound/pci/ice1712/vt1720_mobo.c9
-rw-r--r--sound/pci/ice1712/vt1720_mobo.h4
-rw-r--r--sound/pci/intel8x0.c179
-rw-r--r--sound/pci/intel8x0m.c80
-rw-r--r--sound/pci/korg1212/korg1212.c2
-rw-r--r--sound/pci/maestro3.c248
-rw-r--r--sound/pci/mixart/mixart.c6
-rw-r--r--sound/pci/nm256/nm256.c18
-rw-r--r--sound/pci/rme32.c2
-rw-r--r--sound/pci/rme96.c2
-rw-r--r--sound/pci/rme9652/Makefile2
-rw-r--r--sound/pci/rme9652/hdsp.c98
-rw-r--r--sound/pci/rme9652/hdspm.c3671
-rw-r--r--sound/pci/rme9652/rme9652.c18
-rw-r--r--sound/pci/sonicvibes.c2
-rw-r--r--sound/pci/trident/trident.c5
-rw-r--r--sound/pci/trident/trident_main.c6
-rw-r--r--sound/pci/trident/trident_memory.c2
-rw-r--r--sound/pci/via82xx.c159
-rw-r--r--sound/pci/via82xx_modem.c51
-rw-r--r--sound/pci/vx222/vx222.c2
-rw-r--r--sound/pci/vx222/vx222_ops.c4
-rw-r--r--sound/pci/ymfpci/ymfpci.c2
-rw-r--r--sound/pci/ymfpci/ymfpci_main.c41
76 files changed, 10851 insertions, 2027 deletions
diff --git a/sound/pci/Kconfig b/sound/pci/Kconfig
index 428efdbd70a..6d7a00f34d8 100644
--- a/sound/pci/Kconfig
+++ b/sound/pci/Kconfig
@@ -274,6 +274,19 @@ config SND_HDSP
To compile this driver as a module, choose M here: the module
will be called snd-hdsp.
+config SND_HDSPM
+ tristate "RME Hammerfall DSP MADI"
+ depends on SND
+ select SND_HWDEP
+ select SND_RAWMIDI
+ select SND_PCM
+ help
+ Say Y here to include support for RME Hammerfall DSP MADI
+ soundcards.
+
+ To compile this driver as a module, choose M here: the module
+ will be called snd-hdspm.
+
config SND_TRIDENT
tristate "Trident 4D-Wave DX/NX; SiS 7018"
depends on SND
diff --git a/sound/pci/ac97/ac97_codec.c b/sound/pci/ac97/ac97_codec.c
index 0b024ec1f70..6983eea226d 100644
--- a/sound/pci/ac97/ac97_codec.c
+++ b/sound/pci/ac97/ac97_codec.c
@@ -120,6 +120,7 @@ static const ac97_codec_id_t snd_ac97_codec_ids[] = {
{ 0x414c4770, 0xfffffff0, "ALC203", NULL, NULL },
{ 0x434d4941, 0xffffffff, "CMI9738", patch_cm9738, NULL },
{ 0x434d4961, 0xffffffff, "CMI9739", patch_cm9739, NULL },
+{ 0x434d4969, 0xffffffff, "CMI9780", patch_cm9780, NULL },
{ 0x434d4978, 0xffffffff, "CMI9761", patch_cm9761, NULL },
{ 0x434d4982, 0xffffffff, "CMI9761", patch_cm9761, NULL },
{ 0x434d4983, 0xffffffff, "CMI9761", patch_cm9761, NULL },
@@ -149,7 +150,7 @@ static const ac97_codec_id_t snd_ac97_codec_ids[] = {
{ 0x4e534331, 0xffffffff, "LM4549", NULL, NULL },
{ 0x4e534350, 0xffffffff, "LM4550", NULL, NULL },
{ 0x50534304, 0xffffffff, "UCB1400", NULL, NULL },
-{ 0x53494c20, 0xffffffe0, "Si3036,8", NULL, mpatch_si3036 },
+{ 0x53494c20, 0xffffffe0, "Si3036,8", mpatch_si3036, mpatch_si3036, AC97_MODEM_PATCH },
{ 0x54524102, 0xffffffff, "TR28022", NULL, NULL },
{ 0x54524106, 0xffffffff, "TR28026", NULL, NULL },
{ 0x54524108, 0xffffffff, "TR28028", patch_tritech_tr28028, NULL }, // added by xin jin [07/09/99]
@@ -366,6 +367,7 @@ int snd_ac97_update(ac97_t *ac97, unsigned short reg, unsigned short value)
ac97->regs[reg] = value;
ac97->bus->ops->write(ac97, reg, value);
}
+ set_bit(reg, ac97->reg_accessed);
up(&ac97->reg_mutex);
return change;
}
@@ -409,6 +411,7 @@ int snd_ac97_update_bits_nolock(ac97_t *ac97, unsigned short reg,
ac97->regs[reg] = new;
ac97->bus->ops->write(ac97, reg, new);
}
+ set_bit(reg, ac97->reg_accessed);
return change;
}
@@ -462,12 +465,14 @@ int snd_ac97_get_enum_double(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * u
{
ac97_t *ac97 = snd_kcontrol_chip(kcontrol);
struct ac97_enum *e = (struct ac97_enum *)kcontrol->private_value;
- unsigned short val;
+ unsigned short val, bitmask;
+ for (bitmask = 1; bitmask < e->mask; bitmask <<= 1)
+ ;
val = snd_ac97_read_cache(ac97, e->reg);
- ucontrol->value.enumerated.item[0] = (val >> e->shift_l) & (e->mask - 1);
+ ucontrol->value.enumerated.item[0] = (val >> e->shift_l) & (bitmask - 1);
if (e->shift_l != e->shift_r)
- ucontrol->value.enumerated.item[1] = (val >> e->shift_r) & (e->mask - 1);
+ ucontrol->value.enumerated.item[1] = (val >> e->shift_r) & (bitmask - 1);
return 0;
}
@@ -477,17 +482,19 @@ int snd_ac97_put_enum_double(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * u
ac97_t *ac97 = snd_kcontrol_chip(kcontrol);
struct ac97_enum *e = (struct ac97_enum *)kcontrol->private_value;
unsigned short val;
- unsigned short mask;
+ unsigned short mask, bitmask;
+ for (bitmask = 1; bitmask < e->mask; bitmask <<= 1)
+ ;
if (ucontrol->value.enumerated.item[0] > e->mask - 1)
return -EINVAL;
val = ucontrol->value.enumerated.item[0] << e->shift_l;
- mask = (e->mask - 1) << e->shift_l;
+ mask = (bitmask - 1) << e->shift_l;
if (e->shift_l != e->shift_r) {
if (ucontrol->value.enumerated.item[1] > e->mask - 1)
return -EINVAL;
val |= ucontrol->value.enumerated.item[1] << e->shift_r;
- mask |= (e->mask - 1) << e->shift_r;
+ mask |= (bitmask - 1) << e->shift_r;
}
return snd_ac97_update_bits(ac97, e->reg, mask, val);
}
@@ -658,14 +665,14 @@ AC97_SINGLE("LFE Playback Switch", AC97_CENTER_LFE_MASTER, 15, 1, 1),
AC97_SINGLE("LFE Playback Volume", AC97_CENTER_LFE_MASTER, 8, 31, 1)
};
-static const snd_kcontrol_new_t snd_ac97_controls_surround[2] = {
-AC97_DOUBLE("Surround Playback Switch", AC97_SURROUND_MASTER, 15, 7, 1, 1),
-AC97_DOUBLE("Surround Playback Volume", AC97_SURROUND_MASTER, 8, 0, 31, 1),
-};
-
static const snd_kcontrol_new_t snd_ac97_control_eapd =
AC97_SINGLE("External Amplifier", AC97_POWERDOWN, 15, 1, 1);
+static const snd_kcontrol_new_t snd_ac97_controls_modem_switches[2] = {
+AC97_SINGLE("Off-hook Switch", AC97_GPIO_STATUS, 0, 1, 0),
+AC97_SINGLE("Caller ID Switch", AC97_GPIO_STATUS, 2, 1, 0)
+};
+
/* change the existing EAPD control as inverted */
static void set_inv_eapd(ac97_t *ac97, snd_kcontrol_t *kctl)
{
@@ -1071,10 +1078,15 @@ static void check_volume_resolution(ac97_t *ac97, int reg, unsigned char *lo_max
for (i = 0 ; i < ARRAY_SIZE(cbit); i++) {
unsigned short val;
snd_ac97_write(ac97, reg, 0x8080 | cbit[i] | (cbit[i] << 8));
+ /* Do the read twice due to buffers on some ac97 codecs.
+ * e.g. The STAC9704 returns exactly what you wrote the the register
+ * if you read it immediately. This causes the detect routine to fail.
+ */
val = snd_ac97_read(ac97, reg);
- if (! *lo_max && (val & cbit[i]))
+ val = snd_ac97_read(ac97, reg);
+ if (! *lo_max && (val & 0x7f) == cbit[i])
*lo_max = max[i];
- if (! *hi_max && (val & (cbit[i] << 8)))
+ if (! *hi_max && ((val >> 8) & 0x7f) == cbit[i])
*hi_max = max[i];
if (*lo_max && *hi_max)
break;
@@ -1526,13 +1538,25 @@ static int snd_ac97_mixer_build(ac97_t * ac97)
static int snd_ac97_modem_build(snd_card_t * card, ac97_t * ac97)
{
- /* TODO */
+ int err, idx;
+
//printk("AC97_GPIO_CFG = %x\n",snd_ac97_read(ac97,AC97_GPIO_CFG));
snd_ac97_write(ac97, AC97_GPIO_CFG, 0xffff & ~(AC97_GPIO_LINE1_OH));
snd_ac97_write(ac97, AC97_GPIO_POLARITY, 0xffff & ~(AC97_GPIO_LINE1_OH));
snd_ac97_write(ac97, AC97_GPIO_STICKY, 0xffff);
snd_ac97_write(ac97, AC97_GPIO_WAKEUP, 0x0);
snd_ac97_write(ac97, AC97_MISC_AFE, 0x0);
+
+ /* build modem switches */
+ for (idx = 0; idx < ARRAY_SIZE(snd_ac97_controls_modem_switches); idx++)
+ if ((err = snd_ctl_add(card, snd_ac97_cnew(&snd_ac97_controls_modem_switches[idx], ac97))) < 0)
+ return err;
+
+ /* build chip specific controls */
+ if (ac97->build_ops->build_specific)
+ if ((err = ac97->build_ops->build_specific(ac97)) < 0)
+ return err;
+
return 0;
}
@@ -1872,7 +1896,11 @@ int snd_ac97_mixer(ac97_bus_t *bus, ac97_template_t *template, ac97_t **rac97)
goto __access_ok;
}
- snd_ac97_write(ac97, AC97_RESET, 0); /* reset to defaults */
+ /* reset to defaults */
+ if (!(ac97->scaps & AC97_SCAP_SKIP_AUDIO))
+ snd_ac97_write(ac97, AC97_RESET, 0);
+ if (!(ac97->scaps & AC97_SCAP_SKIP_MODEM))
+ snd_ac97_write(ac97, AC97_EXTENDED_MID, 0);
if (bus->ops->wait)
bus->ops->wait(ac97);
else {
@@ -1964,21 +1992,21 @@ int snd_ac97_mixer(ac97_bus_t *bus, ac97_template_t *template, ac97_t **rac97)
/* note: it's important to set the rate at first */
tmp = AC97_MEA_GPIO;
if (ac97->ext_mid & AC97_MEI_LINE1) {
- snd_ac97_write_cache(ac97, AC97_LINE1_RATE, 12000);
+ snd_ac97_write_cache(ac97, AC97_LINE1_RATE, 8000);
tmp |= AC97_MEA_ADC1 | AC97_MEA_DAC1;
}
if (ac97->ext_mid & AC97_MEI_LINE2) {
- snd_ac97_write_cache(ac97, AC97_LINE2_RATE, 12000);
+ snd_ac97_write_cache(ac97, AC97_LINE2_RATE, 8000);
tmp |= AC97_MEA_ADC2 | AC97_MEA_DAC2;
}
if (ac97->ext_mid & AC97_MEI_HANDSET) {
- snd_ac97_write_cache(ac97, AC97_HANDSET_RATE, 12000);
+ snd_ac97_write_cache(ac97, AC97_HANDSET_RATE, 8000);
tmp |= AC97_MEA_HADC | AC97_MEA_HDAC;
}
- snd_ac97_write_cache(ac97, AC97_EXTENDED_MSTATUS, 0xff00 & ~(tmp << 8));
+ snd_ac97_write_cache(ac97, AC97_EXTENDED_MSTATUS, 0);
udelay(100);
/* nothing should be in powerdown mode */
- snd_ac97_write_cache(ac97, AC97_EXTENDED_MSTATUS, 0xff00 & ~(tmp << 8));
+ snd_ac97_write_cache(ac97, AC97_EXTENDED_MSTATUS, 0);
end_time = jiffies + (HZ / 10);
do {
if ((snd_ac97_read(ac97, AC97_EXTENDED_MSTATUS) & tmp) == tmp)
@@ -2203,7 +2231,7 @@ void snd_ac97_restore_iec958(ac97_t *ac97)
*/
void snd_ac97_resume(ac97_t *ac97)
{
- int i;
+ unsigned long end_time;
if (ac97->bus->ops->reset) {
ac97->bus->ops->reset(ac97);
@@ -2221,26 +2249,26 @@ void snd_ac97_resume(ac97_t *ac97)
snd_ac97_write(ac97, AC97_POWERDOWN, ac97->regs[AC97_POWERDOWN]);
if (ac97_is_audio(ac97)) {
ac97->bus->ops->write(ac97, AC97_MASTER, 0x8101);
- for (i = HZ/10; i >= 0; i--) {
+ end_time = jiffies + msecs_to_jiffies(100);
+ do {
if (snd_ac97_read(ac97, AC97_MASTER) == 0x8101)
break;
set_current_state(TASK_UNINTERRUPTIBLE);
schedule_timeout(1);
- }
+ } while (time_after_eq(end_time, jiffies));
/* FIXME: extra delay */
ac97->bus->ops->write(ac97, AC97_MASTER, 0x8000);
- if (snd_ac97_read(ac97, AC97_MASTER) != 0x8000) {
- set_current_state(TASK_UNINTERRUPTIBLE);
- schedule_timeout(HZ/4);
- }
+ if (snd_ac97_read(ac97, AC97_MASTER) != 0x8000)
+ msleep(250);
} else {
- for (i = HZ/10; i >= 0; i--) {
+ end_time = jiffies + msecs_to_jiffies(100);
+ do {
unsigned short val = snd_ac97_read(ac97, AC97_EXTENDED_MID);
if (val != 0xffff && (val & 1) != 0)
break;
set_current_state(TASK_UNINTERRUPTIBLE);
schedule_timeout(1);
- }
+ } while (time_after_eq(end_time, jiffies));
}
__reset_ready:
@@ -2521,11 +2549,11 @@ int snd_ac97_tune_hardware(ac97_t *ac97, struct ac97_quirk *quirk, const char *o
return result;
}
- for (; quirk->vendor; quirk++) {
- if (quirk->vendor != ac97->subsystem_vendor)
+ for (; quirk->subvendor; quirk++) {
+ if (quirk->subvendor != ac97->subsystem_vendor)
continue;
- if ((! quirk->mask && quirk->device == ac97->subsystem_device) ||
- quirk->device == (quirk->mask & ac97->subsystem_device)) {
+ if ((! quirk->mask && quirk->subdevice == ac97->subsystem_device) ||
+ quirk->subdevice == (quirk->mask & ac97->subsystem_device)) {
if (quirk->codec_id && quirk->codec_id != ac97->id)
continue;
snd_printdd("ac97 quirk for %s (%04x:%04x)\n", quirk->name, ac97->subsystem_vendor, ac97->subsystem_device);
diff --git a/sound/pci/ac97/ac97_patch.c b/sound/pci/ac97/ac97_patch.c
index 13c34a5d820..66edc857d3e 100644
--- a/sound/pci/ac97/ac97_patch.c
+++ b/sound/pci/ac97/ac97_patch.c
@@ -64,6 +64,116 @@ static int ac97_update_bits_page(ac97_t *ac97, unsigned short reg, unsigned shor
return ret;
}
+/*
+ * shared line-in/mic controls
+ */
+static int ac97_enum_text_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *uinfo,
+ const char **texts, unsigned int nums)
+{
+ uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
+ uinfo->count = 1;
+ uinfo->value.enumerated.items = nums;
+ if (uinfo->value.enumerated.item > nums - 1)
+ uinfo->value.enumerated.item = nums - 1;
+ strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
+ return 0;
+}
+
+static int ac97_surround_jack_mode_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *uinfo)
+{
+ static const char *texts[] = { "Shared", "Independent" };
+ return ac97_enum_text_info(kcontrol, uinfo, texts, 2);
+}
+
+static int ac97_surround_jack_mode_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
+{
+ ac97_t *ac97 = snd_kcontrol_chip(kcontrol);
+
+ ucontrol->value.enumerated.item[0] = ac97->indep_surround;
+ return 0;
+}
+
+static int ac97_surround_jack_mode_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
+{
+ ac97_t *ac97 = snd_kcontrol_chip(kcontrol);
+ unsigned char indep = !!ucontrol->value.enumerated.item[0];
+
+ if (indep != ac97->indep_surround) {
+ ac97->indep_surround = indep;
+ if (ac97->build_ops->update_jacks)
+ ac97->build_ops->update_jacks(ac97);
+ return 1;
+ }
+ return 0;
+}
+
+static int ac97_channel_mode_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *uinfo)
+{
+ static const char *texts[] = { "2ch", "4ch", "6ch" };
+ if (kcontrol->private_value)
+ return ac97_enum_text_info(kcontrol, uinfo, texts, 2); /* 4ch only */
+ return ac97_enum_text_info(kcontrol, uinfo, texts, 3);
+}
+
+static int ac97_channel_mode_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
+{
+ ac97_t *ac97 = snd_kcontrol_chip(kcontrol);
+
+ ucontrol->value.enumerated.item[0] = ac97->channel_mode;
+ return 0;
+}
+
+static int ac97_channel_mode_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
+{
+ ac97_t *ac97 = snd_kcontrol_chip(kcontrol);
+ unsigned char mode = ucontrol->value.enumerated.item[0];
+
+ if (mode != ac97->channel_mode) {
+ ac97->channel_mode = mode;
+ if (ac97->build_ops->update_jacks)
+ ac97->build_ops->update_jacks(ac97);
+ return 1;
+ }
+ return 0;
+}
+
+#define AC97_SURROUND_JACK_MODE_CTL \
+ { \
+ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
+ .name = "Surround Jack Mode", \
+ .info = ac97_surround_jack_mode_info, \
+ .get = ac97_surround_jack_mode_get, \
+ .put = ac97_surround_jack_mode_put, \
+ }
+#define AC97_CHANNEL_MODE_CTL \
+ { \
+ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
+ .name = "Channel Mode", \
+ .info = ac97_channel_mode_info, \
+ .get = ac97_channel_mode_get, \
+ .put = ac97_channel_mode_put, \
+ }
+#define AC97_CHANNEL_MODE_4CH_CTL \
+ { \
+ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
+ .name = "Channel Mode", \
+ .info = ac97_channel_mode_info, \
+ .get = ac97_channel_mode_get, \
+ .put = ac97_channel_mode_put, \
+ .private_value = 1, \
+ }
+
+static inline int is_shared_linein(ac97_t *ac97)
+{
+ return ! ac97->indep_surround && ac97->channel_mode >= 1;
+}
+
+static inline int is_shared_micin(ac97_t *ac97)
+{
+ return ! ac97->indep_surround && ac97->channel_mode >= 2;
+}
+
+
/* The following snd_ac97_ymf753_... items added by David Shust (dshust@shustring.com) */
/* It is possible to indicate to the Yamaha YMF753 the type of speakers being used. */
@@ -1390,6 +1500,16 @@ static int snd_ac97_ad1888_downmix_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_va
AC97_AD198X_DMIX0 | AC97_AD198X_DMIX1, val);
}
+static void ad1888_update_jacks(ac97_t *ac97)
+{
+ /* shared Line-In */
+ snd_ac97_update_bits(ac97, AC97_AD_MISC, 1 << 12,
+ is_shared_linein(ac97) ? 0 : 1 << 12);
+ /* shared Mic */
+ snd_ac97_update_bits(ac97, AC97_AD_MISC, 1 << 11,
+ is_shared_micin(ac97) ? 0 : 1 << 11);
+}
+
static const snd_kcontrol_new_t snd_ac97_ad1888_controls[] = {
{
.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
@@ -1406,8 +1526,11 @@ static const snd_kcontrol_new_t snd_ac97_ad1888_controls[] = {
.get = snd_ac97_ad1888_downmix_get,
.put = snd_ac97_ad1888_downmix_put
},
- AC97_SINGLE("Surround Jack as Input", AC97_AD_MISC, 12, 1, 0),
- AC97_SINGLE("Center/LFE Jack as Input", AC97_AD_MISC, 11, 1, 0),
+ AC97_SURROUND_JACK_MODE_CTL,
+ AC97_CHANNEL_MODE_CTL,
+
+ AC97_SINGLE("Headphone Jack Sense", AC97_AD_JACK_SPDIF, 10, 1, 0),
+ AC97_SINGLE("Line Jack Sense", AC97_AD_JACK_SPDIF, 12, 1, 0),
};
static int patch_ad1888_specific(ac97_t *ac97)
@@ -1422,8 +1545,9 @@ static struct snd_ac97_build_ops patch_ad1888_build_ops = {
.build_post_spdif = patch_ad198x_post_spdif,
.build_specific = patch_ad1888_specific,
#ifdef CONFIG_PM
- .resume = ad18xx_resume
+ .resume = ad18xx_resume,
#endif
+ .update_jacks = ad1888_update_jacks,
};
int patch_ad1888(ac97_t * ac97)
@@ -1459,8 +1583,9 @@ static struct snd_ac97_build_ops patch_ad1980_build_ops = {
.build_post_spdif = patch_ad198x_post_spdif,
.build_specific = patch_ad1980_specific,
#ifdef CONFIG_PM
- .resume = ad18xx_resume
+ .resume = ad18xx_resume,
#endif
+ .update_jacks = ad1888_update_jacks,
};
int patch_ad1980(ac97_t * ac97)
@@ -1471,10 +1596,21 @@ int patch_ad1980(ac97_t * ac97)
}
static const snd_kcontrol_new_t snd_ac97_ad1985_controls[] = {
- AC97_SINGLE("Center/LFE Jack as Mic", AC97_AD_SERIAL_CFG, 9, 1, 0),
AC97_SINGLE("Exchange Center/LFE", AC97_AD_SERIAL_CFG, 3, 1, 0)
};
+static void ad1985_update_jacks(ac97_t *ac97)
+{
+ /* shared Line-In */
+ snd_ac97_update_bits(ac97, AC97_AD_MISC, 1 << 12,
+ is_shared_linein(ac97) ? 0 : 1 << 12);
+ /* shared Mic */
+ snd_ac97_update_bits(ac97, AC97_AD_MISC, 1 << 11,
+ is_shared_micin(ac97) ? 0 : 1 << 11);
+ snd_ac97_update_bits(ac97, AC97_AD_SERIAL_CFG, 1 << 9,
+ is_shared_micin(ac97) ? 0 : 1 << 9);
+}
+
static int patch_ad1985_specific(ac97_t *ac97)
{
int err;
@@ -1488,8 +1624,9 @@ static struct snd_ac97_build_ops patch_ad1985_build_ops = {
.build_post_spdif = patch_ad198x_post_spdif,
.build_specific = patch_ad1985_specific,
#ifdef CONFIG_PM
- .resume = ad18xx_resume
+ .resume = ad18xx_resume,
#endif
+ .update_jacks = ad1985_update_jacks,
};
int patch_ad1985(ac97_t * ac97)
@@ -1521,31 +1658,25 @@ int patch_ad1985(ac97_t * ac97)
/*
* realtek ALC65x/850 codecs
*/
-static int snd_ac97_alc650_mic_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t * ucontrol)
-{
-