[ALSA] ASoC AC97 device reg bugfix
This patch fixes a bug whereby AC97 bus device data was being clobbered
when AC97 codecs using the generic ac97_codec.c driver were being
registered. Codecs that didn't use the generic driver were unaffected
(e.g. WM9712, WM9713).
Changes:-
o Add new AC97 codec class for custom (or need bus dev registration)
AC97 codecs.
o Only register/deregister this custom codec device with the AC97 bus.
The generic AC97 driver already does this for generic codec devices.
This may be related to bug #3038 :-
https://bugtrack.alsa-project.org/alsa-bug/view.php?id=3038
Signed-off-by: Liam Girdwood <lg@opensource.wolfsonmicro.com>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Signed-off-by: Jaroslav Kysela <perex@suse.cz>
diff --git a/include/sound/soc.h b/include/sound/soc.h
index b1dc364..db6edba 100644
--- a/include/sound/soc.h
+++ b/include/sound/soc.h
@@ -22,7 +22,7 @@
#include <sound/control.h>
#include <sound/ac97_codec.h>
-#define SND_SOC_VERSION "0.13.0"
+#define SND_SOC_VERSION "0.13.1"
/*
* Convenience kcontrol builders
@@ -83,6 +83,7 @@
#define SND_SOC_DAI_AC97 0x1
#define SND_SOC_DAI_I2S 0x2
#define SND_SOC_DAI_PCM 0x4
+#define SND_SOC_DAI_AC97_BUS 0x8 /* for custom i.e. non ac97_codec.c */
/*
* DAI hardware audio formats
@@ -278,6 +279,7 @@
struct snd_soc_codec_dai {
char *name;
int id;
+ unsigned char type;
/* DAI capabilities */
struct snd_soc_pcm_stream playback;
diff --git a/sound/soc/codecs/ac97.c b/sound/soc/codecs/ac97.c
index f3b3b9e..0b8a6f8 100644
--- a/sound/soc/codecs/ac97.c
+++ b/sound/soc/codecs/ac97.c
@@ -45,6 +45,7 @@
struct snd_soc_codec_dai ac97_dai = {
.name = "AC97 HiFi",
+ .type = SND_SOC_DAI_AC97,
.playback = {
.stream_name = "AC97 Playback",
.channels_min = 1,
diff --git a/sound/soc/codecs/wm9712.c b/sound/soc/codecs/wm9712.c
index 264413a..986b5d59 100644
--- a/sound/soc/codecs/wm9712.c
+++ b/sound/soc/codecs/wm9712.c
@@ -544,6 +544,7 @@
struct snd_soc_codec_dai wm9712_dai[] = {
{
.name = "AC97 HiFi",
+ .type = SND_SOC_DAI_AC97_BUS,
.playback = {
.stream_name = "HiFi Playback",
.channels_min = 1,
diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c
index 36519ae..92d5d91 100644
--- a/sound/soc/soc-core.c
+++ b/sound/soc/soc-core.c
@@ -116,6 +116,7 @@
static inline const char* get_dai_name(int type)
{
switch(type) {
+ case SND_SOC_DAI_AC97_BUS:
case SND_SOC_DAI_AC97:
return "AC97";
case SND_SOC_DAI_I2S:
@@ -1099,7 +1100,8 @@
continue;
}
}
- if (socdev->machine->dai_link[i].cpu_dai->type == SND_SOC_DAI_AC97)
+ if (socdev->machine->dai_link[i].codec_dai->type ==
+ SND_SOC_DAI_AC97_BUS)
ac97 = 1;
}
snprintf(codec->card->shortname, sizeof(codec->card->shortname),
@@ -1148,11 +1150,21 @@
void snd_soc_free_pcms(struct snd_soc_device *socdev)
{
struct snd_soc_codec *codec = socdev->codec;
+#ifdef CONFIG_SND_SOC_AC97_BUS
+ struct snd_soc_codec_dai *codec_dai;
+ int i;
+#endif
mutex_lock(&codec->mutex);
#ifdef CONFIG_SND_SOC_AC97_BUS
- if (codec->ac97)
- soc_ac97_dev_unregister(codec);
+ for(i = 0; i < codec->num_dai; i++) {
+ codec_dai = &codec->dai[i];
+ if (codec_dai->type == SND_SOC_DAI_AC97_BUS && codec->ac97) {
+ soc_ac97_dev_unregister(codec);
+ goto free_card;
+ }
+ }
+free_card:
#endif
if (codec->card)