aboutsummaryrefslogtreecommitdiffstats
path: root/sound/soc/codecs/wm9081.c
diff options
context:
space:
mode:
Diffstat (limited to 'sound/soc/codecs/wm9081.c')
-rw-r--r--sound/soc/codecs/wm9081.c208
1 files changed, 59 insertions, 149 deletions
diff --git a/sound/soc/codecs/wm9081.c b/sound/soc/codecs/wm9081.c
index 76b37ff6c264..00249d5b6793 100644
--- a/sound/soc/codecs/wm9081.c
+++ b/sound/soc/codecs/wm9081.c
@@ -156,7 +156,8 @@ static struct {
156}; 156};
157 157
158struct wm9081_priv { 158struct wm9081_priv {
159 struct snd_soc_codec codec; 159 enum snd_soc_control_type control_type;
160 void *control_data;
160 u16 reg_cache[WM9081_MAX_REGISTER + 1]; 161 u16 reg_cache[WM9081_MAX_REGISTER + 1];
161 int sysclk_source; 162 int sysclk_source;
162 int mclk_rate; 163 int mclk_rate;
@@ -1212,8 +1213,8 @@ static struct snd_soc_dai_ops wm9081_dai_ops = {
1212/* We report two channels because the CODEC processes a stereo signal, even 1213/* We report two channels because the CODEC processes a stereo signal, even
1213 * though it is only capable of handling a mono output. 1214 * though it is only capable of handling a mono output.
1214 */ 1215 */
1215struct snd_soc_dai wm9081_dai = { 1216static struct snd_soc_dai_driver wm9081_dai = {
1216 .name = "WM9081", 1217 .name = "wm9081-hifi",
1217 .playback = { 1218 .playback = {
1218 .stream_name = "HiFi Playback", 1219 .stream_name = "HiFi Playback",
1219 .channels_min = 1, 1220 .channels_min = 1,
@@ -1223,34 +1224,42 @@ struct snd_soc_dai wm9081_dai = {
1223 }, 1224 },
1224 .ops = &wm9081_dai_ops, 1225 .ops = &wm9081_dai_ops,
1225}; 1226};
1226EXPORT_SYMBOL_GPL(wm9081_dai);
1227 1227
1228 1228static int wm9081_probe(struct snd_soc_codec *codec)
1229static struct snd_soc_codec *wm9081_codec;
1230
1231static int wm9081_probe(struct platform_device *pdev)
1232{ 1229{
1233 struct snd_soc_device *socdev = platform_get_drvdata(pdev); 1230 struct wm9081_priv *wm9081 = snd_soc_codec_get_drvdata(codec);
1234 struct snd_soc_codec *codec; 1231 int ret;
1235 struct wm9081_priv *wm9081; 1232 u16 reg;
1236 int ret = 0;
1237 1233
1238 if (wm9081_codec == NULL) { 1234 codec->control_data = wm9081->control_data;
1239 dev_err(&pdev->dev, "Codec device not registered\n"); 1235 ret = snd_soc_codec_set_cache_io(codec, 8, 16, wm9081->control_type);
1240 return -ENODEV; 1236 if (ret != 0) {
1237 dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
1238 return ret;
1241 } 1239 }
1242 1240
1243 socdev->card->codec = wm9081_codec; 1241 reg = snd_soc_read(codec, WM9081_SOFTWARE_RESET);
1244 codec = wm9081_codec; 1242 if (reg != 0x9081) {
1245 wm9081 = snd_soc_codec_get_drvdata(codec); 1243 dev_err(codec->dev, "Device is not a WM9081: ID=0x%x\n", reg);
1244 ret = -EINVAL;
1245 return ret;
1246 }
1246 1247
1247 /* register pcms */ 1248 ret = wm9081_reset(codec);
1248 ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
1249 if (ret < 0) { 1249 if (ret < 0) {
1250 dev_err(codec->dev, "failed to create pcms: %d\n", ret); 1250 dev_err(codec->dev, "Failed to issue reset\n");
1251 goto pcm_err; 1251 return ret;
1252 } 1252 }
1253 1253
1254 wm9081_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
1255
1256 /* Enable zero cross by default */
1257 reg = snd_soc_read(codec, WM9081_ANALOGUE_LINEOUT);
1258 snd_soc_write(codec, WM9081_ANALOGUE_LINEOUT, reg | WM9081_LINEOUTZC);
1259 reg = snd_soc_read(codec, WM9081_ANALOGUE_SPEAKER_PGA);
1260 snd_soc_write(codec, WM9081_ANALOGUE_SPEAKER_PGA,
1261 reg | WM9081_SPKPGAZC);
1262
1254 snd_soc_add_controls(codec, wm9081_snd_controls, 1263 snd_soc_add_controls(codec, wm9081_snd_controls,
1255 ARRAY_SIZE(wm9081_snd_controls)); 1264 ARRAY_SIZE(wm9081_snd_controls));
1256 if (!wm9081->retune) { 1265 if (!wm9081->retune) {
@@ -1265,40 +1274,28 @@ static int wm9081_probe(struct platform_device *pdev)
1265 snd_soc_dapm_add_routes(codec, audio_paths, ARRAY_SIZE(audio_paths)); 1274 snd_soc_dapm_add_routes(codec, audio_paths, ARRAY_SIZE(audio_paths));
1266 1275
1267 return ret; 1276 return ret;
1268
1269pcm_err:
1270 return ret;
1271} 1277}
1272 1278
1273static int wm9081_remove(struct platform_device *pdev) 1279static int wm9081_remove(struct snd_soc_codec *codec)
1274{ 1280{
1275 struct snd_soc_device *socdev = platform_get_drvdata(pdev); 1281 wm9081_set_bias_level(codec, SND_SOC_BIAS_OFF);
1276
1277 snd_soc_free_pcms(socdev);
1278 snd_soc_dapm_free(socdev);
1279
1280 return 0; 1282 return 0;
1281} 1283}
1282 1284
1283#ifdef CONFIG_PM 1285#ifdef CONFIG_PM
1284static int wm9081_suspend(struct platform_device *pdev, pm_message_t state) 1286static int wm9081_suspend(struct snd_soc_codec *codec, pm_message_t state)
1285{ 1287{
1286 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
1287 struct snd_soc_codec *codec = socdev->card->codec;
1288
1289 wm9081_set_bias_level(codec, SND_SOC_BIAS_OFF); 1288 wm9081_set_bias_level(codec, SND_SOC_BIAS_OFF);
1290 1289
1291 return 0; 1290 return 0;
1292} 1291}
1293 1292
1294static int wm9081_resume(struct platform_device *pdev) 1293static int wm9081_resume(struct snd_soc_codec *codec)
1295{ 1294{
1296 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
1297 struct snd_soc_codec *codec = socdev->card->codec;
1298 u16 *reg_cache = codec->reg_cache; 1295 u16 *reg_cache = codec->reg_cache;
1299 int i; 1296 int i;
1300 1297
1301 for (i = 0; i < codec->reg_cache_size; i++) { 1298 for (i = 0; i < codec->driver->reg_cache_size; i++) {
1302 if (i == WM9081_SOFTWARE_RESET) 1299 if (i == WM9081_SOFTWARE_RESET)
1303 continue; 1300 continue;
1304 1301
@@ -1314,133 +1311,43 @@ static int wm9081_resume(struct platform_device *pdev)
1314#define wm9081_resume NULL 1311#define wm9081_resume NULL
1315#endif 1312#endif
1316 1313
1317struct snd_soc_codec_device soc_codec_dev_wm9081 = { 1314static struct snd_soc_codec_driver soc_codec_dev_wm9081 = {
1318 .probe = wm9081_probe, 1315 .probe = wm9081_probe,
1319 .remove = wm9081_remove, 1316 .remove = wm9081_remove,
1320 .suspend = wm9081_suspend, 1317 .suspend = wm9081_suspend,
1321 .resume = wm9081_resume, 1318 .resume = wm9081_resume,
1319 .set_bias_level = wm9081_set_bias_level,
1320 .reg_cache_size = sizeof(wm9081_reg_defaults),
1321 .reg_word_size = sizeof(u16),
1322 .reg_cache_default = wm9081_reg_defaults,
1323 .volatile_register = wm9081_volatile_register,
1322}; 1324};
1323EXPORT_SYMBOL_GPL(soc_codec_dev_wm9081);
1324
1325static int wm9081_register(struct wm9081_priv *wm9081,
1326 enum snd_soc_control_type control)
1327{
1328 struct snd_soc_codec *codec = &wm9081->codec;
1329 int ret;
1330 u16 reg;
1331
1332 if (wm9081_codec) {
1333 dev_err(codec->dev, "Another WM9081 is registered\n");
1334 ret = -EINVAL;
1335 goto err;
1336 }
1337
1338 mutex_init(&codec->mutex);
1339 INIT_LIST_HEAD(&codec->dapm_widgets);
1340 INIT_LIST_HEAD(&codec->dapm_paths);
1341
1342 snd_soc_codec_set_drvdata(codec, wm9081);
1343 codec->name = "WM9081";
1344 codec->owner = THIS_MODULE;
1345 codec->dai = &wm9081_dai;
1346 codec->num_dai = 1;
1347 codec->reg_cache_size = ARRAY_SIZE(wm9081->reg_cache);
1348 codec->reg_cache = &wm9081->reg_cache;
1349 codec->bias_level = SND_SOC_BIAS_OFF;
1350 codec->set_bias_level = wm9081_set_bias_level;
1351 codec->volatile_register = wm9081_volatile_register;
1352
1353 memcpy(codec->reg_cache, wm9081_reg_defaults,
1354 sizeof(wm9081_reg_defaults));
1355
1356 ret = snd_soc_codec_set_cache_io(codec, 8, 16, control);
1357 if (ret != 0) {
1358 dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
1359 goto err;
1360 }
1361
1362 reg = snd_soc_read(codec, WM9081_SOFTWARE_RESET);
1363 if (reg != 0x9081) {
1364 dev_err(codec->dev, "Device is not a WM9081: ID=0x%x\n", reg);
1365 ret = -EINVAL;
1366 goto err;
1367 }
1368
1369 ret = wm9081_reset(codec);
1370 if (ret < 0) {
1371 dev_err(codec->dev, "Failed to issue reset\n");
1372 goto err;
1373 }
1374
1375 wm9081_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
1376
1377 /* Enable zero cross by default */
1378 reg = snd_soc_read(codec, WM9081_ANALOGUE_LINEOUT);
1379 snd_soc_write(codec, WM9081_ANALOGUE_LINEOUT, reg | WM9081_LINEOUTZC);
1380 reg = snd_soc_read(codec, WM9081_ANALOGUE_SPEAKER_PGA);
1381 snd_soc_write(codec, WM9081_ANALOGUE_SPEAKER_PGA,
1382 reg | WM9081_SPKPGAZC);
1383
1384 wm9081_dai.dev = codec->dev;
1385
1386 wm9081_codec = codec;
1387
1388 ret = snd_soc_register_codec(codec);
1389 if (ret != 0) {
1390 dev_err(codec->dev, "Failed to register codec: %d\n", ret);
1391 goto err;
1392 }
1393
1394 ret = snd_soc_register_dai(&wm9081_dai);
1395 if (ret != 0) {
1396 dev_err(codec->dev, "Failed to register DAI: %d\n", ret);
1397 goto err_codec;
1398 }
1399
1400 return 0;
1401
1402err_codec:
1403 snd_soc_unregister_codec(codec);
1404err:
1405 kfree(wm9081);
1406 return ret;
1407}
1408
1409static void wm9081_unregister(struct wm9081_priv *wm9081)
1410{
1411 wm9081_set_bias_level(&wm9081->codec, SND_SOC_BIAS_OFF);
1412 snd_soc_unregister_dai(&wm9081_dai);
1413 snd_soc_unregister_codec(&wm9081->codec);
1414 kfree(wm9081);
1415 wm9081_codec = NULL;
1416}
1417 1325
1326#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
1418static __devinit int wm9081_i2c_probe(struct i2c_client *i2c, 1327static __devinit int wm9081_i2c_probe(struct i2c_client *i2c,
1419 const struct i2c_device_id *id) 1328 const struct i2c_device_id *id)
1420{ 1329{
1421 struct wm9081_priv *wm9081; 1330 struct wm9081_priv *wm9081;
1422 struct snd_soc_codec *codec; 1331 int ret;
1423 1332
1424 wm9081 = kzalloc(sizeof(struct wm9081_priv), GFP_KERNEL); 1333 wm9081 = kzalloc(sizeof(struct wm9081_priv), GFP_KERNEL);
1425 if (wm9081 == NULL) 1334 if (wm9081 == NULL)
1426 return -ENOMEM; 1335 return -ENOMEM;
1427 1336
1428 codec = &wm9081->codec;
1429 codec->hw_write = (hw_write_t)i2c_master_send;
1430 wm9081->retune = i2c->dev.platform_data;
1431
1432 i2c_set_clientdata(i2c, wm9081); 1337 i2c_set_clientdata(i2c, wm9081);
1433 codec->control_data = i2c; 1338 wm9081->control_data = i2c;
1434
1435 codec->dev = &i2c->dev;
1436 1339
1437 return wm9081_register(wm9081, SND_SOC_I2C); 1340 ret = snd_soc_register_codec(&i2c->dev,
1341 &soc_codec_dev_wm9081, &wm9081_dai, 1);
1342 if (ret < 0)
1343 kfree(wm9081);
1344 return ret;
1438} 1345}
1439 1346
1440static __devexit int wm9081_i2c_remove(struct i2c_client *client) 1347static __devexit int wm9081_i2c_remove(struct i2c_client *client)
1441{ 1348{
1442 struct wm9081_priv *wm9081 = i2c_get_clientdata(client); 1349 snd_soc_unregister_codec(&client->dev);
1443 wm9081_unregister(wm9081); 1350 kfree(i2c_get_clientdata(client));
1444 return 0; 1351 return 0;
1445} 1352}
1446 1353
@@ -1452,31 +1359,34 @@ MODULE_DEVICE_TABLE(i2c, wm9081_i2c_id);
1452 1359
1453static struct i2c_driver wm9081_i2c_driver = { 1360static struct i2c_driver wm9081_i2c_driver = {
1454 .driver = { 1361 .driver = {
1455 .name = "wm9081", 1362 .name = "wm9081-codec",
1456 .owner = THIS_MODULE, 1363 .owner = THIS_MODULE,
1457 }, 1364 },
1458 .probe = wm9081_i2c_probe, 1365 .probe = wm9081_i2c_probe,
1459 .remove = __devexit_p(wm9081_i2c_remove), 1366 .remove = __devexit_p(wm9081_i2c_remove),
1460 .id_table = wm9081_i2c_id, 1367 .id_table = wm9081_i2c_id,
1461}; 1368};
1369#endif
1462 1370
1463static int __init wm9081_modinit(void) 1371static int __init wm9081_modinit(void)
1464{ 1372{
1465 int ret; 1373 int ret = 0;
1466 1374#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
1467 ret = i2c_add_driver(&wm9081_i2c_driver); 1375 ret = i2c_add_driver(&wm9081_i2c_driver);
1468 if (ret != 0) { 1376 if (ret != 0) {
1469 printk(KERN_ERR "Failed to register WM9081 I2C driver: %d\n", 1377 printk(KERN_ERR "Failed to register WM9081 I2C driver: %d\n",
1470 ret); 1378 ret);
1471 } 1379 }
1472 1380#endif
1473 return ret; 1381 return ret;
1474} 1382}
1475module_init(wm9081_modinit); 1383module_init(wm9081_modinit);
1476 1384
1477static void __exit wm9081_exit(void) 1385static void __exit wm9081_exit(void)
1478{ 1386{
1387#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
1479 i2c_del_driver(&wm9081_i2c_driver); 1388 i2c_del_driver(&wm9081_i2c_driver);
1389#endif
1480} 1390}
1481module_exit(wm9081_exit); 1391module_exit(wm9081_exit);
1482 1392