aboutsummaryrefslogtreecommitdiffstats
path: root/sound/soc/soc-core.c
diff options
context:
space:
mode:
authorJarkko Nikula <jhnikula@gmail.com>2010-12-06 09:27:07 -0500
committerMark Brown <broonie@opensource.wolfsonmicro.com>2010-12-06 14:14:46 -0500
commit589c3563f6476950f26b5bcc9beb1b39a7bcc644 (patch)
tree8d3d5ef20fc37e36f014fd80059bc0e9f6e42f99 /sound/soc/soc-core.c
parent0afc8c733e95642ee9200966081da82564af8f8f (diff)
ASoC: Merge common code in DAI link and auxiliary codec probing/removal
Commit 2eea392 "ASoC: Add support for optional auxiliary dailess codecs" added much of code that can be shared with DAI link codec probing/removal. Merge now this common code into new soc_probe_codec, soc_remove_codec and soc_post_component_init functions. Error prints in these functions are converted to use dev_err and to print the error code. Signed-off-by: Jarkko Nikula <jhnikula@gmail.com> Acked-by: Liam Girdwood <lrg@slimlogic.co.uk> Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
Diffstat (limited to 'sound/soc/soc-core.c')
-rw-r--r--sound/soc/soc-core.c284
1 files changed, 132 insertions, 152 deletions
diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c
index 17dcd56a2520..b3605a1c8c46 100644
--- a/sound/soc/soc-core.c
+++ b/sound/soc/soc-core.c
@@ -1328,6 +1328,27 @@ out:
1328 return 1; 1328 return 1;
1329} 1329}
1330 1330
1331static void soc_remove_codec(struct snd_soc_codec *codec)
1332{
1333 int err;
1334
1335 if (codec->driver->remove) {
1336 err = codec->driver->remove(codec);
1337 if (err < 0)
1338 dev_err(codec->dev,
1339 "asoc: failed to remove %s: %d\n",
1340 codec->name, err);
1341 }
1342
1343 /* Make sure all DAPM widgets are freed */
1344 snd_soc_dapm_free(&codec->dapm);
1345
1346 soc_cleanup_codec_debugfs(codec);
1347 codec->probed = 0;
1348 list_del(&codec->card_list);
1349 module_put(codec->dev->driver->owner);
1350}
1351
1331static void soc_remove_dai_link(struct snd_soc_card *card, int num) 1352static void soc_remove_dai_link(struct snd_soc_card *card, int num)
1332{ 1353{
1333 struct snd_soc_pcm_runtime *rtd = &card->rtd[num]; 1354 struct snd_soc_pcm_runtime *rtd = &card->rtd[num];
@@ -1339,6 +1360,7 @@ static void soc_remove_dai_link(struct snd_soc_card *card, int num)
1339 /* unregister the rtd device */ 1360 /* unregister the rtd device */
1340 if (rtd->dev_registered) { 1361 if (rtd->dev_registered) {
1341 device_remove_file(&rtd->dev, &dev_attr_pmdown_time); 1362 device_remove_file(&rtd->dev, &dev_attr_pmdown_time);
1363 device_remove_file(&rtd->dev, &dev_attr_codec_reg);
1342 device_unregister(&rtd->dev); 1364 device_unregister(&rtd->dev);
1343 rtd->dev_registered = 0; 1365 rtd->dev_registered = 0;
1344 } 1366 }
@@ -1367,22 +1389,8 @@ static void soc_remove_dai_link(struct snd_soc_card *card, int num)
1367 } 1389 }
1368 1390
1369 /* remove the CODEC */ 1391 /* remove the CODEC */
1370 if (codec && codec->probed) { 1392 if (codec && codec->probed)
1371 if (codec->driver->remove) { 1393 soc_remove_codec(codec);
1372 err = codec->driver->remove(codec);
1373 if (err < 0)
1374 printk(KERN_ERR "asoc: failed to remove %s\n", codec->name);
1375 }
1376
1377 /* Make sure all DAPM widgets are freed */
1378 snd_soc_dapm_free(&codec->dapm);
1379
1380 soc_cleanup_codec_debugfs(codec);
1381 device_remove_file(&rtd->dev, &dev_attr_codec_reg);
1382 codec->probed = 0;
1383 list_del(&codec->card_list);
1384 module_put(codec->dev->driver->owner);
1385 }
1386 1394
1387 /* remove the cpu_dai */ 1395 /* remove the cpu_dai */
1388 if (cpu_dai && cpu_dai->probed) { 1396 if (cpu_dai && cpu_dai->probed) {
@@ -1414,8 +1422,105 @@ static void soc_set_name_prefix(struct snd_soc_card *card,
1414 } 1422 }
1415} 1423}
1416 1424
1425static int soc_probe_codec(struct snd_soc_card *card,
1426 struct snd_soc_codec *codec)
1427{
1428 int ret = 0;
1429
1430 codec->card = card;
1431 codec->dapm.card = card;
1432 soc_set_name_prefix(card, codec);
1433
1434 if (codec->driver->probe) {
1435 ret = codec->driver->probe(codec);
1436 if (ret < 0) {
1437 dev_err(codec->dev,
1438 "asoc: failed to probe CODEC %s: %d\n",
1439 codec->name, ret);
1440 return ret;
1441 }
1442 }
1443
1444 soc_init_codec_debugfs(codec);
1445
1446 /* mark codec as probed and add to card codec list */
1447 codec->probed = 1;
1448 list_add(&codec->card_list, &card->codec_dev_list);
1449
1450 return ret;
1451}
1452
1417static void rtd_release(struct device *dev) {} 1453static void rtd_release(struct device *dev) {}
1418 1454
1455static int soc_post_component_init(struct snd_soc_card *card,
1456 struct snd_soc_codec *codec,
1457 int num, int dailess)
1458{
1459 struct snd_soc_dai_link *dai_link = NULL;
1460 struct snd_soc_aux_dev *aux_dev = NULL;
1461 struct snd_soc_pcm_runtime *rtd;
1462 const char *temp, *name;
1463 int ret = 0;
1464
1465 if (!dailess) {
1466 dai_link = &card->dai_link[num];
1467 rtd = &card->rtd[num];
1468 name = dai_link->name;
1469 } else {
1470 aux_dev = &card->aux_dev[num];
1471 rtd = &card->rtd_aux[num];
1472 name = aux_dev->name;
1473 }
1474
1475 /* machine controls, routes and widgets are not prefixed */
1476 temp = codec->name_prefix;
1477 codec->name_prefix = NULL;
1478
1479 /* do machine specific initialization */
1480 if (!dailess && dai_link->init)
1481 ret = dai_link->init(rtd);
1482 else if (dailess && aux_dev->init)
1483 ret = aux_dev->init(&codec->dapm);
1484 if (ret < 0) {
1485 dev_err(card->dev, "asoc: failed to init %s: %d\n", name, ret);
1486 return ret;
1487 }
1488 codec->name_prefix = temp;
1489
1490 /* Make sure all DAPM widgets are instantiated */
1491 snd_soc_dapm_new_widgets(&codec->dapm);
1492 snd_soc_dapm_sync(&codec->dapm);
1493
1494 /* register the rtd device */
1495 rtd->codec = codec;
1496 rtd->card = card;
1497 rtd->dev.parent = card->dev;
1498 rtd->dev.release = rtd_release;
1499 rtd->dev.init_name = name;
1500 ret = device_register(&rtd->dev);
1501 if (ret < 0) {
1502 dev_err(card->dev,
1503 "asoc: failed to register runtime device: %d\n", ret);
1504 return ret;
1505 }
1506 rtd->dev_registered = 1;
1507
1508 /* add DAPM sysfs entries for this codec */
1509 ret = snd_soc_dapm_sys_add(&rtd->dev);
1510 if (ret < 0)
1511 dev_err(codec->dev,
1512 "asoc: failed to add codec dapm sysfs entries: %d\n",
1513 ret);
1514
1515 /* add codec sysfs entries */
1516 ret = device_create_file(&rtd->dev, &dev_attr_codec_reg);
1517 if (ret < 0)
1518 dev_err(codec->dev,
1519 "asoc: failed to add codec sysfs files: %d\n", ret);
1520
1521 return 0;
1522}
1523
1419static int soc_probe_dai_link(struct snd_soc_card *card, int num) 1524static int soc_probe_dai_link(struct snd_soc_card *card, int num)
1420{ 1525{
1421 struct snd_soc_dai_link *dai_link = &card->dai_link[num]; 1526 struct snd_soc_dai_link *dai_link = &card->dai_link[num];
@@ -1423,17 +1528,13 @@ static int soc_probe_dai_link(struct snd_soc_card *card, int num)
1423 struct snd_soc_codec *codec = rtd->codec; 1528 struct snd_soc_codec *codec = rtd->codec;
1424 struct snd_soc_platform *platform = rtd->platform; 1529 struct snd_soc_platform *platform = rtd->platform;
1425 struct snd_soc_dai *codec_dai = rtd->codec_dai, *cpu_dai = rtd->cpu_dai; 1530 struct snd_soc_dai *codec_dai = rtd->codec_dai, *cpu_dai = rtd->cpu_dai;
1426 const char *temp;
1427 int ret; 1531 int ret;
1428 1532
1429 dev_dbg(card->dev, "probe %s dai link %d\n", card->name, num); 1533 dev_dbg(card->dev, "probe %s dai link %d\n", card->name, num);
1430 1534
1431 /* config components */ 1535 /* config components */
1432 codec_dai->codec = codec; 1536 codec_dai->codec = codec;
1433 codec->card = card;
1434 cpu_dai->platform = platform; 1537 cpu_dai->platform = platform;
1435 rtd->card = card;
1436 rtd->dev.parent = card->dev;
1437 codec_dai->card = card; 1538 codec_dai->card = card;
1438 cpu_dai->card = card; 1539 cpu_dai->card = card;
1439 1540
@@ -1457,22 +1558,9 @@ static int soc_probe_dai_link(struct snd_soc_card *card, int num)
1457 1558
1458 /* probe the CODEC */ 1559 /* probe the CODEC */
1459 if (!codec->probed) { 1560 if (!codec->probed) {
1460 codec->dapm.card = card; 1561 ret = soc_probe_codec(card, codec);
1461 soc_set_name_prefix(card, codec); 1562 if (ret < 0)
1462 if (codec->driver->probe) { 1563 return ret;
1463 ret = codec->driver->probe(codec);
1464 if (ret < 0) {
1465 printk(KERN_ERR "asoc: failed to probe CODEC %s\n",
1466 codec->name);
1467 return ret;
1468 }
1469 }
1470
1471 soc_init_codec_debugfs(codec);
1472
1473 /* mark codec as probed and add to card codec list */
1474 codec->probed = 1;
1475 list_add(&codec->card_list, &card->codec_dev_list);
1476 } 1564 }
1477 1565
1478 /* probe the platform */ 1566 /* probe the platform */
@@ -1509,47 +1597,14 @@ static int soc_probe_dai_link(struct snd_soc_card *card, int num)
1509 /* DAPM dai link stream work */ 1597 /* DAPM dai link stream work */
1510 INIT_DELAYED_WORK(&rtd->delayed_work, close_delayed_work); 1598 INIT_DELAYED_WORK(&rtd->delayed_work, close_delayed_work);
1511 1599
1512 /* now that all clients have probed, initialise the DAI link */ 1600 ret = soc_post_component_init(card, codec, num, 0);
1513 if (dai_link->init) { 1601 if (ret)
1514 /* machine controls, routes and widgets are not prefixed */
1515 temp = rtd->codec->name_prefix;
1516 rtd->codec->name_prefix = NULL;
1517 ret = dai_link->init(rtd);
1518 if (ret < 0) {
1519 printk(KERN_ERR "asoc: failed to init %s\n", dai_link->stream_name);
1520 return ret;
1521 }
1522 rtd->codec->name_prefix = temp;
1523 }
1524
1525 /* Make sure all DAPM widgets are instantiated */
1526 snd_soc_dapm_new_widgets(&codec->dapm);
1527 snd_soc_dapm_sync(&codec->dapm);
1528
1529 /* register the rtd device */
1530 rtd->dev.release = rtd_release;
1531 rtd->dev.init_name = dai_link->name;
1532 ret = device_register(&rtd->dev);
1533 if (ret < 0) {
1534 printk(KERN_ERR "asoc: failed to register DAI runtime device %d\n", ret);
1535 return ret; 1602 return ret;
1536 }
1537 1603
1538 rtd->dev_registered = 1;
1539 ret = device_create_file(&rtd->dev, &dev_attr_pmdown_time); 1604 ret = device_create_file(&rtd->dev, &dev_attr_pmdown_time);
1540 if (ret < 0) 1605 if (ret < 0)
1541 printk(KERN_WARNING "asoc: failed to add pmdown_time sysfs\n"); 1606 printk(KERN_WARNING "asoc: failed to add pmdown_time sysfs\n");
1542 1607
1543 /* add DAPM sysfs entries for this codec */
1544 ret = snd_soc_dapm_sys_add(&rtd->dev);
1545 if (ret < 0)
1546 printk(KERN_WARNING "asoc: failed to add codec dapm sysfs entries\n");
1547
1548 /* add codec sysfs entries */
1549 ret = device_create_file(&rtd->dev, &dev_attr_codec_reg);
1550 if (ret < 0)
1551 printk(KERN_WARNING "asoc: failed to add codec sysfs files\n");
1552
1553 /* create the pcm */ 1608 /* create the pcm */
1554 ret = soc_new_pcm(rtd, num); 1609 ret = soc_new_pcm(rtd, num);
1555 if (ret < 0) { 1610 if (ret < 0) {
@@ -1607,9 +1662,7 @@ static void soc_unregister_ac97_dai_link(struct snd_soc_codec *codec)
1607static int soc_probe_aux_dev(struct snd_soc_card *card, int num) 1662static int soc_probe_aux_dev(struct snd_soc_card *card, int num)
1608{ 1663{
1609 struct snd_soc_aux_dev *aux_dev = &card->aux_dev[num]; 1664 struct snd_soc_aux_dev *aux_dev = &card->aux_dev[num];
1610 struct snd_soc_pcm_runtime *rtd = &card->rtd_aux[num];
1611 struct snd_soc_codec *codec; 1665 struct snd_soc_codec *codec;
1612 const char *temp;
1613 int ret = -ENODEV; 1666 int ret = -ENODEV;
1614 1667
1615 /* find CODEC from registered CODECs*/ 1668 /* find CODEC from registered CODECs*/
@@ -1632,67 +1685,11 @@ found:
1632 if (!try_module_get(codec->dev->driver->owner)) 1685 if (!try_module_get(codec->dev->driver->owner))
1633 return -ENODEV; 1686 return -ENODEV;
1634 1687
1635 codec->card = card; 1688 ret = soc_probe_codec(card, codec);
1636 codec->dapm.card = card;
1637
1638 soc_set_name_prefix(card, codec);
1639 if (codec->driver->probe) {
1640 ret = codec->driver->probe(codec);
1641 if (ret < 0) {
1642 dev_err(codec->dev, "asoc: failed to probe CODEC");
1643 return ret;
1644 }
1645 }
1646
1647 soc_init_codec_debugfs(codec);
1648
1649 /* mark codec as probed and add to card codec list */
1650 codec->probed = 1;
1651 list_add(&codec->card_list, &card->codec_dev_list);
1652
1653 /* now that all clients have probed, initialise the DAI link */
1654 if (aux_dev->init) {
1655 /* machine controls, routes and widgets are not prefixed */
1656 temp = codec->name_prefix;
1657 codec->name_prefix = NULL;
1658 ret = aux_dev->init(&codec->dapm);
1659 if (ret < 0) {
1660 dev_err(codec->dev,
1661 "asoc: failed to init %s\n", aux_dev->name);
1662 return ret;
1663 }
1664 codec->name_prefix = temp;
1665 }
1666
1667 /* Make sure all DAPM widgets are instantiated */
1668 snd_soc_dapm_new_widgets(&codec->dapm);
1669 snd_soc_dapm_sync(&codec->dapm);
1670
1671 /* register the rtd device */
1672 rtd->codec = codec;
1673 rtd->card = card;
1674 rtd->dev.parent = card->dev;
1675 rtd->dev.release = rtd_release;
1676 rtd->dev.init_name = aux_dev->name;
1677 ret = device_register(&rtd->dev);
1678 if (ret < 0) {
1679 dev_err(codec->dev,
1680 "asoc: failed to register aux runtime device %d\n",
1681 ret);
1682 return ret;
1683 }
1684 rtd->dev_registered = 1;
1685
1686 /* add DAPM sysfs entries for this codec */
1687 ret = snd_soc_dapm_sys_add(&rtd->dev);
1688 if (ret < 0) 1689 if (ret < 0)
1689 dev_err(codec->dev, 1690 return ret;
1690 "asoc: failed to add codec dapm sysfs entries\n");
1691 1691
1692 /* add codec sysfs entries */ 1692 ret = soc_post_component_init(card, codec, num, 1);
1693 ret = device_create_file(&rtd->dev, &dev_attr_codec_reg);
1694 if (ret < 0)
1695 dev_err(codec->dev, "asoc: failed to add codec sysfs files\n");
1696 1693
1697out: 1694out:
1698 return ret; 1695 return ret;
@@ -1702,33 +1699,16 @@ static void soc_remove_aux_dev(struct snd_soc_card *card, int num)
1702{ 1699{
1703 struct snd_soc_pcm_runtime *rtd = &card->rtd_aux[num]; 1700 struct snd_soc_pcm_runtime *rtd = &card->rtd_aux[num];
1704 struct snd_soc_codec *codec = rtd->codec; 1701 struct snd_soc_codec *codec = rtd->codec;
1705 int err;
1706 1702
1707 /* unregister the rtd device */ 1703 /* unregister the rtd device */
1708 if (rtd->dev_registered) { 1704 if (rtd->dev_registered) {
1705 device_remove_file(&rtd->dev, &dev_attr_codec_reg);
1709 device_unregister(&rtd->dev); 1706 device_unregister(&rtd->dev);
1710 rtd->dev_registered = 0; 1707 rtd->dev_registered = 0;
1711 } 1708 }
1712 1709
1713 /* remove the CODEC */ 1710 if (codec && codec->probed)
1714 if (codec && codec->probed) { 1711 soc_remove_codec(codec);
1715 if (codec->driver->remove) {
1716 err = codec->driver->remove(codec);
1717 if (err < 0)
1718 dev_err(codec->dev,
1719 "asoc: failed to remove %s\n",
1720 codec->name);
1721 }
1722
1723 /* Make sure all DAPM widgets are freed */
1724 snd_soc_dapm_free(&codec->dapm);
1725
1726 soc_cleanup_codec_debugfs(codec);
1727 device_remove_file(&rtd->dev, &dev_attr_codec_reg);
1728 codec->probed = 0;
1729 list_del(&codec->card_list);
1730 module_put(codec->dev->driver->owner);
1731 }
1732} 1712}
1733 1713
1734static int snd_soc_init_codec_cache(struct snd_soc_codec *codec, 1714static int snd_soc_init_codec_cache(struct snd_soc_codec *codec,