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 /sound/pci/hda/patch_sigmatel.c | |
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>
Diffstat (limited to 'sound/pci/hda/patch_sigmatel.c')
-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 | struct sigmatel_spec *spec = codec->spec; | ||
5340 | |||
5341 | spec->auto_adc_nids[spec->auto_adc_cnt] = nid; | ||
5342 | spec->auto_adc_cnt++; | ||
5343 | } | ||
5344 | |||
5345 | static void stac92hd8x_add_mux(struct hda_codec *codec, hda_nid_t nid) | ||
5346 | { | ||
5347 | int i, j; | ||
5348 | struct sigmatel_spec *spec = codec->spec; | ||
5349 | |||
5350 | for (i = 0; i < spec->auto_adc_cnt; i++) { | ||
5351 | if (get_connection_index(codec, | ||
5352 | spec->auto_adc_nids[i], nid) >= 0) { | ||
5353 | /* mux and volume for adc_nids[i] */ | ||
5354 | if (!spec->auto_mux_nids[i]) { | ||
5355 | spec->auto_mux_nids[i] = nid; | ||
5356 | /* 92hd codecs capture volume is in mux */ | ||
5357 | spec->auto_capvols[i] = HDA_COMPOSE_AMP_VAL(nid, | ||
5358 | 3, 0, HDA_OUTPUT); | ||
5359 | } | ||
5360 | for (j = 0; j < spec->auto_dmic_cnt; j++) { | ||
5361 | if (get_connection_index(codec, nid, | ||
5362 | spec->auto_dmic_nids[j]) >= 0) { | ||
5363 | /* dmux for adc_nids[i] */ | ||
5364 | if (!spec->auto_dmux_nids[i]) | ||
5365 | spec->auto_dmux_nids[i] = nid; | ||
5366 | break; | ||
5367 | } | ||
5368 | } | ||
5369 | break; | ||
5370 | } | ||
5371 | } | ||
5372 | } | ||
5373 | |||
5374 | static void stac92hd8x_fill_auto_spec(struct hda_codec *codec) | ||
5375 | { | ||
5376 | hda_nid_t nid, end_nid; | ||
5377 | unsigned int wid_caps, wid_type; | ||
5378 | struct sigmatel_spec *spec = codec->spec; | ||
5379 | |||
5380 | end_nid = codec->start_nid + codec->num_nodes; | ||
5381 | |||
5382 | for (nid = codec->start_nid; nid < end_nid; nid++) { | ||
5383 | wid_caps = get_wcaps(codec, nid); | ||
5384 | wid_type = get_wcaps_type(wid_caps); | ||
5385 | |||
5386 | if (wid_type == AC_WID_PIN) | ||
5387 | stac92hd8x_add_pin(codec, nid); | ||
5388 | |||
5389 | if (wid_type == AC_WID_AUD_IN && !(wid_caps & AC_WCAP_DIGITAL)) | ||
5390 | stac92hd8x_add_adc(codec, nid); | ||
5391 | } | ||
5392 | |||
5393 | for (nid = codec->start_nid; nid < end_nid; nid++) { | ||
5394 | wid_caps = get_wcaps(codec, nid); | ||
5395 | wid_type = get_wcaps_type(wid_caps); | ||
5396 | |||
5397 | if (wid_type == AC_WID_AUD_SEL) | ||
5398 | stac92hd8x_add_mux(codec, nid); | ||
5399 | } | ||
5400 | |||
5401 | spec->pin_nids = spec->auto_pin_nids; | ||
5402 | spec->num_pins = spec->auto_pin_cnt; | ||
5403 | spec->adc_nids = spec->auto_adc_nids; | ||
5404 | spec->num_adcs = spec->auto_adc_cnt; | ||
5405 | spec->capvols = spec->auto_capvols; | ||
5406 | spec->capsws = spec->auto_capvols; | ||
5407 | spec->num_caps = spec->auto_adc_cnt; | ||
5408 | spec->mux_nids = spec->auto_mux_nids; | ||
5409 | spec->num_muxes = spec->auto_adc_cnt; | ||
5410 | spec->dmux_nids = spec->auto_dmux_nids; | ||
5411 | spec->num_dmuxes = spec->auto_adc_cnt; | ||
5412 | spec->dmic_nids = spec->auto_dmic_nids; | ||
5413 | spec->num_dmics = spec->auto_dmic_cnt; | ||
5414 | } | ||
5415 | |||
5311 | static int patch_stac92hd83xxx(struct hda_codec *codec) | 5416 | static int patch_stac92hd83xxx(struct hda_codec *codec) |
5312 | { | 5417 | { |
5313 | struct sigmatel_spec *spec; | 5418 | struct sigmatel_spec *spec; |
@@ -5329,26 +5434,17 @@ static int patch_stac92hd83xxx(struct hda_codec *codec) | |||
5329 | snd_hda_codec_write_cache(codec, codec->afg, 0, 0x7ED, 0); | 5434 | snd_hda_codec_write_cache(codec, codec->afg, 0, 0x7ED, 0); |
5330 | codec->no_trigger_sense = 1; | 5435 | codec->no_trigger_sense = 1; |
5331 | codec->spec = spec; | 5436 | codec->spec = spec; |
5437 | |||
5438 | stac92hd8x_fill_auto_spec(codec); | ||
5439 | |||
5332 | spec->linear_tone_beep = 0; | 5440 | spec->linear_tone_beep = 0; |
5333 | codec->slave_dig_outs = stac92hd83xxx_slave_dig_outs; | 5441 | codec->slave_dig_outs = stac92hd83xxx_slave_dig_outs; |
5334 | spec->digbeep_nid = 0x21; | 5442 | spec->digbeep_nid = 0x21; |
5335 | spec->dmic_nids = stac92hd83xxx_dmic_nids; | ||
5336 | spec->dmux_nids = stac92hd83xxx_mux_nids; | ||
5337 | spec->mux_nids = stac92hd83xxx_mux_nids; | ||
5338 | spec->num_muxes = ARRAY_SIZE(stac92hd83xxx_mux_nids); | ||
5339 | spec->adc_nids = stac92hd83xxx_adc_nids; | ||
5340 | spec->num_adcs = ARRAY_SIZE(stac92hd83xxx_adc_nids); | ||
5341 | spec->pwr_nids = stac92hd83xxx_pwr_nids; | 5443 | spec->pwr_nids = stac92hd83xxx_pwr_nids; |
5342 | spec->pwr_mapping = stac92hd83xxx_pwr_mapping; | 5444 | spec->pwr_mapping = stac92hd83xxx_pwr_mapping; |
5343 | spec->num_pwrs = ARRAY_SIZE(stac92hd83xxx_pwr_nids); | 5445 | spec->num_pwrs = ARRAY_SIZE(stac92hd83xxx_pwr_nids); |
5344 | spec->multiout.dac_nids = spec->dac_nids; | 5446 | spec->multiout.dac_nids = spec->dac_nids; |
5345 | |||
5346 | spec->init = stac92hd83xxx_core_init; | 5447 | spec->init = stac92hd83xxx_core_init; |
5347 | spec->num_pins = ARRAY_SIZE(stac92hd83xxx_pin_nids); | ||
5348 | spec->pin_nids = stac92hd83xxx_pin_nids; | ||
5349 | spec->num_caps = STAC92HD83XXX_NUM_CAPS; | ||
5350 | spec->capvols = stac92hd83xxx_capvols; | ||
5351 | spec->capsws = stac92hd83xxx_capsws; | ||
5352 | 5448 | ||
5353 | spec->board_config = snd_hda_check_board_config(codec, | 5449 | spec->board_config = snd_hda_check_board_config(codec, |
5354 | STAC_92HD83XXX_MODELS, | 5450 | STAC_92HD83XXX_MODELS, |
@@ -5366,28 +5462,11 @@ again: | |||
5366 | case 0x111d76d1: | 5462 | case 0x111d76d1: |
5367 | case 0x111d76d9: | 5463 | case 0x111d76d9: |
5368 | case 0x111d76e5: | 5464 | case 0x111d76e5: |
5369 | spec->dmic_nids = stac92hd87b_dmic_nids; | ||
5370 | spec->num_dmics = stac92xx_connected_ports(codec, | ||
5371 | stac92hd87b_dmic_nids, | ||
5372 | STAC92HD87B_NUM_DMICS); | ||
5373 | spec->num_pins = ARRAY_SIZE(stac92hd87xxx_pin_nids); | ||
5374 | spec->pin_nids = stac92hd87xxx_pin_nids; | ||
5375 | spec->mono_nid = 0; | ||
5376 | spec->num_pwrs = 0; | ||
5377 | break; | ||
5378 | case 0x111d7666: | 5465 | case 0x111d7666: |
5379 | case 0x111d7667: | 5466 | case 0x111d7667: |
5380 | case 0x111d7668: | 5467 | case 0x111d7668: |
5381 | case 0x111d7669: | 5468 | case 0x111d7669: |
5382 | case 0x111d76e3: | 5469 | case 0x111d76e3: |
5383 | spec->num_dmics = stac92xx_connected_ports(codec, | ||
5384 | stac92hd88xxx_dmic_nids, | ||
5385 | STAC92HD88XXX_NUM_DMICS); | ||
5386 | spec->num_pins = ARRAY_SIZE(stac92hd88xxx_pin_nids); | ||
5387 | spec->pin_nids = stac92hd88xxx_pin_nids; | ||
5388 | spec->mono_nid = 0; | ||
5389 | spec->num_pwrs = 0; | ||
5390 | break; | ||
5391 | case 0x111d7604: | 5470 | case 0x111d7604: |
5392 | case 0x111d76d4: | 5471 | case 0x111d76d4: |
5393 | case 0x111d7605: | 5472 | case 0x111d7605: |
@@ -5396,9 +5475,6 @@ again: | |||
5396 | if (spec->board_config == STAC_92HD83XXX_PWR_REF) | 5475 | if (spec->board_config == STAC_92HD83XXX_PWR_REF) |
5397 | break; | 5476 | break; |
5398 | spec->num_pwrs = 0; | 5477 | spec->num_pwrs = 0; |
5399 | spec->num_dmics = stac92xx_connected_ports(codec, | ||
5400 | stac92hd83xxx_dmic_nids, | ||
5401 | STAC92HD83XXX_NUM_DMICS); | ||
5402 | break; | 5478 | break; |
5403 | } | 5479 | } |
5404 | 5480 | ||