diff options
Diffstat (limited to 'sound/soc/codecs/wm8993.c')
-rw-r--r-- | sound/soc/codecs/wm8993.c | 307 |
1 files changed, 194 insertions, 113 deletions
diff --git a/sound/soc/codecs/wm8993.c b/sound/soc/codecs/wm8993.c index 2981afae842c..bf022f68b84f 100644 --- a/sound/soc/codecs/wm8993.c +++ b/sound/soc/codecs/wm8993.c | |||
@@ -1,7 +1,7 @@ | |||
1 | /* | 1 | /* |
2 | * wm8993.c -- WM8993 ALSA SoC audio driver | 2 | * wm8993.c -- WM8993 ALSA SoC audio driver |
3 | * | 3 | * |
4 | * Copyright 2009 Wolfson Microelectronics plc | 4 | * Copyright 2009, 2010 Wolfson Microelectronics plc |
5 | * | 5 | * |
6 | * Author: Mark Brown <broonie@opensource.wolfsonmicro.com> | 6 | * Author: Mark Brown <broonie@opensource.wolfsonmicro.com> |
7 | * | 7 | * |
@@ -16,6 +16,7 @@ | |||
16 | #include <linux/delay.h> | 16 | #include <linux/delay.h> |
17 | #include <linux/pm.h> | 17 | #include <linux/pm.h> |
18 | #include <linux/i2c.h> | 18 | #include <linux/i2c.h> |
19 | #include <linux/regulator/consumer.h> | ||
19 | #include <linux/spi/spi.h> | 20 | #include <linux/spi/spi.h> |
20 | #include <sound/core.h> | 21 | #include <sound/core.h> |
21 | #include <sound/pcm.h> | 22 | #include <sound/pcm.h> |
@@ -29,6 +30,16 @@ | |||
29 | #include "wm8993.h" | 30 | #include "wm8993.h" |
30 | #include "wm_hubs.h" | 31 | #include "wm_hubs.h" |
31 | 32 | ||
33 | #define WM8993_NUM_SUPPLIES 6 | ||
34 | static const char *wm8993_supply_names[WM8993_NUM_SUPPLIES] = { | ||
35 | "DCVDD", | ||
36 | "DBVDD", | ||
37 | "AVDD1", | ||
38 | "AVDD2", | ||
39 | "CPVDD", | ||
40 | "SPKVDD", | ||
41 | }; | ||
42 | |||
32 | static u16 wm8993_reg_defaults[WM8993_REGISTER_COUNT] = { | 43 | static u16 wm8993_reg_defaults[WM8993_REGISTER_COUNT] = { |
33 | 0x8993, /* R0 - Software Reset */ | 44 | 0x8993, /* R0 - Software Reset */ |
34 | 0x0000, /* R1 - Power Management (1) */ | 45 | 0x0000, /* R1 - Power Management (1) */ |
@@ -213,7 +224,9 @@ static struct { | |||
213 | }; | 224 | }; |
214 | 225 | ||
215 | struct wm8993_priv { | 226 | struct wm8993_priv { |
227 | struct wm_hubs_data hubs_data; | ||
216 | u16 reg_cache[WM8993_REGISTER_COUNT]; | 228 | u16 reg_cache[WM8993_REGISTER_COUNT]; |
229 | struct regulator_bulk_data supplies[WM8993_NUM_SUPPLIES]; | ||
217 | struct wm8993_platform_data pdata; | 230 | struct wm8993_platform_data pdata; |
218 | struct snd_soc_codec codec; | 231 | struct snd_soc_codec codec; |
219 | int master; | 232 | int master; |
@@ -227,36 +240,9 @@ struct wm8993_priv { | |||
227 | int class_w_users; | 240 | int class_w_users; |
228 | unsigned int fll_fref; | 241 | unsigned int fll_fref; |
229 | unsigned int fll_fout; | 242 | unsigned int fll_fout; |
243 | int fll_src; | ||
230 | }; | 244 | }; |
231 | 245 | ||
232 | static unsigned int wm8993_read_hw(struct snd_soc_codec *codec, u8 reg) | ||
233 | { | ||
234 | struct i2c_msg xfer[2]; | ||
235 | u16 data; | ||
236 | int ret; | ||
237 | struct i2c_client *i2c = codec->control_data; | ||
238 | |||
239 | /* Write register */ | ||
240 | xfer[0].addr = i2c->addr; | ||
241 | xfer[0].flags = 0; | ||
242 | xfer[0].len = 1; | ||
243 | xfer[0].buf = ® | ||
244 | |||
245 | /* Read data */ | ||
246 | xfer[1].addr = i2c->addr; | ||
247 | xfer[1].flags = I2C_M_RD; | ||
248 | xfer[1].len = 2; | ||
249 | xfer[1].buf = (u8 *)&data; | ||
250 | |||
251 | ret = i2c_transfer(i2c->adapter, xfer, 2); | ||
252 | if (ret != 2) { | ||
253 | dev_err(codec->dev, "Failed to read 0x%x: %d\n", reg, ret); | ||
254 | return 0; | ||
255 | } | ||
256 | |||
257 | return (data >> 8) | ((data & 0xff) << 8); | ||
258 | } | ||
259 | |||
260 | static int wm8993_volatile(unsigned int reg) | 246 | static int wm8993_volatile(unsigned int reg) |
261 | { | 247 | { |
262 | switch (reg) { | 248 | switch (reg) { |
@@ -271,48 +257,6 @@ static int wm8993_volatile(unsigned int reg) | |||
271 | } | 257 | } |
272 | } | 258 | } |
273 | 259 | ||
274 | static unsigned int wm8993_read(struct snd_soc_codec *codec, | ||
275 | unsigned int reg) | ||
276 | { | ||
277 | u16 *reg_cache = codec->reg_cache; | ||
278 | |||
279 | BUG_ON(reg > WM8993_MAX_REGISTER); | ||
280 | |||
281 | if (wm8993_volatile(reg)) | ||
282 | return wm8993_read_hw(codec, reg); | ||
283 | else | ||
284 | return reg_cache[reg]; | ||
285 | } | ||
286 | |||
287 | static int wm8993_write(struct snd_soc_codec *codec, unsigned int reg, | ||
288 | unsigned int value) | ||
289 | { | ||
290 | u16 *reg_cache = codec->reg_cache; | ||
291 | u8 data[3]; | ||
292 | int ret; | ||
293 | |||
294 | BUG_ON(reg > WM8993_MAX_REGISTER); | ||
295 | |||
296 | /* data is | ||
297 | * D15..D9 WM8993 register offset | ||
298 | * D8...D0 register data | ||
299 | */ | ||
300 | data[0] = reg; | ||
301 | data[1] = value >> 8; | ||
302 | data[2] = value & 0x00ff; | ||
303 | |||
304 | if (!wm8993_volatile(reg)) | ||
305 | reg_cache[reg] = value; | ||
306 | |||
307 | ret = codec->hw_write(codec->control_data, data, 3); | ||
308 | |||
309 | if (ret == 3) | ||
310 | return 0; | ||
311 | if (ret < 0) | ||
312 | return ret; | ||
313 | return -EIO; | ||
314 | } | ||
315 | |||
316 | struct _fll_div { | 260 | struct _fll_div { |
317 | u16 fll_fratio; | 261 | u16 fll_fratio; |
318 | u16 fll_outdiv; | 262 | u16 fll_outdiv; |
@@ -441,9 +385,9 @@ static int wm8993_set_fll(struct snd_soc_dai *dai, int fll_id, int source, | |||
441 | wm8993->fll_fref = 0; | 385 | wm8993->fll_fref = 0; |
442 | wm8993->fll_fout = 0; | 386 | wm8993->fll_fout = 0; |
443 | 387 | ||
444 | reg1 = wm8993_read(codec, WM8993_FLL_CONTROL_1); | 388 | reg1 = snd_soc_read(codec, WM8993_FLL_CONTROL_1); |
445 | reg1 &= ~WM8993_FLL_ENA; | 389 | reg1 &= ~WM8993_FLL_ENA; |
446 | wm8993_write(codec, WM8993_FLL_CONTROL_1, reg1); | 390 | snd_soc_write(codec, WM8993_FLL_CONTROL_1, reg1); |
447 | 391 | ||
448 | return 0; | 392 | return 0; |
449 | } | 393 | } |
@@ -452,7 +396,7 @@ static int wm8993_set_fll(struct snd_soc_dai *dai, int fll_id, int source, | |||
452 | if (ret != 0) | 396 | if (ret != 0) |
453 | return ret; | 397 | return ret; |
454 | 398 | ||
455 | reg5 = wm8993_read(codec, WM8993_FLL_CONTROL_5); | 399 | reg5 = snd_soc_read(codec, WM8993_FLL_CONTROL_5); |
456 | reg5 &= ~WM8993_FLL_CLK_SRC_MASK; | 400 | reg5 &= ~WM8993_FLL_CLK_SRC_MASK; |
457 | 401 | ||
458 | switch (fll_id) { | 402 | switch (fll_id) { |
@@ -474,38 +418,39 @@ static int wm8993_set_fll(struct snd_soc_dai *dai, int fll_id, int source, | |||
474 | 418 | ||
475 | /* Any FLL configuration change requires that the FLL be | 419 | /* Any FLL configuration change requires that the FLL be |
476 | * disabled first. */ | 420 | * disabled first. */ |
477 | reg1 = wm8993_read(codec, WM8993_FLL_CONTROL_1); | 421 | reg1 = snd_soc_read(codec, WM8993_FLL_CONTROL_1); |
478 | reg1 &= ~WM8993_FLL_ENA; | 422 | reg1 &= ~WM8993_FLL_ENA; |
479 | wm8993_write(codec, WM8993_FLL_CONTROL_1, reg1); | 423 | snd_soc_write(codec, WM8993_FLL_CONTROL_1, reg1); |
480 | 424 | ||
481 | /* Apply the configuration */ | 425 | /* Apply the configuration */ |
482 | if (fll_div.k) | 426 | if (fll_div.k) |
483 | reg1 |= WM8993_FLL_FRAC_MASK; | 427 | reg1 |= WM8993_FLL_FRAC_MASK; |
484 | else | 428 | else |
485 | reg1 &= ~WM8993_FLL_FRAC_MASK; | 429 | reg1 &= ~WM8993_FLL_FRAC_MASK; |
486 | wm8993_write(codec, WM8993_FLL_CONTROL_1, reg1); | 430 | snd_soc_write(codec, WM8993_FLL_CONTROL_1, reg1); |
487 | 431 | ||
488 | wm8993_write(codec, WM8993_FLL_CONTROL_2, | 432 | snd_soc_write(codec, WM8993_FLL_CONTROL_2, |
489 | (fll_div.fll_outdiv << WM8993_FLL_OUTDIV_SHIFT) | | 433 | (fll_div.fll_outdiv << WM8993_FLL_OUTDIV_SHIFT) | |
490 | (fll_div.fll_fratio << WM8993_FLL_FRATIO_SHIFT)); | 434 | (fll_div.fll_fratio << WM8993_FLL_FRATIO_SHIFT)); |
491 | wm8993_write(codec, WM8993_FLL_CONTROL_3, fll_div.k); | 435 | snd_soc_write(codec, WM8993_FLL_CONTROL_3, fll_div.k); |
492 | 436 | ||
493 | reg4 = wm8993_read(codec, WM8993_FLL_CONTROL_4); | 437 | reg4 = snd_soc_read(codec, WM8993_FLL_CONTROL_4); |
494 | reg4 &= ~WM8993_FLL_N_MASK; | 438 | reg4 &= ~WM8993_FLL_N_MASK; |
495 | reg4 |= fll_div.n << WM8993_FLL_N_SHIFT; | 439 | reg4 |= fll_div.n << WM8993_FLL_N_SHIFT; |
496 | wm8993_write(codec, WM8993_FLL_CONTROL_4, reg4); | 440 | snd_soc_write(codec, WM8993_FLL_CONTROL_4, reg4); |
497 | 441 | ||
498 | reg5 &= ~WM8993_FLL_CLK_REF_DIV_MASK; | 442 | reg5 &= ~WM8993_FLL_CLK_REF_DIV_MASK; |
499 | reg5 |= fll_div.fll_clk_ref_div << WM8993_FLL_CLK_REF_DIV_SHIFT; | 443 | reg5 |= fll_div.fll_clk_ref_div << WM8993_FLL_CLK_REF_DIV_SHIFT; |
500 | wm8993_write(codec, WM8993_FLL_CONTROL_5, reg5); | 444 | snd_soc_write(codec, WM8993_FLL_CONTROL_5, reg5); |
501 | 445 | ||
502 | /* Enable the FLL */ | 446 | /* Enable the FLL */ |
503 | wm8993_write(codec, WM8993_FLL_CONTROL_1, reg1 | WM8993_FLL_ENA); | 447 | snd_soc_write(codec, WM8993_FLL_CONTROL_1, reg1 | WM8993_FLL_ENA); |
504 | 448 | ||
505 | dev_dbg(codec->dev, "FLL enabled at %dHz->%dHz\n", Fref, Fout); | 449 | dev_dbg(codec->dev, "FLL enabled at %dHz->%dHz\n", Fref, Fout); |
506 | 450 | ||
507 | wm8993->fll_fref = Fref; | 451 | wm8993->fll_fref = Fref; |
508 | wm8993->fll_fout = Fout; | 452 | wm8993->fll_fout = Fout; |
453 | wm8993->fll_src = source; | ||
509 | 454 | ||
510 | return 0; | 455 | return 0; |
511 | } | 456 | } |
@@ -520,7 +465,7 @@ static int configure_clock(struct snd_soc_codec *codec) | |||
520 | case WM8993_SYSCLK_MCLK: | 465 | case WM8993_SYSCLK_MCLK: |
521 | dev_dbg(codec->dev, "Using %dHz MCLK\n", wm8993->mclk_rate); | 466 | dev_dbg(codec->dev, "Using %dHz MCLK\n", wm8993->mclk_rate); |
522 | 467 | ||
523 | reg = wm8993_read(codec, WM8993_CLOCKING_2); | 468 | reg = snd_soc_read(codec, WM8993_CLOCKING_2); |
524 | reg &= ~(WM8993_MCLK_DIV | WM8993_SYSCLK_SRC); | 469 | reg &= ~(WM8993_MCLK_DIV | WM8993_SYSCLK_SRC); |
525 | if (wm8993->mclk_rate > 13500000) { | 470 | if (wm8993->mclk_rate > 13500000) { |
526 | reg |= WM8993_MCLK_DIV; | 471 | reg |= WM8993_MCLK_DIV; |
@@ -529,14 +474,14 @@ static int configure_clock(struct snd_soc_codec *codec) | |||
529 | reg &= ~WM8993_MCLK_DIV; | 474 | reg &= ~WM8993_MCLK_DIV; |
530 | wm8993->sysclk_rate = wm8993->mclk_rate; | 475 | wm8993->sysclk_rate = wm8993->mclk_rate; |
531 | } | 476 | } |
532 | wm8993_write(codec, WM8993_CLOCKING_2, reg); | 477 | snd_soc_write(codec, WM8993_CLOCKING_2, reg); |
533 | break; | 478 | break; |
534 | 479 | ||
535 | case WM8993_SYSCLK_FLL: | 480 | case WM8993_SYSCLK_FLL: |
536 | dev_dbg(codec->dev, "Using %dHz FLL clock\n", | 481 | dev_dbg(codec->dev, "Using %dHz FLL clock\n", |
537 | wm8993->fll_fout); | 482 | wm8993->fll_fout); |
538 | 483 | ||
539 | reg = wm8993_read(codec, WM8993_CLOCKING_2); | 484 | reg = snd_soc_read(codec, WM8993_CLOCKING_2); |
540 | reg |= WM8993_SYSCLK_SRC; | 485 | reg |= WM8993_SYSCLK_SRC; |
541 | if (wm8993->fll_fout > 13500000) { | 486 | if (wm8993->fll_fout > 13500000) { |
542 | reg |= WM8993_MCLK_DIV; | 487 | reg |= WM8993_MCLK_DIV; |
@@ -545,7 +490,7 @@ static int configure_clock(struct snd_soc_codec *codec) | |||
545 | reg &= ~WM8993_MCLK_DIV; | 490 | reg &= ~WM8993_MCLK_DIV; |
546 | wm8993->sysclk_rate = wm8993->fll_fout; | 491 | wm8993->sysclk_rate = wm8993->fll_fout; |
547 | } | 492 | } |
548 | wm8993_write(codec, WM8993_CLOCKING_2, reg); | 493 | snd_soc_write(codec, WM8993_CLOCKING_2, reg); |
549 | break; | 494 | break; |
550 | 495 | ||
551 | default: | 496 | default: |
@@ -978,10 +923,33 @@ static const struct snd_soc_dapm_route routes[] = { | |||
978 | { "Right Headphone Mux", "DAC", "DACR" }, | 923 | { "Right Headphone Mux", "DAC", "DACR" }, |
979 | }; | 924 | }; |
980 | 925 | ||
926 | static void wm8993_cache_restore(struct snd_soc_codec *codec) | ||
927 | { | ||
928 | u16 *cache = codec->reg_cache; | ||
929 | int i; | ||
930 | |||
931 | if (!codec->cache_sync) | ||
932 | return; | ||
933 | |||
934 | /* Reenable hardware writes */ | ||
935 | codec->cache_only = 0; | ||
936 | |||
937 | /* Restore the register settings */ | ||
938 | for (i = 1; i < WM8993_MAX_REGISTER; i++) { | ||
939 | if (cache[i] == wm8993_reg_defaults[i]) | ||
940 | continue; | ||
941 | snd_soc_write(codec, i, cache[i]); | ||
942 | } | ||
943 | |||
944 | /* We're in sync again */ | ||
945 | codec->cache_sync = 0; | ||
946 | } | ||
947 | |||
981 | static int wm8993_set_bias_level(struct snd_soc_codec *codec, | 948 | static int wm8993_set_bias_level(struct snd_soc_codec *codec, |
982 | enum snd_soc_bias_level level) | 949 | enum snd_soc_bias_level level) |
983 | { | 950 | { |
984 | struct wm8993_priv *wm8993 = codec->private_data; | 951 | struct wm8993_priv *wm8993 = codec->private_data; |
952 | int ret; | ||
985 | 953 | ||
986 | switch (level) { | 954 | switch (level) { |
987 | case SND_SOC_BIAS_ON: | 955 | case SND_SOC_BIAS_ON: |
@@ -995,6 +963,18 @@ static int wm8993_set_bias_level(struct snd_soc_codec *codec, | |||
995 | 963 | ||
996 | case SND_SOC_BIAS_STANDBY: | 964 | case SND_SOC_BIAS_STANDBY: |
997 | if (codec->bias_level == SND_SOC_BIAS_OFF) { | 965 | if (codec->bias_level == SND_SOC_BIAS_OFF) { |
966 | ret = regulator_bulk_enable(ARRAY_SIZE(wm8993->supplies), | ||
967 | wm8993->supplies); | ||
968 | if (ret != 0) | ||
969 | return ret; | ||
970 | |||
971 | wm8993_cache_restore(codec); | ||
972 | |||
973 | /* Tune DC servo configuration */ | ||
974 | snd_soc_write(codec, 0x44, 3); | ||
975 | snd_soc_write(codec, 0x56, 3); | ||
976 | snd_soc_write(codec, 0x44, 0); | ||
977 | |||
998 | /* Bring up VMID with fast soft start */ | 978 | /* Bring up VMID with fast soft start */ |
999 | snd_soc_update_bits(codec, WM8993_ANTIPOP2, | 979 | snd_soc_update_bits(codec, WM8993_ANTIPOP2, |
1000 | WM8993_STARTUP_BIAS_ENA | | 980 | WM8993_STARTUP_BIAS_ENA | |
@@ -1042,6 +1022,18 @@ static int wm8993_set_bias_level(struct snd_soc_codec *codec, | |||
1042 | snd_soc_update_bits(codec, WM8993_POWER_MANAGEMENT_1, | 1022 | snd_soc_update_bits(codec, WM8993_POWER_MANAGEMENT_1, |
1043 | WM8993_VMID_SEL_MASK | WM8993_BIAS_ENA, | 1023 | WM8993_VMID_SEL_MASK | WM8993_BIAS_ENA, |
1044 | 0); | 1024 | 0); |
1025 | |||
1026 | #ifdef CONFIG_REGULATOR | ||
1027 | /* Post 2.6.34 we will be able to get a callback when | ||
1028 | * the regulators are disabled which we can use but | ||
1029 | * for now just assume that the power will be cut if | ||
1030 | * the regulator API is in use. | ||
1031 | */ | ||
1032 | codec->cache_sync = 1; | ||
1033 | #endif | ||
1034 | |||
1035 | regulator_bulk_disable(ARRAY_SIZE(wm8993->supplies), | ||
1036 | wm8993->supplies); | ||
1045 | break; | 1037 | break; |
1046 | } | 1038 | } |
1047 | 1039 | ||
@@ -1075,8 +1067,8 @@ static int wm8993_set_dai_fmt(struct snd_soc_dai *dai, | |||
1075 | { | 1067 | { |
1076 | struct snd_soc_codec *codec = dai->codec; | 1068 | struct snd_soc_codec *codec = dai->codec; |
1077 | struct wm8993_priv *wm8993 = codec->private_data; | 1069 | struct wm8993_priv *wm8993 = codec->private_data; |
1078 | unsigned int aif1 = wm8993_read(codec, WM8993_AUDIO_INTERFACE_1); | 1070 | unsigned int aif1 = snd_soc_read(codec, WM8993_AUDIO_INTERFACE_1); |
1079 | unsigned int aif4 = wm8993_read(codec, WM8993_AUDIO_INTERFACE_4); | 1071 | unsigned int aif4 = snd_soc_read(codec, WM8993_AUDIO_INTERFACE_4); |
1080 | 1072 | ||
1081 | aif1 &= ~(WM8993_BCLK_DIR | WM8993_AIF_BCLK_INV | | 1073 | aif1 &= ~(WM8993_BCLK_DIR | WM8993_AIF_BCLK_INV | |
1082 | WM8993_AIF_LRCLK_INV | WM8993_AIF_FMT_MASK); | 1074 | WM8993_AIF_LRCLK_INV | WM8993_AIF_FMT_MASK); |
@@ -1159,8 +1151,8 @@ static int wm8993_set_dai_fmt(struct snd_soc_dai *dai, | |||
1159 | return -EINVAL; | 1151 | return -EINVAL; |
1160 | } | 1152 | } |
1161 | 1153 | ||
1162 | wm8993_write(codec, WM8993_AUDIO_INTERFACE_1, aif1); | 1154 | snd_soc_write(codec, WM8993_AUDIO_INTERFACE_1, aif1); |
1163 | wm8993_write(codec, WM8993_AUDIO_INTERFACE_4, aif4); | 1155 | snd_soc_write(codec, WM8993_AUDIO_INTERFACE_4, aif4); |
1164 | 1156 | ||
1165 | return 0; | 1157 | return 0; |
1166 | } | 1158 | } |
@@ -1174,16 +1166,16 @@ static int wm8993_hw_params(struct snd_pcm_substream *substream, | |||
1174 | int ret, i, best, best_val, cur_val; | 1166 | int ret, i, best, best_val, cur_val; |
1175 | unsigned int clocking1, clocking3, aif1, aif4; | 1167 | unsigned int clocking1, clocking3, aif1, aif4; |
1176 | 1168 | ||
1177 | clocking1 = wm8993_read(codec, WM8993_CLOCKING_1); | 1169 | clocking1 = snd_soc_read(codec, WM8993_CLOCKING_1); |
1178 | clocking1 &= ~WM8993_BCLK_DIV_MASK; | 1170 | clocking1 &= ~WM8993_BCLK_DIV_MASK; |
1179 | 1171 | ||
1180 | clocking3 = wm8993_read(codec, WM8993_CLOCKING_3); | 1172 | clocking3 = snd_soc_read(codec, WM8993_CLOCKING_3); |
1181 | clocking3 &= ~(WM8993_CLK_SYS_RATE_MASK | WM8993_SAMPLE_RATE_MASK); | 1173 | clocking3 &= ~(WM8993_CLK_SYS_RATE_MASK | WM8993_SAMPLE_RATE_MASK); |
1182 | 1174 | ||
1183 | aif1 = wm8993_read(codec, WM8993_AUDIO_INTERFACE_1); | 1175 | aif1 = snd_soc_read(codec, WM8993_AUDIO_INTERFACE_1); |
1184 | aif1 &= ~WM8993_AIF_WL_MASK; | 1176 | aif1 &= ~WM8993_AIF_WL_MASK; |
1185 | 1177 | ||
1186 | aif4 = wm8993_read(codec, WM8993_AUDIO_INTERFACE_4); | 1178 | aif4 = snd_soc_read(codec, WM8993_AUDIO_INTERFACE_4); |
1187 | aif4 &= ~WM8993_LRCLK_RATE_MASK; | 1179 | aif4 &= ~WM8993_LRCLK_RATE_MASK; |
1188 | 1180 | ||
1189 | /* What BCLK do we need? */ | 1181 | /* What BCLK do we need? */ |
@@ -1276,14 +1268,14 @@ static int wm8993_hw_params(struct snd_pcm_substream *substream, | |||
1276 | dev_dbg(codec->dev, "LRCLK_RATE is %d\n", wm8993->bclk / wm8993->fs); | 1268 | dev_dbg(codec->dev, "LRCLK_RATE is %d\n", wm8993->bclk / wm8993->fs); |
1277 | aif4 |= wm8993->bclk / wm8993->fs; | 1269 | aif4 |= wm8993->bclk / wm8993->fs; |
1278 | 1270 | ||
1279 | wm8993_write(codec, WM8993_CLOCKING_1, clocking1); | 1271 | snd_soc_write(codec, WM8993_CLOCKING_1, clocking1); |
1280 | wm8993_write(codec, WM8993_CLOCKING_3, clocking3); | 1272 | snd_soc_write(codec, WM8993_CLOCKING_3, clocking3); |
1281 | wm8993_write(codec, WM8993_AUDIO_INTERFACE_1, aif1); | 1273 | snd_soc_write(codec, WM8993_AUDIO_INTERFACE_1, aif1); |
1282 | wm8993_write(codec, WM8993_AUDIO_INTERFACE_4, aif4); | 1274 | snd_soc_write(codec, WM8993_AUDIO_INTERFACE_4, aif4); |
1283 | 1275 | ||
1284 | /* ReTune Mobile? */ | 1276 | /* ReTune Mobile? */ |
1285 | if (wm8993->pdata.num_retune_configs) { | 1277 | if (wm8993->pdata.num_retune_configs) { |
1286 | u16 eq1 = wm8993_read(codec, WM8993_EQ1); | 1278 | u16 eq1 = snd_soc_read(codec, WM8993_EQ1); |
1287 | struct wm8993_retune_mobile_setting *s; | 1279 | struct wm8993_retune_mobile_setting *s; |
1288 | 1280 | ||
1289 | best = 0; | 1281 | best = 0; |
@@ -1306,7 +1298,7 @@ static int wm8993_hw_params(struct snd_pcm_substream *substream, | |||
1306 | snd_soc_update_bits(codec, WM8993_EQ1, WM8993_EQ_ENA, 0); | 1298 | snd_soc_update_bits(codec, WM8993_EQ1, WM8993_EQ_ENA, 0); |
1307 | 1299 | ||
1308 | for (i = 1; i < ARRAY_SIZE(s->config); i++) | 1300 | for (i = 1; i < ARRAY_SIZE(s->config); i++) |
1309 | wm8993_write(codec, WM8993_EQ1 + i, s->config[i]); | 1301 | snd_soc_write(codec, WM8993_EQ1 + i, s->config[i]); |
1310 | 1302 | ||
1311 | snd_soc_update_bits(codec, WM8993_EQ1, WM8993_EQ_ENA, eq1); | 1303 | snd_soc_update_bits(codec, WM8993_EQ1, WM8993_EQ_ENA, eq1); |
1312 | } | 1304 | } |
@@ -1319,14 +1311,14 @@ static int wm8993_digital_mute(struct snd_soc_dai *codec_dai, int mute) | |||
1319 | struct snd_soc_codec *codec = codec_dai->codec; | 1311 | struct snd_soc_codec *codec = codec_dai->codec; |
1320 | unsigned int reg; | 1312 | unsigned int reg; |
1321 | 1313 | ||
1322 | reg = wm8993_read(codec, WM8993_DAC_CTRL); | 1314 | reg = snd_soc_read(codec, WM8993_DAC_CTRL); |
1323 | 1315 | ||
1324 | if (mute) | 1316 | if (mute) |
1325 | reg |= WM8993_DAC_MUTE; | 1317 | reg |= WM8993_DAC_MUTE; |
1326 | else | 1318 | else |
1327 | reg &= ~WM8993_DAC_MUTE; | 1319 | reg &= ~WM8993_DAC_MUTE; |
1328 | 1320 | ||
1329 | wm8993_write(codec, WM8993_DAC_CTRL, reg); | 1321 | snd_soc_write(codec, WM8993_DAC_CTRL, reg); |
1330 | 1322 | ||
1331 | return 0; | 1323 | return 0; |
1332 | } | 1324 | } |
@@ -1480,9 +1472,66 @@ static int wm8993_remove(struct platform_device *pdev) | |||
1480 | return 0; | 1472 | return 0; |
1481 | } | 1473 | } |
1482 | 1474 | ||
1475 | #ifdef CONFIG_PM | ||
1476 | static int wm8993_suspend(struct platform_device *pdev, pm_message_t state) | ||
1477 | { | ||
1478 | struct snd_soc_device *socdev = platform_get_drvdata(pdev); | ||
1479 | struct snd_soc_codec *codec = socdev->card->codec; | ||
1480 | struct wm8993_priv *wm8993 = codec->private_data; | ||
1481 | int fll_fout = wm8993->fll_fout; | ||
1482 | int fll_fref = wm8993->fll_fref; | ||
1483 | int ret; | ||
1484 | |||
1485 | /* Stop the FLL in an orderly fashion */ | ||
1486 | ret = wm8993_set_fll(codec->dai, 0, 0, 0, 0); | ||
1487 | if (ret != 0) { | ||
1488 | dev_err(&pdev->dev, "Failed to stop FLL\n"); | ||
1489 | return ret; | ||
1490 | } | ||
1491 | |||
1492 | wm8993->fll_fout = fll_fout; | ||
1493 | wm8993->fll_fref = fll_fref; | ||
1494 | |||
1495 | wm8993_set_bias_level(codec, SND_SOC_BIAS_OFF); | ||
1496 | |||
1497 | return 0; | ||
1498 | } | ||
1499 | |||
1500 | static int wm8993_resume(struct platform_device *pdev) | ||
1501 | { | ||
1502 | struct snd_soc_device *socdev = platform_get_drvdata(pdev); | ||
1503 | struct snd_soc_codec *codec = socdev->card->codec; | ||
1504 | struct wm8993_priv *wm8993 = codec->private_data; | ||
1505 | int ret; | ||
1506 | |||
1507 | wm8993_set_bias_level(codec, SND_SOC_BIAS_STANDBY); | ||
1508 | |||
1509 | /* Restart the FLL? */ | ||
1510 | if (wm8993->fll_fout) { | ||
1511 | int fll_fout = wm8993->fll_fout; | ||
1512 | int fll_fref = wm8993->fll_fref; | ||
1513 | |||
1514 | wm8993->fll_fref = 0; | ||
1515 | wm8993->fll_fout = 0; | ||
1516 | |||
1517 | ret = wm8993_set_fll(codec->dai, 0, wm8993->fll_src, | ||
1518 | fll_fref, fll_fout); | ||
1519 | if (ret != 0) | ||
1520 | dev_err(codec->dev, "Failed to restart FLL\n"); | ||
1521 | } | ||
1522 | |||
1523 | return 0; | ||
1524 | } | ||
1525 | #else | ||
1526 | #define wm8993_suspend NULL | ||
1527 | #define wm8993_resume NULL | ||
1528 | #endif | ||
1529 | |||
1483 | struct snd_soc_codec_device soc_codec_dev_wm8993 = { | 1530 | struct snd_soc_codec_device soc_codec_dev_wm8993 = { |
1484 | .probe = wm8993_probe, | 1531 | .probe = wm8993_probe, |
1485 | .remove = wm8993_remove, | 1532 | .remove = wm8993_remove, |
1533 | .suspend = wm8993_suspend, | ||
1534 | .resume = wm8993_resume, | ||
1486 | }; | 1535 | }; |
1487 | EXPORT_SYMBOL_GPL(soc_codec_dev_wm8993); | 1536 | EXPORT_SYMBOL_GPL(soc_codec_dev_wm8993); |
1488 | 1537 | ||
@@ -1493,6 +1542,7 @@ static int wm8993_i2c_probe(struct i2c_client *i2c, | |||
1493 | struct snd_soc_codec *codec; | 1542 | struct snd_soc_codec *codec; |
1494 | unsigned int val; | 1543 | unsigned int val; |
1495 | int ret; | 1544 | int ret; |
1545 | int i; | ||
1496 | 1546 | ||
1497 | if (wm8993_codec) { | 1547 | if (wm8993_codec) { |
1498 | dev_err(&i2c->dev, "A WM8993 is already registered\n"); | 1548 | dev_err(&i2c->dev, "A WM8993 is already registered\n"); |
@@ -1513,9 +1563,7 @@ static int wm8993_i2c_probe(struct i2c_client *i2c, | |||
1513 | INIT_LIST_HEAD(&codec->dapm_paths); | 1563 | INIT_LIST_HEAD(&codec->dapm_paths); |
1514 | 1564 | ||
1515 | codec->name = "WM8993"; | 1565 | codec->name = "WM8993"; |
1516 | codec->read = wm8993_read; | 1566 | codec->volatile_register = wm8993_volatile; |
1517 | codec->write = wm8993_write; | ||
1518 | codec->hw_write = (hw_write_t)i2c_master_send; | ||
1519 | codec->reg_cache = wm8993->reg_cache; | 1567 | codec->reg_cache = wm8993->reg_cache; |
1520 | codec->reg_cache_size = ARRAY_SIZE(wm8993->reg_cache); | 1568 | codec->reg_cache_size = ARRAY_SIZE(wm8993->reg_cache); |
1521 | codec->bias_level = SND_SOC_BIAS_OFF; | 1569 | codec->bias_level = SND_SOC_BIAS_OFF; |
@@ -1524,25 +1572,53 @@ static int wm8993_i2c_probe(struct i2c_client *i2c, | |||
1524 | codec->num_dai = 1; | 1572 | codec->num_dai = 1; |
1525 | codec->private_data = wm8993; | 1573 | codec->private_data = wm8993; |
1526 | 1574 | ||
1575 | wm8993->hubs_data.hp_startup_mode = 1; | ||
1576 | wm8993->hubs_data.dcs_codes = -2; | ||
1577 | |||
1527 | memcpy(wm8993->reg_cache, wm8993_reg_defaults, | 1578 | memcpy(wm8993->reg_cache, wm8993_reg_defaults, |
1528 | sizeof(wm8993->reg_cache)); | 1579 | sizeof(wm8993->reg_cache)); |
1529 | 1580 | ||
1581 | ret = snd_soc_codec_set_cache_io(codec, 8, 16, SND_SOC_I2C); | ||
1582 | if (ret != 0) { | ||
1583 | dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret); | ||
1584 | goto err; | ||
1585 | } | ||
1586 | |||
1530 | i2c_set_clientdata(i2c, wm8993); | 1587 | i2c_set_clientdata(i2c, wm8993); |
1531 | codec->control_data = i2c; | 1588 | codec->control_data = i2c; |
1532 | wm8993_codec = codec; | 1589 | wm8993_codec = codec; |
1533 | 1590 | ||
1534 | codec->dev = &i2c->dev; | 1591 | codec->dev = &i2c->dev; |
1535 | 1592 | ||
1536 | val = wm8993_read_hw(codec, WM8993_SOFTWARE_RESET); | 1593 | for (i = 0; i < ARRAY_SIZE(wm8993->supplies); i++) |
1594 | wm8993->supplies[i].supply = wm8993_supply_names[i]; | ||
1595 | |||
1596 | ret = regulator_bulk_get(codec->dev, ARRAY_SIZE(wm8993->supplies), | ||
1597 | wm8993->supplies); | ||
1598 | if (ret != 0) { | ||
1599 | dev_err(codec->dev, "Failed to request supplies: %d\n", ret); | ||
1600 | goto err; | ||
1601 | } | ||
1602 | |||
1603 | ret = regulator_bulk_enable(ARRAY_SIZE(wm8993->supplies), | ||
1604 | wm8993->supplies); | ||
1605 | if (ret != 0) { | ||
1606 | dev_err(codec->dev, "Failed to enable supplies: %d\n", ret); | ||
1607 | goto err_get; | ||
1608 | } | ||
1609 | |||
1610 | val = snd_soc_read(codec, WM8993_SOFTWARE_RESET); | ||
1537 | if (val != wm8993_reg_defaults[WM8993_SOFTWARE_RESET]) { | 1611 | if (val != wm8993_reg_defaults[WM8993_SOFTWARE_RESET]) { |
1538 | dev_err(codec->dev, "Invalid ID register value %x\n", val); | 1612 | dev_err(codec->dev, "Invalid ID register value %x\n", val); |
1539 | ret = -EINVAL; | 1613 | ret = -EINVAL; |
1540 | goto err; | 1614 | goto err_enable; |
1541 | } | 1615 | } |
1542 | 1616 | ||
1543 | ret = wm8993_write(codec, WM8993_SOFTWARE_RESET, 0xffff); | 1617 | ret = snd_soc_write(codec, WM8993_SOFTWARE_RESET, 0xffff); |
1544 | if (ret != 0) | 1618 | if (ret != 0) |
1545 | goto err; | 1619 | goto err_enable; |
1620 | |||
1621 | codec->cache_only = 1; | ||
1546 | 1622 | ||
1547 | /* By default we're using the output mixers */ | 1623 | /* By default we're using the output mixers */ |
1548 | wm8993->class_w_users = 2; | 1624 | wm8993->class_w_users = 2; |
@@ -1572,7 +1648,7 @@ static int wm8993_i2c_probe(struct i2c_client *i2c, | |||
1572 | 1648 | ||
1573 | ret = wm8993_set_bias_level(codec, SND_SOC_BIAS_STANDBY); | 1649 | ret = wm8993_set_bias_level(codec, SND_SOC_BIAS_STANDBY); |
1574 | if (ret != 0) | 1650 | if (ret != 0) |
1575 | goto err; | 1651 | goto err_enable; |
1576 | 1652 | ||
1577 | wm8993_dai.dev = codec->dev; | 1653 | wm8993_dai.dev = codec->dev; |
1578 | 1654 | ||
@@ -1586,6 +1662,10 @@ static int wm8993_i2c_probe(struct i2c_client *i2c, | |||
1586 | 1662 | ||
1587 | err_bias: | 1663 | err_bias: |
1588 | wm8993_set_bias_level(codec, SND_SOC_BIAS_OFF); | 1664 | wm8993_set_bias_level(codec, SND_SOC_BIAS_OFF); |
1665 | err_enable: | ||
1666 | regulator_bulk_disable(ARRAY_SIZE(wm8993->supplies), wm8993->supplies); | ||
1667 | err_get: | ||
1668 | regulator_bulk_free(ARRAY_SIZE(wm8993->supplies), wm8993->supplies); | ||
1589 | err: | 1669 | err: |
1590 | wm8993_codec = NULL; | 1670 | wm8993_codec = NULL; |
1591 | kfree(wm8993); | 1671 | kfree(wm8993); |
@@ -1600,6 +1680,7 @@ static int wm8993_i2c_remove(struct i2c_client *client) | |||
1600 | snd_soc_unregister_dai(&wm8993_dai); | 1680 | snd_soc_unregister_dai(&wm8993_dai); |
1601 | 1681 | ||
1602 | wm8993_set_bias_level(&wm8993->codec, SND_SOC_BIAS_OFF); | 1682 | wm8993_set_bias_level(&wm8993->codec, SND_SOC_BIAS_OFF); |
1683 | regulator_bulk_free(ARRAY_SIZE(wm8993->supplies), wm8993->supplies); | ||
1603 | kfree(wm8993); | 1684 | kfree(wm8993); |
1604 | 1685 | ||
1605 | return 0; | 1686 | return 0; |