diff options
Diffstat (limited to 'sound/soc/codecs/wm8350.c')
-rw-r--r-- | sound/soc/codecs/wm8350.c | 231 |
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 | ||
1324 | static int wm8350_suspend(struct platform_device *pdev, pm_message_t state) | 1324 | static 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 | ||
1333 | static int wm8350_resume(struct platform_device *pdev) | 1330 | static 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 | } |
1490 | EXPORT_SYMBOL_GPL(wm8350_mic_jack_detect); | 1484 | EXPORT_SYMBOL_GPL(wm8350_mic_jack_detect); |
1491 | 1485 | ||
1492 | static 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 | |||
1492 | static 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 | |||
1502 | static 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 | ||
1494 | static int wm8350_probe(struct platform_device *pdev) | 1521 | static 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 | |||
1613 | err_priv: | ||
1614 | kfree(priv); | ||
1615 | return ret; | ||
1573 | } | 1616 | } |
1574 | 1617 | ||
1575 | static int wm8350_remove(struct platform_device *pdev) | 1618 | static 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) | 1656 | static 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 | |||
1619 | static 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 | |||
1629 | struct 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 | }; | ||
1647 | EXPORT_SYMBOL_GPL(wm8350_dai); | ||
1648 | |||
1649 | struct 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 | }; |
1655 | EXPORT_SYMBOL_GPL(soc_codec_dev_wm8350); | ||
1656 | 1665 | ||
1657 | static __devinit int wm8350_codec_probe(struct platform_device *pdev) | 1666 | static 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 | |||
1717 | err_codec: | ||
1718 | snd_soc_unregister_codec(codec); | ||
1719 | err_supply: | ||
1720 | regulator_bulk_free(ARRAY_SIZE(priv->supplies), priv->supplies); | ||
1721 | err_priv: | ||
1722 | kfree(priv); | ||
1723 | wm8350_codec = NULL; | ||
1724 | return ret; | ||
1725 | } | 1670 | } |
1726 | 1671 | ||
1727 | static int __devexit wm8350_codec_remove(struct platform_device *pdev) | 1672 | static 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 | ||
1750 | static __init int wm8350_init(void) | 1687 | static __init int wm8350_init(void) |