diff options
author | Mark Brown <broonie@opensource.wolfsonmicro.com> | 2010-08-12 10:02:11 -0400 |
---|---|---|
committer | Mark Brown <broonie@opensource.wolfsonmicro.com> | 2010-08-12 10:02:11 -0400 |
commit | 54d8d0aeb96e677c129918b391b9e74d48e65294 (patch) | |
tree | eba0bd3615021f52a19834907862f6323acbbb68 | |
parent | cf7af01aa77ec1b17687f5328ce0a598709efd59 (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.c | 168 | ||||
-rw-r--r-- | sound/soc/codecs/wm8962.h | 3 |
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 | ||
37 | static struct snd_soc_codec *wm8962_codec; | ||
38 | struct snd_soc_codec_device soc_codec_dev_wm8962; | ||
39 | |||
40 | #define WM8962_NUM_SUPPLIES 8 | 37 | #define WM8962_NUM_SUPPLIES 8 |
41 | static const char *wm8962_supply_names[WM8962_NUM_SUPPLIES] = { | 38 | static 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 */ |
53 | struct wm8962_priv { | 50 | struct 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 | ||
110 | static int wm8962_readable(unsigned int reg) | 108 | static 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 | ||
1444 | struct snd_soc_dai wm8962_dai = { | 1444 | static 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 | }; |
1463 | EXPORT_SYMBOL_GPL(wm8962_dai); | ||
1464 | |||
1465 | static 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 | |||
1490 | pcm_err: | ||
1491 | return ret; | ||
1492 | } | ||
1493 | |||
1494 | static 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 |
1505 | static int wm8962_resume(struct platform_device *pdev) | 1465 | static 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 | ||
1532 | struct snd_soc_codec_device soc_codec_dev_wm8962 = { | ||
1533 | .probe = wm8962_probe, | ||
1534 | .remove = wm8962_remove, | ||
1535 | .resume = wm8962_resume, | ||
1536 | }; | ||
1537 | EXPORT_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) |
1540 | static int beep_rates[] = { | 1491 | static 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 | ||
1679 | static int wm8962_register(struct wm8962_priv *wm8962, | 1630 | static 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 | ||
1847 | static void wm8962_unregister(struct wm8962_priv *wm8962) | 1764 | static 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 | ||
1778 | static 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) |
1864 | static __devinit int wm8962_i2c_probe(struct i2c_client *i2c, | 1791 | static __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 | ||
1885 | static __devexit int wm8962_i2c_remove(struct i2c_client *client) | 1811 | static __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 | ||
18 | extern struct snd_soc_dai wm8962_dai; | ||
19 | extern 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 |