diff options
| author | Einar Rünkaru <einarry@smail.ee> | 2009-11-23 15:23:49 -0500 |
|---|---|---|
| committer | Takashi Iwai <tiwai@suse.de> | 2009-11-24 03:01:48 -0500 |
| commit | 95a618bdac29c7b0f1a516aec9fc37626dec1af9 (patch) | |
| tree | 6a73f53909bac4f16d3db8c3b6ed3b62a4bb06f9 | |
| parent | 83dd7408b59c1945069199d712df8c7c64a76e1f (diff) | |
ALSA: hda - Make Dell Vostro 1015n mic and speaker switching work
Dell Vostro 1015n uses Conexant CX20583-10Z (0x14f1:5067). Patch is
based on "olpc-xo-1_5" branch. Dell uses digital mic.
Signed-off-by: Einar Rünkaru <einarry@smail.ee>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
| -rw-r--r-- | sound/pci/hda/patch_conexant.c | 134 |
1 files changed, 134 insertions, 0 deletions
diff --git a/sound/pci/hda/patch_conexant.c b/sound/pci/hda/patch_conexant.c index 0b097fa5421f..36dd5a6bf874 100644 --- a/sound/pci/hda/patch_conexant.c +++ b/sound/pci/hda/patch_conexant.c | |||
| @@ -2009,6 +2009,46 @@ static void cxt5066_automic(struct hda_codec *codec) | |||
| 2009 | } | 2009 | } |
| 2010 | } | 2010 | } |
| 2011 | 2011 | ||
| 2012 | /* toggle input of built-in digital mic and mic jack appropriately */ | ||
| 2013 | static void cxt5066_vostro_automic(struct hda_codec *codec) | ||
| 2014 | { | ||
| 2015 | struct conexant_spec *spec = codec->spec; | ||
| 2016 | unsigned int present; | ||
| 2017 | |||
| 2018 | struct hda_verb ext_mic_present[] = { | ||
| 2019 | /* enable external mic, port B */ | ||
| 2020 | {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, spec->ext_mic_bias}, | ||
| 2021 | |||
| 2022 | /* switch to external mic input */ | ||
| 2023 | {0x17, AC_VERB_SET_CONNECT_SEL, 0}, | ||
| 2024 | {0x14, AC_VERB_SET_CONNECT_SEL, 0}, | ||
| 2025 | |||
| 2026 | /* disable internal digital mic */ | ||
| 2027 | {0x23, AC_VERB_SET_PIN_WIDGET_CONTROL, 0}, | ||
| 2028 | {} | ||
| 2029 | }; | ||
| 2030 | static struct hda_verb ext_mic_absent[] = { | ||
| 2031 | /* enable internal mic, port C */ | ||
| 2032 | {0x23, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, | ||
| 2033 | |||
| 2034 | /* switch to internal mic input */ | ||
| 2035 | {0x14, AC_VERB_SET_CONNECT_SEL, 2}, | ||
| 2036 | |||
| 2037 | /* disable external mic, port B */ | ||
| 2038 | {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0}, | ||
| 2039 | {} | ||
| 2040 | }; | ||
| 2041 | |||
| 2042 | present = snd_hda_jack_detect(codec, 0x1a); | ||
| 2043 | if (present) { | ||
| 2044 | snd_printdd("CXT5066: external microphone detected\n"); | ||
| 2045 | snd_hda_sequence_write(codec, ext_mic_present); | ||
| 2046 | } else { | ||
| 2047 | snd_printdd("CXT5066: external microphone absent\n"); | ||
| 2048 | snd_hda_sequence_write(codec, ext_mic_absent); | ||
| 2049 | } | ||
| 2050 | } | ||
| 2051 | |||
| 2012 | /* mute internal speaker if HP is plugged */ | 2052 | /* mute internal speaker if HP is plugged */ |
| 2013 | static void cxt5066_hp_automute(struct hda_codec *codec) | 2053 | static void cxt5066_hp_automute(struct hda_codec *codec) |
| 2014 | { | 2054 | { |
| @@ -2041,6 +2081,20 @@ static void cxt5066_unsol_event(struct hda_codec *codec, unsigned int res) | |||
| 2041 | } | 2081 | } |
| 2042 | } | 2082 | } |
| 2043 | 2083 | ||
| 2084 | /* unsolicited event for jack sensing */ | ||
| 2085 | static void cxt5066_vostro_event(struct hda_codec *codec, unsigned int res) | ||
| 2086 | { | ||
| 2087 | snd_printdd("CXT5066_vostro: unsol event %x (%x)\n", res, res >> 26); | ||
| 2088 | switch (res >> 26) { | ||
| 2089 | case CONEXANT_HP_EVENT: | ||
| 2090 | cxt5066_hp_automute(codec); | ||
| 2091 | break; | ||
| 2092 | case CONEXANT_MIC_EVENT: | ||
| 2093 | cxt5066_vostro_automic(codec); | ||
| 2094 | break; | ||
| 2095 | } | ||
| 2096 | } | ||
| 2097 | |||
| 2044 | static const struct hda_input_mux cxt5066_analog_mic_boost = { | 2098 | static const struct hda_input_mux cxt5066_analog_mic_boost = { |
| 2045 | .num_items = 5, | 2099 | .num_items = 5, |
| 2046 | .items = { | 2100 | .items = { |
| @@ -2282,6 +2336,67 @@ static struct hda_verb cxt5066_init_verbs_olpc[] = { | |||
| 2282 | { } /* end */ | 2336 | { } /* end */ |
| 2283 | }; | 2337 | }; |
| 2284 | 2338 | ||
| 2339 | static struct hda_verb cxt5066_init_verbs_vostro[] = { | ||
| 2340 | /* Port A: headphones */ | ||
| 2341 | {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0}, | ||
| 2342 | {0x19, AC_VERB_SET_CONNECT_SEL, 0x00}, /* DAC1 */ | ||
| 2343 | |||
| 2344 | /* Port B: external microphone */ | ||
| 2345 | {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0}, | ||
| 2346 | |||
| 2347 | /* Port C: unused */ | ||
| 2348 | {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0}, | ||
| 2349 | |||
| 2350 | /* Port D: unused */ | ||
| 2351 | {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0}, | ||
| 2352 | |||
| 2353 | /* Port E: unused, but has primary EAPD */ | ||
| 2354 | {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0}, | ||
| 2355 | {0x1d, AC_VERB_SET_EAPD_BTLENABLE, 0x2}, /* default on */ | ||
| 2356 | |||
| 2357 | /* Port F: unused */ | ||
| 2358 | {0x1e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0}, | ||
| 2359 | |||
| 2360 | /* Port G: internal speakers */ | ||
| 2361 | {0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, | ||
| 2362 | {0x1f, AC_VERB_SET_CONNECT_SEL, 0x00}, /* DAC1 */ | ||
| 2363 | |||
| 2364 | /* DAC1 */ | ||
| 2365 | {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, | ||
| 2366 | |||
| 2367 | /* DAC2: unused */ | ||
| 2368 | {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, | ||
| 2369 | |||
| 2370 | {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, | ||
| 2371 | {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, | ||
| 2372 | {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, | ||
| 2373 | {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, | ||
| 2374 | {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, | ||
| 2375 | {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, | ||
| 2376 | {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, | ||
| 2377 | {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, | ||
| 2378 | {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, | ||
| 2379 | {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, | ||
| 2380 | {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, | ||
| 2381 | {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, | ||
| 2382 | |||
| 2383 | /* Digital microphone port */ | ||
| 2384 | {0x23, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, | ||
| 2385 | |||
| 2386 | /* Audio input selectors */ | ||
| 2387 | {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE | 0x3}, | ||
| 2388 | {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE }, | ||
| 2389 | |||
| 2390 | /* Disable SPDIF */ | ||
| 2391 | {0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0}, | ||
| 2392 | {0x22, AC_VERB_SET_PIN_WIDGET_CONTROL, 0}, | ||
| 2393 | |||
| 2394 | /* enable unsolicited events for Port A and B */ | ||
| 2395 | {0x19, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | CONEXANT_HP_EVENT}, | ||
| 2396 | {0x1a, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | CONEXANT_MIC_EVENT}, | ||
| 2397 | { } /* end */ | ||
| 2398 | }; | ||
| 2399 | |||
| 2285 | static struct hda_verb cxt5066_init_verbs_portd_lo[] = { | 2400 | static struct hda_verb cxt5066_init_verbs_portd_lo[] = { |
| 2286 | {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, | 2401 | {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, |
| 2287 | { } /* end */ | 2402 | { } /* end */ |
| @@ -2303,6 +2418,7 @@ enum { | |||
| 2303 | CXT5066_LAPTOP, /* Laptops w/ EAPD support */ | 2418 | CXT5066_LAPTOP, /* Laptops w/ EAPD support */ |
| 2304 | CXT5066_DELL_LAPTOP, /* Dell Laptop */ | 2419 | CXT5066_DELL_LAPTOP, /* Dell Laptop */ |
| 2305 | CXT5066_OLPC_XO_1_5, /* OLPC XO 1.5 */ | 2420 | CXT5066_OLPC_XO_1_5, /* OLPC XO 1.5 */ |
| 2421 | CXT5066_DELL_VOSTO, /* Dell Vostro 1015i */ | ||
| 2306 | CXT5066_MODELS | 2422 | CXT5066_MODELS |
| 2307 | }; | 2423 | }; |
| 2308 | 2424 | ||
| @@ -2310,6 +2426,7 @@ static const char *cxt5066_models[CXT5066_MODELS] = { | |||
| 2310 | [CXT5066_LAPTOP] = "laptop", | 2426 | [CXT5066_LAPTOP] = "laptop", |
| 2311 | [CXT5066_DELL_LAPTOP] = "dell-laptop", | 2427 | [CXT5066_DELL_LAPTOP] = "dell-laptop", |
| 2312 | [CXT5066_OLPC_XO_1_5] = "olpc-xo-1_5", | 2428 | [CXT5066_OLPC_XO_1_5] = "olpc-xo-1_5", |
| 2429 | [CXT5066_DELL_VOSTO] = "dell-vostro" | ||
| 2313 | }; | 2430 | }; |
| 2314 | 2431 | ||
| 2315 | static struct snd_pci_quirk cxt5066_cfg_tbl[] = { | 2432 | static struct snd_pci_quirk cxt5066_cfg_tbl[] = { |
| @@ -2318,6 +2435,7 @@ static struct snd_pci_quirk cxt5066_cfg_tbl[] = { | |||
| 2318 | SND_PCI_QUIRK(0x1028, 0x02f5, "Dell", | 2435 | SND_PCI_QUIRK(0x1028, 0x02f5, "Dell", |
| 2319 | CXT5066_DELL_LAPTOP), | 2436 | CXT5066_DELL_LAPTOP), |
| 2320 | SND_PCI_QUIRK(0x152d, 0x0833, "OLPC XO-1.5", CXT5066_OLPC_XO_1_5), | 2437 | SND_PCI_QUIRK(0x152d, 0x0833, "OLPC XO-1.5", CXT5066_OLPC_XO_1_5), |
| 2438 | SND_PCI_QUIRK(0x1028, 0x0402, "Dell Vostro", CXT5066_DELL_VOSTO), | ||
| 2321 | {} | 2439 | {} |
| 2322 | }; | 2440 | }; |
| 2323 | 2441 | ||
| @@ -2385,6 +2503,19 @@ static int patch_cxt5066(struct hda_codec *codec) | |||
| 2385 | /* input source automatically selected */ | 2503 | /* input source automatically selected */ |
| 2386 | spec->input_mux = NULL; | 2504 | spec->input_mux = NULL; |
| 2387 | break; | 2505 | break; |
| 2506 | case CXT5066_DELL_VOSTO: | ||
| 2507 | codec->patch_ops.unsol_event = cxt5066_vostro_event; | ||
| 2508 | spec->init_verbs[0] = cxt5066_init_verbs_vostro; | ||
| 2509 | spec->mixers[spec->num_mixers++] = cxt5066_mixer_master_olpc; | ||
| 2510 | spec->mixers[spec->num_mixers++] = cxt5066_mixers; | ||
| 2511 | spec->port_d_mode = 0; | ||
| 2512 | |||
| 2513 | /* no S/PDIF out */ | ||
| 2514 | spec->multiout.dig_out_nid = 0; | ||
| 2515 | |||
| 2516 | /* input source automatically selected */ | ||
| 2517 | spec->input_mux = NULL; | ||
| 2518 | break; | ||
| 2388 | } | 2519 | } |
| 2389 | 2520 | ||
| 2390 | return 0; | 2521 | return 0; |
| @@ -2402,6 +2533,8 @@ static struct hda_codec_preset snd_hda_preset_conexant[] = { | |||
| 2402 | .patch = patch_cxt5051 }, | 2533 | .patch = patch_cxt5051 }, |
| 2403 | { .id = 0x14f15066, .name = "CX20582 (Pebble)", | 2534 | { .id = 0x14f15066, .name = "CX20582 (Pebble)", |
| 2404 | .patch = patch_cxt5066 }, | 2535 | .patch = patch_cxt5066 }, |
| 2536 | { .id = 0x14f15067, .name = "CX20583 (Pebble HSF)", | ||
| 2537 | .patch = patch_cxt5066 }, | ||
| 2405 | {} /* terminator */ | 2538 | {} /* terminator */ |
| 2406 | }; | 2539 | }; |
| 2407 | 2540 | ||
| @@ -2409,6 +2542,7 @@ MODULE_ALIAS("snd-hda-codec-id:14f15045"); | |||
| 2409 | MODULE_ALIAS("snd-hda-codec-id:14f15047"); | 2542 | MODULE_ALIAS("snd-hda-codec-id:14f15047"); |
| 2410 | MODULE_ALIAS("snd-hda-codec-id:14f15051"); | 2543 | MODULE_ALIAS("snd-hda-codec-id:14f15051"); |
| 2411 | MODULE_ALIAS("snd-hda-codec-id:14f15066"); | 2544 | MODULE_ALIAS("snd-hda-codec-id:14f15066"); |
| 2545 | MODULE_ALIAS("snd-hda-codec-id:14f15067"); | ||
| 2412 | 2546 | ||
| 2413 | MODULE_LICENSE("GPL"); | 2547 | MODULE_LICENSE("GPL"); |
| 2414 | MODULE_DESCRIPTION("Conexant HD-audio codec"); | 2548 | MODULE_DESCRIPTION("Conexant HD-audio codec"); |
