From 902b05c117c33c50075b21c293bf60958dedb92d Mon Sep 17 00:00:00 2001 From: Clemens Ladisch Date: Fri, 22 Feb 2008 18:40:56 +0100 Subject: [PATCH] [ALSA] oxygen: fix line-in recording selection The GPIO pin 0 of the CM9780 must be set when muting the line input even on non-Xonar cards. Signed-off-by: Clemens Ladisch Signed-off-by: Takashi Iwai Signed-off-by: Linus Torvalds --- sound/pci/oxygen/oxygen.c | 35 +++++++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) diff --git a/sound/pci/oxygen/oxygen.c b/sound/pci/oxygen/oxygen.c index f31a0eb409..9a9941bb04 100644 --- a/sound/pci/oxygen/oxygen.c +++ b/sound/pci/oxygen/oxygen.c @@ -28,7 +28,9 @@ * GPIO 1 -> DFS1 of AK5385 */ +#include #include +#include #include #include #include @@ -37,6 +39,7 @@ #include #include "oxygen.h" #include "ak4396.h" +#include "cm9780.h" MODULE_AUTHOR("Clemens Ladisch "); MODULE_DESCRIPTION("C-Media CMI8788 driver"); @@ -75,6 +78,8 @@ MODULE_DEVICE_TABLE(pci, oxygen_ids); #define GPIO_AK5385_DFS_DOUBLE 0x0001 #define GPIO_AK5385_DFS_QUAD 0x0002 +#define GPIO_LINE_MUTE CM9780_GPO0 + #define WM8785_R0 0 #define WM8785_R1 1 #define WM8785_R2 2 @@ -180,16 +185,23 @@ static void wm8785_init(struct oxygen *chip) snd_component_add(chip->card, "WM8785"); } +static void cmi9780_init(struct oxygen *chip) +{ + oxygen_ac97_clear_bits(chip, 0, CM9780_GPIO_STATUS, GPIO_LINE_MUTE); +} + static void generic_init(struct oxygen *chip) { ak4396_init(chip); wm8785_init(chip); + cmi9780_init(chip); } static void meridian_init(struct oxygen *chip) { ak4396_init(chip); ak5385_init(chip); + cmi9780_init(chip); } static void generic_cleanup(struct oxygen *chip) @@ -285,6 +297,27 @@ static void set_ak5385_params(struct oxygen *chip, value, GPIO_AK5385_DFS_MASK); } +static void cmi9780_switch_hook(struct oxygen *chip, unsigned int codec, + unsigned int reg, int mute) +{ + if (codec != 0) + return; + switch (reg) { + case AC97_LINE: + oxygen_write_ac97_masked(chip, 0, CM9780_GPIO_STATUS, + mute ? GPIO_LINE_MUTE : 0, + GPIO_LINE_MUTE); + break; + case AC97_MIC: + case AC97_CD: + case AC97_AUX: + if (!mute) + oxygen_ac97_set_bits(chip, 0, CM9780_GPIO_STATUS, + GPIO_LINE_MUTE); + break; + } +} + static const DECLARE_TLV_DB_LINEAR(ak4396_db_scale, TLV_DB_GAIN_MUTE, 0); static int ak4396_control_filter(struct snd_kcontrol_new *template) @@ -308,6 +341,7 @@ static const struct oxygen_model model_generic = { .set_adc_params = set_wm8785_params, .update_dac_volume = update_ak4396_volume, .update_dac_mute = update_ak4396_mute, + .ac97_switch_hook = cmi9780_switch_hook, .model_data_size = sizeof(struct generic_data), .dac_channels = 8, .used_channels = OXYGEN_CHANNEL_A | @@ -331,6 +365,7 @@ static const struct oxygen_model model_meridian = { .set_adc_params = set_ak5385_params, .update_dac_volume = update_ak4396_volume, .update_dac_mute = update_ak4396_mute, + .ac97_switch_hook = cmi9780_switch_hook, .model_data_size = sizeof(struct generic_data), .dac_channels = 8, .used_channels = OXYGEN_CHANNEL_B | -- 2.39.5