ALSA: hda - Use digital beep for AD codecs
authorTakashi Iwai <tiwai@suse.de>
Fri, 6 Feb 2009 16:22:05 +0000 (17:22 +0100)
committerTakashi Iwai <tiwai@suse.de>
Fri, 6 Feb 2009 16:22:05 +0000 (17:22 +0100)
Use digital beep instead of analog pc-beep for AD codecs.
Create the beep mixer controls dynamically on demand.

Signed-off-by: Takashi Iwai <tiwai@suse.de>
sound/pci/hda/patch_analog.c

index 30399cb..cc02f2d 100644 (file)
 #include <sound/core.h>
 #include "hda_codec.h"
 #include "hda_local.h"
+#include "hda_beep.h"
 
 struct ad198x_spec {
        struct snd_kcontrol_new *mixers[5];
        int num_mixers;
-
+       unsigned int beep_amp;  /* beep amp value, set via set_beep_amp() */
        const struct hda_verb *init_verbs[5];   /* initialization verbs
                                                 * don't forget NULL termination!
                                                 */
@@ -154,6 +155,16 @@ static const char *ad_slave_sws[] = {
 
 static void ad198x_free_kctls(struct hda_codec *codec);
 
+/* additional beep mixers; the actual parameters are overwritten at build */
+static struct snd_kcontrol_new ad_beep_mixer[] = {
+       HDA_CODEC_VOLUME("Beep Playback Volume", 0, 0, HDA_OUTPUT),
+       HDA_CODEC_MUTE("Beep Playback Switch", 0, 0, HDA_OUTPUT),
+       { } /* end */
+};
+
+#define set_beep_amp(spec, nid, idx, dir) \
+       ((spec)->beep_amp = HDA_COMPOSE_AMP_VAL(nid, 1, idx, dir)) /* mono */
+
 static int ad198x_build_controls(struct hda_codec *codec)
 {
        struct ad198x_spec *spec = codec->spec;
@@ -181,6 +192,21 @@ static int ad198x_build_controls(struct hda_codec *codec)
                        return err;
        }
 
+       /* create beep controls if needed */
+       if (spec->beep_amp) {
+               struct snd_kcontrol_new *knew;
+               for (knew = ad_beep_mixer; knew->name; knew++) {
+                       struct snd_kcontrol *kctl;
+                       kctl = snd_ctl_new1(knew, codec);
+                       if (!kctl)
+                               return -ENOMEM;
+                       kctl->private_value = spec->beep_amp;
+                       err = snd_hda_ctl_add(codec, kctl);
+                       if (err < 0)
+                               return err;
+               }
+       }
+
        /* if we have no master control, let's create it */
        if (!snd_hda_find_mixer_ctl(codec, "Master Playback Volume")) {
                unsigned int vmaster_tlv[4];
@@ -397,7 +423,8 @@ static void ad198x_free(struct hda_codec *codec)
                return;
 
        ad198x_free_kctls(codec);
-       kfree(codec->spec);
+       kfree(spec);
+       snd_hda_detach_beep_device(codec);
 }
 
 static struct hda_codec_ops ad198x_patch_ops = {
@@ -536,8 +563,6 @@ static struct snd_kcontrol_new ad1986a_mixers[] = {
        HDA_CODEC_VOLUME("Mic Playback Volume", 0x13, 0x0, HDA_OUTPUT),
        HDA_CODEC_MUTE("Mic Playback Switch", 0x13, 0x0, HDA_OUTPUT),
        HDA_CODEC_VOLUME("Mic Boost", 0x0f, 0x0, HDA_OUTPUT),
-       HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x18, 0x0, HDA_OUTPUT),
-       HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x18, 0x0, HDA_OUTPUT),
        HDA_CODEC_VOLUME("Mono Playback Volume", 0x1e, 0x0, HDA_OUTPUT),
        HDA_CODEC_MUTE("Mono Playback Switch", 0x1e, 0x0, HDA_OUTPUT),
        HDA_CODEC_VOLUME("Capture Volume", 0x12, 0x0, HDA_OUTPUT),
@@ -601,8 +626,7 @@ static struct snd_kcontrol_new ad1986a_laptop_mixers[] = {
        HDA_CODEC_VOLUME("Mic Playback Volume", 0x13, 0x0, HDA_OUTPUT),
        HDA_CODEC_MUTE("Mic Playback Switch", 0x13, 0x0, HDA_OUTPUT),
        HDA_CODEC_VOLUME("Mic Boost", 0x0f, 0x0, HDA_OUTPUT),
-       /* HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x18, 0x0, HDA_OUTPUT),
-          HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x18, 0x0, HDA_OUTPUT),
+       /* 
           HDA_CODEC_VOLUME("Mono Playback Volume", 0x1e, 0x0, HDA_OUTPUT),
           HDA_CODEC_MUTE("Mono Playback Switch", 0x1e, 0x0, HDA_OUTPUT), */
        HDA_CODEC_VOLUME("Capture Volume", 0x12, 0x0, HDA_OUTPUT),
@@ -800,8 +824,6 @@ static struct snd_kcontrol_new ad1986a_laptop_automute_mixers[] = {
        HDA_CODEC_VOLUME("Mic Playback Volume", 0x13, 0x0, HDA_OUTPUT),
        HDA_CODEC_MUTE("Mic Playback Switch", 0x13, 0x0, HDA_OUTPUT),
        HDA_CODEC_VOLUME("Mic Boost", 0x0f, 0x0, HDA_OUTPUT),
-       HDA_CODEC_VOLUME("Beep Playback Volume", 0x18, 0x0, HDA_OUTPUT),
-       HDA_CODEC_MUTE("Beep Playback Switch", 0x18, 0x0, HDA_OUTPUT),
        HDA_CODEC_VOLUME("Capture Volume", 0x12, 0x0, HDA_OUTPUT),
        HDA_CODEC_MUTE("Capture Switch", 0x12, 0x0, HDA_OUTPUT),
        {
@@ -1026,7 +1048,7 @@ static int is_jack_available(struct hda_codec *codec, hda_nid_t nid)
 static int patch_ad1986a(struct hda_codec *codec)
 {
        struct ad198x_spec *spec;
-       int board_config;
+       int err, board_config;
 
        spec = kzalloc(sizeof(*spec), GFP_KERNEL);
        if (spec == NULL)
@@ -1034,6 +1056,13 @@ static int patch_ad1986a(struct hda_codec *codec)
 
        codec->spec = spec;
 
+       err = snd_hda_attach_beep_device(codec, 0x19);
+       if (err < 0) {
+               ad198x_free(codec);
+               return err;
+       }
+       set_beep_amp(spec, 0x18, 0, HDA_OUTPUT);
+
        spec->multiout.max_channels = 6;
        spec->multiout.num_dacs = ARRAY_SIZE(ad1986a_dac_nids);
        spec->multiout.dac_nids = ad1986a_dac_nids;
@@ -1213,8 +1242,6 @@ static struct snd_kcontrol_new ad1983_mixers[] = {
        HDA_CODEC_MUTE("Mic Playback Switch", 0x12, 0x0, HDA_OUTPUT),
        HDA_CODEC_VOLUME("Line Playback Volume", 0x13, 0x0, HDA_OUTPUT),
        HDA_CODEC_MUTE("Line Playback Switch", 0x13, 0x0, HDA_OUTPUT),
-       HDA_CODEC_VOLUME_MONO("PC Speaker Playback Volume", 0x10, 1, 0x0, HDA_OUTPUT),
-       HDA_CODEC_MUTE_MONO("PC Speaker Playback Switch", 0x10, 1, 0x0, HDA_OUTPUT),
        HDA_CODEC_VOLUME("Mic Boost", 0x0c, 0x0, HDA_OUTPUT),
        HDA_CODEC_VOLUME("Capture Volume", 0x15, 0x0, HDA_OUTPUT),
        HDA_CODEC_MUTE("Capture Switch", 0x15, 0x0, HDA_OUTPUT),
@@ -1285,6 +1312,7 @@ static struct hda_amp_list ad1983_loopbacks[] = {
 static int patch_ad1983(struct hda_codec *codec)
 {
        struct ad198x_spec *spec;
+       int err;
 
        spec = kzalloc(sizeof(*spec), GFP_KERNEL);
        if (spec == NULL)
@@ -1292,6 +1320,13 @@ static int patch_ad1983(struct hda_codec *codec)
 
        codec->spec = spec;
 
+       err = snd_hda_attach_beep_device(codec, 0x10);
+       if (err < 0) {
+               ad198x_free(codec);
+               return err;
+       }
+       set_beep_amp(spec, 0x10, 0, HDA_OUTPUT);
+
        spec->multiout.max_channels = 2;
        spec->multiout.num_dacs = ARRAY_SIZE(ad1983_dac_nids);
        spec->multiout.dac_nids = ad1983_dac_nids;
@@ -1361,8 +1396,6 @@ static struct snd_kcontrol_new ad1981_mixers[] = {
        HDA_CODEC_MUTE("Mic Playback Switch", 0x1c, 0x0, HDA_OUTPUT),
        HDA_CODEC_VOLUME("CD Playback Volume", 0x1d, 0x0, HDA_OUTPUT),
        HDA_CODEC_MUTE("CD Playback Switch", 0x1d, 0x0, HDA_OUTPUT),
-       HDA_CODEC_VOLUME_MONO("PC Speaker Playback Volume", 0x0d, 1, 0x0, HDA_OUTPUT),
-       HDA_CODEC_MUTE_MONO("PC Speaker Playback Switch", 0x0d, 1, 0x0, HDA_OUTPUT),
        HDA_CODEC_VOLUME("Front Mic Boost", 0x08, 0x0, HDA_INPUT),
        HDA_CODEC_VOLUME("Mic Boost", 0x18, 0x0, HDA_INPUT),
        HDA_CODEC_VOLUME("Capture Volume", 0x15, 0x0, HDA_OUTPUT),
@@ -1685,7 +1718,7 @@ static struct snd_pci_quirk ad1981_cfg_tbl[] = {
 static int patch_ad1981(struct hda_codec *codec)
 {
        struct ad198x_spec *spec;
-       int board_config;
+       int err, board_config;
 
        spec = kzalloc(sizeof(*spec), GFP_KERNEL);
        if (spec == NULL)
@@ -1693,6 +1726,13 @@ static int patch_ad1981(struct hda_codec *codec)
 
        codec->spec = spec;
 
+       err = snd_hda_attach_beep_device(codec, 0x10);
+       if (err < 0) {
+               ad198x_free(codec);
+               return err;
+       }
+       set_beep_amp(spec, 0x0d, 0, HDA_OUTPUT);
+
        spec->multiout.max_channels = 2;
        spec->multiout.num_dacs = ARRAY_SIZE(ad1981_dac_nids);
        spec->multiout.dac_nids = ad1981_dac_nids;
@@ -1979,9 +2019,6 @@ static struct snd_kcontrol_new ad1988_6stack_mixers2[] = {
        HDA_CODEC_VOLUME("Mic Playback Volume", 0x20, 0x4, HDA_INPUT),
        HDA_CODEC_MUTE("Mic Playback Switch", 0x20, 0x4, HDA_INPUT),
 
-       HDA_CODEC_VOLUME("Beep Playback Volume", 0x10, 0x0, HDA_OUTPUT),
-       HDA_CODEC_MUTE("Beep Playback Switch", 0x10, 0x0, HDA_OUTPUT),
-
        HDA_CODEC_VOLUME("Analog Mix Playback Volume", 0x21, 0x0, HDA_OUTPUT),
        HDA_CODEC_MUTE("Analog Mix Playback Switch", 0x21, 0x0, HDA_OUTPUT),
 
@@ -2025,9 +2062,6 @@ static struct snd_kcontrol_new ad1988_3stack_mixers2[] = {
        HDA_CODEC_VOLUME("Mic Playback Volume", 0x20, 0x4, HDA_INPUT),
        HDA_CODEC_MUTE("Mic Playback Switch", 0x20, 0x4, HDA_INPUT),
 
-       HDA_CODEC_VOLUME("Beep Playback Volume", 0x10, 0x0, HDA_OUTPUT),
-       HDA_CODEC_MUTE("Beep Playback Switch", 0x10, 0x0, HDA_OUTPUT),
-
        HDA_CODEC_VOLUME("Analog Mix Playback Volume", 0x21, 0x0, HDA_OUTPUT),
        HDA_CODEC_MUTE("Analog Mix Playback Switch", 0x21, 0x0, HDA_OUTPUT),
 
@@ -2057,9 +2091,6 @@ static struct snd_kcontrol_new ad1988_laptop_mixers[] = {
        HDA_CODEC_VOLUME("Line Playback Volume", 0x20, 0x1, HDA_INPUT),
        HDA_CODEC_MUTE("Line Playback Switch", 0x20, 0x1, HDA_INPUT),
 
-       HDA_CODEC_VOLUME("Beep Playback Volume", 0x10, 0x0, HDA_OUTPUT),
-       HDA_CODEC_MUTE("Beep Playback Switch", 0x10, 0x0, HDA_OUTPUT),
-
        HDA_CODEC_VOLUME("Analog Mix Playback Volume", 0x21, 0x0, HDA_OUTPUT),
        HDA_CODEC_MUTE("Analog Mix Playback Switch", 0x21, 0x0, HDA_OUTPUT),
 
@@ -2919,7 +2950,7 @@ static struct snd_pci_quirk ad1988_cfg_tbl[] = {
 static int patch_ad1988(struct hda_codec *codec)
 {
        struct ad198x_spec *spec;
-       int board_config;
+       int err, board_config;
 
        spec = kzalloc(sizeof(*spec), GFP_KERNEL);
        if (spec == NULL)
@@ -2939,7 +2970,7 @@ static int patch_ad1988(struct hda_codec *codec)
 
        if (board_config == AD1988_AUTO) {
                /* automatic parse from the BIOS config */
-               int err = ad1988_parse_auto_config(codec);
+               err = ad1988_parse_auto_config(codec);
                if (err < 0) {
                        ad198x_free(codec);
                        return err;
@@ -2949,6 +2980,13 @@ static int patch_ad1988(struct hda_codec *codec)
                }
        }
 
+       err = snd_hda_attach_beep_device(codec, 0x10);
+       if (err < 0) {
+               ad198x_free(codec);
+               return err;
+       }
+       set_beep_amp(spec, 0x10, 0, HDA_OUTPUT);
+
        switch (board_config) {
        case AD1988_6STACK:
        case AD1988_6STACK_DIG:
@@ -3105,12 +3143,6 @@ static struct snd_kcontrol_new ad1884_base_mixers[] = {
        HDA_CODEC_MUTE("Mic Playback Switch", 0x20, 0x01, HDA_INPUT),
        HDA_CODEC_VOLUME("CD Playback Volume", 0x20, 0x02, HDA_INPUT),
        HDA_CODEC_MUTE("CD Playback Switch", 0x20, 0x02, HDA_INPUT),
-       /*
-       HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x20, 0x03, HDA_INPUT),
-       HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x20, 0x03, HDA_INPUT),
-       HDA_CODEC_VOLUME("Digital Beep Playback Volume", 0x10, 0x0, HDA_OUTPUT),
-       HDA_CODEC_MUTE("Digital Beep Playback Switch", 0x10, 0x0, HDA_OUTPUT),
-       */
        HDA_CODEC_VOLUME("Mic Boost", 0x15, 0x0, HDA_INPUT),
        HDA_CODEC_VOLUME("Front Mic Boost", 0x14, 0x0, HDA_INPUT),
        HDA_CODEC_VOLUME("Capture Volume", 0x0c, 0x0, HDA_OUTPUT),
@@ -3219,7 +3251,7 @@ static const char *ad1884_slave_vols[] = {
        "CD Playback Volume",
        "Internal Mic Playback Volume",
        "Docking Mic Playback Volume"
-       "Beep Playback Volume",
+       /* "Beep Playback Volume", */
        "IEC958 Playback Volume",
        NULL
 };
@@ -3227,6 +3259,7 @@ static const char *ad1884_slave_vols[] = {
 static int patch_ad1884(struct hda_codec *codec)
 {
        struct ad198x_spec *spec;
+       int err;
 
        spec = kzalloc(sizeof(*spec), GFP_KERNEL);
        if (spec == NULL)
@@ -3234,6 +3267,13 @@ static int patch_ad1884(struct hda_codec *codec)
 
        codec->spec = spec;
 
+       err = snd_hda_attach_beep_device(codec, 0x10);
+       if (err < 0) {
+               ad198x_free(codec);
+               return err;
+       }
+       set_beep_amp(spec, 0x10, 0, HDA_OUTPUT);
+
        spec->multiout.max_channels = 2;
        spec->multiout.num_dacs = ARRAY_SIZE(ad1884_dac_nids);
        spec->multiout.dac_nids = ad1884_dac_nids;
@@ -3300,8 +3340,6 @@ static struct snd_kcontrol_new ad1984_thinkpad_mixers[] = {
        HDA_CODEC_VOLUME("Mic Boost", 0x14, 0x0, HDA_INPUT),
        HDA_CODEC_VOLUME("Internal Mic Boost", 0x15, 0x0, HDA_INPUT),
        HDA_CODEC_VOLUME("Docking Mic Boost", 0x25, 0x0, HDA_OUTPUT),
-       HDA_CODEC_VOLUME("Beep Playback Volume", 0x20, 0x03, HDA_INPUT),
-       HDA_CODEC_MUTE("Beep Playback Switch", 0x20, 0x03, HDA_INPUT),
        HDA_CODEC_VOLUME("Capture Volume", 0x0c, 0x0, HDA_OUTPUT),
        HDA_CODEC_MUTE("Capture Switch", 0x0c, 0x0, HDA_OUTPUT),
        HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x0d, 0x0, HDA_OUTPUT),
@@ -3358,10 +3396,6 @@ static struct snd_kcontrol_new ad1984_dell_desktop_mixers[] = {
        HDA_CODEC_MUTE("Front Mic Playback Switch", 0x20, 0x00, HDA_INPUT),
        HDA_CODEC_VOLUME("Line-In Playback Volume", 0x20, 0x01, HDA_INPUT),
        HDA_CODEC_MUTE("Line-In Playback Switch", 0x20, 0x01, HDA_INPUT),
-       /*
-       HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x20, 0x03, HDA_INPUT),
-       HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x20, 0x03, HDA_INPUT),
-       */
        HDA_CODEC_VOLUME("Line-In Boost", 0x15, 0x0, HDA_INPUT),
        HDA_CODEC_VOLUME("Front Mic Boost", 0x14, 0x0, HDA_INPUT),
        HDA_CODEC_VOLUME("Capture Volume", 0x0c, 0x0, HDA_OUTPUT),
@@ -3540,8 +3574,6 @@ static struct snd_kcontrol_new ad1884a_base_mixers[] = {
        HDA_CODEC_MUTE("Mic Playback Switch", 0x20, 0x04, HDA_INPUT),
        HDA_CODEC_VOLUME("CD Playback Volume", 0x20, 0x02, HDA_INPUT),
        HDA_CODEC_MUTE("CD Playback Switch", 0x20, 0x02, HDA_INPUT),
-       HDA_CODEC_VOLUME("Beep Playback Volume", 0x20, 0x03, HDA_INPUT),
-       HDA_CODEC_MUTE("Beep Playback Switch", 0x20, 0x03, HDA_INPUT),
        HDA_CODEC_VOLUME("Front Mic Boost", 0x14, 0x0, HDA_INPUT),
        HDA_CODEC_VOLUME("Line Boost", 0x15, 0x0, HDA_INPUT),
        HDA_CODEC_VOLUME("Mic Boost", 0x25, 0x0, HDA_OUTPUT),
@@ -3674,8 +3706,6 @@ static struct snd_kcontrol_new ad1884a_laptop_mixers[] = {
        HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x20, 0x01, HDA_INPUT),
        HDA_CODEC_VOLUME("Dock Mic Playback Volume", 0x20, 0x04, HDA_INPUT),
        HDA_CODEC_MUTE("Dock Mic Playback Switch", 0x20, 0x04, HDA_INPUT),
-       HDA_CODEC_VOLUME("Beep Playback Volume", 0x20, 0x03, HDA_INPUT),
-       HDA_CODEC_MUTE("Beep Playback Switch", 0x20, 0x03, HDA_INPUT),
        HDA_CODEC_VOLUME("Mic Boost", 0x14, 0x0, HDA_INPUT),
        HDA_CODEC_VOLUME("Internal Mic Boost", 0x15, 0x0, HDA_INPUT),
        HDA_CODEC_VOLUME("Dock Mic Boost", 0x25, 0x0, HDA_OUTPUT),
@@ -3703,8 +3733,6 @@ static struct snd_kcontrol_new ad1884a_mobile_mixers[] = {
        HDA_CODEC_MUTE("Master Playback Switch", 0x21, 0x0, HDA_OUTPUT),
        HDA_CODEC_VOLUME("PCM Playback Volume", 0x20, 0x5, HDA_INPUT),
        HDA_CODEC_MUTE("PCM Playback Switch", 0x20, 0x5, HDA_INPUT),
-       HDA_CODEC_VOLUME("Beep Playback Volume", 0x20, 0x03, HDA_INPUT),
-       HDA_CODEC_MUTE("Beep Playback Switch", 0x20, 0x03, HDA_INPUT),
        HDA_CODEC_VOLUME("Mic Capture Volume", 0x14, 0x0, HDA_INPUT),
        HDA_CODEC_VOLUME("Internal Mic Capture Volume", 0x15, 0x0, HDA_INPUT),
        HDA_CODEC_VOLUME("Capture Volume", 0x0c, 0x0, HDA_OUTPUT),
@@ -3815,8 +3843,6 @@ static struct snd_kcontrol_new ad1984a_thinkpad_mixers[] = {
        HDA_CODEC_MUTE("PCM Playback Switch", 0x20, 0x5, HDA_INPUT),
        HDA_CODEC_VOLUME("Mic Playback Volume", 0x20, 0x00, HDA_INPUT),
        HDA_CODEC_MUTE("Mic Playback Switch", 0x20, 0x00, HDA_INPUT),
-       HDA_CODEC_VOLUME("Beep Playback Volume", 0x20, 0x03, HDA_INPUT),
-       HDA_CODEC_MUTE("Beep Playback Switch", 0x20, 0x03, HDA_INPUT),
        HDA_CODEC_VOLUME("Mic Boost", 0x14, 0x0, HDA_INPUT),
        HDA_CODEC_VOLUME("Internal Mic Boost", 0x17, 0x0, HDA_INPUT),
        HDA_CODEC_VOLUME("Capture Volume", 0x0c, 0x0, HDA_OUTPUT),
@@ -3902,7 +3928,7 @@ static struct snd_pci_quirk ad1884a_cfg_tbl[] = {
 static int patch_ad1884a(struct hda_codec *codec)
 {
        struct ad198x_spec *spec;
-       int board_config;
+       int err, board_config;
 
        spec = kzalloc(sizeof(*spec), GFP_KERNEL);
        if (spec == NULL)
@@ -3910,6 +3936,13 @@ static int patch_ad1884a(struct hda_codec *codec)
 
        codec->spec = spec;
 
+       err = snd_hda_attach_beep_device(codec, 0x10);
+       if (err < 0) {
+               ad198x_free(codec);
+               return err;
+       }
+       set_beep_amp(spec, 0x10, 0, HDA_OUTPUT);
+
        spec->multiout.max_channels = 2;
        spec->multiout.num_dacs = ARRAY_SIZE(ad1884a_dac_nids);
        spec->multiout.dac_nids = ad1884a_dac_nids;
@@ -4064,8 +4097,6 @@ static struct snd_kcontrol_new ad1882_loopback_mixers[] = {
        HDA_CODEC_MUTE("Line Playback Switch", 0x20, 0x04, HDA_INPUT),
        HDA_CODEC_VOLUME("CD Playback Volume", 0x20, 0x06, HDA_INPUT),
        HDA_CODEC_MUTE("CD Playback Switch", 0x20, 0x06, HDA_INPUT),
-       HDA_CODEC_VOLUME("Beep Playback Volume", 0x20, 0x07, HDA_INPUT),
-       HDA_CODEC_MUTE("Beep Playback Switch", 0x20, 0x07, HDA_INPUT),
        { } /* end */
 };
 
@@ -4078,8 +4109,6 @@ static struct snd_kcontrol_new ad1882a_loopback_mixers[] = {
        HDA_CODEC_MUTE("Line Playback Switch", 0x20, 0x01, HDA_INPUT),
        HDA_CODEC_VOLUME("CD Playback Volume", 0x20, 0x06, HDA_INPUT),
        HDA_CODEC_MUTE("CD Playback Switch", 0x20, 0x06, HDA_INPUT),
-       HDA_CODEC_VOLUME("Beep Playback Volume", 0x20, 0x07, HDA_INPUT),
-       HDA_CODEC_MUTE("Beep Playback Switch", 0x20, 0x07, HDA_INPUT),
        HDA_CODEC_VOLUME("Digital Mic Boost", 0x1f, 0x0, HDA_INPUT),
        { } /* end */
 };
@@ -4238,7 +4267,7 @@ static const char *ad1882_models[AD1986A_MODELS] = {
 static int patch_ad1882(struct hda_codec *codec)
 {
        struct ad198x_spec *spec;
-       int board_config;
+       int err, board_config;
 
        spec = kzalloc(sizeof(*spec), GFP_KERNEL);
        if (spec == NULL)
@@ -4246,6 +4275,13 @@ static int patch_ad1882(struct hda_codec *codec)
 
        codec->spec = spec;
 
+       err = snd_hda_attach_beep_device(codec, 0x10);
+       if (err < 0) {
+               ad198x_free(codec);
+               return err;
+       }
+       set_beep_amp(spec, 0x10, 0, HDA_OUTPUT);
+
        spec->multiout.max_channels = 6;
        spec->multiout.num_dacs = 3;
        spec->multiout.dac_nids = ad1882_dac_nids;