aboutsummaryrefslogtreecommitdiffstats
path: root/sound/soc/codecs/wm8904.c
diff options
context:
space:
mode:
Diffstat (limited to 'sound/soc/codecs/wm8904.c')
-rw-r--r--sound/soc/codecs/wm8904.c307
1 files changed, 116 insertions, 191 deletions
diff --git a/sound/soc/codecs/wm8904.c b/sound/soc/codecs/wm8904.c
index f7dcabf6283c..9b3bba4df5b3 100644
--- a/sound/soc/codecs/wm8904.c
+++ b/sound/soc/codecs/wm8904.c
@@ -24,16 +24,12 @@
24#include <sound/pcm.h> 24#include <sound/pcm.h>
25#include <sound/pcm_params.h> 25#include <sound/pcm_params.h>
26#include <sound/soc.h> 26#include <sound/soc.h>
27#include <sound/soc-dapm.h>
28#include <sound/initval.h> 27#include <sound/initval.h>
29#include <sound/tlv.h> 28#include <sound/tlv.h>
30#include <sound/wm8904.h> 29#include <sound/wm8904.h>
31 30
32#include "wm8904.h" 31#include "wm8904.h"
33 32
34static struct snd_soc_codec *wm8904_codec;
35struct snd_soc_codec_device soc_codec_dev_wm8904;
36
37enum wm8904_type { 33enum wm8904_type {
38 WM8904, 34 WM8904,
39 WM8912, 35 WM8912,
@@ -52,10 +48,9 @@ static const char *wm8904_supply_names[WM8904_NUM_SUPPLIES] = {
52 48
53/* codec private data */ 49/* codec private data */
54struct wm8904_priv { 50struct wm8904_priv {
55 struct snd_soc_codec codec;
56 u16 reg_cache[WM8904_MAX_REGISTER + 1];
57 51
58 enum wm8904_type devtype; 52 enum wm8904_type devtype;
53 void *control_data;
59 54
60 struct regulator_bulk_data supplies[WM8904_NUM_SUPPLIES]; 55 struct regulator_bulk_data supplies[WM8904_NUM_SUPPLIES];
61 56
@@ -601,7 +596,7 @@ static struct {
601 { 0x003F, 0x003F, 0 }, /* R248 - FLL NCO Test 1 */ 596 { 0x003F, 0x003F, 0 }, /* R248 - FLL NCO Test 1 */
602}; 597};
603 598
604static int wm8904_volatile_register(unsigned int reg) 599static int wm8904_volatile_register(struct snd_soc_codec *codec, unsigned int reg)
605{ 600{
606 return wm8904_access[reg].vol; 601 return wm8904_access[reg].vol;
607} 602}
@@ -689,7 +684,7 @@ static int wm8904_put_drc_enum(struct snd_kcontrol *kcontrol,
689 struct snd_ctl_elem_value *ucontrol) 684 struct snd_ctl_elem_value *ucontrol)
690{ 685{
691 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); 686 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
692 struct wm8904_priv *wm8904 = snd_soc_codec_get_drvdata(codec); 687 struct wm8904_priv *wm8904 = snd_soc_codec_get_drvdata(codec);
693 struct wm8904_pdata *pdata = wm8904->pdata; 688 struct wm8904_pdata *pdata = wm8904->pdata;
694 int value = ucontrol->value.integer.value[0]; 689 int value = ucontrol->value.integer.value[0];
695 690
@@ -760,7 +755,7 @@ static int wm8904_put_retune_mobile_enum(struct snd_kcontrol *kcontrol,
760 struct snd_ctl_elem_value *ucontrol) 755 struct snd_ctl_elem_value *ucontrol)
761{ 756{
762 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); 757 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
763 struct wm8904_priv *wm8904 = snd_soc_codec_get_drvdata(codec); 758 struct wm8904_priv *wm8904 = snd_soc_codec_get_drvdata(codec);
764 struct wm8904_pdata *pdata = wm8904->pdata; 759 struct wm8904_pdata *pdata = wm8904->pdata;
765 int value = ucontrol->value.integer.value[0]; 760 int value = ucontrol->value.integer.value[0];
766 761
@@ -820,7 +815,8 @@ static int wm8904_get_deemph(struct snd_kcontrol *kcontrol,
820 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); 815 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
821 struct wm8904_priv *wm8904 = snd_soc_codec_get_drvdata(codec); 816 struct wm8904_priv *wm8904 = snd_soc_codec_get_drvdata(codec);
822 817
823 return wm8904->deemph; 818 ucontrol->value.enumerated.item[0] = wm8904->deemph;
819 return 0;
824} 820}
825 821
826static int wm8904_put_deemph(struct snd_kcontrol *kcontrol, 822static int wm8904_put_deemph(struct snd_kcontrol *kcontrol,
@@ -1430,10 +1426,11 @@ static const struct snd_soc_dapm_route wm8912_intercon[] = {
1430static int wm8904_add_widgets(struct snd_soc_codec *codec) 1426static int wm8904_add_widgets(struct snd_soc_codec *codec)
1431{ 1427{
1432 struct wm8904_priv *wm8904 = snd_soc_codec_get_drvdata(codec); 1428 struct wm8904_priv *wm8904 = snd_soc_codec_get_drvdata(codec);
1429 struct snd_soc_dapm_context *dapm = &codec->dapm;
1433 1430
1434 snd_soc_dapm_new_controls(codec, wm8904_core_dapm_widgets, 1431 snd_soc_dapm_new_controls(dapm, wm8904_core_dapm_widgets,
1435 ARRAY_SIZE(wm8904_core_dapm_widgets)); 1432 ARRAY_SIZE(wm8904_core_dapm_widgets));
1436 snd_soc_dapm_add_routes(codec, core_intercon, 1433 snd_soc_dapm_add_routes(dapm, core_intercon,
1437 ARRAY_SIZE(core_intercon)); 1434 ARRAY_SIZE(core_intercon));
1438 1435
1439 switch (wm8904->devtype) { 1436 switch (wm8904->devtype) {
@@ -1445,20 +1442,20 @@ static int wm8904_add_widgets(struct snd_soc_codec *codec)
1445 snd_soc_add_controls(codec, wm8904_snd_controls, 1442 snd_soc_add_controls(codec, wm8904_snd_controls,
1446 ARRAY_SIZE(wm8904_snd_controls)); 1443 ARRAY_SIZE(wm8904_snd_controls));
1447 1444
1448 snd_soc_dapm_new_controls(codec, wm8904_adc_dapm_widgets, 1445 snd_soc_dapm_new_controls(dapm, wm8904_adc_dapm_widgets,
1449 ARRAY_SIZE(wm8904_adc_dapm_widgets)); 1446 ARRAY_SIZE(wm8904_adc_dapm_widgets));
1450 snd_soc_dapm_new_controls(codec, wm8904_dac_dapm_widgets, 1447 snd_soc_dapm_new_controls(dapm, wm8904_dac_dapm_widgets,
1451 ARRAY_SIZE(wm8904_dac_dapm_widgets)); 1448 ARRAY_SIZE(wm8904_dac_dapm_widgets));
1452 snd_soc_dapm_new_controls(codec, wm8904_dapm_widgets, 1449 snd_soc_dapm_new_controls(dapm, wm8904_dapm_widgets,
1453 ARRAY_SIZE(wm8904_dapm_widgets)); 1450 ARRAY_SIZE(wm8904_dapm_widgets));
1454 1451
1455 snd_soc_dapm_add_routes(codec, core_intercon, 1452 snd_soc_dapm_add_routes(dapm, core_intercon,
1456 ARRAY_SIZE(core_intercon)); 1453 ARRAY_SIZE(core_intercon));
1457 snd_soc_dapm_add_routes(codec, adc_intercon, 1454 snd_soc_dapm_add_routes(dapm, adc_intercon,
1458 ARRAY_SIZE(adc_intercon)); 1455 ARRAY_SIZE(adc_intercon));
1459 snd_soc_dapm_add_routes(codec, dac_intercon, 1456 snd_soc_dapm_add_routes(dapm, dac_intercon,
1460 ARRAY_SIZE(dac_intercon)); 1457 ARRAY_SIZE(dac_intercon));
1461 snd_soc_dapm_add_routes(codec, wm8904_intercon, 1458 snd_soc_dapm_add_routes(dapm, wm8904_intercon,
1462 ARRAY_SIZE(wm8904_intercon)); 1459 ARRAY_SIZE(wm8904_intercon));
1463 break; 1460 break;
1464 1461
@@ -1466,17 +1463,17 @@ static int wm8904_add_widgets(struct snd_soc_codec *codec)
1466 snd_soc_add_controls(codec, wm8904_dac_snd_controls, 1463 snd_soc_add_controls(codec, wm8904_dac_snd_controls,
1467 ARRAY_SIZE(wm8904_dac_snd_controls)); 1464 ARRAY_SIZE(wm8904_dac_snd_controls));
1468 1465
1469 snd_soc_dapm_new_controls(codec, wm8904_dac_dapm_widgets, 1466 snd_soc_dapm_new_controls(dapm, wm8904_dac_dapm_widgets,
1470 ARRAY_SIZE(wm8904_dac_dapm_widgets)); 1467 ARRAY_SIZE(wm8904_dac_dapm_widgets));
1471 1468
1472 snd_soc_dapm_add_routes(codec, dac_intercon, 1469 snd_soc_dapm_add_routes(dapm, dac_intercon,
1473 ARRAY_SIZE(dac_intercon)); 1470 ARRAY_SIZE(dac_intercon));
1474 snd_soc_dapm_add_routes(codec, wm8912_intercon, 1471 snd_soc_dapm_add_routes(dapm, wm8912_intercon,
1475 ARRAY_SIZE(wm8912_intercon)); 1472 ARRAY_SIZE(wm8912_intercon));
1476 break; 1473 break;
1477 } 1474 }
1478 1475
1479 snd_soc_dapm_new_widgets(codec); 1476 snd_soc_dapm_new_widgets(dapm);
1480 return 0; 1477 return 0;
1481} 1478}
1482 1479
@@ -1592,7 +1589,7 @@ static int wm8904_hw_params(struct snd_pcm_substream *substream,
1592 - wm8904->fs); 1589 - wm8904->fs);
1593 for (i = 1; i < ARRAY_SIZE(clk_sys_rates); i++) { 1590 for (i = 1; i < ARRAY_SIZE(clk_sys_rates); i++) {
1594 cur_val = abs((wm8904->sysclk_rate / 1591 cur_val = abs((wm8904->sysclk_rate /
1595 clk_sys_rates[i].ratio) - wm8904->fs);; 1592 clk_sys_rates[i].ratio) - wm8904->fs);
1596 if (cur_val < best_val) { 1593 if (cur_val < best_val) {
1597 best = i; 1594 best = i;
1598 best_val = cur_val; 1595 best_val = cur_val;
@@ -1898,7 +1895,7 @@ static int fll_factors(struct _fll_div *fll_div, unsigned int Fref,
1898 1895
1899 pr_debug("Fvco=%dHz\n", target); 1896 pr_debug("Fvco=%dHz\n", target);
1900 1897
1901 /* Find an appropraite FLL_FRATIO and factor it out of the target */ 1898 /* Find an appropriate FLL_FRATIO and factor it out of the target */
1902 for (i = 0; i < ARRAY_SIZE(fll_fratios); i++) { 1899 for (i = 0; i < ARRAY_SIZE(fll_fratios); i++) {
1903 if (fll_fratios[i].min <= Fref && Fref <= fll_fratios[i].max) { 1900 if (fll_fratios[i].min <= Fref && Fref <= fll_fratios[i].max) {
1904 fll_div->fll_fratio = fll_fratios[i].fll_fratio; 1901 fll_div->fll_fratio = fll_fratios[i].fll_fratio;
@@ -2095,7 +2092,7 @@ static int wm8904_digital_mute(struct snd_soc_dai *codec_dai, int mute)
2095 2092
2096static void wm8904_sync_cache(struct snd_soc_codec *codec) 2093static void wm8904_sync_cache(struct snd_soc_codec *codec)
2097{ 2094{
2098 struct wm8904_priv *wm8904 = snd_soc_codec_get_drvdata(codec); 2095 u16 *reg_cache = codec->reg_cache;
2099 int i; 2096 int i;
2100 2097
2101 if (!codec->cache_sync) 2098 if (!codec->cache_sync)
@@ -2106,14 +2103,14 @@ static void wm8904_sync_cache(struct snd_soc_codec *codec)
2106 /* Sync back cached values if they're different from the 2103 /* Sync back cached values if they're different from the
2107 * hardware default. 2104 * hardware default.
2108 */ 2105 */
2109 for (i = 1; i < ARRAY_SIZE(wm8904->reg_cache); i++) { 2106 for (i = 1; i < codec->driver->reg_cache_size; i++) {
2110 if (!wm8904_access[i].writable) 2107 if (!wm8904_access[i].writable)
2111 continue; 2108 continue;
2112 2109
2113 if (wm8904->reg_cache[i] == wm8904_reg[i]) 2110 if (reg_cache[i] == wm8904_reg[i])
2114 continue; 2111 continue;
2115 2112
2116 snd_soc_write(codec, i, wm8904->reg_cache[i]); 2113 snd_soc_write(codec, i, reg_cache[i]);
2117 } 2114 }
2118 2115
2119 codec->cache_sync = 0; 2116 codec->cache_sync = 0;
@@ -2141,7 +2138,7 @@ static int wm8904_set_bias_level(struct snd_soc_codec *codec,
2141 break; 2138 break;
2142 2139
2143 case SND_SOC_BIAS_STANDBY: 2140 case SND_SOC_BIAS_STANDBY:
2144 if (codec->bias_level == SND_SOC_BIAS_OFF) { 2141 if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) {
2145 ret = regulator_bulk_enable(ARRAY_SIZE(wm8904->supplies), 2142 ret = regulator_bulk_enable(ARRAY_SIZE(wm8904->supplies),
2146 wm8904->supplies); 2143 wm8904->supplies);
2147 if (ret != 0) { 2144 if (ret != 0) {
@@ -2200,7 +2197,7 @@ static int wm8904_set_bias_level(struct snd_soc_codec *codec,
2200 wm8904->supplies); 2197 wm8904->supplies);
2201 break; 2198 break;
2202 } 2199 }
2203 codec->bias_level = level; 2200 codec->dapm.bias_level = level;
2204 return 0; 2201 return 0;
2205} 2202}
2206 2203
@@ -2218,8 +2215,8 @@ static struct snd_soc_dai_ops wm8904_dai_ops = {
2218 .digital_mute = wm8904_digital_mute, 2215 .digital_mute = wm8904_digital_mute,
2219}; 2216};
2220 2217
2221struct snd_soc_dai wm8904_dai = { 2218static struct snd_soc_dai_driver wm8904_dai = {
2222 .name = "WM8904", 2219 .name = "wm8904-hifi",
2223 .playback = { 2220 .playback = {
2224 .stream_name = "Playback", 2221 .stream_name = "Playback",
2225 .channels_min = 2, 2222 .channels_min = 2,
@@ -2237,24 +2234,17 @@ struct snd_soc_dai wm8904_dai = {
2237 .ops = &wm8904_dai_ops, 2234 .ops = &wm8904_dai_ops,
2238 .symmetric_rates = 1, 2235 .symmetric_rates = 1,
2239}; 2236};
2240EXPORT_SYMBOL_GPL(wm8904_dai);
2241 2237
2242#ifdef CONFIG_PM 2238#ifdef CONFIG_PM
2243static int wm8904_suspend(struct platform_device *pdev, pm_message_t state) 2239static int wm8904_suspend(struct snd_soc_codec *codec, pm_message_t state)
2244{ 2240{
2245 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
2246 struct snd_soc_codec *codec = socdev->card->codec;
2247
2248 wm8904_set_bias_level(codec, SND_SOC_BIAS_OFF); 2241 wm8904_set_bias_level(codec, SND_SOC_BIAS_OFF);
2249 2242
2250 return 0; 2243 return 0;
2251} 2244}
2252 2245
2253static int wm8904_resume(struct platform_device *pdev) 2246static int wm8904_resume(struct snd_soc_codec *codec)
2254{ 2247{
2255 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
2256 struct snd_soc_codec *codec = socdev->card->codec;
2257
2258 wm8904_set_bias_level(codec, SND_SOC_BIAS_STANDBY); 2248 wm8904_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
2259 2249
2260 return 0; 2250 return 0;
@@ -2264,9 +2254,9 @@ static int wm8904_resume(struct platform_device *pdev)
2264#define wm8904_resume NULL 2254#define wm8904_resume NULL
2265#endif 2255#endif
2266 2256
2267static void wm8904_handle_retune_mobile_pdata(struct wm8904_priv *wm8904) 2257static void wm8904_handle_retune_mobile_pdata(struct snd_soc_codec *codec)
2268{ 2258{
2269 struct snd_soc_codec *codec = &wm8904->codec; 2259 struct wm8904_priv *wm8904 = snd_soc_codec_get_drvdata(codec);
2270 struct wm8904_pdata *pdata = wm8904->pdata; 2260 struct wm8904_pdata *pdata = wm8904->pdata;
2271 struct snd_kcontrol_new control = 2261 struct snd_kcontrol_new control =
2272 SOC_ENUM_EXT("EQ Mode", 2262 SOC_ENUM_EXT("EQ Mode",
@@ -2315,20 +2305,20 @@ static void wm8904_handle_retune_mobile_pdata(struct wm8904_priv *wm8904)
2315 wm8904->retune_mobile_enum.max = wm8904->num_retune_mobile_texts; 2305 wm8904->retune_mobile_enum.max = wm8904->num_retune_mobile_texts;
2316 wm8904->retune_mobile_enum.texts = wm8904->retune_mobile_texts; 2306 wm8904->retune_mobile_enum.texts = wm8904->retune_mobile_texts;
2317 2307
2318 ret = snd_soc_add_controls(&wm8904->codec, &control, 1); 2308 ret = snd_soc_add_controls(codec, &control, 1);
2319 if (ret != 0) 2309 if (ret != 0)
2320 dev_err(wm8904->codec.dev, 2310 dev_err(codec->dev,
2321 "Failed to add ReTune Mobile control: %d\n", ret); 2311 "Failed to add ReTune Mobile control: %d\n", ret);
2322} 2312}
2323 2313
2324static void wm8904_handle_pdata(struct wm8904_priv *wm8904) 2314static void wm8904_handle_pdata(struct snd_soc_codec *codec)
2325{ 2315{
2326 struct snd_soc_codec *codec = &wm8904->codec; 2316 struct wm8904_priv *wm8904 = snd_soc_codec_get_drvdata(codec);
2327 struct wm8904_pdata *pdata = wm8904->pdata; 2317 struct wm8904_pdata *pdata = wm8904->pdata;
2328 int ret, i; 2318 int ret, i;
2329 2319
2330 if (!pdata) { 2320 if (!pdata) {
2331 snd_soc_add_controls(&wm8904->codec, wm8904_eq_controls, 2321 snd_soc_add_controls(codec, wm8904_eq_controls,
2332 ARRAY_SIZE(wm8904_eq_controls)); 2322 ARRAY_SIZE(wm8904_eq_controls));
2333 return; 2323 return;
2334 } 2324 }
@@ -2344,7 +2334,7 @@ static void wm8904_handle_pdata(struct wm8904_priv *wm8904)
2344 wm8904->drc_texts = kmalloc(sizeof(char *) 2334 wm8904->drc_texts = kmalloc(sizeof(char *)
2345 * pdata->num_drc_cfgs, GFP_KERNEL); 2335 * pdata->num_drc_cfgs, GFP_KERNEL);
2346 if (!wm8904->drc_texts) { 2336 if (!wm8904->drc_texts) {
2347 dev_err(wm8904->codec.dev, 2337 dev_err(codec->dev,
2348 "Failed to allocate %d DRC config texts\n", 2338 "Failed to allocate %d DRC config texts\n",
2349 pdata->num_drc_cfgs); 2339 pdata->num_drc_cfgs);
2350 return; 2340 return;
@@ -2356,9 +2346,9 @@ static void wm8904_handle_pdata(struct wm8904_priv *wm8904)
2356 wm8904->drc_enum.max = pdata->num_drc_cfgs; 2346 wm8904->drc_enum.max = pdata->num_drc_cfgs;
2357 wm8904->drc_enum.texts = wm8904->drc_texts; 2347 wm8904->drc_enum.texts = wm8904->drc_texts;
2358 2348
2359 ret = snd_soc_add_controls(&wm8904->codec, &control, 1); 2349 ret = snd_soc_add_controls(codec, &control, 1);
2360 if (ret != 0) 2350 if (ret != 0)
2361 dev_err(wm8904->codec.dev, 2351 dev_err(codec->dev,
2362 "Failed to add DRC mode control: %d\n", ret); 2352 "Failed to add DRC mode control: %d\n", ret);
2363 2353
2364 wm8904_set_drc(codec); 2354 wm8904_set_drc(codec);
@@ -2368,91 +2358,22 @@ static void wm8904_handle_pdata(struct wm8904_priv *wm8904)
2368 pdata->num_retune_mobile_cfgs); 2358 pdata->num_retune_mobile_cfgs);
2369 2359
2370 if (pdata->num_retune_mobile_cfgs) 2360 if (pdata->num_retune_mobile_cfgs)
2371 wm8904_handle_retune_mobile_pdata(wm8904); 2361 wm8904_handle_retune_mobile_pdata(codec);
2372 else 2362 else
2373 snd_soc_add_controls(&wm8904->codec, wm8904_eq_controls, 2363 snd_soc_add_controls(codec, wm8904_eq_controls,
2374 ARRAY_SIZE(wm8904_eq_controls)); 2364 ARRAY_SIZE(wm8904_eq_controls));
2375} 2365}
2376 2366
2377static int wm8904_probe(struct platform_device *pdev)
2378{
2379 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
2380 struct snd_soc_codec *codec;
2381 int ret = 0;
2382
2383 if (wm8904_codec == NULL) {
2384 dev_err(&pdev->dev, "Codec device not registered\n");
2385 return -ENODEV;
2386 }
2387
2388 socdev->card->codec = wm8904_codec;
2389 codec = wm8904_codec;
2390
2391 /* register pcms */
2392 ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
2393 if (ret < 0) {
2394 dev_err(codec->dev, "failed to create pcms: %d\n", ret);
2395 goto pcm_err;
2396 }
2397
2398 wm8904_handle_pdata(snd_soc_codec_get_drvdata(codec));
2399
2400 wm8904_add_widgets(codec);
2401
2402 return ret;
2403
2404pcm_err:
2405 return ret;
2406}
2407
2408static int wm8904_remove(struct platform_device *pdev)
2409{
2410 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
2411
2412 snd_soc_free_pcms(socdev);
2413 snd_soc_dapm_free(socdev);
2414
2415 return 0;
2416}
2417
2418struct snd_soc_codec_device soc_codec_dev_wm8904 = {
2419 .probe = wm8904_probe,
2420 .remove = wm8904_remove,
2421 .suspend = wm8904_suspend,
2422 .resume = wm8904_resume,
2423};
2424EXPORT_SYMBOL_GPL(soc_codec_dev_wm8904);
2425 2367
2426static int wm8904_register(struct wm8904_priv *wm8904, 2368static int wm8904_probe(struct snd_soc_codec *codec)
2427 enum snd_soc_control_type control)
2428{ 2369{
2370 struct wm8904_priv *wm8904 = snd_soc_codec_get_drvdata(codec);
2429 struct wm8904_pdata *pdata = wm8904->pdata; 2371 struct wm8904_pdata *pdata = wm8904->pdata;
2430 int ret; 2372 u16 *reg_cache = codec->reg_cache;
2431 struct snd_soc_codec *codec = &wm8904->codec; 2373 int ret, i;
2432 int i;
2433
2434 if (wm8904_codec) {
2435 dev_err(codec->dev, "Another WM8904 is registered\n");
2436 ret = -EINVAL;
2437 goto err;
2438 }
2439 2374
2440 mutex_init(&codec->mutex);
2441 INIT_LIST_HEAD(&codec->dapm_widgets);
2442 INIT_LIST_HEAD(&codec->dapm_paths);
2443
2444 snd_soc_codec_set_drvdata(codec, wm8904);
2445 codec->name = "WM8904";
2446 codec->owner = THIS_MODULE;
2447 codec->bias_level = SND_SOC_BIAS_OFF;
2448 codec->set_bias_level = wm8904_set_bias_level;
2449 codec->dai = &wm8904_dai;
2450 codec->num_dai = 1;
2451 codec->reg_cache_size = WM8904_MAX_REGISTER;
2452 codec->reg_cache = &wm8904->reg_cache;
2453 codec->volatile_register = wm8904_volatile_register;
2454 codec->cache_sync = 1; 2375 codec->cache_sync = 1;
2455 codec->idle_bias_off = 1; 2376 codec->dapm.idle_bias_off = 1;
2456 2377
2457 switch (wm8904->devtype) { 2378 switch (wm8904->devtype) {
2458 case WM8904: 2379 case WM8904:
@@ -2463,16 +2384,13 @@ static int wm8904_register(struct wm8904_priv *wm8904,
2463 default: 2384 default:
2464 dev_err(codec->dev, "Unknown device type %d\n", 2385 dev_err(codec->dev, "Unknown device type %d\n",
2465 wm8904->devtype); 2386 wm8904->devtype);
2466 ret = -EINVAL; 2387 return -EINVAL;
2467 goto err;
2468 } 2388 }
2469 2389
2470 memcpy(codec->reg_cache, wm8904_reg, sizeof(wm8904_reg)); 2390 ret = snd_soc_codec_set_cache_io(codec, 8, 16, SND_SOC_I2C);
2471
2472 ret = snd_soc_codec_set_cache_io(codec, 8, 16, control);
2473 if (ret != 0) { 2391 if (ret != 0) {
2474 dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret); 2392 dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
2475 goto err; 2393 return ret;
2476 } 2394 }
2477 2395
2478 for (i = 0; i < ARRAY_SIZE(wm8904->supplies); i++) 2396 for (i = 0; i < ARRAY_SIZE(wm8904->supplies); i++)
@@ -2482,7 +2400,7 @@ static int wm8904_register(struct wm8904_priv *wm8904,
2482 wm8904->supplies); 2400 wm8904->supplies);
2483 if (ret != 0) { 2401 if (ret != 0) {
2484 dev_err(codec->dev, "Failed to request supplies: %d\n", ret); 2402 dev_err(codec->dev, "Failed to request supplies: %d\n", ret);
2485 goto err; 2403 return ret;
2486 } 2404 }
2487 2405
2488 ret = regulator_bulk_enable(ARRAY_SIZE(wm8904->supplies), 2406 ret = regulator_bulk_enable(ARRAY_SIZE(wm8904->supplies),
@@ -2517,22 +2435,29 @@ static int wm8904_register(struct wm8904_priv *wm8904,
2517 goto err_enable; 2435 goto err_enable;
2518 } 2436 }
2519 2437
2520 wm8904_dai.dev = codec->dev;
2521
2522 /* Change some default settings - latch VU and enable ZC */ 2438 /* Change some default settings - latch VU and enable ZC */
2523 wm8904->reg_cache[WM8904_ADC_DIGITAL_VOLUME_LEFT] |= WM8904_ADC_VU; 2439 snd_soc_update_bits(codec, WM8904_ADC_DIGITAL_VOLUME_LEFT,
2524 wm8904->reg_cache[WM8904_ADC_DIGITAL_VOLUME_RIGHT] |= WM8904_ADC_VU; 2440 WM8904_ADC_VU, WM8904_ADC_VU);
2525 wm8904->reg_cache[WM8904_DAC_DIGITAL_VOLUME_LEFT] |= WM8904_DAC_VU; 2441 snd_soc_update_bits(codec, WM8904_ADC_DIGITAL_VOLUME_RIGHT,
2526 wm8904->reg_cache[WM8904_DAC_DIGITAL_VOLUME_RIGHT] |= WM8904_DAC_VU; 2442 WM8904_ADC_VU, WM8904_ADC_VU);
2527 wm8904->reg_cache[WM8904_ANALOGUE_OUT1_LEFT] |= WM8904_HPOUT_VU | 2443 snd_soc_update_bits(codec, WM8904_DAC_DIGITAL_VOLUME_LEFT,
2528 WM8904_HPOUTLZC; 2444 WM8904_DAC_VU, WM8904_DAC_VU);
2529 wm8904->reg_cache[WM8904_ANALOGUE_OUT1_RIGHT] |= WM8904_HPOUT_VU | 2445 snd_soc_update_bits(codec, WM8904_DAC_DIGITAL_VOLUME_RIGHT,
2530 WM8904_HPOUTRZC; 2446 WM8904_DAC_VU, WM8904_DAC_VU);
2531 wm8904->reg_cache[WM8904_ANALOGUE_OUT2_LEFT] |= WM8904_LINEOUT_VU | 2447 snd_soc_update_bits(codec, WM8904_ANALOGUE_OUT1_LEFT,
2532 WM8904_LINEOUTLZC; 2448 WM8904_HPOUT_VU | WM8904_HPOUTLZC,
2533 wm8904->reg_cache[WM8904_ANALOGUE_OUT2_RIGHT] |= WM8904_LINEOUT_VU | 2449 WM8904_HPOUT_VU | WM8904_HPOUTLZC);
2534 WM8904_LINEOUTRZC; 2450 snd_soc_update_bits(codec, WM8904_ANALOGUE_OUT1_RIGHT,
2535 wm8904->reg_cache[WM8904_CLOCK_RATES_0] &= ~WM8904_SR_MODE; 2451 WM8904_HPOUT_VU | WM8904_HPOUTRZC,
2452 WM8904_HPOUT_VU | WM8904_HPOUTRZC);
2453 snd_soc_update_bits(codec, WM8904_ANALOGUE_OUT2_LEFT,
2454 WM8904_LINEOUT_VU | WM8904_LINEOUTLZC,
2455 WM8904_LINEOUT_VU | WM8904_LINEOUTLZC);
2456 snd_soc_update_bits(codec, WM8904_ANALOGUE_OUT2_RIGHT,
2457 WM8904_LINEOUT_VU | WM8904_LINEOUTRZC,
2458 WM8904_LINEOUT_VU | WM8904_LINEOUTRZC);
2459 snd_soc_update_bits(codec, WM8904_CLOCK_RATES_0,
2460 WM8904_SR_MODE, 0);
2536 2461
2537 /* Apply configuration from the platform data. */ 2462 /* Apply configuration from the platform data. */
2538 if (wm8904->pdata) { 2463 if (wm8904->pdata) {
@@ -2540,95 +2465,95 @@ static int wm8904_register(struct wm8904_priv *wm8904,
2540 if (!pdata->gpio_cfg[i]) 2465 if (!pdata->gpio_cfg[i])
2541 continue; 2466 continue;
2542 2467
2543 wm8904->reg_cache[WM8904_GPIO_CONTROL_1 + i] 2468 reg_cache[WM8904_GPIO_CONTROL_1 + i]
2544 = pdata->gpio_cfg[i] & 0xffff; 2469 = pdata->gpio_cfg[i] & 0xffff;
2545 } 2470 }
2546 2471
2547 /* Zero is the default value for these anyway */ 2472 /* Zero is the default value for these anyway */
2548 for (i = 0; i < WM8904_MIC_REGS; i++) 2473 for (i = 0; i < WM8904_MIC_REGS; i++)
2549 wm8904->reg_cache[WM8904_MIC_BIAS_CONTROL_0 + i] 2474 reg_cache[WM8904_MIC_BIAS_CONTROL_0 + i]
2550 = pdata->mic_cfg[i]; 2475 = pdata->mic_cfg[i];
2551 } 2476 }
2552 2477
2553 /* Set Class W by default - this will be managed by the Class 2478 /* Set Class W by default - this will be managed by the Class
2554 * G widget at runtime where bypass paths are available. 2479 * G widget at runtime where bypass paths are available.
2555 */ 2480 */
2556 wm8904->reg_cache[WM8904_CLASS_W_0] |= WM8904_CP_DYN_PWR; 2481 snd_soc_update_bits(codec, WM8904_CLASS_W_0,
2482 WM8904_CP_DYN_PWR, WM8904_CP_DYN_PWR);
2557 2483
2558 /* Use normal bias source */ 2484 /* Use normal bias source */
2559 wm8904->reg_cache[WM8904_BIAS_CONTROL_0] &= ~WM8904_POBCTRL; 2485 snd_soc_update_bits(codec, WM8904_BIAS_CONTROL_0,
2486 WM8904_POBCTRL, 0);
2560 2487
2561 wm8904_set_bias_level(codec, SND_SOC_BIAS_STANDBY); 2488 wm8904_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
2562 2489
2563 /* Bias level configuration will have done an extra enable */ 2490 /* Bias level configuration will have done an extra enable */
2564 regulator_bulk_disable(ARRAY_SIZE(wm8904->supplies), wm8904->supplies); 2491 regulator_bulk_disable(ARRAY_SIZE(wm8904->supplies), wm8904->supplies);
2565 2492
2566 wm8904_codec = codec; 2493 wm8904_handle_pdata(codec);
2567 2494
2568 ret = snd_soc_register_codec(codec); 2495 wm8904_add_widgets(codec);
2569 if (ret != 0) {
2570 dev_err(codec->dev, "Failed to register codec: %d\n", ret);
2571 goto err_enable;
2572 }
2573
2574 ret = snd_soc_register_dai(&wm8904_dai);
2575 if (ret != 0) {
2576 dev_err(codec->dev, "Failed to register DAI: %d\n", ret);
2577 goto err_codec;
2578 }
2579 2496
2580 return 0; 2497 return 0;
2581 2498
2582err_codec:
2583 snd_soc_unregister_codec(codec);
2584err_enable: 2499err_enable:
2585 regulator_bulk_disable(ARRAY_SIZE(wm8904->supplies), wm8904->supplies); 2500 regulator_bulk_disable(ARRAY_SIZE(wm8904->supplies), wm8904->supplies);
2586err_get: 2501err_get:
2587 regulator_bulk_free(ARRAY_SIZE(wm8904->supplies), wm8904->supplies); 2502 regulator_bulk_free(ARRAY_SIZE(wm8904->supplies), wm8904->supplies);
2588err:
2589 kfree(wm8904);
2590 return ret; 2503 return ret;
2591} 2504}
2592 2505
2593static void wm8904_unregister(struct wm8904_priv *wm8904) 2506static int wm8904_remove(struct snd_soc_codec *codec)
2594{ 2507{
2595 wm8904_set_bias_level(&wm8904->codec, SND_SOC_BIAS_OFF); 2508 struct wm8904_priv *wm8904 = snd_soc_codec_get_drvdata(codec);
2509
2510 wm8904_set_bias_level(codec, SND_SOC_BIAS_OFF);
2596 regulator_bulk_free(ARRAY_SIZE(wm8904->supplies), wm8904->supplies); 2511 regulator_bulk_free(ARRAY_SIZE(wm8904->supplies), wm8904->supplies);
2597 snd_soc_unregister_dai(&wm8904_dai); 2512 kfree(wm8904->retune_mobile_texts);
2598 snd_soc_unregister_codec(&wm8904->codec); 2513 kfree(wm8904->drc_texts);
2599 kfree(wm8904); 2514
2600 wm8904_codec = NULL; 2515 return 0;
2601} 2516}
2602 2517
2518static struct snd_soc_codec_driver soc_codec_dev_wm8904 = {
2519 .probe = wm8904_probe,
2520 .remove = wm8904_remove,
2521 .suspend = wm8904_suspend,
2522 .resume = wm8904_resume,
2523 .set_bias_level = wm8904_set_bias_level,
2524 .reg_cache_size = ARRAY_SIZE(wm8904_reg),
2525 .reg_word_size = sizeof(u16),
2526 .reg_cache_default = wm8904_reg,
2527 .volatile_register = wm8904_volatile_register,
2528};
2529
2603#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) 2530#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
2604static __devinit int wm8904_i2c_probe(struct i2c_client *i2c, 2531static __devinit int wm8904_i2c_probe(struct i2c_client *i2c,
2605 const struct i2c_device_id *id) 2532 const struct i2c_device_id *id)
2606{ 2533{
2607 struct wm8904_priv *wm8904; 2534 struct wm8904_priv *wm8904;
2608 struct snd_soc_codec *codec; 2535 int ret;
2609 2536
2610 wm8904 = kzalloc(sizeof(struct wm8904_priv), GFP_KERNEL); 2537 wm8904 = kzalloc(sizeof(struct wm8904_priv), GFP_KERNEL);
2611 if (wm8904 == NULL) 2538 if (wm8904 == NULL)
2612 return -ENOMEM; 2539 return -ENOMEM;
2613 2540
2614 codec = &wm8904->codec;
2615 codec->hw_write = (hw_write_t)i2c_master_send;
2616
2617 wm8904->devtype = id->driver_data; 2541 wm8904->devtype = id->driver_data;
2618
2619 i2c_set_clientdata(i2c, wm8904); 2542 i2c_set_clientdata(i2c, wm8904);
2620 codec->control_data = i2c; 2543 wm8904->control_data = i2c;
2621 wm8904->pdata = i2c->dev.platform_data; 2544 wm8904->pdata = i2c->dev.platform_data;
2622 2545
2623 codec->dev = &i2c->dev; 2546 ret = snd_soc_register_codec(&i2c->dev,
2624 2547 &soc_codec_dev_wm8904, &wm8904_dai, 1);
2625 return wm8904_register(wm8904, SND_SOC_I2C); 2548 if (ret < 0)
2549 kfree(wm8904);
2550 return ret;
2626} 2551}
2627 2552
2628static __devexit int wm8904_i2c_remove(struct i2c_client *client) 2553static __devexit int wm8904_i2c_remove(struct i2c_client *client)
2629{ 2554{
2630 struct wm8904_priv *wm8904 = i2c_get_clientdata(client); 2555 snd_soc_unregister_codec(&client->dev);
2631 wm8904_unregister(wm8904); 2556 kfree(i2c_get_clientdata(client));
2632 return 0; 2557 return 0;
2633} 2558}
2634 2559
@@ -2641,7 +2566,7 @@ MODULE_DEVICE_TABLE(i2c, wm8904_i2c_id);
2641 2566
2642static struct i2c_driver wm8904_i2c_driver = { 2567static struct i2c_driver wm8904_i2c_driver = {
2643 .driver = { 2568 .driver = {
2644 .name = "WM8904", 2569 .name = "wm8904-codec",
2645 .owner = THIS_MODULE, 2570 .owner = THIS_MODULE,
2646 }, 2571 },
2647 .probe = wm8904_i2c_probe, 2572 .probe = wm8904_i2c_probe,
@@ -2652,15 +2577,15 @@ static struct i2c_driver wm8904_i2c_driver = {
2652 2577
2653static int __init wm8904_modinit(void) 2578static int __init wm8904_modinit(void)
2654{ 2579{
2655 int ret; 2580 int ret = 0;
2656#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) 2581#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
2657 ret = i2c_add_driver(&wm8904_i2c_driver); 2582 ret = i2c_add_driver(&wm8904_i2c_driver);
2658 if (ret != 0) { 2583 if (ret != 0) {
2659 printk(KERN_ERR "Failed to register WM8904 I2C driver: %d\n", 2584 printk(KERN_ERR "Failed to register wm8904 I2C driver: %d\n",
2660 ret); 2585 ret);
2661 } 2586 }
2662#endif 2587#endif
2663 return 0; 2588 return ret;
2664} 2589}
2665module_init(wm8904_modinit); 2590module_init(wm8904_modinit);
2666 2591