diff mbox

[v2] ALSA: hda/via - Add beep controls to VIA codecs

Message ID 75dc1612e1a507e7f89549e70f83e303d78370dc.1427269200.git.wking@tremily.us (mailing list archive)
State New, archived
Headers show

Commit Message

W. Trevor King March 25, 2015, 7:43 a.m. UTC
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

Signed-off-by: W. Trevor King <wking@tremily.us>
---
On Wed, Mar 25, 2015 at 08:15:51AM +0100, Takashi Iwai wrote:
> Care to brush up your patch as a formal form to be merged to upstream?
> There are a few conflicts with the latest sound.git tree code, but I
> can manage to resolve them.

Done.  The only change since v1 is rebasing from v3.19 to the current
sound.git master, resolving some trivial conflicts with 688b12cc
(ALSA: hda - Use the new power control for VIA codecs, 2015-03-17).
If you feel inclined to make further edits to my commit message,
you have my permission.

> Later on, we can move the common code to the generic parser (with yet
> some behavior flag), but it can be done by another patch.

Works for me.

 sound/pci/hda/patch_via.c | 61 +++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 61 insertions(+)

Comments

Takashi Iwai March 25, 2015, 8:01 a.m. UTC | #1
At Wed, 25 Mar 2015 00:43:42 -0700,
W. Trevor King wrote:
> 
> 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
> 
> Signed-off-by: W. Trevor King <wking@tremily.us>
> ---
> On Wed, Mar 25, 2015 at 08:15:51AM +0100, Takashi Iwai wrote:
> > Care to brush up your patch as a formal form to be merged to upstream?
> > There are a few conflicts with the latest sound.git tree code, but I
> > can manage to resolve them.
> 
> Done.  The only change since v1 is rebasing from v3.19 to the current
> sound.git master, resolving some trivial conflicts with 688b12cc
> (ALSA: hda - Use the new power control for VIA codecs, 2015-03-17).
> If you feel inclined to make further edits to my commit message,
> you have my permission.
> 
> > Later on, we can move the common code to the generic parser (with yet
> > some behavior flag), but it can be done by another patch.
> 
> Works for me.

OK, I applied the patch with a slight modification.


thanks,

Takashi

> 
>  sound/pci/hda/patch_via.c | 61 +++++++++++++++++++++++++++++++++++++++++++++++
>  1 file changed, 61 insertions(+)
> 
> diff --git a/sound/pci/hda/patch_via.c b/sound/pci/hda/patch_via.c
> index a34d767..3f63c34f 100644
> --- a/sound/pci/hda/patch_via.c
> +++ b/sound/pci/hda/patch_via.c
> @@ -107,6 +107,8 @@ struct via_spec {
>  	/* work to check hp jack state */
>  	int hp_work_active;
>  	int vt1708_jack_detect;
> +
> +	unsigned int beep_amp;
>  };
>  
>  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[] = {
>  	{} /* terminator */
>  };
>  
> +#ifdef CONFIG_SND_HDA_INPUT_BEEP
> +static inline void set_beep_amp(struct via_spec *spec, hda_nid_t nid,
> +				int idx, int dir)
> +{
> +	spec->gen.beep_nid = nid;
> +	spec->beep_amp = HDA_COMPOSE_AMP_VAL(nid, 1, idx, dir);
> +}
> +/* additional beep mixers; the actual parameters are overwritten at build */
> +static const struct snd_kcontrol_new cxt_beep_mixer[] = {
> +	HDA_CODEC_VOLUME_MONO("Beep Playback Volume", 0, 1, 0, HDA_OUTPUT),
> +	HDA_CODEC_MUTE_BEEP_MONO("Beep Playback Switch", 0, 1, 0, HDA_OUTPUT),
> +	{ } /* end */
> +};
> +
> +/* create beep controls if needed */
> +static int add_beep_ctls(struct hda_codec *codec)
> +{
> +	struct via_spec *spec = codec->spec;
> +	int err;
> +
> +	if (spec->beep_amp) {
> +		const struct snd_kcontrol_new *knew;
> +		for (knew = cxt_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, 0, kctl);
> +			if (err < 0)
> +				return err;
> +		}
> +	}
> +	return 0;
> +}
> +
> +static void auto_parse_beep(struct hda_codec *codec)
> +{
> +	struct via_spec *spec = codec->spec;
> +	hda_nid_t nid, end_nid;
> +
> +	end_nid = codec->start_nid + codec->num_nodes;
> +	for (nid = codec->start_nid; nid < end_nid; nid++)
> +		if (get_wcaps_type(get_wcaps(codec, nid)) == AC_WID_BEEP) {
> +			set_beep_amp(spec, nid, 0, HDA_OUTPUT);
> +			break;
> +		}
> +}
> +#else
> +#define set_beep_amp(spec, nid, idx, dir) /* NOP */
> +#define add_beep_ctls(codec)	0
> +#define auto_parse_beep(codec)
> +#endif
>  
>  /* check AA path's mute status */
>  static bool is_aa_path_mute(struct hda_codec *codec)
> @@ -352,6 +407,10 @@ static int via_build_controls(struct hda_codec *codec)
>  	if (err < 0)
>  		return err;
>  
> +	err = add_beep_ctls(codec);
> +	if (err < 0)
> +		return err;
> +
>  	spec->mixers[spec->num_mixers++] = via_pin_power_ctl_enum;
>  
>  	for (i = 0; i < spec->num_mixers; i++) {
> @@ -512,6 +571,8 @@ static int via_parse_auto_config(struct hda_codec *codec)
>  	if (err < 0)
>  		return err;
>  
> +	auto_parse_beep(codec);
> +
>  	err = snd_hda_gen_parse_auto_config(codec, &spec->gen.autocfg);
>  	if (err < 0)
>  		return err;
> -- 
> 2.1.0.60.g85f0837
>
W. Trevor King March 25, 2015, 8:10 a.m. UTC | #2
On Wed, Mar 25, 2015 at 09:01:38AM +0100, Takashi Iwai wrote:
> OK, I applied the patch with a slight modification.

4738465c looks good to me.  I should have thought to re-check
patch_conexant.c to see if the code I'd copied had changed.  I'm
looking forward to having this all factored out into a generic
location :).

Thanks,
Trevor
Takashi Iwai March 25, 2015, 8:32 a.m. UTC | #3
At Wed, 25 Mar 2015 01:10:03 -0700,
W. Trevor King wrote:
> 
> On Wed, Mar 25, 2015 at 09:01:38AM +0100, Takashi Iwai wrote:
> > OK, I applied the patch with a slight modification.
> 
> 4738465c looks good to me.  I should have thought to re-check
> patch_conexant.c to see if the code I'd copied had changed.  I'm
> looking forward to having this all factored out into a generic
> location :).

Feel free to work on it by yourself, too ;)


Takashi
diff mbox

Patch

diff --git a/sound/pci/hda/patch_via.c b/sound/pci/hda/patch_via.c
index a34d767..3f63c34f 100644
--- a/sound/pci/hda/patch_via.c
+++ b/sound/pci/hda/patch_via.c
@@ -107,6 +107,8 @@  struct via_spec {
 	/* work to check hp jack state */
 	int hp_work_active;
 	int vt1708_jack_detect;
+
+	unsigned int beep_amp;
 };
 
 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[] = {
 	{} /* terminator */
 };
 
+#ifdef CONFIG_SND_HDA_INPUT_BEEP
+static inline void set_beep_amp(struct via_spec *spec, hda_nid_t nid,
+				int idx, int dir)
+{
+	spec->gen.beep_nid = nid;
+	spec->beep_amp = HDA_COMPOSE_AMP_VAL(nid, 1, idx, dir);
+}
+/* additional beep mixers; the actual parameters are overwritten at build */
+static const struct snd_kcontrol_new cxt_beep_mixer[] = {
+	HDA_CODEC_VOLUME_MONO("Beep Playback Volume", 0, 1, 0, HDA_OUTPUT),
+	HDA_CODEC_MUTE_BEEP_MONO("Beep Playback Switch", 0, 1, 0, HDA_OUTPUT),
+	{ } /* end */
+};
+
+/* create beep controls if needed */
+static int add_beep_ctls(struct hda_codec *codec)
+{
+	struct via_spec *spec = codec->spec;
+	int err;
+
+	if (spec->beep_amp) {
+		const struct snd_kcontrol_new *knew;
+		for (knew = cxt_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, 0, kctl);
+			if (err < 0)
+				return err;
+		}
+	}
+	return 0;
+}
+
+static void auto_parse_beep(struct hda_codec *codec)
+{
+	struct via_spec *spec = codec->spec;
+	hda_nid_t nid, end_nid;
+
+	end_nid = codec->start_nid + codec->num_nodes;
+	for (nid = codec->start_nid; nid < end_nid; nid++)
+		if (get_wcaps_type(get_wcaps(codec, nid)) == AC_WID_BEEP) {
+			set_beep_amp(spec, nid, 0, HDA_OUTPUT);
+			break;
+		}
+}
+#else
+#define set_beep_amp(spec, nid, idx, dir) /* NOP */
+#define add_beep_ctls(codec)	0
+#define auto_parse_beep(codec)
+#endif
 
 /* check AA path's mute status */
 static bool is_aa_path_mute(struct hda_codec *codec)
@@ -352,6 +407,10 @@  static int via_build_controls(struct hda_codec *codec)
 	if (err < 0)
 		return err;
 
+	err = add_beep_ctls(codec);
+	if (err < 0)
+		return err;
+
 	spec->mixers[spec->num_mixers++] = via_pin_power_ctl_enum;
 
 	for (i = 0; i < spec->num_mixers; i++) {
@@ -512,6 +571,8 @@  static int via_parse_auto_config(struct hda_codec *codec)
 	if (err < 0)
 		return err;
 
+	auto_parse_beep(codec);
+
 	err = snd_hda_gen_parse_auto_config(codec, &spec->gen.autocfg);
 	if (err < 0)
 		return err;