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

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

Merge tag 'asoc-fix-ac97-v3.19-rc7' of...

Merge tag 'asoc-fix-ac97-v3.19-rc7' of git://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound into for-linus

ASoC: AC'97 fixes

These are rather too large for this late in the release cycle but
they're clear, well understood and have been tested to fix a regression
which was introduced for v3.19.  The details are all in Lars' changelog
and they've been cooking in -next for a while, to a large extent out
of conservatism about the size.
parents deb08737 f8d71be5
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -498,6 +498,7 @@ int snd_soc_test_bits(struct snd_soc_codec *codec, unsigned int reg,
				unsigned int mask, unsigned int value);

#ifdef CONFIG_SND_SOC_AC97_BUS
struct snd_ac97 *snd_soc_alloc_ac97_codec(struct snd_soc_codec *codec);
struct snd_ac97 *snd_soc_new_ac97_codec(struct snd_soc_codec *codec);
void snd_soc_free_ac97_codec(struct snd_ac97 *ac97);

+10 −6
Original line number Diff line number Diff line
@@ -344,23 +344,27 @@ static int wm9705_soc_probe(struct snd_soc_codec *codec)
	struct snd_ac97 *ac97;
	int ret = 0;

	ac97 = snd_soc_new_ac97_codec(codec);
	ac97 = snd_soc_alloc_ac97_codec(codec);
	if (IS_ERR(ac97)) {
		ret = PTR_ERR(ac97);
		dev_err(codec->dev, "Failed to register AC97 codec\n");
		return ret;
	}

	snd_soc_codec_set_drvdata(codec, ac97);

	ret = wm9705_reset(codec);
	if (ret)
		goto reset_err;
		goto err_put_device;

	ret = device_add(&ac97->dev);
	if (ret)
		goto err_put_device;

	snd_soc_codec_set_drvdata(codec, ac97);

	return 0;

reset_err:
	snd_soc_free_ac97_codec(ac97);
err_put_device:
	put_device(&ac97->dev);
	return ret;
}

+8 −4
Original line number Diff line number Diff line
@@ -666,7 +666,7 @@ static int wm9712_soc_probe(struct snd_soc_codec *codec)
	struct wm9712_priv *wm9712 = snd_soc_codec_get_drvdata(codec);
	int ret = 0;

	wm9712->ac97 = snd_soc_new_ac97_codec(codec);
	wm9712->ac97 = snd_soc_alloc_ac97_codec(codec);
	if (IS_ERR(wm9712->ac97)) {
		ret = PTR_ERR(wm9712->ac97);
		dev_err(codec->dev, "Failed to register AC97 codec: %d\n", ret);
@@ -675,15 +675,19 @@ static int wm9712_soc_probe(struct snd_soc_codec *codec)

	ret = wm9712_reset(codec, 0);
	if (ret < 0)
		goto reset_err;
		goto err_put_device;

	ret = device_add(&wm9712->ac97->dev);
	if (ret)
		goto err_put_device;

	/* set alc mux to none */
	ac97_write(codec, AC97_VIDEO, ac97_read(codec, AC97_VIDEO) | 0x3000);

	return 0;

reset_err:
	snd_soc_free_ac97_codec(wm9712->ac97);
err_put_device:
	put_device(&wm9712->ac97->dev);
	return ret;
}

+8 −4
Original line number Diff line number Diff line
@@ -1225,7 +1225,7 @@ static int wm9713_soc_probe(struct snd_soc_codec *codec)
	struct wm9713_priv *wm9713 = snd_soc_codec_get_drvdata(codec);
	int ret = 0, reg;

	wm9713->ac97 = snd_soc_new_ac97_codec(codec);
	wm9713->ac97 = snd_soc_alloc_ac97_codec(codec);
	if (IS_ERR(wm9713->ac97))
		return PTR_ERR(wm9713->ac97);

@@ -1234,7 +1234,11 @@ static int wm9713_soc_probe(struct snd_soc_codec *codec)
	wm9713_reset(codec, 0);
	ret = wm9713_reset(codec, 1);
	if (ret < 0)
		goto reset_err;
		goto err_put_device;

	ret = device_add(&wm9713->ac97->dev);
	if (ret)
		goto err_put_device;

	/* unmute the adc - move to kcontrol */
	reg = ac97_read(codec, AC97_CD) & 0x7fff;
@@ -1242,8 +1246,8 @@ static int wm9713_soc_probe(struct snd_soc_codec *codec)

	return 0;

reset_err:
	snd_soc_free_ac97_codec(wm9713->ac97);
err_put_device:
	put_device(&wm9713->ac97->dev);
	return ret;
}

+30 −6
Original line number Diff line number Diff line
@@ -48,15 +48,18 @@ static void soc_ac97_device_release(struct device *dev)
}

/**
 * snd_soc_new_ac97_codec - initailise AC97 device
 * @codec: audio codec
 * snd_soc_alloc_ac97_codec() - Allocate new a AC'97 device
 * @codec: The CODEC for which to create the AC'97 device
 *
 * Initialises AC97 codec resources for use by ad-hoc devices only.
 * Allocated a new snd_ac97 device and intializes it, but does not yet register
 * it. The caller is responsible to either call device_add(&ac97->dev) to
 * register the device, or to call put_device(&ac97->dev) to free the device.
 *
 * Returns: A snd_ac97 device or a PTR_ERR in case of an error.
 */
struct snd_ac97 *snd_soc_new_ac97_codec(struct snd_soc_codec *codec)
struct snd_ac97 *snd_soc_alloc_ac97_codec(struct snd_soc_codec *codec)
{
	struct snd_ac97 *ac97;
	int ret;

	ac97 = kzalloc(sizeof(struct snd_ac97), GFP_KERNEL);
	if (ac97 == NULL)
@@ -73,7 +76,28 @@ struct snd_ac97 *snd_soc_new_ac97_codec(struct snd_soc_codec *codec)
		     codec->component.card->snd_card->number, 0,
		     codec->component.name);

	ret = device_register(&ac97->dev);
	device_initialize(&ac97->dev);

	return ac97;
}
EXPORT_SYMBOL(snd_soc_alloc_ac97_codec);

/**
 * snd_soc_new_ac97_codec - initailise AC97 device
 * @codec: audio codec
 *
 * Initialises AC97 codec resources for use by ad-hoc devices only.
 */
struct snd_ac97 *snd_soc_new_ac97_codec(struct snd_soc_codec *codec)
{
	struct snd_ac97 *ac97;
	int ret;

	ac97 = snd_soc_alloc_ac97_codec(codec);
	if (IS_ERR(ac97))
		return ac97;

	ret = device_add(&ac97->dev);
	if (ret) {
		put_device(&ac97->dev);
		return ERR_PTR(ret);