diff options
author | W. Trevor King <wking@tremily.us> | 2015-03-25 03:43:42 -0400 |
---|---|---|
committer | Takashi Iwai <tiwai@suse.de> | 2015-03-25 03:59:00 -0400 |
commit | 4738465c37298cd9228750f7e16aad88af8495c5 (patch) | |
tree | 6a3f1895a34b3c4f6ec5fdc6348a8dd22e0420fe /sound/pci/hda/patch_via.c | |
parent | 44e39b985393e506d82b669c9765e850daed9dc5 (diff) |
ALSA: hda/via - Add beep controls to VIA codecs
My codec has a beep-generating node:
$ cat /proc/asound/card1/codec#0
Codec: VIA VT1802
...
Vendor Id: 0x11068446
Subsystem Id: 0x15587410
Revision Id: 0x100000
...
Node 0x22 [Beep Generator Widget] wcaps 0x70040c: Mono Amp-Out
Amp-Out caps: ofs=0x0a, nsteps=0x12, stepsize=0x05, mute=1
Amp-Out vals: [0x0a]
Power states: D0 D1 D2 D3
Power: setting=D0, actual=D0
...
But I was missing the:
Control: name=...
entries that I need to manage this widget from alsamixer. With this
patch (based on the similar Mono Amp-Out handling in
patch_conexant.c), I get a new:
input: HDA Digital PCBeep as /devices/pci0000:00/0000:00:1b.0/sound/card1/hdaudioC1D0/input15
entry in dmesg and controls to manage that beep:
$ cat /proc/asound/card1/codec#0 | grep -A5 Beep
Node 0x22 [Beep Generator Widget] wcaps 0x70040c: Mono Amp-Out
Control: name="Beep Playback Volume", index=0, device=0
ControlAmp: chs=1, dir=Out, idx=0, ofs=0
Control: name="Beep Playback Switch", index=0, device=0
ControlAmp: chs=1, dir=Out, idx=0, ofs=0
Amp-Out caps: ofs=0x0a, nsteps=0x12, stepsize=0x05, mute=1
Amp-Out vals: [0x12]
Power states: D0 D1 D2 D3
Power: setting=D0, actual=D0
[rebased and modified for the latest tree by tiwai]
Signed-off-by: W. Trevor King <wking@tremily.us>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Diffstat (limited to 'sound/pci/hda/patch_via.c')
-rw-r--r-- | sound/pci/hda/patch_via.c | 61 |
1 files changed, 61 insertions, 0 deletions
diff --git a/sound/pci/hda/patch_via.c b/sound/pci/hda/patch_via.c index a34d7671937f..742087ef378f 100644 --- a/sound/pci/hda/patch_via.c +++ b/sound/pci/hda/patch_via.c | |||
@@ -107,6 +107,8 @@ struct via_spec { | |||
107 | /* work to check hp jack state */ | 107 | /* work to check hp jack state */ |
108 | int hp_work_active; | 108 | int hp_work_active; |
109 | int vt1708_jack_detect; | 109 | int vt1708_jack_detect; |
110 | |||
111 | unsigned int beep_amp; | ||
110 | }; | 112 | }; |
111 | 113 | ||
112 | static enum VIA_HDA_CODEC get_codec_type(struct hda_codec *codec); | 114 | static enum VIA_HDA_CODEC get_codec_type(struct hda_codec *codec); |
@@ -266,6 +268,59 @@ static const struct snd_kcontrol_new via_pin_power_ctl_enum[] = { | |||
266 | {} /* terminator */ | 268 | {} /* terminator */ |
267 | }; | 269 | }; |
268 | 270 | ||
271 | #ifdef CONFIG_SND_HDA_INPUT_BEEP | ||
272 | static inline void set_beep_amp(struct via_spec *spec, hda_nid_t nid, | ||
273 | int idx, int dir) | ||
274 | { | ||
275 | spec->gen.beep_nid = nid; | ||
276 | spec->beep_amp = HDA_COMPOSE_AMP_VAL(nid, 1, idx, dir); | ||
277 | } | ||
278 | |||
279 | /* additional beep mixers; the actual parameters are overwritten at build */ | ||
280 | static const struct snd_kcontrol_new cxt_beep_mixer[] = { | ||
281 | HDA_CODEC_VOLUME_MONO("Beep Playback Volume", 0, 1, 0, HDA_OUTPUT), | ||
282 | HDA_CODEC_MUTE_BEEP_MONO("Beep Playback Switch", 0, 1, 0, HDA_OUTPUT), | ||
283 | { } /* end */ | ||
284 | }; | ||
285 | |||
286 | /* create beep controls if needed */ | ||
287 | static int add_beep_ctls(struct hda_codec *codec) | ||
288 | { | ||
289 | struct via_spec *spec = codec->spec; | ||
290 | int err; | ||
291 | |||
292 | if (spec->beep_amp) { | ||
293 | const struct snd_kcontrol_new *knew; | ||
294 | for (knew = cxt_beep_mixer; knew->name; knew++) { | ||
295 | struct snd_kcontrol *kctl; | ||
296 | kctl = snd_ctl_new1(knew, codec); | ||
297 | if (!kctl) | ||
298 | return -ENOMEM; | ||
299 | kctl->private_value = spec->beep_amp; | ||
300 | err = snd_hda_ctl_add(codec, 0, kctl); | ||
301 | if (err < 0) | ||
302 | return err; | ||
303 | } | ||
304 | } | ||
305 | return 0; | ||
306 | } | ||
307 | |||
308 | static void auto_parse_beep(struct hda_codec *codec) | ||
309 | { | ||
310 | struct via_spec *spec = codec->spec; | ||
311 | hda_nid_t nid; | ||
312 | |||
313 | for_each_hda_codec_node(nid, codec) | ||
314 | if (get_wcaps_type(get_wcaps(codec, nid)) == AC_WID_BEEP) { | ||
315 | set_beep_amp(spec, nid, 0, HDA_OUTPUT); | ||
316 | break; | ||
317 | } | ||
318 | } | ||
319 | #else | ||
320 | #define set_beep_amp(spec, nid, idx, dir) /* NOP */ | ||
321 | #define add_beep_ctls(codec) 0 | ||
322 | #define auto_parse_beep(codec) | ||
323 | #endif | ||
269 | 324 | ||
270 | /* check AA path's mute status */ | 325 | /* check AA path's mute status */ |
271 | static bool is_aa_path_mute(struct hda_codec *codec) | 326 | static bool is_aa_path_mute(struct hda_codec *codec) |
@@ -352,6 +407,10 @@ static int via_build_controls(struct hda_codec *codec) | |||
352 | if (err < 0) | 407 | if (err < 0) |
353 | return err; | 408 | return err; |
354 | 409 | ||
410 | err = add_beep_ctls(codec); | ||
411 | if (err < 0) | ||
412 | return err; | ||
413 | |||
355 | spec->mixers[spec->num_mixers++] = via_pin_power_ctl_enum; | 414 | spec->mixers[spec->num_mixers++] = via_pin_power_ctl_enum; |
356 | 415 | ||
357 | for (i = 0; i < spec->num_mixers; i++) { | 416 | for (i = 0; i < spec->num_mixers; i++) { |
@@ -512,6 +571,8 @@ static int via_parse_auto_config(struct hda_codec *codec) | |||
512 | if (err < 0) | 571 | if (err < 0) |
513 | return err; | 572 | return err; |
514 | 573 | ||
574 | auto_parse_beep(codec); | ||
575 | |||
515 | err = snd_hda_gen_parse_auto_config(codec, &spec->gen.autocfg); | 576 | err = snd_hda_gen_parse_auto_config(codec, &spec->gen.autocfg); |
516 | if (err < 0) | 577 | if (err < 0) |
517 | return err; | 578 | return err; |