Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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>

authored by

Lars-Peter Clausen and committed by
Mark Brown
7361fbea 5f1d980e

+29 -8
+2 -1
include/sound/soc.h
··· 526 526 527 527 #ifdef CONFIG_SND_SOC_AC97_BUS 528 528 struct snd_ac97 *snd_soc_alloc_ac97_codec(struct snd_soc_codec *codec); 529 - struct snd_ac97 *snd_soc_new_ac97_codec(struct snd_soc_codec *codec); 529 + struct snd_ac97 *snd_soc_new_ac97_codec(struct snd_soc_codec *codec, 530 + unsigned int id, unsigned int id_mask); 530 531 void snd_soc_free_ac97_codec(struct snd_ac97 *ac97); 531 532 532 533 int snd_soc_set_ac97_ops(struct snd_ac97_bus_ops *ops);
+1 -1
sound/soc/codecs/ad1980.c
··· 240 240 u16 vendor_id2; 241 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 244 if (IS_ERR(ac97)) { 245 245 ret = PTR_ERR(ac97); 246 246 dev_err(codec->dev, "Failed to register AC97 codec: %d\n", ret);
+1 -1
sound/soc/codecs/stac9766.c
··· 332 332 struct snd_ac97 *ac97; 333 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 336 if (IS_ERR(ac97)) 337 337 return PTR_ERR(ac97); 338 338
+25 -5
sound/soc/soc-ac97.c
··· 85 85 /** 86 86 * snd_soc_new_ac97_codec - initailise AC97 device 87 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 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 */ 91 - struct snd_ac97 *snd_soc_new_ac97_codec(struct snd_soc_codec *codec) 99 + struct snd_ac97 *snd_soc_new_ac97_codec(struct snd_soc_codec *codec, 100 + unsigned int id, unsigned int id_mask) 92 101 { 93 102 struct snd_ac97 *ac97; 94 103 int ret; ··· 106 97 if (IS_ERR(ac97)) 107 98 return ac97; 108 99 109 - ret = device_add(&ac97->dev); 110 - if (ret) { 111 - put_device(&ac97->dev); 112 - return ERR_PTR(ret); 100 + if (id) { 101 + ret = snd_ac97_reset(ac97, false, id, id_mask); 102 + if (ret < 0) { 103 + dev_err(codec->dev, "Failed to reset AC97 device: %d\n", 104 + ret); 105 + goto err_put_device; 106 + } 113 107 } 114 108 109 + ret = device_add(&ac97->dev); 110 + if (ret) 111 + goto err_put_device; 112 + 115 113 return ac97; 114 + 115 + err_put_device: 116 + put_device(&ac97->dev); 117 + return ERR_PTR(ret); 116 118 } 117 119 EXPORT_SYMBOL_GPL(snd_soc_new_ac97_codec); 118 120