diff options
author | Takashi Iwai <tiwai@suse.de> | 2009-08-13 12:14:42 -0400 |
---|---|---|
committer | Takashi Iwai <tiwai@suse.de> | 2009-08-13 12:14:42 -0400 |
commit | 667067d8980249a71ccf82a55202fff2cd1cd54f (patch) | |
tree | 30a02ea2c58efa53c4e29844a9d5a75834c68887 /sound/pci/hda/patch_sigmatel.c | |
parent | a6cd7a71fde47e19738e7791c75584e2aca15187 (diff) |
ALSA: hda - Fix / clean up IDT92HD83xxx codec parser
A few improvements for IDT 92HD83xxx codec pareser:
- Remove unused / deprecated mixer-amp controls
- Handle d-mics as normal inputs since this codec has no separate
MUXes for analog and digital
- Don't create duplicated controls for capture volumes with Mux
capture volumes
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 | 149 |
1 files changed, 69 insertions, 80 deletions
diff --git a/sound/pci/hda/patch_sigmatel.c b/sound/pci/hda/patch_sigmatel.c index f6d7ef452d78..7d33e0a76c1e 100644 --- a/sound/pci/hda/patch_sigmatel.c +++ b/sound/pci/hda/patch_sigmatel.c | |||
@@ -359,14 +359,9 @@ static unsigned long stac92hd73xx_capvols[] = { | |||
359 | }; | 359 | }; |
360 | #define stac92hd73xx_capsws stac92hd73xx_capvols | 360 | #define stac92hd73xx_capsws stac92hd73xx_capvols |
361 | 361 | ||
362 | #define STAC92HD83XXX_NUM_DMICS 2 | ||
363 | static hda_nid_t stac92hd83xxx_dmic_nids[STAC92HD83XXX_NUM_DMICS + 1] = { | ||
364 | 0x11, 0x12, 0 | ||
365 | }; | ||
366 | |||
367 | #define STAC92HD83_DAC_COUNT 3 | 362 | #define STAC92HD83_DAC_COUNT 3 |
368 | 363 | ||
369 | static hda_nid_t stac92hd83xxx_dmux_nids[2] = { | 364 | static hda_nid_t stac92hd83xxx_mux_nids[2] = { |
370 | 0x17, 0x18, | 365 | 0x17, 0x18, |
371 | }; | 366 | }; |
372 | 367 | ||
@@ -386,10 +381,6 @@ static unsigned int stac92hd83xxx_pwr_mapping[4] = { | |||
386 | 0x03, 0x0c, 0x20, 0x40, | 381 | 0x03, 0x0c, 0x20, 0x40, |
387 | }; | 382 | }; |
388 | 383 | ||
389 | static hda_nid_t stac92hd83xxx_amp_nids[1] = { | ||
390 | 0xc, | ||
391 | }; | ||
392 | |||
393 | #define STAC92HD83XXX_NUM_CAPS 2 | 384 | #define STAC92HD83XXX_NUM_CAPS 2 |
394 | static unsigned long stac92hd83xxx_capvols[] = { | 385 | static unsigned long stac92hd83xxx_capvols[] = { |
395 | HDA_COMPOSE_AMP_VAL(0x17, 3, 0, HDA_OUTPUT), | 386 | HDA_COMPOSE_AMP_VAL(0x17, 3, 0, HDA_OUTPUT), |
@@ -1212,26 +1203,6 @@ static struct snd_kcontrol_new stac92hd73xx_10ch_mixer[] = { | |||
1212 | }; | 1203 | }; |
1213 | 1204 | ||
1214 | 1205 | ||
1215 | static struct snd_kcontrol_new stac92hd83xxx_mixer[] = { | ||
1216 | HDA_CODEC_VOLUME("DAC0 Capture Volume", 0x1b, 0x3, HDA_INPUT), | ||
1217 | HDA_CODEC_MUTE("DAC0 Capture Switch", 0x1b, 0x3, HDA_INPUT), | ||
1218 | |||
1219 | HDA_CODEC_VOLUME("DAC1 Capture Volume", 0x1b, 0x4, HDA_INPUT), | ||
1220 | HDA_CODEC_MUTE("DAC1 Capture Switch", 0x1b, 0x4, HDA_INPUT), | ||
1221 | |||
1222 | HDA_CODEC_VOLUME("Front Mic Capture Volume", 0x1b, 0x0, HDA_INPUT), | ||
1223 | HDA_CODEC_MUTE("Front Mic Capture Switch", 0x1b, 0x0, HDA_INPUT), | ||
1224 | |||
1225 | HDA_CODEC_VOLUME("Line In Capture Volume", 0x1b, 0x2, HDA_INPUT), | ||
1226 | HDA_CODEC_MUTE("Line In Capture Switch", 0x1b, 0x2, HDA_INPUT), | ||
1227 | |||
1228 | /* | ||
1229 | HDA_CODEC_VOLUME("Mic Capture Volume", 0x1b, 0x1, HDA_INPUT), | ||
1230 | HDA_CODEC_MUTE("Mic Capture Switch", 0x1b 0x1, HDA_INPUT), | ||
1231 | */ | ||
1232 | { } /* end */ | ||
1233 | }; | ||
1234 | |||
1235 | static struct snd_kcontrol_new stac92hd71bxx_loopback[] = { | 1206 | static struct snd_kcontrol_new stac92hd71bxx_loopback[] = { |
1236 | STAC_ANALOG_LOOPBACK(0xFA0, 0x7A0, 2) | 1207 | STAC_ANALOG_LOOPBACK(0xFA0, 0x7A0, 2) |
1237 | }; | 1208 | }; |
@@ -3521,19 +3492,33 @@ static int stac92xx_beep_switch_ctl(struct hda_codec *codec) | |||
3521 | static int stac92xx_auto_create_mux_input_ctls(struct hda_codec *codec) | 3492 | static int stac92xx_auto_create_mux_input_ctls(struct hda_codec *codec) |
3522 | { | 3493 | { |
3523 | struct sigmatel_spec *spec = codec->spec; | 3494 | struct sigmatel_spec *spec = codec->spec; |
3524 | int wcaps, nid, i, err = 0; | 3495 | int i, j, err = 0; |
3525 | 3496 | ||
3526 | for (i = 0; i < spec->num_muxes; i++) { | 3497 | for (i = 0; i < spec->num_muxes; i++) { |
3498 | hda_nid_t nid; | ||
3499 | unsigned int wcaps; | ||
3500 | unsigned long val; | ||
3501 | |||
3527 | nid = spec->mux_nids[i]; | 3502 | nid = spec->mux_nids[i]; |
3528 | wcaps = get_wcaps(codec, nid); | 3503 | wcaps = get_wcaps(codec, nid); |
3504 | if (!(wcaps & AC_WCAP_OUT_AMP)) | ||
3505 | continue; | ||
3529 | 3506 | ||
3530 | if (wcaps & AC_WCAP_OUT_AMP) { | 3507 | /* check whether already the same control was created as |
3531 | err = stac92xx_add_control_idx(spec, | 3508 | * normal Capture Volume. |
3532 | STAC_CTL_WIDGET_VOL, i, "Mux Capture Volume", | 3509 | */ |
3533 | HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT)); | 3510 | val = HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT); |
3534 | if (err < 0) | 3511 | for (j = 0; j < spec->num_caps; j++) { |
3535 | return err; | 3512 | if (spec->capvols[j] == val) |
3513 | break; | ||
3536 | } | 3514 | } |
3515 | if (j < spec->num_caps) | ||
3516 | continue; | ||
3517 | |||
3518 | err = stac92xx_add_control_idx(spec, STAC_CTL_WIDGET_VOL, i, | ||
3519 | "Mux Capture Volume", val); | ||
3520 | if (err < 0) | ||
3521 | return err; | ||
3537 | } | 3522 | } |
3538 | return 0; | 3523 | return 0; |
3539 | }; | 3524 | }; |
@@ -3588,6 +3573,24 @@ static int get_connection_index(struct hda_codec *codec, hda_nid_t mux, | |||
3588 | return -1; | 3573 | return -1; |
3589 | } | 3574 | } |
3590 | 3575 | ||
3576 | /* create a volume assigned to the given pin (only if supported) */ | ||
3577 | static int create_elem_capture_vol(struct hda_codec *codec, hda_nid_t nid, | ||
3578 | const char *label) | ||
3579 | { | ||
3580 | unsigned int caps, nums; | ||
3581 | char name[32]; | ||
3582 | |||
3583 | if (!(get_wcaps(codec, nid) & AC_WCAP_IN_AMP)) | ||
3584 | return 0; | ||
3585 | caps = query_amp_caps(codec, nid, HDA_OUTPUT); | ||
3586 | nums = (caps & AC_AMPCAP_NUM_STEPS) >> AC_AMPCAP_NUM_STEPS_SHIFT; | ||
3587 | if (!nums) | ||
3588 | return 0; | ||
3589 | snprintf(name, sizeof(name), "%s Capture Volume", label); | ||
3590 | return stac92xx_add_control(codec->spec, STAC_CTL_WIDGET_VOL, name, | ||
3591 | HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_INPUT)); | ||
3592 | } | ||
3593 | |||
3591 | /* create playback/capture controls for input pins on dmic capable codecs */ | 3594 | /* create playback/capture controls for input pins on dmic capable codecs */ |
3592 | static int stac92xx_auto_create_dmic_input_ctls(struct hda_codec *codec, | 3595 | static int stac92xx_auto_create_dmic_input_ctls(struct hda_codec *codec, |
3593 | const struct auto_pin_cfg *cfg) | 3596 | const struct auto_pin_cfg *cfg) |
@@ -3597,7 +3600,6 @@ static int stac92xx_auto_create_dmic_input_ctls(struct hda_codec *codec, | |||
3597 | struct hda_input_mux *dimux = &spec->private_dimux; | 3600 | struct hda_input_mux *dimux = &spec->private_dimux; |
3598 | int err, i, active_mics; | 3601 | int err, i, active_mics; |
3599 | unsigned int def_conf; | 3602 | unsigned int def_conf; |
3600 | char name[32]; | ||
3601 | 3603 | ||
3602 | dimux->items[dimux->num_items].label = stac92xx_dmic_labels[0]; | 3604 | dimux->items[dimux->num_items].label = stac92xx_dmic_labels[0]; |
3603 | dimux->items[dimux->num_items].index = 0; | 3605 | dimux->items[dimux->num_items].index = 0; |
@@ -3605,6 +3607,10 @@ static int stac92xx_auto_create_dmic_input_ctls(struct hda_codec *codec, | |||
3605 | 3607 | ||
3606 | active_mics = 0; | 3608 | active_mics = 0; |
3607 | for (i = 0; i < spec->num_dmics; i++) { | 3609 | for (i = 0; i < spec->num_dmics; i++) { |
3610 | /* check the validity: sometimes it's a dead vendor-spec node */ | ||
3611 | if (get_wcaps_type(get_wcaps(codec, spec->dmic_nids[i])) | ||
3612 | != AC_WID_PIN) | ||
3613 | continue; | ||
3608 | def_conf = snd_hda_codec_get_pincfg(codec, spec->dmic_nids[i]); | 3614 | def_conf = snd_hda_codec_get_pincfg(codec, spec->dmic_nids[i]); |
3609 | if (get_defcfg_connect(def_conf) != AC_JACK_PORT_NONE) | 3615 | if (get_defcfg_connect(def_conf) != AC_JACK_PORT_NONE) |
3610 | active_mics++; | 3616 | active_mics++; |
@@ -3613,14 +3619,15 @@ static int stac92xx_auto_create_dmic_input_ctls(struct hda_codec *codec, | |||
3613 | for (i = 0; i < spec->num_dmics; i++) { | 3619 | for (i = 0; i < spec->num_dmics; i++) { |
3614 | hda_nid_t nid; | 3620 | hda_nid_t nid; |
3615 | int index; | 3621 | int index; |
3616 | unsigned int wcaps; | ||
3617 | const char *label; | 3622 | const char *label; |
3618 | 3623 | ||
3619 | def_conf = snd_hda_codec_get_pincfg(codec, spec->dmic_nids[i]); | 3624 | nid = spec->dmic_nids[i]; |
3625 | if (get_wcaps_type(get_wcaps(codec, nid)) != AC_WID_PIN) | ||
3626 | continue; | ||
3627 | def_conf = snd_hda_codec_get_pincfg(codec, nid); | ||
3620 | if (get_defcfg_connect(def_conf) == AC_JACK_PORT_NONE) | 3628 | if (get_defcfg_connect(def_conf) == AC_JACK_PORT_NONE) |
3621 | continue; | 3629 | continue; |
3622 | 3630 | ||
3623 | nid = spec->dmic_nids[i]; | ||
3624 | index = get_connection_index(codec, spec->dmux_nids[0], nid); | 3631 | index = get_connection_index(codec, spec->dmux_nids[0], nid); |
3625 | if (index < 0) | 3632 | if (index < 0) |
3626 | continue; | 3633 | continue; |
@@ -3630,21 +3637,9 @@ static int stac92xx_auto_create_dmic_input_ctls(struct hda_codec *codec, | |||
3630 | else | 3637 | else |
3631 | label = stac92xx_dmic_labels[dimux->num_items]; | 3638 | label = stac92xx_dmic_labels[dimux->num_items]; |
3632 | 3639 | ||
3633 | wcaps = get_wcaps(codec, nid) & | 3640 | err = create_elem_capture_vol(codec, nid, label); |
3634 | (AC_WCAP_OUT_AMP | AC_WCAP_IN_AMP); | 3641 | if (err < 0) |
3635 | 3642 | return err; | |
3636 | if (wcaps) { | ||
3637 | sprintf(name, "%s Capture Volume", label); | ||
3638 | |||
3639 | err = stac92xx_add_control(spec, | ||
3640 | STAC_CTL_WIDGET_VOL, | ||
3641 | name, | ||
3642 | HDA_COMPOSE_AMP_VAL(nid, 3, 0, | ||
3643 | (wcaps & AC_WCAP_OUT_AMP) ? | ||
3644 | HDA_OUTPUT : HDA_INPUT)); | ||
3645 | if (err < 0) | ||
3646 | return err; | ||
3647 | } | ||
3648 | 3643 | ||
3649 | dimux->items[dimux->num_items].label = label; | 3644 | dimux->items[dimux->num_items].label = label; |
3650 | dimux->items[dimux->num_items].index = index; | 3645 | dimux->items[dimux->num_items].index = index; |
@@ -3746,29 +3741,29 @@ static int stac92xx_auto_create_analog_input_ctls(struct hda_codec *codec, const | |||
3746 | { | 3741 | { |
3747 | struct sigmatel_spec *spec = codec->spec; | 3742 | struct sigmatel_spec *spec = codec->spec; |
3748 | struct hda_input_mux *imux = &spec->private_imux; | 3743 | struct hda_input_mux *imux = &spec->private_imux; |
3749 | hda_nid_t con_lst[HDA_MAX_NUM_INPUTS]; | 3744 | int i, j; |
3750 | int i, j, k; | ||
3751 | 3745 | ||
3752 | for (i = 0; i < AUTO_PIN_LAST; i++) { | 3746 | for (i = 0; i < AUTO_PIN_LAST; i++) { |
3753 | int index; | 3747 | hda_nid_t nid = cfg->input_pins[i]; |
3748 | int index, err; | ||
3754 | 3749 | ||
3755 | if (!cfg->input_pins[i]) | 3750 | if (!nid) |
3756 | continue; | 3751 | continue; |
3757 | index = -1; | 3752 | index = -1; |
3758 | for (j = 0; j < spec->num_muxes; j++) { | 3753 | for (j = 0; j < spec->num_muxes; j++) { |
3759 | int num_cons; | 3754 | index = get_connection_index(codec, spec->mux_nids[j], |
3760 | num_cons = snd_hda_get_connections(codec, | 3755 | nid); |
3761 | spec->mux_nids[j], | 3756 | if (index >= 0) |
3762 | con_lst, | 3757 | break; |
3763 | HDA_MAX_NUM_INPUTS); | ||
3764 | for (k = 0; k < num_cons; k++) | ||
3765 | if (con_lst[k] == cfg->input_pins[i]) { | ||
3766 | index = k; | ||
3767 | goto found; | ||
3768 | } | ||
3769 | } | 3758 | } |
3770 | continue; | 3759 | if (index < 0) |
3771 | found: | 3760 | continue; |
3761 | |||
3762 | err = create_elem_capture_vol(codec, nid, | ||
3763 | auto_pin_cfg_labels[i]); | ||
3764 | if (err < 0) | ||
3765 | return err; | ||
3766 | |||
3772 | imux->items[imux->num_items].label = auto_pin_cfg_labels[i]; | 3767 | imux->items[imux->num_items].label = auto_pin_cfg_labels[i]; |
3773 | imux->items[imux->num_items].index = index; | 3768 | imux->items[imux->num_items].index = index; |
3774 | imux->num_items++; | 3769 | imux->num_items++; |
@@ -5299,22 +5294,16 @@ static int patch_stac92hd83xxx(struct hda_codec *codec) | |||
5299 | codec->slave_dig_outs = stac92hd83xxx_slave_dig_outs; | 5294 | codec->slave_dig_outs = stac92hd83xxx_slave_dig_outs; |
5300 | spec->mono_nid = 0x19; | 5295 | spec->mono_nid = 0x19; |
5301 | spec->digbeep_nid = 0x21; | 5296 | spec->digbeep_nid = 0x21; |
5302 | spec->dmic_nids = stac92hd83xxx_dmic_nids; | 5297 | spec->mux_nids = stac92hd83xxx_mux_nids; |
5303 | spec->dmux_nids = stac92hd83xxx_dmux_nids; | 5298 | spec->num_muxes = ARRAY_SIZE(stac92hd83xxx_mux_nids); |
5304 | spec->adc_nids = stac92hd83xxx_adc_nids; | 5299 | spec->adc_nids = stac92hd83xxx_adc_nids; |
5305 | spec->pwr_nids = stac92hd83xxx_pwr_nids; | 5300 | spec->pwr_nids = stac92hd83xxx_pwr_nids; |
5306 | spec->amp_nids = stac92hd83xxx_amp_nids; | ||
5307 | spec->pwr_mapping = stac92hd83xxx_pwr_mapping; | 5301 | spec->pwr_mapping = stac92hd83xxx_pwr_mapping; |
5308 | spec->num_pwrs = ARRAY_SIZE(stac92hd83xxx_pwr_nids); | 5302 | spec->num_pwrs = ARRAY_SIZE(stac92hd83xxx_pwr_nids); |
5309 | spec->multiout.dac_nids = spec->dac_nids; | 5303 | spec->multiout.dac_nids = spec->dac_nids; |
5310 | 5304 | ||
5311 | spec->init = stac92hd83xxx_core_init; | 5305 | spec->init = stac92hd83xxx_core_init; |
5312 | spec->mixer = stac92hd83xxx_mixer; | ||
5313 | spec->num_pins = ARRAY_SIZE(stac92hd83xxx_pin_nids); | 5306 | spec->num_pins = ARRAY_SIZE(stac92hd83xxx_pin_nids); |
5314 | spec->num_dmuxes = ARRAY_SIZE(stac92hd83xxx_dmux_nids); | ||
5315 | spec->num_adcs = ARRAY_SIZE(stac92hd83xxx_adc_nids); | ||
5316 | spec->num_amps = ARRAY_SIZE(stac92hd83xxx_amp_nids); | ||
5317 | spec->num_dmics = STAC92HD83XXX_NUM_DMICS; | ||
5318 | spec->pin_nids = stac92hd83xxx_pin_nids; | 5307 | spec->pin_nids = stac92hd83xxx_pin_nids; |
5319 | spec->num_caps = STAC92HD83XXX_NUM_CAPS; | 5308 | spec->num_caps = STAC92HD83XXX_NUM_CAPS; |
5320 | spec->capvols = stac92hd83xxx_capvols; | 5309 | spec->capvols = stac92hd83xxx_capvols; |