Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit cd80bc6f authored by Takashi Iwai's avatar Takashi Iwai
Browse files

Merge branch 'topic/fix/hda' into topic/hda

Conflicts:
	sound/pci/hda/patch_sigmatel.c
parents c4da29ca 6a12afb5
Loading
Loading
Loading
Loading
+8 −0
Original line number Diff line number Diff line
@@ -37,6 +37,9 @@ static void snd_hda_generate_beep(struct work_struct *work)
		container_of(work, struct hda_beep, beep_work);
	struct hda_codec *codec = beep->codec;

	if (!beep->enabled)
		return;

	/* generate tone */
	snd_hda_codec_write_cache(codec, beep->nid, 0,
			AC_VERB_SET_BEEP_CONTROL, beep->tone);
@@ -85,6 +88,10 @@ int snd_hda_attach_beep_device(struct hda_codec *codec, int nid)
	snprintf(beep->phys, sizeof(beep->phys),
		"card%d/codec#%d/beep0", codec->bus->card->number, codec->addr);
	input_dev = input_allocate_device();
	if (!input_dev) {
		kfree(beep);
		return -ENOMEM;
	}

	/* setup digital beep device */
	input_dev->name = "HDA Digital PCBeep";
@@ -115,6 +122,7 @@ int snd_hda_attach_beep_device(struct hda_codec *codec, int nid)
	beep->nid = nid;
	beep->dev = input_dev;
	beep->codec = codec;
	beep->enabled = 1;
	codec->beep = beep;

	INIT_WORK(&beep->beep_work, &snd_hda_generate_beep);
+1 −0
Original line number Diff line number Diff line
@@ -31,6 +31,7 @@ struct hda_beep {
	char phys[32];
	int tone;
	int nid;
	int enabled;
	struct work_struct beep_work; /* scheduled task for beep event */
};

+63 −6
Original line number Diff line number Diff line
@@ -2608,8 +2608,10 @@ static struct snd_kcontrol_new stac92xx_control_templates[] = {
};

/* add dynamic controls */
static int stac92xx_add_control_idx(struct sigmatel_spec *spec, int type,
		int idx, const char *name, unsigned long val)
static int stac92xx_add_control_temp(struct sigmatel_spec *spec,
				     struct snd_kcontrol_new *ktemp,
				     int idx, const char *name,
				     unsigned long val)
{
	struct snd_kcontrol_new *knew;

@@ -2617,7 +2619,7 @@ static int stac92xx_add_control_idx(struct sigmatel_spec *spec, int type,
	knew = snd_array_new(&spec->kctls);
	if (!knew)
		return -ENOMEM;
	*knew = stac92xx_control_templates[type];
	*knew = *ktemp;
	knew->index = idx;
	knew->name = kstrdup(name, GFP_KERNEL);
	if (!knew->name)
@@ -2626,9 +2628,18 @@ static int stac92xx_add_control_idx(struct sigmatel_spec *spec, int type,
	return 0;
}

static inline int stac92xx_add_control_idx(struct sigmatel_spec *spec,
					   int type, int idx, const char *name,
					   unsigned long val)
{
	return stac92xx_add_control_temp(spec,
					 &stac92xx_control_templates[type],
					 idx, name, val);
}


/* add dynamic controls */
static int stac92xx_add_control(struct sigmatel_spec *spec, int type,
static inline int stac92xx_add_control(struct sigmatel_spec *spec, int type,
				       const char *name, unsigned long val)
{
	return stac92xx_add_control_idx(spec, type, 0, name, val);
@@ -3071,6 +3082,43 @@ static int stac92xx_auto_create_beep_ctls(struct hda_codec *codec,
	return 0;
}

#ifdef CONFIG_SND_HDA_INPUT_BEEP
#define stac92xx_dig_beep_switch_info snd_ctl_boolean_mono_info

static int stac92xx_dig_beep_switch_get(struct snd_kcontrol *kcontrol,
					struct snd_ctl_elem_value *ucontrol)
{
	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
	ucontrol->value.integer.value[0] = codec->beep->enabled;
	return 0;
}

static int stac92xx_dig_beep_switch_put(struct snd_kcontrol *kcontrol,
					struct snd_ctl_elem_value *ucontrol)
{
	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
	int enabled = !!ucontrol->value.integer.value[0];
	if (codec->beep->enabled != enabled) {
		codec->beep->enabled = enabled;
		return 1;
	}
	return 0;
}

static struct snd_kcontrol_new stac92xx_dig_beep_ctrl = {
	.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
	.info = stac92xx_dig_beep_switch_info,
	.get = stac92xx_dig_beep_switch_get,
	.put = stac92xx_dig_beep_switch_put,
};

static int stac92xx_beep_switch_ctl(struct hda_codec *codec)
{
	return stac92xx_add_control_temp(codec->spec, &stac92xx_dig_beep_ctrl,
					 0, "PC Beep Playback Switch", 0);
}
#endif

static int stac92xx_auto_create_mux_input_ctls(struct hda_codec *codec)
{
	struct sigmatel_spec *spec = codec->spec;
@@ -3377,6 +3425,7 @@ static int stac92xx_parse_auto_config(struct hda_codec *codec, hda_nid_t dig_out
#ifdef CONFIG_SND_HDA_INPUT_BEEP
	if (spec->digbeep_nid > 0) {
		hda_nid_t nid = spec->digbeep_nid;
		unsigned int caps;

		err = stac92xx_auto_create_beep_ctls(codec, nid);
		if (err < 0)
@@ -3384,6 +3433,14 @@ static int stac92xx_parse_auto_config(struct hda_codec *codec, hda_nid_t dig_out
		err = snd_hda_attach_beep_device(codec, nid);
		if (err < 0)
			return err;
		/* if no beep switch is available, make its own one */
		caps = query_amp_caps(codec, nid, HDA_OUTPUT);
		if (codec->beep &&
		    !((caps & AC_AMPCAP_MUTE) >> AC_AMPCAP_MUTE_SHIFT)) {
			err = stac92xx_beep_switch_ctl(codec);
			if (err < 0)
				return err;
		}
	}
#endif