diff options
author | Mark Brown <broonie@opensource.wolfsonmicro.com> | 2009-02-24 18:33:12 -0500 |
---|---|---|
committer | Mark Brown <broonie@opensource.wolfsonmicro.com> | 2009-02-24 18:49:53 -0500 |
commit | c2bac1606a937d4700f8fdd8e051a4c49593c41b (patch) | |
tree | be475b7bb6b31e2a76efe1ec2b8e2ab4316429d6 /sound/soc/codecs/wm8753.c | |
parent | 69e169da5a69cc991d54bb4d54f236523145756c (diff) |
ASoC: Convert WM8753 to register via normal device probe
The base support for the only in-tree user, the GTA01, is out of tree
and will be updated separately.
Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
Diffstat (limited to 'sound/soc/codecs/wm8753.c')
-rw-r--r-- | sound/soc/codecs/wm8753.c | 369 |
1 files changed, 171 insertions, 198 deletions
diff --git a/sound/soc/codecs/wm8753.c b/sound/soc/codecs/wm8753.c index 4b426888f98d..bc29558149e9 100644 --- a/sound/soc/codecs/wm8753.c +++ b/sound/soc/codecs/wm8753.c | |||
@@ -63,12 +63,6 @@ MODULE_PARM_DESC(caps_charge, "WM8753 cap charge time (msecs)"); | |||
63 | static void wm8753_set_dai_mode(struct snd_soc_codec *codec, | 63 | static void wm8753_set_dai_mode(struct snd_soc_codec *codec, |
64 | unsigned int mode); | 64 | unsigned int mode); |
65 | 65 | ||
66 | /* codec private data */ | ||
67 | struct wm8753_priv { | ||
68 | unsigned int sysclk; | ||
69 | unsigned int pcmclk; | ||
70 | }; | ||
71 | |||
72 | /* | 66 | /* |
73 | * wm8753 register cache | 67 | * wm8753 register cache |
74 | * We can't read the WM8753 register space when we | 68 | * We can't read the WM8753 register space when we |
@@ -93,6 +87,14 @@ static const u16 wm8753_reg[] = { | |||
93 | 0x0000, 0x0000 | 87 | 0x0000, 0x0000 |
94 | }; | 88 | }; |
95 | 89 | ||
90 | /* codec private data */ | ||
91 | struct wm8753_priv { | ||
92 | unsigned int sysclk; | ||
93 | unsigned int pcmclk; | ||
94 | struct snd_soc_codec codec; | ||
95 | u16 reg_cache[ARRAY_SIZE(wm8753_reg)]; | ||
96 | }; | ||
97 | |||
96 | /* | 98 | /* |
97 | * read wm8753 register cache | 99 | * read wm8753 register cache |
98 | */ | 100 | */ |
@@ -1542,36 +1544,24 @@ static int wm8753_resume(struct platform_device *pdev) | |||
1542 | return 0; | 1544 | return 0; |
1543 | } | 1545 | } |
1544 | 1546 | ||
1545 | /* | 1547 | static struct snd_soc_codec *wm8753_codec; |
1546 | * initialise the WM8753 driver | 1548 | |
1547 | * register the mixer and dsp interfaces with the kernel | 1549 | static int wm8753_probe(struct platform_device *pdev) |
1548 | */ | ||
1549 | static int wm8753_init(struct snd_soc_device *socdev) | ||
1550 | { | 1550 | { |
1551 | struct snd_soc_codec *codec = socdev->card->codec; | 1551 | struct snd_soc_device *socdev = platform_get_drvdata(pdev); |
1552 | int reg, ret = 0; | 1552 | struct snd_soc_codec *codec; |
1553 | int ret = 0; | ||
1553 | 1554 | ||
1554 | codec->name = "WM8753"; | 1555 | if (!wm8753_codec) { |
1555 | codec->owner = THIS_MODULE; | 1556 | dev_err(&pdev->dev, "WM8753 codec not yet registered\n"); |
1556 | codec->read = wm8753_read_reg_cache; | 1557 | return -EINVAL; |
1557 | codec->write = wm8753_write; | 1558 | } |
1558 | codec->set_bias_level = wm8753_set_bias_level; | ||
1559 | codec->dai = wm8753_dai; | ||
1560 | codec->num_dai = 2; | ||
1561 | codec->reg_cache_size = ARRAY_SIZE(wm8753_reg); | ||
1562 | codec->reg_cache = kmemdup(wm8753_reg, sizeof(wm8753_reg), GFP_KERNEL); | ||
1563 | 1559 | ||
1564 | if (codec->reg_cache == NULL) | 1560 | socdev->card->codec = wm8753_codec; |
1565 | return -ENOMEM; | 1561 | codec = wm8753_codec; |
1566 | 1562 | ||
1567 | wm8753_set_dai_mode(codec, 0); | 1563 | wm8753_set_dai_mode(codec, 0); |
1568 | 1564 | ||
1569 | ret = wm8753_reset(codec); | ||
1570 | if (ret < 0) { | ||
1571 | printk(KERN_ERR "wm8753: failed to reset device\n"); | ||
1572 | return ret; | ||
1573 | } | ||
1574 | |||
1575 | /* register pcms */ | 1565 | /* register pcms */ |
1576 | ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1); | 1566 | ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1); |
1577 | if (ret < 0) { | 1567 | if (ret < 0) { |
@@ -1579,36 +1569,7 @@ static int wm8753_init(struct snd_soc_device *socdev) | |||
1579 | goto pcm_err; | 1569 | goto pcm_err; |
1580 | } | 1570 | } |
1581 | 1571 | ||
1582 | /* charge output caps */ | 1572 | wm8753_add_controls(codec); |
1583 | wm8753_set_bias_level(codec, SND_SOC_BIAS_PREPARE); | ||
1584 | codec->bias_level = SND_SOC_BIAS_STANDBY; | ||
1585 | schedule_delayed_work(&codec->delayed_work, | ||
1586 | msecs_to_jiffies(caps_charge)); | ||
1587 | |||
1588 | /* set the update bits */ | ||
1589 | reg = wm8753_read_reg_cache(codec, WM8753_LDAC); | ||
1590 | wm8753_write(codec, WM8753_LDAC, reg | 0x0100); | ||
1591 | reg = wm8753_read_reg_cache(codec, WM8753_RDAC); | ||
1592 | wm8753_write(codec, WM8753_RDAC, reg | 0x0100); | ||
1593 | reg = wm8753_read_reg_cache(codec, WM8753_LADC); | ||
1594 | wm8753_write(codec, WM8753_LADC, reg | 0x0100); | ||
1595 | reg = wm8753_read_reg_cache(codec, WM8753_RADC); | ||
1596 | wm8753_write(codec, WM8753_RADC, reg | 0x0100); | ||
1597 | reg = wm8753_read_reg_cache(codec, WM8753_LOUT1V); | ||
1598 | wm8753_write(codec, WM8753_LOUT1V, reg | 0x0100); | ||
1599 | reg = wm8753_read_reg_cache(codec, WM8753_ROUT1V); | ||
1600 | wm8753_write(codec, WM8753_ROUT1V, reg | 0x0100); | ||
1601 | reg = wm8753_read_reg_cache(codec, WM8753_LOUT2V); | ||
1602 | wm8753_write(codec, WM8753_LOUT2V, reg | 0x0100); | ||
1603 | reg = wm8753_read_reg_cache(codec, WM8753_ROUT2V); | ||
1604 | wm8753_write(codec, WM8753_ROUT2V, reg | 0x0100); | ||
1605 | reg = wm8753_read_reg_cache(codec, WM8753_LINVOL); | ||
1606 | wm8753_write(codec, WM8753_LINVOL, reg | 0x0100); | ||
1607 | reg = wm8753_read_reg_cache(codec, WM8753_RINVOL); | ||
1608 | wm8753_write(codec, WM8753_RINVOL, reg | 0x0100); | ||
1609 | |||
1610 | snd_soc_add_controls(codec, wm8753_snd_controls, | ||
1611 | ARRAY_SIZE(wm8753_snd_controls)); | ||
1612 | wm8753_add_widgets(codec); | 1573 | wm8753_add_widgets(codec); |
1613 | ret = snd_soc_init_card(socdev); | 1574 | ret = snd_soc_init_card(socdev); |
1614 | if (ret < 0) { | 1575 | if (ret < 0) { |
@@ -1616,110 +1577,13 @@ static int wm8753_init(struct snd_soc_device *socdev) | |||
1616 | goto card_err; | 1577 | goto card_err; |
1617 | } | 1578 | } |
1618 | 1579 | ||
1619 | return ret; | 1580 | return 0; |
1620 | 1581 | ||
1621 | card_err: | 1582 | card_err: |
1622 | snd_soc_free_pcms(socdev); | 1583 | snd_soc_free_pcms(socdev); |
1623 | snd_soc_dapm_free(socdev); | 1584 | snd_soc_dapm_free(socdev); |
1624 | pcm_err: | ||
1625 | kfree(codec->reg_cache); | ||
1626 | return ret; | ||
1627 | } | ||
1628 | |||
1629 | /* If the i2c layer weren't so broken, we could pass this kind of data | ||
1630 | around */ | ||
1631 | static struct snd_soc_device *wm8753_socdev; | ||
1632 | |||
1633 | #if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) | ||
1634 | static struct i2c_driver wm8753_i2c_driver; | ||
1635 | |||
1636 | static int wm8753_add_i2c_device(struct platform_device *pdev, | ||
1637 | const struct wm8753_setup_data *setup) | ||
1638 | { | ||
1639 | struct i2c_board_info info; | ||
1640 | struct i2c_adapter *adapter; | ||
1641 | struct i2c_client *client; | ||
1642 | int ret; | ||
1643 | |||
1644 | ret = i2c_add_driver(&wm8753_i2c_driver); | ||
1645 | if (ret != 0) { | ||
1646 | dev_err(&pdev->dev, "can't add i2c driver\n"); | ||
1647 | return ret; | ||
1648 | } | ||
1649 | |||
1650 | memset(&info, 0, sizeof(struct i2c_board_info)); | ||
1651 | info.addr = setup->i2c_address; | ||
1652 | strlcpy(info.type, "wm8753", I2C_NAME_SIZE); | ||
1653 | |||
1654 | adapter = i2c_get_adapter(setup->i2c_bus); | ||
1655 | if (!adapter) { | ||
1656 | dev_err(&pdev->dev, "can't get i2c adapter %d\n", | ||
1657 | setup->i2c_bus); | ||
1658 | goto err_driver; | ||
1659 | } | ||
1660 | |||
1661 | client = i2c_new_device(adapter, &info); | ||
1662 | i2c_put_adapter(adapter); | ||
1663 | if (!client) { | ||
1664 | dev_err(&pdev->dev, "can't add i2c device at 0x%x\n", | ||
1665 | (unsigned int)info.addr); | ||
1666 | goto err_driver; | ||
1667 | } | ||
1668 | |||
1669 | return 0; | ||
1670 | |||
1671 | err_driver: | ||
1672 | i2c_del_driver(&wm8753_i2c_driver); | ||
1673 | return -ENODEV; | ||
1674 | } | ||
1675 | #endif | ||
1676 | |||
1677 | static int wm8753_probe(struct platform_device *pdev) | ||
1678 | { | ||
1679 | struct snd_soc_device *socdev = platform_get_drvdata(pdev); | ||
1680 | struct wm8753_setup_data *setup; | ||
1681 | struct snd_soc_codec *codec; | ||
1682 | struct wm8753_priv *wm8753; | ||
1683 | int ret = 0; | ||
1684 | |||
1685 | setup = socdev->codec_data; | ||
1686 | codec = kzalloc(sizeof(struct snd_soc_codec), GFP_KERNEL); | ||
1687 | if (codec == NULL) | ||
1688 | return -ENOMEM; | ||
1689 | |||
1690 | wm8753 = kzalloc(sizeof(struct wm8753_priv), GFP_KERNEL); | ||
1691 | if (wm8753 == NULL) { | ||
1692 | kfree(codec); | ||
1693 | return -ENOMEM; | ||
1694 | } | ||
1695 | |||
1696 | codec->private_data = wm8753; | ||
1697 | socdev->card->codec = codec; | ||
1698 | mutex_init(&codec->mutex); | ||
1699 | INIT_LIST_HEAD(&codec->dapm_widgets); | ||
1700 | INIT_LIST_HEAD(&codec->dapm_paths); | ||
1701 | wm8753_socdev = socdev; | ||
1702 | INIT_DELAYED_WORK(&codec->delayed_work, wm8753_work); | ||
1703 | |||
1704 | #if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) | ||
1705 | if (setup->i2c_address) { | ||
1706 | codec->hw_write = (hw_write_t)i2c_master_send; | ||
1707 | ret = wm8753_add_i2c_device(pdev, setup); | ||
1708 | } | ||
1709 | #endif | ||
1710 | #if defined(CONFIG_SPI_MASTER) | ||
1711 | if (setup->spi) { | ||
1712 | codec->hw_write = (hw_write_t)wm8753_spi_write; | ||
1713 | ret = spi_register_driver(&wm8753_spi_driver); | ||
1714 | if (ret != 0) | ||
1715 | printk(KERN_ERR "can't add spi driver"); | ||
1716 | } | ||
1717 | #endif | ||
1718 | 1585 | ||
1719 | if (ret != 0) { | 1586 | pcm_err: |
1720 | kfree(codec->private_data); | ||
1721 | kfree(codec); | ||
1722 | } | ||
1723 | return ret; | 1587 | return ret; |
1724 | } | 1588 | } |
1725 | 1589 | ||
@@ -1746,26 +1610,9 @@ static int run_delayed_work(struct delayed_work *dwork) | |||
1746 | static int wm8753_remove(struct platform_device *pdev) | 1610 | static int wm8753_remove(struct platform_device *pdev) |
1747 | { | 1611 | { |
1748 | struct snd_soc_device *socdev = platform_get_drvdata(pdev); | 1612 | struct snd_soc_device *socdev = platform_get_drvdata(pdev); |
1749 | struct snd_soc_codec *codec = socdev->card->codec; | ||
1750 | struct wm8753_setup_data *setup = socdev->codec_data; | ||
1751 | 1613 | ||
1752 | if (codec->control_data) | ||
1753 | wm8753_set_bias_level(codec, SND_SOC_BIAS_OFF); | ||
1754 | run_delayed_work(&codec->delayed_work); | ||
1755 | snd_soc_free_pcms(socdev); | 1614 | snd_soc_free_pcms(socdev); |
1756 | snd_soc_dapm_free(socdev); | 1615 | snd_soc_dapm_free(socdev); |
1757 | #if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) | ||
1758 | if (setup->i2c_address) { | ||
1759 | i2c_unregister_device(codec->control_data); | ||
1760 | i2c_del_driver(&wm8753_i2c_driver); | ||
1761 | } | ||
1762 | #endif | ||
1763 | #if defined(CONFIG_SPI_MASTER) | ||
1764 | if (setup->spi) | ||
1765 | spi_unregister_driver(&wm8753_spi_driver); | ||
1766 | #endif | ||
1767 | kfree(codec->private_data); | ||
1768 | kfree(codec); | ||
1769 | 1616 | ||
1770 | return 0; | 1617 | return 0; |
1771 | } | 1618 | } |
@@ -1778,30 +1625,134 @@ struct snd_soc_codec_device soc_codec_dev_wm8753 = { | |||
1778 | }; | 1625 | }; |
1779 | EXPORT_SYMBOL_GPL(soc_codec_dev_wm8753); | 1626 | EXPORT_SYMBOL_GPL(soc_codec_dev_wm8753); |
1780 | 1627 | ||
1628 | static int wm8753_register(struct wm8753_priv *wm8753) | ||
1629 | { | ||
1630 | int ret, i; | ||
1631 | struct snd_soc_codec *codec = &wm8753->codec; | ||
1632 | u16 reg; | ||
1633 | |||
1634 | if (wm8753_codec) { | ||
1635 | dev_err(codec->dev, "Multiple WM8753 devices not supported\n"); | ||
1636 | ret = -EINVAL; | ||
1637 | goto err; | ||
1638 | } | ||
1639 | |||
1640 | mutex_init(&codec->mutex); | ||
1641 | INIT_LIST_HEAD(&codec->dapm_widgets); | ||
1642 | INIT_LIST_HEAD(&codec->dapm_paths); | ||
1643 | |||
1644 | codec->name = "WM8753"; | ||
1645 | codec->owner = THIS_MODULE; | ||
1646 | codec->read = wm8753_read_reg_cache; | ||
1647 | codec->write = wm8753_write; | ||
1648 | codec->bias_level = SND_SOC_BIAS_STANDBY; | ||
1649 | codec->set_bias_level = wm8753_set_bias_level; | ||
1650 | codec->dai = wm8753_dai; | ||
1651 | codec->num_dai = 2; | ||
1652 | codec->reg_cache_size = ARRAY_SIZE(wm8753->reg_cache); | ||
1653 | codec->reg_cache = &wm8753->reg_cache; | ||
1654 | codec->private_data = wm8753; | ||
1655 | |||
1656 | memcpy(codec->reg_cache, wm8753_reg, sizeof(codec->reg_cache)); | ||
1657 | INIT_DELAYED_WORK(&codec->delayed_work, wm8753_work); | ||
1658 | |||
1659 | ret = wm8753_reset(codec); | ||
1660 | if (ret < 0) { | ||
1661 | dev_err(codec->dev, "Failed to issue reset\n"); | ||
1662 | goto err; | ||
1663 | } | ||
1664 | |||
1665 | /* charge output caps */ | ||
1666 | wm8753_set_bias_level(codec, SND_SOC_BIAS_PREPARE); | ||
1667 | schedule_delayed_work(&codec->delayed_work, | ||
1668 | msecs_to_jiffies(caps_charge)); | ||
1669 | |||
1670 | /* set the update bits */ | ||
1671 | reg = wm8753_read_reg_cache(codec, WM8753_LDAC); | ||
1672 | wm8753_write(codec, WM8753_LDAC, reg | 0x0100); | ||
1673 | reg = wm8753_read_reg_cache(codec, WM8753_RDAC); | ||
1674 | wm8753_write(codec, WM8753_RDAC, reg | 0x0100); | ||
1675 | reg = wm8753_read_reg_cache(codec, WM8753_LADC); | ||
1676 | wm8753_write(codec, WM8753_LADC, reg | 0x0100); | ||
1677 | reg = wm8753_read_reg_cache(codec, WM8753_RADC); | ||
1678 | wm8753_write(codec, WM8753_RADC, reg | 0x0100); | ||
1679 | reg = wm8753_read_reg_cache(codec, WM8753_LOUT1V); | ||
1680 | wm8753_write(codec, WM8753_LOUT1V, reg | 0x0100); | ||
1681 | reg = wm8753_read_reg_cache(codec, WM8753_ROUT1V); | ||
1682 | wm8753_write(codec, WM8753_ROUT1V, reg | 0x0100); | ||
1683 | reg = wm8753_read_reg_cache(codec, WM8753_LOUT2V); | ||
1684 | wm8753_write(codec, WM8753_LOUT2V, reg | 0x0100); | ||
1685 | reg = wm8753_read_reg_cache(codec, WM8753_ROUT2V); | ||
1686 | wm8753_write(codec, WM8753_ROUT2V, reg | 0x0100); | ||
1687 | reg = wm8753_read_reg_cache(codec, WM8753_LINVOL); | ||
1688 | wm8753_write(codec, WM8753_LINVOL, reg | 0x0100); | ||
1689 | reg = wm8753_read_reg_cache(codec, WM8753_RINVOL); | ||
1690 | wm8753_write(codec, WM8753_RINVOL, reg | 0x0100); | ||
1691 | |||
1692 | wm8753_codec = codec; | ||
1693 | |||
1694 | for (i = 0; i < ARRAY_SIZE(wm8753_dai); i++) | ||
1695 | wm8753_dai[i].dev = codec->dev; | ||
1696 | |||
1697 | ret = snd_soc_register_codec(codec); | ||
1698 | if (ret != 0) { | ||
1699 | dev_err(codec->dev, "Failed to register codec: %d\n", ret); | ||
1700 | goto err; | ||
1701 | } | ||
1702 | |||
1703 | ret = snd_soc_register_dais(&wm8753_dai[0], ARRAY_SIZE(wm8753_dai)); | ||
1704 | if (ret != 0) { | ||
1705 | dev_err(codec->dev, "Failed to register DAIs: %d\n", ret); | ||
1706 | goto err_codec; | ||
1707 | } | ||
1708 | |||
1709 | return 0; | ||
1710 | |||
1711 | err_codec: | ||
1712 | run_delayed_work(&codec->delayed_work); | ||
1713 | snd_soc_unregister_codec(codec); | ||
1714 | err: | ||
1715 | kfree(wm8753); | ||
1716 | return ret; | ||
1717 | } | ||
1718 | |||
1719 | static void wm8753_unregister(struct wm8753_priv *wm8753) | ||
1720 | { | ||
1721 | wm8753_set_bias_level(&wm8753->codec, SND_SOC_BIAS_OFF); | ||
1722 | run_delayed_work(&wm8753->codec.delayed_work); | ||
1723 | snd_soc_unregister_dais(&wm8753_dai[0], ARRAY_SIZE(wm8753_dai)); | ||
1724 | snd_soc_unregister_codec(&wm8753->codec); | ||
1725 | kfree(wm8753); | ||
1726 | wm8753_codec = NULL; | ||
1727 | } | ||
1728 | |||
1781 | #if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) | 1729 | #if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) |
1782 | 1730 | ||
1783 | static int wm8753_i2c_probe(struct i2c_client *i2c, | 1731 | static int wm8753_i2c_probe(struct i2c_client *i2c, |
1784 | const struct i2c_device_id *id) | 1732 | const struct i2c_device_id *id) |
1785 | { | 1733 | { |
1786 | struct snd_soc_device *socdev = wm8753_socdev; | 1734 | struct snd_soc_codec *codec; |
1787 | struct snd_soc_codec *codec = socdev->card->codec; | 1735 | struct wm8753_priv *wm8753; |
1788 | int ret; | ||
1789 | 1736 | ||
1790 | i2c_set_clientdata(i2c, codec); | 1737 | wm8753 = kzalloc(sizeof(struct wm8753_priv), GFP_KERNEL); |
1791 | codec->control_data = i2c; | 1738 | if (wm8753 == NULL) |
1739 | return -ENOMEM; | ||
1792 | 1740 | ||
1793 | ret = wm8753_init(socdev); | 1741 | codec = &wm8753->codec; |
1794 | if (ret < 0) | 1742 | codec->hw_write = (hw_write_t)i2c_master_send; |
1795 | pr_err("failed to initialise WM8753\n"); | 1743 | codec->control_data = i2c; |
1744 | i2c_set_clientdata(i2c, wm8753); | ||
1796 | 1745 | ||
1797 | return ret; | 1746 | codec->dev = &i2c->dev; |
1747 | |||
1748 | return wm8753_register(wm8753); | ||
1798 | } | 1749 | } |
1799 | 1750 | ||
1800 | static int wm8753_i2c_remove(struct i2c_client *client) | 1751 | static int wm8753_i2c_remove(struct i2c_client *client) |
1801 | { | 1752 | { |
1802 | struct snd_soc_codec *codec = i2c_get_clientdata(client); | 1753 | struct wm8753_priv *wm8753 = i2c_get_clientdata(client); |
1803 | kfree(codec->reg_cache); | 1754 | wm8753_unregister(wm8753); |
1804 | return 0; | 1755 | return 0; |
1805 | } | 1756 | } |
1806 | 1757 | ||
1807 | static const struct i2c_device_id wm8753_i2c_id[] = { | 1758 | static const struct i2c_device_id wm8753_i2c_id[] = { |
@@ -1812,7 +1763,7 @@ MODULE_DEVICE_TABLE(i2c, wm8753_i2c_id); | |||
1812 | 1763 | ||
1813 | static struct i2c_driver wm8753_i2c_driver = { | 1764 | static struct i2c_driver wm8753_i2c_driver = { |
1814 | .driver = { | 1765 | .driver = { |
1815 | .name = "WM8753 I2C Codec", | 1766 | .name = "wm8753", |
1816 | .owner = THIS_MODULE, | 1767 | .owner = THIS_MODULE, |
1817 | }, | 1768 | }, |
1818 | .probe = wm8753_i2c_probe, | 1769 | .probe = wm8753_i2c_probe, |
@@ -1848,21 +1799,27 @@ static int wm8753_spi_write(struct spi_device *spi, const char *data, int len) | |||
1848 | 1799 | ||
1849 | static int __devinit wm8753_spi_probe(struct spi_device *spi) | 1800 | static int __devinit wm8753_spi_probe(struct spi_device *spi) |
1850 | { | 1801 | { |
1851 | struct snd_soc_device *socdev = wm8753_socdev; | 1802 | struct snd_soc_codec *codec; |
1852 | struct snd_soc_codec *codec = socdev->card->codec; | 1803 | struct wm8753_priv *wm8753; |
1853 | int ret; | 1804 | |
1805 | wm8753 = kzalloc(sizeof(struct wm8753_priv), GFP_KERNEL); | ||
1806 | if (wm8753 == NULL) | ||
1807 | return -ENOMEM; | ||
1854 | 1808 | ||
1809 | codec = &wm8753->codec; | ||
1855 | codec->control_data = spi; | 1810 | codec->control_data = spi; |
1811 | codec->hw_write = (hw_write_t)wm8753_spi_write; | ||
1812 | codec->dev = &spi->dev; | ||
1856 | 1813 | ||
1857 | ret = wm8753_init(socdev); | 1814 | spi->dev.driver_data = wm8753; |
1858 | if (ret < 0) | ||
1859 | dev_err(&spi->dev, "failed to initialise WM8753\n"); | ||
1860 | 1815 | ||
1861 | return ret; | 1816 | return wm8753_register(wm8753); |
1862 | } | 1817 | } |
1863 | 1818 | ||
1864 | static int __devexit wm8753_spi_remove(struct spi_device *spi) | 1819 | static int __devexit wm8753_spi_remove(struct spi_device *spi) |
1865 | { | 1820 | { |
1821 | struct wm8753_priv *wm8753 = spi->dev.driver_data; | ||
1822 | wm8753_unregister(wm8753); | ||
1866 | return 0; | 1823 | return 0; |
1867 | } | 1824 | } |
1868 | 1825 | ||
@@ -1879,13 +1836,29 @@ static struct spi_driver wm8753_spi_driver = { | |||
1879 | 1836 | ||
1880 | static int __init wm8753_modinit(void) | 1837 | static int __init wm8753_modinit(void) |
1881 | { | 1838 | { |
1882 | return snd_soc_register_dais(wm8753_dai, ARRAY_SIZE(wm8753_dai)); | 1839 | int ret; |
1840 | #if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) | ||
1841 | ret = i2c_add_driver(&wm8753_i2c_driver); | ||
1842 | if (ret != 0) | ||
1843 | pr_err("Failed to register WM8753 I2C driver: %d\n", ret); | ||
1844 | #endif | ||
1845 | #if defined(CONFIG_SPI_MASTER) | ||
1846 | ret = spi_register_driver(&wm8753_spi_driver); | ||
1847 | if (ret != 0) | ||
1848 | pr_err("Failed to register WM8753 SPI driver: %d\n", ret); | ||
1849 | #endif | ||
1850 | return 0; | ||
1883 | } | 1851 | } |
1884 | module_init(wm8753_modinit); | 1852 | module_init(wm8753_modinit); |
1885 | 1853 | ||
1886 | static void __exit wm8753_exit(void) | 1854 | static void __exit wm8753_exit(void) |
1887 | { | 1855 | { |
1888 | snd_soc_unregister_dais(wm8753_dai, ARRAY_SIZE(wm8753_dai)); | 1856 | #if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) |
1857 | i2c_del_driver(&wm8753_i2c_driver); | ||
1858 | #endif | ||
1859 | #if defined(CONFIG_SPI_MASTER) | ||
1860 | spi_unregister_driver(&wm8753_spi_driver); | ||
1861 | #endif | ||
1889 | } | 1862 | } |
1890 | module_exit(wm8753_exit); | 1863 | module_exit(wm8753_exit); |
1891 | 1864 | ||