diff options
author | Takashi Iwai <tiwai@suse.de> | 2012-10-06 10:33:52 -0400 |
---|---|---|
committer | Takashi Iwai <tiwai@suse.de> | 2012-10-06 10:33:52 -0400 |
commit | 0fd0ba5f9e8ebae66afded580f5f34936f740ac7 (patch) | |
tree | f232be1bf350b2aec4e860e7156f5292344b0c62 /sound | |
parent | b7ef37d0e382298bcf7ba399ce67b044d9add23a (diff) | |
parent | 9911f7f7562a25381eff93fdc660a4a3b4c0f6e0 (diff) |
Merge tag 'asoc-3.7' of git://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound into for-next
ASoC: Additional updates for v3.7
A couple more updates for 3.7, enhancements to the ux500 and wm2000
drivers, a new driver for DA9055 and the support for regulator bypass
mode. With the exception of the DA9055 this has all had a chance to
soak in -next (the driver was added on Friday so should be in -next
today).
Diffstat (limited to 'sound')
-rw-r--r-- | sound/soc/codecs/Kconfig | 4 | ||||
-rw-r--r-- | sound/soc/codecs/Makefile | 2 | ||||
-rw-r--r-- | sound/soc/codecs/ab8500-codec.c | 81 | ||||
-rw-r--r-- | sound/soc/codecs/arizona.c | 42 | ||||
-rw-r--r-- | sound/soc/codecs/arizona.h | 2 | ||||
-rw-r--r-- | sound/soc/codecs/cs4270.c | 4 | ||||
-rw-r--r-- | sound/soc/codecs/cs4271.c | 24 | ||||
-rw-r--r-- | sound/soc/codecs/da9055.c | 1510 | ||||
-rw-r--r-- | sound/soc/codecs/wm0010.c | 18 | ||||
-rw-r--r-- | sound/soc/codecs/wm2000.c | 60 | ||||
-rw-r--r-- | sound/soc/codecs/wm5102.c | 2 | ||||
-rw-r--r-- | sound/soc/codecs/wm5110.c | 79 | ||||
-rw-r--r-- | sound/soc/codecs/wm_hubs.c | 5 | ||||
-rw-r--r-- | sound/soc/fsl/eukrea-tlv320.c | 37 | ||||
-rw-r--r-- | sound/soc/soc-dapm.c | 23 | ||||
-rw-r--r-- | sound/soc/ux500/mop500.c | 47 | ||||
-rw-r--r-- | sound/soc/ux500/ux500_msp_dai.c | 6 | ||||
-rw-r--r-- | sound/soc/ux500/ux500_msp_i2s.c | 89 | ||||
-rw-r--r-- | sound/soc/ux500/ux500_msp_i2s.h | 8 |
19 files changed, 1951 insertions, 92 deletions
diff --git a/sound/soc/codecs/Kconfig b/sound/soc/codecs/Kconfig index 3684255e5fba..b92759a39361 100644 --- a/sound/soc/codecs/Kconfig +++ b/sound/soc/codecs/Kconfig | |||
@@ -37,6 +37,7 @@ config SND_SOC_ALL_CODECS | |||
37 | select SND_SOC_CX20442 | 37 | select SND_SOC_CX20442 |
38 | select SND_SOC_DA7210 if I2C | 38 | select SND_SOC_DA7210 if I2C |
39 | select SND_SOC_DA732X if I2C | 39 | select SND_SOC_DA732X if I2C |
40 | select SND_SOC_DA9055 if I2C | ||
40 | select SND_SOC_DFBMCS320 | 41 | select SND_SOC_DFBMCS320 |
41 | select SND_SOC_ISABELLE if I2C | 42 | select SND_SOC_ISABELLE if I2C |
42 | select SND_SOC_JZ4740_CODEC | 43 | select SND_SOC_JZ4740_CODEC |
@@ -239,6 +240,9 @@ config SND_SOC_DA7210 | |||
239 | config SND_SOC_DA732X | 240 | config SND_SOC_DA732X |
240 | tristate | 241 | tristate |
241 | 242 | ||
243 | config SND_SOC_DA9055 | ||
244 | tristate | ||
245 | |||
242 | config SND_SOC_DFBMCS320 | 246 | config SND_SOC_DFBMCS320 |
243 | tristate | 247 | tristate |
244 | 248 | ||
diff --git a/sound/soc/codecs/Makefile b/sound/soc/codecs/Makefile index ca508b251df7..9bd4d95aab4f 100644 --- a/sound/soc/codecs/Makefile +++ b/sound/soc/codecs/Makefile | |||
@@ -24,6 +24,7 @@ snd-soc-cs4271-objs := cs4271.o | |||
24 | snd-soc-cx20442-objs := cx20442.o | 24 | snd-soc-cx20442-objs := cx20442.o |
25 | snd-soc-da7210-objs := da7210.o | 25 | snd-soc-da7210-objs := da7210.o |
26 | snd-soc-da732x-objs := da732x.o | 26 | snd-soc-da732x-objs := da732x.o |
27 | snd-soc-da9055-objs := da9055.o | ||
27 | snd-soc-dfbmcs320-objs := dfbmcs320.o | 28 | snd-soc-dfbmcs320-objs := dfbmcs320.o |
28 | snd-soc-dmic-objs := dmic.o | 29 | snd-soc-dmic-objs := dmic.o |
29 | snd-soc-isabelle-objs := isabelle.o | 30 | snd-soc-isabelle-objs := isabelle.o |
@@ -144,6 +145,7 @@ obj-$(CONFIG_SND_SOC_CS4271) += snd-soc-cs4271.o | |||
144 | obj-$(CONFIG_SND_SOC_CX20442) += snd-soc-cx20442.o | 145 | obj-$(CONFIG_SND_SOC_CX20442) += snd-soc-cx20442.o |
145 | obj-$(CONFIG_SND_SOC_DA7210) += snd-soc-da7210.o | 146 | obj-$(CONFIG_SND_SOC_DA7210) += snd-soc-da7210.o |
146 | obj-$(CONFIG_SND_SOC_DA732X) += snd-soc-da732x.o | 147 | obj-$(CONFIG_SND_SOC_DA732X) += snd-soc-da732x.o |
148 | obj-$(CONFIG_SND_SOC_DA9055) += snd-soc-da9055.o | ||
147 | obj-$(CONFIG_SND_SOC_DFBMCS320) += snd-soc-dfbmcs320.o | 149 | obj-$(CONFIG_SND_SOC_DFBMCS320) += snd-soc-dfbmcs320.o |
148 | obj-$(CONFIG_SND_SOC_DMIC) += snd-soc-dmic.o | 150 | obj-$(CONFIG_SND_SOC_DMIC) += snd-soc-dmic.o |
149 | obj-$(CONFIG_SND_SOC_ISABELLE) += snd-soc-isabelle.o | 151 | obj-$(CONFIG_SND_SOC_ISABELLE) += snd-soc-isabelle.o |
diff --git a/sound/soc/codecs/ab8500-codec.c b/sound/soc/codecs/ab8500-codec.c index 2c1c2524ef8c..af547490b4f7 100644 --- a/sound/soc/codecs/ab8500-codec.c +++ b/sound/soc/codecs/ab8500-codec.c | |||
@@ -34,6 +34,7 @@ | |||
34 | #include <linux/mfd/abx500/ab8500-sysctrl.h> | 34 | #include <linux/mfd/abx500/ab8500-sysctrl.h> |
35 | #include <linux/mfd/abx500/ab8500-codec.h> | 35 | #include <linux/mfd/abx500/ab8500-codec.h> |
36 | #include <linux/regulator/consumer.h> | 36 | #include <linux/regulator/consumer.h> |
37 | #include <linux/of.h> | ||
37 | 38 | ||
38 | #include <sound/core.h> | 39 | #include <sound/core.h> |
39 | #include <sound/pcm.h> | 40 | #include <sound/pcm.h> |
@@ -2394,9 +2395,65 @@ struct snd_soc_dai_driver ab8500_codec_dai[] = { | |||
2394 | } | 2395 | } |
2395 | }; | 2396 | }; |
2396 | 2397 | ||
2398 | static void ab8500_codec_of_probe(struct device *dev, struct device_node *np, | ||
2399 | struct ab8500_codec_platform_data *codec) | ||
2400 | { | ||
2401 | u32 value; | ||
2402 | |||
2403 | if (of_get_property(np, "stericsson,amic1-type-single-ended", NULL)) | ||
2404 | codec->amics.mic1_type = AMIC_TYPE_SINGLE_ENDED; | ||
2405 | else | ||
2406 | codec->amics.mic1_type = AMIC_TYPE_DIFFERENTIAL; | ||
2407 | |||
2408 | if (of_get_property(np, "stericsson,amic2-type-single-ended", NULL)) | ||
2409 | codec->amics.mic2_type = AMIC_TYPE_SINGLE_ENDED; | ||
2410 | else | ||
2411 | codec->amics.mic2_type = AMIC_TYPE_DIFFERENTIAL; | ||
2412 | |||
2413 | /* Has a non-standard Vamic been requested? */ | ||
2414 | if (of_get_property(np, "stericsson,amic1a-bias-vamic2", NULL)) | ||
2415 | codec->amics.mic1a_micbias = AMIC_MICBIAS_VAMIC2; | ||
2416 | else | ||
2417 | codec->amics.mic1a_micbias = AMIC_MICBIAS_VAMIC1; | ||
2418 | |||
2419 | if (of_get_property(np, "stericsson,amic1b-bias-vamic2", NULL)) | ||
2420 | codec->amics.mic1b_micbias = AMIC_MICBIAS_VAMIC2; | ||
2421 | else | ||
2422 | codec->amics.mic1b_micbias = AMIC_MICBIAS_VAMIC1; | ||
2423 | |||
2424 | if (of_get_property(np, "stericsson,amic2-bias-vamic1", NULL)) | ||
2425 | codec->amics.mic2_micbias = AMIC_MICBIAS_VAMIC1; | ||
2426 | else | ||
2427 | codec->amics.mic2_micbias = AMIC_MICBIAS_VAMIC2; | ||
2428 | |||
2429 | if (!of_property_read_u32(np, "stericsson,earpeice-cmv", &value)) { | ||
2430 | switch (value) { | ||
2431 | case 950 : | ||
2432 | codec->ear_cmv = EAR_CMV_0_95V; | ||
2433 | break; | ||
2434 | case 1100 : | ||
2435 | codec->ear_cmv = EAR_CMV_1_10V; | ||
2436 | break; | ||
2437 | case 1270 : | ||
2438 | codec->ear_cmv = EAR_CMV_1_27V; | ||
2439 | break; | ||
2440 | case 1580 : | ||
2441 | codec->ear_cmv = EAR_CMV_1_58V; | ||
2442 | break; | ||
2443 | default : | ||
2444 | codec->ear_cmv = EAR_CMV_UNKNOWN; | ||
2445 | dev_err(dev, "Unsuitable earpiece voltage found in DT\n"); | ||
2446 | } | ||
2447 | } else { | ||
2448 | dev_warn(dev, "No earpiece voltage found in DT - using default\n"); | ||
2449 | codec->ear_cmv = EAR_CMV_0_95V; | ||
2450 | } | ||
2451 | } | ||
2452 | |||
2397 | static int ab8500_codec_probe(struct snd_soc_codec *codec) | 2453 | static int ab8500_codec_probe(struct snd_soc_codec *codec) |
2398 | { | 2454 | { |
2399 | struct device *dev = codec->dev; | 2455 | struct device *dev = codec->dev; |
2456 | struct device_node *np = dev->of_node; | ||
2400 | struct ab8500_codec_drvdata *drvdata = dev_get_drvdata(dev); | 2457 | struct ab8500_codec_drvdata *drvdata = dev_get_drvdata(dev); |
2401 | struct ab8500_platform_data *pdata; | 2458 | struct ab8500_platform_data *pdata; |
2402 | struct filter_control *fc; | 2459 | struct filter_control *fc; |
@@ -2407,6 +2464,30 @@ static int ab8500_codec_probe(struct snd_soc_codec *codec) | |||
2407 | /* Setup AB8500 according to board-settings */ | 2464 | /* Setup AB8500 according to board-settings */ |
2408 | pdata = dev_get_platdata(dev->parent); | 2465 | pdata = dev_get_platdata(dev->parent); |
2409 | 2466 | ||
2467 | if (np) { | ||
2468 | if (!pdata) | ||
2469 | pdata = devm_kzalloc(dev, | ||
2470 | sizeof(struct ab8500_platform_data), | ||
2471 | GFP_KERNEL); | ||
2472 | |||
2473 | if (pdata && !pdata->codec) | ||
2474 | pdata->codec | ||
2475 | = devm_kzalloc(dev, | ||
2476 | sizeof(struct ab8500_codec_platform_data), | ||
2477 | GFP_KERNEL); | ||
2478 | |||
2479 | if (!(pdata && pdata->codec)) | ||
2480 | return -ENOMEM; | ||
2481 | |||
2482 | ab8500_codec_of_probe(dev, np, pdata->codec); | ||
2483 | |||
2484 | } else { | ||
2485 | if (!(pdata && pdata->codec)) { | ||
2486 | dev_err(dev, "No codec platform data or DT found\n"); | ||
2487 | return -EINVAL; | ||
2488 | } | ||
2489 | } | ||
2490 | |||
2410 | status = ab8500_audio_setup_mics(codec, &pdata->codec->amics); | 2491 | status = ab8500_audio_setup_mics(codec, &pdata->codec->amics); |
2411 | if (status < 0) { | 2492 | if (status < 0) { |
2412 | pr_err("%s: Failed to setup mics (%d)!\n", __func__, status); | 2493 | pr_err("%s: Failed to setup mics (%d)!\n", __func__, status); |
diff --git a/sound/soc/codecs/arizona.c b/sound/soc/codecs/arizona.c index c167c896eaee..c03b65af3059 100644 --- a/sound/soc/codecs/arizona.c +++ b/sound/soc/codecs/arizona.c | |||
@@ -119,6 +119,24 @@ const char *arizona_mixer_texts[ARIZONA_NUM_MIXER_INPUTS] = { | |||
119 | "DSP1.4", | 119 | "DSP1.4", |
120 | "DSP1.5", | 120 | "DSP1.5", |
121 | "DSP1.6", | 121 | "DSP1.6", |
122 | "DSP2.1", | ||
123 | "DSP2.2", | ||
124 | "DSP2.3", | ||
125 | "DSP2.4", | ||
126 | "DSP2.5", | ||
127 | "DSP2.6", | ||
128 | "DSP3.1", | ||
129 | "DSP3.2", | ||
130 | "DSP3.3", | ||
131 | "DSP3.4", | ||
132 | "DSP3.5", | ||
133 | "DSP3.6", | ||
134 | "DSP4.1", | ||
135 | "DSP4.2", | ||
136 | "DSP4.3", | ||
137 | "DSP4.4", | ||
138 | "DSP4.5", | ||
139 | "DSP4.6", | ||
122 | "ASRC1L", | 140 | "ASRC1L", |
123 | "ASRC1R", | 141 | "ASRC1R", |
124 | "ASRC2L", | 142 | "ASRC2L", |
@@ -180,6 +198,24 @@ int arizona_mixer_values[ARIZONA_NUM_MIXER_INPUTS] = { | |||
180 | 0x6b, | 198 | 0x6b, |
181 | 0x6c, | 199 | 0x6c, |
182 | 0x6d, | 200 | 0x6d, |
201 | 0x70, /* DSP2.1 */ | ||
202 | 0x71, | ||
203 | 0x72, | ||
204 | 0x73, | ||
205 | 0x74, | ||
206 | 0x75, | ||
207 | 0x78, /* DSP3.1 */ | ||
208 | 0x79, | ||
209 | 0x7a, | ||
210 | 0x7b, | ||
211 | 0x7c, | ||
212 | 0x7d, | ||
213 | 0x80, /* DSP4.1 */ | ||
214 | 0x81, | ||
215 | 0x82, | ||
216 | 0x83, | ||
217 | 0x84, | ||
218 | 0x85, | ||
183 | 0x90, /* ASRC1L */ | 219 | 0x90, /* ASRC1L */ |
184 | 0x91, | 220 | 0x91, |
185 | 0x92, | 221 | 0x92, |
@@ -234,6 +270,9 @@ static unsigned int arizona_sysclk_48k_rates[] = { | |||
234 | 12288000, | 270 | 12288000, |
235 | 22579200, | 271 | 22579200, |
236 | 49152000, | 272 | 49152000, |
273 | 73728000, | ||
274 | 98304000, | ||
275 | 147456000, | ||
237 | }; | 276 | }; |
238 | 277 | ||
239 | static unsigned int arizona_sysclk_44k1_rates[] = { | 278 | static unsigned int arizona_sysclk_44k1_rates[] = { |
@@ -241,6 +280,9 @@ static unsigned int arizona_sysclk_44k1_rates[] = { | |||
241 | 11289600, | 280 | 11289600, |
242 | 24576000, | 281 | 24576000, |
243 | 45158400, | 282 | 45158400, |
283 | 67737600, | ||
284 | 90316800, | ||
285 | 135475200, | ||
244 | }; | 286 | }; |
245 | 287 | ||
246 | static int arizona_set_opclk(struct snd_soc_codec *codec, unsigned int clk, | 288 | static int arizona_set_opclk(struct snd_soc_codec *codec, unsigned int clk, |
diff --git a/sound/soc/codecs/arizona.h b/sound/soc/codecs/arizona.h index eb66b52777c9..36ec64946120 100644 --- a/sound/soc/codecs/arizona.h +++ b/sound/soc/codecs/arizona.h | |||
@@ -61,7 +61,7 @@ struct arizona_priv { | |||
61 | struct arizona_dai_priv dai[ARIZONA_MAX_DAI]; | 61 | struct arizona_dai_priv dai[ARIZONA_MAX_DAI]; |
62 | }; | 62 | }; |
63 | 63 | ||
64 | #define ARIZONA_NUM_MIXER_INPUTS 57 | 64 | #define ARIZONA_NUM_MIXER_INPUTS 75 |
65 | 65 | ||
66 | extern const unsigned int arizona_mixer_tlv[]; | 66 | extern const unsigned int arizona_mixer_tlv[]; |
67 | extern const char *arizona_mixer_texts[ARIZONA_NUM_MIXER_INPUTS]; | 67 | extern const char *arizona_mixer_texts[ARIZONA_NUM_MIXER_INPUTS]; |
diff --git a/sound/soc/codecs/cs4270.c b/sound/soc/codecs/cs4270.c index 815b53bc2d27..8e4779812b96 100644 --- a/sound/soc/codecs/cs4270.c +++ b/sound/soc/codecs/cs4270.c | |||
@@ -459,7 +459,7 @@ static struct snd_soc_dai_driver cs4270_dai = { | |||
459 | .name = "cs4270-hifi", | 459 | .name = "cs4270-hifi", |
460 | .playback = { | 460 | .playback = { |
461 | .stream_name = "Playback", | 461 | .stream_name = "Playback", |
462 | .channels_min = 1, | 462 | .channels_min = 2, |
463 | .channels_max = 2, | 463 | .channels_max = 2, |
464 | .rates = SNDRV_PCM_RATE_CONTINUOUS, | 464 | .rates = SNDRV_PCM_RATE_CONTINUOUS, |
465 | .rate_min = 4000, | 465 | .rate_min = 4000, |
@@ -468,7 +468,7 @@ static struct snd_soc_dai_driver cs4270_dai = { | |||
468 | }, | 468 | }, |
469 | .capture = { | 469 | .capture = { |
470 | .stream_name = "Capture", | 470 | .stream_name = "Capture", |
471 | .channels_min = 1, | 471 | .channels_min = 2, |
472 | .channels_max = 2, | 472 | .channels_max = 2, |
473 | .rates = SNDRV_PCM_RATE_CONTINUOUS, | 473 | .rates = SNDRV_PCM_RATE_CONTINUOUS, |
474 | .rate_min = 4000, | 474 | .rate_min = 4000, |
diff --git a/sound/soc/codecs/cs4271.c b/sound/soc/codecs/cs4271.c index 9eb01d7d58a3..f994af34f552 100644 --- a/sound/soc/codecs/cs4271.c +++ b/sound/soc/codecs/cs4271.c | |||
@@ -22,12 +22,14 @@ | |||
22 | #include <linux/module.h> | 22 | #include <linux/module.h> |
23 | #include <linux/slab.h> | 23 | #include <linux/slab.h> |
24 | #include <linux/delay.h> | 24 | #include <linux/delay.h> |
25 | #include <sound/pcm.h> | ||
26 | #include <sound/soc.h> | ||
27 | #include <sound/tlv.h> | ||
28 | #include <linux/gpio.h> | 25 | #include <linux/gpio.h> |
29 | #include <linux/i2c.h> | 26 | #include <linux/i2c.h> |
30 | #include <linux/spi/spi.h> | 27 | #include <linux/spi/spi.h> |
28 | #include <linux/of_device.h> | ||
29 | #include <linux/of_gpio.h> | ||
30 | #include <sound/pcm.h> | ||
31 | #include <sound/soc.h> | ||
32 | #include <sound/tlv.h> | ||
31 | #include <sound/cs4271.h> | 33 | #include <sound/cs4271.h> |
32 | 34 | ||
33 | #define CS4271_PCM_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | \ | 35 | #define CS4271_PCM_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | \ |
@@ -458,6 +460,14 @@ static int cs4271_soc_resume(struct snd_soc_codec *codec) | |||
458 | #define cs4271_soc_resume NULL | 460 | #define cs4271_soc_resume NULL |
459 | #endif /* CONFIG_PM */ | 461 | #endif /* CONFIG_PM */ |
460 | 462 | ||
463 | #ifdef CONFIG_OF | ||
464 | static const struct of_device_id cs4271_dt_ids[] = { | ||
465 | { .compatible = "cirrus,cs4271", }, | ||
466 | { } | ||
467 | }; | ||
468 | MODULE_DEVICE_TABLE(of, cs4271_dt_ids); | ||
469 | #endif | ||
470 | |||
461 | static int cs4271_probe(struct snd_soc_codec *codec) | 471 | static int cs4271_probe(struct snd_soc_codec *codec) |
462 | { | 472 | { |
463 | struct cs4271_private *cs4271 = snd_soc_codec_get_drvdata(codec); | 473 | struct cs4271_private *cs4271 = snd_soc_codec_get_drvdata(codec); |
@@ -465,6 +475,12 @@ static int cs4271_probe(struct snd_soc_codec *codec) | |||
465 | int ret; | 475 | int ret; |
466 | int gpio_nreset = -EINVAL; | 476 | int gpio_nreset = -EINVAL; |
467 | 477 | ||
478 | #ifdef CONFIG_OF | ||
479 | if (of_match_device(cs4271_dt_ids, codec->dev)) | ||
480 | gpio_nreset = of_get_named_gpio(codec->dev->of_node, | ||
481 | "reset-gpio", 0); | ||
482 | #endif | ||
483 | |||
468 | if (cs4271plat && gpio_is_valid(cs4271plat->gpio_nreset)) | 484 | if (cs4271plat && gpio_is_valid(cs4271plat->gpio_nreset)) |
469 | gpio_nreset = cs4271plat->gpio_nreset; | 485 | gpio_nreset = cs4271plat->gpio_nreset; |
470 | 486 | ||
@@ -569,6 +585,7 @@ static struct spi_driver cs4271_spi_driver = { | |||
569 | .driver = { | 585 | .driver = { |
570 | .name = "cs4271", | 586 | .name = "cs4271", |
571 | .owner = THIS_MODULE, | 587 | .owner = THIS_MODULE, |
588 | .of_match_table = of_match_ptr(cs4271_dt_ids), | ||
572 | }, | 589 | }, |
573 | .probe = cs4271_spi_probe, | 590 | .probe = cs4271_spi_probe, |
574 | .remove = __devexit_p(cs4271_spi_remove), | 591 | .remove = __devexit_p(cs4271_spi_remove), |
@@ -608,6 +625,7 @@ static struct i2c_driver cs4271_i2c_driver = { | |||
608 | .driver = { | 625 | .driver = { |
609 | .name = "cs4271", | 626 | .name = "cs4271", |
610 | .owner = THIS_MODULE, | 627 | .owner = THIS_MODULE, |
628 | .of_match_table = of_match_ptr(cs4271_dt_ids), | ||
611 | }, | 629 | }, |
612 | .id_table = cs4271_i2c_id, | 630 | .id_table = cs4271_i2c_id, |
613 | .probe = cs4271_i2c_probe, | 631 | .probe = cs4271_i2c_probe, |
diff --git a/sound/soc/codecs/da9055.c b/sound/soc/codecs/da9055.c new file mode 100644 index 000000000000..185d8dd36399 --- /dev/null +++ b/sound/soc/codecs/da9055.c | |||
@@ -0,0 +1,1510 @@ | |||
1 | /* | ||
2 | * DA9055 ALSA Soc codec driver | ||
3 | * | ||
4 | * Copyright (c) 2012 Dialog Semiconductor | ||
5 | * | ||
6 | * Tested on (Samsung SMDK6410 board + DA9055 EVB) using I2S and I2C | ||
7 | * Written by David Chen <david.chen@diasemi.com> and | ||
8 | * Ashish Chavan <ashish.chavan@kpitcummins.com> | ||
9 | * | ||
10 | * This program is free software; you can redistribute it and/or modify it | ||
11 | * under the terms of the GNU General Public License as published by the | ||
12 | * Free Software Foundation; either version 2 of the License, or (at your | ||
13 | * option) any later version. | ||
14 | */ | ||
15 | |||
16 | #include <linux/delay.h> | ||
17 | #include <linux/i2c.h> | ||
18 | #include <linux/regmap.h> | ||
19 | #include <linux/slab.h> | ||
20 | #include <linux/module.h> | ||
21 | #include <sound/pcm.h> | ||
22 | #include <sound/pcm_params.h> | ||
23 | #include <sound/soc.h> | ||
24 | #include <sound/initval.h> | ||
25 | #include <sound/tlv.h> | ||
26 | #include <sound/da9055.h> | ||
27 | |||
28 | /* DA9055 register space */ | ||
29 | |||
30 | /* Status Registers */ | ||
31 | #define DA9055_STATUS1 0x02 | ||
32 | #define DA9055_PLL_STATUS 0x03 | ||
33 | #define DA9055_AUX_L_GAIN_STATUS 0x04 | ||
34 | #define DA9055_AUX_R_GAIN_STATUS 0x05 | ||
35 | #define DA9055_MIC_L_GAIN_STATUS 0x06 | ||
36 | #define DA9055_MIC_R_GAIN_STATUS 0x07 | ||
37 | #define DA9055_MIXIN_L_GAIN_STATUS 0x08 | ||
38 | #define DA9055_MIXIN_R_GAIN_STATUS 0x09 | ||
39 | #define DA9055_ADC_L_GAIN_STATUS 0x0A | ||
40 | #define DA9055_ADC_R_GAIN_STATUS 0x0B | ||
41 | #define DA9055_DAC_L_GAIN_STATUS 0x0C | ||
42 | #define DA9055_DAC_R_GAIN_STATUS 0x0D | ||
43 | #define DA9055_HP_L_GAIN_STATUS 0x0E | ||
44 | #define DA9055_HP_R_GAIN_STATUS 0x0F | ||
45 | #define DA9055_LINE_GAIN_STATUS 0x10 | ||
46 | |||
47 | /* System Initialisation Registers */ | ||
48 | #define DA9055_CIF_CTRL 0x20 | ||
49 | #define DA9055_DIG_ROUTING_AIF 0X21 | ||
50 | #define DA9055_SR 0x22 | ||
51 | #define DA9055_REFERENCES 0x23 | ||
52 | #define DA9055_PLL_FRAC_TOP 0x24 | ||
53 | #define DA9055_PLL_FRAC_BOT 0x25 | ||
54 | #define DA9055_PLL_INTEGER 0x26 | ||
55 | #define DA9055_PLL_CTRL 0x27 | ||
56 | #define DA9055_AIF_CLK_MODE 0x28 | ||
57 | #define DA9055_AIF_CTRL 0x29 | ||
58 | #define DA9055_DIG_ROUTING_DAC 0x2A | ||
59 | #define DA9055_ALC_CTRL1 0x2B | ||
60 | |||
61 | /* Input - Gain, Select and Filter Registers */ | ||
62 | #define DA9055_AUX_L_GAIN 0x30 | ||
63 | #define DA9055_AUX_R_GAIN 0x31 | ||
64 | #define DA9055_MIXIN_L_SELECT 0x32 | ||
65 | #define DA9055_MIXIN_R_SELECT 0x33 | ||
66 | #define DA9055_MIXIN_L_GAIN 0x34 | ||
67 | #define DA9055_MIXIN_R_GAIN 0x35 | ||
68 | #define DA9055_ADC_L_GAIN 0x36 | ||
69 | #define DA9055_ADC_R_GAIN 0x37 | ||
70 | #define DA9055_ADC_FILTERS1 0x38 | ||
71 | #define DA9055_MIC_L_GAIN 0x39 | ||
72 | #define DA9055_MIC_R_GAIN 0x3A | ||
73 | |||
74 | /* Output - Gain, Select and Filter Registers */ | ||
75 | #define DA9055_DAC_FILTERS5 0x40 | ||
76 | #define DA9055_DAC_FILTERS2 0x41 | ||
77 | #define DA9055_DAC_FILTERS3 0x42 | ||
78 | #define DA9055_DAC_FILTERS4 0x43 | ||
79 | #define DA9055_DAC_FILTERS1 0x44 | ||
80 | #define DA9055_DAC_L_GAIN 0x45 | ||
81 | #define DA9055_DAC_R_GAIN 0x46 | ||
82 | #define DA9055_CP_CTRL 0x47 | ||
83 | #define DA9055_HP_L_GAIN 0x48 | ||
84 | #define DA9055_HP_R_GAIN 0x49 | ||
85 | #define DA9055_LINE_GAIN 0x4A | ||
86 | #define DA9055_MIXOUT_L_SELECT 0x4B | ||
87 | #define DA9055_MIXOUT_R_SELECT 0x4C | ||
88 | |||
89 | /* System Controller Registers */ | ||
90 | #define DA9055_SYSTEM_MODES_INPUT 0x50 | ||
91 | #define DA9055_SYSTEM_MODES_OUTPUT 0x51 | ||
92 | |||
93 | /* Control Registers */ | ||
94 | #define DA9055_AUX_L_CTRL 0x60 | ||
95 | #define DA9055_AUX_R_CTRL 0x61 | ||
96 | #define DA9055_MIC_BIAS_CTRL 0x62 | ||
97 | #define DA9055_MIC_L_CTRL 0x63 | ||
98 | #define DA9055_MIC_R_CTRL 0x64 | ||
99 | #define DA9055_MIXIN_L_CTRL 0x65 | ||
100 | #define DA9055_MIXIN_R_CTRL 0x66 | ||
101 | #define DA9055_ADC_L_CTRL 0x67 | ||
102 | #define DA9055_ADC_R_CTRL 0x68 | ||
103 | #define DA9055_DAC_L_CTRL 0x69 | ||
104 | #define DA9055_DAC_R_CTRL 0x6A | ||
105 | #define DA9055_HP_L_CTRL 0x6B | ||
106 | #define DA9055_HP_R_CTRL 0x6C | ||
107 | #define DA9055_LINE_CTRL 0x6D | ||
108 | #define DA9055_MIXOUT_L_CTRL 0x6E | ||
109 | #define DA9055_MIXOUT_R_CTRL 0x6F | ||
110 | |||
111 | /* Configuration Registers */ | ||
112 | #define DA9055_LDO_CTRL 0x90 | ||
113 | #define DA9055_IO_CTRL 0x91 | ||
114 | #define DA9055_GAIN_RAMP_CTRL 0x92 | ||
115 | #define DA9055_MIC_CONFIG 0x93 | ||
116 | #define DA9055_PC_COUNT 0x94 | ||
117 | #define DA9055_CP_VOL_THRESHOLD1 0x95 | ||
118 | #define DA9055_CP_DELAY 0x96 | ||
119 | #define DA9055_CP_DETECTOR 0x97 | ||
120 | #define DA9055_AIF_OFFSET 0x98 | ||
121 | #define DA9055_DIG_CTRL 0x99 | ||
122 | #define DA9055_ALC_CTRL2 0x9A | ||
123 | #define DA9055_ALC_CTRL3 0x9B | ||
124 | #define DA9055_ALC_NOISE 0x9C | ||
125 | #define DA9055_ALC_TARGET_MIN 0x9D | ||
126 | #define DA9055_ALC_TARGET_MAX 0x9E | ||
127 | #define DA9055_ALC_GAIN_LIMITS 0x9F | ||
128 | #define DA9055_ALC_ANA_GAIN_LIMITS 0xA0 | ||
129 | #define DA9055_ALC_ANTICLIP_CTRL 0xA1 | ||
130 | #define DA9055_ALC_ANTICLIP_LEVEL 0xA2 | ||
131 | #define DA9055_ALC_OFFSET_OP2M_L 0xA6 | ||
132 | #define DA9055_ALC_OFFSET_OP2U_L 0xA7 | ||
133 | #define DA9055_ALC_OFFSET_OP2M_R 0xAB | ||
134 | #define DA9055_ALC_OFFSET_OP2U_R 0xAC | ||
135 | #define DA9055_ALC_CIC_OP_LVL_CTRL 0xAD | ||
136 | #define DA9055_ALC_CIC_OP_LVL_DATA 0xAE | ||
137 | #define DA9055_DAC_NG_SETUP_TIME 0xAF | ||
138 | #define DA9055_DAC_NG_OFF_THRESHOLD 0xB0 | ||
139 | #define DA9055_DAC_NG_ON_THRESHOLD 0xB1 | ||
140 | #define DA9055_DAC_NG_CTRL 0xB2 | ||
141 | |||
142 | /* SR bit fields */ | ||
143 | #define DA9055_SR_8000 (0x1 << 0) | ||
144 | #define DA9055_SR_11025 (0x2 << 0) | ||
145 | #define DA9055_SR_12000 (0x3 << 0) | ||
146 | #define DA9055_SR_16000 (0x5 << 0) | ||
147 | #define DA9055_SR_22050 (0x6 << 0) | ||
148 | #define DA9055_SR_24000 (0x7 << 0) | ||
149 | #define DA9055_SR_32000 (0x9 << 0) | ||
150 | #define DA9055_SR_44100 (0xA << 0) | ||
151 | #define DA9055_SR_48000 (0xB << 0) | ||
152 | #define DA9055_SR_88200 (0xE << 0) | ||
153 | #define DA9055_SR_96000 (0xF << 0) | ||
154 | |||
155 | /* REFERENCES bit fields */ | ||
156 | #define DA9055_BIAS_EN (1 << 3) | ||
157 | #define DA9055_VMID_EN (1 << 7) | ||
158 | |||
159 | /* PLL_CTRL bit fields */ | ||
160 | #define DA9055_PLL_INDIV_10_20_MHZ (1 << 2) | ||
161 | #define DA9055_PLL_SRM_EN (1 << 6) | ||
162 | #define DA9055_PLL_EN (1 << 7) | ||
163 | |||
164 | /* AIF_CLK_MODE bit fields */ | ||
165 | #define DA9055_AIF_BCLKS_PER_WCLK_32 (0 << 0) | ||
166 | #define DA9055_AIF_BCLKS_PER_WCLK_64 (1 << 0) | ||
167 | #define DA9055_AIF_BCLKS_PER_WCLK_128 (2 << 0) | ||
168 | #define DA9055_AIF_BCLKS_PER_WCLK_256 (3 << 0) | ||
169 | #define DA9055_AIF_CLK_EN_SLAVE_MODE (0 << 7) | ||
170 | #define DA9055_AIF_CLK_EN_MASTER_MODE (1 << 7) | ||
171 | |||
172 | /* AIF_CTRL bit fields */ | ||
173 | #define DA9055_AIF_FORMAT_I2S_MODE (0 << 0) | ||
174 | #define DA9055_AIF_FORMAT_LEFT_J (1 << 0) | ||
175 | #define DA9055_AIF_FORMAT_RIGHT_J (2 << 0) | ||
176 | #define DA9055_AIF_WORD_S16_LE (0 << 2) | ||
177 | #define DA9055_AIF_WORD_S20_3LE (1 << 2) | ||
178 | #define DA9055_AIF_WORD_S24_LE (2 << 2) | ||
179 | #define DA9055_AIF_WORD_S32_LE (3 << 2) | ||
180 | |||
181 | /* MIXIN_L_CTRL bit fields */ | ||
182 | #define DA9055_MIXIN_L_MIX_EN (1 << 3) | ||
183 | |||
184 | /* MIXIN_R_CTRL bit fields */ | ||
185 | #define DA9055_MIXIN_R_MIX_EN (1 << 3) | ||
186 | |||
187 | /* ADC_L_CTRL bit fields */ | ||
188 | #define DA9055_ADC_L_EN (1 << 7) | ||
189 | |||
190 | /* ADC_R_CTRL bit fields */ | ||
191 | #define DA9055_ADC_R_EN (1 << 7) | ||
192 | |||
193 | /* DAC_L_CTRL bit fields */ | ||
194 | #define DA9055_DAC_L_MUTE_EN (1 << 6) | ||
195 | |||
196 | /* DAC_R_CTRL bit fields */ | ||
197 | #define DA9055_DAC_R_MUTE_EN (1 << 6) | ||
198 | |||
199 | /* HP_L_CTRL bit fields */ | ||
200 | #define DA9055_HP_L_AMP_OE (1 << 3) | ||
201 | |||
202 | /* HP_R_CTRL bit fields */ | ||
203 | #define DA9055_HP_R_AMP_OE (1 << 3) | ||
204 | |||
205 | /* LINE_CTRL bit fields */ | ||
206 | #define DA9055_LINE_AMP_OE (1 << 3) | ||
207 | |||
208 | /* MIXOUT_L_CTRL bit fields */ | ||
209 | #define DA9055_MIXOUT_L_MIX_EN (1 << 3) | ||
210 | |||
211 | /* MIXOUT_R_CTRL bit fields */ | ||
212 | #define DA9055_MIXOUT_R_MIX_EN (1 << 3) | ||
213 | |||
214 | /* MIC bias select bit fields */ | ||
215 | #define DA9055_MICBIAS2_EN (1 << 6) | ||
216 | |||
217 | /* ALC_CIC_OP_LEVEL_CTRL bit fields */ | ||
218 | #define DA9055_ALC_DATA_MIDDLE (2 << 0) | ||
219 | #define DA9055_ALC_DATA_TOP (3 << 0) | ||
220 | #define DA9055_ALC_CIC_OP_CHANNEL_LEFT (0 << 7) | ||
221 | #define DA9055_ALC_CIC_OP_CHANNEL_RIGHT (1 << 7) | ||
222 | |||
223 | #define DA9055_AIF_BCLK_MASK (3 << 0) | ||
224 | #define DA9055_AIF_CLK_MODE_MASK (1 << 7) | ||
225 | #define DA9055_AIF_FORMAT_MASK (3 << 0) | ||
226 | #define DA9055_AIF_WORD_LENGTH_MASK (3 << 2) | ||
227 | #define DA9055_GAIN_RAMPING_EN (1 << 5) | ||
228 | #define DA9055_MICBIAS_LEVEL_MASK (3 << 4) | ||
229 | |||
230 | #define DA9055_ALC_OFFSET_15_8 0x00FF00 | ||
231 | #define DA9055_ALC_OFFSET_17_16 0x030000 | ||
232 | #define DA9055_ALC_AVG_ITERATIONS 5 | ||
233 | |||
234 | struct pll_div { | ||
235 | int fref; | ||
236 | int fout; | ||
237 | u8 frac_top; | ||
238 | u8 frac_bot; | ||
239 | u8 integer; | ||
240 | u8 mode; /* 0 = slave, 1 = master */ | ||
241 | }; | ||
242 | |||
243 | /* PLL divisor table */ | ||
244 | static const struct pll_div da9055_pll_div[] = { | ||
245 | /* for MASTER mode, fs = 44.1Khz and its harmonics */ | ||
246 | {11289600, 2822400, 0x00, 0x00, 0x20, 1}, /* MCLK=11.2896Mhz */ | ||
247 | {12000000, 2822400, 0x03, 0x61, 0x1E, 1}, /* MCLK=12Mhz */ | ||
248 | {12288000, 2822400, 0x0C, 0xCC, 0x1D, 1}, /* MCLK=12.288Mhz */ | ||
249 | {13000000, 2822400, 0x19, 0x45, 0x1B, 1}, /* MCLK=13Mhz */ | ||
250 | {13500000, 2822400, 0x18, 0x56, 0x1A, 1}, /* MCLK=13.5Mhz */ | ||
251 | {14400000, 2822400, 0x02, 0xD0, 0x19, 1}, /* MCLK=14.4Mhz */ | ||
252 | {19200000, 2822400, 0x1A, 0x1C, 0x12, 1}, /* MCLK=19.2Mhz */ | ||
253 | {19680000, 2822400, 0x0B, 0x6D, 0x12, 1}, /* MCLK=19.68Mhz */ | ||
254 | {19800000, 2822400, 0x07, 0xDD, 0x12, 1}, /* MCLK=19.8Mhz */ | ||
255 | /* for MASTER mode, fs = 48Khz and its harmonics */ | ||
256 | {11289600, 3072000, 0x1A, 0x8E, 0x22, 1}, /* MCLK=11.2896Mhz */ | ||
257 | {12000000, 3072000, 0x18, 0x93, 0x20, 1}, /* MCLK=12Mhz */ | ||
258 | {12288000, 3072000, 0x00, 0x00, 0x20, 1}, /* MCLK=12.288Mhz */ | ||
259 | {13000000, 3072000, 0x07, 0xEA, 0x1E, 1}, /* MCLK=13Mhz */ | ||
260 | {13500000, 3072000, 0x04, 0x11, 0x1D, 1}, /* MCLK=13.5Mhz */ | ||
261 | {14400000, 3072000, 0x09, 0xD0, 0x1B, 1}, /* MCLK=14.4Mhz */ | ||
262 | {19200000, 3072000, 0x0F, 0x5C, 0x14, 1}, /* MCLK=19.2Mhz */ | ||
263 | {19680000, 3072000, 0x1F, 0x60, 0x13, 1}, /* MCLK=19.68Mhz */ | ||
264 | {19800000, 3072000, 0x1B, 0x80, 0x13, 1}, /* MCLK=19.8Mhz */ | ||
265 | /* for SLAVE mode with SRM */ | ||
266 | {11289600, 2822400, 0x0D, 0x47, 0x21, 0}, /* MCLK=11.2896Mhz */ | ||
267 | {12000000, 2822400, 0x0D, 0xFA, 0x1F, 0}, /* MCLK=12Mhz */ | ||
268 | {12288000, 2822400, 0x16, 0x66, 0x1E, 0}, /* MCLK=12.288Mhz */ | ||
269 | {13000000, 2822400, 0x00, 0x98, 0x1D, 0}, /* MCLK=13Mhz */ | ||
270 | {13500000, 2822400, 0x1E, 0x33, 0x1B, 0}, /* MCLK=13.5Mhz */ | ||
271 | {14400000, 2822400, 0x06, 0x50, 0x1A, 0}, /* MCLK=14.4Mhz */ | ||
272 | {19200000, 2822400, 0x14, 0xBC, 0x13, 0}, /* MCLK=19.2Mhz */ | ||
273 | {19680000, 2822400, 0x05, 0x66, 0x13, 0}, /* MCLK=19.68Mhz */ | ||
274 | {19800000, 2822400, 0x01, 0xAE, 0x13, 0}, /* MCLK=19.8Mhz */ | ||
275 | }; | ||
276 | |||
277 | enum clk_src { | ||
278 | DA9055_CLKSRC_MCLK | ||
279 | }; | ||
280 | |||
281 | /* Gain and Volume */ | ||
282 | |||
283 | static const unsigned int aux_vol_tlv[] = { | ||
284 | TLV_DB_RANGE_HEAD(2), | ||
285 | 0x0, 0x10, TLV_DB_SCALE_ITEM(-5400, 0, 0), | ||
286 | /* -54dB to 15dB */ | ||
287 | 0x11, 0x3f, TLV_DB_SCALE_ITEM(-5400, 150, 0) | ||
288 | }; | ||
289 | |||
290 | static const unsigned int digital_gain_tlv[] = { | ||
291 | TLV_DB_RANGE_HEAD(2), | ||
292 | 0x0, 0x07, TLV_DB_SCALE_ITEM(TLV_DB_GAIN_MUTE, 0, 1), | ||
293 | /* -78dB to 12dB */ | ||
294 | 0x08, 0x7f, TLV_DB_SCALE_ITEM(-7800, 75, 0) | ||
295 | }; | ||
296 | |||
297 | static const unsigned int alc_analog_gain_tlv[] = { | ||
298 | TLV_DB_RANGE_HEAD(2), | ||
299 | 0x0, 0x0, TLV_DB_SCALE_ITEM(TLV_DB_GAIN_MUTE, 0, 1), | ||
300 | /* 0dB to 36dB */ | ||
301 | 0x01, 0x07, TLV_DB_SCALE_ITEM(0, 600, 0) | ||
302 | }; | ||
303 | |||
304 | static const DECLARE_TLV_DB_SCALE(mic_vol_tlv, -600, 600, 0); | ||
305 | static const DECLARE_TLV_DB_SCALE(mixin_gain_tlv, -450, 150, 0); | ||
306 | static const DECLARE_TLV_DB_SCALE(eq_gain_tlv, -1050, 150, 0); | ||
307 | static const DECLARE_TLV_DB_SCALE(hp_vol_tlv, -5700, 100, 0); | ||
308 | static const DECLARE_TLV_DB_SCALE(lineout_vol_tlv, -4800, 100, 0); | ||
309 | static const DECLARE_TLV_DB_SCALE(alc_threshold_tlv, -9450, 150, 0); | ||
310 | static const DECLARE_TLV_DB_SCALE(alc_gain_tlv, 0, 600, 0); | ||
311 | |||
312 | /* ADC and DAC high pass filter cutoff value */ | ||
313 | static const char * const da9055_hpf_cutoff_txt[] = { | ||
314 | "Fs/24000", "Fs/12000", "Fs/6000", "Fs/3000" | ||
315 | }; | ||
316 | |||
317 | static const struct soc_enum da9055_dac_hpf_cutoff = | ||
318 | SOC_ENUM_SINGLE(DA9055_DAC_FILTERS1, 4, 4, da9055_hpf_cutoff_txt); | ||
319 | |||
320 | static const struct soc_enum da9055_adc_hpf_cutoff = | ||
321 | SOC_ENUM_SINGLE(DA9055_ADC_FILTERS1, 4, 4, da9055_hpf_cutoff_txt); | ||
322 | |||
323 | /* ADC and DAC voice mode (8kHz) high pass cutoff value */ | ||
324 | static const char * const da9055_vf_cutoff_txt[] = { | ||
325 | "2.5Hz", "25Hz", "50Hz", "100Hz", "150Hz", "200Hz", "300Hz", "400Hz" | ||
326 | }; | ||
327 | |||
328 | static const struct soc_enum da9055_dac_vf_cutoff = | ||
329 | SOC_ENUM_SINGLE(DA9055_DAC_FILTERS1, 0, 8, da9055_vf_cutoff_txt); | ||
330 | |||
331 | static const struct soc_enum da9055_adc_vf_cutoff = | ||
332 | SOC_ENUM_SINGLE(DA9055_ADC_FILTERS1, 0, 8, da9055_vf_cutoff_txt); | ||
333 | |||
334 | /* Gain ramping rate value */ | ||
335 | static const char * const da9055_gain_ramping_txt[] = { | ||
336 | "nominal rate", "nominal rate * 4", "nominal rate * 8", | ||
337 | "nominal rate / 8" | ||
338 | }; | ||
339 | |||
340 | static const struct soc_enum da9055_gain_ramping_rate = | ||
341 | SOC_ENUM_SINGLE(DA9055_GAIN_RAMP_CTRL, 0, 4, da9055_gain_ramping_txt); | ||
342 | |||
343 | /* DAC noise gate setup time value */ | ||
344 | static const char * const da9055_dac_ng_setup_time_txt[] = { | ||
345 | "256 samples", "512 samples", "1024 samples", "2048 samples" | ||
346 | }; | ||
347 | |||
348 | static const struct soc_enum da9055_dac_ng_setup_time = | ||
349 | SOC_ENUM_SINGLE(DA9055_DAC_NG_SETUP_TIME, 0, 4, | ||
350 | da9055_dac_ng_setup_time_txt); | ||
351 | |||
352 | /* DAC noise gate rampup rate value */ | ||
353 | static const char * const da9055_dac_ng_rampup_txt[] = { | ||
354 | "0.02 ms/dB", "0.16 ms/dB" | ||
355 | }; | ||
356 | |||
357 | static const struct soc_enum da9055_dac_ng_rampup_rate = | ||
358 | SOC_ENUM_SINGLE(DA9055_DAC_NG_SETUP_TIME, 2, 2, | ||
359 | da9055_dac_ng_rampup_txt); | ||
360 | |||
361 | /* DAC noise gate rampdown rate value */ | ||
362 | static const char * const da9055_dac_ng_rampdown_txt[] = { | ||
363 | "0.64 ms/dB", "20.48 ms/dB" | ||
364 | }; | ||
365 | |||
366 | static const struct soc_enum da9055_dac_ng_rampdown_rate = | ||
367 | SOC_ENUM_SINGLE(DA9055_DAC_NG_SETUP_TIME, 3, 2, | ||
368 | da9055_dac_ng_rampdown_txt); | ||
369 | |||
370 | /* DAC soft mute rate value */ | ||
371 | static const char * const da9055_dac_soft_mute_rate_txt[] = { | ||
372 | "1", "2", "4", "8", "16", "32", "64" | ||
373 | }; | ||
374 | |||
375 | static const struct soc_enum da9055_dac_soft_mute_rate = | ||
376 | SOC_ENUM_SINGLE(DA9055_DAC_FILTERS5, 4, 7, | ||
377 | da9055_dac_soft_mute_rate_txt); | ||
378 | |||
379 | /* DAC routing select */ | ||
380 | static const char * const da9055_dac_src_txt[] = { | ||
381 | "ADC output left", "ADC output right", "AIF input left", | ||
382 | "AIF input right" | ||
383 | }; | ||
384 | |||
385 | static const struct soc_enum da9055_dac_l_src = | ||
386 | SOC_ENUM_SINGLE(DA9055_DIG_ROUTING_DAC, 0, 4, da9055_dac_src_txt); | ||
387 | |||
388 | static const struct soc_enum da9055_dac_r_src = | ||
389 | SOC_ENUM_SINGLE(DA9055_DIG_ROUTING_DAC, 4, 4, da9055_dac_src_txt); | ||
390 | |||
391 | /* MIC PGA Left source select */ | ||
392 | static const char * const da9055_mic_l_src_txt[] = { | ||
393 | "MIC1_P_N", "MIC1_P", "MIC1_N", "MIC2_L" | ||
394 | }; | ||
395 | |||
396 | static const struct soc_enum da9055_mic_l_src = | ||
397 | SOC_ENUM_SINGLE(DA9055_MIXIN_L_SELECT, 4, 4, da9055_mic_l_src_txt); | ||
398 | |||
399 | /* MIC PGA Right source select */ | ||
400 | static const char * const da9055_mic_r_src_txt[] = { | ||
401 | "MIC2_R_L", "MIC2_R", "MIC2_L" | ||
402 | }; | ||
403 | |||
404 | static const struct soc_enum da9055_mic_r_src = | ||
405 | SOC_ENUM_SINGLE(DA9055_MIXIN_R_SELECT, 4, 3, da9055_mic_r_src_txt); | ||
406 | |||
407 | /* ALC Input Signal Tracking rate select */ | ||
408 | static const char * const da9055_signal_tracking_rate_txt[] = { | ||
409 | "1/4", "1/16", "1/256", "1/65536" | ||
410 | }; | ||
411 | |||
412 | static const struct soc_enum da9055_integ_attack_rate = | ||
413 | SOC_ENUM_SINGLE(DA9055_ALC_CTRL3, 4, 4, | ||
414 | da9055_signal_tracking_rate_txt); | ||
415 | |||
416 | static const struct soc_enum da9055_integ_release_rate = | ||
417 | SOC_ENUM_SINGLE(DA9055_ALC_CTRL3, 6, 4, | ||
418 | da9055_signal_tracking_rate_txt); | ||
419 | |||
420 | /* ALC Attack Rate select */ | ||
421 | static const char * const da9055_attack_rate_txt[] = { | ||
422 | "44/fs", "88/fs", "176/fs", "352/fs", "704/fs", "1408/fs", "2816/fs", | ||
423 | "5632/fs", "11264/fs", "22528/fs", "45056/fs", "90112/fs", "180224/fs" | ||
424 | }; | ||
425 | |||
426 | static const struct soc_enum da9055_attack_rate = | ||
427 | SOC_ENUM_SINGLE(DA9055_ALC_CTRL2, 0, 13, da9055_attack_rate_txt); | ||
428 | |||
429 | /* ALC Release Rate select */ | ||
430 | static const char * const da9055_release_rate_txt[] = { | ||
431 | "176/fs", "352/fs", "704/fs", "1408/fs", "2816/fs", "5632/fs", | ||
432 | "11264/fs", "22528/fs", "45056/fs", "90112/fs", "180224/fs" | ||
433 | }; | ||
434 | |||
435 | static const struct soc_enum da9055_release_rate = | ||
436 | SOC_ENUM_SINGLE(DA9055_ALC_CTRL2, 4, 11, da9055_release_rate_txt); | ||
437 | |||
438 | /* ALC Hold Time select */ | ||
439 | static const char * const da9055_hold_time_txt[] = { | ||
440 | "62/fs", "124/fs", "248/fs", "496/fs", "992/fs", "1984/fs", "3968/fs", | ||
441 | "7936/fs", "15872/fs", "31744/fs", "63488/fs", "126976/fs", | ||
442 | "253952/fs", "507904/fs", "1015808/fs", "2031616/fs" | ||
443 | }; | ||
444 | |||
445 | static const struct soc_enum da9055_hold_time = | ||
446 | SOC_ENUM_SINGLE(DA9055_ALC_CTRL3, 0, 16, da9055_hold_time_txt); | ||
447 | |||
448 | static int da9055_get_alc_data(struct snd_soc_codec *codec, u8 reg_val) | ||
449 | { | ||
450 | int mid_data, top_data; | ||
451 | int sum = 0; | ||
452 | u8 iteration; | ||
453 | |||
454 | for (iteration = 0; iteration < DA9055_ALC_AVG_ITERATIONS; | ||
455 | iteration++) { | ||
456 | /* Select the left or right channel and capture data */ | ||
457 | snd_soc_write(codec, DA9055_ALC_CIC_OP_LVL_CTRL, reg_val); | ||
458 | |||
459 | /* Select middle 8 bits for read back from data register */ | ||
460 | snd_soc_write(codec, DA9055_ALC_CIC_OP_LVL_CTRL, | ||
461 | reg_val | DA9055_ALC_DATA_MIDDLE); | ||
462 | mid_data = snd_soc_read(codec, DA9055_ALC_CIC_OP_LVL_DATA); | ||
463 | |||
464 | /* Select top 8 bits for read back from data register */ | ||
465 | snd_soc_write(codec, DA9055_ALC_CIC_OP_LVL_CTRL, | ||
466 | reg_val | DA9055_ALC_DATA_TOP); | ||
467 | top_data = snd_soc_read(codec, DA9055_ALC_CIC_OP_LVL_DATA); | ||
468 | |||
469 | sum += ((mid_data << 8) | (top_data << 16)); | ||
470 | } | ||
471 | |||
472 | return sum / DA9055_ALC_AVG_ITERATIONS; | ||
473 | } | ||
474 | |||
475 | static int da9055_put_alc_sw(struct snd_kcontrol *kcontrol, | ||
476 | struct snd_ctl_elem_value *ucontrol) | ||
477 | { | ||
478 | struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); | ||
479 | u8 reg_val, adc_left, adc_right; | ||
480 | int avg_left_data, avg_right_data, offset_l, offset_r; | ||
481 | |||
482 | if (ucontrol->value.integer.value[0]) { | ||
483 | /* | ||
484 | * While enabling ALC (or ALC sync mode), calibration of the DC | ||
485 | * offsets must be done first | ||
486 | */ | ||
487 | |||
488 | /* Save current values from ADC control registers */ | ||
489 | adc_left = snd_soc_read(codec, DA9055_ADC_L_CTRL); | ||
490 | adc_right = snd_soc_read(codec, DA9055_ADC_R_CTRL); | ||
491 | |||
492 | /* Enable ADC Left and Right */ | ||
493 | snd_soc_update_bits(codec, DA9055_ADC_L_CTRL, | ||
494 | DA9055_ADC_L_EN, DA9055_ADC_L_EN); | ||
495 | snd_soc_update_bits(codec, DA9055_ADC_R_CTRL, | ||
496 | DA9055_ADC_R_EN, DA9055_ADC_R_EN); | ||
497 | |||
498 | /* Calculate average for Left and Right data */ | ||
499 | /* Left Data */ | ||
500 | avg_left_data = da9055_get_alc_data(codec, | ||
501 | DA9055_ALC_CIC_OP_CHANNEL_LEFT); | ||
502 | /* Right Data */ | ||
503 | avg_right_data = da9055_get_alc_data(codec, | ||
504 | DA9055_ALC_CIC_OP_CHANNEL_RIGHT); | ||
505 | |||
506 | /* Calculate DC offset */ | ||
507 | offset_l = -avg_left_data; | ||
508 | offset_r = -avg_right_data; | ||
509 | |||
510 | reg_val = (offset_l & DA9055_ALC_OFFSET_15_8) >> 8; | ||
511 | snd_soc_write(codec, DA9055_ALC_OFFSET_OP2M_L, reg_val); | ||
512 | reg_val = (offset_l & DA9055_ALC_OFFSET_17_16) >> 16; | ||
513 | snd_soc_write(codec, DA9055_ALC_OFFSET_OP2U_L, reg_val); | ||
514 | |||
515 | reg_val = (offset_r & DA9055_ALC_OFFSET_15_8) >> 8; | ||
516 | snd_soc_write(codec, DA9055_ALC_OFFSET_OP2M_R, reg_val); | ||
517 | reg_val = (offset_r & DA9055_ALC_OFFSET_17_16) >> 16; | ||
518 | snd_soc_write(codec, DA9055_ALC_OFFSET_OP2U_R, reg_val); | ||
519 | |||
520 | /* Restore original values of ADC control registers */ | ||
521 | snd_soc_write(codec, DA9055_ADC_L_CTRL, adc_left); | ||
522 | snd_soc_write(codec, DA9055_ADC_R_CTRL, adc_right); | ||
523 | } | ||
524 | |||
525 | return snd_soc_put_volsw(kcontrol, ucontrol); | ||
526 | } | ||
527 | |||
528 | static const struct snd_kcontrol_new da9055_snd_controls[] = { | ||
529 | |||
530 | /* Volume controls */ | ||
531 | SOC_DOUBLE_R_TLV("Mic Volume", | ||
532 | DA9055_MIC_L_GAIN, DA9055_MIC_R_GAIN, | ||
533 | 0, 0x7, 0, mic_vol_tlv), | ||
534 | SOC_DOUBLE_R_TLV("Aux Volume", | ||
535 | DA9055_AUX_L_GAIN, DA9055_AUX_R_GAIN, | ||
536 | 0, 0x3f, 0, aux_vol_tlv), | ||
537 | SOC_DOUBLE_R_TLV("Mixin PGA Volume", | ||
538 | DA9055_MIXIN_L_GAIN, DA9055_MIXIN_R_GAIN, | ||
539 | 0, 0xf, 0, mixin_gain_tlv), | ||
540 | SOC_DOUBLE_R_TLV("ADC Volume", | ||
541 | DA9055_ADC_L_GAIN, DA9055_ADC_R_GAIN, | ||
542 | 0, 0x7f, 0, digital_gain_tlv), | ||
543 | |||
544 | SOC_DOUBLE_R_TLV("DAC Volume", | ||
545 | DA9055_DAC_L_GAIN, DA9055_DAC_R_GAIN, | ||
546 | 0, 0x7f, 0, digital_gain_tlv), | ||
547 | SOC_DOUBLE_R_TLV("Headphone Volume", | ||
548 | DA9055_HP_L_GAIN, DA9055_HP_R_GAIN, | ||
549 | 0, 0x3f, 0, hp_vol_tlv), | ||
550 | SOC_SINGLE_TLV("Lineout Volume", DA9055_LINE_GAIN, 0, 0x3f, 0, | ||
551 | lineout_vol_tlv), | ||
552 | |||
553 | /* DAC Equalizer controls */ | ||
554 | SOC_SINGLE("DAC EQ Switch", DA9055_DAC_FILTERS4, 7, 1, 0), | ||
555 | SOC_SINGLE_TLV("DAC EQ1 Volume", DA9055_DAC_FILTERS2, 0, 0xf, 0, | ||
556 | eq_gain_tlv), | ||
557 | SOC_SINGLE_TLV("DAC EQ2 Volume", DA9055_DAC_FILTERS2, 4, 0xf, 0, | ||
558 | eq_gain_tlv), | ||
559 | SOC_SINGLE_TLV("DAC EQ3 Volume", DA9055_DAC_FILTERS3, 0, 0xf, 0, | ||
560 | eq_gain_tlv), | ||
561 | SOC_SINGLE_TLV("DAC EQ4 Volume", DA9055_DAC_FILTERS3, 4, 0xf, 0, | ||
562 | eq_gain_tlv), | ||
563 | SOC_SINGLE_TLV("DAC EQ5 Volume", DA9055_DAC_FILTERS4, 0, 0xf, 0, | ||
564 | eq_gain_tlv), | ||
565 | |||
566 | /* High Pass Filter and Voice Mode controls */ | ||
567 | SOC_SINGLE("ADC HPF Switch", DA9055_ADC_FILTERS1, 7, 1, 0), | ||
568 | SOC_ENUM("ADC HPF Cutoff", da9055_adc_hpf_cutoff), | ||
569 | SOC_SINGLE("ADC Voice Mode Switch", DA9055_ADC_FILTERS1, 3, 1, 0), | ||
570 | SOC_ENUM("ADC Voice Cutoff", da9055_adc_vf_cutoff), | ||
571 | |||
572 | SOC_SINGLE("DAC HPF Switch", DA9055_DAC_FILTERS1, 7, 1, 0), | ||
573 | SOC_ENUM("DAC HPF Cutoff", da9055_dac_hpf_cutoff), | ||
574 | SOC_SINGLE("DAC Voice Mode Switch", DA9055_DAC_FILTERS1, 3, 1, 0), | ||
575 | SOC_ENUM("DAC Voice Cutoff", da9055_dac_vf_cutoff), | ||
576 | |||
577 | /* Mute controls */ | ||
578 | SOC_DOUBLE_R("Mic Switch", DA9055_MIC_L_CTRL, | ||
579 | DA9055_MIC_R_CTRL, 6, 1, 0), | ||
580 | SOC_DOUBLE_R("Aux Switch", DA9055_AUX_L_CTRL, | ||
581 | DA9055_AUX_R_CTRL, 6, 1, 0), | ||
582 | SOC_DOUBLE_R("Mixin PGA Switch", DA9055_MIXIN_L_CTRL, | ||
583 | DA9055_MIXIN_R_CTRL, 6, 1, 0), | ||
584 | SOC_DOUBLE_R("ADC Switch", DA9055_ADC_L_CTRL, | ||
585 | DA9055_ADC_R_CTRL, 6, 1, 0), | ||
586 | SOC_DOUBLE_R("Headphone Switch", DA9055_HP_L_CTRL, | ||
587 | DA9055_HP_R_CTRL, 6, 1, 0), | ||
588 | SOC_SINGLE("Lineout Switch", DA9055_LINE_CTRL, 6, 1, 0), | ||
589 | SOC_SINGLE("DAC Soft Mute Switch", DA9055_DAC_FILTERS5, 7, 1, 0), | ||
590 | SOC_ENUM("DAC Soft Mute Rate", da9055_dac_soft_mute_rate), | ||
591 | |||
592 | /* Zero Cross controls */ | ||
593 | SOC_DOUBLE_R("Aux ZC Switch", DA9055_AUX_L_CTRL, | ||
594 | DA9055_AUX_R_CTRL, 4, 1, 0), | ||
595 | SOC_DOUBLE_R("Mixin PGA ZC Switch", DA9055_MIXIN_L_CTRL, | ||
596 | DA9055_MIXIN_R_CTRL, 4, 1, 0), | ||
597 | SOC_DOUBLE_R("Headphone ZC Switch", DA9055_HP_L_CTRL, | ||
598 | DA9055_HP_R_CTRL, 4, 1, 0), | ||
599 | SOC_SINGLE("Lineout ZC Switch", DA9055_LINE_CTRL, 4, 1, 0), | ||
600 | |||
601 | /* Gain Ramping controls */ | ||
602 | SOC_DOUBLE_R("Aux Gain Ramping Switch", DA9055_AUX_L_CTRL, | ||
603 | DA9055_AUX_R_CTRL, 5, 1, 0), | ||
604 | SOC_DOUBLE_R("Mixin Gain Ramping Switch", DA9055_MIXIN_L_CTRL, | ||
605 | DA9055_MIXIN_R_CTRL, 5, 1, 0), | ||
606 | SOC_DOUBLE_R("ADC Gain Ramping Switch", DA9055_ADC_L_CTRL, | ||
607 | DA9055_ADC_R_CTRL, 5, 1, 0), | ||
608 | SOC_DOUBLE_R("DAC Gain Ramping Switch", DA9055_DAC_L_CTRL, | ||
609 | DA9055_DAC_R_CTRL, 5, 1, 0), | ||
610 | SOC_DOUBLE_R("Headphone Gain Ramping Switch", DA9055_HP_L_CTRL, | ||
611 | DA9055_HP_R_CTRL, 5, 1, 0), | ||
612 | SOC_SINGLE("Lineout Gain Ramping Switch", DA9055_LINE_CTRL, 5, 1, 0), | ||
613 | SOC_ENUM("Gain Ramping Rate", da9055_gain_ramping_rate), | ||
614 | |||
615 | /* DAC Noise Gate controls */ | ||
616 | SOC_SINGLE("DAC NG Switch", DA9055_DAC_NG_CTRL, 7, 1, 0), | ||
617 | SOC_SINGLE("DAC NG ON Threshold", DA9055_DAC_NG_ON_THRESHOLD, | ||
618 | 0, 0x7, 0), | ||
619 | SOC_SINGLE("DAC NG OFF Threshold", DA9055_DAC_NG_OFF_THRESHOLD, | ||
620 | 0, 0x7, 0), | ||
621 | SOC_ENUM("DAC NG Setup Time", da9055_dac_ng_setup_time), | ||
622 | SOC_ENUM("DAC NG Rampup Rate", da9055_dac_ng_rampup_rate), | ||
623 | SOC_ENUM("DAC NG Rampdown Rate", da9055_dac_ng_rampdown_rate), | ||
624 | |||
625 | /* DAC Invertion control */ | ||
626 | SOC_SINGLE("DAC Left Invert", DA9055_DIG_CTRL, 3, 1, 0), | ||
627 | SOC_SINGLE("DAC Right Invert", DA9055_DIG_CTRL, 7, 1, 0), | ||
628 | |||
629 | /* DMIC controls */ | ||
630 | SOC_DOUBLE_R("DMIC Switch", DA9055_MIXIN_L_SELECT, | ||
631 | DA9055_MIXIN_R_SELECT, 7, 1, 0), | ||
632 | |||
633 | /* ALC Controls */ | ||
634 | SOC_DOUBLE_EXT("ALC Switch", DA9055_ALC_CTRL1, 3, 7, 1, 0, | ||
635 | snd_soc_get_volsw, da9055_put_alc_sw), | ||
636 | SOC_SINGLE_EXT("ALC Sync Mode Switch", DA9055_ALC_CTRL1, 1, 1, 0, | ||
637 | snd_soc_get_volsw, da9055_put_alc_sw), | ||
638 | SOC_SINGLE("ALC Offset Switch", DA9055_ALC_CTRL1, 0, 1, 0), | ||
639 | SOC_SINGLE("ALC Anticlip Mode Switch", DA9055_ALC_ANTICLIP_CTRL, | ||
640 | 7, 1, 0), | ||
641 | SOC_SINGLE("ALC Anticlip Level", DA9055_ALC_ANTICLIP_LEVEL, | ||
642 | 0, 0x7f, 0), | ||
643 | SOC_SINGLE_TLV("ALC Min Threshold Volume", DA9055_ALC_TARGET_MIN, | ||
644 | 0, 0x3f, 1, alc_threshold_tlv), | ||
645 | SOC_SINGLE_TLV("ALC Max Threshold Volume", DA9055_ALC_TARGET_MAX, | ||
646 | 0, 0x3f, 1, alc_threshold_tlv), | ||
647 | SOC_SINGLE_TLV("ALC Noise Threshold Volume", DA9055_ALC_NOISE, | ||
648 | 0, 0x3f, 1, alc_threshold_tlv), | ||
649 | SOC_SINGLE_TLV("ALC Max Gain Volume", DA9055_ALC_GAIN_LIMITS, | ||
650 | 4, 0xf, 0, alc_gain_tlv), | ||
651 | SOC_SINGLE_TLV("ALC Max Attenuation Volume", DA9055_ALC_GAIN_LIMITS, | ||
652 | 0, 0xf, 0, alc_gain_tlv), | ||
653 | SOC_SINGLE_TLV("ALC Min Analog Gain Volume", | ||
654 | DA9055_ALC_ANA_GAIN_LIMITS, | ||
655 | 0, 0x7, 0, alc_analog_gain_tlv), | ||
656 | SOC_SINGLE_TLV("ALC Max Analog Gain Volume", | ||
657 | DA9055_ALC_ANA_GAIN_LIMITS, | ||
658 | 4, 0x7, 0, alc_analog_gain_tlv), | ||
659 | SOC_ENUM("ALC Attack Rate", da9055_attack_rate), | ||
660 | SOC_ENUM("ALC Release Rate", da9055_release_rate), | ||
661 | SOC_ENUM("ALC Hold Time", da9055_hold_time), | ||
662 | /* | ||
663 | * Rate at which input signal envelope is tracked as the signal gets | ||
664 | * larger | ||
665 | */ | ||
666 | SOC_ENUM("ALC Integ Attack Rate", da9055_integ_attack_rate), | ||
667 | /* | ||
668 | * Rate at which input signal envelope is tracked as the signal gets | ||
669 | * smaller | ||
670 | */ | ||
671 | SOC_ENUM("ALC Integ Release Rate", da9055_integ_release_rate), | ||
672 | }; | ||
673 | |||
674 | /* DAPM Controls */ | ||
675 | |||
676 | /* Mic PGA Left Source */ | ||
677 | static const struct snd_kcontrol_new da9055_mic_l_mux_controls = | ||
678 | SOC_DAPM_ENUM("Route", da9055_mic_l_src); | ||
679 | |||
680 | /* Mic PGA Right Source */ | ||
681 | static const struct snd_kcontrol_new da9055_mic_r_mux_controls = | ||
682 | SOC_DAPM_ENUM("Route", da9055_mic_r_src); | ||
683 | |||
684 | /* In Mixer Left */ | ||
685 | static const struct snd_kcontrol_new da9055_dapm_mixinl_controls[] = { | ||
686 | SOC_DAPM_SINGLE("Aux Left Switch", DA9055_MIXIN_L_SELECT, 0, 1, 0), | ||
687 | SOC_DAPM_SINGLE("Mic Left Switch", DA9055_MIXIN_L_SELECT, 1, 1, 0), | ||
688 | SOC_DAPM_SINGLE("Mic Right Switch", DA9055_MIXIN_L_SELECT, 2, 1, 0), | ||
689 | }; | ||
690 | |||
691 | /* In Mixer Right */ | ||
692 | static const struct snd_kcontrol_new da9055_dapm_mixinr_controls[] = { | ||
693 | SOC_DAPM_SINGLE("Aux Right Switch", DA9055_MIXIN_R_SELECT, 0, 1, 0), | ||
694 | SOC_DAPM_SINGLE("Mic Right Switch", DA9055_MIXIN_R_SELECT, 1, 1, 0), | ||
695 | SOC_DAPM_SINGLE("Mic Left Switch", DA9055_MIXIN_R_SELECT, 2, 1, 0), | ||
696 | SOC_DAPM_SINGLE("Mixin Left Switch", DA9055_MIXIN_R_SELECT, 3, 1, 0), | ||
697 | }; | ||
698 | |||
699 | /* DAC Left Source */ | ||
700 | static const struct snd_kcontrol_new da9055_dac_l_mux_controls = | ||
701 | SOC_DAPM_ENUM("Route", da9055_dac_l_src); | ||
702 | |||
703 | /* DAC Right Source */ | ||
704 | static const struct snd_kcontrol_new da9055_dac_r_mux_controls = | ||
705 | SOC_DAPM_ENUM("Route", da9055_dac_r_src); | ||
706 | |||
707 | /* Out Mixer Left */ | ||
708 | static const struct snd_kcontrol_new da9055_dapm_mixoutl_controls[] = { | ||
709 | SOC_DAPM_SINGLE("Aux Left Switch", DA9055_MIXOUT_L_SELECT, 0, 1, 0), | ||
710 | SOC_DAPM_SINGLE("Mixin Left Switch", DA9055_MIXOUT_L_SELECT, 1, 1, 0), | ||
711 | SOC_DAPM_SINGLE("Mixin Right Switch", DA9055_MIXOUT_L_SELECT, 2, 1, 0), | ||
712 | SOC_DAPM_SINGLE("DAC Left Switch", DA9055_MIXOUT_L_SELECT, 3, 1, 0), | ||
713 | SOC_DAPM_SINGLE("Aux Left Invert Switch", DA9055_MIXOUT_L_SELECT, | ||
714 | 4, 1, 0), | ||
715 | SOC_DAPM_SINGLE("Mixin Left Invert Switch", DA9055_MIXOUT_L_SELECT, | ||
716 | 5, 1, 0), | ||
717 | SOC_DAPM_SINGLE("Mixin Right Invert Switch", DA9055_MIXOUT_L_SELECT, | ||
718 | 6, 1, 0), | ||
719 | }; | ||
720 | |||
721 | /* Out Mixer Right */ | ||
722 | static const struct snd_kcontrol_new da9055_dapm_mixoutr_controls[] = { | ||
723 | SOC_DAPM_SINGLE("Aux Right Switch", DA9055_MIXOUT_R_SELECT, 0, 1, 0), | ||
724 | SOC_DAPM_SINGLE("Mixin Right Switch", DA9055_MIXOUT_R_SELECT, 1, 1, 0), | ||
725 | SOC_DAPM_SINGLE("Mixin Left Switch", DA9055_MIXOUT_R_SELECT, 2, 1, 0), | ||
726 | SOC_DAPM_SINGLE("DAC Right Switch", DA9055_MIXOUT_R_SELECT, 3, 1, 0), | ||
727 | SOC_DAPM_SINGLE("Aux Right Invert Switch", DA9055_MIXOUT_R_SELECT, | ||
728 | 4, 1, 0), | ||
729 | SOC_DAPM_SINGLE("Mixin Right Invert Switch", DA9055_MIXOUT_R_SELECT, | ||
730 | 5, 1, 0), | ||
731 | SOC_DAPM_SINGLE("Mixin Left Invert Switch", DA9055_MIXOUT_R_SELECT, | ||
732 | 6, 1, 0), | ||
733 | }; | ||
734 | |||
735 | /* DAPM widgets */ | ||
736 | static const struct snd_soc_dapm_widget da9055_dapm_widgets[] = { | ||
737 | /* Input Side */ | ||
738 | |||
739 | /* Input Lines */ | ||
740 | SND_SOC_DAPM_INPUT("MIC1"), | ||
741 | SND_SOC_DAPM_INPUT("MIC2"), | ||
742 | SND_SOC_DAPM_INPUT("AUXL"), | ||
743 | SND_SOC_DAPM_INPUT("AUXR"), | ||
744 | |||
745 | /* MUXs for Mic PGA source selection */ | ||
746 | SND_SOC_DAPM_MUX("Mic Left Source", SND_SOC_NOPM, 0, 0, | ||
747 | &da9055_mic_l_mux_controls), | ||
748 | SND_SOC_DAPM_MUX("Mic Right Source", SND_SOC_NOPM, 0, 0, | ||
749 | &da9055_mic_r_mux_controls), | ||
750 | |||
751 | /* Input PGAs */ | ||
752 | SND_SOC_DAPM_PGA("Mic Left", DA9055_MIC_L_CTRL, 7, 0, NULL, 0), | ||
753 | SND_SOC_DAPM_PGA("Mic Right", DA9055_MIC_R_CTRL, 7, 0, NULL, 0), | ||
754 | SND_SOC_DAPM_PGA("Aux Left", DA9055_AUX_L_CTRL, 7, 0, NULL, 0), | ||
755 | SND_SOC_DAPM_PGA("Aux Right", DA9055_AUX_R_CTRL, 7, 0, NULL, 0), | ||
756 | SND_SOC_DAPM_PGA("MIXIN Left", DA9055_MIXIN_L_CTRL, 7, 0, NULL, 0), | ||
757 | SND_SOC_DAPM_PGA("MIXIN Right", DA9055_MIXIN_R_CTRL, 7, 0, NULL, 0), | ||
758 | |||
759 | SND_SOC_DAPM_SUPPLY("Mic Bias", DA9055_MIC_BIAS_CTRL, 7, 0, NULL, 0), | ||
760 | SND_SOC_DAPM_SUPPLY("AIF", DA9055_AIF_CTRL, 7, 0, NULL, 0), | ||
761 | SND_SOC_DAPM_SUPPLY("Charge Pump", DA9055_CP_CTRL, 7, 0, NULL, 0), | ||
762 | |||
763 | /* Input Mixers */ | ||
764 | SND_SOC_DAPM_MIXER("In Mixer Left", SND_SOC_NOPM, 0, 0, | ||
765 | &da9055_dapm_mixinl_controls[0], | ||
766 | ARRAY_SIZE(da9055_dapm_mixinl_controls)), | ||
767 | SND_SOC_DAPM_MIXER("In Mixer Right", SND_SOC_NOPM, 0, 0, | ||
768 | &da9055_dapm_mixinr_controls[0], | ||
769 | ARRAY_SIZE(da9055_dapm_mixinr_controls)), | ||
770 | |||
771 | /* ADCs */ | ||
772 | SND_SOC_DAPM_ADC("ADC Left", "Capture", DA9055_ADC_L_CTRL, 7, 0), | ||
773 | SND_SOC_DAPM_ADC("ADC Right", "Capture", DA9055_ADC_R_CTRL, 7, 0), | ||
774 | |||
775 | /* Output Side */ | ||
776 | |||
777 | /* MUXs for DAC source selection */ | ||
778 | SND_SOC_DAPM_MUX("DAC Left Source", SND_SOC_NOPM, 0, 0, | ||
779 | &da9055_dac_l_mux_controls), | ||
780 | SND_SOC_DAPM_MUX("DAC Right Source", SND_SOC_NOPM, 0, 0, | ||
781 | &da9055_dac_r_mux_controls), | ||
782 | |||
783 | /* AIF input */ | ||
784 | SND_SOC_DAPM_AIF_IN("AIFIN Left", "Playback", 0, SND_SOC_NOPM, 0, 0), | ||
785 | SND_SOC_DAPM_AIF_IN("AIFIN Right", "Playback", 0, SND_SOC_NOPM, 0, 0), | ||
786 | |||
787 | /* DACs */ | ||
788 | SND_SOC_DAPM_DAC("DAC Left", "Playback", DA9055_DAC_L_CTRL, 7, 0), | ||
789 | SND_SOC_DAPM_DAC("DAC Right", "Playback", DA9055_DAC_R_CTRL, 7, 0), | ||
790 | |||
791 | /* Output Mixers */ | ||
792 | SND_SOC_DAPM_MIXER("Out Mixer Left", SND_SOC_NOPM, 0, 0, | ||
793 | &da9055_dapm_mixoutl_controls[0], | ||
794 | ARRAY_SIZE(da9055_dapm_mixoutl_controls)), | ||
795 | SND_SOC_DAPM_MIXER("Out Mixer Right", SND_SOC_NOPM, 0, 0, | ||
796 | &da9055_dapm_mixoutr_controls[0], | ||
797 | ARRAY_SIZE(da9055_dapm_mixoutr_controls)), | ||
798 | |||
799 | /* Output PGAs */ | ||
800 | SND_SOC_DAPM_PGA("MIXOUT Left", DA9055_MIXOUT_L_CTRL, 7, 0, NULL, 0), | ||
801 | SND_SOC_DAPM_PGA("MIXOUT Right", DA9055_MIXOUT_R_CTRL, 7, 0, NULL, 0), | ||
802 | SND_SOC_DAPM_PGA("Lineout", DA9055_LINE_CTRL, 7, 0, NULL, 0), | ||
803 | SND_SOC_DAPM_PGA("Headphone Left", DA9055_HP_L_CTRL, 7, 0, NULL, 0), | ||
804 | SND_SOC_DAPM_PGA("Headphone Right", DA9055_HP_R_CTRL, 7, 0, NULL, 0), | ||
805 | |||
806 | /* Output Lines */ | ||
807 | SND_SOC_DAPM_OUTPUT("HPL"), | ||
808 | SND_SOC_DAPM_OUTPUT("HPR"), | ||
809 | SND_SOC_DAPM_OUTPUT("LINE"), | ||
810 | }; | ||
811 | |||
812 | /* DAPM audio route definition */ | ||
813 | static const struct snd_soc_dapm_route da9055_audio_map[] = { | ||
814 | /* Dest Connecting Widget source */ | ||
815 | |||
816 | /* Input path */ | ||
817 | {"Mic Left Source", "MIC1_P_N", "MIC1"}, | ||
818 | {"Mic Left Source", "MIC1_P", "MIC1"}, | ||
819 | {"Mic Left Source", "MIC1_N", "MIC1"}, | ||
820 | {"Mic Left Source", "MIC2_L", "MIC2"}, | ||
821 | |||
822 | {"Mic Right Source", "MIC2_R_L", "MIC2"}, | ||
823 | {"Mic Right Source", "MIC2_R", "MIC2"}, | ||
824 | {"Mic Right Source", "MIC2_L", "MIC2"}, | ||
825 | |||
826 | {"Mic Left", NULL, "Mic Left Source"}, | ||
827 | {"Mic Right", NULL, "Mic Right Source"}, | ||
828 | |||
829 | {"Aux Left", NULL, "AUXL"}, | ||
830 | {"Aux Right", NULL, "AUXR"}, | ||
831 | |||
832 | {"In Mixer Left", "Mic Left Switch", "Mic Left"}, | ||
833 | {"In Mixer Left", "Mic Right Switch", "Mic Right"}, | ||
834 | {"In Mixer Left", "Aux Left Switch", "Aux Left"}, | ||
835 | |||
836 | {"In Mixer Right", "Mic Right Switch", "Mic Right"}, | ||
837 | {"In Mixer Right", "Mic Left Switch", "Mic Left"}, | ||
838 | {"In Mixer Right", "Aux Right Switch", "Aux Right"}, | ||
839 | {"In Mixer Right", "Mixin Left Switch", "MIXIN Left"}, | ||
840 | |||
841 | {"MIXIN Left", NULL, "In Mixer Left"}, | ||
842 | {"ADC Left", NULL, "MIXIN Left"}, | ||
843 | |||
844 | {"MIXIN Right", NULL, "In Mixer Right"}, | ||
845 | {"ADC Right", NULL, "MIXIN Right"}, | ||
846 | |||
847 | {"ADC Left", NULL, "AIF"}, | ||
848 | {"ADC Right", NULL, "AIF"}, | ||
849 | |||
850 | /* Output path */ | ||
851 | {"AIFIN Left", NULL, "AIF"}, | ||
852 | {"AIFIN Right", NULL, "AIF"}, | ||
853 | |||
854 | {"DAC Left Source", "ADC output left", "ADC Left"}, | ||
855 | {"DAC Left Source", "ADC output right", "ADC Right"}, | ||
856 | {"DAC Left Source", "AIF input left", "AIFIN Left"}, | ||
857 | {"DAC Left Source", "AIF input right", "AIFIN Right"}, | ||
858 | |||
859 | {"DAC Right Source", "ADC output left", "ADC Left"}, | ||
860 | {"DAC Right Source", "ADC output right", "ADC Right"}, | ||
861 | {"DAC Right Source", "AIF input left", "AIFIN Left"}, | ||
862 | {"DAC Right Source", "AIF input right", "AIFIN Right"}, | ||
863 | |||
864 | {"DAC Left", NULL, "DAC Left Source"}, | ||
865 | {"DAC Right", NULL, "DAC Right Source"}, | ||
866 | |||
867 | {"Out Mixer Left", "Aux Left Switch", "Aux Left"}, | ||
868 | {"Out Mixer Left", "Mixin Left Switch", "MIXIN Left"}, | ||
869 | {"Out Mixer Left", "Mixin Right Switch", "MIXIN Right"}, | ||
870 | {"Out Mixer Left", "Aux Left Invert Switch", "Aux Left"}, | ||
871 | {"Out Mixer Left", "Mixin Left Invert Switch", "MIXIN Left"}, | ||
872 | {"Out Mixer Left", "Mixin Right Invert Switch", "MIXIN Right"}, | ||
873 | {"Out Mixer Left", "DAC Left Switch", "DAC Left"}, | ||
874 | |||
875 | {"Out Mixer Right", "Aux Right Switch", "Aux Right"}, | ||
876 | {"Out Mixer Right", "Mixin Right Switch", "MIXIN Right"}, | ||
877 | {"Out Mixer Right", "Mixin Left Switch", "MIXIN Left"}, | ||
878 | {"Out Mixer Right", "Aux Right Invert Switch", "Aux Right"}, | ||
879 | {"Out Mixer Right", "Mixin Right Invert Switch", "MIXIN Right"}, | ||
880 | {"Out Mixer Right", "Mixin Left Invert Switch", "MIXIN Left"}, | ||
881 | {"Out Mixer Right", "DAC Right Switch", "DAC Right"}, | ||
882 | |||
883 | {"MIXOUT Left", NULL, "Out Mixer Left"}, | ||
884 | {"Headphone Left", NULL, "MIXOUT Left"}, | ||
885 | {"Headphone Left", NULL, "Charge Pump"}, | ||
886 | {"HPL", NULL, "Headphone Left"}, | ||
887 | |||
888 | {"MIXOUT Right", NULL, "Out Mixer Right"}, | ||
889 | {"Headphone Right", NULL, "MIXOUT Right"}, | ||
890 | {"Headphone Right", NULL, "Charge Pump"}, | ||
891 | {"HPR", NULL, "Headphone Right"}, | ||
892 | |||
893 | {"MIXOUT Right", NULL, "Out Mixer Right"}, | ||
894 | {"Lineout", NULL, "MIXOUT Right"}, | ||
895 | {"LINE", NULL, "Lineout"}, | ||
896 | }; | ||
897 | |||
898 | /* Codec private data */ | ||
899 | struct da9055_priv { | ||
900 | struct regmap *regmap; | ||
901 | unsigned int mclk_rate; | ||
902 | int master; | ||
903 | struct da9055_platform_data *pdata; | ||
904 | }; | ||
905 | |||
906 | static struct reg_default da9055_reg_defaults[] = { | ||
907 | { 0x21, 0x10 }, | ||
908 | { 0x22, 0x0A }, | ||
909 | { 0x23, 0x00 }, | ||
910 | { 0x24, 0x00 }, | ||
911 | { 0x25, 0x00 }, | ||
912 | { 0x26, 0x00 }, | ||
913 | { 0x27, 0x0C }, | ||
914 | { 0x28, 0x01 }, | ||
915 | { 0x29, 0x08 }, | ||
916 | { 0x2A, 0x32 }, | ||
917 | { 0x2B, 0x00 }, | ||
918 | { 0x30, 0x35 }, | ||
919 | { 0x31, 0x35 }, | ||
920 | { 0x32, 0x00 }, | ||
921 | { 0x33, 0x00 }, | ||
922 | { 0x34, 0x03 }, | ||
923 | { 0x35, 0x03 }, | ||
924 | { 0x36, 0x6F }, | ||
925 | { 0x37, 0x6F }, | ||
926 | { 0x38, 0x80 }, | ||
927 | { 0x39, 0x01 }, | ||
928 | { 0x3A, 0x01 }, | ||
929 | { 0x40, 0x00 }, | ||
930 | { 0x41, 0x88 }, | ||
931 | { 0x42, 0x88 }, | ||
932 | { 0x43, 0x08 }, | ||
933 | { 0x44, 0x80 }, | ||
934 | { 0x45, 0x6F }, | ||
935 | { 0x46, 0x6F }, | ||
936 | { 0x47, 0x61 }, | ||
937 | { 0x48, 0x35 }, | ||
938 | { 0x49, 0x35 }, | ||
939 | { 0x4A, 0x35 }, | ||
940 | { 0x4B, 0x00 }, | ||
941 | { 0x4C, 0x00 }, | ||
942 | { 0x60, 0x44 }, | ||
943 | { 0x61, 0x44 }, | ||
944 | { 0x62, 0x00 }, | ||
945 | { 0x63, 0x40 }, | ||
946 | { 0x64, 0x40 }, | ||
947 | { 0x65, 0x40 }, | ||
948 | { 0x66, 0x40 }, | ||
949 | { 0x67, 0x40 }, | ||
950 | { 0x68, 0x40 }, | ||
951 | { 0x69, 0x48 }, | ||
952 | { 0x6A, 0x40 }, | ||
953 | { 0x6B, 0x41 }, | ||
954 | { 0x6C, 0x40 }, | ||
955 | { 0x6D, 0x40 }, | ||
956 | { 0x6E, 0x10 }, | ||
957 | { 0x6F, 0x10 }, | ||
958 | { 0x90, 0x80 }, | ||
959 | { 0x92, 0x02 }, | ||
960 | { 0x93, 0x00 }, | ||
961 | { 0x99, 0x00 }, | ||
962 | { 0x9A, 0x00 }, | ||
963 | { 0x9B, 0x00 }, | ||
964 | { 0x9C, 0x3F }, | ||
965 | { 0x9D, 0x00 }, | ||
966 | { 0x9E, 0x3F }, | ||
967 | { 0x9F, 0xFF }, | ||
968 | { 0xA0, 0x71 }, | ||
969 | { 0xA1, 0x00 }, | ||
970 | { 0xA2, 0x00 }, | ||
971 | { 0xA6, 0x00 }, | ||
972 | { 0xA7, 0x00 }, | ||
973 | { 0xAB, 0x00 }, | ||
974 | { 0xAC, 0x00 }, | ||
975 | { 0xAD, 0x00 }, | ||
976 | { 0xAF, 0x08 }, | ||
977 | { 0xB0, 0x00 }, | ||
978 | { 0xB1, 0x00 }, | ||
979 | { 0xB2, 0x00 }, | ||
980 | }; | ||
981 | |||
982 | static bool da9055_volatile_register(struct device *dev, | ||
983 | unsigned int reg) | ||
984 | { | ||
985 | switch (reg) { | ||
986 | case DA9055_STATUS1: | ||
987 | case DA9055_PLL_STATUS: | ||
988 | case DA9055_AUX_L_GAIN_STATUS: | ||
989 | case DA9055_AUX_R_GAIN_STATUS: | ||
990 | case DA9055_MIC_L_GAIN_STATUS: | ||
991 | case DA9055_MIC_R_GAIN_STATUS: | ||
992 | case DA9055_MIXIN_L_GAIN_STATUS: | ||
993 | case DA9055_MIXIN_R_GAIN_STATUS: | ||
994 | case DA9055_ADC_L_GAIN_STATUS: | ||
995 | case DA9055_ADC_R_GAIN_STATUS: | ||
996 | case DA9055_DAC_L_GAIN_STATUS: | ||
997 | case DA9055_DAC_R_GAIN_STATUS: | ||
998 | case DA9055_HP_L_GAIN_STATUS: | ||
999 | case DA9055_HP_R_GAIN_STATUS: | ||
1000 | case DA9055_LINE_GAIN_STATUS: | ||
1001 | case DA9055_ALC_CIC_OP_LVL_DATA: | ||
1002 | return 1; | ||
1003 | default: | ||
1004 | return 0; | ||
1005 | } | ||
1006 | } | ||
1007 | |||
1008 | /* Set DAI word length */ | ||
1009 | static int da9055_hw_params(struct snd_pcm_substream *substream, | ||
1010 | struct snd_pcm_hw_params *params, | ||
1011 | struct snd_soc_dai *dai) | ||
1012 | { | ||
1013 | struct snd_soc_codec *codec = dai->codec; | ||
1014 | struct da9055_priv *da9055 = snd_soc_codec_get_drvdata(codec); | ||
1015 | u8 aif_ctrl, fs; | ||
1016 | u32 sysclk; | ||
1017 | |||
1018 | switch (params_format(params)) { | ||
1019 | case SNDRV_PCM_FORMAT_S16_LE: | ||
1020 | aif_ctrl = DA9055_AIF_WORD_S16_LE; | ||
1021 | break; | ||
1022 | case SNDRV_PCM_FORMAT_S20_3LE: | ||
1023 | aif_ctrl = DA9055_AIF_WORD_S20_3LE; | ||
1024 | break; | ||
1025 | case SNDRV_PCM_FORMAT_S24_LE: | ||
1026 | aif_ctrl = DA9055_AIF_WORD_S24_LE; | ||
1027 | break; | ||
1028 | case SNDRV_PCM_FORMAT_S32_LE: | ||
1029 | aif_ctrl = DA9055_AIF_WORD_S32_LE; | ||
1030 | break; | ||
1031 | default: | ||
1032 | return -EINVAL; | ||
1033 | } | ||
1034 | |||
1035 | /* Set AIF format */ | ||
1036 | snd_soc_update_bits(codec, DA9055_AIF_CTRL, DA9055_AIF_WORD_LENGTH_MASK, | ||
1037 | aif_ctrl); | ||
1038 | |||
1039 | switch (params_rate(params)) { | ||
1040 | case 8000: | ||
1041 | fs = DA9055_SR_8000; | ||
1042 | sysclk = 3072000; | ||
1043 | break; | ||
1044 | case 11025: | ||
1045 | fs = DA9055_SR_11025; | ||
1046 | sysclk = 2822400; | ||
1047 | break; | ||
1048 | case 12000: | ||
1049 | fs = DA9055_SR_12000; | ||
1050 | sysclk = 3072000; | ||
1051 | break; | ||
1052 | case 16000: | ||
1053 | fs = DA9055_SR_16000; | ||
1054 | sysclk = 3072000; | ||
1055 | break; | ||
1056 | case 22050: | ||
1057 | fs = DA9055_SR_22050; | ||
1058 | sysclk = 2822400; | ||
1059 | break; | ||
1060 | case 32000: | ||
1061 | fs = DA9055_SR_32000; | ||
1062 | sysclk = 3072000; | ||
1063 | break; | ||
1064 | case 44100: | ||
1065 | fs = DA9055_SR_44100; | ||
1066 | sysclk = 2822400; | ||
1067 | break; | ||
1068 | case 48000: | ||
1069 | fs = DA9055_SR_48000; | ||
1070 | sysclk = 3072000; | ||
1071 | break; | ||
1072 | case 88200: | ||
1073 | fs = DA9055_SR_88200; | ||
1074 | sysclk = 2822400; | ||
1075 | break; | ||
1076 | case 96000: | ||
1077 | fs = DA9055_SR_96000; | ||
1078 | sysclk = 3072000; | ||
1079 | break; | ||
1080 | default: | ||
1081 | return -EINVAL; | ||
1082 | } | ||
1083 | |||
1084 | if (da9055->mclk_rate) { | ||
1085 | /* PLL Mode, Write actual FS */ | ||
1086 | snd_soc_write(codec, DA9055_SR, fs); | ||
1087 | } else { | ||
1088 | /* | ||
1089 | * Non-PLL Mode | ||
1090 | * When PLL is bypassed, chip assumes constant MCLK of | ||
1091 | * 12.288MHz and uses sample rate value to divide this MCLK | ||
1092 | * to derive its sys clk. As sys clk has to be 256 * Fs, we | ||
1093 | * need to write constant sample rate i.e. 48KHz. | ||
1094 | */ | ||
1095 | snd_soc_write(codec, DA9055_SR, DA9055_SR_48000); | ||
1096 | } | ||
1097 | |||
1098 | if (da9055->mclk_rate && (da9055->mclk_rate != sysclk)) { | ||
1099 | /* PLL Mode */ | ||
1100 | if (!da9055->master) { | ||
1101 | /* PLL slave mode, enable PLL and also SRM */ | ||
1102 | snd_soc_update_bits(codec, DA9055_PLL_CTRL, | ||
1103 | DA9055_PLL_EN | DA9055_PLL_SRM_EN, | ||
1104 | DA9055_PLL_EN | DA9055_PLL_SRM_EN); | ||
1105 | } else { | ||
1106 | /* PLL master mode, only enable PLL */ | ||
1107 | snd_soc_update_bits(codec, DA9055_PLL_CTRL, | ||
1108 | DA9055_PLL_EN, DA9055_PLL_EN); | ||
1109 | } | ||
1110 | } else { | ||
1111 | /* Non PLL Mode, disable PLL */ | ||
1112 | snd_soc_update_bits(codec, DA9055_PLL_CTRL, DA9055_PLL_EN, 0); | ||
1113 | } | ||
1114 | |||
1115 | return 0; | ||
1116 | } | ||
1117 | |||
1118 | /* Set DAI mode and Format */ | ||
1119 | static int da9055_set_dai_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt) | ||
1120 | { | ||
1121 | struct snd_soc_codec *codec = codec_dai->codec; | ||
1122 | struct da9055_priv *da9055 = snd_soc_codec_get_drvdata(codec); | ||
1123 | u8 aif_clk_mode, aif_ctrl, mode; | ||
1124 | |||
1125 | switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { | ||
1126 | case SND_SOC_DAIFMT_CBM_CFM: | ||
1127 | /* DA9055 in I2S Master Mode */ | ||
1128 | mode = 1; | ||
1129 | aif_clk_mode = DA9055_AIF_CLK_EN_MASTER_MODE; | ||
1130 | break; | ||
1131 | case SND_SOC_DAIFMT_CBS_CFS: | ||
1132 | /* DA9055 in I2S Slave Mode */ | ||
1133 | mode = 0; | ||
1134 | aif_clk_mode = DA9055_AIF_CLK_EN_SLAVE_MODE; | ||
1135 | break; | ||
1136 | default: | ||
1137 | return -EINVAL; | ||
1138 | } | ||
1139 | |||
1140 | /* Don't allow change of mode if PLL is enabled */ | ||
1141 | if ((snd_soc_read(codec, DA9055_PLL_CTRL) & DA9055_PLL_EN) && | ||
1142 | (da9055->master != mode)) | ||
1143 | return -EINVAL; | ||
1144 | |||
1145 | da9055->master = mode; | ||
1146 | |||
1147 | /* Only I2S is supported */ | ||
1148 | switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { | ||
1149 | case SND_SOC_DAIFMT_I2S: | ||
1150 | aif_ctrl = DA9055_AIF_FORMAT_I2S_MODE; | ||
1151 | break; | ||
1152 | case SND_SOC_DAIFMT_LEFT_J: | ||
1153 | aif_ctrl = DA9055_AIF_FORMAT_LEFT_J; | ||
1154 | break; | ||
1155 | case SND_SOC_DAIFMT_RIGHT_J: | ||
1156 | aif_ctrl = DA9055_AIF_FORMAT_RIGHT_J; | ||
1157 | break; | ||
1158 | default: | ||
1159 | return -EINVAL; | ||
1160 | } | ||
1161 | |||
1162 | /* By default only 32 BCLK per WCLK is supported */ | ||
1163 | aif_clk_mode |= DA9055_AIF_BCLKS_PER_WCLK_32; | ||
1164 | |||
1165 | snd_soc_update_bits(codec, DA9055_AIF_CLK_MODE, | ||
1166 | (DA9055_AIF_CLK_MODE_MASK | DA9055_AIF_BCLK_MASK), | ||
1167 | aif_clk_mode); | ||
1168 | snd_soc_update_bits(codec, DA9055_AIF_CTRL, DA9055_AIF_FORMAT_MASK, | ||
1169 | aif_ctrl); | ||
1170 | return 0; | ||
1171 | } | ||
1172 | |||
1173 | static int da9055_mute(struct snd_soc_dai *dai, int mute) | ||
1174 | { | ||
1175 | struct snd_soc_codec *codec = dai->codec; | ||
1176 | |||
1177 | if (mute) { | ||
1178 | snd_soc_update_bits(codec, DA9055_DAC_L_CTRL, | ||
1179 | DA9055_DAC_L_MUTE_EN, DA9055_DAC_L_MUTE_EN); | ||
1180 | snd_soc_update_bits(codec, DA9055_DAC_R_CTRL, | ||
1181 | DA9055_DAC_R_MUTE_EN, DA9055_DAC_R_MUTE_EN); | ||
1182 | } else { | ||
1183 | snd_soc_update_bits(codec, DA9055_DAC_L_CTRL, | ||
1184 | DA9055_DAC_L_MUTE_EN, 0); | ||
1185 | snd_soc_update_bits(codec, DA9055_DAC_R_CTRL, | ||
1186 | DA9055_DAC_R_MUTE_EN, 0); | ||
1187 | } | ||
1188 | |||
1189 | return 0; | ||
1190 | } | ||
1191 | |||
1192 | #define DA9055_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\ | ||
1193 | SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE) | ||
1194 | |||
1195 | static int da9055_set_dai_sysclk(struct snd_soc_dai *codec_dai, | ||
1196 | int clk_id, unsigned int freq, int dir) | ||
1197 | { | ||
1198 | struct snd_soc_codec *codec = codec_dai->codec; | ||
1199 | struct da9055_priv *da9055 = snd_soc_codec_get_drvdata(codec); | ||
1200 | |||
1201 | switch (clk_id) { | ||
1202 | case DA9055_CLKSRC_MCLK: | ||
1203 | switch (freq) { | ||
1204 | case 11289600: | ||
1205 | case 12000000: | ||
1206 | case 12288000: | ||
1207 | case 13000000: | ||
1208 | case 13500000: | ||
1209 | case 14400000: | ||
1210 | case 19200000: | ||
1211 | case 19680000: | ||
1212 | case 19800000: | ||
1213 | da9055->mclk_rate = freq; | ||
1214 | return 0; | ||
1215 | default: | ||
1216 | dev_err(codec_dai->dev, "Unsupported MCLK value %d\n", | ||
1217 | freq); | ||
1218 | return -EINVAL; | ||
1219 | } | ||
1220 | break; | ||
1221 | default: | ||
1222 | dev_err(codec_dai->dev, "Unknown clock source %d\n", clk_id); | ||
1223 | return -EINVAL; | ||
1224 | } | ||
1225 | } | ||
1226 | |||
1227 | /* | ||
1228 | * da9055_set_dai_pll : Configure the codec PLL | ||
1229 | * @param codec_dai : Pointer to codec DAI | ||
1230 | * @param pll_id : da9055 has only one pll, so pll_id is always zero | ||
1231 | * @param fref : Input MCLK frequency | ||
1232 | * @param fout : FsDM value | ||
1233 | * @return int : Zero for success, negative error code for error | ||
1234 | * | ||
1235 | * Note: Supported PLL input frequencies are 11.2896MHz, 12MHz, 12.288MHz, | ||
1236 | * 13MHz, 13.5MHz, 14.4MHz, 19.2MHz, 19.6MHz and 19.8MHz | ||
1237 | */ | ||
1238 | static int da9055_set_dai_pll(struct snd_soc_dai *codec_dai, int pll_id, | ||
1239 | int source, unsigned int fref, unsigned int fout) | ||
1240 | { | ||
1241 | struct snd_soc_codec *codec = codec_dai->codec; | ||
1242 | struct da9055_priv *da9055 = snd_soc_codec_get_drvdata(codec); | ||
1243 | |||
1244 | u8 pll_frac_top, pll_frac_bot, pll_integer, cnt; | ||
1245 | |||
1246 | /* Disable PLL before setting the divisors */ | ||
1247 | snd_soc_update_bits(codec, DA9055_PLL_CTRL, DA9055_PLL_EN, 0); | ||
1248 | |||
1249 | /* In slave mode, there is only one set of divisors */ | ||
1250 | if (!da9055->master && (fout != 2822400)) | ||
1251 | goto pll_err; | ||
1252 | |||
1253 | /* Search pll div array for correct divisors */ | ||
1254 | for (cnt = 0; cnt < ARRAY_SIZE(da9055_pll_div); cnt++) { | ||
1255 | /* Check fref, mode and fout */ | ||
1256 | if ((fref == da9055_pll_div[cnt].fref) && | ||
1257 | (da9055->master == da9055_pll_div[cnt].mode) && | ||
1258 | (fout == da9055_pll_div[cnt].fout)) { | ||
1259 | /* All match, pick up divisors */ | ||
1260 | pll_frac_top = da9055_pll_div[cnt].frac_top; | ||
1261 | pll_frac_bot = da9055_pll_div[cnt].frac_bot; | ||
1262 | pll_integer = da9055_pll_div[cnt].integer; | ||
1263 | break; | ||
1264 | } | ||
1265 | } | ||
1266 | if (cnt >= ARRAY_SIZE(da9055_pll_div)) | ||
1267 | goto pll_err; | ||
1268 | |||
1269 | /* Write PLL dividers */ | ||
1270 | snd_soc_write(codec, DA9055_PLL_FRAC_TOP, pll_frac_top); | ||
1271 | snd_soc_write(codec, DA9055_PLL_FRAC_BOT, pll_frac_bot); | ||
1272 | snd_soc_write(codec, DA9055_PLL_INTEGER, pll_integer); | ||
1273 | |||
1274 | return 0; | ||
1275 | pll_err: | ||
1276 | dev_err(codec_dai->dev, "Error in setting up PLL\n"); | ||
1277 | return -EINVAL; | ||
1278 | } | ||
1279 | |||
1280 | /* DAI operations */ | ||
1281 | static const struct snd_soc_dai_ops da9055_dai_ops = { | ||
1282 | .hw_params = da9055_hw_params, | ||
1283 | .set_fmt = da9055_set_dai_fmt, | ||
1284 | .set_sysclk = da9055_set_dai_sysclk, | ||
1285 | .set_pll = da9055_set_dai_pll, | ||
1286 | .digital_mute = da9055_mute, | ||
1287 | }; | ||
1288 | |||
1289 | static struct snd_soc_dai_driver da9055_dai = { | ||
1290 | .name = "da9055-hifi", | ||
1291 | /* Playback Capabilities */ | ||
1292 | .playback = { | ||
1293 | .stream_name = "Playback", | ||
1294 | .channels_min = 1, | ||
1295 | .channels_max = 2, | ||
1296 | .rates = SNDRV_PCM_RATE_8000_96000, | ||
1297 | .formats = DA9055_FORMATS, | ||
1298 | }, | ||
1299 | /* Capture Capabilities */ | ||
1300 | .capture = { | ||
1301 | .stream_name = "Capture", | ||
1302 | .channels_min = 1, | ||
1303 | .channels_max = 2, | ||
1304 | .rates = SNDRV_PCM_RATE_8000_96000, | ||
1305 | .formats = DA9055_FORMATS, | ||
1306 | }, | ||
1307 | .ops = &da9055_dai_ops, | ||
1308 | .symmetric_rates = 1, | ||
1309 | }; | ||
1310 | |||
1311 | static int da9055_set_bias_level(struct snd_soc_codec *codec, | ||
1312 | enum snd_soc_bias_level level) | ||
1313 | { | ||
1314 | switch (level) { | ||
1315 | case SND_SOC_BIAS_ON: | ||
1316 | case SND_SOC_BIAS_PREPARE: | ||
1317 | break; | ||
1318 | case SND_SOC_BIAS_STANDBY: | ||
1319 | if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) { | ||
1320 | /* Enable VMID reference & master bias */ | ||
1321 | snd_soc_update_bits(codec, DA9055_REFERENCES, | ||
1322 | DA9055_VMID_EN | DA9055_BIAS_EN, | ||
1323 | DA9055_VMID_EN | DA9055_BIAS_EN); | ||
1324 | } | ||
1325 | break; | ||
1326 | case SND_SOC_BIAS_OFF: | ||
1327 | /* Disable VMID reference & master bias */ | ||
1328 | snd_soc_update_bits(codec, DA9055_REFERENCES, | ||
1329 | DA9055_VMID_EN | DA9055_BIAS_EN, 0); | ||
1330 | break; | ||
1331 | } | ||
1332 | codec->dapm.bias_level = level; | ||
1333 | return 0; | ||
1334 | } | ||
1335 | |||
1336 | static int da9055_probe(struct snd_soc_codec *codec) | ||
1337 | { | ||
1338 | int ret; | ||
1339 | struct da9055_priv *da9055 = snd_soc_codec_get_drvdata(codec); | ||
1340 | |||
1341 | codec->control_data = da9055->regmap; | ||
1342 | ret = snd_soc_codec_set_cache_io(codec, 8, 8, SND_SOC_REGMAP); | ||
1343 | if (ret < 0) { | ||
1344 | dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret); | ||
1345 | return ret; | ||
1346 | } | ||
1347 | |||
1348 | /* Enable all Gain Ramps */ | ||
1349 | snd_soc_update_bits(codec, DA9055_AUX_L_CTRL, | ||
1350 | DA9055_GAIN_RAMPING_EN, DA9055_GAIN_RAMPING_EN); | ||
1351 | snd_soc_update_bits(codec, DA9055_AUX_R_CTRL, | ||
1352 | DA9055_GAIN_RAMPING_EN, DA9055_GAIN_RAMPING_EN); | ||
1353 | snd_soc_update_bits(codec, DA9055_MIXIN_L_CTRL, | ||
1354 | DA9055_GAIN_RAMPING_EN, DA9055_GAIN_RAMPING_EN); | ||
1355 | snd_soc_update_bits(codec, DA9055_MIXIN_R_CTRL, | ||
1356 | DA9055_GAIN_RAMPING_EN, DA9055_GAIN_RAMPING_EN); | ||
1357 | snd_soc_update_bits(codec, DA9055_ADC_L_CTRL, | ||
1358 | DA9055_GAIN_RAMPING_EN, DA9055_GAIN_RAMPING_EN); | ||
1359 | snd_soc_update_bits(codec, DA9055_ADC_R_CTRL, | ||
1360 | DA9055_GAIN_RAMPING_EN, DA9055_GAIN_RAMPING_EN); | ||
1361 | snd_soc_update_bits(codec, DA9055_DAC_L_CTRL, | ||
1362 | DA9055_GAIN_RAMPING_EN, DA9055_GAIN_RAMPING_EN); | ||
1363 | snd_soc_update_bits(codec, DA9055_DAC_R_CTRL, | ||
1364 | DA9055_GAIN_RAMPING_EN, DA9055_GAIN_RAMPING_EN); | ||
1365 | snd_soc_update_bits(codec, DA9055_HP_L_CTRL, | ||
1366 | DA9055_GAIN_RAMPING_EN, DA9055_GAIN_RAMPING_EN); | ||
1367 | snd_soc_update_bits(codec, DA9055_HP_R_CTRL, | ||
1368 | DA9055_GAIN_RAMPING_EN, DA9055_GAIN_RAMPING_EN); | ||
1369 | snd_soc_update_bits(codec, DA9055_LINE_CTRL, | ||
1370 | DA9055_GAIN_RAMPING_EN, DA9055_GAIN_RAMPING_EN); | ||
1371 | |||
1372 | /* | ||
1373 | * There are two separate control bits for input and output mixers as | ||
1374 | * well as headphone and line outs. | ||
1375 | * One to enable corresponding amplifier and other to enable its | ||
1376 | * output. As amplifier bits are related to power control, they are | ||
1377 | * being managed by DAPM while other (non power related) bits are | ||
1378 | * enabled here | ||
1379 | */ | ||
1380 | snd_soc_update_bits(codec, DA9055_MIXIN_L_CTRL, | ||
1381 | DA9055_MIXIN_L_MIX_EN, DA9055_MIXIN_L_MIX_EN); | ||
1382 | snd_soc_update_bits(codec, DA9055_MIXIN_R_CTRL, | ||
1383 | DA9055_MIXIN_R_MIX_EN, DA9055_MIXIN_R_MIX_EN); | ||
1384 | |||
1385 | snd_soc_update_bits(codec, DA9055_MIXOUT_L_CTRL, | ||
1386 | DA9055_MIXOUT_L_MIX_EN, DA9055_MIXOUT_L_MIX_EN); | ||
1387 | snd_soc_update_bits(codec, DA9055_MIXOUT_R_CTRL, | ||
1388 | DA9055_MIXOUT_R_MIX_EN, DA9055_MIXOUT_R_MIX_EN); | ||
1389 | |||
1390 | snd_soc_update_bits(codec, DA9055_HP_L_CTRL, | ||
1391 | DA9055_HP_L_AMP_OE, DA9055_HP_L_AMP_OE); | ||
1392 | snd_soc_update_bits(codec, DA9055_HP_R_CTRL, | ||
1393 | DA9055_HP_R_AMP_OE, DA9055_HP_R_AMP_OE); | ||
1394 | |||
1395 | snd_soc_update_bits(codec, DA9055_LINE_CTRL, | ||
1396 | DA9055_LINE_AMP_OE, DA9055_LINE_AMP_OE); | ||
1397 | |||
1398 | /* Set this as per your system configuration */ | ||
1399 | snd_soc_write(codec, DA9055_PLL_CTRL, DA9055_PLL_INDIV_10_20_MHZ); | ||
1400 | |||
1401 | /* Set platform data values */ | ||
1402 | if (da9055->pdata) { | ||
1403 | /* set mic bias source */ | ||
1404 | if (da9055->pdata->micbias_source) { | ||
1405 | snd_soc_update_bits(codec, DA9055_MIXIN_R_SELECT, | ||
1406 | DA9055_MICBIAS2_EN, | ||
1407 | DA9055_MICBIAS2_EN); | ||
1408 | } else { | ||
1409 | snd_soc_update_bits(codec, DA9055_MIXIN_R_SELECT, | ||
1410 | DA9055_MICBIAS2_EN, 0); | ||
1411 | } | ||
1412 | /* set mic bias voltage */ | ||
1413 | switch (da9055->pdata->micbias) { | ||
1414 | case DA9055_MICBIAS_2_2V: | ||
1415 | case DA9055_MICBIAS_2_1V: | ||
1416 | case DA9055_MICBIAS_1_8V: | ||
1417 | case DA9055_MICBIAS_1_6V: | ||
1418 | snd_soc_update_bits(codec, DA9055_MIC_CONFIG, | ||
1419 | DA9055_MICBIAS_LEVEL_MASK, | ||
1420 | (da9055->pdata->micbias) << 4); | ||
1421 | break; | ||
1422 | } | ||
1423 | } | ||
1424 | return 0; | ||
1425 | } | ||
1426 | |||
1427 | static struct snd_soc_codec_driver soc_codec_dev_da9055 = { | ||
1428 | .probe = da9055_probe, | ||
1429 | .set_bias_level = da9055_set_bias_level, | ||
1430 | |||
1431 | .controls = da9055_snd_controls, | ||
1432 | .num_controls = ARRAY_SIZE(da9055_snd_controls), | ||
1433 | |||
1434 | .dapm_widgets = da9055_dapm_widgets, | ||
1435 | .num_dapm_widgets = ARRAY_SIZE(da9055_dapm_widgets), | ||
1436 | .dapm_routes = da9055_audio_map, | ||
1437 | .num_dapm_routes = ARRAY_SIZE(da9055_audio_map), | ||
1438 | }; | ||
1439 | |||
1440 | static const struct regmap_config da9055_regmap_config = { | ||
1441 | .reg_bits = 8, | ||
1442 | .val_bits = 8, | ||
1443 | |||
1444 | .reg_defaults = da9055_reg_defaults, | ||
1445 | .num_reg_defaults = ARRAY_SIZE(da9055_reg_defaults), | ||
1446 | .volatile_reg = da9055_volatile_register, | ||
1447 | .cache_type = REGCACHE_RBTREE, | ||
1448 | }; | ||
1449 | |||
1450 | static int __devinit da9055_i2c_probe(struct i2c_client *i2c, | ||
1451 | const struct i2c_device_id *id) | ||
1452 | { | ||
1453 | struct da9055_priv *da9055; | ||
1454 | struct da9055_platform_data *pdata = dev_get_platdata(&i2c->dev); | ||
1455 | int ret; | ||
1456 | |||
1457 | da9055 = devm_kzalloc(&i2c->dev, sizeof(struct da9055_priv), | ||
1458 | GFP_KERNEL); | ||
1459 | if (!da9055) | ||
1460 | return -ENOMEM; | ||
1461 | |||
1462 | if (pdata) | ||
1463 | da9055->pdata = pdata; | ||
1464 | |||
1465 | i2c_set_clientdata(i2c, da9055); | ||
1466 | |||
1467 | da9055->regmap = devm_regmap_init_i2c(i2c, &da9055_regmap_config); | ||
1468 | if (IS_ERR(da9055->regmap)) { | ||
1469 | ret = PTR_ERR(da9055->regmap); | ||
1470 | dev_err(&i2c->dev, "regmap_init() failed: %d\n", ret); | ||
1471 | return ret; | ||
1472 | } | ||
1473 | |||
1474 | ret = snd_soc_register_codec(&i2c->dev, | ||
1475 | &soc_codec_dev_da9055, &da9055_dai, 1); | ||
1476 | if (ret < 0) { | ||
1477 | dev_err(&i2c->dev, "Failed to register da9055 codec: %d\n", | ||
1478 | ret); | ||
1479 | } | ||
1480 | return ret; | ||
1481 | } | ||
1482 | |||
1483 | static int __devexit da9055_remove(struct i2c_client *client) | ||
1484 | { | ||
1485 | snd_soc_unregister_codec(&client->dev); | ||
1486 | return 0; | ||
1487 | } | ||
1488 | |||
1489 | static const struct i2c_device_id da9055_i2c_id[] = { | ||
1490 | { "da9055", 0 }, | ||
1491 | { } | ||
1492 | }; | ||
1493 | MODULE_DEVICE_TABLE(i2c, da9055_i2c_id); | ||
1494 | |||
1495 | /* I2C codec control layer */ | ||
1496 | static struct i2c_driver da9055_i2c_driver = { | ||
1497 | .driver = { | ||
1498 | .name = "da9055", | ||
1499 | .owner = THIS_MODULE, | ||
1500 | }, | ||
1501 | .probe = da9055_i2c_probe, | ||
1502 | .remove = __devexit_p(da9055_remove), | ||
1503 | .id_table = da9055_i2c_id, | ||
1504 | }; | ||
1505 | |||
1506 | module_i2c_driver(da9055_i2c_driver); | ||
1507 | |||
1508 | MODULE_DESCRIPTION("ASoC DA9055 Codec driver"); | ||
1509 | MODULE_AUTHOR("David Chen, Ashish Chavan"); | ||
1510 | MODULE_LICENSE("GPL"); | ||
diff --git a/sound/soc/codecs/wm0010.c b/sound/soc/codecs/wm0010.c index f8d6c31db870..99afc003a084 100644 --- a/sound/soc/codecs/wm0010.c +++ b/sound/soc/codecs/wm0010.c | |||
@@ -168,7 +168,8 @@ static void wm0010_halt(struct snd_soc_codec *codec) | |||
168 | case WM0010_STAGE2: | 168 | case WM0010_STAGE2: |
169 | case WM0010_FIRMWARE: | 169 | case WM0010_FIRMWARE: |
170 | /* Remember to put chip back into reset */ | 170 | /* Remember to put chip back into reset */ |
171 | gpio_set_value(wm0010->gpio_reset, wm0010->gpio_reset_value); | 171 | gpio_set_value_cansleep(wm0010->gpio_reset, |
172 | wm0010->gpio_reset_value); | ||
172 | /* Disable the regulators */ | 173 | /* Disable the regulators */ |
173 | regulator_disable(wm0010->dbvdd); | 174 | regulator_disable(wm0010->dbvdd); |
174 | regulator_bulk_disable(ARRAY_SIZE(wm0010->core_supplies), | 175 | regulator_bulk_disable(ARRAY_SIZE(wm0010->core_supplies), |
@@ -387,7 +388,7 @@ static int wm0010_boot(struct snd_soc_codec *codec) | |||
387 | } | 388 | } |
388 | 389 | ||
389 | /* Release reset */ | 390 | /* Release reset */ |
390 | gpio_set_value(wm0010->gpio_reset, !wm0010->gpio_reset_value); | 391 | gpio_set_value_cansleep(wm0010->gpio_reset, !wm0010->gpio_reset_value); |
391 | spin_lock_irqsave(&wm0010->irq_lock, flags); | 392 | spin_lock_irqsave(&wm0010->irq_lock, flags); |
392 | wm0010->state = WM0010_OUT_OF_RESET; | 393 | wm0010->state = WM0010_OUT_OF_RESET; |
393 | spin_unlock_irqrestore(&wm0010->irq_lock, flags); | 394 | spin_unlock_irqrestore(&wm0010->irq_lock, flags); |
@@ -809,7 +810,6 @@ static int wm0010_probe(struct snd_soc_codec *codec) | |||
809 | 810 | ||
810 | static int __devinit wm0010_spi_probe(struct spi_device *spi) | 811 | static int __devinit wm0010_spi_probe(struct spi_device *spi) |
811 | { | 812 | { |
812 | unsigned long flags; | ||
813 | unsigned long gpio_flags; | 813 | unsigned long gpio_flags; |
814 | int ret; | 814 | int ret; |
815 | int trigger; | 815 | int trigger; |
@@ -876,6 +876,8 @@ static int __devinit wm0010_spi_probe(struct spi_device *spi) | |||
876 | return -EINVAL; | 876 | return -EINVAL; |
877 | } | 877 | } |
878 | 878 | ||
879 | wm0010->state = WM0010_POWER_OFF; | ||
880 | |||
879 | irq = spi->irq; | 881 | irq = spi->irq; |
880 | if (wm0010->pdata.irq_flags) | 882 | if (wm0010->pdata.irq_flags) |
881 | trigger = wm0010->pdata.irq_flags; | 883 | trigger = wm0010->pdata.irq_flags; |
@@ -897,10 +899,6 @@ static int __devinit wm0010_spi_probe(struct spi_device *spi) | |||
897 | else | 899 | else |
898 | wm0010->board_max_spi_speed = 0; | 900 | wm0010->board_max_spi_speed = 0; |
899 | 901 | ||
900 | spin_lock_irqsave(&wm0010->irq_lock, flags); | ||
901 | wm0010->state = WM0010_POWER_OFF; | ||
902 | spin_unlock_irqrestore(&wm0010->irq_lock, flags); | ||
903 | |||
904 | ret = snd_soc_register_codec(&spi->dev, | 902 | ret = snd_soc_register_codec(&spi->dev, |
905 | &soc_codec_dev_wm0010, wm0010_dai, | 903 | &soc_codec_dev_wm0010, wm0010_dai, |
906 | ARRAY_SIZE(wm0010_dai)); | 904 | ARRAY_SIZE(wm0010_dai)); |
@@ -916,10 +914,8 @@ static int __devexit wm0010_spi_remove(struct spi_device *spi) | |||
916 | 914 | ||
917 | snd_soc_unregister_codec(&spi->dev); | 915 | snd_soc_unregister_codec(&spi->dev); |
918 | 916 | ||
919 | if (wm0010->gpio_reset) { | 917 | gpio_set_value_cansleep(wm0010->gpio_reset, |
920 | /* Remember to put chip back into reset */ | 918 | wm0010->gpio_reset_value); |
921 | gpio_set_value(wm0010->gpio_reset, wm0010->gpio_reset_value); | ||
922 | } | ||
923 | 919 | ||
924 | if (wm0010->irq) | 920 | if (wm0010->irq) |
925 | free_irq(wm0010->irq, wm0010); | 921 | free_irq(wm0010->irq, wm0010); |
diff --git a/sound/soc/codecs/wm2000.c b/sound/soc/codecs/wm2000.c index 89cd6fcad015..b723e910fcdc 100644 --- a/sound/soc/codecs/wm2000.c +++ b/sound/soc/codecs/wm2000.c | |||
@@ -31,6 +31,7 @@ | |||
31 | #include <linux/i2c.h> | 31 | #include <linux/i2c.h> |
32 | #include <linux/regmap.h> | 32 | #include <linux/regmap.h> |
33 | #include <linux/debugfs.h> | 33 | #include <linux/debugfs.h> |
34 | #include <linux/regulator/consumer.h> | ||
34 | #include <linux/slab.h> | 35 | #include <linux/slab.h> |
35 | #include <sound/core.h> | 36 | #include <sound/core.h> |
36 | #include <sound/pcm.h> | 37 | #include <sound/pcm.h> |
@@ -43,6 +44,14 @@ | |||
43 | 44 | ||
44 | #include "wm2000.h" | 45 | #include "wm2000.h" |
45 | 46 | ||
47 | #define WM2000_NUM_SUPPLIES 3 | ||
48 | |||
49 | static const char *wm2000_supplies[WM2000_NUM_SUPPLIES] = { | ||
50 | "SPKVDD", | ||
51 | "DBVDD", | ||
52 | "DCVDD", | ||
53 | }; | ||
54 | |||
46 | enum wm2000_anc_mode { | 55 | enum wm2000_anc_mode { |
47 | ANC_ACTIVE = 0, | 56 | ANC_ACTIVE = 0, |
48 | ANC_BYPASS = 1, | 57 | ANC_BYPASS = 1, |
@@ -54,6 +63,8 @@ struct wm2000_priv { | |||
54 | struct i2c_client *i2c; | 63 | struct i2c_client *i2c; |
55 | struct regmap *regmap; | 64 | struct regmap *regmap; |
56 | 65 | ||
66 | struct regulator_bulk_data supplies[WM2000_NUM_SUPPLIES]; | ||
67 | |||
57 | enum wm2000_anc_mode anc_mode; | 68 | enum wm2000_anc_mode anc_mode; |
58 | 69 | ||
59 | unsigned int anc_active:1; | 70 | unsigned int anc_active:1; |
@@ -126,6 +137,12 @@ static int wm2000_power_up(struct i2c_client *i2c, int analogue) | |||
126 | 137 | ||
127 | dev_dbg(&i2c->dev, "Beginning power up\n"); | 138 | dev_dbg(&i2c->dev, "Beginning power up\n"); |
128 | 139 | ||
140 | ret = regulator_bulk_enable(WM2000_NUM_SUPPLIES, wm2000->supplies); | ||
141 | if (ret != 0) { | ||
142 | dev_err(&i2c->dev, "Failed to enable supplies: %d\n", ret); | ||
143 | return ret; | ||
144 | } | ||
145 | |||
129 | if (!wm2000->mclk_div) { | 146 | if (!wm2000->mclk_div) { |
130 | dev_dbg(&i2c->dev, "Disabling MCLK divider\n"); | 147 | dev_dbg(&i2c->dev, "Disabling MCLK divider\n"); |
131 | wm2000_write(i2c, WM2000_REG_SYS_CTL2, | 148 | wm2000_write(i2c, WM2000_REG_SYS_CTL2, |
@@ -143,12 +160,14 @@ static int wm2000_power_up(struct i2c_client *i2c, int analogue) | |||
143 | if (!wm2000_poll_bit(i2c, WM2000_REG_ANC_STAT, | 160 | if (!wm2000_poll_bit(i2c, WM2000_REG_ANC_STAT, |
144 | WM2000_ANC_ENG_IDLE)) { | 161 | WM2000_ANC_ENG_IDLE)) { |
145 | dev_err(&i2c->dev, "ANC engine failed to reset\n"); | 162 | dev_err(&i2c->dev, "ANC engine failed to reset\n"); |
163 | regulator_bulk_disable(WM2000_NUM_SUPPLIES, wm2000->supplies); | ||
146 | return -ETIMEDOUT; | 164 | return -ETIMEDOUT; |
147 | } | 165 | } |
148 | 166 | ||
149 | if (!wm2000_poll_bit(i2c, WM2000_REG_SYS_STATUS, | 167 | if (!wm2000_poll_bit(i2c, WM2000_REG_SYS_STATUS, |
150 | WM2000_STATUS_BOOT_COMPLETE)) { | 168 | WM2000_STATUS_BOOT_COMPLETE)) { |
151 | dev_err(&i2c->dev, "ANC engine failed to initialise\n"); | 169 | dev_err(&i2c->dev, "ANC engine failed to initialise\n"); |
170 | regulator_bulk_disable(WM2000_NUM_SUPPLIES, wm2000->supplies); | ||
152 | return -ETIMEDOUT; | 171 | return -ETIMEDOUT; |
153 | } | 172 | } |
154 | 173 | ||
@@ -163,11 +182,13 @@ static int wm2000_power_up(struct i2c_client *i2c, int analogue) | |||
163 | wm2000->anc_download_size); | 182 | wm2000->anc_download_size); |
164 | if (ret < 0) { | 183 | if (ret < 0) { |
165 | dev_err(&i2c->dev, "i2c_transfer() failed: %d\n", ret); | 184 | dev_err(&i2c->dev, "i2c_transfer() failed: %d\n", ret); |
185 | regulator_bulk_disable(WM2000_NUM_SUPPLIES, wm2000->supplies); | ||
166 | return ret; | 186 | return ret; |
167 | } | 187 | } |
168 | if (ret != wm2000->anc_download_size) { | 188 | if (ret != wm2000->anc_download_size) { |
169 | dev_err(&i2c->dev, "i2c_transfer() failed, %d != %d\n", | 189 | dev_err(&i2c->dev, "i2c_transfer() failed, %d != %d\n", |
170 | ret, wm2000->anc_download_size); | 190 | ret, wm2000->anc_download_size); |
191 | regulator_bulk_disable(WM2000_NUM_SUPPLIES, wm2000->supplies); | ||
171 | return -EIO; | 192 | return -EIO; |
172 | } | 193 | } |
173 | 194 | ||
@@ -201,6 +222,7 @@ static int wm2000_power_up(struct i2c_client *i2c, int analogue) | |||
201 | if (!wm2000_poll_bit(i2c, WM2000_REG_SYS_STATUS, | 222 | if (!wm2000_poll_bit(i2c, WM2000_REG_SYS_STATUS, |
202 | WM2000_STATUS_MOUSE_ACTIVE)) { | 223 | WM2000_STATUS_MOUSE_ACTIVE)) { |
203 | dev_err(&i2c->dev, "Timed out waiting for device\n"); | 224 | dev_err(&i2c->dev, "Timed out waiting for device\n"); |
225 | regulator_bulk_disable(WM2000_NUM_SUPPLIES, wm2000->supplies); | ||
204 | return -ETIMEDOUT; | 226 | return -ETIMEDOUT; |
205 | } | 227 | } |
206 | 228 | ||
@@ -238,6 +260,8 @@ static int wm2000_power_down(struct i2c_client *i2c, int analogue) | |||
238 | return -ETIMEDOUT; | 260 | return -ETIMEDOUT; |
239 | } | 261 | } |
240 | 262 | ||
263 | regulator_bulk_disable(WM2000_NUM_SUPPLIES, wm2000->supplies); | ||
264 | |||
241 | dev_dbg(&i2c->dev, "powered off\n"); | 265 | dev_dbg(&i2c->dev, "powered off\n"); |
242 | wm2000->anc_mode = ANC_OFF; | 266 | wm2000->anc_mode = ANC_OFF; |
243 | 267 | ||
@@ -747,7 +771,7 @@ static int __devinit wm2000_i2c_probe(struct i2c_client *i2c, | |||
747 | struct wm2000_platform_data *pdata; | 771 | struct wm2000_platform_data *pdata; |
748 | const char *filename; | 772 | const char *filename; |
749 | const struct firmware *fw = NULL; | 773 | const struct firmware *fw = NULL; |
750 | int ret; | 774 | int ret, i; |
751 | int reg; | 775 | int reg; |
752 | u16 id; | 776 | u16 id; |
753 | 777 | ||
@@ -760,7 +784,7 @@ static int __devinit wm2000_i2c_probe(struct i2c_client *i2c, | |||
760 | 784 | ||
761 | dev_set_drvdata(&i2c->dev, wm2000); | 785 | dev_set_drvdata(&i2c->dev, wm2000); |
762 | 786 | ||
763 | wm2000->regmap = regmap_init_i2c(i2c, &wm2000_regmap); | 787 | wm2000->regmap = devm_regmap_init_i2c(i2c, &wm2000_regmap); |
764 | if (IS_ERR(wm2000->regmap)) { | 788 | if (IS_ERR(wm2000->regmap)) { |
765 | ret = PTR_ERR(wm2000->regmap); | 789 | ret = PTR_ERR(wm2000->regmap); |
766 | dev_err(&i2c->dev, "Failed to allocate register map: %d\n", | 790 | dev_err(&i2c->dev, "Failed to allocate register map: %d\n", |
@@ -768,6 +792,22 @@ static int __devinit wm2000_i2c_probe(struct i2c_client *i2c, | |||
768 | goto out; | 792 | goto out; |
769 | } | 793 | } |
770 | 794 | ||
795 | for (i = 0; i < WM2000_NUM_SUPPLIES; i++) | ||
796 | wm2000->supplies[i].supply = wm2000_supplies[i]; | ||
797 | |||
798 | ret = devm_regulator_bulk_get(&i2c->dev, WM2000_NUM_SUPPLIES, | ||
799 | wm2000->supplies); | ||
800 | if (ret != 0) { | ||
801 | dev_err(&i2c->dev, "Failed to get supplies: %d\n", ret); | ||
802 | return ret; | ||
803 | } | ||
804 | |||
805 | ret = regulator_bulk_enable(WM2000_NUM_SUPPLIES, wm2000->supplies); | ||
806 | if (ret != 0) { | ||
807 | dev_err(&i2c->dev, "Failed to enable supplies: %d\n", ret); | ||
808 | return ret; | ||
809 | } | ||
810 | |||
771 | /* Verify that this is a WM2000 */ | 811 | /* Verify that this is a WM2000 */ |
772 | reg = wm2000_read(i2c, WM2000_REG_ID1); | 812 | reg = wm2000_read(i2c, WM2000_REG_ID1); |
773 | id = reg << 8; | 813 | id = reg << 8; |
@@ -777,7 +817,7 @@ static int __devinit wm2000_i2c_probe(struct i2c_client *i2c, | |||
777 | if (id != 0x2000) { | 817 | if (id != 0x2000) { |
778 | dev_err(&i2c->dev, "Device is not a WM2000 - ID %x\n", id); | 818 | dev_err(&i2c->dev, "Device is not a WM2000 - ID %x\n", id); |
779 | ret = -ENODEV; | 819 | ret = -ENODEV; |
780 | goto out_regmap_exit; | 820 | goto err_supplies; |
781 | } | 821 | } |
782 | 822 | ||
783 | reg = wm2000_read(i2c, WM2000_REG_REVISON); | 823 | reg = wm2000_read(i2c, WM2000_REG_REVISON); |
@@ -796,7 +836,7 @@ static int __devinit wm2000_i2c_probe(struct i2c_client *i2c, | |||
796 | ret = request_firmware(&fw, filename, &i2c->dev); | 836 | ret = request_firmware(&fw, filename, &i2c->dev); |
797 | if (ret != 0) { | 837 | if (ret != 0) { |
798 | dev_err(&i2c->dev, "Failed to acquire ANC data: %d\n", ret); | 838 | dev_err(&i2c->dev, "Failed to acquire ANC data: %d\n", ret); |
799 | goto out_regmap_exit; | 839 | goto err_supplies; |
800 | } | 840 | } |
801 | 841 | ||
802 | /* Pre-cook the concatenation of the register address onto the image */ | 842 | /* Pre-cook the concatenation of the register address onto the image */ |
@@ -807,7 +847,7 @@ static int __devinit wm2000_i2c_probe(struct i2c_client *i2c, | |||
807 | if (wm2000->anc_download == NULL) { | 847 | if (wm2000->anc_download == NULL) { |
808 | dev_err(&i2c->dev, "Out of memory\n"); | 848 | dev_err(&i2c->dev, "Out of memory\n"); |
809 | ret = -ENOMEM; | 849 | ret = -ENOMEM; |
810 | goto out_regmap_exit; | 850 | goto err_supplies; |
811 | } | 851 | } |
812 | 852 | ||
813 | wm2000->anc_download[0] = 0x80; | 853 | wm2000->anc_download[0] = 0x80; |
@@ -822,11 +862,10 @@ static int __devinit wm2000_i2c_probe(struct i2c_client *i2c, | |||
822 | wm2000_reset(wm2000); | 862 | wm2000_reset(wm2000); |
823 | 863 | ||
824 | ret = snd_soc_register_codec(&i2c->dev, &soc_codec_dev_wm2000, NULL, 0); | 864 | ret = snd_soc_register_codec(&i2c->dev, &soc_codec_dev_wm2000, NULL, 0); |
825 | if (!ret) | ||
826 | goto out; | ||
827 | 865 | ||
828 | out_regmap_exit: | 866 | err_supplies: |
829 | regmap_exit(wm2000->regmap); | 867 | regulator_bulk_disable(WM2000_NUM_SUPPLIES, wm2000->supplies); |
868 | |||
830 | out: | 869 | out: |
831 | release_firmware(fw); | 870 | release_firmware(fw); |
832 | return ret; | 871 | return ret; |
@@ -834,10 +873,7 @@ out: | |||
834 | 873 | ||
835 | static __devexit int wm2000_i2c_remove(struct i2c_client *i2c) | 874 | static __devexit int wm2000_i2c_remove(struct i2c_client *i2c) |
836 | { | 875 | { |
837 | struct wm2000_priv *wm2000 = dev_get_drvdata(&i2c->dev); | ||
838 | |||
839 | snd_soc_unregister_codec(&i2c->dev); | 876 | snd_soc_unregister_codec(&i2c->dev); |
840 | regmap_exit(wm2000->regmap); | ||
841 | 877 | ||
842 | return 0; | 878 | return 0; |
843 | } | 879 | } |
diff --git a/sound/soc/codecs/wm5102.c b/sound/soc/codecs/wm5102.c index 4a2db4e10885..1722b586bdba 100644 --- a/sound/soc/codecs/wm5102.c +++ b/sound/soc/codecs/wm5102.c | |||
@@ -308,7 +308,7 @@ SND_SOC_DAPM_SUPPLY("ASYNCOPCLK", ARIZONA_OUTPUT_ASYNC_CLOCK, | |||
308 | SND_SOC_DAPM_REGULATOR_SUPPLY("DBVDD2", 0, 0), | 308 | SND_SOC_DAPM_REGULATOR_SUPPLY("DBVDD2", 0, 0), |
309 | SND_SOC_DAPM_REGULATOR_SUPPLY("DBVDD3", 0, 0), | 309 | SND_SOC_DAPM_REGULATOR_SUPPLY("DBVDD3", 0, 0), |
310 | SND_SOC_DAPM_REGULATOR_SUPPLY("CPVDD", 20, 0), | 310 | SND_SOC_DAPM_REGULATOR_SUPPLY("CPVDD", 20, 0), |
311 | SND_SOC_DAPM_REGULATOR_SUPPLY("MICVDD", 0, 0), | 311 | SND_SOC_DAPM_REGULATOR_SUPPLY("MICVDD", 0, SND_SOC_DAPM_REGULATOR_BYPASS), |
312 | SND_SOC_DAPM_REGULATOR_SUPPLY("SPKVDDL", 0, 0), | 312 | SND_SOC_DAPM_REGULATOR_SUPPLY("SPKVDDL", 0, 0), |
313 | SND_SOC_DAPM_REGULATOR_SUPPLY("SPKVDDR", 0, 0), | 313 | SND_SOC_DAPM_REGULATOR_SUPPLY("SPKVDDR", 0, 0), |
314 | 314 | ||
diff --git a/sound/soc/codecs/wm5110.c b/sound/soc/codecs/wm5110.c index bf47914234b3..9211e4192f71 100644 --- a/sound/soc/codecs/wm5110.c +++ b/sound/soc/codecs/wm5110.c | |||
@@ -153,6 +153,15 @@ SOC_ENUM("LHPF2 Mode", arizona_lhpf2_mode), | |||
153 | SOC_ENUM("LHPF3 Mode", arizona_lhpf3_mode), | 153 | SOC_ENUM("LHPF3 Mode", arizona_lhpf3_mode), |
154 | SOC_ENUM("LHPF4 Mode", arizona_lhpf4_mode), | 154 | SOC_ENUM("LHPF4 Mode", arizona_lhpf4_mode), |
155 | 155 | ||
156 | ARIZONA_MIXER_CONTROLS("DSP1L", ARIZONA_DSP1LMIX_INPUT_1_SOURCE), | ||
157 | ARIZONA_MIXER_CONTROLS("DSP1R", ARIZONA_DSP1RMIX_INPUT_1_SOURCE), | ||
158 | ARIZONA_MIXER_CONTROLS("DSP2L", ARIZONA_DSP2LMIX_INPUT_1_SOURCE), | ||
159 | ARIZONA_MIXER_CONTROLS("DSP2R", ARIZONA_DSP2RMIX_INPUT_1_SOURCE), | ||
160 | ARIZONA_MIXER_CONTROLS("DSP3L", ARIZONA_DSP3LMIX_INPUT_1_SOURCE), | ||
161 | ARIZONA_MIXER_CONTROLS("DSP3R", ARIZONA_DSP3RMIX_INPUT_1_SOURCE), | ||
162 | ARIZONA_MIXER_CONTROLS("DSP4L", ARIZONA_DSP4LMIX_INPUT_1_SOURCE), | ||
163 | ARIZONA_MIXER_CONTROLS("DSP5R", ARIZONA_DSP4RMIX_INPUT_1_SOURCE), | ||
164 | |||
156 | ARIZONA_MIXER_CONTROLS("Mic", ARIZONA_MICMIX_INPUT_1_SOURCE), | 165 | ARIZONA_MIXER_CONTROLS("Mic", ARIZONA_MICMIX_INPUT_1_SOURCE), |
157 | ARIZONA_MIXER_CONTROLS("Noise", ARIZONA_NOISEMIX_INPUT_1_SOURCE), | 166 | ARIZONA_MIXER_CONTROLS("Noise", ARIZONA_NOISEMIX_INPUT_1_SOURCE), |
158 | 167 | ||
@@ -163,7 +172,8 @@ ARIZONA_MIXER_CONTROLS("HPOUT1L", ARIZONA_OUT1LMIX_INPUT_1_SOURCE), | |||
163 | ARIZONA_MIXER_CONTROLS("HPOUT1R", ARIZONA_OUT1RMIX_INPUT_1_SOURCE), | 172 | ARIZONA_MIXER_CONTROLS("HPOUT1R", ARIZONA_OUT1RMIX_INPUT_1_SOURCE), |
164 | ARIZONA_MIXER_CONTROLS("HPOUT2L", ARIZONA_OUT2LMIX_INPUT_1_SOURCE), | 173 | ARIZONA_MIXER_CONTROLS("HPOUT2L", ARIZONA_OUT2LMIX_INPUT_1_SOURCE), |
165 | ARIZONA_MIXER_CONTROLS("HPOUT2R", ARIZONA_OUT2RMIX_INPUT_1_SOURCE), | 174 | ARIZONA_MIXER_CONTROLS("HPOUT2R", ARIZONA_OUT2RMIX_INPUT_1_SOURCE), |
166 | ARIZONA_MIXER_CONTROLS("EPOUT", ARIZONA_OUT3LMIX_INPUT_1_SOURCE), | 175 | ARIZONA_MIXER_CONTROLS("HPOUT3L", ARIZONA_OUT3LMIX_INPUT_1_SOURCE), |
176 | ARIZONA_MIXER_CONTROLS("HPOUT3R", ARIZONA_OUT3RMIX_INPUT_1_SOURCE), | ||
167 | ARIZONA_MIXER_CONTROLS("SPKOUTL", ARIZONA_OUT4LMIX_INPUT_1_SOURCE), | 177 | ARIZONA_MIXER_CONTROLS("SPKOUTL", ARIZONA_OUT4LMIX_INPUT_1_SOURCE), |
168 | ARIZONA_MIXER_CONTROLS("SPKOUTR", ARIZONA_OUT4RMIX_INPUT_1_SOURCE), | 178 | ARIZONA_MIXER_CONTROLS("SPKOUTR", ARIZONA_OUT4RMIX_INPUT_1_SOURCE), |
169 | ARIZONA_MIXER_CONTROLS("SPKDAT1L", ARIZONA_OUT5LMIX_INPUT_1_SOURCE), | 179 | ARIZONA_MIXER_CONTROLS("SPKDAT1L", ARIZONA_OUT5LMIX_INPUT_1_SOURCE), |
@@ -175,7 +185,7 @@ SOC_SINGLE("HPOUT1 High Performance Switch", ARIZONA_OUTPUT_PATH_CONFIG_1L, | |||
175 | ARIZONA_OUT1_OSR_SHIFT, 1, 0), | 185 | ARIZONA_OUT1_OSR_SHIFT, 1, 0), |
176 | SOC_SINGLE("OUT2 High Performance Switch", ARIZONA_OUTPUT_PATH_CONFIG_2L, | 186 | SOC_SINGLE("OUT2 High Performance Switch", ARIZONA_OUTPUT_PATH_CONFIG_2L, |
177 | ARIZONA_OUT2_OSR_SHIFT, 1, 0), | 187 | ARIZONA_OUT2_OSR_SHIFT, 1, 0), |
178 | SOC_SINGLE("EPOUT High Performance Switch", ARIZONA_OUTPUT_PATH_CONFIG_3L, | 188 | SOC_SINGLE("OUT3 High Performance Switch", ARIZONA_OUTPUT_PATH_CONFIG_3L, |
179 | ARIZONA_OUT3_OSR_SHIFT, 1, 0), | 189 | ARIZONA_OUT3_OSR_SHIFT, 1, 0), |
180 | SOC_SINGLE("Speaker High Performance Switch", ARIZONA_OUTPUT_PATH_CONFIG_4L, | 190 | SOC_SINGLE("Speaker High Performance Switch", ARIZONA_OUTPUT_PATH_CONFIG_4L, |
181 | ARIZONA_OUT4_OSR_SHIFT, 1, 0), | 191 | ARIZONA_OUT4_OSR_SHIFT, 1, 0), |
@@ -188,8 +198,8 @@ SOC_DOUBLE_R("HPOUT1 Digital Switch", ARIZONA_DAC_DIGITAL_VOLUME_1L, | |||
188 | ARIZONA_DAC_DIGITAL_VOLUME_1R, ARIZONA_OUT1L_MUTE_SHIFT, 1, 1), | 198 | ARIZONA_DAC_DIGITAL_VOLUME_1R, ARIZONA_OUT1L_MUTE_SHIFT, 1, 1), |
189 | SOC_DOUBLE_R("OUT2 Digital Switch", ARIZONA_DAC_DIGITAL_VOLUME_2L, | 199 | SOC_DOUBLE_R("OUT2 Digital Switch", ARIZONA_DAC_DIGITAL_VOLUME_2L, |
190 | ARIZONA_DAC_DIGITAL_VOLUME_2R, ARIZONA_OUT2L_MUTE_SHIFT, 1, 1), | 200 | ARIZONA_DAC_DIGITAL_VOLUME_2R, ARIZONA_OUT2L_MUTE_SHIFT, 1, 1), |
191 | SOC_SINGLE("EPOUT Digital Switch", ARIZONA_DAC_DIGITAL_VOLUME_3L, | 201 | SOC_DOUBLE_R("OUT3 Digital Switch", ARIZONA_DAC_DIGITAL_VOLUME_3L, |
192 | ARIZONA_OUT3L_MUTE_SHIFT, 1, 1), | 202 | ARIZONA_DAC_DIGITAL_VOLUME_3R, ARIZONA_OUT3L_MUTE_SHIFT, 1, 1), |
193 | SOC_DOUBLE_R("Speaker Digital Switch", ARIZONA_DAC_DIGITAL_VOLUME_4L, | 203 | SOC_DOUBLE_R("Speaker Digital Switch", ARIZONA_DAC_DIGITAL_VOLUME_4L, |
194 | ARIZONA_DAC_DIGITAL_VOLUME_4R, ARIZONA_OUT4L_MUTE_SHIFT, 1, 1), | 204 | ARIZONA_DAC_DIGITAL_VOLUME_4R, ARIZONA_OUT4L_MUTE_SHIFT, 1, 1), |
195 | SOC_DOUBLE_R("SPKDAT1 Digital Switch", ARIZONA_DAC_DIGITAL_VOLUME_5L, | 205 | SOC_DOUBLE_R("SPKDAT1 Digital Switch", ARIZONA_DAC_DIGITAL_VOLUME_5L, |
@@ -203,8 +213,9 @@ SOC_DOUBLE_R_TLV("HPOUT1 Digital Volume", ARIZONA_DAC_DIGITAL_VOLUME_1L, | |||
203 | SOC_DOUBLE_R_TLV("OUT2 Digital Volume", ARIZONA_DAC_DIGITAL_VOLUME_2L, | 213 | SOC_DOUBLE_R_TLV("OUT2 Digital Volume", ARIZONA_DAC_DIGITAL_VOLUME_2L, |
204 | ARIZONA_DAC_DIGITAL_VOLUME_2R, ARIZONA_OUT2L_VOL_SHIFT, | 214 | ARIZONA_DAC_DIGITAL_VOLUME_2R, ARIZONA_OUT2L_VOL_SHIFT, |
205 | 0xbf, 0, digital_tlv), | 215 | 0xbf, 0, digital_tlv), |
206 | SOC_SINGLE_TLV("EPOUT Digital Volume", ARIZONA_DAC_DIGITAL_VOLUME_3L, | 216 | SOC_DOUBLE_R_TLV("OUT3 Digital Volume", ARIZONA_DAC_DIGITAL_VOLUME_3L, |
207 | ARIZONA_OUT3L_VOL_SHIFT, 0xbf, 0, digital_tlv), | 217 | ARIZONA_DAC_DIGITAL_VOLUME_3R, ARIZONA_OUT3L_VOL_SHIFT, |
218 | 0xbf, 0, digital_tlv), | ||
208 | SOC_DOUBLE_R_TLV("Speaker Digital Volume", ARIZONA_DAC_DIGITAL_VOLUME_4L, | 219 | SOC_DOUBLE_R_TLV("Speaker Digital Volume", ARIZONA_DAC_DIGITAL_VOLUME_4L, |
209 | ARIZONA_DAC_DIGITAL_VOLUME_4R, ARIZONA_OUT4L_VOL_SHIFT, | 220 | ARIZONA_DAC_DIGITAL_VOLUME_4R, ARIZONA_OUT4L_VOL_SHIFT, |
210 | 0xbf, 0, digital_tlv), | 221 | 0xbf, 0, digital_tlv), |
@@ -223,8 +234,9 @@ SOC_DOUBLE_R_RANGE_TLV("OUT2 Volume", ARIZONA_OUTPUT_PATH_CONFIG_2L, | |||
223 | ARIZONA_OUTPUT_PATH_CONFIG_2R, | 234 | ARIZONA_OUTPUT_PATH_CONFIG_2R, |
224 | ARIZONA_OUT2L_PGA_VOL_SHIFT, | 235 | ARIZONA_OUT2L_PGA_VOL_SHIFT, |
225 | 0x34, 0x40, 0, ana_tlv), | 236 | 0x34, 0x40, 0, ana_tlv), |
226 | SOC_SINGLE_RANGE_TLV("EPOUT Volume", ARIZONA_OUTPUT_PATH_CONFIG_3L, | 237 | SOC_DOUBLE_R_RANGE_TLV("OUT3 Volume", ARIZONA_OUTPUT_PATH_CONFIG_3L, |
227 | ARIZONA_OUT3L_PGA_VOL_SHIFT, 0x34, 0x40, 0, ana_tlv), | 238 | ARIZONA_OUTPUT_PATH_CONFIG_3R, |
239 | ARIZONA_OUT3L_PGA_VOL_SHIFT, 0x34, 0x40, 0, ana_tlv), | ||
228 | 240 | ||
229 | SOC_DOUBLE("SPKDAT1 Switch", ARIZONA_PDM_SPK1_CTRL_1, ARIZONA_SPK1L_MUTE_SHIFT, | 241 | SOC_DOUBLE("SPKDAT1 Switch", ARIZONA_PDM_SPK1_CTRL_1, ARIZONA_SPK1L_MUTE_SHIFT, |
230 | ARIZONA_SPK1R_MUTE_SHIFT, 1, 1), | 242 | ARIZONA_SPK1R_MUTE_SHIFT, 1, 1), |
@@ -272,7 +284,8 @@ ARIZONA_MIXER_ENUMS(OUT1L, ARIZONA_OUT1LMIX_INPUT_1_SOURCE); | |||
272 | ARIZONA_MIXER_ENUMS(OUT1R, ARIZONA_OUT1RMIX_INPUT_1_SOURCE); | 284 | ARIZONA_MIXER_ENUMS(OUT1R, ARIZONA_OUT1RMIX_INPUT_1_SOURCE); |
273 | ARIZONA_MIXER_ENUMS(OUT2L, ARIZONA_OUT2LMIX_INPUT_1_SOURCE); | 285 | ARIZONA_MIXER_ENUMS(OUT2L, ARIZONA_OUT2LMIX_INPUT_1_SOURCE); |
274 | ARIZONA_MIXER_ENUMS(OUT2R, ARIZONA_OUT2RMIX_INPUT_1_SOURCE); | 286 | ARIZONA_MIXER_ENUMS(OUT2R, ARIZONA_OUT2RMIX_INPUT_1_SOURCE); |
275 | ARIZONA_MIXER_ENUMS(OUT3, ARIZONA_OUT3LMIX_INPUT_1_SOURCE); | 287 | ARIZONA_MIXER_ENUMS(OUT3L, ARIZONA_OUT3LMIX_INPUT_1_SOURCE); |
288 | ARIZONA_MIXER_ENUMS(OUT3R, ARIZONA_OUT3RMIX_INPUT_1_SOURCE); | ||
276 | ARIZONA_MIXER_ENUMS(SPKOUTL, ARIZONA_OUT4LMIX_INPUT_1_SOURCE); | 289 | ARIZONA_MIXER_ENUMS(SPKOUTL, ARIZONA_OUT4LMIX_INPUT_1_SOURCE); |
277 | ARIZONA_MIXER_ENUMS(SPKOUTR, ARIZONA_OUT4RMIX_INPUT_1_SOURCE); | 290 | ARIZONA_MIXER_ENUMS(SPKOUTR, ARIZONA_OUT4RMIX_INPUT_1_SOURCE); |
278 | ARIZONA_MIXER_ENUMS(SPKDAT1L, ARIZONA_OUT5LMIX_INPUT_1_SOURCE); | 291 | ARIZONA_MIXER_ENUMS(SPKDAT1L, ARIZONA_OUT5LMIX_INPUT_1_SOURCE); |
@@ -300,6 +313,26 @@ ARIZONA_MIXER_ENUMS(ASRC1R, ARIZONA_ASRC1RMIX_INPUT_1_SOURCE); | |||
300 | ARIZONA_MIXER_ENUMS(ASRC2L, ARIZONA_ASRC2LMIX_INPUT_1_SOURCE); | 313 | ARIZONA_MIXER_ENUMS(ASRC2L, ARIZONA_ASRC2LMIX_INPUT_1_SOURCE); |
301 | ARIZONA_MIXER_ENUMS(ASRC2R, ARIZONA_ASRC2RMIX_INPUT_1_SOURCE); | 314 | ARIZONA_MIXER_ENUMS(ASRC2R, ARIZONA_ASRC2RMIX_INPUT_1_SOURCE); |
302 | 315 | ||
316 | static const char *wm5110_aec_loopback_texts[] = { | ||
317 | "HPOUT1L", "HPOUT1R", "HPOUT2L", "HPOUT2R", "HPOUT3L", "HPOUT3R", | ||
318 | "SPKOUTL", "SPKOUTR", "SPKDAT1L", "SPKDAT1R", "SPKDAT2L", "SPKDAT2R", | ||
319 | }; | ||
320 | |||
321 | static const unsigned int wm5110_aec_loopback_values[] = { | ||
322 | 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, | ||
323 | }; | ||
324 | |||
325 | static const struct soc_enum wm5110_aec_loopback = | ||
326 | SOC_VALUE_ENUM_SINGLE(ARIZONA_DAC_AEC_CONTROL_1, | ||
327 | ARIZONA_AEC_LOOPBACK_SRC_SHIFT, | ||
328 | ARIZONA_AEC_LOOPBACK_SRC_MASK, | ||
329 | ARRAY_SIZE(wm5110_aec_loopback_texts), | ||
330 | wm5110_aec_loopback_texts, | ||
331 | wm5110_aec_loopback_values); | ||
332 | |||
333 | static const struct snd_kcontrol_new wm5110_aec_loopback_mux = | ||
334 | SOC_DAPM_VALUE_ENUM("AEC Loopback", wm5110_aec_loopback); | ||
335 | |||
303 | static const struct snd_soc_dapm_widget wm5110_dapm_widgets[] = { | 336 | static const struct snd_soc_dapm_widget wm5110_dapm_widgets[] = { |
304 | SND_SOC_DAPM_SUPPLY("SYSCLK", ARIZONA_SYSTEM_CLOCK_1, ARIZONA_SYSCLK_ENA_SHIFT, | 337 | SND_SOC_DAPM_SUPPLY("SYSCLK", ARIZONA_SYSTEM_CLOCK_1, ARIZONA_SYSCLK_ENA_SHIFT, |
305 | 0, NULL, 0), | 338 | 0, NULL, 0), |
@@ -313,7 +346,7 @@ SND_SOC_DAPM_SUPPLY("ASYNCOPCLK", ARIZONA_OUTPUT_ASYNC_CLOCK, | |||
313 | SND_SOC_DAPM_REGULATOR_SUPPLY("DBVDD2", 0, 0), | 346 | SND_SOC_DAPM_REGULATOR_SUPPLY("DBVDD2", 0, 0), |
314 | SND_SOC_DAPM_REGULATOR_SUPPLY("DBVDD3", 0, 0), | 347 | SND_SOC_DAPM_REGULATOR_SUPPLY("DBVDD3", 0, 0), |
315 | SND_SOC_DAPM_REGULATOR_SUPPLY("CPVDD", 20, 0), | 348 | SND_SOC_DAPM_REGULATOR_SUPPLY("CPVDD", 20, 0), |
316 | SND_SOC_DAPM_REGULATOR_SUPPLY("MICVDD", 0, 0), | 349 | SND_SOC_DAPM_REGULATOR_SUPPLY("MICVDD", 0, SND_SOC_DAPM_REGULATOR_BYPASS), |
317 | SND_SOC_DAPM_REGULATOR_SUPPLY("SPKVDDL", 0, 0), | 350 | SND_SOC_DAPM_REGULATOR_SUPPLY("SPKVDDL", 0, 0), |
318 | SND_SOC_DAPM_REGULATOR_SUPPLY("SPKVDDR", 0, 0), | 351 | SND_SOC_DAPM_REGULATOR_SUPPLY("SPKVDDR", 0, 0), |
319 | 352 | ||
@@ -409,6 +442,9 @@ SND_SOC_DAPM_PGA("ASRC2L", ARIZONA_ASRC_ENABLE, ARIZONA_ASRC2L_ENA_SHIFT, 0, | |||
409 | SND_SOC_DAPM_PGA("ASRC2R", ARIZONA_ASRC_ENABLE, ARIZONA_ASRC2R_ENA_SHIFT, 0, | 442 | SND_SOC_DAPM_PGA("ASRC2R", ARIZONA_ASRC_ENABLE, ARIZONA_ASRC2R_ENA_SHIFT, 0, |
410 | NULL, 0), | 443 | NULL, 0), |
411 | 444 | ||
445 | SND_SOC_DAPM_VALUE_MUX("AEC Loopback", ARIZONA_DAC_AEC_CONTROL_1, | ||
446 | ARIZONA_AEC_LOOPBACK_ENA, 0, &wm5110_aec_loopback_mux), | ||
447 | |||
412 | SND_SOC_DAPM_AIF_OUT("AIF1TX1", NULL, 0, | 448 | SND_SOC_DAPM_AIF_OUT("AIF1TX1", NULL, 0, |
413 | ARIZONA_AIF1_TX_ENABLES, ARIZONA_AIF1TX1_ENA_SHIFT, 0), | 449 | ARIZONA_AIF1_TX_ENABLES, ARIZONA_AIF1TX1_ENA_SHIFT, 0), |
414 | SND_SOC_DAPM_AIF_OUT("AIF1TX2", NULL, 0, | 450 | SND_SOC_DAPM_AIF_OUT("AIF1TX2", NULL, 0, |
@@ -478,6 +514,9 @@ SND_SOC_DAPM_PGA_E("OUT2R", ARIZONA_OUTPUT_ENABLES_1, | |||
478 | SND_SOC_DAPM_PGA_E("OUT3L", ARIZONA_OUTPUT_ENABLES_1, | 514 | SND_SOC_DAPM_PGA_E("OUT3L", ARIZONA_OUTPUT_ENABLES_1, |
479 | ARIZONA_OUT3L_ENA_SHIFT, 0, NULL, 0, arizona_out_ev, | 515 | ARIZONA_OUT3L_ENA_SHIFT, 0, NULL, 0, arizona_out_ev, |
480 | SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU), | 516 | SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU), |
517 | SND_SOC_DAPM_PGA_E("OUT3R", ARIZONA_OUTPUT_ENABLES_1, | ||
518 | ARIZONA_OUT3R_ENA_SHIFT, 0, NULL, 0, arizona_out_ev, | ||
519 | SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU), | ||
481 | SND_SOC_DAPM_PGA_E("OUT4L", ARIZONA_OUTPUT_ENABLES_1, | 520 | SND_SOC_DAPM_PGA_E("OUT4L", ARIZONA_OUTPUT_ENABLES_1, |
482 | ARIZONA_OUT4L_ENA_SHIFT, 0, NULL, 0, arizona_out_ev, | 521 | ARIZONA_OUT4L_ENA_SHIFT, 0, NULL, 0, arizona_out_ev, |
483 | SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU), | 522 | SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU), |
@@ -522,7 +561,8 @@ ARIZONA_MIXER_WIDGETS(OUT1L, "HPOUT1L"), | |||
522 | ARIZONA_MIXER_WIDGETS(OUT1R, "HPOUT1R"), | 561 | ARIZONA_MIXER_WIDGETS(OUT1R, "HPOUT1R"), |
523 | ARIZONA_MIXER_WIDGETS(OUT2L, "HPOUT2L"), | 562 | ARIZONA_MIXER_WIDGETS(OUT2L, "HPOUT2L"), |
524 | ARIZONA_MIXER_WIDGETS(OUT2R, "HPOUT2R"), | 563 | ARIZONA_MIXER_WIDGETS(OUT2R, "HPOUT2R"), |
525 | ARIZONA_MIXER_WIDGETS(OUT3, "EPOUT"), | 564 | ARIZONA_MIXER_WIDGETS(OUT3L, "HPOUT3L"), |
565 | ARIZONA_MIXER_WIDGETS(OUT3R, "HPOUT3R"), | ||
526 | ARIZONA_MIXER_WIDGETS(SPKOUTL, "SPKOUTL"), | 566 | ARIZONA_MIXER_WIDGETS(SPKOUTL, "SPKOUTL"), |
527 | ARIZONA_MIXER_WIDGETS(SPKOUTR, "SPKOUTR"), | 567 | ARIZONA_MIXER_WIDGETS(SPKOUTR, "SPKOUTR"), |
528 | ARIZONA_MIXER_WIDGETS(SPKDAT1L, "SPKDAT1L"), | 568 | ARIZONA_MIXER_WIDGETS(SPKDAT1L, "SPKDAT1L"), |
@@ -554,8 +594,8 @@ SND_SOC_DAPM_OUTPUT("HPOUT1L"), | |||
554 | SND_SOC_DAPM_OUTPUT("HPOUT1R"), | 594 | SND_SOC_DAPM_OUTPUT("HPOUT1R"), |
555 | SND_SOC_DAPM_OUTPUT("HPOUT2L"), | 595 | SND_SOC_DAPM_OUTPUT("HPOUT2L"), |
556 | SND_SOC_DAPM_OUTPUT("HPOUT2R"), | 596 | SND_SOC_DAPM_OUTPUT("HPOUT2R"), |
557 | SND_SOC_DAPM_OUTPUT("EPOUTN"), | 597 | SND_SOC_DAPM_OUTPUT("HPOUT3L"), |
558 | SND_SOC_DAPM_OUTPUT("EPOUTP"), | 598 | SND_SOC_DAPM_OUTPUT("HPOUT3R"), |
559 | SND_SOC_DAPM_OUTPUT("SPKOUTLN"), | 599 | SND_SOC_DAPM_OUTPUT("SPKOUTLN"), |
560 | SND_SOC_DAPM_OUTPUT("SPKOUTLP"), | 600 | SND_SOC_DAPM_OUTPUT("SPKOUTLP"), |
561 | SND_SOC_DAPM_OUTPUT("SPKOUTRN"), | 601 | SND_SOC_DAPM_OUTPUT("SPKOUTRN"), |
@@ -570,6 +610,7 @@ SND_SOC_DAPM_OUTPUT("SPKDAT2R"), | |||
570 | { name, "Noise Generator", "Noise Generator" }, \ | 610 | { name, "Noise Generator", "Noise Generator" }, \ |
571 | { name, "Tone Generator 1", "Tone Generator 1" }, \ | 611 | { name, "Tone Generator 1", "Tone Generator 1" }, \ |
572 | { name, "Tone Generator 2", "Tone Generator 2" }, \ | 612 | { name, "Tone Generator 2", "Tone Generator 2" }, \ |
613 | { name, "AEC", "AEC Loopback" }, \ | ||
573 | { name, "IN1L", "IN1L PGA" }, \ | 614 | { name, "IN1L", "IN1L PGA" }, \ |
574 | { name, "IN1R", "IN1R PGA" }, \ | 615 | { name, "IN1R", "IN1R PGA" }, \ |
575 | { name, "IN2L", "IN2L PGA" }, \ | 616 | { name, "IN2L", "IN2L PGA" }, \ |
@@ -620,6 +661,7 @@ static const struct snd_soc_dapm_route wm5110_dapm_routes[] = { | |||
620 | { "OUT2L", NULL, "CPVDD" }, | 661 | { "OUT2L", NULL, "CPVDD" }, |
621 | { "OUT2R", NULL, "CPVDD" }, | 662 | { "OUT2R", NULL, "CPVDD" }, |
622 | { "OUT3L", NULL, "CPVDD" }, | 663 | { "OUT3L", NULL, "CPVDD" }, |
664 | { "OUT3R", NULL, "CPVDD" }, | ||
623 | 665 | ||
624 | { "OUT4L", NULL, "SPKVDDL" }, | 666 | { "OUT4L", NULL, "SPKVDDL" }, |
625 | { "OUT4R", NULL, "SPKVDDR" }, | 667 | { "OUT4R", NULL, "SPKVDDR" }, |
@@ -701,7 +743,8 @@ static const struct snd_soc_dapm_route wm5110_dapm_routes[] = { | |||
701 | ARIZONA_MIXER_ROUTES("OUT1R", "HPOUT1R"), | 743 | ARIZONA_MIXER_ROUTES("OUT1R", "HPOUT1R"), |
702 | ARIZONA_MIXER_ROUTES("OUT2L", "HPOUT2L"), | 744 | ARIZONA_MIXER_ROUTES("OUT2L", "HPOUT2L"), |
703 | ARIZONA_MIXER_ROUTES("OUT2R", "HPOUT2R"), | 745 | ARIZONA_MIXER_ROUTES("OUT2R", "HPOUT2R"), |
704 | ARIZONA_MIXER_ROUTES("OUT3L", "EPOUT"), | 746 | ARIZONA_MIXER_ROUTES("OUT3L", "HPOUT3L"), |
747 | ARIZONA_MIXER_ROUTES("OUT3R", "HPOUT3R"), | ||
705 | 748 | ||
706 | ARIZONA_MIXER_ROUTES("OUT4L", "SPKOUTL"), | 749 | ARIZONA_MIXER_ROUTES("OUT4L", "SPKOUTL"), |
707 | ARIZONA_MIXER_ROUTES("OUT4R", "SPKOUTR"), | 750 | ARIZONA_MIXER_ROUTES("OUT4R", "SPKOUTR"), |
@@ -754,8 +797,8 @@ static const struct snd_soc_dapm_route wm5110_dapm_routes[] = { | |||
754 | { "HPOUT2L", NULL, "OUT2L" }, | 797 | { "HPOUT2L", NULL, "OUT2L" }, |
755 | { "HPOUT2R", NULL, "OUT2R" }, | 798 | { "HPOUT2R", NULL, "OUT2R" }, |
756 | 799 | ||
757 | { "EPOUTN", NULL, "OUT3L" }, | 800 | { "HPOUT3L", NULL, "OUT3L" }, |
758 | { "EPOUTP", NULL, "OUT3L" }, | 801 | { "HPOUT3R", NULL, "OUT3L" }, |
759 | 802 | ||
760 | { "SPKOUTLN", NULL, "OUT4L" }, | 803 | { "SPKOUTLN", NULL, "OUT4L" }, |
761 | { "SPKOUTLP", NULL, "OUT4L" }, | 804 | { "SPKOUTLP", NULL, "OUT4L" }, |
@@ -873,6 +916,8 @@ static unsigned int wm5110_digital_vu[] = { | |||
873 | ARIZONA_ADC_DIGITAL_VOLUME_2R, | 916 | ARIZONA_ADC_DIGITAL_VOLUME_2R, |
874 | ARIZONA_ADC_DIGITAL_VOLUME_3L, | 917 | ARIZONA_ADC_DIGITAL_VOLUME_3L, |
875 | ARIZONA_ADC_DIGITAL_VOLUME_3R, | 918 | ARIZONA_ADC_DIGITAL_VOLUME_3R, |
919 | ARIZONA_ADC_DIGITAL_VOLUME_4L, | ||
920 | ARIZONA_ADC_DIGITAL_VOLUME_4R, | ||
876 | 921 | ||
877 | ARIZONA_DAC_DIGITAL_VOLUME_1L, | 922 | ARIZONA_DAC_DIGITAL_VOLUME_1L, |
878 | ARIZONA_DAC_DIGITAL_VOLUME_1R, | 923 | ARIZONA_DAC_DIGITAL_VOLUME_1R, |
@@ -884,6 +929,8 @@ static unsigned int wm5110_digital_vu[] = { | |||
884 | ARIZONA_DAC_DIGITAL_VOLUME_4R, | 929 | ARIZONA_DAC_DIGITAL_VOLUME_4R, |
885 | ARIZONA_DAC_DIGITAL_VOLUME_5L, | 930 | ARIZONA_DAC_DIGITAL_VOLUME_5L, |
886 | ARIZONA_DAC_DIGITAL_VOLUME_5R, | 931 | ARIZONA_DAC_DIGITAL_VOLUME_5R, |
932 | ARIZONA_DAC_DIGITAL_VOLUME_6L, | ||
933 | ARIZONA_DAC_DIGITAL_VOLUME_6R, | ||
887 | }; | 934 | }; |
888 | 935 | ||
889 | static struct snd_soc_codec_driver soc_codec_dev_wm5110 = { | 936 | static struct snd_soc_codec_driver soc_codec_dev_wm5110 = { |
diff --git a/sound/soc/codecs/wm_hubs.c b/sound/soc/codecs/wm_hubs.c index 7a773a835b8e..867ae97ddcec 100644 --- a/sound/soc/codecs/wm_hubs.c +++ b/sound/soc/codecs/wm_hubs.c | |||
@@ -681,6 +681,11 @@ void wm_hubs_update_class_w(struct snd_soc_codec *codec) | |||
681 | 681 | ||
682 | snd_soc_update_bits(codec, WM8993_CLASS_W_0, | 682 | snd_soc_update_bits(codec, WM8993_CLASS_W_0, |
683 | WM8993_CP_DYN_V | WM8993_CP_DYN_FREQ, enable); | 683 | WM8993_CP_DYN_V | WM8993_CP_DYN_FREQ, enable); |
684 | |||
685 | snd_soc_write(codec, WM8993_LEFT_OUTPUT_VOLUME, | ||
686 | snd_soc_read(codec, WM8993_LEFT_OUTPUT_VOLUME)); | ||
687 | snd_soc_write(codec, WM8993_RIGHT_OUTPUT_VOLUME, | ||
688 | snd_soc_read(codec, WM8993_RIGHT_OUTPUT_VOLUME)); | ||
684 | } | 689 | } |
685 | EXPORT_SYMBOL_GPL(wm_hubs_update_class_w); | 690 | EXPORT_SYMBOL_GPL(wm_hubs_update_class_w); |
686 | 691 | ||
diff --git a/sound/soc/fsl/eukrea-tlv320.c b/sound/soc/fsl/eukrea-tlv320.c index efb9ede01208..267d5b4b63ce 100644 --- a/sound/soc/fsl/eukrea-tlv320.c +++ b/sound/soc/fsl/eukrea-tlv320.c | |||
@@ -93,9 +93,7 @@ static struct snd_soc_card eukrea_tlv320 = { | |||
93 | .num_links = 1, | 93 | .num_links = 1, |
94 | }; | 94 | }; |
95 | 95 | ||
96 | static struct platform_device *eukrea_tlv320_snd_device; | 96 | static int __devinit eukrea_tlv320_probe(struct platform_device *pdev) |
97 | |||
98 | static int __init eukrea_tlv320_init(void) | ||
99 | { | 97 | { |
100 | int ret; | 98 | int ret; |
101 | int int_port = 0, ext_port; | 99 | int int_port = 0, ext_port; |
@@ -136,29 +134,32 @@ static int __init eukrea_tlv320_init(void) | |||
136 | return 0; | 134 | return 0; |
137 | } | 135 | } |
138 | 136 | ||
139 | eukrea_tlv320_snd_device = platform_device_alloc("soc-audio", -1); | 137 | eukrea_tlv320.dev = &pdev->dev; |
140 | if (!eukrea_tlv320_snd_device) | 138 | ret = snd_soc_register_card(&eukrea_tlv320); |
141 | return -ENOMEM; | 139 | if (ret) |
142 | 140 | dev_err(&pdev->dev, "snd_soc_register_card failed (%d)\n", ret); | |
143 | platform_set_drvdata(eukrea_tlv320_snd_device, &eukrea_tlv320); | ||
144 | ret = platform_device_add(eukrea_tlv320_snd_device); | ||
145 | |||
146 | if (ret) { | ||
147 | printk(KERN_ERR "ASoC: Platform device allocation failed\n"); | ||
148 | platform_device_put(eukrea_tlv320_snd_device); | ||
149 | } | ||
150 | 141 | ||
151 | return ret; | 142 | return ret; |
152 | } | 143 | } |
153 | 144 | ||
154 | static void __exit eukrea_tlv320_exit(void) | 145 | static int __devexit eukrea_tlv320_remove(struct platform_device *pdev) |
155 | { | 146 | { |
156 | platform_device_unregister(eukrea_tlv320_snd_device); | 147 | snd_soc_unregister_card(&eukrea_tlv320); |
148 | |||
149 | return 0; | ||
157 | } | 150 | } |
158 | 151 | ||
159 | module_init(eukrea_tlv320_init); | 152 | static struct platform_driver eukrea_tlv320_driver = { |
160 | module_exit(eukrea_tlv320_exit); | 153 | .driver = { |
154 | .name = "eukrea_tlv320", | ||
155 | .owner = THIS_MODULE, | ||
156 | }, | ||
157 | .probe = eukrea_tlv320_probe, | ||
158 | .remove = __devexit_p(eukrea_tlv320_remove),}; | ||
159 | |||
160 | module_platform_driver(eukrea_tlv320_driver); | ||
161 | 161 | ||
162 | MODULE_AUTHOR("Eric Bénard <eric@eukrea.com>"); | 162 | MODULE_AUTHOR("Eric Bénard <eric@eukrea.com>"); |
163 | MODULE_DESCRIPTION("CPUIMX ALSA SoC driver"); | 163 | MODULE_DESCRIPTION("CPUIMX ALSA SoC driver"); |
164 | MODULE_LICENSE("GPL"); | 164 | MODULE_LICENSE("GPL"); |
165 | MODULE_ALIAS("platform:eukrea_tlv320"); | ||
diff --git a/sound/soc/soc-dapm.c b/sound/soc/soc-dapm.c index 873e6e76ee87..d0a4be38dc0f 100644 --- a/sound/soc/soc-dapm.c +++ b/sound/soc/soc-dapm.c | |||
@@ -1017,10 +1017,29 @@ EXPORT_SYMBOL_GPL(dapm_reg_event); | |||
1017 | int dapm_regulator_event(struct snd_soc_dapm_widget *w, | 1017 | int dapm_regulator_event(struct snd_soc_dapm_widget *w, |
1018 | struct snd_kcontrol *kcontrol, int event) | 1018 | struct snd_kcontrol *kcontrol, int event) |
1019 | { | 1019 | { |
1020 | if (SND_SOC_DAPM_EVENT_ON(event)) | 1020 | int ret; |
1021 | |||
1022 | if (SND_SOC_DAPM_EVENT_ON(event)) { | ||
1023 | if (w->invert & SND_SOC_DAPM_REGULATOR_BYPASS) { | ||
1024 | ret = regulator_allow_bypass(w->regulator, true); | ||
1025 | if (ret != 0) | ||
1026 | dev_warn(w->dapm->dev, | ||
1027 | "Failed to bypass %s: %d\n", | ||
1028 | w->name, ret); | ||
1029 | } | ||
1030 | |||
1021 | return regulator_enable(w->regulator); | 1031 | return regulator_enable(w->regulator); |
1022 | else | 1032 | } else { |
1033 | if (w->invert & SND_SOC_DAPM_REGULATOR_BYPASS) { | ||
1034 | ret = regulator_allow_bypass(w->regulator, false); | ||
1035 | if (ret != 0) | ||
1036 | dev_warn(w->dapm->dev, | ||
1037 | "Failed to unbypass %s: %d\n", | ||
1038 | w->name, ret); | ||
1039 | } | ||
1040 | |||
1023 | return regulator_disable_deferred(w->regulator, w->shift); | 1041 | return regulator_disable_deferred(w->regulator, w->shift); |
1042 | } | ||
1024 | } | 1043 | } |
1025 | EXPORT_SYMBOL_GPL(dapm_regulator_event); | 1044 | EXPORT_SYMBOL_GPL(dapm_regulator_event); |
1026 | 1045 | ||
diff --git a/sound/soc/ux500/mop500.c b/sound/soc/ux500/mop500.c index 31c4d26d0359..356611d9654d 100644 --- a/sound/soc/ux500/mop500.c +++ b/sound/soc/ux500/mop500.c | |||
@@ -16,6 +16,7 @@ | |||
16 | #include <linux/module.h> | 16 | #include <linux/module.h> |
17 | #include <linux/io.h> | 17 | #include <linux/io.h> |
18 | #include <linux/spi/spi.h> | 18 | #include <linux/spi/spi.h> |
19 | #include <linux/of.h> | ||
19 | 20 | ||
20 | #include <sound/soc.h> | 21 | #include <sound/soc.h> |
21 | #include <sound/initval.h> | 22 | #include <sound/initval.h> |
@@ -56,16 +57,47 @@ static struct snd_soc_card mop500_card = { | |||
56 | .num_links = ARRAY_SIZE(mop500_dai_links), | 57 | .num_links = ARRAY_SIZE(mop500_dai_links), |
57 | }; | 58 | }; |
58 | 59 | ||
60 | static int __devinit mop500_of_probe(struct platform_device *pdev, | ||
61 | struct device_node *np) | ||
62 | { | ||
63 | struct device_node *codec_np, *msp_np[2]; | ||
64 | int i; | ||
65 | |||
66 | msp_np[0] = of_parse_phandle(np, "stericsson,cpu-dai", 0); | ||
67 | msp_np[1] = of_parse_phandle(np, "stericsson,cpu-dai", 1); | ||
68 | codec_np = of_parse_phandle(np, "stericsson,audio-codec", 0); | ||
69 | |||
70 | if (!(msp_np[0] && msp_np[1] && codec_np)) { | ||
71 | dev_err(&pdev->dev, "Phandle missing or invalid\n"); | ||
72 | return -EINVAL; | ||
73 | } | ||
74 | |||
75 | for (i = 0; i < 2; i++) { | ||
76 | mop500_dai_links[i].cpu_of_node = msp_np[i]; | ||
77 | mop500_dai_links[i].cpu_dai_name = NULL; | ||
78 | mop500_dai_links[i].codec_of_node = codec_np; | ||
79 | mop500_dai_links[i].codec_name = NULL; | ||
80 | } | ||
81 | |||
82 | snd_soc_of_parse_card_name(&mop500_card, "stericsson,card-name"); | ||
83 | |||
84 | return 0; | ||
85 | } | ||
59 | static int __devinit mop500_probe(struct platform_device *pdev) | 86 | static int __devinit mop500_probe(struct platform_device *pdev) |
60 | { | 87 | { |
88 | struct device_node *np = pdev->dev.of_node; | ||
61 | int ret; | 89 | int ret; |
62 | 90 | ||
63 | pr_debug("%s: Enter.\n", __func__); | ||
64 | |||
65 | dev_dbg(&pdev->dev, "%s: Enter.\n", __func__); | 91 | dev_dbg(&pdev->dev, "%s: Enter.\n", __func__); |
66 | 92 | ||
67 | mop500_card.dev = &pdev->dev; | 93 | mop500_card.dev = &pdev->dev; |
68 | 94 | ||
95 | if (np) { | ||
96 | ret = mop500_of_probe(pdev, np); | ||
97 | if (ret) | ||
98 | return ret; | ||
99 | } | ||
100 | |||
69 | dev_dbg(&pdev->dev, "%s: Card %s: Set platform drvdata.\n", | 101 | dev_dbg(&pdev->dev, "%s: Card %s: Set platform drvdata.\n", |
70 | __func__, mop500_card.name); | 102 | __func__, mop500_card.name); |
71 | platform_set_drvdata(pdev, &mop500_card); | 103 | platform_set_drvdata(pdev, &mop500_card); |
@@ -83,8 +115,7 @@ static int __devinit mop500_probe(struct platform_device *pdev) | |||
83 | ret = snd_soc_register_card(&mop500_card); | 115 | ret = snd_soc_register_card(&mop500_card); |
84 | if (ret) | 116 | if (ret) |
85 | dev_err(&pdev->dev, | 117 | dev_err(&pdev->dev, |
86 | "Error: snd_soc_register_card failed (%d)!\n", | 118 | "Error: snd_soc_register_card failed (%d)!\n", ret); |
87 | ret); | ||
88 | 119 | ||
89 | return ret; | 120 | return ret; |
90 | } | 121 | } |
@@ -97,14 +128,20 @@ static int __devexit mop500_remove(struct platform_device *pdev) | |||
97 | 128 | ||
98 | snd_soc_unregister_card(mop500_card); | 129 | snd_soc_unregister_card(mop500_card); |
99 | mop500_ab8500_remove(mop500_card); | 130 | mop500_ab8500_remove(mop500_card); |
100 | 131 | ||
101 | return 0; | 132 | return 0; |
102 | } | 133 | } |
103 | 134 | ||
135 | static const struct of_device_id snd_soc_mop500_match[] = { | ||
136 | { .compatible = "stericsson,snd-soc-mop500", }, | ||
137 | {}, | ||
138 | }; | ||
139 | |||
104 | static struct platform_driver snd_soc_mop500_driver = { | 140 | static struct platform_driver snd_soc_mop500_driver = { |
105 | .driver = { | 141 | .driver = { |
106 | .owner = THIS_MODULE, | 142 | .owner = THIS_MODULE, |
107 | .name = "snd-soc-mop500", | 143 | .name = "snd-soc-mop500", |
144 | .of_match_table = snd_soc_mop500_match, | ||
108 | }, | 145 | }, |
109 | .probe = mop500_probe, | 146 | .probe = mop500_probe, |
110 | .remove = __devexit_p(mop500_remove), | 147 | .remove = __devexit_p(mop500_remove), |
diff --git a/sound/soc/ux500/ux500_msp_dai.c b/sound/soc/ux500/ux500_msp_dai.c index 772cb19d2fb3..be94bf9bf94f 100644 --- a/sound/soc/ux500/ux500_msp_dai.c +++ b/sound/soc/ux500/ux500_msp_dai.c | |||
@@ -833,10 +833,16 @@ static int __devexit ux500_msp_drv_remove(struct platform_device *pdev) | |||
833 | return 0; | 833 | return 0; |
834 | } | 834 | } |
835 | 835 | ||
836 | static const struct of_device_id ux500_msp_i2s_match[] = { | ||
837 | { .compatible = "stericsson,ux500-msp-i2s", }, | ||
838 | {}, | ||
839 | }; | ||
840 | |||
836 | static struct platform_driver msp_i2s_driver = { | 841 | static struct platform_driver msp_i2s_driver = { |
837 | .driver = { | 842 | .driver = { |
838 | .name = "ux500-msp-i2s", | 843 | .name = "ux500-msp-i2s", |
839 | .owner = THIS_MODULE, | 844 | .owner = THIS_MODULE, |
845 | .of_match_table = ux500_msp_i2s_match, | ||
840 | }, | 846 | }, |
841 | .probe = ux500_msp_drv_probe, | 847 | .probe = ux500_msp_drv_probe, |
842 | .remove = ux500_msp_drv_remove, | 848 | .remove = ux500_msp_drv_remove, |
diff --git a/sound/soc/ux500/ux500_msp_i2s.c b/sound/soc/ux500/ux500_msp_i2s.c index 1b7c2f58ce13..b7c996e77570 100644 --- a/sound/soc/ux500/ux500_msp_i2s.c +++ b/sound/soc/ux500/ux500_msp_i2s.c | |||
@@ -15,8 +15,10 @@ | |||
15 | 15 | ||
16 | #include <linux/module.h> | 16 | #include <linux/module.h> |
17 | #include <linux/platform_device.h> | 17 | #include <linux/platform_device.h> |
18 | #include <linux/pinctrl/consumer.h> | ||
18 | #include <linux/delay.h> | 19 | #include <linux/delay.h> |
19 | #include <linux/slab.h> | 20 | #include <linux/slab.h> |
21 | #include <linux/of.h> | ||
20 | 22 | ||
21 | #include <mach/hardware.h> | 23 | #include <mach/hardware.h> |
22 | #include <mach/msp.h> | 24 | #include <mach/msp.h> |
@@ -25,6 +27,9 @@ | |||
25 | 27 | ||
26 | #include "ux500_msp_i2s.h" | 28 | #include "ux500_msp_i2s.h" |
27 | 29 | ||
30 | /* MSP1/3 Tx/Rx usage protection */ | ||
31 | static DEFINE_SPINLOCK(msp_rxtx_lock); | ||
32 | |||
28 | /* Protocol desciptors */ | 33 | /* Protocol desciptors */ |
29 | static const struct msp_protdesc prot_descs[] = { | 34 | static const struct msp_protdesc prot_descs[] = { |
30 | { /* I2S */ | 35 | { /* I2S */ |
@@ -352,17 +357,23 @@ static int configure_multichannel(struct ux500_msp *msp, | |||
352 | 357 | ||
353 | static int enable_msp(struct ux500_msp *msp, struct ux500_msp_config *config) | 358 | static int enable_msp(struct ux500_msp *msp, struct ux500_msp_config *config) |
354 | { | 359 | { |
355 | int status = 0; | 360 | int status = 0, retval = 0; |
356 | u32 reg_val_DMACR, reg_val_GCR; | 361 | u32 reg_val_DMACR, reg_val_GCR; |
362 | unsigned long flags; | ||
357 | 363 | ||
358 | /* Check msp state whether in RUN or CONFIGURED Mode */ | 364 | /* Check msp state whether in RUN or CONFIGURED Mode */ |
359 | if ((msp->msp_state == MSP_STATE_IDLE) && (msp->plat_init)) { | 365 | if (msp->msp_state == MSP_STATE_IDLE) { |
360 | status = msp->plat_init(); | 366 | spin_lock_irqsave(&msp_rxtx_lock, flags); |
361 | if (status) { | 367 | if (msp->pinctrl_rxtx_ref == 0 && |
362 | dev_err(msp->dev, "%s: ERROR: Failed to init MSP (%d)!\n", | 368 | !(IS_ERR(msp->pinctrl_p) || IS_ERR(msp->pinctrl_def))) { |
363 | __func__, status); | 369 | retval = pinctrl_select_state(msp->pinctrl_p, |
364 | return status; | 370 | msp->pinctrl_def); |
371 | if (retval) | ||
372 | pr_err("could not set MSP defstate\n"); | ||
365 | } | 373 | } |
374 | if (!retval) | ||
375 | msp->pinctrl_rxtx_ref++; | ||
376 | spin_unlock_irqrestore(&msp_rxtx_lock, flags); | ||
366 | } | 377 | } |
367 | 378 | ||
368 | /* Configure msp with protocol dependent settings */ | 379 | /* Configure msp with protocol dependent settings */ |
@@ -620,7 +631,8 @@ int ux500_msp_i2s_trigger(struct ux500_msp *msp, int cmd, int direction) | |||
620 | 631 | ||
621 | int ux500_msp_i2s_close(struct ux500_msp *msp, unsigned int dir) | 632 | int ux500_msp_i2s_close(struct ux500_msp *msp, unsigned int dir) |
622 | { | 633 | { |
623 | int status = 0; | 634 | int status = 0, retval = 0; |
635 | unsigned long flags; | ||
624 | 636 | ||
625 | dev_dbg(msp->dev, "%s: Enter (dir = 0x%01x).\n", __func__, dir); | 637 | dev_dbg(msp->dev, "%s: Enter (dir = 0x%01x).\n", __func__, dir); |
626 | 638 | ||
@@ -631,12 +643,19 @@ int ux500_msp_i2s_close(struct ux500_msp *msp, unsigned int dir) | |||
631 | writel((readl(msp->registers + MSP_GCR) & | 643 | writel((readl(msp->registers + MSP_GCR) & |
632 | (~(FRAME_GEN_ENABLE | SRG_ENABLE))), | 644 | (~(FRAME_GEN_ENABLE | SRG_ENABLE))), |
633 | msp->registers + MSP_GCR); | 645 | msp->registers + MSP_GCR); |
634 | if (msp->plat_exit) | 646 | |
635 | status = msp->plat_exit(); | 647 | spin_lock_irqsave(&msp_rxtx_lock, flags); |
636 | if (status) | 648 | WARN_ON(!msp->pinctrl_rxtx_ref); |
637 | dev_warn(msp->dev, | 649 | msp->pinctrl_rxtx_ref--; |
638 | "%s: WARN: ux500_msp_i2s_exit failed (%d)!\n", | 650 | if (msp->pinctrl_rxtx_ref == 0 && |
639 | __func__, status); | 651 | !(IS_ERR(msp->pinctrl_p) || IS_ERR(msp->pinctrl_sleep))) { |
652 | retval = pinctrl_select_state(msp->pinctrl_p, | ||
653 | msp->pinctrl_sleep); | ||
654 | if (retval) | ||
655 | pr_err("could not set MSP sleepstate\n"); | ||
656 | } | ||
657 | spin_unlock_irqrestore(&msp_rxtx_lock, flags); | ||
658 | |||
640 | writel(0, msp->registers + MSP_GCR); | 659 | writel(0, msp->registers + MSP_GCR); |
641 | writel(0, msp->registers + MSP_TCF); | 660 | writel(0, msp->registers + MSP_TCF); |
642 | writel(0, msp->registers + MSP_RCF); | 661 | writel(0, msp->registers + MSP_RCF); |
@@ -665,20 +684,33 @@ int ux500_msp_i2s_init_msp(struct platform_device *pdev, | |||
665 | { | 684 | { |
666 | struct resource *res = NULL; | 685 | struct resource *res = NULL; |
667 | struct i2s_controller *i2s_cont; | 686 | struct i2s_controller *i2s_cont; |
687 | struct device_node *np = pdev->dev.of_node; | ||
668 | struct ux500_msp *msp; | 688 | struct ux500_msp *msp; |
669 | 689 | ||
670 | dev_dbg(&pdev->dev, "%s: Enter (name: %s, id: %d).\n", __func__, | ||
671 | pdev->name, platform_data->id); | ||
672 | |||
673 | *msp_p = devm_kzalloc(&pdev->dev, sizeof(struct ux500_msp), GFP_KERNEL); | 690 | *msp_p = devm_kzalloc(&pdev->dev, sizeof(struct ux500_msp), GFP_KERNEL); |
674 | msp = *msp_p; | 691 | msp = *msp_p; |
675 | if (!msp) | 692 | if (!msp) |
676 | return -ENOMEM; | 693 | return -ENOMEM; |
677 | 694 | ||
695 | if (np) { | ||
696 | if (!platform_data) { | ||
697 | platform_data = devm_kzalloc(&pdev->dev, | ||
698 | sizeof(struct msp_i2s_platform_data), GFP_KERNEL); | ||
699 | if (!platform_data) | ||
700 | ret = -ENOMEM; | ||
701 | } | ||
702 | } else | ||
703 | if (!platform_data) | ||
704 | ret = -EINVAL; | ||
705 | |||
706 | if (ret) | ||
707 | goto err_res; | ||
708 | |||
709 | dev_dbg(&pdev->dev, "%s: Enter (name: %s, id: %d).\n", __func__, | ||
710 | pdev->name, platform_data->id); | ||
711 | |||
678 | msp->id = platform_data->id; | 712 | msp->id = platform_data->id; |
679 | msp->dev = &pdev->dev; | 713 | msp->dev = &pdev->dev; |
680 | msp->plat_init = platform_data->msp_i2s_init; | ||
681 | msp->plat_exit = platform_data->msp_i2s_exit; | ||
682 | msp->dma_cfg_rx = platform_data->msp_i2s_dma_rx; | 714 | msp->dma_cfg_rx = platform_data->msp_i2s_dma_rx; |
683 | msp->dma_cfg_tx = platform_data->msp_i2s_dma_tx; | 715 | msp->dma_cfg_tx = platform_data->msp_i2s_dma_tx; |
684 | 716 | ||
@@ -715,6 +747,25 @@ int ux500_msp_i2s_init_msp(struct platform_device *pdev, | |||
715 | dev_dbg(&pdev->dev, "I2S device-name: '%s'\n", i2s_cont->name); | 747 | dev_dbg(&pdev->dev, "I2S device-name: '%s'\n", i2s_cont->name); |
716 | msp->i2s_cont = i2s_cont; | 748 | msp->i2s_cont = i2s_cont; |
717 | 749 | ||
750 | msp->pinctrl_p = pinctrl_get(msp->dev); | ||
751 | if (IS_ERR(msp->pinctrl_p)) | ||
752 | dev_err(&pdev->dev, "could not get MSP pinctrl\n"); | ||
753 | else { | ||
754 | msp->pinctrl_def = pinctrl_lookup_state(msp->pinctrl_p, | ||
755 | PINCTRL_STATE_DEFAULT); | ||
756 | if (IS_ERR(msp->pinctrl_def)) { | ||
757 | dev_err(&pdev->dev, | ||
758 | "could not get MSP defstate (%li)\n", | ||
759 | PTR_ERR(msp->pinctrl_def)); | ||
760 | } | ||
761 | msp->pinctrl_sleep = pinctrl_lookup_state(msp->pinctrl_p, | ||
762 | PINCTRL_STATE_SLEEP); | ||
763 | if (IS_ERR(msp->pinctrl_sleep)) | ||
764 | dev_err(&pdev->dev, | ||
765 | "could not get MSP idlestate (%li)\n", | ||
766 | PTR_ERR(msp->pinctrl_def)); | ||
767 | } | ||
768 | |||
718 | return 0; | 769 | return 0; |
719 | } | 770 | } |
720 | 771 | ||
diff --git a/sound/soc/ux500/ux500_msp_i2s.h b/sound/soc/ux500/ux500_msp_i2s.h index 2d9136da9865..1311c0df7628 100644 --- a/sound/soc/ux500/ux500_msp_i2s.h +++ b/sound/soc/ux500/ux500_msp_i2s.h | |||
@@ -524,14 +524,18 @@ struct ux500_msp { | |||
524 | struct dma_chan *rx_pipeid; | 524 | struct dma_chan *rx_pipeid; |
525 | enum msp_state msp_state; | 525 | enum msp_state msp_state; |
526 | int (*transfer) (struct ux500_msp *msp, struct i2s_message *message); | 526 | int (*transfer) (struct ux500_msp *msp, struct i2s_message *message); |
527 | int (*plat_init) (void); | ||
528 | int (*plat_exit) (void); | ||
529 | struct timer_list notify_timer; | 527 | struct timer_list notify_timer; |
530 | int def_elem_len; | 528 | int def_elem_len; |
531 | unsigned int dir_busy; | 529 | unsigned int dir_busy; |
532 | int loopback_enable; | 530 | int loopback_enable; |
533 | u32 backup_regs[MAX_MSP_BACKUP_REGS]; | 531 | u32 backup_regs[MAX_MSP_BACKUP_REGS]; |
534 | unsigned int f_bitclk; | 532 | unsigned int f_bitclk; |
533 | /* Pin modes */ | ||
534 | struct pinctrl *pinctrl_p; | ||
535 | struct pinctrl_state *pinctrl_def; | ||
536 | struct pinctrl_state *pinctrl_sleep; | ||
537 | /* Reference Count */ | ||
538 | int pinctrl_rxtx_ref; | ||
535 | }; | 539 | }; |
536 | 540 | ||
537 | struct ux500_msp_dma_params { | 541 | struct ux500_msp_dma_params { |