aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMark Brown <broonie@opensource.wolfsonmicro.com>2010-08-12 10:02:11 -0400
committerMark Brown <broonie@opensource.wolfsonmicro.com>2010-08-12 10:02:11 -0400
commit54d8d0aeb96e677c129918b391b9e74d48e65294 (patch)
treeeba0bd3615021f52a19834907862f6323acbbb68
parentcf7af01aa77ec1b17687f5328ce0a598709efd59 (diff)
ASoC: Update WM8962 to build with multi-component
No notable changes, currently build tested only. Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
-rw-r--r--sound/soc/codecs/wm8962.c168
-rw-r--r--sound/soc/codecs/wm8962.h3
2 files changed, 47 insertions, 124 deletions
diff --git a/sound/soc/codecs/wm8962.c b/sound/soc/codecs/wm8962.c
index ea8940e80263..58ba2d3ca533 100644
--- a/sound/soc/codecs/wm8962.c
+++ b/sound/soc/codecs/wm8962.c
@@ -34,9 +34,6 @@
34 34
35#include "wm8962.h" 35#include "wm8962.h"
36 36
37static struct snd_soc_codec *wm8962_codec;
38struct snd_soc_codec_device soc_codec_dev_wm8962;
39
40#define WM8962_NUM_SUPPLIES 8 37#define WM8962_NUM_SUPPLIES 8
41static const char *wm8962_supply_names[WM8962_NUM_SUPPLIES] = { 38static const char *wm8962_supply_names[WM8962_NUM_SUPPLIES] = {
42 "DCVDD", 39 "DCVDD",
@@ -51,7 +48,8 @@ static const char *wm8962_supply_names[WM8962_NUM_SUPPLIES] = {
51 48
52/* codec private data */ 49/* codec private data */
53struct wm8962_priv { 50struct wm8962_priv {
54 struct snd_soc_codec codec; 51 struct snd_soc_codec *codec;
52
55 u16 reg_cache[WM8962_MAX_REGISTER + 1]; 53 u16 reg_cache[WM8962_MAX_REGISTER + 1];
56 54
57 int sysclk; 55 int sysclk;
@@ -85,7 +83,7 @@ static int wm8962_regulator_event_##n(struct notifier_block *nb, \
85 struct wm8962_priv *wm8962 = container_of(nb, struct wm8962_priv, \ 83 struct wm8962_priv *wm8962 = container_of(nb, struct wm8962_priv, \
86 disable_nb[n]); \ 84 disable_nb[n]); \
87 if (event & REGULATOR_EVENT_DISABLE) { \ 85 if (event & REGULATOR_EVENT_DISABLE) { \
88 wm8962->codec.cache_sync = 1; \ 86 wm8962->codec->cache_sync = 1; \
89 } \ 87 } \
90 return 0; \ 88 return 0; \
91} 89}
@@ -107,7 +105,7 @@ static int wm8962_volatile_register(unsigned int reg)
107 return 0; 105 return 0;
108} 106}
109 107
110static int wm8962_readable(unsigned int reg) 108static int wm8962_readable_register(unsigned int reg)
111{ 109{
112 if (wm8962_reg_access[reg].read) 110 if (wm8962_reg_access[reg].read)
113 return 1; 111 return 1;
@@ -150,7 +148,8 @@ static int wm8962_put_hp_sw(struct snd_kcontrol *kcontrol,
150 struct snd_ctl_elem_value *ucontrol) 148 struct snd_ctl_elem_value *ucontrol)
151{ 149{
152 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); 150 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
153 u16 *reg_cache = codec->reg_cache; 151 struct wm8962_priv *wm8962 = snd_soc_codec_get_drvdata(codec);
152 u16 *reg_cache = wm8962->reg_cache;
154 int ret; 153 int ret;
155 154
156 /* Apply the update (if any) */ 155 /* Apply the update (if any) */
@@ -178,7 +177,8 @@ static int wm8962_put_spk_sw(struct snd_kcontrol *kcontrol,
178 struct snd_ctl_elem_value *ucontrol) 177 struct snd_ctl_elem_value *ucontrol)
179{ 178{
180 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); 179 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
181 u16 *reg_cache = codec->reg_cache; 180 struct wm8962_priv *wm8962 = snd_soc_codec_get_drvdata(codec);
181 u16 *reg_cache = wm8962->reg_cache;
182 int ret; 182 int ret;
183 183
184 /* Apply the update (if any) */ 184 /* Apply the update (if any) */
@@ -486,7 +486,8 @@ static int out_pga_event(struct snd_soc_dapm_widget *w,
486 struct snd_kcontrol *kcontrol, int event) 486 struct snd_kcontrol *kcontrol, int event)
487{ 487{
488 struct snd_soc_codec *codec = w->codec; 488 struct snd_soc_codec *codec = w->codec;
489 u16 *reg_cache = codec->reg_cache; 489 struct wm8962_priv *wm8962 = snd_soc_codec_get_drvdata(codec);
490 u16 *reg_cache = wm8962->reg_cache;
490 int reg; 491 int reg;
491 492
492 switch (w->shift) { 493 switch (w->shift) {
@@ -1071,8 +1072,7 @@ static int wm8962_hw_params(struct snd_pcm_substream *substream,
1071 struct snd_soc_dai *dai) 1072 struct snd_soc_dai *dai)
1072{ 1073{
1073 struct snd_soc_pcm_runtime *rtd = substream->private_data; 1074 struct snd_soc_pcm_runtime *rtd = substream->private_data;
1074 struct snd_soc_device *socdev = rtd->socdev; 1075 struct snd_soc_codec *codec = rtd->codec;
1075 struct snd_soc_codec *codec = socdev->card->codec;
1076 struct wm8962_priv *wm8962 = snd_soc_codec_get_drvdata(codec); 1076 struct wm8962_priv *wm8962 = snd_soc_codec_get_drvdata(codec);
1077 int rate = params_rate(params); 1077 int rate = params_rate(params);
1078 int i; 1078 int i;
@@ -1441,8 +1441,8 @@ static struct snd_soc_dai_ops wm8962_dai_ops = {
1441 .digital_mute = wm8962_mute, 1441 .digital_mute = wm8962_mute,
1442}; 1442};
1443 1443
1444struct snd_soc_dai wm8962_dai = { 1444static struct snd_soc_dai_driver wm8962_dai = {
1445 .name = "WM8962", 1445 .name = "wm8962",
1446 .playback = { 1446 .playback = {
1447 .stream_name = "Playback", 1447 .stream_name = "Playback",
1448 .channels_min = 2, 1448 .channels_min = 2,
@@ -1460,52 +1460,10 @@ struct snd_soc_dai wm8962_dai = {
1460 .ops = &wm8962_dai_ops, 1460 .ops = &wm8962_dai_ops,
1461 .symmetric_rates = 1, 1461 .symmetric_rates = 1,
1462}; 1462};
1463EXPORT_SYMBOL_GPL(wm8962_dai);
1464
1465static int wm8962_probe(struct platform_device *pdev)
1466{
1467 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
1468 struct snd_soc_codec *codec;
1469 int ret = 0;
1470
1471 if (wm8962_codec == NULL) {
1472 dev_err(&pdev->dev, "Codec device not registered\n");
1473 return -ENODEV;
1474 }
1475
1476 socdev->card->codec = wm8962_codec;
1477 codec = wm8962_codec;
1478
1479 /* register pcms */
1480 ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
1481 if (ret < 0) {
1482 dev_err(codec->dev, "failed to create pcms: %d\n", ret);
1483 goto pcm_err;
1484 }
1485
1486 wm8962_add_widgets(codec);
1487
1488 return ret;
1489
1490pcm_err:
1491 return ret;
1492}
1493
1494static int wm8962_remove(struct platform_device *pdev)
1495{
1496 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
1497
1498 snd_soc_free_pcms(socdev);
1499 snd_soc_dapm_free(socdev);
1500
1501 return 0;
1502}
1503 1463
1504#ifdef CONFIG_PM 1464#ifdef CONFIG_PM
1505static int wm8962_resume(struct platform_device *pdev) 1465static int wm8962_resume(struct snd_soc_codec *codec)
1506{ 1466{
1507 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
1508 struct snd_soc_codec *codec = socdev->card->codec;
1509 struct wm8962_priv *wm8962 = snd_soc_codec_get_drvdata(codec); 1467 struct wm8962_priv *wm8962 = snd_soc_codec_get_drvdata(codec);
1510 u16 *reg_cache = codec->reg_cache; 1468 u16 *reg_cache = codec->reg_cache;
1511 int i; 1469 int i;
@@ -1529,13 +1487,6 @@ static int wm8962_resume(struct platform_device *pdev)
1529#define wm8962_resume NULL 1487#define wm8962_resume NULL
1530#endif 1488#endif
1531 1489
1532struct snd_soc_codec_device soc_codec_dev_wm8962 = {
1533 .probe = wm8962_probe,
1534 .remove = wm8962_remove,
1535 .resume = wm8962_resume,
1536};
1537EXPORT_SYMBOL_GPL(soc_codec_dev_wm8962);
1538
1539#if defined(CONFIG_INPUT) || defined(CONFIG_INPUT_MODULE) 1490#if defined(CONFIG_INPUT) || defined(CONFIG_INPUT_MODULE)
1540static int beep_rates[] = { 1491static int beep_rates[] = {
1541 500, 1000, 2000, 4000, 1492 500, 1000, 2000, 4000,
@@ -1545,7 +1496,7 @@ static void wm8962_beep_work(struct work_struct *work)
1545{ 1496{
1546 struct wm8962_priv *wm8962 = 1497 struct wm8962_priv *wm8962 =
1547 container_of(work, struct wm8962_priv, beep_work); 1498 container_of(work, struct wm8962_priv, beep_work);
1548 struct snd_soc_codec *codec = &wm8962->codec; 1499 struct snd_soc_codec *codec = wm8962->codec;
1549 int i; 1500 int i;
1550 int reg = 0; 1501 int reg = 0;
1551 int best = 0; 1502 int best = 0;
@@ -1676,40 +1627,19 @@ static void wm8962_free_beep(struct snd_soc_codec *codec)
1676} 1627}
1677#endif 1628#endif
1678 1629
1679static int wm8962_register(struct wm8962_priv *wm8962, 1630static int wm8962_probe(struct snd_soc_codec *codec)
1680 enum snd_soc_control_type control)
1681{ 1631{
1682 int ret; 1632 int ret;
1683 struct snd_soc_codec *codec = &wm8962->codec; 1633 struct wm8962_priv *wm8962 = snd_soc_codec_get_drvdata(codec);
1684 struct wm8962_pdata *pdata = dev_get_platdata(codec->dev); 1634 struct wm8962_pdata *pdata = dev_get_platdata(codec->dev);
1685 int i; 1635 int i;
1686 1636
1687 if (wm8962_codec) { 1637 wm8962->codec = codec;
1688 dev_err(codec->dev, "Another WM8962 is registered\n");
1689 return -EINVAL;
1690 }
1691 1638
1692 mutex_init(&codec->mutex);
1693 INIT_LIST_HEAD(&codec->dapm_widgets);
1694 INIT_LIST_HEAD(&codec->dapm_paths);
1695
1696 snd_soc_codec_set_drvdata(codec, wm8962);
1697 codec->name = "WM8962";
1698 codec->owner = THIS_MODULE;
1699 codec->bias_level = SND_SOC_BIAS_OFF;
1700 codec->set_bias_level = wm8962_set_bias_level;
1701 codec->dai = &wm8962_dai;
1702 codec->num_dai = 1;
1703 codec->reg_cache_size = WM8962_MAX_REGISTER;
1704 codec->reg_cache = &wm8962->reg_cache;
1705 codec->volatile_register = wm8962_volatile_register;
1706 codec->cache_sync = 1; 1639 codec->cache_sync = 1;
1707 codec->idle_bias_off = 1; 1640 codec->idle_bias_off = 1;
1708 codec->readable_register = wm8962_readable;
1709 1641
1710 memcpy(codec->reg_cache, wm8962_reg, sizeof(wm8962_reg)); 1642 ret = snd_soc_codec_set_cache_io(codec, 16, 16, SND_SOC_I2C);
1711
1712 ret = snd_soc_codec_set_cache_io(codec, 16, 16, control);
1713 if (ret != 0) { 1643 if (ret != 0) {
1714 dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret); 1644 dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
1715 goto err; 1645 goto err;
@@ -1814,22 +1744,9 @@ static int wm8962_register(struct wm8962_priv *wm8962,
1814 wm8962->reg_cache[WM8962_HPOUTL_VOLUME] |= WM8962_HPOUT_VU; 1744 wm8962->reg_cache[WM8962_HPOUTL_VOLUME] |= WM8962_HPOUT_VU;
1815 wm8962->reg_cache[WM8962_HPOUTR_VOLUME] |= WM8962_HPOUT_VU; 1745 wm8962->reg_cache[WM8962_HPOUTR_VOLUME] |= WM8962_HPOUT_VU;
1816 1746
1817 wm8962_dai.dev = codec->dev; 1747 snd_soc_add_controls(codec, wm8962_snd_controls,
1818 1748 ARRAY_SIZE(wm8962_snd_controls));
1819 wm8962_codec = codec; 1749 wm8962_add_widgets(codec);
1820
1821 ret = snd_soc_register_codec(codec);
1822 if (ret != 0) {
1823 dev_err(codec->dev, "Failed to register codec: %d\n", ret);
1824 return ret;
1825 }
1826
1827 ret = snd_soc_register_dai(&wm8962_dai);
1828 if (ret != 0) {
1829 dev_err(codec->dev, "Failed to register DAI: %d\n", ret);
1830 snd_soc_unregister_codec(codec);
1831 return ret;
1832 }
1833 1750
1834 wm8962_init_beep(codec); 1751 wm8962_init_beep(codec);
1835 1752
@@ -1844,48 +1761,57 @@ err:
1844 return ret; 1761 return ret;
1845} 1762}
1846 1763
1847static void wm8962_unregister(struct wm8962_priv *wm8962) 1764static int wm8962_remove(struct snd_soc_codec *codec)
1848{ 1765{
1766 struct wm8962_priv *wm8962 = snd_soc_codec_get_drvdata(codec);
1849 int i; 1767 int i;
1850 1768
1851 wm8962_free_beep(&wm8962->codec); 1769 wm8962_free_beep(codec);
1852 wm8962_set_bias_level(&wm8962->codec, SND_SOC_BIAS_OFF);
1853 for (i = 0; i < ARRAY_SIZE(wm8962->supplies); i++) 1770 for (i = 0; i < ARRAY_SIZE(wm8962->supplies); i++)
1854 regulator_unregister_notifier(wm8962->supplies[i].consumer, 1771 regulator_unregister_notifier(wm8962->supplies[i].consumer,
1855 &wm8962->disable_nb[i]); 1772 &wm8962->disable_nb[i]);
1856 regulator_bulk_free(ARRAY_SIZE(wm8962->supplies), wm8962->supplies); 1773 regulator_bulk_free(ARRAY_SIZE(wm8962->supplies), wm8962->supplies);
1857 snd_soc_unregister_dai(&wm8962_dai); 1774
1858 snd_soc_unregister_codec(&wm8962->codec); 1775 return 0;
1859 kfree(wm8962);
1860 wm8962_codec = NULL;
1861} 1776}
1862 1777
1778static struct snd_soc_codec_driver soc_codec_dev_wm8962 = {
1779 .probe = wm8962_probe,
1780 .remove = wm8962_remove,
1781 .resume = wm8962_resume,
1782 .set_bias_level = wm8962_set_bias_level,
1783 .reg_cache_size = WM8962_MAX_REGISTER,
1784 .reg_word_size = sizeof(u16),
1785 .reg_cache_default = wm8962_reg,
1786 .volatile_register = wm8962_volatile_register,
1787 .readable_register = wm8962_readable_register,
1788};
1789
1863#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) 1790#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
1864static __devinit int wm8962_i2c_probe(struct i2c_client *i2c, 1791static __devinit int wm8962_i2c_probe(struct i2c_client *i2c,
1865 const struct i2c_device_id *id) 1792 const struct i2c_device_id *id)
1866{ 1793{
1867 struct wm8962_priv *wm8962; 1794 struct wm8962_priv *wm8962;
1868 struct snd_soc_codec *codec; 1795 int ret;
1869 1796
1870 wm8962 = kzalloc(sizeof(struct wm8962_priv), GFP_KERNEL); 1797 wm8962 = kzalloc(sizeof(struct wm8962_priv), GFP_KERNEL);
1871 if (wm8962 == NULL) 1798 if (wm8962 == NULL)
1872 return -ENOMEM; 1799 return -ENOMEM;
1873 1800
1874 codec = &wm8962->codec;
1875 codec->hw_write = (hw_write_t)i2c_master_send;
1876
1877 i2c_set_clientdata(i2c, wm8962); 1801 i2c_set_clientdata(i2c, wm8962);
1878 codec->control_data = i2c;
1879 1802
1880 codec->dev = &i2c->dev; 1803 ret = snd_soc_register_codec(&i2c->dev,
1804 &soc_codec_dev_wm8962, &wm8962_dai, 1);
1805 if (ret < 0)
1806 kfree(wm8962);
1881 1807
1882 return wm8962_register(wm8962, SND_SOC_I2C); 1808 return ret;
1883} 1809}
1884 1810
1885static __devexit int wm8962_i2c_remove(struct i2c_client *client) 1811static __devexit int wm8962_i2c_remove(struct i2c_client *client)
1886{ 1812{
1887 struct wm8962_priv *wm8962 = i2c_get_clientdata(client); 1813 snd_soc_unregister_codec(&client->dev);
1888 wm8962_unregister(wm8962); 1814 kfree(i2c_get_clientdata(client));
1889 return 0; 1815 return 0;
1890} 1816}
1891 1817
diff --git a/sound/soc/codecs/wm8962.h b/sound/soc/codecs/wm8962.h
index bc0b1876174c..6145399acb16 100644
--- a/sound/soc/codecs/wm8962.h
+++ b/sound/soc/codecs/wm8962.h
@@ -15,9 +15,6 @@
15 15
16#include <asm/types.h> 16#include <asm/types.h>
17 17
18extern struct snd_soc_dai wm8962_dai;
19extern struct snd_soc_codec_device soc_codec_dev_wm8962;
20
21#define WM8962_SYSCLK_MCLK 1 18#define WM8962_SYSCLK_MCLK 1
22#define WM8962_SYSCLK_FLL 2 19#define WM8962_SYSCLK_FLL 2
23#define WM8962_SYSCLK_PLL3 3 20#define WM8962_SYSCLK_PLL3 3