]> git.karo-electronics.de Git - linux-beck.git/commitdiff
ASoC: ac97: Add support for resetting device before registration
authorLars-Peter Clausen <lars@metafoo.de>
Tue, 21 Jul 2015 19:53:01 +0000 (21:53 +0200)
committerMark Brown <broonie@kernel.org>
Thu, 23 Jul 2015 16:33:28 +0000 (17:33 +0100)
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>
include/sound/soc.h
sound/soc/codecs/ad1980.c
sound/soc/codecs/stac9766.c
sound/soc/soc-ac97.c

index 93df8bf9d54a9e1b9502836faec752b4c6aa20b0..42d144a4b7ba7d1a4c32ca97e2f7b39c5422fcf1 100644 (file)
@@ -526,7 +526,8 @@ int snd_soc_test_bits(struct snd_soc_codec *codec, unsigned int reg,
 
 #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);
+struct snd_ac97 *snd_soc_new_ac97_codec(struct snd_soc_codec *codec,
+       unsigned int id, unsigned int id_mask);
 void snd_soc_free_ac97_codec(struct snd_ac97 *ac97);
 
 int snd_soc_set_ac97_ops(struct snd_ac97_bus_ops *ops);
index 3cc69a626454fce289a497dd92d5c8650cca7388..d9cb81dd64b55a09ea4a37a28ddfa12aa1343754 100644 (file)
@@ -240,7 +240,7 @@ static int ad1980_soc_probe(struct snd_soc_codec *codec)
        u16 vendor_id2;
        u16 ext_status;
 
-       ac97 = snd_soc_new_ac97_codec(codec);
+       ac97 = snd_soc_new_ac97_codec(codec, 0, 0);
        if (IS_ERR(ac97)) {
                ret = PTR_ERR(ac97);
                dev_err(codec->dev, "Failed to register AC97 codec: %d\n", ret);
index ed4cca7f6779937a4e92717cc29209356f9a9e5e..c6028300c0ac49d9717bb1e7253989a98a8a5393 100644 (file)
@@ -332,7 +332,7 @@ static int stac9766_codec_probe(struct snd_soc_codec *codec)
        struct snd_ac97 *ac97;
        int ret = 0;
 
-       ac97 = snd_soc_new_ac97_codec(codec);
+       ac97 = snd_soc_new_ac97_codec(codec, 0, 0);
        if (IS_ERR(ac97))
                return PTR_ERR(ac97);
 
index 08d7259bbaabad727709281234905011e990f07d..d40efc9fe0a9b4597511b2de2ad02712aa912043 100644 (file)
@@ -85,10 +85,19 @@ EXPORT_SYMBOL(snd_soc_alloc_ac97_codec);
 /**
  * snd_soc_new_ac97_codec - initailise AC97 device
  * @codec: audio codec
+ * @id: The expected device ID
+ * @id_mask: Mask that is applied to the device ID before comparing with @id
  *
  * Initialises AC97 codec resources for use by ad-hoc devices only.
+ *
+ * If @id is not 0 this function will reset the device, then read the ID from
+ * the device and check if it matches the expected ID. If it doesn't match an
+ * error will be returned and device will not be registered.
+ *
+ * Returns: A PTR_ERR() on failure or a valid snd_ac97 struct on success.
  */
-struct snd_ac97 *snd_soc_new_ac97_codec(struct snd_soc_codec *codec)
+struct snd_ac97 *snd_soc_new_ac97_codec(struct snd_soc_codec *codec,
+       unsigned int id, unsigned int id_mask)
 {
        struct snd_ac97 *ac97;
        int ret;
@@ -97,13 +106,24 @@ struct snd_ac97 *snd_soc_new_ac97_codec(struct snd_soc_codec *codec)
        if (IS_ERR(ac97))
                return ac97;
 
-       ret = device_add(&ac97->dev);
-       if (ret) {
-               put_device(&ac97->dev);
-               return ERR_PTR(ret);
+       if (id) {
+               ret = snd_ac97_reset(ac97, false, id, id_mask);
+               if (ret < 0) {
+                       dev_err(codec->dev, "Failed to reset AC97 device: %d\n",
+                               ret);
+                       goto err_put_device;
+               }
        }
 
+       ret = device_add(&ac97->dev);
+       if (ret)
+               goto err_put_device;
+
        return ac97;
+
+err_put_device:
+       put_device(&ac97->dev);
+       return ERR_PTR(ret);
 }
 EXPORT_SYMBOL_GPL(snd_soc_new_ac97_codec);