aboutsummaryrefslogtreecommitdiffstats
path: root/sound/soc/codecs/ad1980.c
diff options
context:
space:
mode:
Diffstat (limited to 'sound/soc/codecs/ad1980.c')
-rw-r--r--sound/soc/codecs/ad1980.c107
1 files changed, 46 insertions, 61 deletions
diff --git a/sound/soc/codecs/ad1980.c b/sound/soc/codecs/ad1980.c
index 042072738cdc..1371afac657b 100644
--- a/sound/soc/codecs/ad1980.c
+++ b/sound/soc/codecs/ad1980.c
@@ -130,8 +130,8 @@ static int ac97_write(struct snd_soc_codec *codec, unsigned int reg,
130 return 0; 130 return 0;
131} 131}
132 132
133struct snd_soc_dai ad1980_dai = { 133struct snd_soc_dai_driver ad1980_dai = {
134 .name = "AC97", 134 .name = "ad1980-hifi",
135 .ac97_control = 1, 135 .ac97_control = 1,
136 .playback = { 136 .playback = {
137 .stream_name = "Playback", 137 .stream_name = "Playback",
@@ -177,53 +177,20 @@ err:
177 return -EIO; 177 return -EIO;
178} 178}
179 179
180static int ad1980_soc_probe(struct platform_device *pdev) 180static int ad1980_soc_probe(struct snd_soc_codec *codec)
181{ 181{
182 struct snd_soc_device *socdev = platform_get_drvdata(pdev); 182 int ret;
183 struct snd_soc_codec *codec;
184 int ret = 0;
185 u16 vendor_id2; 183 u16 vendor_id2;
186 u16 ext_status; 184 u16 ext_status;
187 185
188 printk(KERN_INFO "AD1980 SoC Audio Codec\n"); 186 printk(KERN_INFO "AD1980 SoC Audio Codec\n");
189 187
190 socdev->card->codec = kzalloc(sizeof(struct snd_soc_codec), GFP_KERNEL);
191 if (socdev->card->codec == NULL)
192 return -ENOMEM;
193 codec = socdev->card->codec;
194 mutex_init(&codec->mutex);
195
196 codec->reg_cache =
197 kzalloc(sizeof(u16) * ARRAY_SIZE(ad1980_reg), GFP_KERNEL);
198 if (codec->reg_cache == NULL) {
199 ret = -ENOMEM;
200 goto cache_err;
201 }
202 memcpy(codec->reg_cache, ad1980_reg, sizeof(u16) * \
203 ARRAY_SIZE(ad1980_reg));
204 codec->reg_cache_size = sizeof(u16) * ARRAY_SIZE(ad1980_reg);
205 codec->reg_cache_step = 2;
206 codec->name = "AD1980";
207 codec->owner = THIS_MODULE;
208 codec->dai = &ad1980_dai;
209 codec->num_dai = 1;
210 codec->write = ac97_write;
211 codec->read = ac97_read;
212 INIT_LIST_HEAD(&codec->dapm_widgets);
213 INIT_LIST_HEAD(&codec->dapm_paths);
214
215 ret = snd_soc_new_ac97_codec(codec, &soc_ac97_ops, 0); 188 ret = snd_soc_new_ac97_codec(codec, &soc_ac97_ops, 0);
216 if (ret < 0) { 189 if (ret < 0) {
217 printk(KERN_ERR "ad1980: failed to register AC97 codec\n"); 190 printk(KERN_ERR "ad1980: failed to register AC97 codec\n");
218 goto codec_err; 191 return ret;
219 } 192 }
220 193
221 /* register pcms */
222 ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
223 if (ret < 0)
224 goto pcm_err;
225
226
227 ret = ad1980_reset(codec, 0); 194 ret = ad1980_reset(codec, 0);
228 if (ret < 0) { 195 if (ret < 0) {
229 printk(KERN_ERR "Failed to reset AD1980: AC97 link error\n"); 196 printk(KERN_ERR "Failed to reset AD1980: AC97 link error\n");
@@ -262,41 +229,59 @@ static int ad1980_soc_probe(struct platform_device *pdev)
262 return 0; 229 return 0;
263 230
264reset_err: 231reset_err:
265 snd_soc_free_pcms(socdev);
266
267pcm_err:
268 snd_soc_free_ac97_codec(codec); 232 snd_soc_free_ac97_codec(codec);
269
270codec_err:
271 kfree(codec->reg_cache);
272
273cache_err:
274 kfree(socdev->card->codec);
275 socdev->card->codec = NULL;
276 return ret; 233 return ret;
277} 234}
278 235
279static int ad1980_soc_remove(struct platform_device *pdev) 236static int ad1980_soc_remove(struct snd_soc_codec *codec)
280{ 237{
281 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
282 struct snd_soc_codec *codec = socdev->card->codec;
283
284 if (codec == NULL)
285 return 0;
286
287 snd_soc_dapm_free(socdev);
288 snd_soc_free_pcms(socdev);
289 snd_soc_free_ac97_codec(codec); 238 snd_soc_free_ac97_codec(codec);
290 kfree(codec->reg_cache);
291 kfree(codec);
292 return 0; 239 return 0;
293} 240}
294 241
295struct snd_soc_codec_device soc_codec_dev_ad1980 = { 242static struct snd_soc_codec_driver soc_codec_dev_ad1980 = {
296 .probe = ad1980_soc_probe, 243 .probe = ad1980_soc_probe,
297 .remove = ad1980_soc_remove, 244 .remove = ad1980_soc_remove,
245 .reg_cache_size = ARRAY_SIZE(ad1980_reg),
246 .reg_word_size = sizeof(u16),
247 .reg_cache_step = 2,
248 .write = ac97_write,
249 .read = ac97_read,
298}; 250};
299EXPORT_SYMBOL_GPL(soc_codec_dev_ad1980); 251
252static __devinit int ad1980_probe(struct platform_device *pdev)
253{
254 return snd_soc_register_codec(&pdev->dev,
255 &soc_codec_dev_ad1980, &ad1980_dai, 1);
256}
257
258static int __devexit ad1980_remove(struct platform_device *pdev)
259{
260 snd_soc_unregister_codec(&pdev->dev);
261 return 0;
262}
263
264static struct platform_driver ad1980_codec_driver = {
265 .driver = {
266 .name = "ad1980-codec",
267 .owner = THIS_MODULE,
268 },
269
270 .probe = ad1980_probe,
271 .remove = __devexit_p(ad1980_remove),
272};
273
274static int __init ad1980_init(void)
275{
276 return platform_driver_register(&ad1980_codec_driver);
277}
278module_init(ad1980_init);
279
280static void __exit ad1980_exit(void)
281{
282 platform_driver_unregister(&ad1980_codec_driver);
283}
284module_exit(ad1980_exit);
300 285
301MODULE_DESCRIPTION("ASoC ad1980 driver"); 286MODULE_DESCRIPTION("ASoC ad1980 driver");
302MODULE_AUTHOR("Roy Huang, Cliff Cai"); 287MODULE_AUTHOR("Roy Huang, Cliff Cai");