aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLars-Peter Clausen <lars@metafoo.de>2015-07-21 15:53:01 -0400
committerMark Brown <broonie@kernel.org>2015-07-23 12:33:28 -0400
commit7361fbeaeaab5282bbfc88f1f6fe4cf034f7623c (patch)
tree7eb363e1a32f5791aa5ca52f693b097809c159f6
parent5f1d980ee9b6353f18765bfa6774a5a08d6cb944 (diff)
ASoC: ac97: Add support for resetting device before registration
AC97 devices need to be initially reset before they can be used. Currently each driver does this on its own. Add support for resetting the device to core in snd_soc_new_ac97_codec(). If the caller supplies a device ID and device ID mask the function will reset the device and verify that it has the correct ID, if it does not a error is returned. This will allow to remove custom code with similar functionality from individual drivers. Signed-off-by: Lars-Peter Clausen <lars@metafoo.de> Reviewed-by: Takashi Iwai <tiwai@suse.de> Signed-off-by: Mark Brown <broonie@kernel.org>
-rw-r--r--include/sound/soc.h3
-rw-r--r--sound/soc/codecs/ad1980.c2
-rw-r--r--sound/soc/codecs/stac9766.c2
-rw-r--r--sound/soc/soc-ac97.c30
4 files changed, 29 insertions, 8 deletions
diff --git a/include/sound/soc.h b/include/sound/soc.h
index 93df8bf9d54a..42d144a4b7ba 100644
--- a/include/sound/soc.h
+++ b/include/sound/soc.h
@@ -526,7 +526,8 @@ int snd_soc_test_bits(struct snd_soc_codec *codec, unsigned int reg,
526 526
527#ifdef CONFIG_SND_SOC_AC97_BUS 527#ifdef CONFIG_SND_SOC_AC97_BUS
528struct snd_ac97 *snd_soc_alloc_ac97_codec(struct snd_soc_codec *codec); 528struct snd_ac97 *snd_soc_alloc_ac97_codec(struct snd_soc_codec *codec);
529struct snd_ac97 *snd_soc_new_ac97_codec(struct snd_soc_codec *codec); 529struct snd_ac97 *snd_soc_new_ac97_codec(struct snd_soc_codec *codec,
530 unsigned int id, unsigned int id_mask);
530void snd_soc_free_ac97_codec(struct snd_ac97 *ac97); 531void snd_soc_free_ac97_codec(struct snd_ac97 *ac97);
531 532
532int snd_soc_set_ac97_ops(struct snd_ac97_bus_ops *ops); 533int snd_soc_set_ac97_ops(struct snd_ac97_bus_ops *ops);
diff --git a/sound/soc/codecs/ad1980.c b/sound/soc/codecs/ad1980.c
index 3cc69a626454..d9cb81dd64b5 100644
--- a/sound/soc/codecs/ad1980.c
+++ b/sound/soc/codecs/ad1980.c
@@ -240,7 +240,7 @@ static int ad1980_soc_probe(struct snd_soc_codec *codec)
240 u16 vendor_id2; 240 u16 vendor_id2;
241 u16 ext_status; 241 u16 ext_status;
242 242
243 ac97 = snd_soc_new_ac97_codec(codec); 243 ac97 = snd_soc_new_ac97_codec(codec, 0, 0);
244 if (IS_ERR(ac97)) { 244 if (IS_ERR(ac97)) {
245 ret = PTR_ERR(ac97); 245 ret = PTR_ERR(ac97);
246 dev_err(codec->dev, "Failed to register AC97 codec: %d\n", ret); 246 dev_err(codec->dev, "Failed to register AC97 codec: %d\n", ret);
diff --git a/sound/soc/codecs/stac9766.c b/sound/soc/codecs/stac9766.c
index ed4cca7f6779..c6028300c0ac 100644
--- a/sound/soc/codecs/stac9766.c
+++ b/sound/soc/codecs/stac9766.c
@@ -332,7 +332,7 @@ static int stac9766_codec_probe(struct snd_soc_codec *codec)
332 struct snd_ac97 *ac97; 332 struct snd_ac97 *ac97;
333 int ret = 0; 333 int ret = 0;
334 334
335 ac97 = snd_soc_new_ac97_codec(codec); 335 ac97 = snd_soc_new_ac97_codec(codec, 0, 0);
336 if (IS_ERR(ac97)) 336 if (IS_ERR(ac97))
337 return PTR_ERR(ac97); 337 return PTR_ERR(ac97);
338 338
diff --git a/sound/soc/soc-ac97.c b/sound/soc/soc-ac97.c
index 08d7259bbaab..d40efc9fe0a9 100644
--- a/sound/soc/soc-ac97.c
+++ b/sound/soc/soc-ac97.c
@@ -85,10 +85,19 @@ EXPORT_SYMBOL(snd_soc_alloc_ac97_codec);
85/** 85/**
86 * snd_soc_new_ac97_codec - initailise AC97 device 86 * snd_soc_new_ac97_codec - initailise AC97 device
87 * @codec: audio codec 87 * @codec: audio codec
88 * @id: The expected device ID
89 * @id_mask: Mask that is applied to the device ID before comparing with @id
88 * 90 *
89 * Initialises AC97 codec resources for use by ad-hoc devices only. 91 * Initialises AC97 codec resources for use by ad-hoc devices only.
92 *
93 * If @id is not 0 this function will reset the device, then read the ID from
94 * the device and check if it matches the expected ID. If it doesn't match an
95 * error will be returned and device will not be registered.
96 *
97 * Returns: A PTR_ERR() on failure or a valid snd_ac97 struct on success.
90 */ 98 */
91struct snd_ac97 *snd_soc_new_ac97_codec(struct snd_soc_codec *codec) 99struct snd_ac97 *snd_soc_new_ac97_codec(struct snd_soc_codec *codec,
100 unsigned int id, unsigned int id_mask)
92{ 101{
93 struct snd_ac97 *ac97; 102 struct snd_ac97 *ac97;
94 int ret; 103 int ret;
@@ -97,13 +106,24 @@ struct snd_ac97 *snd_soc_new_ac97_codec(struct snd_soc_codec *codec)
97 if (IS_ERR(ac97)) 106 if (IS_ERR(ac97))
98 return ac97; 107 return ac97;
99 108
100 ret = device_add(&ac97->dev); 109 if (id) {
101 if (ret) { 110 ret = snd_ac97_reset(ac97, false, id, id_mask);
102 put_device(&ac97->dev); 111 if (ret < 0) {
103 return ERR_PTR(ret); 112 dev_err(codec->dev, "Failed to reset AC97 device: %d\n",
113 ret);
114 goto err_put_device;
115 }
104 } 116 }
105 117
118 ret = device_add(&ac97->dev);
119 if (ret)
120 goto err_put_device;
121
106 return ac97; 122 return ac97;
123
124err_put_device:
125 put_device(&ac97->dev);
126 return ERR_PTR(ret);
107} 127}
108EXPORT_SYMBOL_GPL(snd_soc_new_ac97_codec); 128EXPORT_SYMBOL_GPL(snd_soc_new_ac97_codec);
109 129