diff options
author | Takashi Iwai <tiwai@suse.de> | 2011-04-28 12:09:52 -0400 |
---|---|---|
committer | Takashi Iwai <tiwai@suse.de> | 2011-04-28 12:09:52 -0400 |
commit | ae8a60a598ce39e8e42fd4ce1348c0883a23b5d8 (patch) | |
tree | 553c0682b44f72274a826d635fe4775347479a24 /sound/pci/hda/patch_realtek.c | |
parent | 1daf5f46c62bc69922e1ca8ccebbbff04f48e1f1 (diff) |
ALSA: hda - Add Auto-Mute Mode enum for two-output cases
The Auto-Mute Mode control is useful even when only two outputs
(e.g. HP and speaker) are available. Then user can enable/disable
the auto-mute behavior on the fly.
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Diffstat (limited to 'sound/pci/hda/patch_realtek.c')
-rw-r--r-- | sound/pci/hda/patch_realtek.c | 32 |
1 files changed, 26 insertions, 6 deletions
diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index 3e41d5637764..faede0f49cca 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c | |||
@@ -397,6 +397,7 @@ struct alc_spec { | |||
397 | unsigned int automute:1; /* HP automute enabled */ | 397 | unsigned int automute:1; /* HP automute enabled */ |
398 | unsigned int detect_line:1; /* Line-out detection enabled */ | 398 | unsigned int detect_line:1; /* Line-out detection enabled */ |
399 | unsigned int automute_lines:1; /* automute line-out as well */ | 399 | unsigned int automute_lines:1; /* automute line-out as well */ |
400 | unsigned int automute_hp_lo:1; /* both HP and LO available */ | ||
400 | 401 | ||
401 | /* other flags */ | 402 | /* other flags */ |
402 | unsigned int no_analog :1; /* digital I/O only */ | 403 | unsigned int no_analog :1; /* digital I/O only */ |
@@ -1427,15 +1428,27 @@ static void alc_auto_init_amp(struct hda_codec *codec, int type) | |||
1427 | static int alc_automute_mode_info(struct snd_kcontrol *kcontrol, | 1428 | static int alc_automute_mode_info(struct snd_kcontrol *kcontrol, |
1428 | struct snd_ctl_elem_info *uinfo) | 1429 | struct snd_ctl_elem_info *uinfo) |
1429 | { | 1430 | { |
1430 | static const char * const texts[] = { | 1431 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); |
1432 | struct alc_spec *spec = codec->spec; | ||
1433 | static const char * const texts2[] = { | ||
1434 | "Disabled", "Enabled" | ||
1435 | }; | ||
1436 | static const char * const texts3[] = { | ||
1431 | "Disabled", "Speaker Only", "Line-Out+Speaker" | 1437 | "Disabled", "Speaker Only", "Line-Out+Speaker" |
1432 | }; | 1438 | }; |
1439 | const char * const *texts; | ||
1433 | 1440 | ||
1434 | uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; | 1441 | uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; |
1435 | uinfo->count = 1; | 1442 | uinfo->count = 1; |
1436 | uinfo->value.enumerated.items = 3; | 1443 | if (spec->automute_hp_lo) { |
1437 | if (uinfo->value.enumerated.item >= 3) | 1444 | uinfo->value.enumerated.items = 3; |
1438 | uinfo->value.enumerated.item = 2; | 1445 | texts = texts3; |
1446 | } else { | ||
1447 | uinfo->value.enumerated.items = 2; | ||
1448 | texts = texts2; | ||
1449 | } | ||
1450 | if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items) | ||
1451 | uinfo->value.enumerated.item = uinfo->value.enumerated.items - 1; | ||
1439 | strcpy(uinfo->value.enumerated.name, | 1452 | strcpy(uinfo->value.enumerated.name, |
1440 | texts[uinfo->value.enumerated.item]); | 1453 | texts[uinfo->value.enumerated.item]); |
1441 | return 0; | 1454 | return 0; |
@@ -1476,6 +1489,8 @@ static int alc_automute_mode_put(struct snd_kcontrol *kcontrol, | |||
1476 | spec->automute_lines = 0; | 1489 | spec->automute_lines = 0; |
1477 | break; | 1490 | break; |
1478 | case 2: | 1491 | case 2: |
1492 | if (!spec->automute_hp_lo) | ||
1493 | return -EINVAL; | ||
1479 | if (spec->automute && spec->automute_lines) | 1494 | if (spec->automute && spec->automute_lines) |
1480 | return 0; | 1495 | return 0; |
1481 | spec->automute = 1; | 1496 | spec->automute = 1; |
@@ -1528,6 +1543,8 @@ static void alc_init_auto_hp(struct hda_codec *codec) | |||
1528 | present++; | 1543 | present++; |
1529 | if (present < 2) /* need two different output types */ | 1544 | if (present < 2) /* need two different output types */ |
1530 | return; | 1545 | return; |
1546 | if (present == 3) | ||
1547 | spec->automute_hp_lo = 1; /* both HP and LO automute */ | ||
1531 | 1548 | ||
1532 | if (!cfg->speaker_pins[0]) { | 1549 | if (!cfg->speaker_pins[0]) { |
1533 | memcpy(cfg->speaker_pins, cfg->line_out_pins, | 1550 | memcpy(cfg->speaker_pins, cfg->line_out_pins, |
@@ -1569,11 +1586,14 @@ static void alc_init_auto_hp(struct hda_codec *codec) | |||
1569 | AC_USRSP_EN | ALC880_FRONT_EVENT); | 1586 | AC_USRSP_EN | ALC880_FRONT_EVENT); |
1570 | spec->detect_line = 1; | 1587 | spec->detect_line = 1; |
1571 | } | 1588 | } |
1589 | spec->automute_lines = 1; | ||
1590 | } | ||
1591 | |||
1592 | if (spec->automute) { | ||
1572 | /* create a control for automute mode */ | 1593 | /* create a control for automute mode */ |
1573 | alc_add_automute_mode_enum(codec); | 1594 | alc_add_automute_mode_enum(codec); |
1574 | spec->automute_lines = 1; | 1595 | spec->unsol_event = alc_sku_unsol_event; |
1575 | } | 1596 | } |
1576 | spec->unsol_event = alc_sku_unsol_event; | ||
1577 | } | 1597 | } |
1578 | 1598 | ||
1579 | static void alc_init_auto_mic(struct hda_codec *codec) | 1599 | static void alc_init_auto_mic(struct hda_codec *codec) |