Commit 529b10c0 authored by Linus Torvalds's avatar Linus Torvalds
Browse files
Pull sound fixes from Takashi Iwai:
 "A collection of device-specific small fixes: a series of fixes for
  TAS2781 HD-audio codec, ASoC SOF, Cirrus CS35L56 and a couple of
  legacy drivers"

* tag 'sound-6.9-rc2' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound:
  ALSA: hda/tas2781: remove useless dev_dbg from playback_hook
  ALSA: hda/tas2781: add debug statements to kcontrols
  ALSA: hda/tas2781: add locks to kcontrols
  ALSA: hda/tas2781: remove digital gain kcontrol
  ALSA: aoa: avoid false-positive format truncation warning
  ALSA: sh: aica: reorder cleanup operations to avoid UAF bugs
  ALSA: hda: cs35l56: Set the init_done flag before component_add()
  ALSA: hda: cs35l56: Raise device name message log level
  ASoC: SOF: ipc4-topology: support NHLT device type
  ALSA: hda: intel-nhlt: add intel_nhlt_ssp_device_type() function
parents 6e7a2ffd 1506d961
Loading
Loading
Loading
Loading
+10 −0
Original line number Diff line number Diff line
@@ -143,6 +143,9 @@ intel_nhlt_get_endpoint_blob(struct device *dev, struct nhlt_acpi_table *nhlt,
			     u32 bus_id, u8 link_type, u8 vbps, u8 bps,
			     u8 num_ch, u32 rate, u8 dir, u8 dev_type);

int intel_nhlt_ssp_device_type(struct device *dev, struct nhlt_acpi_table *nhlt,
			       u8 virtual_bus_id);

#else

static inline struct nhlt_acpi_table *intel_nhlt_init(struct device *dev)
@@ -184,6 +187,13 @@ intel_nhlt_get_endpoint_blob(struct device *dev, struct nhlt_acpi_table *nhlt,
	return NULL;
}

static inline int intel_nhlt_ssp_device_type(struct device *dev,
					     struct nhlt_acpi_table *nhlt,
					     u8 virtual_bus_id)
{
	return -EINVAL;
}

#endif

#endif
+1 −1
Original line number Diff line number Diff line
@@ -158,7 +158,7 @@ static int i2sbus_add_dev(struct macio_dev *macio,
	struct device_node *child, *sound = NULL;
	struct resource *r;
	int i, layout = 0, rlen, ok = force;
	char node_name[6];
	char node_name[8];
	static const char *rnames[] = { "i2sbus: %pOFn (control)",
					"i2sbus: %pOFn (tx)",
					"i2sbus: %pOFn (rx)" };
+26 −0
Original line number Diff line number Diff line
@@ -343,3 +343,29 @@ intel_nhlt_get_endpoint_blob(struct device *dev, struct nhlt_acpi_table *nhlt,
	return NULL;
}
EXPORT_SYMBOL(intel_nhlt_get_endpoint_blob);

int intel_nhlt_ssp_device_type(struct device *dev, struct nhlt_acpi_table *nhlt,
			       u8 virtual_bus_id)
{
	struct nhlt_endpoint *epnt;
	int i;

	if (!nhlt)
		return -EINVAL;

	epnt = (struct nhlt_endpoint *)nhlt->desc;
	for (i = 0; i < nhlt->endpoint_count; i++) {
		/* for SSP link the virtual bus id is the SSP port number */
		if (epnt->linktype == NHLT_LINK_SSP &&
		    epnt->virtual_bus_id == virtual_bus_id) {
			dev_dbg(dev, "SSP%d: dev_type=%d\n", virtual_bus_id,
				epnt->device_type);
			return epnt->device_type;
		}

		epnt = (struct nhlt_endpoint *)((u8 *)epnt + epnt->length);
	}

	return -EINVAL;
}
EXPORT_SYMBOL(intel_nhlt_ssp_device_type);
+4 −4
Original line number Diff line number Diff line
@@ -1024,7 +1024,7 @@ int cs35l56_hda_common_probe(struct cs35l56_hda *cs35l56, int hid, int id)
		goto err;
	}

	dev_dbg(cs35l56->base.dev, "DSP system name: '%s', amp name: '%s'\n",
	dev_info(cs35l56->base.dev, "DSP system name: '%s', amp name: '%s'\n",
		 cs35l56->system_name, cs35l56->amp_name);

	regmap_multi_reg_write(cs35l56->base.regmap, cs35l56_hda_dai_config,
@@ -1045,14 +1045,14 @@ int cs35l56_hda_common_probe(struct cs35l56_hda *cs35l56, int hid, int id)
	pm_runtime_mark_last_busy(cs35l56->base.dev);
	pm_runtime_enable(cs35l56->base.dev);

	cs35l56->base.init_done = true;

	ret = component_add(cs35l56->base.dev, &cs35l56_hda_comp_ops);
	if (ret) {
		dev_err(cs35l56->base.dev, "Register component failed: %d\n", ret);
		goto pm_err;
	}

	cs35l56->base.init_done = true;

	return 0;

pm_err:
+77 −41
Original line number Diff line number Diff line
@@ -89,7 +89,7 @@ struct tas2781_hda {
	struct snd_kcontrol *dsp_prog_ctl;
	struct snd_kcontrol *dsp_conf_ctl;
	struct snd_kcontrol *prof_ctl;
	struct snd_kcontrol *snd_ctls[3];
	struct snd_kcontrol *snd_ctls[2];
};

static int tas2781_get_i2c_res(struct acpi_resource *ares, void *data)
@@ -161,8 +161,6 @@ static void tas2781_hda_playback_hook(struct device *dev, int action)
		pm_runtime_put_autosuspend(dev);
		break;
	default:
		dev_dbg(tas_hda->dev, "Playback action not supported: %d\n",
			action);
		break;
	}
}
@@ -185,8 +183,15 @@ static int tasdevice_get_profile_id(struct snd_kcontrol *kcontrol,
{
	struct tasdevice_priv *tas_priv = snd_kcontrol_chip(kcontrol);

	mutex_lock(&tas_priv->codec_lock);

	ucontrol->value.integer.value[0] = tas_priv->rcabin.profile_cfg_id;

	dev_dbg(tas_priv->dev, "%s: kcontrol %s: %d\n",
		__func__, kcontrol->id.name, tas_priv->rcabin.profile_cfg_id);

	mutex_unlock(&tas_priv->codec_lock);

	return 0;
}

@@ -200,11 +205,19 @@ static int tasdevice_set_profile_id(struct snd_kcontrol *kcontrol,

	val = clamp(nr_profile, 0, max);

	mutex_lock(&tas_priv->codec_lock);

	dev_dbg(tas_priv->dev, "%s: kcontrol %s: %d -> %d\n",
		__func__, kcontrol->id.name,
		tas_priv->rcabin.profile_cfg_id, val);

	if (tas_priv->rcabin.profile_cfg_id != val) {
		tas_priv->rcabin.profile_cfg_id = val;
		ret = 1;
	}

	mutex_unlock(&tas_priv->codec_lock);

	return ret;
}

@@ -241,8 +254,15 @@ static int tasdevice_program_get(struct snd_kcontrol *kcontrol,
{
	struct tasdevice_priv *tas_priv = snd_kcontrol_chip(kcontrol);

	mutex_lock(&tas_priv->codec_lock);

	ucontrol->value.integer.value[0] = tas_priv->cur_prog;

	dev_dbg(tas_priv->dev, "%s: kcontrol %s: %d\n",
		__func__, kcontrol->id.name, tas_priv->cur_prog);

	mutex_unlock(&tas_priv->codec_lock);

	return 0;
}

@@ -257,11 +277,18 @@ static int tasdevice_program_put(struct snd_kcontrol *kcontrol,

	val = clamp(nr_program, 0, max);

	mutex_lock(&tas_priv->codec_lock);

	dev_dbg(tas_priv->dev, "%s: kcontrol %s: %d -> %d\n",
		__func__, kcontrol->id.name, tas_priv->cur_prog, val);

	if (tas_priv->cur_prog != val) {
		tas_priv->cur_prog = val;
		ret = 1;
	}

	mutex_unlock(&tas_priv->codec_lock);

	return ret;
}

@@ -270,8 +297,15 @@ static int tasdevice_config_get(struct snd_kcontrol *kcontrol,
{
	struct tasdevice_priv *tas_priv = snd_kcontrol_chip(kcontrol);

	mutex_lock(&tas_priv->codec_lock);

	ucontrol->value.integer.value[0] = tas_priv->cur_conf;

	dev_dbg(tas_priv->dev, "%s: kcontrol %s: %d\n",
		__func__, kcontrol->id.name, tas_priv->cur_conf);

	mutex_unlock(&tas_priv->codec_lock);

	return 0;
}

@@ -286,54 +320,39 @@ static int tasdevice_config_put(struct snd_kcontrol *kcontrol,

	val = clamp(nr_config, 0, max);

	mutex_lock(&tas_priv->codec_lock);

	dev_dbg(tas_priv->dev, "%s: kcontrol %s: %d -> %d\n",
		__func__, kcontrol->id.name, tas_priv->cur_conf, val);

	if (tas_priv->cur_conf != val) {
		tas_priv->cur_conf = val;
		ret = 1;
	}

	mutex_unlock(&tas_priv->codec_lock);

	return ret;
}

/*
 * tas2781_digital_getvol - get the volum control
 * @kcontrol: control pointer
 * @ucontrol: User data
 * Customer Kcontrol for tas2781 is primarily for regmap booking, paging
 * depends on internal regmap mechanism.
 * tas2781 contains book and page two-level register map, especially
 * book switching will set the register BXXP00R7F, after switching to the
 * correct book, then leverage the mechanism for paging to access the
 * register.
 */
static int tas2781_digital_getvol(struct snd_kcontrol *kcontrol,
static int tas2781_amp_getvol(struct snd_kcontrol *kcontrol,
	struct snd_ctl_elem_value *ucontrol)
{
	struct tasdevice_priv *tas_priv = snd_kcontrol_chip(kcontrol);
	struct soc_mixer_control *mc =
		(struct soc_mixer_control *)kcontrol->private_value;
	int ret;

	return tasdevice_digital_getvol(tas_priv, ucontrol, mc);
}
	mutex_lock(&tas_priv->codec_lock);

static int tas2781_amp_getvol(struct snd_kcontrol *kcontrol,
	struct snd_ctl_elem_value *ucontrol)
{
	struct tasdevice_priv *tas_priv = snd_kcontrol_chip(kcontrol);
	struct soc_mixer_control *mc =
		(struct soc_mixer_control *)kcontrol->private_value;
	ret = tasdevice_amp_getvol(tas_priv, ucontrol, mc);

	return tasdevice_amp_getvol(tas_priv, ucontrol, mc);
}
	dev_dbg(tas_priv->dev, "%s: kcontrol %s: %ld\n",
		__func__, kcontrol->id.name, ucontrol->value.integer.value[0]);

static int tas2781_digital_putvol(struct snd_kcontrol *kcontrol,
	struct snd_ctl_elem_value *ucontrol)
{
	struct tasdevice_priv *tas_priv = snd_kcontrol_chip(kcontrol);
	struct soc_mixer_control *mc =
		(struct soc_mixer_control *)kcontrol->private_value;
	mutex_unlock(&tas_priv->codec_lock);

	/* The check of the given value is in tasdevice_digital_putvol. */
	return tasdevice_digital_putvol(tas_priv, ucontrol, mc);
	return ret;
}

static int tas2781_amp_putvol(struct snd_kcontrol *kcontrol,
@@ -342,9 +361,19 @@ static int tas2781_amp_putvol(struct snd_kcontrol *kcontrol,
	struct tasdevice_priv *tas_priv = snd_kcontrol_chip(kcontrol);
	struct soc_mixer_control *mc =
		(struct soc_mixer_control *)kcontrol->private_value;
	int ret;

	mutex_lock(&tas_priv->codec_lock);

	dev_dbg(tas_priv->dev, "%s: kcontrol %s: -> %ld\n",
		__func__, kcontrol->id.name, ucontrol->value.integer.value[0]);

	/* The check of the given value is in tasdevice_amp_putvol. */
	return tasdevice_amp_putvol(tas_priv, ucontrol, mc);
	ret = tasdevice_amp_putvol(tas_priv, ucontrol, mc);

	mutex_unlock(&tas_priv->codec_lock);

	return ret;
}

static int tas2781_force_fwload_get(struct snd_kcontrol *kcontrol,
@@ -352,9 +381,13 @@ static int tas2781_force_fwload_get(struct snd_kcontrol *kcontrol,
{
	struct tasdevice_priv *tas_priv = snd_kcontrol_chip(kcontrol);

	mutex_lock(&tas_priv->codec_lock);

	ucontrol->value.integer.value[0] = (int)tas_priv->force_fwload_status;
	dev_dbg(tas_priv->dev, "%s : Force FWload %s\n", __func__,
			tas_priv->force_fwload_status ? "ON" : "OFF");
	dev_dbg(tas_priv->dev, "%s: kcontrol %s: %d\n",
		__func__, kcontrol->id.name, tas_priv->force_fwload_status);

	mutex_unlock(&tas_priv->codec_lock);

	return 0;
}
@@ -365,14 +398,20 @@ static int tas2781_force_fwload_put(struct snd_kcontrol *kcontrol,
	struct tasdevice_priv *tas_priv = snd_kcontrol_chip(kcontrol);
	bool change, val = (bool)ucontrol->value.integer.value[0];

	mutex_lock(&tas_priv->codec_lock);

	dev_dbg(tas_priv->dev, "%s: kcontrol %s: %d -> %d\n",
		__func__, kcontrol->id.name,
		tas_priv->force_fwload_status, val);

	if (tas_priv->force_fwload_status == val)
		change = false;
	else {
		change = true;
		tas_priv->force_fwload_status = val;
	}
	dev_dbg(tas_priv->dev, "%s : Force FWload %s\n", __func__,
		tas_priv->force_fwload_status ? "ON" : "OFF");

	mutex_unlock(&tas_priv->codec_lock);

	return change;
}
@@ -381,9 +420,6 @@ static const struct snd_kcontrol_new tas2781_snd_controls[] = {
	ACARD_SINGLE_RANGE_EXT_TLV("Speaker Analog Gain", TAS2781_AMP_LEVEL,
		1, 0, 20, 0, tas2781_amp_getvol,
		tas2781_amp_putvol, amp_vol_tlv),
	ACARD_SINGLE_RANGE_EXT_TLV("Speaker Digital Gain", TAS2781_DVC_LVL,
		0, 0, 200, 1, tas2781_digital_getvol,
		tas2781_digital_putvol, dvc_tlv),
	ACARD_SINGLE_BOOL_EXT("Speaker Force Firmware Load", 0,
		tas2781_force_fwload_get, tas2781_force_fwload_put),
};
Loading