diff options
| author | Vitaliy Kulikov <Vitaliy.Kulikov@idt.com> | 2011-03-10 14:43:35 -0500 |
|---|---|---|
| committer | Takashi Iwai <tiwai@suse.de> | 2011-03-14 10:38:57 -0400 |
| commit | 699d899560cd7e72da39231e584412e7ac8114a4 (patch) | |
| tree | 71ccc46475ccb77b8669affa8c5aa6b1d412d482 | |
| parent | 094a42452abd5564429045e210281c6d22e67fca (diff) | |
ALSA: hda - pin-adc-mux-dmic auto-configuration of 92HD8X codecs
This patch replaces use of the harcoded arrays of pins, muxes, digital
mics and adcs with the auto-generated ones using codec parsing and
auto-discovers all actually connected digital mic pins on 92HD8X-like
codecs
This patch also adds the support for d-mic on pin 0x20.
Signed-off-by: Vitaliy Kulikov <Vitaliy.Kulikov@idt.com>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
| -rw-r--r-- | sound/pci/hda/patch_sigmatel.c | 222 |
1 files changed, 149 insertions, 73 deletions
diff --git a/sound/pci/hda/patch_sigmatel.c b/sound/pci/hda/patch_sigmatel.c index 32f744d47da7..05fcd60cc46f 100644 --- a/sound/pci/hda/patch_sigmatel.c +++ b/sound/pci/hda/patch_sigmatel.c | |||
| @@ -186,6 +186,10 @@ struct sigmatel_mic_route { | |||
| 186 | signed char dmux_idx; | 186 | signed char dmux_idx; |
| 187 | }; | 187 | }; |
| 188 | 188 | ||
| 189 | #define MAX_PINS_NUM 16 | ||
| 190 | #define MAX_ADCS_NUM 4 | ||
| 191 | #define MAX_DMICS_NUM 4 | ||
| 192 | |||
| 189 | struct sigmatel_spec { | 193 | struct sigmatel_spec { |
| 190 | struct snd_kcontrol_new *mixers[4]; | 194 | struct snd_kcontrol_new *mixers[4]; |
| 191 | unsigned int num_mixers; | 195 | unsigned int num_mixers; |
| @@ -300,6 +304,17 @@ struct sigmatel_spec { | |||
| 300 | struct hda_input_mux private_imux; | 304 | struct hda_input_mux private_imux; |
| 301 | struct hda_input_mux private_smux; | 305 | struct hda_input_mux private_smux; |
| 302 | struct hda_input_mux private_mono_mux; | 306 | struct hda_input_mux private_mono_mux; |
| 307 | |||
| 308 | /* auto spec */ | ||
| 309 | unsigned auto_pin_cnt; | ||
| 310 | hda_nid_t auto_pin_nids[MAX_PINS_NUM]; | ||
| 311 | unsigned auto_adc_cnt; | ||
| 312 | hda_nid_t auto_adc_nids[MAX_ADCS_NUM]; | ||
| 313 | hda_nid_t auto_mux_nids[MAX_ADCS_NUM]; | ||
| 314 | hda_nid_t auto_dmux_nids[MAX_ADCS_NUM]; | ||
| 315 | unsigned long auto_capvols[MAX_ADCS_NUM]; | ||
| 316 | unsigned auto_dmic_cnt; | ||
| 317 | hda_nid_t auto_dmic_nids[MAX_DMICS_NUM]; | ||
| 303 | }; | 318 | }; |
| 304 | 319 | ||
| 305 | static hda_nid_t stac9200_adc_nids[1] = { | 320 | static hda_nid_t stac9200_adc_nids[1] = { |
| @@ -355,14 +370,6 @@ static unsigned long stac92hd73xx_capvols[] = { | |||
| 355 | 370 | ||
| 356 | #define STAC92HD83_DAC_COUNT 3 | 371 | #define STAC92HD83_DAC_COUNT 3 |
| 357 | 372 | ||
| 358 | static hda_nid_t stac92hd83xxx_mux_nids[2] = { | ||
| 359 | 0x17, 0x18, | ||
| 360 | }; | ||
| 361 | |||
| 362 | static hda_nid_t stac92hd83xxx_adc_nids[2] = { | ||
| 363 | 0x15, 0x16, | ||
| 364 | }; | ||
| 365 | |||
| 366 | static hda_nid_t stac92hd83xxx_pwr_nids[4] = { | 373 | static hda_nid_t stac92hd83xxx_pwr_nids[4] = { |
| 367 | 0xa, 0xb, 0xd, 0xe, | 374 | 0xa, 0xb, 0xd, 0xe, |
| 368 | }; | 375 | }; |
| @@ -375,25 +382,9 @@ static unsigned int stac92hd83xxx_pwr_mapping[4] = { | |||
| 375 | 0x03, 0x0c, 0x20, 0x40, | 382 | 0x03, 0x0c, 0x20, 0x40, |
| 376 | }; | 383 | }; |
| 377 | 384 | ||
| 378 | #define STAC92HD83XXX_NUM_DMICS 2 | 385 | static hda_nid_t stac92hd83xxx_dmic_nids[] = { |
| 379 | static hda_nid_t stac92hd83xxx_dmic_nids[STAC92HD83XXX_NUM_DMICS + 1] = { | 386 | 0x11, 0x20, |
| 380 | 0x11, 0x20, 0 | ||
| 381 | }; | ||
| 382 | |||
| 383 | #define STAC92HD88XXX_NUM_DMICS STAC92HD83XXX_NUM_DMICS | ||
| 384 | #define stac92hd88xxx_dmic_nids stac92hd83xxx_dmic_nids | ||
| 385 | |||
| 386 | #define STAC92HD87B_NUM_DMICS 1 | ||
| 387 | static hda_nid_t stac92hd87b_dmic_nids[STAC92HD87B_NUM_DMICS + 1] = { | ||
| 388 | 0x11, 0 | ||
| 389 | }; | ||
| 390 | |||
| 391 | #define STAC92HD83XXX_NUM_CAPS 2 | ||
| 392 | static unsigned long stac92hd83xxx_capvols[] = { | ||
| 393 | HDA_COMPOSE_AMP_VAL(0x17, 3, 0, HDA_OUTPUT), | ||
| 394 | HDA_COMPOSE_AMP_VAL(0x18, 3, 0, HDA_OUTPUT), | ||
| 395 | }; | 387 | }; |
| 396 | #define stac92hd83xxx_capsws stac92hd83xxx_capvols | ||
| 397 | 388 | ||
| 398 | static hda_nid_t stac92hd71bxx_pwr_nids[3] = { | 389 | static hda_nid_t stac92hd71bxx_pwr_nids[3] = { |
| 399 | 0x0a, 0x0d, 0x0f | 390 | 0x0a, 0x0d, 0x0f |
| @@ -572,21 +563,6 @@ static hda_nid_t stac92hd73xx_pin_nids[13] = { | |||
| 572 | 0x14, 0x22, 0x23 | 563 | 0x14, 0x22, 0x23 |
| 573 | }; | 564 | }; |
| 574 | 565 | ||
| 575 | static hda_nid_t stac92hd83xxx_pin_nids[10] = { | ||
| 576 | 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, | ||
| 577 | 0x0f, 0x10, 0x11, 0x1f, 0x20, | ||
| 578 | }; | ||
| 579 | |||
| 580 | static hda_nid_t stac92hd87xxx_pin_nids[6] = { | ||
| 581 | 0x0a, 0x0b, 0x0c, 0x0d, | ||
| 582 | 0x0f, 0x11, | ||
| 583 | }; | ||
| 584 | |||
| 585 | static hda_nid_t stac92hd88xxx_pin_nids[8] = { | ||
| 586 | 0x0a, 0x0b, 0x0c, 0x0d, | ||
| 587 | 0x0f, 0x11, 0x1f, 0x20, | ||
| 588 | }; | ||
| 589 | |||
| 590 | #define STAC92HD71BXX_NUM_PINS 13 | 566 | #define STAC92HD71BXX_NUM_PINS 13 |
| 591 | static hda_nid_t stac92hd71bxx_pin_nids_4port[STAC92HD71BXX_NUM_PINS] = { | 567 | static hda_nid_t stac92hd71bxx_pin_nids_4port[STAC92HD71BXX_NUM_PINS] = { |
| 592 | 0x0a, 0x0b, 0x0c, 0x0d, 0x00, | 568 | 0x0a, 0x0b, 0x0c, 0x0d, 0x00, |
| @@ -3415,6 +3391,17 @@ static const char * const stac92xx_dmic_labels[5] = { | |||
| 3415 | "Digital Mic 3", "Digital Mic 4" | 3391 | "Digital Mic 3", "Digital Mic 4" |
| 3416 | }; | 3392 | }; |
| 3417 | 3393 | ||
| 3394 | static hda_nid_t get_connected_node(struct hda_codec *codec, hda_nid_t mux, | ||
| 3395 | int idx) | ||
| 3396 | { | ||
| 3397 | hda_nid_t conn[HDA_MAX_NUM_INPUTS]; | ||
| 3398 | int nums; | ||
| 3399 | nums = snd_hda_get_connections(codec, mux, conn, ARRAY_SIZE(conn)); | ||
| 3400 | if (idx >= 0 && idx < nums) | ||
| 3401 | return conn[idx]; | ||
| 3402 | return 0; | ||
| 3403 | } | ||
| 3404 | |||
| 3418 | static int get_connection_index(struct hda_codec *codec, hda_nid_t mux, | 3405 | static int get_connection_index(struct hda_codec *codec, hda_nid_t mux, |
| 3419 | hda_nid_t nid) | 3406 | hda_nid_t nid) |
| 3420 | { | 3407 | { |
| @@ -3425,6 +3412,15 @@ static int get_connection_index(struct hda_codec *codec, hda_nid_t mux, | |||
| 3425 | for (i = 0; i < nums; i++) | 3412 | for (i = 0; i < nums; i++) |
| 3426 | if (conn[i] == nid) | 3413 | if (conn[i] == nid) |
| 3427 | return i; | 3414 | return i; |
| 3415 | |||
| 3416 | for (i = 0; i < nums; i++) { | ||
| 3417 | unsigned int wid_caps = get_wcaps(codec, conn[i]); | ||
| 3418 | unsigned int wid_type = get_wcaps_type(wid_caps); | ||
| 3419 | |||
| 3420 | if (wid_type != AC_WID_PIN && wid_type != AC_WID_AUD_MIX) | ||
| 3421 | if (get_connection_index(codec, conn[i], nid) >= 0) | ||
| 3422 | return i; | ||
| 3423 | } | ||
| 3428 | return -1; | 3424 | return -1; |
| 3429 | } | 3425 | } |
| 3430 | 3426 | ||
| @@ -3497,6 +3493,16 @@ static int stac92xx_auto_create_dmic_input_ctls(struct hda_codec *codec, | |||
| 3497 | type_idx, HDA_OUTPUT); | 3493 | type_idx, HDA_OUTPUT); |
| 3498 | if (err < 0) | 3494 | if (err < 0) |
| 3499 | return err; | 3495 | return err; |
| 3496 | if (!err) { | ||
| 3497 | nid = get_connected_node(codec, | ||
| 3498 | spec->dmux_nids[0], index); | ||
| 3499 | if (nid) | ||
| 3500 | err = create_elem_capture_vol(codec, | ||
| 3501 | nid, label, | ||
| 3502 | type_idx, HDA_INPUT); | ||
| 3503 | if (err < 0) | ||
| 3504 | return err; | ||
| 3505 | } | ||
| 3500 | } | 3506 | } |
| 3501 | } | 3507 | } |
| 3502 | 3508 | ||
| @@ -5308,6 +5314,105 @@ static int hp_bnb2011_with_dock(struct hda_codec *codec) | |||
| 5308 | return 0; | 5314 | return 0; |
| 5309 | } | 5315 | } |
| 5310 | 5316 | ||
| 5317 | static void stac92hd8x_add_pin(struct hda_codec *codec, hda_nid_t nid) | ||
| 5318 | { | ||
| 5319 | struct sigmatel_spec *spec = codec->spec; | ||
| 5320 | unsigned int def_conf = snd_hda_codec_get_pincfg(codec, nid); | ||
| 5321 | int i; | ||
| 5322 | |||
| 5323 | spec->auto_pin_nids[spec->auto_pin_cnt] = nid; | ||
| 5324 | spec->auto_pin_cnt++; | ||
| 5325 | |||
| 5326 | if (get_defcfg_device(def_conf) == AC_JACK_MIC_IN && | ||
| 5327 | get_defcfg_connect(def_conf) != AC_JACK_PORT_NONE) { | ||
| 5328 | for (i = 0; i < ARRAY_SIZE(stac92hd83xxx_dmic_nids); i++) { | ||
| 5329 | if (nid == stac92hd83xxx_dmic_nids[i]) { | ||
| 5330 | spec->auto_dmic_nids[spec->auto_dmic_cnt] = nid; | ||
| 5331 | spec->auto_dmic_cnt++; | ||
| 5332 | } | ||
| 5333 | } | ||
| 5334 | } | ||
| 5335 | } | ||
| 5336 | |||
| 5337 | static void stac92hd8x_add_adc(struct hda_codec *codec, hda_nid_t nid) | ||
| 5338 | { | ||
| 5339 | |||
