From 4525c9f31f4606881ed49d822b44c2c5d6080ef4 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Tue, 13 Sep 2005 11:47:07 +0200 Subject: [ALSA] Fix surround control of CMI9761 Modules: AC97 Codec - Fixed surround controls of CMI9761 (model 83) in update_jacks callback. - Clean up ad1888 and ad1985 update_jacks callbacks. Signed-off-by: Takashi Iwai --- sound/pci/ac97/ac97_patch.c | 77 +++++++++++++++++++++++++++++---------------- 1 file changed, 50 insertions(+), 27 deletions(-) diff --git a/sound/pci/ac97/ac97_patch.c b/sound/pci/ac97/ac97_patch.c index 0238cc65d32a..ffc8d6521073 100644 --- a/sound/pci/ac97/ac97_patch.c +++ b/sound/pci/ac97/ac97_patch.c @@ -163,14 +163,24 @@ static int ac97_channel_mode_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t .private_value = 1, \ } +static inline int is_surround_on(ac97_t *ac97) +{ + return ac97->channel_mode >= 1; +} + +static inline int is_clfe_on(ac97_t *ac97) +{ + return a97->channel_mode >= 2; +} + static inline int is_shared_linein(ac97_t *ac97) { - return ! ac97->indep_surround && ac97->channel_mode >= 1; + return ! ac97->indep_surround && is_surround_on(ac97); } static inline int is_shared_micin(ac97_t *ac97) { - return ! ac97->indep_surround && ac97->channel_mode >= 2; + return ! ac97->indep_surround && is_clfe_on(ac97); } @@ -1753,12 +1763,13 @@ static int snd_ac97_ad1888_downmix_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_va static void ad1888_update_jacks(ac97_t *ac97) { + unsigned short val = 0; + if (! is_shared_linein(ac97)) + val |= (1 << 12); + if (! is_shared_micin(ac97)) + val |= (1 << 11); /* 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_MISC, (1 << 11) | (1 << 12), val); } static const snd_kcontrol_new_t snd_ac97_ad1888_controls[] = { @@ -1852,12 +1863,7 @@ static const snd_kcontrol_new_t snd_ac97_ad1985_controls[] = { 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); + ad1888_update_jacks(ac97); snd_ac97_update_bits(ac97, AC97_AD_SERIAL_CFG, 1 << 9, is_shared_micin(ac97) ? 0 : 1 << 9); } @@ -2442,21 +2448,37 @@ int patch_cm9739(ac97_t * ac97) static void cm9761_update_jacks(ac97_t *ac97) { - unsigned short surr_vals[2][2] = { - { 0x0008, 0x0400 }, /* off, on */ - { 0x0000, 0x0408 }, /* off, on (9761-82 rev.B) */ + /* FIXME: check the bits for each model + * model 83 is confirmed to work + */ + static unsigned short surr_on[3][2] = { + { 0x0008, 0x0000 }, /* 9761-78 & 82 */ + { 0x0000, 0x0008 }, /* 9761-82 rev.B */ + { 0x0000, 0x0008 }, /* 9761-83 */ + }; + static unsigned short clfe_on[3][2] = { + { 0x0000, 0x1000 }, /* 9761-78 & 82 */ + { 0x1000, 0x0000 }, /* 9761-82 rev.B */ + { 0x0000, 0x1000 }, /* 9761-83 */ + }; + static unsigned short surr_shared[3][2] = { + { 0x0000, 0x0400 }, /* 9761-78 & 82 */ + { 0x0000, 0x0400 }, /* 9761-82 rev.B */ + { 0x0000, 0x0400 }, /* 9761-83 */ }; - unsigned short clfe_vals[2][2] = { - { 0x2000, 0x1880 }, /* off, on */ - { 0x1000, 0x2880 }, /* off, on (9761-82 rev.B) */ + static unsigned short clfe_shared[3][2] = { + { 0x2000, 0x0880 }, /* 9761-78 & 82 */ + { 0x0000, 0x2880 }, /* 9761-82 rev.B */ + { 0x2000, 0x0800 }, /* 9761-83 */ }; + unsigned short val = 0; - /* shared Line-In */ - snd_ac97_update_bits(ac97, AC97_CM9761_MULTI_CHAN, 0x0408, - surr_vals[ac97->spec.dev_flags][is_shared_linein(ac97)]); - /* shared Mic */ - snd_ac97_update_bits(ac97, AC97_CM9761_MULTI_CHAN, 0x3880, - clfe_vals[ac97->spec.dev_flags][is_shared_micin(ac97)]); + val |= surr_on[ac97->spec.dev_flags][is_surround_on(ac97)]; + val |= clfe_on[ac97->spec.dev_flags][is_clfe_on(ac97)]; + val |= surr_shared[ac97->spec.dev_flags][is_shared_linein(ac97)]; + val |= clfe_shared[ac97->spec.dev_flags][is_shared_micin(ac97)]; + + snd_ac97_update_bits(ac97, AC97_CM9761_MULTI_CHAN, 0x3c88, val); } static const snd_kcontrol_new_t snd_ac97_cm9761_controls[] = { @@ -2551,7 +2573,7 @@ int patch_cm9761(ac97_t *ac97) snd_ac97_write_cache(ac97, AC97_MASTER, 0x8808); snd_ac97_write_cache(ac97, AC97_PCM, 0x8808); - ac97->spec.dev_flags = 0; /* 1 = model 82 revision B */ + ac97->spec.dev_flags = 0; /* 1 = model 82 revision B, 2 = model 83 */ if (ac97->id == AC97_ID_CM9761_82) { unsigned short tmp; /* check page 1, reg 0x60 */ @@ -2560,7 +2582,8 @@ int patch_cm9761(ac97_t *ac97) tmp = snd_ac97_read(ac97, 0x60); ac97->spec.dev_flags = tmp & 1; /* revision B? */ snd_ac97_write_cache(ac97, AC97_INT_PAGING, val); - } + } else if (ac97->id == AC97_ID_CM9761_83) + ac97->spec.dev_flags = 2; ac97->build_ops = &patch_cm9761_ops; -- cgit v1.2.2