aboutsummaryrefslogtreecommitdiffstats
path: root/sound/soc/codecs/wm8350.c
diff options
context:
space:
mode:
Diffstat (limited to 'sound/soc/codecs/wm8350.c')
-rw-r--r--sound/soc/codecs/wm8350.c231
1 files changed, 84 insertions, 147 deletions
diff --git a/sound/soc/codecs/wm8350.c b/sound/soc/codecs/wm8350.c
index 0221ca79b3ae..f4f1fba38eb9 100644
--- a/sound/soc/codecs/wm8350.c
+++ b/sound/soc/codecs/wm8350.c
@@ -1321,20 +1321,14 @@ static int wm8350_set_bias_level(struct snd_soc_codec *codec,
1321 return 0; 1321 return 0;
1322} 1322}
1323 1323
1324static int wm8350_suspend(struct platform_device *pdev, pm_message_t state) 1324static int wm8350_suspend(struct snd_soc_codec *codec, pm_message_t state)
1325{ 1325{
1326 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
1327 struct snd_soc_codec *codec = socdev->card->codec;
1328
1329 wm8350_set_bias_level(codec, SND_SOC_BIAS_OFF); 1326 wm8350_set_bias_level(codec, SND_SOC_BIAS_OFF);
1330 return 0; 1327 return 0;
1331} 1328}
1332 1329
1333static int wm8350_resume(struct platform_device *pdev) 1330static int wm8350_resume(struct snd_soc_codec *codec)
1334{ 1331{
1335 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
1336 struct snd_soc_codec *codec = socdev->card->codec;
1337
1338 wm8350_set_bias_level(codec, SND_SOC_BIAS_STANDBY); 1332 wm8350_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
1339 1333
1340 return 0; 1334 return 0;
@@ -1489,24 +1483,74 @@ int wm8350_mic_jack_detect(struct snd_soc_codec *codec,
1489} 1483}
1490EXPORT_SYMBOL_GPL(wm8350_mic_jack_detect); 1484EXPORT_SYMBOL_GPL(wm8350_mic_jack_detect);
1491 1485
1492static struct snd_soc_codec *wm8350_codec; 1486#define WM8350_RATES (SNDRV_PCM_RATE_8000_96000)
1487
1488#define WM8350_FORMATS (SNDRV_PCM_FMTBIT_S16_LE |\
1489 SNDRV_PCM_FMTBIT_S20_3LE |\
1490 SNDRV_PCM_FMTBIT_S24_LE)
1491
1492static struct snd_soc_dai_ops wm8350_dai_ops = {
1493 .hw_params = wm8350_pcm_hw_params,
1494 .digital_mute = wm8350_mute,
1495 .trigger = wm8350_pcm_trigger,
1496 .set_fmt = wm8350_set_dai_fmt,
1497 .set_sysclk = wm8350_set_dai_sysclk,
1498 .set_pll = wm8350_set_fll,
1499 .set_clkdiv = wm8350_set_clkdiv,
1500};
1501
1502static struct snd_soc_dai_driver wm8350_dai = {
1503 .name = "wm8350-hifi",
1504 .playback = {
1505 .stream_name = "Playback",
1506 .channels_min = 1,
1507 .channels_max = 2,
1508 .rates = WM8350_RATES,
1509 .formats = WM8350_FORMATS,
1510 },
1511 .capture = {
1512 .stream_name = "Capture",
1513 .channels_min = 1,
1514 .channels_max = 2,
1515 .rates = WM8350_RATES,
1516 .formats = WM8350_FORMATS,
1517 },
1518 .ops = &wm8350_dai_ops,
1519};
1493 1520
1494static int wm8350_probe(struct platform_device *pdev) 1521static int wm8350_codec_probe(struct snd_soc_codec *codec)
1495{ 1522{
1496 struct snd_soc_device *socdev = platform_get_drvdata(pdev); 1523 struct wm8350 *wm8350 = dev_get_platdata(codec->dev);
1497 struct snd_soc_codec *codec;
1498 struct wm8350 *wm8350;
1499 struct wm8350_data *priv; 1524 struct wm8350_data *priv;
1500 int ret;
1501 struct wm8350_output *out1; 1525 struct wm8350_output *out1;
1502 struct wm8350_output *out2; 1526 struct wm8350_output *out2;
1527 int ret, i;
1503 1528
1504 BUG_ON(!wm8350_codec); 1529 if (wm8350->codec.platform_data == NULL) {
1530 dev_err(codec->dev, "No audio platform data supplied\n");
1531 return -EINVAL;
1532 }
1533
1534 priv = kzalloc(sizeof(struct wm8350_data), GFP_KERNEL);
1535 if (priv == NULL)
1536 return -ENOMEM;
1537 snd_soc_codec_set_drvdata(codec, priv);
1538
1539 for (i = 0; i < ARRAY_SIZE(supply_names); i++)
1540 priv->supplies[i].supply = supply_names[i];
1541
1542 ret = regulator_bulk_get(wm8350->dev, ARRAY_SIZE(priv->supplies),
1543 priv->supplies);
1544 if (ret != 0)
1545 goto err_priv;
1546
1547 wm8350->codec.codec = codec;
1548 codec->control_data = wm8350;
1505 1549
1506 socdev->card->codec = wm8350_codec; 1550 /* Put the codec into reset if it wasn't already */
1507 codec = socdev->card->codec; 1551 wm8350_clear_bits(wm8350, WM8350_POWER_MGMT_5, WM8350_CODEC_ENA);
1508 wm8350 = codec->control_data; 1552
1509 priv = snd_soc_codec_get_drvdata(codec); 1553 INIT_DELAYED_WORK(&codec->delayed_work, wm8350_pga_work);
1510 1554
1511 /* Enable the codec */ 1555 /* Enable the codec */
1512 wm8350_set_bits(wm8350, WM8350_POWER_MGMT_5, WM8350_CODEC_ENA); 1556 wm8350_set_bits(wm8350, WM8350_POWER_MGMT_5, WM8350_CODEC_ENA);
@@ -1557,11 +1601,6 @@ static int wm8350_probe(struct platform_device *pdev)
1557 wm8350_register_irq(wm8350, WM8350_IRQ_CODEC_MICD, 1601 wm8350_register_irq(wm8350, WM8350_IRQ_CODEC_MICD,
1558 wm8350_mic_handler, 0, "Microphone detect", priv); 1602 wm8350_mic_handler, 0, "Microphone detect", priv);
1559 1603
1560 ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
1561 if (ret < 0) {
1562 dev_err(&pdev->dev, "failed to create pcms\n");
1563 return ret;
1564 }
1565 1604
1566 snd_soc_add_controls(codec, wm8350_snd_controls, 1605 snd_soc_add_controls(codec, wm8350_snd_controls,
1567 ARRAY_SIZE(wm8350_snd_controls)); 1606 ARRAY_SIZE(wm8350_snd_controls));
@@ -1570,14 +1609,16 @@ static int wm8350_probe(struct platform_device *pdev)
1570 wm8350_set_bias_level(codec, SND_SOC_BIAS_STANDBY); 1609 wm8350_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
1571 1610
1572 return 0; 1611 return 0;
1612
1613err_priv:
1614 kfree(priv);
1615 return ret;
1573} 1616}
1574 1617
1575static int wm8350_remove(struct platform_device *pdev) 1618static int wm8350_codec_remove(struct snd_soc_codec *codec)
1576{ 1619{
1577 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
1578 struct snd_soc_codec *codec = socdev->card->codec;
1579 struct wm8350 *wm8350 = codec->control_data;
1580 struct wm8350_data *priv = snd_soc_codec_get_drvdata(codec); 1620 struct wm8350_data *priv = snd_soc_codec_get_drvdata(codec);
1621 struct wm8350 *wm8350 = dev_get_platdata(codec->dev);
1581 int ret; 1622 int ret;
1582 1623
1583 wm8350_clear_bits(wm8350, WM8350_JACK_DETECT, 1624 wm8350_clear_bits(wm8350, WM8350_JACK_DETECT,
@@ -1607,134 +1648,30 @@ static int wm8350_remove(struct platform_device *pdev)
1607 1648
1608 wm8350_clear_bits(wm8350, WM8350_POWER_MGMT_5, WM8350_CODEC_ENA); 1649 wm8350_clear_bits(wm8350, WM8350_POWER_MGMT_5, WM8350_CODEC_ENA);
1609 1650
1651 regulator_bulk_free(ARRAY_SIZE(priv->supplies), priv->supplies);
1652 kfree(priv);
1610 return 0; 1653 return 0;
1611} 1654}
1612 1655
1613#define WM8350_RATES (SNDRV_PCM_RATE_8000_96000) 1656static struct snd_soc_codec_driver soc_codec_dev_wm8350 = {
1614 1657 .probe = wm8350_codec_probe,
1615#define WM8350_FORMATS (SNDRV_PCM_FMTBIT_S16_LE |\ 1658 .remove = wm8350_codec_remove,
1616 SNDRV_PCM_FMTBIT_S20_3LE |\
1617 SNDRV_PCM_FMTBIT_S24_LE)
1618
1619static struct snd_soc_dai_ops wm8350_dai_ops = {
1620 .hw_params = wm8350_pcm_hw_params,
1621 .digital_mute = wm8350_mute,
1622 .trigger = wm8350_pcm_trigger,
1623 .set_fmt = wm8350_set_dai_fmt,
1624 .set_sysclk = wm8350_set_dai_sysclk,
1625 .set_pll = wm8350_set_fll,
1626 .set_clkdiv = wm8350_set_clkdiv,
1627};
1628
1629struct snd_soc_dai wm8350_dai = {
1630 .name = "WM8350",
1631 .playback = {
1632 .stream_name = "Playback",
1633 .channels_min = 1,
1634 .channels_max = 2,
1635 .rates = WM8350_RATES,
1636 .formats = WM8350_FORMATS,
1637 },
1638 .capture = {
1639 .stream_name = "Capture",
1640 .channels_min = 1,
1641 .channels_max = 2,
1642 .rates = WM8350_RATES,
1643 .formats = WM8350_FORMATS,
1644 },
1645 .ops = &wm8350_dai_ops,
1646};
1647EXPORT_SYMBOL_GPL(wm8350_dai);
1648
1649struct snd_soc_codec_device soc_codec_dev_wm8350 = {
1650 .probe = wm8350_probe,
1651 .remove = wm8350_remove,
1652 .suspend = wm8350_suspend, 1659 .suspend = wm8350_suspend,
1653 .resume = wm8350_resume, 1660 .resume = wm8350_resume,
1661 .read = wm8350_codec_read,
1662 .write = wm8350_codec_write,
1663 .set_bias_level = wm8350_set_bias_level,
1654}; 1664};
1655EXPORT_SYMBOL_GPL(soc_codec_dev_wm8350);
1656 1665
1657static __devinit int wm8350_codec_probe(struct platform_device *pdev) 1666static int __devinit wm8350_probe(struct platform_device *pdev)
1658{ 1667{
1659 struct wm8350 *wm8350 = platform_get_drvdata(pdev); 1668 return snd_soc_register_codec(&pdev->dev, &soc_codec_dev_wm8350,
1660 struct wm8350_data *priv; 1669 &wm8350_dai, 1);
1661 struct snd_soc_codec *codec;
1662 int ret, i;
1663
1664 if (wm8350->codec.platform_data == NULL) {
1665 dev_err(&pdev->dev, "No audio platform data supplied\n");
1666 return -EINVAL;
1667 }
1668
1669 priv = kzalloc(sizeof(struct wm8350_data), GFP_KERNEL);
1670 if (priv == NULL)
1671 return -ENOMEM;
1672
1673 for (i = 0; i < ARRAY_SIZE(supply_names); i++)
1674 priv->supplies[i].supply = supply_names[i];
1675
1676 ret = regulator_bulk_get(wm8350->dev, ARRAY_SIZE(priv->supplies),
1677 priv->supplies);
1678 if (ret != 0)
1679 goto err_priv;
1680
1681 codec = &priv->codec;
1682 wm8350->codec.codec = codec;
1683
1684 wm8350_dai.dev = &pdev->dev;
1685
1686 mutex_init(&codec->mutex);
1687 INIT_LIST_HEAD(&codec->dapm_widgets);
1688 INIT_LIST_HEAD(&codec->dapm_paths);
1689 codec->dev = &pdev->dev;
1690 codec->name = "WM8350";
1691 codec->owner = THIS_MODULE;
1692 codec->read = wm8350_codec_read;
1693 codec->write = wm8350_codec_write;
1694 codec->bias_level = SND_SOC_BIAS_OFF;
1695 codec->set_bias_level = wm8350_set_bias_level;
1696 codec->dai = &wm8350_dai;
1697 codec->num_dai = 1;
1698 codec->reg_cache_size = WM8350_MAX_REGISTER;
1699 snd_soc_codec_set_drvdata(codec, priv);
1700 codec->control_data = wm8350;
1701
1702 /* Put the codec into reset if it wasn't already */
1703 wm8350_clear_bits(wm8350, WM8350_POWER_MGMT_5, WM8350_CODEC_ENA);
1704
1705 INIT_DELAYED_WORK(&codec->delayed_work, wm8350_pga_work);
1706 ret = snd_soc_register_codec(codec);
1707 if (ret != 0)
1708 goto err_supply;
1709
1710 wm8350_codec = codec;
1711
1712 ret = snd_soc_register_dai(&wm8350_dai);
1713 if (ret != 0)
1714 goto err_codec;
1715 return 0;
1716
1717err_codec:
1718 snd_soc_unregister_codec(codec);
1719err_supply:
1720 regulator_bulk_free(ARRAY_SIZE(priv->supplies), priv->supplies);
1721err_priv:
1722 kfree(priv);
1723 wm8350_codec = NULL;
1724 return ret;
1725} 1670}
1726 1671
1727static int __devexit wm8350_codec_remove(struct platform_device *pdev) 1672static int __devexit wm8350_remove(struct platform_device *pdev)
1728{ 1673{
1729 struct wm8350 *wm8350 = platform_get_drvdata(pdev); 1674 snd_soc_unregister_codec(&pdev->dev);
1730 struct snd_soc_codec *codec = wm8350->codec.codec;
1731 struct wm8350_data *priv = snd_soc_codec_get_drvdata(codec);
1732
1733 snd_soc_unregister_dai(&wm8350_dai);
1734 snd_soc_unregister_codec(codec);
1735 regulator_bulk_free(ARRAY_SIZE(priv->supplies), priv->supplies);
1736 kfree(priv);
1737 wm8350_codec = NULL;
1738 return 0; 1675 return 0;
1739} 1676}
1740 1677
@@ -1743,8 +1680,8 @@ static struct platform_driver wm8350_codec_driver = {
1743 .name = "wm8350-codec", 1680 .name = "wm8350-codec",
1744 .owner = THIS_MODULE, 1681 .owner = THIS_MODULE,
1745 }, 1682 },
1746 .probe = wm8350_codec_probe, 1683 .probe = wm8350_probe,
1747 .remove = __devexit_p(wm8350_codec_remove), 1684 .remove = __devexit_p(wm8350_remove),
1748}; 1685};
1749 1686
1750static __init int wm8350_init(void) 1687static __init int wm8350_init(void)