diff options
Diffstat (limited to 'sound/soc/codecs/wm9713.c')
-rw-r--r-- | sound/soc/codecs/wm9713.c | 131 |
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 | ||
1060 | struct snd_soc_dai wm9713_dai[] = { | 1060 | static 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 | }; |
1106 | EXPORT_SYMBOL_GPL(wm9713_dai); | ||
1107 | 1106 | ||
1108 | int wm9713_reset(struct snd_soc_codec *codec, int try_warm) | 1107 | int 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 | ||
1155 | static int wm9713_soc_suspend(struct platform_device *pdev, | 1154 | static 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 | ||
1174 | static int wm9713_soc_resume(struct platform_device *pdev) | 1171 | static 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 | ||
1207 | static int wm9713_soc_probe(struct platform_device *pdev) | 1202 | static 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 | ||
1275 | reset_err: | 1237 | reset_err: |
1276 | snd_soc_free_pcms(socdev); | ||
1277 | pcm_err: | ||
1278 | snd_soc_free_ac97_codec(codec); | 1238 | snd_soc_free_ac97_codec(codec); |
1279 | |||
1280 | codec_err: | 1239 | codec_err: |
1281 | kfree(snd_soc_codec_get_drvdata(codec)); | 1240 | kfree(wm9713); |
1282 | |||
1283 | priv_err: | ||
1284 | kfree(codec->reg_cache); | ||
1285 | |||
1286 | cache_err: | ||
1287 | kfree(socdev->card->codec); | ||
1288 | socdev->card->codec = NULL; | ||
1289 | return ret; | 1241 | return ret; |
1290 | } | 1242 | } |
1291 | 1243 | ||
1292 | static int wm9713_soc_remove(struct platform_device *pdev) | 1244 | static 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 | ||
1309 | struct snd_soc_codec_device soc_codec_dev_wm9713 = { | 1252 | static 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 | |||
1266 | static __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 | |||
1272 | static int __devexit wm9713_remove(struct platform_device *pdev) | ||
1273 | { | ||
1274 | snd_soc_unregister_codec(&pdev->dev); | ||
1275 | return 0; | ||
1276 | } | ||
1277 | |||
1278 | static 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 | }; |
1315 | EXPORT_SYMBOL_GPL(soc_codec_dev_wm9713); | 1287 | |
1288 | static int __init wm9713_init(void) | ||
1289 | { | ||
1290 | return platform_driver_register(&wm9713_codec_driver); | ||
1291 | } | ||
1292 | module_init(wm9713_init); | ||
1293 | |||
1294 | static void __exit wm9713_exit(void) | ||
1295 | { | ||
1296 | platform_driver_unregister(&wm9713_codec_driver); | ||
1297 | } | ||
1298 | module_exit(wm9713_exit); | ||
1316 | 1299 | ||
1317 | MODULE_DESCRIPTION("ASoC WM9713/WM9714 driver"); | 1300 | MODULE_DESCRIPTION("ASoC WM9713/WM9714 driver"); |
1318 | MODULE_AUTHOR("Liam Girdwood"); | 1301 | MODULE_AUTHOR("Liam Girdwood"); |