diff options
-rw-r--r-- | Documentation/sound/alsa/ALSA-Configuration.txt | 1 | ||||
-rw-r--r-- | sound/pci/hda/patch_realtek.c | 86 |
2 files changed, 87 insertions, 0 deletions
diff --git a/Documentation/sound/alsa/ALSA-Configuration.txt b/Documentation/sound/alsa/ALSA-Configuration.txt index fd4c32a031c9..0bbee38acd26 100644 --- a/Documentation/sound/alsa/ALSA-Configuration.txt +++ b/Documentation/sound/alsa/ALSA-Configuration.txt | |||
@@ -795,6 +795,7 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed. | |||
795 | lg-lw LG LW20/LW25 laptop | 795 | lg-lw LG LW20/LW25 laptop |
796 | tcl TCL S700 | 796 | tcl TCL S700 |
797 | clevo Clevo laptops (m520G, m665n) | 797 | clevo Clevo laptops (m520G, m665n) |
798 | medion Medion Rim 2150 | ||
798 | test for testing/debugging purpose, almost all controls can be | 799 | test for testing/debugging purpose, almost all controls can be |
799 | adjusted. Appearing only when compiled with | 800 | adjusted. Appearing only when compiled with |
800 | $CONFIG_SND_DEBUG=y | 801 | $CONFIG_SND_DEBUG=y |
diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index cdda64b02f46..d9783a4263e0 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c | |||
@@ -60,6 +60,7 @@ enum { | |||
60 | ALC880_TCL_S700, | 60 | ALC880_TCL_S700, |
61 | ALC880_LG, | 61 | ALC880_LG, |
62 | ALC880_LG_LW, | 62 | ALC880_LG_LW, |
63 | ALC880_MEDION_RIM, | ||
63 | #ifdef CONFIG_SND_DEBUG | 64 | #ifdef CONFIG_SND_DEBUG |
64 | ALC880_TEST, | 65 | ALC880_TEST, |
65 | #endif | 66 | #endif |
@@ -2275,6 +2276,75 @@ static void alc880_lg_lw_unsol_event(struct hda_codec *codec, unsigned int res) | |||
2275 | alc880_lg_lw_automute(codec); | 2276 | alc880_lg_lw_automute(codec); |
2276 | } | 2277 | } |
2277 | 2278 | ||
2279 | static struct snd_kcontrol_new alc880_medion_rim_mixer[] = { | ||
2280 | HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT), | ||
2281 | HDA_BIND_MUTE("Master Playback Switch", 0x0c, 2, HDA_INPUT), | ||
2282 | HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), | ||
2283 | HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), | ||
2284 | HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), | ||
2285 | HDA_CODEC_MUTE("Internal Playback Switch", 0x0b, 0x1, HDA_INPUT), | ||
2286 | { } /* end */ | ||
2287 | }; | ||
2288 | |||
2289 | static struct hda_input_mux alc880_medion_rim_capture_source = { | ||
2290 | .num_items = 2, | ||
2291 | .items = { | ||
2292 | { "Mic", 0x0 }, | ||
2293 | { "Internal Mic", 0x1 }, | ||
2294 | }, | ||
2295 | }; | ||
2296 | |||
2297 | static struct hda_verb alc880_medion_rim_init_verbs[] = { | ||
2298 | {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */ | ||
2299 | |||
2300 | {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, | ||
2301 | {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, | ||
2302 | |||
2303 | /* Mic1 (rear panel) pin widget for input and vref at 80% */ | ||
2304 | {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, | ||
2305 | {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, | ||
2306 | /* Mic2 (as headphone out) for HP output */ | ||
2307 | {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, | ||
2308 | {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, | ||
2309 | /* Internal Speaker */ | ||
2310 | {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, | ||
2311 | {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, | ||
2312 | |||
2313 | {0x20, AC_VERB_SET_COEF_INDEX, 0x07}, | ||
2314 | {0x20, AC_VERB_SET_PROC_COEF, 0x3060}, | ||
2315 | |||
2316 | {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, | ||
2317 | { } | ||
2318 | }; | ||
2319 | |||
2320 | /* toggle speaker-output according to the hp-jack state */ | ||
2321 | static void alc880_medion_rim_automute(struct hda_codec *codec) | ||
2322 | { | ||
2323 | unsigned int present; | ||
2324 | unsigned char bits; | ||
2325 | |||
2326 | present = snd_hda_codec_read(codec, 0x14, 0, | ||
2327 | AC_VERB_GET_PIN_SENSE, 0) | ||
2328 | & AC_PINSENSE_PRESENCE; | ||
2329 | bits = present ? HDA_AMP_MUTE : 0; | ||
2330 | snd_hda_codec_amp_stereo(codec, 0x1b, HDA_OUTPUT, 0, | ||
2331 | HDA_AMP_MUTE, bits); | ||
2332 | if (present) | ||
2333 | snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DATA, 0); | ||
2334 | else | ||
2335 | snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DATA, 2); | ||
2336 | } | ||
2337 | |||
2338 | static void alc880_medion_rim_unsol_event(struct hda_codec *codec, | ||
2339 | unsigned int res) | ||
2340 | { | ||
2341 | /* Looks like the unsol event is incompatible with the standard | ||
2342 | * definition. 4bit tag is placed at 28 bit! | ||
2343 | */ | ||
2344 | if ((res >> 28) == ALC880_HP_EVENT) | ||
2345 | alc880_medion_rim_automute(codec); | ||
2346 | } | ||
2347 | |||
2278 | #ifdef CONFIG_SND_HDA_POWER_SAVE | 2348 | #ifdef CONFIG_SND_HDA_POWER_SAVE |
2279 | static struct hda_amp_list alc880_loopbacks[] = { | 2349 | static struct hda_amp_list alc880_loopbacks[] = { |
2280 | { 0x0b, HDA_INPUT, 0 }, | 2350 | { 0x0b, HDA_INPUT, 0 }, |
@@ -2882,6 +2952,7 @@ static const char *alc880_models[ALC880_MODEL_LAST] = { | |||
2882 | [ALC880_F1734] = "F1734", | 2952 | [ALC880_F1734] = "F1734", |
2883 | [ALC880_LG] = "lg", | 2953 | [ALC880_LG] = "lg", |
2884 | [ALC880_LG_LW] = "lg-lw", | 2954 | [ALC880_LG_LW] = "lg-lw", |
2955 | [ALC880_MEDION_RIM] = "medion", | ||
2885 | #ifdef CONFIG_SND_DEBUG | 2956 | #ifdef CONFIG_SND_DEBUG |
2886 | [ALC880_TEST] = "test", | 2957 | [ALC880_TEST] = "test", |
2887 | #endif | 2958 | #endif |
@@ -2933,6 +3004,7 @@ static struct snd_pci_quirk alc880_cfg_tbl[] = { | |||
2933 | SND_PCI_QUIRK(0x1584, 0x9070, "Uniwill", ALC880_UNIWILL), | 3004 | SND_PCI_QUIRK(0x1584, 0x9070, "Uniwill", ALC880_UNIWILL), |
2934 | SND_PCI_QUIRK(0x1584, 0x9077, "Uniwill P53", ALC880_UNIWILL_P53), | 3005 | SND_PCI_QUIRK(0x1584, 0x9077, "Uniwill P53", ALC880_UNIWILL_P53), |
2935 | SND_PCI_QUIRK(0x161f, 0x203d, "W810", ALC880_W810), | 3006 | SND_PCI_QUIRK(0x161f, 0x203d, "W810", ALC880_W810), |
3007 | SND_PCI_QUIRK(0x161f, 0x205d, "Medion Rim 2150", ALC880_MEDION_RIM), | ||
2936 | SND_PCI_QUIRK(0x1695, 0x400d, "EPoX", ALC880_5ST_DIG), | 3008 | SND_PCI_QUIRK(0x1695, 0x400d, "EPoX", ALC880_5ST_DIG), |
2937 | SND_PCI_QUIRK(0x1695, 0x4012, "EPox EP-5LDA", ALC880_5ST_DIG), | 3009 | SND_PCI_QUIRK(0x1695, 0x4012, "EPox EP-5LDA", ALC880_5ST_DIG), |
2938 | SND_PCI_QUIRK(0x1734, 0x107c, "FSC F1734", ALC880_F1734), | 3010 | SND_PCI_QUIRK(0x1734, 0x107c, "FSC F1734", ALC880_F1734), |
@@ -3227,6 +3299,20 @@ static struct alc_config_preset alc880_presets[] = { | |||
3227 | .unsol_event = alc880_lg_lw_unsol_event, | 3299 | .unsol_event = alc880_lg_lw_unsol_event, |
3228 | .init_hook = alc880_lg_lw_automute, | 3300 | .init_hook = alc880_lg_lw_automute, |
3229 | }, | 3301 | }, |
3302 | [ALC880_MEDION_RIM] = { | ||
3303 | .mixers = { alc880_medion_rim_mixer }, | ||
3304 | .init_verbs = { alc880_volume_init_verbs, | ||
3305 | alc880_medion_rim_init_verbs, | ||
3306 | alc_gpio2_init_verbs }, | ||
3307 | .num_dacs = ARRAY_SIZE(alc880_dac_nids), | ||
3308 | .dac_nids = alc880_dac_nids, | ||
3309 | .dig_out_nid = ALC880_DIGOUT_NID, | ||
3310 | .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes), | ||
3311 | .channel_mode = alc880_2_jack_modes, | ||
3312 | .input_mux = &alc880_medion_rim_capture_source, | ||
3313 | .unsol_event = alc880_medion_rim_unsol_event, | ||
3314 | .init_hook = alc880_medion_rim_automute, | ||
3315 | }, | ||
3230 | #ifdef CONFIG_SND_DEBUG | 3316 | #ifdef CONFIG_SND_DEBUG |
3231 | [ALC880_TEST] = { | 3317 | [ALC880_TEST] = { |
3232 | .mixers = { alc880_test_mixer }, | 3318 | .mixers = { alc880_test_mixer }, |