aboutsummaryrefslogtreecommitdiffstats
path: root/sound/soc/codecs/wm8900.c
diff options
context:
space:
mode:
Diffstat (limited to 'sound/soc/codecs/wm8900.c')
-rw-r--r--sound/soc/codecs/wm8900.c262
1 files changed, 107 insertions, 155 deletions
diff --git a/sound/soc/codecs/wm8900.c b/sound/soc/codecs/wm8900.c
index 3b326c9b5586..6767de10ded0 100644
--- a/sound/soc/codecs/wm8900.c
+++ b/sound/soc/codecs/wm8900.c
@@ -138,6 +138,10 @@
138struct snd_soc_codec_device soc_codec_dev_wm8900; 138struct snd_soc_codec_device soc_codec_dev_wm8900;
139 139
140struct wm8900_priv { 140struct wm8900_priv {
141 struct snd_soc_codec codec;
142
143 u16 reg_cache[WM8900_MAXREG];
144
141 u32 fll_in; /* FLL input frequency */ 145 u32 fll_in; /* FLL input frequency */
142 u32 fll_out; /* FLL output frequency */ 146 u32 fll_out; /* FLL output frequency */
143}; 147};
@@ -727,7 +731,8 @@ static int wm8900_add_widgets(struct snd_soc_codec *codec)
727} 731}
728 732
729static int wm8900_hw_params(struct snd_pcm_substream *substream, 733static int wm8900_hw_params(struct snd_pcm_substream *substream,
730 struct snd_pcm_hw_params *params) 734 struct snd_pcm_hw_params *params,
735 struct snd_soc_dai *dai)
731{ 736{
732 struct snd_soc_pcm_runtime *rtd = substream->private_data; 737 struct snd_soc_pcm_runtime *rtd = substream->private_data;
733 struct snd_soc_device *socdev = rtd->socdev; 738 struct snd_soc_device *socdev = rtd->socdev;
@@ -1117,8 +1122,6 @@ struct snd_soc_dai wm8900_dai = {
1117 }, 1122 },
1118 .ops = { 1123 .ops = {
1119 .hw_params = wm8900_hw_params, 1124 .hw_params = wm8900_hw_params,
1120 },
1121 .dai_ops = {
1122 .set_clkdiv = wm8900_set_dai_clkdiv, 1125 .set_clkdiv = wm8900_set_dai_clkdiv,
1123 .set_pll = wm8900_set_dai_pll, 1126 .set_pll = wm8900_set_dai_pll,
1124 .set_fmt = wm8900_set_dai_fmt, 1127 .set_fmt = wm8900_set_dai_fmt,
@@ -1283,16 +1286,28 @@ static int wm8900_resume(struct platform_device *pdev)
1283 return 0; 1286 return 0;
1284} 1287}
1285 1288
1286/* 1289static struct snd_soc_codec *wm8900_codec;
1287 * initialise the WM8900 driver 1290
1288 * register the mixer and dsp interfaces with the kernel 1291static int wm8900_i2c_probe(struct i2c_client *i2c,
1289 */ 1292 const struct i2c_device_id *id)
1290static int wm8900_init(struct snd_soc_device *socdev)
1291{ 1293{
1292 struct snd_soc_codec *codec = socdev->codec; 1294 struct wm8900_priv *wm8900;
1293 int ret = 0; 1295 struct snd_soc_codec *codec;
1294 unsigned int reg; 1296 unsigned int reg;
1295 struct i2c_client *i2c_client = socdev->codec->control_data; 1297 int ret;
1298
1299 wm8900 = kzalloc(sizeof(struct wm8900_priv), GFP_KERNEL);
1300 if (wm8900 == NULL)
1301 return -ENOMEM;
1302
1303 codec = &wm8900->codec;
1304 codec->private_data = wm8900;
1305 codec->reg_cache = &wm8900->reg_cache[0];
1306 codec->reg_cache_size = WM8900_MAXREG;
1307
1308 mutex_init(&codec->mutex);
1309 INIT_LIST_HEAD(&codec->dapm_widgets);
1310 INIT_LIST_HEAD(&codec->dapm_paths);
1296 1311
1297 codec->name = "WM8900"; 1312 codec->name = "WM8900";
1298 codec->owner = THIS_MODULE; 1313 codec->owner = THIS_MODULE;
@@ -1300,33 +1315,28 @@ static int wm8900_init(struct snd_soc_device *socdev)
1300 codec->write = wm8900_write; 1315 codec->write = wm8900_write;
1301 codec->dai = &wm8900_dai; 1316 codec->dai = &wm8900_dai;
1302 codec->num_dai = 1; 1317 codec->num_dai = 1;
1303 codec->reg_cache_size = WM8900_MAXREG; 1318 codec->hw_write = (hw_write_t)i2c_master_send;
1304 codec->reg_cache = kmemdup(wm8900_reg_defaults, 1319 codec->control_data = i2c;
1305 sizeof(wm8900_reg_defaults), GFP_KERNEL); 1320 codec->set_bias_level = wm8900_set_bias_level;
1306 1321 codec->dev = &i2c->dev;
1307 if (codec->reg_cache == NULL)
1308 return -ENOMEM;
1309 1322
1310 reg = wm8900_read(codec, WM8900_REG_ID); 1323 reg = wm8900_read(codec, WM8900_REG_ID);
1311 if (reg != 0x8900) { 1324 if (reg != 0x8900) {
1312 dev_err(&i2c_client->dev, "Device is not a WM8900 - ID %x\n", 1325 dev_err(&i2c->dev, "Device is not a WM8900 - ID %x\n", reg);
1313 reg); 1326 ret = -ENODEV;
1314 return -ENODEV; 1327 goto err;
1315 }
1316
1317 codec->private_data = kzalloc(sizeof(struct wm8900_priv), GFP_KERNEL);
1318 if (codec->private_data == NULL) {
1319 ret = -ENOMEM;
1320 goto priv_err;
1321 } 1328 }
1322 1329
1323 /* Read back from the chip */ 1330 /* Read back from the chip */
1324 reg = wm8900_chip_read(codec, WM8900_REG_POWER1); 1331 reg = wm8900_chip_read(codec, WM8900_REG_POWER1);
1325 reg = (reg >> 12) & 0xf; 1332 reg = (reg >> 12) & 0xf;
1326 dev_info(&i2c_client->dev, "WM8900 revision %d\n", reg); 1333 dev_info(&i2c->dev, "WM8900 revision %d\n", reg);
1327 1334
1328 wm8900_reset(codec); 1335 wm8900_reset(codec);
1329 1336
1337 /* Turn the chip on */
1338 wm8900_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
1339
1330 /* Latch the volume update bits */ 1340 /* Latch the volume update bits */
1331 wm8900_write(codec, WM8900_REG_LINVOL, 1341 wm8900_write(codec, WM8900_REG_LINVOL,
1332 wm8900_read(codec, WM8900_REG_LINVOL) | 0x100); 1342 wm8900_read(codec, WM8900_REG_LINVOL) | 0x100);
@@ -1352,160 +1362,98 @@ static int wm8900_init(struct snd_soc_device *socdev)
1352 /* Set the DAC and mixer output bias */ 1362 /* Set the DAC and mixer output bias */
1353 wm8900_write(codec, WM8900_REG_OUTBIASCTL, 0x81); 1363 wm8900_write(codec, WM8900_REG_OUTBIASCTL, 0x81);
1354 1364
1355 /* Register pcms */ 1365 wm8900_dai.dev = &i2c->dev;
1356 ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
1357 if (ret < 0) {
1358 dev_err(&i2c_client->dev, "Failed to register new PCMs\n");
1359 goto pcm_err;
1360 }
1361
1362 /* Turn the chip on */
1363 codec->bias_level = SND_SOC_BIAS_OFF;
1364 wm8900_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
1365
1366 wm8900_add_controls(codec);
1367 wm8900_add_widgets(codec);
1368
1369 ret = snd_soc_register_card(socdev);
1370 if (ret < 0) {
1371 dev_err(&i2c_client->dev, "Failed to register card\n");
1372 goto card_err;
1373 }
1374 return ret;
1375
1376card_err:
1377 snd_soc_free_pcms(socdev);
1378 snd_soc_dapm_free(socdev);
1379pcm_err:
1380 kfree(codec->reg_cache);
1381priv_err:
1382 kfree(codec->private_data);
1383 return ret;
1384}
1385 1366
1386static struct snd_soc_device *wm8900_socdev; 1367 wm8900_codec = codec;
1387 1368
1388#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) 1369 ret = snd_soc_register_codec(codec);
1389 1370 if (ret != 0) {
1390static unsigned short normal_i2c[] = { 0, I2C_CLIENT_END }; 1371 dev_err(&i2c->dev, "Failed to register codec: %d\n", ret);
1391
1392/* Magic definition of all other variables and things */
1393I2C_CLIENT_INSMOD;
1394
1395static struct i2c_driver wm8900_i2c_driver;
1396static struct i2c_client client_template;
1397
1398/* If the i2c layer weren't so broken, we could pass this kind of data
1399 around */
1400static int wm8900_codec_probe(struct i2c_adapter *adap, int addr, int kind)
1401{
1402 struct snd_soc_device *socdev = wm8900_socdev;
1403 struct wm8900_setup_data *setup = socdev->codec_data;
1404 struct snd_soc_codec *codec = socdev->codec;
1405 struct i2c_client *i2c;
1406 int ret;
1407
1408 if (addr != setup->i2c_address)
1409 return -ENODEV;
1410
1411 dev_err(&adap->dev, "Probe on %x\n", addr);
1412
1413 client_template.adapter = adap;
1414 client_template.addr = addr;
1415
1416 i2c = kmemdup(&client_template, sizeof(client_template), GFP_KERNEL);
1417 if (i2c == NULL) {
1418 kfree(codec);
1419 return -ENOMEM;
1420 }
1421 i2c_set_clientdata(i2c, codec);
1422 codec->control_data = i2c;
1423
1424 ret = i2c_attach_client(i2c);
1425 if (ret < 0) {
1426 dev_err(&adap->dev,
1427 "failed to attach codec at addr %x\n", addr);
1428 goto err; 1372 goto err;
1429 } 1373 }
1430 1374
1431 ret = wm8900_init(socdev); 1375 ret = snd_soc_register_dai(&wm8900_dai);
1432 if (ret < 0) { 1376 if (ret != 0) {
1433 dev_err(&adap->dev, "failed to initialise WM8900\n"); 1377 dev_err(&i2c->dev, "Failed to register DAI: %d\n", ret);
1434 goto err; 1378 goto err_codec;
1435 } 1379 }
1380
1436 return ret; 1381 return ret;
1437 1382
1383err_codec:
1384 snd_soc_unregister_codec(codec);
1438err: 1385err:
1439 kfree(codec); 1386 kfree(wm8900);
1440 kfree(i2c); 1387 wm8900_codec = NULL;
1441 return ret; 1388 return ret;
1442} 1389}
1443 1390
1444static int wm8900_i2c_detach(struct i2c_client *client) 1391static int wm8900_i2c_remove(struct i2c_client *client)
1445{ 1392{
1446 struct snd_soc_codec *codec = i2c_get_clientdata(client); 1393 snd_soc_unregister_dai(&wm8900_dai);
1447 i2c_detach_client(client); 1394 snd_soc_unregister_codec(wm8900_codec);
1448 kfree(codec->reg_cache); 1395
1449 kfree(client); 1396 wm8900_set_bias_level(wm8900_codec, SND_SOC_BIAS_OFF);
1397
1398 wm8900_dai.dev = NULL;
1399 kfree(wm8900_codec->private_data);
1400 wm8900_codec = NULL;
1401
1450 return 0; 1402 return 0;
1451} 1403}
1452 1404
1453static int wm8900_i2c_attach(struct i2c_adapter *adap) 1405static const struct i2c_device_id wm8900_i2c_id[] = {
1454{ 1406 { "wm8900", 0 },
1455 return i2c_probe(adap, &addr_data, wm8900_codec_probe); 1407 { }
1456} 1408};
1409MODULE_DEVICE_TABLE(i2c, wm8900_i2c_id);
1457 1410
1458/* corgi i2c codec control layer */
1459static struct i2c_driver wm8900_i2c_driver = { 1411static struct i2c_driver wm8900_i2c_driver = {
1460 .driver = { 1412 .driver = {
1461 .name = "WM8900 I2C codec", 1413 .name = "WM8900",
1462 .owner = THIS_MODULE, 1414 .owner = THIS_MODULE,
1463 }, 1415 },
1464 .attach_adapter = wm8900_i2c_attach, 1416 .probe = wm8900_i2c_probe,
1465 .detach_client = wm8900_i2c_detach, 1417 .remove = wm8900_i2c_remove,
1466 .command = NULL, 1418 .id_table = wm8900_i2c_id,
1467};
1468
1469static struct i2c_client client_template = {
1470 .name = "WM8900",
1471 .driver = &wm8900_i2c_driver,
1472}; 1419};
1473#endif
1474 1420
1475static int wm8900_probe(struct platform_device *pdev) 1421static int wm8900_probe(struct platform_device *pdev)
1476{ 1422{
1477 struct snd_soc_device *socdev = platform_get_drvdata(pdev); 1423 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
1478 struct wm8900_setup_data *setup;
1479 struct snd_soc_codec *codec; 1424 struct snd_soc_codec *codec;
1480 int ret = 0; 1425 int ret = 0;
1481 1426
1482 dev_info(&pdev->dev, "WM8900 Audio Codec\n"); 1427 if (!wm8900_codec) {
1483 1428 dev_err(&pdev->dev, "I2C client not yet instantiated\n");
1484 setup = socdev->codec_data; 1429 return -ENODEV;
1485 codec = kzalloc(sizeof(struct snd_soc_codec), GFP_KERNEL); 1430 }
1486 if (codec == NULL)
1487 return -ENOMEM;
1488
1489 mutex_init(&codec->mutex);
1490 INIT_LIST_HEAD(&codec->dapm_widgets);
1491 INIT_LIST_HEAD(&codec->dapm_paths);
1492 1431
1432 codec = wm8900_codec;
1493 socdev->codec = codec; 1433 socdev->codec = codec;
1494 1434
1495 codec->set_bias_level = wm8900_set_bias_level; 1435 /* Register pcms */
1436 ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
1437 if (ret < 0) {
1438 dev_err(&pdev->dev, "Failed to register new PCMs\n");
1439 goto pcm_err;
1440 }
1496 1441
1497 wm8900_socdev = socdev; 1442 wm8900_add_controls(codec);
1498#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) 1443 wm8900_add_widgets(codec);
1499 if (setup->i2c_address) { 1444
1500 normal_i2c[0] = setup->i2c_address; 1445 ret = snd_soc_init_card(socdev);
1501 codec->hw_write = (hw_write_t)i2c_master_send; 1446 if (ret < 0) {
1502 ret = i2c_add_driver(&wm8900_i2c_driver); 1447 dev_err(&pdev->dev, "Failed to register card\n");
1503 if (ret != 0) 1448 goto card_err;
1504 printk(KERN_ERR "can't add i2c driver");
1505 } 1449 }
1506#else 1450
1507#error Non-I2C interfaces not yet supported 1451 return ret;
1508#endif 1452
1453card_err:
1454 snd_soc_free_pcms(socdev);
1455 snd_soc_dapm_free(socdev);
1456pcm_err:
1509 return ret; 1457 return ret;
1510} 1458}
1511 1459
@@ -1513,17 +1461,9 @@ static int wm8900_probe(struct platform_device *pdev)
1513static int wm8900_remove(struct platform_device *pdev) 1461static int wm8900_remove(struct platform_device *pdev)
1514{ 1462{
1515 struct snd_soc_device *socdev = platform_get_drvdata(pdev); 1463 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
1516 struct snd_soc_codec *codec = socdev->codec;
1517
1518 if (codec->control_data)
1519 wm8900_set_bias_level(codec, SND_SOC_BIAS_OFF);
1520 1464
1521 snd_soc_free_pcms(socdev); 1465 snd_soc_free_pcms(socdev);
1522 snd_soc_dapm_free(socdev); 1466 snd_soc_dapm_free(socdev);
1523#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
1524 i2c_del_driver(&wm8900_i2c_driver);
1525#endif
1526 kfree(codec);
1527 1467
1528 return 0; 1468 return 0;
1529} 1469}
@@ -1536,6 +1476,18 @@ struct snd_soc_codec_device soc_codec_dev_wm8900 = {
1536}; 1476};
1537EXPORT_SYMBOL_GPL(soc_codec_dev_wm8900); 1477EXPORT_SYMBOL_GPL(soc_codec_dev_wm8900);
1538 1478
1479static int __init wm8900_modinit(void)
1480{
1481 return i2c_add_driver(&wm8900_i2c_driver);
1482}
1483module_init(wm8900_modinit);
1484
1485static void __exit wm8900_exit(void)
1486{
1487 i2c_del_driver(&wm8900_i2c_driver);
1488}
1489module_exit(wm8900_exit);
1490
1539MODULE_DESCRIPTION("ASoC WM8900 driver"); 1491MODULE_DESCRIPTION("ASoC WM8900 driver");
1540MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfonmicro.com>"); 1492MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfonmicro.com>");
1541MODULE_LICENSE("GPL"); 1493MODULE_LICENSE("GPL");