Commit 5b46fb03 authored by Linus Torvalds's avatar Linus Torvalds
Browse files
Pull sound fixes from Takashi Iwai:
 "Another collection of small fixes. It's still not quite calm yet, but
  nothing looks scary.

  ALSA core got a few fixes for covering the issues detected by fuzzer
  and the 32bit compat problem of control API, while the rest are all
  device-specific small fixes, including the continued fixes for Tegra"

* tag 'sound-5.16-rc5' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound: (23 commits)
  ALSA: hda/realtek - Add headset Mic support for Lenovo ALC897 platform
  ALSA: usb-audio: Reorder snd_djm_devices[] entries
  ALSA: hda/realtek: Fix quirk for TongFang PHxTxX1
  ALSA: ctl: Fix copy of updated id with element read/write
  ALSA: pcm: oss: Handle missing errors in snd_pcm_oss_change_params*()
  ALSA: pcm: oss: Limit the period size to 16MB
  ALSA: pcm: oss: Fix negative period/buffer sizes
  ASoC: codecs: wsa881x: fix return values from kcontrol put
  ASoC: codecs: wcd934x: return correct value from mixer put
  ASoC: codecs: wcd934x: handle channel mappping list correctly
  ASoC: qdsp6: q6routing: Fix return value from msm_routing_put_audio_mixer
  ASoC: SOF: Intel: Retry codec probing if it fails
  ASoC: amd: fix uninitialized variable in snd_acp6x_probe()
  ASoC: rockchip: i2s_tdm: Dup static DAI template
  ASoC: rt5682s: Fix crash due to out of scope stack vars
  ASoC: rt5682: Fix crash due to out of scope stack vars
  ASoC: tegra: Use normal system sleep for ADX
  ASoC: tegra: Use normal system sleep for AMX
  ASoC: tegra: Use normal system sleep for Mixer
  ASoC: tegra: Use normal system sleep for MVC
  ...
parents 9b302ffe d7f32791
Loading
Loading
Loading
Loading
+3 −0
Original line number Diff line number Diff line
@@ -19,6 +19,9 @@ properties:
  clocks:
    maxItems: 1

  interrupts:
    maxItems: 1

  "#sound-dai-cells":
    const: 0

+3 −0
Original line number Diff line number Diff line
@@ -264,6 +264,7 @@ static int copy_ctl_value_to_user(void __user *userdata,
				  struct snd_ctl_elem_value *data,
				  int type, int count)
{
	struct snd_ctl_elem_value32 __user *data32 = userdata;
	int i, size;

	if (type == SNDRV_CTL_ELEM_TYPE_BOOLEAN ||
@@ -280,6 +281,8 @@ static int copy_ctl_value_to_user(void __user *userdata,
		if (copy_to_user(valuep, data->value.bytes.data, size))
			return -EFAULT;
	}
	if (copy_to_user(&data32->id, &data->id, sizeof(data32->id)))
		return -EFAULT;
	return 0;
}

+25 −12
Original line number Diff line number Diff line
@@ -147,7 +147,7 @@ snd_pcm_hw_param_value_min(const struct snd_pcm_hw_params *params,
 *
 * Return the maximum value for field PAR.
 */
static unsigned int
static int
snd_pcm_hw_param_value_max(const struct snd_pcm_hw_params *params,
			   snd_pcm_hw_param_t var, int *dir)
{
@@ -682,18 +682,24 @@ static int snd_pcm_oss_period_size(struct snd_pcm_substream *substream,
				   struct snd_pcm_hw_params *oss_params,
				   struct snd_pcm_hw_params *slave_params)
{
	size_t s;
	size_t oss_buffer_size, oss_period_size, oss_periods;
	size_t min_period_size, max_period_size;
	ssize_t s;
	ssize_t oss_buffer_size;
	ssize_t oss_period_size, oss_periods;
	ssize_t min_period_size, max_period_size;
	struct snd_pcm_runtime *runtime = substream->runtime;
	size_t oss_frame_size;

	oss_frame_size = snd_pcm_format_physical_width(params_format(oss_params)) *
			 params_channels(oss_params) / 8;

	oss_buffer_size = snd_pcm_hw_param_value_max(slave_params,
						     SNDRV_PCM_HW_PARAM_BUFFER_SIZE,
						     NULL);
	if (oss_buffer_size <= 0)
		return -EINVAL;
	oss_buffer_size = snd_pcm_plug_client_size(substream,
						   snd_pcm_hw_param_value_max(slave_params, SNDRV_PCM_HW_PARAM_BUFFER_SIZE, NULL)) * oss_frame_size;
	if (!oss_buffer_size)
						   oss_buffer_size * oss_frame_size);
	if (oss_buffer_size <= 0)
		return -EINVAL;
	oss_buffer_size = rounddown_pow_of_two(oss_buffer_size);
	if (atomic_read(&substream->mmap_count)) {
@@ -730,7 +736,7 @@ static int snd_pcm_oss_period_size(struct snd_pcm_substream *substream,

	min_period_size = snd_pcm_plug_client_size(substream,
						   snd_pcm_hw_param_value_min(slave_params, SNDRV_PCM_HW_PARAM_PERIOD_SIZE, NULL));
	if (min_period_size) {
	if (min_period_size > 0) {
		min_period_size *= oss_frame_size;
		min_period_size = roundup_pow_of_two(min_period_size);
		if (oss_period_size < min_period_size)
@@ -739,7 +745,7 @@ static int snd_pcm_oss_period_size(struct snd_pcm_substream *substream,

	max_period_size = snd_pcm_plug_client_size(substream,
						   snd_pcm_hw_param_value_max(slave_params, SNDRV_PCM_HW_PARAM_PERIOD_SIZE, NULL));
	if (max_period_size) {
	if (max_period_size > 0) {
		max_period_size *= oss_frame_size;
		max_period_size = rounddown_pow_of_two(max_period_size);
		if (oss_period_size > max_period_size)
@@ -752,7 +758,7 @@ static int snd_pcm_oss_period_size(struct snd_pcm_substream *substream,
		oss_periods = substream->oss.setup.periods;

	s = snd_pcm_hw_param_value_max(slave_params, SNDRV_PCM_HW_PARAM_PERIODS, NULL);
	if (runtime->oss.maxfrags && s > runtime->oss.maxfrags)
	if (s > 0 && runtime->oss.maxfrags && s > runtime->oss.maxfrags)
		s = runtime->oss.maxfrags;
	if (oss_periods > s)
		oss_periods = s;
@@ -878,8 +884,15 @@ static int snd_pcm_oss_change_params_locked(struct snd_pcm_substream *substream)
		err = -EINVAL;
		goto failure;
	}
	choose_rate(substream, sparams, runtime->oss.rate);
	snd_pcm_hw_param_near(substream, sparams, SNDRV_PCM_HW_PARAM_CHANNELS, runtime->oss.channels, NULL);

	err = choose_rate(substream, sparams, runtime->oss.rate);
	if (err < 0)
		goto failure;
	err = snd_pcm_hw_param_near(substream, sparams,
				    SNDRV_PCM_HW_PARAM_CHANNELS,
				    runtime->oss.channels, NULL);
	if (err < 0)
		goto failure;

	format = snd_pcm_oss_format_from(runtime->oss.format);

@@ -1956,7 +1969,7 @@ static int snd_pcm_oss_set_fragment1(struct snd_pcm_substream *substream, unsign
	if (runtime->oss.subdivision || runtime->oss.fragshift)
		return -EINVAL;
	fragshift = val & 0xffff;
	if (fragshift >= 31)
	if (fragshift >= 25) /* should be large enough */
		return -EINVAL;
	runtime->oss.fragshift = fragshift;
	runtime->oss.maxfrags = (val >> 16) & 0xffff;
+62 −18
Original line number Diff line number Diff line
@@ -6503,22 +6503,26 @@ static void alc287_fixup_legion_15imhg05_speakers(struct hda_codec *codec,
/* for alc285_fixup_ideapad_s740_coef() */
#include "ideapad_s740_helper.c"

static void alc256_fixup_tongfang_reset_persistent_settings(struct hda_codec *codec,
static const struct coef_fw alc256_fixup_set_coef_defaults_coefs[] = {
	WRITE_COEF(0x10, 0x0020), WRITE_COEF(0x24, 0x0000),
	WRITE_COEF(0x26, 0x0000), WRITE_COEF(0x29, 0x3000),
	WRITE_COEF(0x37, 0xfe05), WRITE_COEF(0x45, 0x5089),
	{}
};

static void alc256_fixup_set_coef_defaults(struct hda_codec *codec,
					   const struct hda_fixup *fix,
					   int action)
{
	/*
	* A certain other OS sets these coeffs to different values. On at least one TongFang
	* barebone these settings might survive even a cold reboot. So to restore a clean slate the
	* values are explicitly reset to default here. Without this, the external microphone is
	* always in a plugged-in state, while the internal microphone is always in an unplugged
	* state, breaking the ability to use the internal microphone.
	 * A certain other OS sets these coeffs to different values. On at least
	 * one TongFang barebone these settings might survive even a cold
	 * reboot. So to restore a clean slate the values are explicitly reset
	 * to default here. Without this, the external microphone is always in a
	 * plugged-in state, while the internal microphone is always in an
	 * unplugged state, breaking the ability to use the internal microphone.
	 */
	alc_write_coef_idx(codec, 0x24, 0x0000);
	alc_write_coef_idx(codec, 0x26, 0x0000);
	alc_write_coef_idx(codec, 0x29, 0x3000);
	alc_write_coef_idx(codec, 0x37, 0xfe05);
	alc_write_coef_idx(codec, 0x45, 0x5089);
	alc_process_coef_fw(codec, alc256_fixup_set_coef_defaults_coefs);
}

static const struct coef_fw alc233_fixup_no_audio_jack_coefs[] = {
@@ -6759,7 +6763,7 @@ enum {
	ALC287_FIXUP_LEGION_15IMHG05_AUTOMUTE,
	ALC287_FIXUP_YOGA7_14ITL_SPEAKERS,
	ALC287_FIXUP_13S_GEN2_SPEAKERS,
	ALC256_FIXUP_TONGFANG_RESET_PERSISTENT_SETTINGS,
	ALC256_FIXUP_SET_COEF_DEFAULTS,
	ALC256_FIXUP_SYSTEM76_MIC_NO_PRESENCE,
	ALC233_FIXUP_NO_AUDIO_JACK,
};
@@ -8465,9 +8469,9 @@ static const struct hda_fixup alc269_fixups[] = {
		.chained = true,
		.chain_id = ALC269_FIXUP_HEADSET_MODE,
	},
	[ALC256_FIXUP_TONGFANG_RESET_PERSISTENT_SETTINGS] = {
	[ALC256_FIXUP_SET_COEF_DEFAULTS] = {
		.type = HDA_FIXUP_FUNC,
		.v.func = alc256_fixup_tongfang_reset_persistent_settings,
		.v.func = alc256_fixup_set_coef_defaults,
	},
	[ALC245_FIXUP_HP_GPIO_LED] = {
		.type = HDA_FIXUP_FUNC,
@@ -8929,7 +8933,7 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = {
	SND_PCI_QUIRK(0x1b7d, 0xa831, "Ordissimo EVE2 ", ALC269VB_FIXUP_ORDISSIMO_EVE2), /* Also known as Malata PC-B1303 */
	SND_PCI_QUIRK(0x1c06, 0x2013, "Lemote A1802", ALC269_FIXUP_LEMOTE_A1802),
	SND_PCI_QUIRK(0x1c06, 0x2015, "Lemote A190X", ALC269_FIXUP_LEMOTE_A190X),
	SND_PCI_QUIRK(0x1d05, 0x1132, "TongFang PHxTxX1", ALC256_FIXUP_TONGFANG_RESET_PERSISTENT_SETTINGS),
	SND_PCI_QUIRK(0x1d05, 0x1132, "TongFang PHxTxX1", ALC256_FIXUP_SET_COEF_DEFAULTS),
	SND_PCI_QUIRK(0x1d72, 0x1602, "RedmiBook", ALC255_FIXUP_XIAOMI_HEADSET_MIC),
	SND_PCI_QUIRK(0x1d72, 0x1701, "XiaomiNotebook Pro", ALC298_FIXUP_DELL1_MIC_NO_PRESENCE),
	SND_PCI_QUIRK(0x1d72, 0x1901, "RedmiBook 14", ALC256_FIXUP_ASUS_HEADSET_MIC),
@@ -10231,6 +10235,27 @@ static void alc671_fixup_hp_headset_mic2(struct hda_codec *codec,
	}
}

static void alc897_hp_automute_hook(struct hda_codec *codec,
					 struct hda_jack_callback *jack)
{
	struct alc_spec *spec = codec->spec;
	int vref;

	snd_hda_gen_hp_automute(codec, jack);
	vref = spec->gen.hp_jack_present ? (PIN_HP | AC_PINCTL_VREF_100) : PIN_HP;
	snd_hda_codec_write(codec, 0x1b, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
			    vref);
}

static void alc897_fixup_lenovo_headset_mic(struct hda_codec *codec,
				     const struct hda_fixup *fix, int action)
{
	struct alc_spec *spec = codec->spec;
	if (action == HDA_FIXUP_ACT_PRE_PROBE) {
		spec->gen.hp_automute_hook = alc897_hp_automute_hook;
	}
}

static const struct coef_fw alc668_coefs[] = {
	WRITE_COEF(0x01, 0xbebe), WRITE_COEF(0x02, 0xaaaa), WRITE_COEF(0x03,    0x0),
	WRITE_COEF(0x04, 0x0180), WRITE_COEF(0x06,    0x0), WRITE_COEF(0x07, 0x0f80),
@@ -10311,6 +10336,8 @@ enum {
	ALC668_FIXUP_ASUS_NO_HEADSET_MIC,
	ALC668_FIXUP_HEADSET_MIC,
	ALC668_FIXUP_MIC_DET_COEF,
	ALC897_FIXUP_LENOVO_HEADSET_MIC,
	ALC897_FIXUP_HEADSET_MIC_PIN,
};

static const struct hda_fixup alc662_fixups[] = {
@@ -10717,6 +10744,19 @@ static const struct hda_fixup alc662_fixups[] = {
			{}
		},
	},
	[ALC897_FIXUP_LENOVO_HEADSET_MIC] = {
		.type = HDA_FIXUP_FUNC,
		.v.func = alc897_fixup_lenovo_headset_mic,
	},
	[ALC897_FIXUP_HEADSET_MIC_PIN] = {
		.type = HDA_FIXUP_PINS,
		.v.pins = (const struct hda_pintbl[]) {
			{ 0x1a, 0x03a11050 },
			{ }
		},
		.chained = true,
		.chain_id = ALC897_FIXUP_LENOVO_HEADSET_MIC
	},
};

static const struct snd_pci_quirk alc662_fixup_tbl[] = {
@@ -10761,6 +10801,10 @@ static const struct snd_pci_quirk alc662_fixup_tbl[] = {
	SND_PCI_QUIRK(0x144d, 0xc051, "Samsung R720", ALC662_FIXUP_IDEAPAD),
	SND_PCI_QUIRK(0x14cd, 0x5003, "USI", ALC662_FIXUP_USI_HEADSET_MODE),
	SND_PCI_QUIRK(0x17aa, 0x1036, "Lenovo P520", ALC662_FIXUP_LENOVO_MULTI_CODECS),
	SND_PCI_QUIRK(0x17aa, 0x32ca, "Lenovo ThinkCentre M80", ALC897_FIXUP_HEADSET_MIC_PIN),
	SND_PCI_QUIRK(0x17aa, 0x32cb, "Lenovo ThinkCentre M70", ALC897_FIXUP_HEADSET_MIC_PIN),
	SND_PCI_QUIRK(0x17aa, 0x32cf, "Lenovo ThinkCentre M950", ALC897_FIXUP_HEADSET_MIC_PIN),
	SND_PCI_QUIRK(0x17aa, 0x32f7, "Lenovo ThinkCentre M90", ALC897_FIXUP_HEADSET_MIC_PIN),
	SND_PCI_QUIRK(0x17aa, 0x38af, "Lenovo Ideapad Y550P", ALC662_FIXUP_IDEAPAD),
	SND_PCI_QUIRK(0x17aa, 0x3a0d, "Lenovo Ideapad Y550", ALC662_FIXUP_IDEAPAD),
	SND_PCI_QUIRK(0x1849, 0x5892, "ASRock B150M", ALC892_FIXUP_ASROCK_MOBO),
+2 −1
Original line number Diff line number Diff line
@@ -146,10 +146,11 @@ static int snd_acp6x_probe(struct pci_dev *pci,
{
	struct acp6x_dev_data *adata;
	struct platform_device_info pdevinfo[ACP6x_DEVS];
	int ret, index;
	int index = 0;
	int val = 0x00;
	u32 addr;
	unsigned int irqflags;
	int ret;

	irqflags = IRQF_SHARED;
	/* Yellow Carp device check */
Loading