aboutsummaryrefslogtreecommitdiffstats
path: root/sound/soc/codecs/wm9713.c
diff options
context:
space:
mode:
Diffstat (limited to 'sound/soc/codecs/wm9713.c')
-rw-r--r--sound/soc/codecs/wm9713.c131
1 files changed, 57 insertions, 74 deletions
diff --git a/sound/soc/codecs/wm9713.c b/sound/soc/codecs/wm9713.c
index 34e0c91092fa..463917e762b5 100644
--- a/sound/soc/codecs/wm9713.c
+++ b/sound/soc/codecs/wm9713.c
@@ -1057,9 +1057,9 @@ static struct snd_soc_dai_ops wm9713_dai_ops_voice = {
1057 .set_tristate = wm9713_set_dai_tristate, 1057 .set_tristate = wm9713_set_dai_tristate,
1058}; 1058};
1059 1059
1060struct snd_soc_dai wm9713_dai[] = { 1060static struct snd_soc_dai_driver wm9713_dai[] = {
1061{ 1061{
1062 .name = "AC97 HiFi", 1062 .name = "wm9713-hifi",
1063 .ac97_control = 1, 1063 .ac97_control = 1,
1064 .playback = { 1064 .playback = {
1065 .stream_name = "HiFi Playback", 1065 .stream_name = "HiFi Playback",
@@ -1076,7 +1076,7 @@ struct snd_soc_dai wm9713_dai[] = {
1076 .ops = &wm9713_dai_ops_hifi, 1076 .ops = &wm9713_dai_ops_hifi,
1077 }, 1077 },
1078 { 1078 {
1079 .name = "AC97 Aux", 1079 .name = "wm9713-aux",
1080 .playback = { 1080 .playback = {
1081 .stream_name = "Aux Playback", 1081 .stream_name = "Aux Playback",
1082 .channels_min = 1, 1082 .channels_min = 1,
@@ -1086,7 +1086,7 @@ struct snd_soc_dai wm9713_dai[] = {
1086 .ops = &wm9713_dai_ops_aux, 1086 .ops = &wm9713_dai_ops_aux,
1087 }, 1087 },
1088 { 1088 {
1089 .name = "WM9713 Voice", 1089 .name = "wm9713-voice",
1090 .playback = { 1090 .playback = {
1091 .stream_name = "Voice Playback", 1091 .stream_name = "Voice Playback",
1092 .channels_min = 1, 1092 .channels_min = 1,
@@ -1103,7 +1103,6 @@ struct snd_soc_dai wm9713_dai[] = {
1103 .symmetric_rates = 1, 1103 .symmetric_rates = 1,
1104 }, 1104 },
1105}; 1105};
1106EXPORT_SYMBOL_GPL(wm9713_dai);
1107 1106
1108int wm9713_reset(struct snd_soc_codec *codec, int try_warm) 1107int wm9713_reset(struct snd_soc_codec *codec, int try_warm)
1109{ 1108{
@@ -1152,11 +1151,9 @@ static int wm9713_set_bias_level(struct snd_soc_codec *codec,
1152 return 0; 1151 return 0;
1153} 1152}
1154 1153
1155static int wm9713_soc_suspend(struct platform_device *pdev, 1154static int wm9713_soc_suspend(struct snd_soc_codec *codec,
1156 pm_message_t state) 1155 pm_message_t state)
1157{ 1156{
1158 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
1159 struct snd_soc_codec *codec = socdev->card->codec;
1160 u16 reg; 1157 u16 reg;
1161 1158
1162 /* Disable everything except touchpanel - that will be handled 1159 /* Disable everything except touchpanel - that will be handled
@@ -1171,10 +1168,8 @@ static int wm9713_soc_suspend(struct platform_device *pdev,
1171 return 0; 1168 return 0;
1172} 1169}
1173 1170
1174static int wm9713_soc_resume(struct platform_device *pdev) 1171static int wm9713_soc_resume(struct snd_soc_codec *codec)
1175{ 1172{
1176 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
1177 struct snd_soc_codec *codec = socdev->card->codec;
1178 struct wm9713_priv *wm9713 = snd_soc_codec_get_drvdata(codec); 1173 struct wm9713_priv *wm9713 = snd_soc_codec_get_drvdata(codec);
1179 int i, ret; 1174 int i, ret;
1180 u16 *cache = codec->reg_cache; 1175 u16 *cache = codec->reg_cache;
@@ -1204,53 +1199,20 @@ static int wm9713_soc_resume(struct platform_device *pdev)
1204 return ret; 1199 return ret;
1205} 1200}
1206 1201
1207static int wm9713_soc_probe(struct platform_device *pdev) 1202static int wm9713_soc_probe(struct snd_soc_codec *codec)
1208{ 1203{
1209 struct snd_soc_device *socdev = platform_get_drvdata(pdev); 1204 struct wm9713_priv *wm9713;
1210 struct snd_soc_codec *codec;
1211 int ret = 0, reg; 1205 int ret = 0, reg;
1212 1206
1213 socdev->card->codec = kzalloc(sizeof(struct snd_soc_codec), 1207 wm9713 = kzalloc(sizeof(struct wm9713_priv), GFP_KERNEL);
1214 GFP_KERNEL); 1208 if (wm9713 == NULL)
1215 if (socdev->card->codec == NULL)
1216 return -ENOMEM; 1209 return -ENOMEM;
1217 codec = socdev->card->codec; 1210 snd_soc_codec_set_drvdata(codec, wm9713);
1218 mutex_init(&codec->mutex);
1219
1220 codec->reg_cache = kmemdup(wm9713_reg, sizeof(wm9713_reg), GFP_KERNEL);
1221 if (codec->reg_cache == NULL) {
1222 ret = -ENOMEM;
1223 goto cache_err;
1224 }
1225 codec->reg_cache_size = sizeof(wm9713_reg);
1226 codec->reg_cache_step = 2;
1227
1228 snd_soc_codec_set_drvdata(codec, kzalloc(sizeof(struct wm9713_priv),
1229 GFP_KERNEL));
1230 if (snd_soc_codec_get_drvdata(codec) == NULL) {
1231 ret = -ENOMEM;
1232 goto priv_err;
1233 }
1234
1235 codec->name = "WM9713";
1236 codec->owner = THIS_MODULE;
1237 codec->dai = wm9713_dai;
1238 codec->num_dai = ARRAY_SIZE(wm9713_dai);
1239 codec->write = ac97_write;
1240 codec->read = ac97_read;
1241 codec->set_bias_level = wm9713_set_bias_level;
1242 INIT_LIST_HEAD(&codec->dapm_widgets);
1243 INIT_LIST_HEAD(&codec->dapm_paths);
1244 1211
1245 ret = snd_soc_new_ac97_codec(codec, &soc_ac97_ops, 0); 1212 ret = snd_soc_new_ac97_codec(codec, &soc_ac97_ops, 0);
1246 if (ret < 0) 1213 if (ret < 0)
1247 goto codec_err; 1214 goto codec_err;
1248 1215
1249 /* register pcms */
1250 ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
1251 if (ret < 0)
1252 goto pcm_err;
1253
1254 /* do a cold reset for the controller and then try 1216 /* do a cold reset for the controller and then try
1255 * a warm reset followed by an optional cold reset for codec */ 1217 * a warm reset followed by an optional cold reset for codec */
1256 wm9713_reset(codec, 0); 1218 wm9713_reset(codec, 0);
@@ -1273,46 +1235,67 @@ static int wm9713_soc_probe(struct platform_device *pdev)
1273 return 0; 1235 return 0;
1274 1236
1275reset_err: 1237reset_err:
1276 snd_soc_free_pcms(socdev);
1277pcm_err:
1278 snd_soc_free_ac97_codec(codec); 1238 snd_soc_free_ac97_codec(codec);
1279
1280codec_err: 1239codec_err:
1281 kfree(snd_soc_codec_get_drvdata(codec)); 1240 kfree(wm9713);
1282
1283priv_err:
1284 kfree(codec->reg_cache);
1285
1286cache_err:
1287 kfree(socdev->card->codec);
1288 socdev->card->codec = NULL;
1289 return ret; 1241 return ret;
1290} 1242}
1291 1243
1292static int wm9713_soc_remove(struct platform_device *pdev) 1244static int wm9713_soc_remove(struct snd_soc_codec *codec)
1293{ 1245{
1294 struct snd_soc_device *socdev = platform_get_drvdata(pdev); 1246 struct wm9713_priv *wm9713 = snd_soc_codec_get_drvdata(codec);
1295 struct snd_soc_codec *codec = socdev->card->codec;
1296
1297 if (codec == NULL)
1298 return 0;
1299
1300 snd_soc_dapm_free(socdev);
1301 snd_soc_free_pcms(socdev);
1302 snd_soc_free_ac97_codec(codec); 1247 snd_soc_free_ac97_codec(codec);
1303 kfree(snd_soc_codec_get_drvdata(codec)); 1248 kfree(wm9713);
1304 kfree(codec->reg_cache);
1305 kfree(codec);
1306 return 0; 1249 return 0;
1307} 1250}
1308 1251
1309struct snd_soc_codec_device soc_codec_dev_wm9713 = { 1252static struct snd_soc_codec_driver soc_codec_dev_wm9713 = {
1310 .probe = wm9713_soc_probe, 1253 .probe = wm9713_soc_probe,
1311 .remove = wm9713_soc_remove, 1254 .remove = wm9713_soc_remove,
1312 .suspend = wm9713_soc_suspend, 1255 .suspend = wm9713_soc_suspend,
1313 .resume = wm9713_soc_resume, 1256 .resume = wm9713_soc_resume,
1257 .read = ac97_read,
1258 .write = ac97_write,
1259 .set_bias_level = wm9713_set_bias_level,
1260 .reg_cache_size = sizeof(wm9713_reg),
1261 .reg_word_size = sizeof(u16),
1262 .reg_cache_step = 2,
1263 .reg_cache_default = wm9713_reg,
1264};
1265
1266static __devinit int wm9713_probe(struct platform_device *pdev)
1267{
1268 return snd_soc_register_codec(&pdev->dev,
1269 &soc_codec_dev_wm9713, wm9713_dai, ARRAY_SIZE(wm9713_dai));
1270}
1271
1272static int __devexit wm9713_remove(struct platform_device *pdev)
1273{
1274 snd_soc_unregister_codec(&pdev->dev);
1275 return 0;
1276}
1277
1278static struct platform_driver wm9713_codec_driver = {
1279 .driver = {
1280 .name = "wm9713-codec",
1281 .owner = THIS_MODULE,
1282 },
1283
1284 .probe = wm9713_probe,
1285 .remove = __devexit_p(wm9713_remove),
1314}; 1286};
1315EXPORT_SYMBOL_GPL(soc_codec_dev_wm9713); 1287
1288static int __init wm9713_init(void)
1289{
1290 return platform_driver_register(&wm9713_codec_driver);
1291}
1292module_init(wm9713_init);
1293
1294static void __exit wm9713_exit(void)
1295{
1296 platform_driver_unregister(&wm9713_codec_driver);
1297}
1298module_exit(wm9713_exit);
1316 1299
1317MODULE_DESCRIPTION("ASoC WM9713/WM9714 driver"); 1300MODULE_DESCRIPTION("ASoC WM9713/WM9714 driver");
1318MODULE_AUTHOR("Liam Girdwood"); 1301MODULE_AUTHOR("Liam Girdwood");