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

Commit 486bc794 authored by Linus Torvalds's avatar Linus Torvalds
Browse files
* 'fix/asoc' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound:
  ASoC: wm2000: Fix use-after-free - don't release_firmware() twice on error
  ASoC: wm8958: Use correct format string in dev_err() call
  ASoC: wm8996: Call _POST_PMU callback for CPVDD
  ASoC: mxs: Fix mxs-saif timeout
  ASoC: Disable register synchronisation for low frequency WM8996 SYSCLK
  ASoC: Don't go through cache when applying WM5100 rev A updates
  ASoC: Mark WM5100 register map cache only when going into BIAS_OFF
  ASoC: tlv320aic32x4: always enable analouge block
  ASoC: tlv320aic32x4: always enable dividers
  ASoC: sgtl5000: Fix wrong register name in restore
parents 7ca4e8c4 c83f1d7e
Loading
Loading
Loading
Loading
+13 −4
Original line number Diff line number Diff line
@@ -987,12 +987,12 @@ static int sgtl5000_restore_regs(struct snd_soc_codec *codec)
	/* restore regular registers */
	for (reg = 0; reg <= SGTL5000_CHIP_SHORT_CTRL; reg += 2) {

		/* this regs depends on the others */
		/* These regs should restore in particular order */
		if (reg == SGTL5000_CHIP_ANA_POWER ||
			reg == SGTL5000_CHIP_CLK_CTRL ||
			reg == SGTL5000_CHIP_LINREG_CTRL ||
			reg == SGTL5000_CHIP_LINE_OUT_CTRL ||
			reg == SGTL5000_CHIP_CLK_CTRL)
			reg == SGTL5000_CHIP_REF_CTRL)
			continue;

		snd_soc_write(codec, reg, cache[reg]);
@@ -1003,8 +1003,17 @@ static int sgtl5000_restore_regs(struct snd_soc_codec *codec)
		snd_soc_write(codec, reg, cache[reg]);

	/*
	 * restore power and other regs according
	 * to set_power() and set_clock()
	 * restore these regs according to the power setting sequence in
	 * sgtl5000_set_power_regs() and clock setting sequence in
	 * sgtl5000_set_clock().
	 *
	 * The order of restore is:
	 * 1. SGTL5000_CHIP_CLK_CTRL MCLK_FREQ bits (1:0) should be restore after
	 *    SGTL5000_CHIP_ANA_POWER PLL bits set
	 * 2. SGTL5000_CHIP_LINREG_CTRL should be set before
	 *    SGTL5000_CHIP_ANA_POWER LINREG_D restored
	 * 3. SGTL5000_CHIP_REF_CTRL controls Analog Ground Voltage,
	 *    prefer to resotre it after SGTL5000_CHIP_ANA_POWER restored
	 */
	snd_soc_write(codec, SGTL5000_CHIP_LINREG_CTRL,
			cache[SGTL5000_CHIP_LINREG_CTRL]);
+51 −59
Original line number Diff line number Diff line
@@ -60,7 +60,6 @@ struct aic32x4_rate_divs {

struct aic32x4_priv {
	u32 sysclk;
	s32 master;
	u8 page_no;
	void *control_data;
	u32 power_cfg;
@@ -369,7 +368,6 @@ static int aic32x4_set_dai_sysclk(struct snd_soc_dai *codec_dai,
static int aic32x4_set_dai_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt)
{
	struct snd_soc_codec *codec = codec_dai->codec;
	struct aic32x4_priv *aic32x4 = snd_soc_codec_get_drvdata(codec);
	u8 iface_reg_1;
	u8 iface_reg_2;
	u8 iface_reg_3;
@@ -384,11 +382,9 @@ static int aic32x4_set_dai_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt)
	/* set master/slave audio interface */
	switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
	case SND_SOC_DAIFMT_CBM_CFM:
		aic32x4->master = 1;
		iface_reg_1 |= AIC32X4_BCLKMASTER | AIC32X4_WCLKMASTER;
		break;
	case SND_SOC_DAIFMT_CBS_CFS:
		aic32x4->master = 0;
		break;
	default:
		printk(KERN_ERR "aic32x4: invalid DAI master/slave interface\n");
@@ -526,11 +522,8 @@ static int aic32x4_mute(struct snd_soc_dai *dai, int mute)
static int aic32x4_set_bias_level(struct snd_soc_codec *codec,
				  enum snd_soc_bias_level level)
{
	struct aic32x4_priv *aic32x4 = snd_soc_codec_get_drvdata(codec);

	switch (level) {
	case SND_SOC_BIAS_ON:
		if (aic32x4->master) {
		/* Switch on PLL */
		snd_soc_update_bits(codec, AIC32X4_PLLPR,
				    AIC32X4_PLLEN, AIC32X4_PLLEN);
@@ -554,12 +547,10 @@ static int aic32x4_set_bias_level(struct snd_soc_codec *codec,
		/* Switch on BCLK_N Divider */
		snd_soc_update_bits(codec, AIC32X4_BCLKN,
				    AIC32X4_BCLKEN, AIC32X4_BCLKEN);
		}
		break;
	case SND_SOC_BIAS_PREPARE:
		break;
	case SND_SOC_BIAS_STANDBY:
		if (aic32x4->master) {
		/* Switch off PLL */
		snd_soc_update_bits(codec, AIC32X4_PLLPR,
				    AIC32X4_PLLEN, 0);
@@ -583,7 +574,6 @@ static int aic32x4_set_bias_level(struct snd_soc_codec *codec,
		/* Switch off BCLK_N Divider */
		snd_soc_update_bits(codec, AIC32X4_BCLKN,
				    AIC32X4_BCLKEN, 0);
		}
		break;
	case SND_SOC_BIAS_OFF:
		break;
@@ -651,9 +641,11 @@ static int aic32x4_probe(struct snd_soc_codec *codec)
	if (aic32x4->power_cfg & AIC32X4_PWR_AVDD_DVDD_WEAK_DISABLE) {
		snd_soc_write(codec, AIC32X4_PWRCFG, AIC32X4_AVDDWEAKDISABLE);
	}
	if (aic32x4->power_cfg & AIC32X4_PWR_AIC32X4_LDO_ENABLE) {
		snd_soc_write(codec, AIC32X4_LDOCTL, AIC32X4_LDOCTLEN);
	}

	tmp_reg = (aic32x4->power_cfg & AIC32X4_PWR_AIC32X4_LDO_ENABLE) ?
			AIC32X4_LDOCTLEN : 0;
	snd_soc_write(codec, AIC32X4_LDOCTL, tmp_reg);

	tmp_reg = snd_soc_read(codec, AIC32X4_CMMODE);
	if (aic32x4->power_cfg & AIC32X4_PWR_CMMODE_LDOIN_RANGE_18_36) {
		tmp_reg |= AIC32X4_LDOIN_18_36;
+13 −18
Original line number Diff line number Diff line
@@ -733,8 +733,9 @@ static int __devinit wm2000_i2c_probe(struct i2c_client *i2c,
	struct wm2000_priv *wm2000;
	struct wm2000_platform_data *pdata;
	const char *filename;
	const struct firmware *fw;
	int reg, ret;
	const struct firmware *fw = NULL;
	int ret;
	int reg;
	u16 id;

	wm2000 = devm_kzalloc(&i2c->dev, sizeof(struct wm2000_priv),
@@ -751,7 +752,7 @@ static int __devinit wm2000_i2c_probe(struct i2c_client *i2c,
		ret = PTR_ERR(wm2000->regmap);
		dev_err(&i2c->dev, "Failed to allocate register map: %d\n",
			ret);
		goto err;
		goto out;
	}

	/* Verify that this is a WM2000 */
@@ -763,7 +764,7 @@ static int __devinit wm2000_i2c_probe(struct i2c_client *i2c,
	if (id != 0x2000) {
		dev_err(&i2c->dev, "Device is not a WM2000 - ID %x\n", id);
		ret = -ENODEV;
		goto err_regmap;
		goto out_regmap_exit;
	}

	reg = wm2000_read(i2c, WM2000_REG_REVISON);
@@ -782,7 +783,7 @@ static int __devinit wm2000_i2c_probe(struct i2c_client *i2c,
	ret = request_firmware(&fw, filename, &i2c->dev);
	if (ret != 0) {
		dev_err(&i2c->dev, "Failed to acquire ANC data: %d\n", ret);
		goto err_regmap;
		goto out_regmap_exit;
	}

	/* Pre-cook the concatenation of the register address onto the image */
@@ -793,15 +794,13 @@ static int __devinit wm2000_i2c_probe(struct i2c_client *i2c,
	if (wm2000->anc_download == NULL) {
		dev_err(&i2c->dev, "Out of memory\n");
		ret = -ENOMEM;
		goto err_fw;
		goto out_regmap_exit;
	}

	wm2000->anc_download[0] = 0x80;
	wm2000->anc_download[1] = 0x00;
	memcpy(wm2000->anc_download + 2, fw->data, fw->size);

	release_firmware(fw);

	wm2000->anc_eng_ena = 1;
	wm2000->anc_active = 1;
	wm2000->spk_ena = 1;
@@ -809,18 +808,14 @@ static int __devinit wm2000_i2c_probe(struct i2c_client *i2c,

	wm2000_reset(wm2000);

	ret = snd_soc_register_codec(&i2c->dev, &soc_codec_dev_wm2000,
				     NULL, 0);
	if (ret != 0)
		goto err_fw;

	return 0;
	ret = snd_soc_register_codec(&i2c->dev, &soc_codec_dev_wm2000, NULL, 0);
	if (!ret)
		goto out;

err_fw:
	release_firmware(fw);
err_regmap:
out_regmap_exit:
	regmap_exit(wm2000->regmap);
err:
out:
	release_firmware(fw);
	return ret;
}

+3 −0
Original line number Diff line number Diff line
@@ -1377,6 +1377,7 @@ static int wm5100_set_bias_level(struct snd_soc_codec *codec,

			switch (wm5100->rev) {
			case 0:
				regcache_cache_bypass(wm5100->regmap, true);
				snd_soc_write(codec, 0x11, 0x3);
				snd_soc_write(codec, 0x203, 0xc);
				snd_soc_write(codec, 0x206, 0);
@@ -1392,6 +1393,7 @@ static int wm5100_set_bias_level(struct snd_soc_codec *codec,
					snd_soc_write(codec,
						      wm5100_reva_patches[i].reg,
						      wm5100_reva_patches[i].val);
				regcache_cache_bypass(wm5100->regmap, false);
				break;
			default:
				break;
@@ -1402,6 +1404,7 @@ static int wm5100_set_bias_level(struct snd_soc_codec *codec,
		break;

	case SND_SOC_BIAS_OFF:
		regcache_cache_only(wm5100->regmap, true);
		if (wm5100->pdata.ldo_ena)
			gpio_set_value_cansleep(wm5100->pdata.ldo_ena, 0);
		regulator_bulk_disable(ARRAY_SIZE(wm5100->core_supplies),
+1 −1
Original line number Diff line number Diff line
@@ -55,7 +55,7 @@ static int wm8958_dsp2_fw(struct snd_soc_codec *codec, const char *name,
		return 0;

	if (fw->size < 32) {
		dev_err(codec->dev, "%s: firmware too short (%d bytes)\n",
		dev_err(codec->dev, "%s: firmware too short (%zd bytes)\n",
			name, fw->size);
		goto err;
	}
Loading