diff options
Diffstat (limited to 'sound/soc')
75 files changed, 1715 insertions, 690 deletions
diff --git a/sound/soc/Kconfig b/sound/soc/Kconfig index c5de0a84566f..c24de902f5f5 100644 --- a/sound/soc/Kconfig +++ b/sound/soc/Kconfig | |||
@@ -9,6 +9,7 @@ menuconfig SND_SOC | |||
9 | select SND_JACK if INPUT=y || INPUT=SND | 9 | select SND_JACK if INPUT=y || INPUT=SND |
10 | select REGMAP_I2C if I2C | 10 | select REGMAP_I2C if I2C |
11 | select REGMAP_SPI if SPI_MASTER | 11 | select REGMAP_SPI if SPI_MASTER |
12 | select SND_COMPRESS_OFFLOAD | ||
12 | ---help--- | 13 | ---help--- |
13 | 14 | ||
14 | If you want ASoC support, you should say Y here and also to the | 15 | If you want ASoC support, you should say Y here and also to the |
diff --git a/sound/soc/Makefile b/sound/soc/Makefile index 00a555a743b6..c1264007b4ee 100644 --- a/sound/soc/Makefile +++ b/sound/soc/Makefile | |||
@@ -1,5 +1,5 @@ | |||
1 | snd-soc-core-objs := soc-core.o soc-dapm.o soc-jack.o soc-cache.o soc-utils.o | 1 | snd-soc-core-objs := soc-core.o soc-dapm.o soc-jack.o soc-cache.o soc-utils.o |
2 | snd-soc-core-objs += soc-pcm.o soc-io.o | 2 | snd-soc-core-objs += soc-pcm.o soc-compress.o soc-io.o |
3 | 3 | ||
4 | snd-soc-dmaengine-pcm-objs := soc-dmaengine-pcm.o | 4 | snd-soc-dmaengine-pcm-objs := soc-dmaengine-pcm.o |
5 | obj-$(CONFIG_SND_SOC_DMAENGINE_PCM) += snd-soc-dmaengine-pcm.o | 5 | obj-$(CONFIG_SND_SOC_DMAENGINE_PCM) += snd-soc-dmaengine-pcm.o |
diff --git a/sound/soc/blackfin/bf5xx-ad1836.c b/sound/soc/blackfin/bf5xx-ad1836.c index d542d4063771..16b9c9efd19a 100644 --- a/sound/soc/blackfin/bf5xx-ad1836.c +++ b/sound/soc/blackfin/bf5xx-ad1836.c | |||
@@ -59,62 +59,63 @@ static struct snd_soc_ops bf5xx_ad1836_ops = { | |||
59 | #define BF5XX_AD1836_DAIFMT (SND_SOC_DAIFMT_DSP_A | SND_SOC_DAIFMT_IB_IF | \ | 59 | #define BF5XX_AD1836_DAIFMT (SND_SOC_DAIFMT_DSP_A | SND_SOC_DAIFMT_IB_IF | \ |
60 | SND_SOC_DAIFMT_CBM_CFM) | 60 | SND_SOC_DAIFMT_CBM_CFM) |
61 | 61 | ||
62 | static struct snd_soc_dai_link bf5xx_ad1836_dai[] = { | 62 | static struct snd_soc_dai_link bf5xx_ad1836_dai = { |
63 | { | 63 | .name = "ad1836", |
64 | .name = "ad1836", | 64 | .stream_name = "AD1836", |
65 | .stream_name = "AD1836", | 65 | .codec_dai_name = "ad1836-hifi", |
66 | .cpu_dai_name = "bfin-tdm.0", | 66 | .platform_name = "bfin-tdm-pcm-audio", |
67 | .codec_dai_name = "ad1836-hifi", | 67 | .ops = &bf5xx_ad1836_ops, |
68 | .platform_name = "bfin-tdm-pcm-audio", | 68 | .dai_fmt = BF5XX_AD1836_DAIFMT, |
69 | .codec_name = "spi0.4", | ||
70 | .ops = &bf5xx_ad1836_ops, | ||
71 | .dai_fmt = BF5XX_AD1836_DAIFMT, | ||
72 | }, | ||
73 | { | ||
74 | .name = "ad1836", | ||
75 | .stream_name = "AD1836", | ||
76 | .cpu_dai_name = "bfin-tdm.1", | ||
77 | .codec_dai_name = "ad1836-hifi", | ||
78 | .platform_name = "bfin-tdm-pcm-audio", | ||
79 | .codec_name = "spi0.4", | ||
80 | .ops = &bf5xx_ad1836_ops, | ||
81 | .dai_fmt = BF5XX_AD1836_DAIFMT, | ||
82 | }, | ||
83 | }; | 69 | }; |
84 | 70 | ||
85 | static struct snd_soc_card bf5xx_ad1836 = { | 71 | static struct snd_soc_card bf5xx_ad1836 = { |
86 | .name = "bfin-ad1836", | 72 | .name = "bfin-ad1836", |
87 | .owner = THIS_MODULE, | 73 | .owner = THIS_MODULE, |
88 | .dai_link = &bf5xx_ad1836_dai[CONFIG_SND_BF5XX_SPORT_NUM], | 74 | .dai_link = &bf5xx_ad1836_dai, |
89 | .num_links = 1, | 75 | .num_links = 1, |
90 | }; | 76 | }; |
91 | 77 | ||
92 | static struct platform_device *bfxx_ad1836_snd_device; | 78 | static __devinit int bf5xx_ad1836_driver_probe(struct platform_device *pdev) |
93 | |||
94 | static int __init bf5xx_ad1836_init(void) | ||
95 | { | 79 | { |
80 | struct snd_soc_card *card = &bf5xx_ad1836; | ||
81 | const char **link_name; | ||
96 | int ret; | 82 | int ret; |
97 | 83 | ||
98 | bfxx_ad1836_snd_device = platform_device_alloc("soc-audio", -1); | 84 | link_name = pdev->dev.platform_data; |
99 | if (!bfxx_ad1836_snd_device) | 85 | if (!link_name) { |
100 | return -ENOMEM; | 86 | dev_err(&pdev->dev, "No platform data supplied\n"); |
87 | return -EINVAL; | ||
88 | } | ||
89 | bf5xx_ad1836_dai.cpu_dai_name = link_name[0]; | ||
90 | bf5xx_ad1836_dai.codec_name = link_name[1]; | ||
101 | 91 | ||
102 | platform_set_drvdata(bfxx_ad1836_snd_device, &bf5xx_ad1836); | 92 | card->dev = &pdev->dev; |
103 | ret = platform_device_add(bfxx_ad1836_snd_device); | 93 | platform_set_drvdata(pdev, card); |
104 | 94 | ||
95 | ret = snd_soc_register_card(card); | ||
105 | if (ret) | 96 | if (ret) |
106 | platform_device_put(bfxx_ad1836_snd_device); | 97 | dev_err(&pdev->dev, "Failed to register card\n"); |
107 | |||
108 | return ret; | 98 | return ret; |
109 | } | 99 | } |
110 | 100 | ||
111 | static void __exit bf5xx_ad1836_exit(void) | 101 | static int __devexit bf5xx_ad1836_driver_remove(struct platform_device *pdev) |
112 | { | 102 | { |
113 | platform_device_unregister(bfxx_ad1836_snd_device); | 103 | struct snd_soc_card *card = platform_get_drvdata(pdev); |
104 | |||
105 | snd_soc_unregister_card(card); | ||
106 | return 0; | ||
114 | } | 107 | } |
115 | 108 | ||
116 | module_init(bf5xx_ad1836_init); | 109 | static struct platform_driver bf5xx_ad1836_driver = { |
117 | module_exit(bf5xx_ad1836_exit); | 110 | .driver = { |
111 | .name = "bfin-snd-ad1836", | ||
112 | .owner = THIS_MODULE, | ||
113 | .pm = &snd_soc_pm_ops, | ||
114 | }, | ||
115 | .probe = bf5xx_ad1836_driver_probe, | ||
116 | .remove = __devexit_p(bf5xx_ad1836_driver_remove), | ||
117 | }; | ||
118 | module_platform_driver(bf5xx_ad1836_driver); | ||
118 | 119 | ||
119 | /* Module information */ | 120 | /* Module information */ |
120 | MODULE_AUTHOR("Barry Song"); | 121 | MODULE_AUTHOR("Barry Song"); |
diff --git a/sound/soc/codecs/ab8500-codec.c b/sound/soc/codecs/ab8500-codec.c index 3c795921c5f6..b7836503dc69 100644 --- a/sound/soc/codecs/ab8500-codec.c +++ b/sound/soc/codecs/ab8500-codec.c | |||
@@ -2404,8 +2404,12 @@ static int ab8500_codec_probe(struct snd_soc_codec *codec) | |||
2404 | 2404 | ||
2405 | dev_dbg(dev, "%s: Enter.\n", __func__); | 2405 | dev_dbg(dev, "%s: Enter.\n", __func__); |
2406 | 2406 | ||
2407 | /* Inform SoC Core that we have our own I/O arrangements. */ | ||
2408 | codec->control_data = (void *)true; | ||
2409 | |||
2407 | /* Setup AB8500 according to board-settings */ | 2410 | /* Setup AB8500 according to board-settings */ |
2408 | pdata = (struct ab8500_platform_data *)dev_get_platdata(dev->parent); | 2411 | pdata = dev_get_platdata(dev->parent); |
2412 | |||
2409 | status = ab8500_audio_setup_mics(codec, &pdata->codec->amics); | 2413 | status = ab8500_audio_setup_mics(codec, &pdata->codec->amics); |
2410 | if (status < 0) { | 2414 | if (status < 0) { |
2411 | pr_err("%s: Failed to setup mics (%d)!\n", __func__, status); | 2415 | pr_err("%s: Failed to setup mics (%d)!\n", __func__, status); |
diff --git a/sound/soc/codecs/ad1980.c b/sound/soc/codecs/ad1980.c index 8c39dddd7d00..11b1b714b8b5 100644 --- a/sound/soc/codecs/ad1980.c +++ b/sound/soc/codecs/ad1980.c | |||
@@ -186,6 +186,7 @@ static int ad1980_soc_probe(struct snd_soc_codec *codec) | |||
186 | 186 | ||
187 | printk(KERN_INFO "AD1980 SoC Audio Codec\n"); | 187 | printk(KERN_INFO "AD1980 SoC Audio Codec\n"); |
188 | 188 | ||
189 | codec->control_data = codec; /* we don't use regmap! */ | ||
189 | ret = snd_soc_new_ac97_codec(codec, &soc_ac97_ops, 0); | 190 | ret = snd_soc_new_ac97_codec(codec, &soc_ac97_ops, 0); |
190 | if (ret < 0) { | 191 | if (ret < 0) { |
191 | printk(KERN_ERR "ad1980: failed to register AC97 codec\n"); | 192 | printk(KERN_ERR "ad1980: failed to register AC97 codec\n"); |
diff --git a/sound/soc/codecs/adau1373.c b/sound/soc/codecs/adau1373.c index 44f59064d8de..704544bfc90d 100644 --- a/sound/soc/codecs/adau1373.c +++ b/sound/soc/codecs/adau1373.c | |||
@@ -1392,17 +1392,7 @@ static struct i2c_driver adau1373_i2c_driver = { | |||
1392 | .id_table = adau1373_i2c_id, | 1392 | .id_table = adau1373_i2c_id, |
1393 | }; | 1393 | }; |
1394 | 1394 | ||
1395 | static int __init adau1373_init(void) | 1395 | module_i2c_driver(adau1373_i2c_driver); |
1396 | { | ||
1397 | return i2c_add_driver(&adau1373_i2c_driver); | ||
1398 | } | ||
1399 | module_init(adau1373_init); | ||
1400 | |||
1401 | static void __exit adau1373_exit(void) | ||
1402 | { | ||
1403 | i2c_del_driver(&adau1373_i2c_driver); | ||
1404 | } | ||
1405 | module_exit(adau1373_exit); | ||
1406 | 1396 | ||
1407 | MODULE_DESCRIPTION("ASoC ADAU1373 driver"); | 1397 | MODULE_DESCRIPTION("ASoC ADAU1373 driver"); |
1408 | MODULE_AUTHOR("Lars-Peter Clausen <lars@metafoo.de>"); | 1398 | MODULE_AUTHOR("Lars-Peter Clausen <lars@metafoo.de>"); |
diff --git a/sound/soc/codecs/adau1701.c b/sound/soc/codecs/adau1701.c index 3d50fc8646b6..51f2f3cd8136 100644 --- a/sound/soc/codecs/adau1701.c +++ b/sound/soc/codecs/adau1701.c | |||
@@ -527,17 +527,7 @@ static struct i2c_driver adau1701_i2c_driver = { | |||
527 | .id_table = adau1701_i2c_id, | 527 | .id_table = adau1701_i2c_id, |
528 | }; | 528 | }; |
529 | 529 | ||
530 | static int __init adau1701_init(void) | 530 | module_i2c_driver(adau1701_i2c_driver); |
531 | { | ||
532 | return i2c_add_driver(&adau1701_i2c_driver); | ||
533 | } | ||
534 | module_init(adau1701_init); | ||
535 | |||
536 | static void __exit adau1701_exit(void) | ||
537 | { | ||
538 | i2c_del_driver(&adau1701_i2c_driver); | ||
539 | } | ||
540 | module_exit(adau1701_exit); | ||
541 | 531 | ||
542 | MODULE_DESCRIPTION("ASoC ADAU1701 SigmaDSP driver"); | 532 | MODULE_DESCRIPTION("ASoC ADAU1701 SigmaDSP driver"); |
543 | MODULE_AUTHOR("Cliff Cai <cliff.cai@analog.com>"); | 533 | MODULE_AUTHOR("Cliff Cai <cliff.cai@analog.com>"); |
diff --git a/sound/soc/codecs/ak4671.c b/sound/soc/codecs/ak4671.c index 5fb7c2a80e6d..2b457976a7bf 100644 --- a/sound/soc/codecs/ak4671.c +++ b/sound/soc/codecs/ak4671.c | |||
@@ -696,17 +696,7 @@ static struct i2c_driver ak4671_i2c_driver = { | |||
696 | .id_table = ak4671_i2c_id, | 696 | .id_table = ak4671_i2c_id, |
697 | }; | 697 | }; |
698 | 698 | ||
699 | static int __init ak4671_modinit(void) | 699 | module_i2c_driver(ak4671_i2c_driver); |
700 | { | ||
701 | return i2c_add_driver(&ak4671_i2c_driver); | ||
702 | } | ||
703 | module_init(ak4671_modinit); | ||
704 | |||
705 | static void __exit ak4671_exit(void) | ||
706 | { | ||
707 | i2c_del_driver(&ak4671_i2c_driver); | ||
708 | } | ||
709 | module_exit(ak4671_exit); | ||
710 | 700 | ||
711 | MODULE_DESCRIPTION("ASoC AK4671 codec driver"); | 701 | MODULE_DESCRIPTION("ASoC AK4671 codec driver"); |
712 | MODULE_AUTHOR("Joonyoung Shim <jy0922.shim@samsung.com>"); | 702 | MODULE_AUTHOR("Joonyoung Shim <jy0922.shim@samsung.com>"); |
diff --git a/sound/soc/codecs/arizona.c b/sound/soc/codecs/arizona.c index 5c9cacaf2d52..5e96a0a1669c 100644 --- a/sound/soc/codecs/arizona.c +++ b/sound/soc/codecs/arizona.c | |||
@@ -229,6 +229,69 @@ int arizona_out_ev(struct snd_soc_dapm_widget *w, | |||
229 | } | 229 | } |
230 | EXPORT_SYMBOL_GPL(arizona_out_ev); | 230 | EXPORT_SYMBOL_GPL(arizona_out_ev); |
231 | 231 | ||
232 | static unsigned int arizona_sysclk_48k_rates[] = { | ||
233 | 6144000, | ||
234 | 12288000, | ||
235 | 22579200, | ||
236 | 49152000, | ||
237 | }; | ||
238 | |||
239 | static unsigned int arizona_sysclk_44k1_rates[] = { | ||
240 | 5644800, | ||
241 | 11289600, | ||
242 | 24576000, | ||
243 | 45158400, | ||
244 | }; | ||
245 | |||
246 | static int arizona_set_opclk(struct snd_soc_codec *codec, unsigned int clk, | ||
247 | unsigned int freq) | ||
248 | { | ||
249 | struct arizona_priv *priv = snd_soc_codec_get_drvdata(codec); | ||
250 | unsigned int reg; | ||
251 | unsigned int *rates; | ||
252 | int ref, div, refclk; | ||
253 | |||
254 | switch (clk) { | ||
255 | case ARIZONA_CLK_OPCLK: | ||
256 | reg = ARIZONA_OUTPUT_SYSTEM_CLOCK; | ||
257 | refclk = priv->sysclk; | ||
258 | break; | ||
259 | case ARIZONA_CLK_ASYNC_OPCLK: | ||
260 | reg = ARIZONA_OUTPUT_ASYNC_CLOCK; | ||
261 | refclk = priv->asyncclk; | ||
262 | break; | ||
263 | default: | ||
264 | return -EINVAL; | ||
265 | } | ||
266 | |||
267 | if (refclk % 8000) | ||
268 | rates = arizona_sysclk_44k1_rates; | ||
269 | else | ||
270 | rates = arizona_sysclk_48k_rates; | ||
271 | |||
272 | for (ref = 0; ref < ARRAY_SIZE(arizona_sysclk_48k_rates) && | ||
273 | rates[ref] <= refclk; ref++) { | ||
274 | div = 1; | ||
275 | while (rates[ref] / div >= freq && div < 32) { | ||
276 | if (rates[ref] / div == freq) { | ||
277 | dev_dbg(codec->dev, "Configured %dHz OPCLK\n", | ||
278 | freq); | ||
279 | snd_soc_update_bits(codec, reg, | ||
280 | ARIZONA_OPCLK_DIV_MASK | | ||
281 | ARIZONA_OPCLK_SEL_MASK, | ||
282 | (div << | ||
283 | ARIZONA_OPCLK_DIV_SHIFT) | | ||
284 | ref); | ||
285 | return 0; | ||
286 | } | ||
287 | div++; | ||
288 | } | ||
289 | } | ||
290 | |||
291 | dev_err(codec->dev, "Unable to generate %dHz OPCLK\n", freq); | ||
292 | return -EINVAL; | ||
293 | } | ||
294 | |||
232 | int arizona_set_sysclk(struct snd_soc_codec *codec, int clk_id, | 295 | int arizona_set_sysclk(struct snd_soc_codec *codec, int clk_id, |
233 | int source, unsigned int freq, int dir) | 296 | int source, unsigned int freq, int dir) |
234 | { | 297 | { |
@@ -252,6 +315,9 @@ int arizona_set_sysclk(struct snd_soc_codec *codec, int clk_id, | |||
252 | reg = ARIZONA_ASYNC_CLOCK_1; | 315 | reg = ARIZONA_ASYNC_CLOCK_1; |
253 | clk = &priv->asyncclk; | 316 | clk = &priv->asyncclk; |
254 | break; | 317 | break; |
318 | case ARIZONA_CLK_OPCLK: | ||
319 | case ARIZONA_CLK_ASYNC_OPCLK: | ||
320 | return arizona_set_opclk(codec, clk_id, freq); | ||
255 | default: | 321 | default: |
256 | return -EINVAL; | 322 | return -EINVAL; |
257 | } | 323 | } |
diff --git a/sound/soc/codecs/arizona.h b/sound/soc/codecs/arizona.h index 59caca8865e8..eb66b52777c9 100644 --- a/sound/soc/codecs/arizona.h +++ b/sound/soc/codecs/arizona.h | |||
@@ -17,8 +17,10 @@ | |||
17 | 17 | ||
18 | #include <sound/soc.h> | 18 | #include <sound/soc.h> |
19 | 19 | ||
20 | #define ARIZONA_CLK_SYSCLK 1 | 20 | #define ARIZONA_CLK_SYSCLK 1 |
21 | #define ARIZONA_CLK_ASYNCCLK 2 | 21 | #define ARIZONA_CLK_ASYNCCLK 2 |
22 | #define ARIZONA_CLK_OPCLK 3 | ||
23 | #define ARIZONA_CLK_ASYNC_OPCLK 4 | ||
22 | 24 | ||
23 | #define ARIZONA_CLK_SRC_MCLK1 0x0 | 25 | #define ARIZONA_CLK_SRC_MCLK1 0x0 |
24 | #define ARIZONA_CLK_SRC_MCLK2 0x1 | 26 | #define ARIZONA_CLK_SRC_MCLK2 0x1 |
diff --git a/sound/soc/codecs/cs4270.c b/sound/soc/codecs/cs4270.c index 047917f0b8ae..44a176f74170 100644 --- a/sound/soc/codecs/cs4270.c +++ b/sound/soc/codecs/cs4270.c | |||
@@ -29,6 +29,8 @@ | |||
29 | #include <linux/i2c.h> | 29 | #include <linux/i2c.h> |
30 | #include <linux/delay.h> | 30 | #include <linux/delay.h> |
31 | #include <linux/regulator/consumer.h> | 31 | #include <linux/regulator/consumer.h> |
32 | #include <linux/of_device.h> | ||
33 | #include <linux/of_gpio.h> | ||
32 | 34 | ||
33 | /* | 35 | /* |
34 | * The codec isn't really big-endian or little-endian, since the I2S | 36 | * The codec isn't really big-endian or little-endian, since the I2S |
@@ -639,6 +641,15 @@ static const struct snd_soc_codec_driver soc_codec_device_cs4270 = { | |||
639 | .reg_cache_default = cs4270_default_reg_cache, | 641 | .reg_cache_default = cs4270_default_reg_cache, |
640 | }; | 642 | }; |
641 | 643 | ||
644 | /* | ||
645 | * cs4270_of_match - the device tree bindings | ||
646 | */ | ||
647 | static const struct of_device_id cs4270_of_match[] = { | ||
648 | { .compatible = "cirrus,cs4270", }, | ||
649 | { } | ||
650 | }; | ||
651 | MODULE_DEVICE_TABLE(of, cs4270_of_match); | ||
652 | |||
642 | /** | 653 | /** |
643 | * cs4270_i2c_probe - initialize the I2C interface of the CS4270 | 654 | * cs4270_i2c_probe - initialize the I2C interface of the CS4270 |
644 | * @i2c_client: the I2C client object | 655 | * @i2c_client: the I2C client object |
@@ -650,9 +661,25 @@ static const struct snd_soc_codec_driver soc_codec_device_cs4270 = { | |||
650 | static int cs4270_i2c_probe(struct i2c_client *i2c_client, | 661 | static int cs4270_i2c_probe(struct i2c_client *i2c_client, |
651 | const struct i2c_device_id *id) | 662 | const struct i2c_device_id *id) |
652 | { | 663 | { |
664 | struct device_node *np = i2c_client->dev.of_node; | ||
653 | struct cs4270_private *cs4270; | 665 | struct cs4270_private *cs4270; |
654 | int ret; | 666 | int ret; |
655 | 667 | ||
668 | /* See if we have a way to bring the codec out of reset */ | ||
669 | if (np) { | ||
670 | enum of_gpio_flags flags; | ||
671 | int gpio = of_get_named_gpio_flags(np, "reset-gpio", 0, &flags); | ||
672 | |||
673 | if (gpio_is_valid(gpio)) { | ||
674 | ret = devm_gpio_request_one(&i2c_client->dev, gpio, | ||
675 | flags & OF_GPIO_ACTIVE_LOW ? | ||
676 | GPIOF_OUT_INIT_LOW : GPIOF_OUT_INIT_HIGH, | ||
677 | "cs4270 reset"); | ||
678 | if (ret < 0) | ||
679 | return ret; | ||
680 | } | ||
681 | } | ||
682 | |||
656 | /* Verify that we have a CS4270 */ | 683 | /* Verify that we have a CS4270 */ |
657 | 684 | ||
658 | ret = i2c_smbus_read_byte_data(i2c_client, CS4270_CHIPID); | 685 | ret = i2c_smbus_read_byte_data(i2c_client, CS4270_CHIPID); |
@@ -718,23 +745,14 @@ static struct i2c_driver cs4270_i2c_driver = { | |||
718 | .driver = { | 745 | .driver = { |
719 | .name = "cs4270", | 746 | .name = "cs4270", |
720 | .owner = THIS_MODULE, | 747 | .owner = THIS_MODULE, |
748 | .of_match_table = cs4270_of_match, | ||
721 | }, | 749 | }, |
722 | .id_table = cs4270_id, | 750 | .id_table = cs4270_id, |
723 | .probe = cs4270_i2c_probe, | 751 | .probe = cs4270_i2c_probe, |
724 | .remove = cs4270_i2c_remove, | 752 | .remove = cs4270_i2c_remove, |
725 | }; | 753 | }; |
726 | 754 | ||
727 | static int __init cs4270_init(void) | 755 | module_i2c_driver(cs4270_i2c_driver); |
728 | { | ||
729 | return i2c_add_driver(&cs4270_i2c_driver); | ||
730 | } | ||
731 | module_init(cs4270_init); | ||
732 | |||
733 | static void __exit cs4270_exit(void) | ||
734 | { | ||
735 | i2c_del_driver(&cs4270_i2c_driver); | ||
736 | } | ||
737 | module_exit(cs4270_exit); | ||
738 | 756 | ||
739 | MODULE_AUTHOR("Timur Tabi <timur@freescale.com>"); | 757 | MODULE_AUTHOR("Timur Tabi <timur@freescale.com>"); |
740 | MODULE_DESCRIPTION("Cirrus Logic CS4270 ALSA SoC Codec Driver"); | 758 | MODULE_DESCRIPTION("Cirrus Logic CS4270 ALSA SoC Codec Driver"); |
diff --git a/sound/soc/codecs/cs42l51.c b/sound/soc/codecs/cs42l51.c index 091d0193f507..1e0fa3b5f79a 100644 --- a/sound/soc/codecs/cs42l51.c +++ b/sound/soc/codecs/cs42l51.c | |||
@@ -614,24 +614,7 @@ static struct i2c_driver cs42l51_i2c_driver = { | |||
614 | .remove = cs42l51_i2c_remove, | 614 | .remove = cs42l51_i2c_remove, |
615 | }; | 615 | }; |
616 | 616 | ||
617 | static int __init cs42l51_init(void) | 617 | module_i2c_driver(cs42l51_i2c_driver); |
618 | { | ||
619 | int ret; | ||
620 | |||
621 | ret = i2c_add_driver(&cs42l51_i2c_driver); | ||
622 | if (ret != 0) { | ||
623 | printk(KERN_ERR "%s: can't add i2c driver\n", __func__); | ||
624 | return ret; | ||
625 | } | ||
626 | return 0; | ||
627 | } | ||
628 | module_init(cs42l51_init); | ||
629 | |||
630 | static void __exit cs42l51_exit(void) | ||
631 | { | ||
632 | i2c_del_driver(&cs42l51_i2c_driver); | ||
633 | } | ||
634 | module_exit(cs42l51_exit); | ||
635 | 618 | ||
636 | MODULE_AUTHOR("Arnaud Patard <arnaud.patard@rtp-net.org>"); | 619 | MODULE_AUTHOR("Arnaud Patard <arnaud.patard@rtp-net.org>"); |
637 | MODULE_DESCRIPTION("Cirrus Logic CS42L51 ALSA SoC Codec Driver"); | 620 | MODULE_DESCRIPTION("Cirrus Logic CS42L51 ALSA SoC Codec Driver"); |
diff --git a/sound/soc/codecs/cs42l52.c b/sound/soc/codecs/cs42l52.c index 628daf6a1d97..61599298fb26 100644 --- a/sound/soc/codecs/cs42l52.c +++ b/sound/soc/codecs/cs42l52.c | |||
@@ -24,7 +24,6 @@ | |||
24 | #include <linux/slab.h> | 24 | #include <linux/slab.h> |
25 | #include <linux/workqueue.h> | 25 | #include <linux/workqueue.h> |
26 | #include <linux/platform_device.h> | 26 | #include <linux/platform_device.h> |
27 | #include <linux/slab.h> | ||
28 | #include <sound/core.h> | 27 | #include <sound/core.h> |
29 | #include <sound/pcm.h> | 28 | #include <sound/pcm.h> |
30 | #include <sound/pcm_params.h> | 29 | #include <sound/pcm_params.h> |
diff --git a/sound/soc/codecs/isabelle.c b/sound/soc/codecs/isabelle.c index 5d8f39e32978..1bf55602c9eb 100644 --- a/sound/soc/codecs/isabelle.c +++ b/sound/soc/codecs/isabelle.c | |||
@@ -13,7 +13,6 @@ | |||
13 | */ | 13 | */ |
14 | #include <linux/module.h> | 14 | #include <linux/module.h> |
15 | #include <linux/moduleparam.h> | 15 | #include <linux/moduleparam.h> |
16 | #include <linux/version.h> | ||
17 | #include <linux/kernel.h> | 16 | #include <linux/kernel.h> |
18 | #include <linux/init.h> | 17 | #include <linux/init.h> |
19 | #include <linux/delay.h> | 18 | #include <linux/delay.h> |
diff --git a/sound/soc/codecs/lm4857.c b/sound/soc/codecs/lm4857.c index ba4fafb93e56..81a328c78838 100644 --- a/sound/soc/codecs/lm4857.c +++ b/sound/soc/codecs/lm4857.c | |||
@@ -250,17 +250,7 @@ static struct i2c_driver lm4857_i2c_driver = { | |||
250 | .id_table = lm4857_i2c_id, | 250 | .id_table = lm4857_i2c_id, |
251 | }; | 251 | }; |
252 | 252 | ||
253 | static int __init lm4857_init(void) | 253 | module_i2c_driver(lm4857_i2c_driver); |
254 | { | ||
255 | return i2c_add_driver(&lm4857_i2c_driver); | ||
256 | } | ||
257 | module_init(lm4857_init); | ||
258 | |||
259 | static void __exit lm4857_exit(void) | ||
260 | { | ||
261 | i2c_del_driver(&lm4857_i2c_driver); | ||
262 | } | ||
263 | module_exit(lm4857_exit); | ||
264 | 254 | ||
265 | MODULE_AUTHOR("Lars-Peter Clausen <lars@metafoo.de>"); | 255 | MODULE_AUTHOR("Lars-Peter Clausen <lars@metafoo.de>"); |
266 | MODULE_DESCRIPTION("LM4857 amplifier driver"); | 256 | MODULE_DESCRIPTION("LM4857 amplifier driver"); |
diff --git a/sound/soc/codecs/max98088.c b/sound/soc/codecs/max98088.c index af7324b79dd0..3264a5169306 100644 --- a/sound/soc/codecs/max98088.c +++ b/sound/soc/codecs/max98088.c | |||
@@ -2107,23 +2107,7 @@ static struct i2c_driver max98088_i2c_driver = { | |||
2107 | .id_table = max98088_i2c_id, | 2107 | .id_table = max98088_i2c_id, |
2108 | }; | 2108 | }; |
2109 | 2109 | ||
2110 | static int __init max98088_init(void) | 2110 | module_i2c_driver(max98088_i2c_driver); |
2111 | { | ||
2112 | int ret; | ||
2113 | |||
2114 | ret = i2c_add_driver(&max98088_i2c_driver); | ||
2115 | if (ret) | ||
2116 | pr_err("Failed to register max98088 I2C driver: %d\n", ret); | ||
2117 | |||
2118 | return ret; | ||
2119 | } | ||
2120 | module_init(max98088_init); | ||
2121 | |||
2122 | static void __exit max98088_exit(void) | ||
2123 | { | ||
2124 | i2c_del_driver(&max98088_i2c_driver); | ||
2125 | } | ||
2126 | module_exit(max98088_exit); | ||
2127 | 2111 | ||
2128 | MODULE_DESCRIPTION("ALSA SoC MAX98088 driver"); | 2112 | MODULE_DESCRIPTION("ALSA SoC MAX98088 driver"); |
2129 | MODULE_AUTHOR("Peter Hsiang, Jesse Marroquin"); | 2113 | MODULE_AUTHOR("Peter Hsiang, Jesse Marroquin"); |
diff --git a/sound/soc/codecs/max98095.c b/sound/soc/codecs/max98095.c index 7cd508e16a5c..38d43c59d3f4 100644 --- a/sound/soc/codecs/max98095.c +++ b/sound/soc/codecs/max98095.c | |||
@@ -2533,23 +2533,7 @@ static struct i2c_driver max98095_i2c_driver = { | |||
2533 | .id_table = max98095_i2c_id, | 2533 | .id_table = max98095_i2c_id, |
2534 | }; | 2534 | }; |
2535 | 2535 | ||
2536 | static int __init max98095_init(void) | 2536 | module_i2c_driver(max98095_i2c_driver); |
2537 | { | ||
2538 | int ret; | ||
2539 | |||
2540 | ret = i2c_add_driver(&max98095_i2c_driver); | ||
2541 | if (ret) | ||
2542 | pr_err("Failed to register max98095 I2C driver: %d\n", ret); | ||
2543 | |||
2544 | return ret; | ||
2545 | } | ||
2546 | module_init(max98095_init); | ||
2547 | |||
2548 | static void __exit max98095_exit(void) | ||
2549 | { | ||
2550 | i2c_del_driver(&max98095_i2c_driver); | ||
2551 | } | ||
2552 | module_exit(max98095_exit); | ||
2553 | 2537 | ||
2554 | MODULE_DESCRIPTION("ALSA SoC MAX98095 driver"); | 2538 | MODULE_DESCRIPTION("ALSA SoC MAX98095 driver"); |
2555 | MODULE_AUTHOR("Peter Hsiang"); | 2539 | MODULE_AUTHOR("Peter Hsiang"); |
diff --git a/sound/soc/codecs/max9850.c b/sound/soc/codecs/max9850.c index a1913091f56c..efe535c37b39 100644 --- a/sound/soc/codecs/max9850.c +++ b/sound/soc/codecs/max9850.c | |||
@@ -369,17 +369,7 @@ static struct i2c_driver max9850_i2c_driver = { | |||
369 | .id_table = max9850_i2c_id, | 369 | .id_table = max9850_i2c_id, |
370 | }; | 370 | }; |
371 | 371 | ||
372 | static int __init max9850_init(void) | 372 | module_i2c_driver(max9850_i2c_driver); |
373 | { | ||
374 | return i2c_add_driver(&max9850_i2c_driver); | ||
375 | } | ||
376 | module_init(max9850_init); | ||
377 | |||
378 | static void __exit max9850_exit(void) | ||
379 | { | ||
380 | i2c_del_driver(&max9850_i2c_driver); | ||
381 | } | ||
382 | module_exit(max9850_exit); | ||
383 | 373 | ||
384 | MODULE_AUTHOR("Christian Glindkamp <christian.glindkamp@taskit.de>"); | 374 | MODULE_AUTHOR("Christian Glindkamp <christian.glindkamp@taskit.de>"); |
385 | MODULE_DESCRIPTION("ASoC MAX9850 codec driver"); | 375 | MODULE_DESCRIPTION("ASoC MAX9850 codec driver"); |
diff --git a/sound/soc/codecs/max9877.c b/sound/soc/codecs/max9877.c index 3a2ba3d8fd6d..d15e5943c85e 100644 --- a/sound/soc/codecs/max9877.c +++ b/sound/soc/codecs/max9877.c | |||
@@ -291,17 +291,7 @@ static struct i2c_driver max9877_i2c_driver = { | |||
291 | .id_table = max9877_i2c_id, | 291 | .id_table = max9877_i2c_id, |
292 | }; | 292 | }; |
293 | 293 | ||
294 | static int __init max9877_init(void) | 294 | module_i2c_driver(max9877_i2c_driver); |
295 | { | ||
296 | return i2c_add_driver(&max9877_i2c_driver); | ||
297 | } | ||
298 | module_init(max9877_init); | ||
299 | |||
300 | static void __exit max9877_exit(void) | ||
301 | { | ||
302 | i2c_del_driver(&max9877_i2c_driver); | ||
303 | } | ||
304 | module_exit(max9877_exit); | ||
305 | 295 | ||
306 | MODULE_DESCRIPTION("ASoC MAX9877 amp driver"); | 296 | MODULE_DESCRIPTION("ASoC MAX9877 amp driver"); |
307 | MODULE_AUTHOR("Joonyoung Shim <jy0922.shim@samsung.com>"); | 297 | MODULE_AUTHOR("Joonyoung Shim <jy0922.shim@samsung.com>"); |
diff --git a/sound/soc/codecs/mc13783.c b/sound/soc/codecs/mc13783.c index 6276e352125f..8f726c063f42 100644 --- a/sound/soc/codecs/mc13783.c +++ b/sound/soc/codecs/mc13783.c | |||
@@ -581,6 +581,8 @@ static int mc13783_probe(struct snd_soc_codec *codec) | |||
581 | { | 581 | { |
582 | struct mc13783_priv *priv = snd_soc_codec_get_drvdata(codec); | 582 | struct mc13783_priv *priv = snd_soc_codec_get_drvdata(codec); |
583 | 583 | ||
584 | codec->control_data = priv->mc13xxx; | ||
585 | |||
584 | mc13xxx_lock(priv->mc13xxx); | 586 | mc13xxx_lock(priv->mc13xxx); |
585 | 587 | ||
586 | /* these are the reset values */ | 588 | /* these are the reset values */ |
diff --git a/sound/soc/codecs/sgtl5000.c b/sound/soc/codecs/sgtl5000.c index 8af6a5245b18..df2f99d1d428 100644 --- a/sound/soc/codecs/sgtl5000.c +++ b/sound/soc/codecs/sgtl5000.c | |||
@@ -239,6 +239,7 @@ static const struct snd_soc_dapm_route sgtl5000_dapm_routes[] = { | |||
239 | {"Headphone Mux", "DAC", "DAC"}, /* dac --> hp_mux */ | 239 | {"Headphone Mux", "DAC", "DAC"}, /* dac --> hp_mux */ |
240 | {"LO", NULL, "DAC"}, /* dac --> line_out */ | 240 | {"LO", NULL, "DAC"}, /* dac --> line_out */ |
241 | 241 | ||
242 | {"LINE_IN", NULL, "VAG_POWER"}, | ||
242 | {"Headphone Mux", "LINE_IN", "LINE_IN"},/* line_in --> hp_mux */ | 243 | {"Headphone Mux", "LINE_IN", "LINE_IN"},/* line_in --> hp_mux */ |
243 | {"HP", NULL, "Headphone Mux"}, /* hp_mux --> hp */ | 244 | {"HP", NULL, "Headphone Mux"}, /* hp_mux --> hp */ |
244 | 245 | ||
@@ -1357,8 +1358,6 @@ static int sgtl5000_probe(struct snd_soc_codec *codec) | |||
1357 | if (ret) | 1358 | if (ret) |
1358 | goto err; | 1359 | goto err; |
1359 | 1360 | ||
1360 | snd_soc_dapm_new_widgets(&codec->dapm); | ||
1361 | |||
1362 | return 0; | 1361 | return 0; |
1363 | 1362 | ||
1364 | err: | 1363 | err: |
diff --git a/sound/soc/codecs/sta32x.c b/sound/soc/codecs/sta32x.c index 8d717f4b5a87..51b7313a4c14 100644 --- a/sound/soc/codecs/sta32x.c +++ b/sound/soc/codecs/sta32x.c | |||
@@ -1006,17 +1006,7 @@ static struct i2c_driver sta32x_i2c_driver = { | |||
1006 | .id_table = sta32x_i2c_id, | 1006 | .id_table = sta32x_i2c_id, |
1007 | }; | 1007 | }; |
1008 | 1008 | ||
1009 | static int __init sta32x_init(void) | 1009 | module_i2c_driver(sta32x_i2c_driver); |
1010 | { | ||
1011 | return i2c_add_driver(&sta32x_i2c_driver); | ||
1012 | } | ||
1013 | module_init(sta32x_init); | ||
1014 | |||
1015 | static void __exit sta32x_exit(void) | ||
1016 | { | ||
1017 | i2c_del_driver(&sta32x_i2c_driver); | ||
1018 | } | ||
1019 | module_exit(sta32x_exit); | ||
1020 | 1010 | ||
1021 | MODULE_DESCRIPTION("ASoC STA32X driver"); | 1011 | MODULE_DESCRIPTION("ASoC STA32X driver"); |
1022 | MODULE_AUTHOR("Johannes Stezenbach <js@sig21.net>"); | 1012 | MODULE_AUTHOR("Johannes Stezenbach <js@sig21.net>"); |
diff --git a/sound/soc/codecs/sta529.c b/sound/soc/codecs/sta529.c index 0c225cd569d2..9e3144862386 100644 --- a/sound/soc/codecs/sta529.c +++ b/sound/soc/codecs/sta529.c | |||
@@ -358,7 +358,7 @@ static int sta529_resume(struct snd_soc_codec *codec) | |||
358 | return 0; | 358 | return 0; |
359 | } | 359 | } |
360 | 360 | ||
361 | struct snd_soc_codec_driver sta529_codec_driver = { | 361 | static const struct snd_soc_codec_driver sta529_codec_driver = { |
362 | .probe = sta529_probe, | 362 | .probe = sta529_probe, |
363 | .remove = sta529_remove, | 363 | .remove = sta529_remove, |
364 | .set_bias_level = sta529_set_bias_level, | 364 | .set_bias_level = sta529_set_bias_level, |
diff --git a/sound/soc/codecs/stac9766.c b/sound/soc/codecs/stac9766.c index 982e437799a8..33c0f3d39c87 100644 --- a/sound/soc/codecs/stac9766.c +++ b/sound/soc/codecs/stac9766.c | |||
@@ -340,6 +340,7 @@ static int stac9766_codec_probe(struct snd_soc_codec *codec) | |||
340 | 340 | ||
341 | printk(KERN_INFO "STAC9766 SoC Audio Codec %s\n", STAC9766_VERSION); | 341 | printk(KERN_INFO "STAC9766 SoC Audio Codec %s\n", STAC9766_VERSION); |
342 | 342 | ||
343 | codec->control_data = codec; /* we don't use regmap! */ | ||
343 | ret = snd_soc_new_ac97_codec(codec, &soc_ac97_ops, 0); | 344 | ret = snd_soc_new_ac97_codec(codec, &soc_ac97_ops, 0); |
344 | if (ret < 0) | 345 | if (ret < 0) |
345 | goto codec_err; | 346 | goto codec_err; |
diff --git a/sound/soc/codecs/tlv320aic32x4.c b/sound/soc/codecs/tlv320aic32x4.c index b0a73d37ed52..f230292ba96b 100644 --- a/sound/soc/codecs/tlv320aic32x4.c +++ b/sound/soc/codecs/tlv320aic32x4.c | |||
@@ -746,24 +746,7 @@ static struct i2c_driver aic32x4_i2c_driver = { | |||
746 | .id_table = aic32x4_i2c_id, | 746 | .id_table = aic32x4_i2c_id, |
747 | }; | 747 | }; |
748 | 748 | ||
749 | static int __init aic32x4_modinit(void) | 749 | module_i2c_driver(aic32x4_i2c_driver); |
750 | { | ||
751 | int ret = 0; | ||
752 | |||
753 | ret = i2c_add_driver(&aic32x4_i2c_driver); | ||
754 | if (ret != 0) { | ||
755 | printk(KERN_ERR "Failed to register aic32x4 I2C driver: %d\n", | ||
756 | ret); | ||
757 | } | ||
758 | return ret; | ||
759 | } | ||
760 | module_init(aic32x4_modinit); | ||
761 | |||
762 | static void __exit aic32x4_exit(void) | ||
763 | { | ||
764 | i2c_del_driver(&aic32x4_i2c_driver); | ||
765 | } | ||
766 | module_exit(aic32x4_exit); | ||
767 | 750 | ||
768 | MODULE_DESCRIPTION("ASoC tlv320aic32x4 codec driver"); | 751 | MODULE_DESCRIPTION("ASoC tlv320aic32x4 codec driver"); |
769 | MODULE_AUTHOR("Javier Martin <javier.martin@vista-silicon.com>"); | 752 | MODULE_AUTHOR("Javier Martin <javier.martin@vista-silicon.com>"); |
diff --git a/sound/soc/codecs/tlv320aic3x.c b/sound/soc/codecs/tlv320aic3x.c index dc78f5a4bcbf..01485bd51404 100644 --- a/sound/soc/codecs/tlv320aic3x.c +++ b/sound/soc/codecs/tlv320aic3x.c | |||
@@ -1499,23 +1499,7 @@ static struct i2c_driver aic3x_i2c_driver = { | |||
1499 | .id_table = aic3x_i2c_id, | 1499 | .id_table = aic3x_i2c_id, |
1500 | }; | 1500 | }; |
1501 | 1501 | ||
1502 | static int __init aic3x_modinit(void) | 1502 | module_i2c_driver(aic3x_i2c_driver); |
1503 | { | ||
1504 | int ret = 0; | ||
1505 | ret = i2c_add_driver(&aic3x_i2c_driver); | ||
1506 | if (ret != 0) { | ||
1507 | printk(KERN_ERR "Failed to register TLV320AIC3x I2C driver: %d\n", | ||
1508 | ret); | ||
1509 | } | ||
1510 | return ret; | ||
1511 | } | ||
1512 | module_init(aic3x_modinit); | ||
1513 | |||
1514 | static void __exit aic3x_exit(void) | ||
1515 | { | ||
1516 | i2c_del_driver(&aic3x_i2c_driver); | ||
1517 | } | ||
1518 | module_exit(aic3x_exit); | ||
1519 | 1503 | ||
1520 | MODULE_DESCRIPTION("ASoC TLV320AIC3X codec driver"); | 1504 | MODULE_DESCRIPTION("ASoC TLV320AIC3X codec driver"); |
1521 | MODULE_AUTHOR("Vladimir Barinov"); | 1505 | MODULE_AUTHOR("Vladimir Barinov"); |
diff --git a/sound/soc/codecs/tlv320dac33.c b/sound/soc/codecs/tlv320dac33.c index 0dd41077ab79..d2e16c5d7d1f 100644 --- a/sound/soc/codecs/tlv320dac33.c +++ b/sound/soc/codecs/tlv320dac33.c | |||
@@ -1621,24 +1621,7 @@ static struct i2c_driver tlv320dac33_i2c_driver = { | |||
1621 | .id_table = tlv320dac33_i2c_id, | 1621 | .id_table = tlv320dac33_i2c_id, |
1622 | }; | 1622 | }; |
1623 | 1623 | ||
1624 | static int __init dac33_module_init(void) | 1624 | module_i2c_driver(tlv320dac33_i2c_driver); |
1625 | { | ||
1626 | int r; | ||
1627 | r = i2c_add_driver(&tlv320dac33_i2c_driver); | ||
1628 | if (r < 0) { | ||
1629 | printk(KERN_ERR "DAC33: driver registration failed\n"); | ||
1630 | return r; | ||
1631 | } | ||
1632 | return 0; | ||
1633 | } | ||
1634 | module_init(dac33_module_init); | ||
1635 | |||
1636 | static void __exit dac33_module_exit(void) | ||
1637 | { | ||
1638 | i2c_del_driver(&tlv320dac33_i2c_driver); | ||
1639 | } | ||
1640 | module_exit(dac33_module_exit); | ||
1641 | |||
1642 | 1625 | ||
1643 | MODULE_DESCRIPTION("ASoC TLV320DAC33 codec driver"); | 1626 | MODULE_DESCRIPTION("ASoC TLV320DAC33 codec driver"); |
1644 | MODULE_AUTHOR("Peter Ujfalusi <peter.ujfalusi@ti.com>"); | 1627 | MODULE_AUTHOR("Peter Ujfalusi <peter.ujfalusi@ti.com>"); |
diff --git a/sound/soc/codecs/tpa6130a2.c b/sound/soc/codecs/tpa6130a2.c index 6fe4aa3ac544..565ff39ad3a3 100644 --- a/sound/soc/codecs/tpa6130a2.c +++ b/sound/soc/codecs/tpa6130a2.c | |||
@@ -487,19 +487,8 @@ static struct i2c_driver tpa6130a2_i2c_driver = { | |||
487 | .id_table = tpa6130a2_id, | 487 | .id_table = tpa6130a2_id, |
488 | }; | 488 | }; |
489 | 489 | ||
490 | static int __init tpa6130a2_init(void) | 490 | module_i2c_driver(tpa6130a2_i2c_driver); |
491 | { | ||
492 | return i2c_add_driver(&tpa6130a2_i2c_driver); | ||
493 | } | ||
494 | |||
495 | static void __exit tpa6130a2_exit(void) | ||
496 | { | ||
497 | i2c_del_driver(&tpa6130a2_i2c_driver); | ||
498 | } | ||
499 | 491 | ||
500 | MODULE_AUTHOR("Peter Ujfalusi <peter.ujfalusi@ti.com>"); | 492 | MODULE_AUTHOR("Peter Ujfalusi <peter.ujfalusi@ti.com>"); |
501 | MODULE_DESCRIPTION("TPA6130A2 Headphone amplifier driver"); | 493 | MODULE_DESCRIPTION("TPA6130A2 Headphone amplifier driver"); |
502 | MODULE_LICENSE("GPL"); | 494 | MODULE_LICENSE("GPL"); |
503 | |||
504 | module_init(tpa6130a2_init); | ||
505 | module_exit(tpa6130a2_exit); | ||
diff --git a/sound/soc/codecs/wm2000.c b/sound/soc/codecs/wm2000.c index 3fd5b29dc933..89cd6fcad015 100644 --- a/sound/soc/codecs/wm2000.c +++ b/sound/soc/codecs/wm2000.c | |||
@@ -858,17 +858,7 @@ static struct i2c_driver wm2000_i2c_driver = { | |||
858 | .id_table = wm2000_i2c_id, | 858 | .id_table = wm2000_i2c_id, |
859 | }; | 859 | }; |
860 | 860 | ||
861 | static int __init wm2000_init(void) | 861 | module_i2c_driver(wm2000_i2c_driver); |
862 | { | ||
863 | return i2c_add_driver(&wm2000_i2c_driver); | ||
864 | } | ||
865 | module_init(wm2000_init); | ||
866 | |||
867 | static void __exit wm2000_exit(void) | ||
868 | { | ||
869 | i2c_del_driver(&wm2000_i2c_driver); | ||
870 | } | ||
871 | module_exit(wm2000_exit); | ||
872 | 862 | ||
873 | MODULE_DESCRIPTION("ASoC WM2000 driver"); | 863 | MODULE_DESCRIPTION("ASoC WM2000 driver"); |
874 | MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfonmicro.com>"); | 864 | MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfonmicro.com>"); |
diff --git a/sound/soc/codecs/wm2200.c b/sound/soc/codecs/wm2200.c index 32682c1b7cde..71debd0a3822 100644 --- a/sound/soc/codecs/wm2200.c +++ b/sound/soc/codecs/wm2200.c | |||
@@ -2270,17 +2270,7 @@ static struct i2c_driver wm2200_i2c_driver = { | |||
2270 | .id_table = wm2200_i2c_id, | 2270 | .id_table = wm2200_i2c_id, |
2271 | }; | 2271 | }; |
2272 | 2272 | ||
2273 | static int __init wm2200_modinit(void) | 2273 | module_i2c_driver(wm2200_i2c_driver); |
2274 | { | ||
2275 | return i2c_add_driver(&wm2200_i2c_driver); | ||
2276 | } | ||
2277 | module_init(wm2200_modinit); | ||
2278 | |||
2279 | static void __exit wm2200_exit(void) | ||
2280 | { | ||
2281 | i2c_del_driver(&wm2200_i2c_driver); | ||
2282 | } | ||
2283 | module_exit(wm2200_exit); | ||
2284 | 2274 | ||
2285 | MODULE_DESCRIPTION("ASoC WM2200 driver"); | 2275 | MODULE_DESCRIPTION("ASoC WM2200 driver"); |
2286 | MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>"); | 2276 | MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>"); |
diff --git a/sound/soc/codecs/wm5102.c b/sound/soc/codecs/wm5102.c index 6537f16d383e..2e6f1ffc9fd4 100644 --- a/sound/soc/codecs/wm5102.c +++ b/sound/soc/codecs/wm5102.c | |||
@@ -280,11 +280,36 @@ ARIZONA_MIXER_ENUMS(ASRC1R, ARIZONA_ASRC1RMIX_INPUT_1_SOURCE); | |||
280 | ARIZONA_MIXER_ENUMS(ASRC2L, ARIZONA_ASRC2LMIX_INPUT_1_SOURCE); | 280 | ARIZONA_MIXER_ENUMS(ASRC2L, ARIZONA_ASRC2LMIX_INPUT_1_SOURCE); |
281 | ARIZONA_MIXER_ENUMS(ASRC2R, ARIZONA_ASRC2RMIX_INPUT_1_SOURCE); | 281 | ARIZONA_MIXER_ENUMS(ASRC2R, ARIZONA_ASRC2RMIX_INPUT_1_SOURCE); |
282 | 282 | ||
283 | |||
284 | static const char *wm5102_aec_loopback_texts[] = { | ||
285 | "HPOUT1L", "HPOUT1R", "HPOUT2L", "HPOUT2R", "EPOUT", | ||
286 | "SPKOUTL", "SPKOUTR", "SPKDAT1L", "SPKDAT1R", | ||
287 | }; | ||
288 | |||
289 | static const unsigned int wm5102_aec_loopback_values[] = { | ||
290 | 0, 1, 2, 3, 4, 6, 7, 8, 9, | ||
291 | }; | ||
292 | |||
293 | static const struct soc_enum wm5102_aec_loopback = | ||
294 | SOC_VALUE_ENUM_SINGLE(ARIZONA_DAC_AEC_CONTROL_1, | ||
295 | ARIZONA_AEC_LOOPBACK_SRC_SHIFT, | ||
296 | ARIZONA_AEC_LOOPBACK_SRC_MASK, | ||
297 | ARRAY_SIZE(wm5102_aec_loopback_texts), | ||
298 | wm5102_aec_loopback_texts, | ||
299 | wm5102_aec_loopback_values); | ||
300 | |||
301 | static const struct snd_kcontrol_new wm5102_aec_loopback_mux = | ||
302 | SOC_DAPM_VALUE_ENUM("AEC Loopback", wm5102_aec_loopback); | ||
303 | |||
283 | static const struct snd_soc_dapm_widget wm5102_dapm_widgets[] = { | 304 | static const struct snd_soc_dapm_widget wm5102_dapm_widgets[] = { |
284 | SND_SOC_DAPM_SUPPLY("SYSCLK", ARIZONA_SYSTEM_CLOCK_1, ARIZONA_SYSCLK_ENA_SHIFT, | 305 | SND_SOC_DAPM_SUPPLY("SYSCLK", ARIZONA_SYSTEM_CLOCK_1, ARIZONA_SYSCLK_ENA_SHIFT, |
285 | 0, NULL, 0), | 306 | 0, NULL, 0), |
286 | SND_SOC_DAPM_SUPPLY("ASYNCCLK", ARIZONA_ASYNC_CLOCK_1, | 307 | SND_SOC_DAPM_SUPPLY("ASYNCCLK", ARIZONA_ASYNC_CLOCK_1, |
287 | ARIZONA_ASYNC_CLK_ENA_SHIFT, 0, NULL, 0), | 308 | ARIZONA_ASYNC_CLK_ENA_SHIFT, 0, NULL, 0), |
309 | SND_SOC_DAPM_SUPPLY("OPCLK", ARIZONA_OUTPUT_SYSTEM_CLOCK, | ||
310 | ARIZONA_OPCLK_ENA_SHIFT, 0, NULL, 0), | ||
311 | SND_SOC_DAPM_SUPPLY("ASYNCOPCLK", ARIZONA_OUTPUT_ASYNC_CLOCK, | ||
312 | ARIZONA_OPCLK_ASYNC_ENA_SHIFT, 0, NULL, 0), | ||
288 | 313 | ||
289 | SND_SOC_DAPM_REGULATOR_SUPPLY("DBVDD2", 0), | 314 | SND_SOC_DAPM_REGULATOR_SUPPLY("DBVDD2", 0), |
290 | SND_SOC_DAPM_REGULATOR_SUPPLY("DBVDD3", 0), | 315 | SND_SOC_DAPM_REGULATOR_SUPPLY("DBVDD3", 0), |
@@ -431,6 +456,9 @@ SND_SOC_DAPM_AIF_IN("AIF3RX1", NULL, 0, | |||
431 | SND_SOC_DAPM_AIF_IN("AIF3RX2", NULL, 0, | 456 | SND_SOC_DAPM_AIF_IN("AIF3RX2", NULL, 0, |
432 | ARIZONA_AIF3_RX_ENABLES, ARIZONA_AIF3RX2_ENA_SHIFT, 0), | 457 | ARIZONA_AIF3_RX_ENABLES, ARIZONA_AIF3RX2_ENA_SHIFT, 0), |
433 | 458 | ||
459 | SND_SOC_DAPM_VALUE_MUX("AEC Loopback", ARIZONA_DAC_AEC_CONTROL_1, | ||
460 | ARIZONA_AEC_LOOPBACK_ENA, 0, &wm5102_aec_loopback_mux), | ||
461 | |||
434 | SND_SOC_DAPM_PGA_E("OUT1L", ARIZONA_OUTPUT_ENABLES_1, | 462 | SND_SOC_DAPM_PGA_E("OUT1L", ARIZONA_OUTPUT_ENABLES_1, |
435 | ARIZONA_OUT1L_ENA_SHIFT, 0, NULL, 0, arizona_out_ev, | 463 | ARIZONA_OUT1L_ENA_SHIFT, 0, NULL, 0, arizona_out_ev, |
436 | SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU), | 464 | SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU), |
@@ -528,6 +556,7 @@ SND_SOC_DAPM_OUTPUT("SPKDAT1R"), | |||
528 | { name, "Noise Generator", "Noise Generator" }, \ | 556 | { name, "Noise Generator", "Noise Generator" }, \ |
529 | { name, "Tone Generator 1", "Tone Generator 1" }, \ | 557 | { name, "Tone Generator 1", "Tone Generator 1" }, \ |
530 | { name, "Tone Generator 2", "Tone Generator 2" }, \ | 558 | { name, "Tone Generator 2", "Tone Generator 2" }, \ |
559 | { name, "AEC", "AEC Loopback" }, \ | ||
531 | { name, "IN1L", "IN1L PGA" }, \ | 560 | { name, "IN1L", "IN1L PGA" }, \ |
532 | { name, "IN1R", "IN1R PGA" }, \ | 561 | { name, "IN1R", "IN1R PGA" }, \ |
533 | { name, "IN2L", "IN2L PGA" }, \ | 562 | { name, "IN2L", "IN2L PGA" }, \ |
@@ -688,21 +717,30 @@ static const struct snd_soc_dapm_route wm5102_dapm_routes[] = { | |||
688 | ARIZONA_MIXER_ROUTES("ASRC2L", "ASRC2L"), | 717 | ARIZONA_MIXER_ROUTES("ASRC2L", "ASRC2L"), |
689 | ARIZONA_MIXER_ROUTES("ASRC2R", "ASRC2R"), | 718 | ARIZONA_MIXER_ROUTES("ASRC2R", "ASRC2R"), |
690 | 719 | ||
720 | { "AEC Loopback", "HPOUT1L", "OUT1L" }, | ||
721 | { "AEC Loopback", "HPOUT1R", "OUT1R" }, | ||
691 | { "HPOUT1L", NULL, "OUT1L" }, | 722 | { "HPOUT1L", NULL, "OUT1L" }, |
692 | { "HPOUT1R", NULL, "OUT1R" }, | 723 | { "HPOUT1R", NULL, "OUT1R" }, |
693 | 724 | ||
725 | { "AEC Loopback", "HPOUT2L", "OUT2L" }, | ||
726 | { "AEC Loopback", "HPOUT2R", "OUT2R" }, | ||
694 | { "HPOUT2L", NULL, "OUT2L" }, | 727 | { "HPOUT2L", NULL, "OUT2L" }, |
695 | { "HPOUT2R", NULL, "OUT2R" }, | 728 | { "HPOUT2R", NULL, "OUT2R" }, |
696 | 729 | ||
730 | { "AEC Loopback", "EPOUT", "OUT3L" }, | ||
697 | { "EPOUTN", NULL, "OUT3L" }, | 731 | { "EPOUTN", NULL, "OUT3L" }, |
698 | { "EPOUTP", NULL, "OUT3L" }, | 732 | { "EPOUTP", NULL, "OUT3L" }, |
699 | 733 | ||
734 | { "AEC Loopback", "SPKOUTL", "OUT4L" }, | ||
700 | { "SPKOUTLN", NULL, "OUT4L" }, | 735 | { "SPKOUTLN", NULL, "OUT4L" }, |
701 | { "SPKOUTLP", NULL, "OUT4L" }, | 736 | { "SPKOUTLP", NULL, "OUT4L" }, |
702 | 737 | ||
738 | { "AEC Loopback", "SPKOUTR", "OUT4R" }, | ||
703 | { "SPKOUTRN", NULL, "OUT4R" }, | 739 | { "SPKOUTRN", NULL, "OUT4R" }, |
704 | { "SPKOUTRP", NULL, "OUT4R" }, | 740 | { "SPKOUTRP", NULL, "OUT4R" }, |
705 | 741 | ||
742 | { "AEC Loopback", "SPKDAT1L", "OUT5L" }, | ||
743 | { "AEC Loopback", "SPKDAT1R", "OUT5R" }, | ||
706 | { "SPKDAT1L", NULL, "OUT5L" }, | 744 | { "SPKDAT1L", NULL, "OUT5L" }, |
707 | { "SPKDAT1R", NULL, "OUT5R" }, | 745 | { "SPKDAT1R", NULL, "OUT5R" }, |
708 | }; | 746 | }; |
diff --git a/sound/soc/codecs/wm5110.c b/sound/soc/codecs/wm5110.c index 8033f7065189..3db6e6e7a591 100644 --- a/sound/soc/codecs/wm5110.c +++ b/sound/soc/codecs/wm5110.c | |||
@@ -305,6 +305,10 @@ SND_SOC_DAPM_SUPPLY("SYSCLK", ARIZONA_SYSTEM_CLOCK_1, ARIZONA_SYSCLK_ENA_SHIFT, | |||
305 | 0, NULL, 0), | 305 | 0, NULL, 0), |
306 | SND_SOC_DAPM_SUPPLY("ASYNCCLK", ARIZONA_ASYNC_CLOCK_1, | 306 | SND_SOC_DAPM_SUPPLY("ASYNCCLK", ARIZONA_ASYNC_CLOCK_1, |
307 | ARIZONA_ASYNC_CLK_ENA_SHIFT, 0, NULL, 0), | 307 | ARIZONA_ASYNC_CLK_ENA_SHIFT, 0, NULL, 0), |
308 | SND_SOC_DAPM_SUPPLY("OPCLK", ARIZONA_OUTPUT_SYSTEM_CLOCK, | ||
309 | ARIZONA_OPCLK_ENA_SHIFT, 0, NULL, 0), | ||
310 | SND_SOC_DAPM_SUPPLY("ASYNCOPCLK", ARIZONA_OUTPUT_ASYNC_CLOCK, | ||
311 | ARIZONA_OPCLK_ASYNC_ENA_SHIFT, 0, NULL, 0), | ||
308 | 312 | ||
309 | SND_SOC_DAPM_REGULATOR_SUPPLY("DBVDD2", 0), | 313 | SND_SOC_DAPM_REGULATOR_SUPPLY("DBVDD2", 0), |
310 | SND_SOC_DAPM_REGULATOR_SUPPLY("DBVDD3", 0), | 314 | SND_SOC_DAPM_REGULATOR_SUPPLY("DBVDD3", 0), |
diff --git a/sound/soc/codecs/wm8903.c b/sound/soc/codecs/wm8903.c index 73f1c8d7bafb..839414f9e2ed 100644 --- a/sound/soc/codecs/wm8903.c +++ b/sound/soc/codecs/wm8903.c | |||
@@ -2241,23 +2241,7 @@ static struct i2c_driver wm8903_i2c_driver = { | |||
2241 | .id_table = wm8903_i2c_id, | 2241 | .id_table = wm8903_i2c_id, |
2242 | }; | 2242 | }; |
2243 | 2243 | ||
2244 | static int __init wm8903_modinit(void) | 2244 | module_i2c_driver(wm8903_i2c_driver); |
2245 | { | ||
2246 | int ret = 0; | ||
2247 | ret = i2c_add_driver(&wm8903_i2c_driver); | ||
2248 | if (ret != 0) { | ||
2249 | printk(KERN_ERR "Failed to register wm8903 I2C driver: %d\n", | ||
2250 | ret); | ||
2251 | } | ||
2252 | return ret; | ||
2253 | } | ||
2254 | module_init(wm8903_modinit); | ||
2255 | |||
2256 | static void __exit wm8903_exit(void) | ||
2257 | { | ||
2258 | i2c_del_driver(&wm8903_i2c_driver); | ||
2259 | } | ||
2260 | module_exit(wm8903_exit); | ||
2261 | 2245 | ||
2262 | MODULE_DESCRIPTION("ASoC WM8903 driver"); | 2246 | MODULE_DESCRIPTION("ASoC WM8903 driver"); |
2263 | MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.cm>"); | 2247 | MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.cm>"); |
diff --git a/sound/soc/codecs/wm8940.c b/sound/soc/codecs/wm8940.c index 481a3d9cfe48..b20aa4e7c3f9 100644 --- a/sound/soc/codecs/wm8940.c +++ b/sound/soc/codecs/wm8940.c | |||
@@ -785,23 +785,7 @@ static struct i2c_driver wm8940_i2c_driver = { | |||
785 | .id_table = wm8940_i2c_id, | 785 | .id_table = wm8940_i2c_id, |
786 | }; | 786 | }; |
787 | 787 | ||
788 | static int __init wm8940_modinit(void) | 788 | module_i2c_driver(wm8940_i2c_driver); |
789 | { | ||
790 | int ret = 0; | ||
791 | ret = i2c_add_driver(&wm8940_i2c_driver); | ||
792 | if (ret != 0) { | ||
793 | printk(KERN_ERR "Failed to register wm8940 I2C driver: %d\n", | ||
794 | ret); | ||
795 | } | ||
796 | return ret; | ||
797 | } | ||
798 | module_init(wm8940_modinit); | ||
799 | |||
800 | static void __exit wm8940_exit(void) | ||
801 | { | ||
802 | i2c_del_driver(&wm8940_i2c_driver); | ||
803 | } | ||
804 | module_exit(wm8940_exit); | ||
805 | 789 | ||
806 | MODULE_DESCRIPTION("ASoC WM8940 driver"); | 790 | MODULE_DESCRIPTION("ASoC WM8940 driver"); |
807 | MODULE_AUTHOR("Jonathan Cameron"); | 791 | MODULE_AUTHOR("Jonathan Cameron"); |
diff --git a/sound/soc/codecs/wm8955.c b/sound/soc/codecs/wm8955.c index 61fe97433e73..2f1c075755b1 100644 --- a/sound/soc/codecs/wm8955.c +++ b/sound/soc/codecs/wm8955.c | |||
@@ -1071,23 +1071,7 @@ static struct i2c_driver wm8955_i2c_driver = { | |||
1071 | .id_table = wm8955_i2c_id, | 1071 | .id_table = wm8955_i2c_id, |
1072 | }; | 1072 | }; |
1073 | 1073 | ||
1074 | static int __init wm8955_modinit(void) | 1074 | module_i2c_driver(wm8955_i2c_driver); |
1075 | { | ||
1076 | int ret = 0; | ||
1077 | ret = i2c_add_driver(&wm8955_i2c_driver); | ||
1078 | if (ret != 0) { | ||
1079 | printk(KERN_ERR "Failed to register WM8955 I2C driver: %d\n", | ||
1080 | ret); | ||
1081 | } | ||
1082 | return ret; | ||
1083 | } | ||
1084 | module_init(wm8955_modinit); | ||
1085 | |||
1086 | static void __exit wm8955_exit(void) | ||
1087 | { | ||
1088 | i2c_del_driver(&wm8955_i2c_driver); | ||
1089 | } | ||
1090 | module_exit(wm8955_exit); | ||
1091 | 1075 | ||
1092 | MODULE_DESCRIPTION("ASoC WM8955 driver"); | 1076 | MODULE_DESCRIPTION("ASoC WM8955 driver"); |
1093 | MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>"); | 1077 | MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>"); |
diff --git a/sound/soc/codecs/wm8958-dsp2.c b/sound/soc/codecs/wm8958-dsp2.c index 1332692ef81b..00121ba36597 100644 --- a/sound/soc/codecs/wm8958-dsp2.c +++ b/sound/soc/codecs/wm8958-dsp2.c | |||
@@ -946,7 +946,7 @@ void wm8958_dsp2_init(struct snd_soc_codec *codec) | |||
946 | wm8994->mbc_texts = kmalloc(sizeof(char *) | 946 | wm8994->mbc_texts = kmalloc(sizeof(char *) |
947 | * pdata->num_mbc_cfgs, GFP_KERNEL); | 947 | * pdata->num_mbc_cfgs, GFP_KERNEL); |
948 | if (!wm8994->mbc_texts) { | 948 | if (!wm8994->mbc_texts) { |
949 | dev_err(wm8994->codec->dev, | 949 | dev_err(wm8994->hubs.codec->dev, |
950 | "Failed to allocate %d MBC config texts\n", | 950 | "Failed to allocate %d MBC config texts\n", |
951 | pdata->num_mbc_cfgs); | 951 | pdata->num_mbc_cfgs); |
952 | return; | 952 | return; |
@@ -958,9 +958,10 @@ void wm8958_dsp2_init(struct snd_soc_codec *codec) | |||
958 | wm8994->mbc_enum.max = pdata->num_mbc_cfgs; | 958 | wm8994->mbc_enum.max = pdata->num_mbc_cfgs; |
959 | wm8994->mbc_enum.texts = wm8994->mbc_texts; | 959 | wm8994->mbc_enum.texts = wm8994->mbc_texts; |
960 | 960 | ||
961 | ret = snd_soc_add_codec_controls(wm8994->codec, control, 1); | 961 | ret = snd_soc_add_codec_controls(wm8994->hubs.codec, |
962 | control, 1); | ||
962 | if (ret != 0) | 963 | if (ret != 0) |
963 | dev_err(wm8994->codec->dev, | 964 | dev_err(wm8994->hubs.codec->dev, |
964 | "Failed to add MBC mode controls: %d\n", ret); | 965 | "Failed to add MBC mode controls: %d\n", ret); |
965 | } | 966 | } |
966 | 967 | ||
@@ -974,7 +975,7 @@ void wm8958_dsp2_init(struct snd_soc_codec *codec) | |||
974 | wm8994->vss_texts = kmalloc(sizeof(char *) | 975 | wm8994->vss_texts = kmalloc(sizeof(char *) |
975 | * pdata->num_vss_cfgs, GFP_KERNEL); | 976 | * pdata->num_vss_cfgs, GFP_KERNEL); |
976 | if (!wm8994->vss_texts) { | 977 | if (!wm8994->vss_texts) { |
977 | dev_err(wm8994->codec->dev, | 978 | dev_err(wm8994->hubs.codec->dev, |
978 | "Failed to allocate %d VSS config texts\n", | 979 | "Failed to allocate %d VSS config texts\n", |
979 | pdata->num_vss_cfgs); | 980 | pdata->num_vss_cfgs); |
980 | return; | 981 | return; |
@@ -986,9 +987,10 @@ void wm8958_dsp2_init(struct snd_soc_codec *codec) | |||
986 | wm8994->vss_enum.max = pdata->num_vss_cfgs; | 987 | wm8994->vss_enum.max = pdata->num_vss_cfgs; |
987 | wm8994->vss_enum.texts = wm8994->vss_texts; | 988 | wm8994->vss_enum.texts = wm8994->vss_texts; |
988 | 989 | ||
989 | ret = snd_soc_add_codec_controls(wm8994->codec, control, 1); | 990 | ret = snd_soc_add_codec_controls(wm8994->hubs.codec, |
991 | control, 1); | ||
990 | if (ret != 0) | 992 | if (ret != 0) |
991 | dev_err(wm8994->codec->dev, | 993 | dev_err(wm8994->hubs.codec->dev, |
992 | "Failed to add VSS mode controls: %d\n", ret); | 994 | "Failed to add VSS mode controls: %d\n", ret); |
993 | } | 995 | } |
994 | 996 | ||
@@ -1003,7 +1005,7 @@ void wm8958_dsp2_init(struct snd_soc_codec *codec) | |||
1003 | wm8994->vss_hpf_texts = kmalloc(sizeof(char *) | 1005 | wm8994->vss_hpf_texts = kmalloc(sizeof(char *) |
1004 | * pdata->num_vss_hpf_cfgs, GFP_KERNEL); | 1006 | * pdata->num_vss_hpf_cfgs, GFP_KERNEL); |
1005 | if (!wm8994->vss_hpf_texts) { | 1007 | if (!wm8994->vss_hpf_texts) { |
1006 | dev_err(wm8994->codec->dev, | 1008 | dev_err(wm8994->hubs.codec->dev, |
1007 | "Failed to allocate %d VSS HPF config texts\n", | 1009 | "Failed to allocate %d VSS HPF config texts\n", |
1008 | pdata->num_vss_hpf_cfgs); | 1010 | pdata->num_vss_hpf_cfgs); |
1009 | return; | 1011 | return; |
@@ -1015,9 +1017,10 @@ void wm8958_dsp2_init(struct snd_soc_codec *codec) | |||
1015 | wm8994->vss_hpf_enum.max = pdata->num_vss_hpf_cfgs; | 1017 | wm8994->vss_hpf_enum.max = pdata->num_vss_hpf_cfgs; |
1016 | wm8994->vss_hpf_enum.texts = wm8994->vss_hpf_texts; | 1018 | wm8994->vss_hpf_enum.texts = wm8994->vss_hpf_texts; |
1017 | 1019 | ||
1018 | ret = snd_soc_add_codec_controls(wm8994->codec, control, 1); | 1020 | ret = snd_soc_add_codec_controls(wm8994->hubs.codec, |
1021 | control, 1); | ||
1019 | if (ret != 0) | 1022 | if (ret != 0) |
1020 | dev_err(wm8994->codec->dev, | 1023 | dev_err(wm8994->hubs.codec->dev, |
1021 | "Failed to add VSS HPFmode controls: %d\n", | 1024 | "Failed to add VSS HPFmode controls: %d\n", |
1022 | ret); | 1025 | ret); |
1023 | } | 1026 | } |
@@ -1033,7 +1036,7 @@ void wm8958_dsp2_init(struct snd_soc_codec *codec) | |||
1033 | wm8994->enh_eq_texts = kmalloc(sizeof(char *) | 1036 | wm8994->enh_eq_texts = kmalloc(sizeof(char *) |
1034 | * pdata->num_enh_eq_cfgs, GFP_KERNEL); | 1037 | * pdata->num_enh_eq_cfgs, GFP_KERNEL); |
1035 | if (!wm8994->enh_eq_texts) { | 1038 | if (!wm8994->enh_eq_texts) { |
1036 | dev_err(wm8994->codec->dev, | 1039 | dev_err(wm8994->hubs.codec->dev, |
1037 | "Failed to allocate %d enhanced EQ config texts\n", | 1040 | "Failed to allocate %d enhanced EQ config texts\n", |
1038 | pdata->num_enh_eq_cfgs); | 1041 | pdata->num_enh_eq_cfgs); |
1039 | return; | 1042 | return; |
@@ -1045,9 +1048,10 @@ void wm8958_dsp2_init(struct snd_soc_codec *codec) | |||
1045 | wm8994->enh_eq_enum.max = pdata->num_enh_eq_cfgs; | 1048 | wm8994->enh_eq_enum.max = pdata->num_enh_eq_cfgs; |
1046 | wm8994->enh_eq_enum.texts = wm8994->enh_eq_texts; | 1049 | wm8994->enh_eq_enum.texts = wm8994->enh_eq_texts; |
1047 | 1050 | ||
1048 | ret = snd_soc_add_codec_controls(wm8994->codec, control, 1); | 1051 | ret = snd_soc_add_codec_controls(wm8994->hubs.codec, |
1052 | control, 1); | ||
1049 | if (ret != 0) | 1053 | if (ret != 0) |
1050 | dev_err(wm8994->codec->dev, | 1054 | dev_err(wm8994->hubs.codec->dev, |
1051 | "Failed to add enhanced EQ controls: %d\n", | 1055 | "Failed to add enhanced EQ controls: %d\n", |
1052 | ret); | 1056 | ret); |
1053 | } | 1057 | } |
diff --git a/sound/soc/codecs/wm8960.c b/sound/soc/codecs/wm8960.c index 96518ac8e24c..804f4116912f 100644 --- a/sound/soc/codecs/wm8960.c +++ b/sound/soc/codecs/wm8960.c | |||
@@ -1010,23 +1010,7 @@ static struct i2c_driver wm8960_i2c_driver = { | |||
1010 | .id_table = wm8960_i2c_id, | 1010 | .id_table = wm8960_i2c_id, |
1011 | }; | 1011 | }; |
1012 | 1012 | ||
1013 | static int __init wm8960_modinit(void) | 1013 | module_i2c_driver(wm8960_i2c_driver); |
1014 | { | ||
1015 | int ret = 0; | ||
1016 | ret = i2c_add_driver(&wm8960_i2c_driver); | ||
1017 | if (ret != 0) { | ||
1018 | printk(KERN_ERR "Failed to register WM8960 I2C driver: %d\n", | ||
1019 | ret); | ||
1020 | } | ||
1021 | return ret; | ||
1022 | } | ||
1023 | module_init(wm8960_modinit); | ||
1024 | |||
1025 | static void __exit wm8960_exit(void) | ||
1026 | { | ||
1027 | i2c_del_driver(&wm8960_i2c_driver); | ||
1028 | } | ||
1029 | module_exit(wm8960_exit); | ||
1030 | 1014 | ||
1031 | MODULE_DESCRIPTION("ASoC WM8960 driver"); | 1015 | MODULE_DESCRIPTION("ASoC WM8960 driver"); |
1032 | MODULE_AUTHOR("Liam Girdwood"); | 1016 | MODULE_AUTHOR("Liam Girdwood"); |
diff --git a/sound/soc/codecs/wm8961.c b/sound/soc/codecs/wm8961.c index 01edbcc754d2..719fb69a17c8 100644 --- a/sound/soc/codecs/wm8961.c +++ b/sound/soc/codecs/wm8961.c | |||
@@ -1114,23 +1114,7 @@ static struct i2c_driver wm8961_i2c_driver = { | |||
1114 | .id_table = wm8961_i2c_id, | 1114 | .id_table = wm8961_i2c_id, |
1115 | }; | 1115 | }; |
1116 | 1116 | ||
1117 | static int __init wm8961_modinit(void) | 1117 | module_i2c_driver(wm8961_i2c_driver); |
1118 | { | ||
1119 | int ret = 0; | ||
1120 | ret = i2c_add_driver(&wm8961_i2c_driver); | ||
1121 | if (ret != 0) { | ||
1122 | printk(KERN_ERR "Failed to register wm8961 I2C driver: %d\n", | ||
1123 | ret); | ||
1124 | } | ||
1125 | return ret; | ||
1126 | } | ||
1127 | module_init(wm8961_modinit); | ||
1128 | |||
1129 | static void __exit wm8961_exit(void) | ||
1130 | { | ||
1131 | i2c_del_driver(&wm8961_i2c_driver); | ||
1132 | } | ||
1133 | module_exit(wm8961_exit); | ||
1134 | 1118 | ||
1135 | MODULE_DESCRIPTION("ASoC WM8961 driver"); | 1119 | MODULE_DESCRIPTION("ASoC WM8961 driver"); |
1136 | MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>"); | 1120 | MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>"); |
diff --git a/sound/soc/codecs/wm8962.c b/sound/soc/codecs/wm8962.c index eaf65863ec21..aa9ce9dd7d8a 100644 --- a/sound/soc/codecs/wm8962.c +++ b/sound/soc/codecs/wm8962.c | |||
@@ -2501,6 +2501,9 @@ static int wm8962_set_bias_level(struct snd_soc_codec *codec, | |||
2501 | /* VMID 2*250k */ | 2501 | /* VMID 2*250k */ |
2502 | snd_soc_update_bits(codec, WM8962_PWR_MGMT_1, | 2502 | snd_soc_update_bits(codec, WM8962_PWR_MGMT_1, |
2503 | WM8962_VMID_SEL_MASK, 0x100); | 2503 | WM8962_VMID_SEL_MASK, 0x100); |
2504 | |||
2505 | if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) | ||
2506 | msleep(100); | ||
2504 | break; | 2507 | break; |
2505 | 2508 | ||
2506 | case SND_SOC_BIAS_OFF: | 2509 | case SND_SOC_BIAS_OFF: |
diff --git a/sound/soc/codecs/wm8971.c b/sound/soc/codecs/wm8971.c index eef783f6b6d6..5ce647758443 100644 --- a/sound/soc/codecs/wm8971.c +++ b/sound/soc/codecs/wm8971.c | |||
@@ -721,23 +721,7 @@ static struct i2c_driver wm8971_i2c_driver = { | |||
721 | .id_table = wm8971_i2c_id, | 721 | .id_table = wm8971_i2c_id, |
722 | }; | 722 | }; |
723 | 723 | ||
724 | static int __init wm8971_modinit(void) | 724 | module_i2c_driver(wm8971_i2c_driver); |
725 | { | ||
726 | int ret = 0; | ||
727 | ret = i2c_add_driver(&wm8971_i2c_driver); | ||
728 | if (ret != 0) { | ||
729 | printk(KERN_ERR "Failed to register WM8971 I2C driver: %d\n", | ||
730 | ret); | ||
731 | } | ||
732 | return ret; | ||
733 | } | ||
734 | module_init(wm8971_modinit); | ||
735 | |||
736 | static void __exit wm8971_exit(void) | ||
737 | { | ||
738 | i2c_del_driver(&wm8971_i2c_driver); | ||
739 | } | ||
740 | module_exit(wm8971_exit); | ||
741 | 725 | ||
742 | MODULE_DESCRIPTION("ASoC WM8971 driver"); | 726 | MODULE_DESCRIPTION("ASoC WM8971 driver"); |
743 | MODULE_AUTHOR("Lab126"); | 727 | MODULE_AUTHOR("Lab126"); |
diff --git a/sound/soc/codecs/wm8974.c b/sound/soc/codecs/wm8974.c index d93c03f820c9..9a39511af52a 100644 --- a/sound/soc/codecs/wm8974.c +++ b/sound/soc/codecs/wm8974.c | |||
@@ -659,23 +659,7 @@ static struct i2c_driver wm8974_i2c_driver = { | |||
659 | .id_table = wm8974_i2c_id, | 659 | .id_table = wm8974_i2c_id, |
660 | }; | 660 | }; |
661 | 661 | ||
662 | static int __init wm8974_modinit(void) | 662 | module_i2c_driver(wm8974_i2c_driver); |
663 | { | ||
664 | int ret = 0; | ||
665 | ret = i2c_add_driver(&wm8974_i2c_driver); | ||
666 | if (ret != 0) { | ||
667 | printk(KERN_ERR "Failed to register wm8974 I2C driver: %d\n", | ||
668 | ret); | ||
669 | } | ||
670 | return ret; | ||
671 | } | ||
672 | module_init(wm8974_modinit); | ||
673 | |||
674 | static void __exit wm8974_exit(void) | ||
675 | { | ||
676 | i2c_del_driver(&wm8974_i2c_driver); | ||
677 | } | ||
678 | module_exit(wm8974_exit); | ||
679 | 663 | ||
680 | MODULE_DESCRIPTION("ASoC WM8974 driver"); | 664 | MODULE_DESCRIPTION("ASoC WM8974 driver"); |
681 | MODULE_AUTHOR("Liam Girdwood"); | 665 | MODULE_AUTHOR("Liam Girdwood"); |
diff --git a/sound/soc/codecs/wm8978.c b/sound/soc/codecs/wm8978.c index a5be3adecf75..5421fd9fbcb5 100644 --- a/sound/soc/codecs/wm8978.c +++ b/sound/soc/codecs/wm8978.c | |||
@@ -1105,23 +1105,7 @@ static struct i2c_driver wm8978_i2c_driver = { | |||
1105 | .id_table = wm8978_i2c_id, | 1105 | .id_table = wm8978_i2c_id, |
1106 | }; | 1106 | }; |
1107 | 1107 | ||
1108 | static int __init wm8978_modinit(void) | 1108 | module_i2c_driver(wm8978_i2c_driver); |
1109 | { | ||
1110 | int ret = 0; | ||
1111 | ret = i2c_add_driver(&wm8978_i2c_driver); | ||
1112 | if (ret != 0) { | ||
1113 | printk(KERN_ERR "Failed to register WM8978 I2C driver: %d\n", | ||
1114 | ret); | ||
1115 | } | ||
1116 | return ret; | ||
1117 | } | ||
1118 | module_init(wm8978_modinit); | ||
1119 | |||
1120 | static void __exit wm8978_exit(void) | ||
1121 | { | ||
1122 | i2c_del_driver(&wm8978_i2c_driver); | ||
1123 | } | ||
1124 | module_exit(wm8978_exit); | ||
1125 | 1109 | ||
1126 | MODULE_DESCRIPTION("ASoC WM8978 codec driver"); | 1110 | MODULE_DESCRIPTION("ASoC WM8978 codec driver"); |
1127 | MODULE_AUTHOR("Guennadi Liakhovetski <g.liakhovetski@gmx.de>"); | 1111 | MODULE_AUTHOR("Guennadi Liakhovetski <g.liakhovetski@gmx.de>"); |
diff --git a/sound/soc/codecs/wm8991.c b/sound/soc/codecs/wm8991.c index 9ac31ba9b82e..b9dbfebbda13 100644 --- a/sound/soc/codecs/wm8991.c +++ b/sound/soc/codecs/wm8991.c | |||
@@ -1400,23 +1400,7 @@ static struct i2c_driver wm8991_i2c_driver = { | |||
1400 | .id_table = wm8991_i2c_id, | 1400 | .id_table = wm8991_i2c_id, |
1401 | }; | 1401 | }; |
1402 | 1402 | ||
1403 | static int __init wm8991_modinit(void) | 1403 | module_i2c_driver(wm8991_i2c_driver); |
1404 | { | ||
1405 | int ret; | ||
1406 | ret = i2c_add_driver(&wm8991_i2c_driver); | ||
1407 | if (ret != 0) { | ||
1408 | printk(KERN_ERR "Failed to register WM8991 I2C driver: %d\n", | ||
1409 | ret); | ||
1410 | } | ||
1411 | return 0; | ||
1412 | } | ||
1413 | module_init(wm8991_modinit); | ||
1414 | |||
1415 | static void __exit wm8991_exit(void) | ||
1416 | { | ||
1417 | i2c_del_driver(&wm8991_i2c_driver); | ||
1418 | } | ||
1419 | module_exit(wm8991_exit); | ||
1420 | 1404 | ||
1421 | MODULE_DESCRIPTION("ASoC WM8991 driver"); | 1405 | MODULE_DESCRIPTION("ASoC WM8991 driver"); |
1422 | MODULE_AUTHOR("Graeme Gregory"); | 1406 | MODULE_AUTHOR("Graeme Gregory"); |
diff --git a/sound/soc/codecs/wm8993.c b/sound/soc/codecs/wm8993.c index 9fd80d688979..94737a30716b 100644 --- a/sound/soc/codecs/wm8993.c +++ b/sound/soc/codecs/wm8993.c | |||
@@ -1520,6 +1520,8 @@ static int wm8993_probe(struct snd_soc_codec *codec) | |||
1520 | wm8993->pdata.lineout2fb, | 1520 | wm8993->pdata.lineout2fb, |
1521 | wm8993->pdata.jd_scthr, | 1521 | wm8993->pdata.jd_scthr, |
1522 | wm8993->pdata.jd_thr, | 1522 | wm8993->pdata.jd_thr, |
1523 | wm8993->pdata.micbias1_delay, | ||
1524 | wm8993->pdata.micbias2_delay, | ||
1523 | wm8993->pdata.micbias1_lvl, | 1525 | wm8993->pdata.micbias1_lvl, |
1524 | wm8993->pdata.micbias2_lvl); | 1526 | wm8993->pdata.micbias2_lvl); |
1525 | 1527 | ||
diff --git a/sound/soc/codecs/wm8994.c b/sound/soc/codecs/wm8994.c index bb62f4b3d563..b74df52d2820 100644 --- a/sound/soc/codecs/wm8994.c +++ b/sound/soc/codecs/wm8994.c | |||
@@ -671,6 +671,18 @@ SOC_SINGLE_TLV("AIF2 EQ5 Volume", WM8994_AIF2_EQ_GAINS_2, 6, 31, 0, | |||
671 | eq_tlv), | 671 | eq_tlv), |
672 | }; | 672 | }; |
673 | 673 | ||
674 | static const struct snd_kcontrol_new wm8994_drc_controls[] = { | ||
675 | SND_SOC_BYTES_MASK("AIF1.1 DRC", WM8994_AIF1_DRC1_1, 5, | ||
676 | WM8994_AIF1DAC1_DRC_ENA | WM8994_AIF1ADC1L_DRC_ENA | | ||
677 | WM8994_AIF1ADC1R_DRC_ENA), | ||
678 | SND_SOC_BYTES_MASK("AIF1.2 DRC", WM8994_AIF1_DRC2_1, 5, | ||
679 | WM8994_AIF1DAC2_DRC_ENA | WM8994_AIF1ADC2L_DRC_ENA | | ||
680 | WM8994_AIF1ADC2R_DRC_ENA), | ||
681 | SND_SOC_BYTES_MASK("AIF2 DRC", WM8994_AIF2_DRC_1, 5, | ||
682 | WM8994_AIF2DAC_DRC_ENA | WM8994_AIF2ADCL_DRC_ENA | | ||
683 | WM8994_AIF2ADCR_DRC_ENA), | ||
684 | }; | ||
685 | |||
674 | static const char *wm8958_ng_text[] = { | 686 | static const char *wm8958_ng_text[] = { |
675 | "30ms", "125ms", "250ms", "500ms", | 687 | "30ms", "125ms", "250ms", "500ms", |
676 | }; | 688 | }; |
@@ -789,11 +801,27 @@ static int clk_sys_event(struct snd_soc_dapm_widget *w, | |||
789 | struct snd_kcontrol *kcontrol, int event) | 801 | struct snd_kcontrol *kcontrol, int event) |
790 | { | 802 | { |
791 | struct snd_soc_codec *codec = w->codec; | 803 | struct snd_soc_codec *codec = w->codec; |
804 | struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); | ||
792 | 805 | ||
793 | switch (event) { | 806 | switch (event) { |
794 | case SND_SOC_DAPM_PRE_PMU: | 807 | case SND_SOC_DAPM_PRE_PMU: |
795 | return configure_clock(codec); | 808 | return configure_clock(codec); |
796 | 809 | ||
810 | case SND_SOC_DAPM_POST_PMU: | ||
811 | /* | ||
812 | * JACKDET won't run until we start the clock and it | ||
813 | * only reports deltas, make sure we notify the state | ||
814 | * up the stack on startup. Use a *very* generous | ||
815 | * timeout for paranoia, there's no urgency and we | ||
816 | * don't want false reports. | ||
817 | */ | ||
818 | if (wm8994->jackdet && !wm8994->clk_has_run) { | ||
819 | schedule_delayed_work(&wm8994->jackdet_bootstrap, | ||
820 | msecs_to_jiffies(1000)); | ||
821 | wm8994->clk_has_run = true; | ||
822 | } | ||
823 | break; | ||
824 | |||
797 | case SND_SOC_DAPM_POST_PMD: | 825 | case SND_SOC_DAPM_POST_PMD: |
798 | configure_clock(codec); | 826 | configure_clock(codec); |
799 | break; | 827 | break; |
@@ -1632,7 +1660,8 @@ SND_SOC_DAPM_SUPPLY("VMID", SND_SOC_NOPM, 0, 0, vmid_event, | |||
1632 | SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), | 1660 | SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), |
1633 | 1661 | ||
1634 | SND_SOC_DAPM_SUPPLY("CLK_SYS", SND_SOC_NOPM, 0, 0, clk_sys_event, | 1662 | SND_SOC_DAPM_SUPPLY("CLK_SYS", SND_SOC_NOPM, 0, 0, clk_sys_event, |
1635 | SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD), | 1663 | SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | |
1664 | SND_SOC_DAPM_PRE_PMD), | ||
1636 | 1665 | ||
1637 | SND_SOC_DAPM_SUPPLY("DSP1CLK", SND_SOC_NOPM, 3, 0, NULL, 0), | 1666 | SND_SOC_DAPM_SUPPLY("DSP1CLK", SND_SOC_NOPM, 3, 0, NULL, 0), |
1638 | SND_SOC_DAPM_SUPPLY("DSP2CLK", SND_SOC_NOPM, 2, 0, NULL, 0), | 1667 | SND_SOC_DAPM_SUPPLY("DSP2CLK", SND_SOC_NOPM, 2, 0, NULL, 0), |
@@ -2102,6 +2131,10 @@ static int _wm8994_set_fll(struct snd_soc_codec *codec, int id, int src, | |||
2102 | case WM8994_FLL_SRC_LRCLK: | 2131 | case WM8994_FLL_SRC_LRCLK: |
2103 | case WM8994_FLL_SRC_BCLK: | 2132 | case WM8994_FLL_SRC_BCLK: |
2104 | break; | 2133 | break; |
2134 | case WM8994_FLL_SRC_INTERNAL: | ||
2135 | freq_in = 12000000; | ||
2136 | freq_out = 12000000; | ||
2137 | break; | ||
2105 | default: | 2138 | default: |
2106 | return -EINVAL; | 2139 | return -EINVAL; |
2107 | } | 2140 | } |
@@ -2161,12 +2194,14 @@ static int _wm8994_set_fll(struct snd_soc_codec *codec, int id, int src, | |||
2161 | 2194 | ||
2162 | snd_soc_update_bits(codec, WM8994_FLL1_CONTROL_4 + reg_offset, | 2195 | snd_soc_update_bits(codec, WM8994_FLL1_CONTROL_4 + reg_offset, |
2163 | WM8994_FLL1_N_MASK, | 2196 | WM8994_FLL1_N_MASK, |
2164 | fll.n << WM8994_FLL1_N_SHIFT); | 2197 | fll.n << WM8994_FLL1_N_SHIFT); |
2165 | 2198 | ||
2166 | snd_soc_update_bits(codec, WM8994_FLL1_CONTROL_5 + reg_offset, | 2199 | snd_soc_update_bits(codec, WM8994_FLL1_CONTROL_5 + reg_offset, |
2167 | WM8958_FLL1_BYP | | 2200 | WM8994_FLL1_FRC_NCO | WM8958_FLL1_BYP | |
2168 | WM8994_FLL1_REFCLK_DIV_MASK | | 2201 | WM8994_FLL1_REFCLK_DIV_MASK | |
2169 | WM8994_FLL1_REFCLK_SRC_MASK, | 2202 | WM8994_FLL1_REFCLK_SRC_MASK, |
2203 | ((src == WM8994_FLL_SRC_INTERNAL) | ||
2204 | << WM8994_FLL1_FRC_NCO_SHIFT) | | ||
2170 | (fll.clk_ref_div << WM8994_FLL1_REFCLK_DIV_SHIFT) | | 2205 | (fll.clk_ref_div << WM8994_FLL1_REFCLK_DIV_SHIFT) | |
2171 | (src - 1)); | 2206 | (src - 1)); |
2172 | 2207 | ||
@@ -2192,13 +2227,16 @@ static int _wm8994_set_fll(struct snd_soc_codec *codec, int id, int src, | |||
2192 | } | 2227 | } |
2193 | } | 2228 | } |
2194 | 2229 | ||
2230 | reg = WM8994_FLL1_ENA; | ||
2231 | |||
2195 | if (fll.k) | 2232 | if (fll.k) |
2196 | reg = WM8994_FLL1_ENA | WM8994_FLL1_FRAC; | 2233 | reg |= WM8994_FLL1_FRAC; |
2197 | else | 2234 | if (src == WM8994_FLL_SRC_INTERNAL) |
2198 | reg = WM8994_FLL1_ENA; | 2235 | reg |= WM8994_FLL1_OSC_ENA; |
2236 | |||
2199 | snd_soc_update_bits(codec, WM8994_FLL1_CONTROL_1 + reg_offset, | 2237 | snd_soc_update_bits(codec, WM8994_FLL1_CONTROL_1 + reg_offset, |
2200 | WM8994_FLL1_ENA | WM8994_FLL1_FRAC, | 2238 | WM8994_FLL1_ENA | WM8994_FLL1_OSC_ENA | |
2201 | reg); | 2239 | WM8994_FLL1_FRAC, reg); |
2202 | 2240 | ||
2203 | if (wm8994->fll_locked_irq) { | 2241 | if (wm8994->fll_locked_irq) { |
2204 | timeout = wait_for_completion_timeout(&wm8994->fll_locked[id], | 2242 | timeout = wait_for_completion_timeout(&wm8994->fll_locked[id], |
@@ -2649,7 +2687,7 @@ static int wm8994_hw_params(struct snd_pcm_substream *substream, | |||
2649 | return -EINVAL; | 2687 | return -EINVAL; |
2650 | } | 2688 | } |
2651 | 2689 | ||
2652 | bclk_rate = params_rate(params) * 2; | 2690 | bclk_rate = params_rate(params) * 4; |
2653 | switch (params_format(params)) { | 2691 | switch (params_format(params)) { |
2654 | case SNDRV_PCM_FORMAT_S16_LE: | 2692 | case SNDRV_PCM_FORMAT_S16_LE: |
2655 | bclk_rate *= 16; | 2693 | bclk_rate *= 16; |
@@ -3027,7 +3065,7 @@ static int wm8994_codec_resume(struct snd_soc_codec *codec) | |||
3027 | 3065 | ||
3028 | static void wm8994_handle_retune_mobile_pdata(struct wm8994_priv *wm8994) | 3066 | static void wm8994_handle_retune_mobile_pdata(struct wm8994_priv *wm8994) |
3029 | { | 3067 | { |
3030 | struct snd_soc_codec *codec = wm8994->codec; | 3068 | struct snd_soc_codec *codec = wm8994->hubs.codec; |
3031 | struct wm8994_pdata *pdata = wm8994->pdata; | 3069 | struct wm8994_pdata *pdata = wm8994->pdata; |
3032 | struct snd_kcontrol_new controls[] = { | 3070 | struct snd_kcontrol_new controls[] = { |
3033 | SOC_ENUM_EXT("AIF1.1 EQ Mode", | 3071 | SOC_ENUM_EXT("AIF1.1 EQ Mode", |
@@ -3085,16 +3123,16 @@ static void wm8994_handle_retune_mobile_pdata(struct wm8994_priv *wm8994) | |||
3085 | wm8994->retune_mobile_enum.max = wm8994->num_retune_mobile_texts; | 3123 | wm8994->retune_mobile_enum.max = wm8994->num_retune_mobile_texts; |
3086 | wm8994->retune_mobile_enum.texts = wm8994->retune_mobile_texts; | 3124 | wm8994->retune_mobile_enum.texts = wm8994->retune_mobile_texts; |
3087 | 3125 | ||
3088 | ret = snd_soc_add_codec_controls(wm8994->codec, controls, | 3126 | ret = snd_soc_add_codec_controls(wm8994->hubs.codec, controls, |
3089 | ARRAY_SIZE(controls)); | 3127 | ARRAY_SIZE(controls)); |
3090 | if (ret != 0) | 3128 | if (ret != 0) |
3091 | dev_err(wm8994->codec->dev, | 3129 | dev_err(wm8994->hubs.codec->dev, |
3092 | "Failed to add ReTune Mobile controls: %d\n", ret); | 3130 | "Failed to add ReTune Mobile controls: %d\n", ret); |
3093 | } | 3131 | } |
3094 | 3132 | ||
3095 | static void wm8994_handle_pdata(struct wm8994_priv *wm8994) | 3133 | static void wm8994_handle_pdata(struct wm8994_priv *wm8994) |
3096 | { | 3134 | { |
3097 | struct snd_soc_codec *codec = wm8994->codec; | 3135 | struct snd_soc_codec *codec = wm8994->hubs.codec; |
3098 | struct wm8994_pdata *pdata = wm8994->pdata; | 3136 | struct wm8994_pdata *pdata = wm8994->pdata; |
3099 | int ret, i; | 3137 | int ret, i; |
3100 | 3138 | ||
@@ -3107,6 +3145,8 @@ static void wm8994_handle_pdata(struct wm8994_priv *wm8994) | |||
3107 | pdata->lineout2fb, | 3145 | pdata->lineout2fb, |
3108 | pdata->jd_scthr, | 3146 | pdata->jd_scthr, |
3109 | pdata->jd_thr, | 3147 | pdata->jd_thr, |
3148 | pdata->micb1_delay, | ||
3149 | pdata->micb2_delay, | ||
3110 | pdata->micbias1_lvl, | 3150 | pdata->micbias1_lvl, |
3111 | pdata->micbias2_lvl); | 3151 | pdata->micbias2_lvl); |
3112 | 3152 | ||
@@ -3123,10 +3163,10 @@ static void wm8994_handle_pdata(struct wm8994_priv *wm8994) | |||
3123 | }; | 3163 | }; |
3124 | 3164 | ||
3125 | /* We need an array of texts for the enum API */ | 3165 | /* We need an array of texts for the enum API */ |
3126 | wm8994->drc_texts = devm_kzalloc(wm8994->codec->dev, | 3166 | wm8994->drc_texts = devm_kzalloc(wm8994->hubs.codec->dev, |
3127 | sizeof(char *) * pdata->num_drc_cfgs, GFP_KERNEL); | 3167 | sizeof(char *) * pdata->num_drc_cfgs, GFP_KERNEL); |
3128 | if (!wm8994->drc_texts) { | 3168 | if (!wm8994->drc_texts) { |
3129 | dev_err(wm8994->codec->dev, | 3169 | dev_err(wm8994->hubs.codec->dev, |
3130 | "Failed to allocate %d DRC config texts\n", | 3170 | "Failed to allocate %d DRC config texts\n", |
3131 | pdata->num_drc_cfgs); | 3171 | pdata->num_drc_cfgs); |
3132 | return; | 3172 | return; |
@@ -3138,23 +3178,28 @@ static void wm8994_handle_pdata(struct wm8994_priv *wm8994) | |||
3138 | wm8994->drc_enum.max = pdata->num_drc_cfgs; | 3178 | wm8994->drc_enum.max = pdata->num_drc_cfgs; |
3139 | wm8994->drc_enum.texts = wm8994->drc_texts; | 3179 | wm8994->drc_enum.texts = wm8994->drc_texts; |
3140 | 3180 | ||
3141 | ret = snd_soc_add_codec_controls(wm8994->codec, controls, | 3181 | ret = snd_soc_add_codec_controls(wm8994->hubs.codec, controls, |
3142 | ARRAY_SIZE(controls)); | 3182 | ARRAY_SIZE(controls)); |
3143 | if (ret != 0) | ||
3144 | dev_err(wm8994->codec->dev, | ||
3145 | "Failed to add DRC mode controls: %d\n", ret); | ||
3146 | |||
3147 | for (i = 0; i < WM8994_NUM_DRC; i++) | 3183 | for (i = 0; i < WM8994_NUM_DRC; i++) |
3148 | wm8994_set_drc(codec, i); | 3184 | wm8994_set_drc(codec, i); |
3185 | } else { | ||
3186 | ret = snd_soc_add_codec_controls(wm8994->hubs.codec, | ||
3187 | wm8994_drc_controls, | ||
3188 | ARRAY_SIZE(wm8994_drc_controls)); | ||
3149 | } | 3189 | } |
3150 | 3190 | ||
3191 | if (ret != 0) | ||
3192 | dev_err(wm8994->hubs.codec->dev, | ||
3193 | "Failed to add DRC mode controls: %d\n", ret); | ||
3194 | |||
3195 | |||
3151 | dev_dbg(codec->dev, "%d ReTune Mobile configurations\n", | 3196 | dev_dbg(codec->dev, "%d ReTune Mobile configurations\n", |
3152 | pdata->num_retune_mobile_cfgs); | 3197 | pdata->num_retune_mobile_cfgs); |
3153 | 3198 | ||
3154 | if (pdata->num_retune_mobile_cfgs) | 3199 | if (pdata->num_retune_mobile_cfgs) |
3155 | wm8994_handle_retune_mobile_pdata(wm8994); | 3200 | wm8994_handle_retune_mobile_pdata(wm8994); |
3156 | else | 3201 | else |
3157 | snd_soc_add_codec_controls(wm8994->codec, wm8994_eq_controls, | 3202 | snd_soc_add_codec_controls(wm8994->hubs.codec, wm8994_eq_controls, |
3158 | ARRAY_SIZE(wm8994_eq_controls)); | 3203 | ARRAY_SIZE(wm8994_eq_controls)); |
3159 | 3204 | ||
3160 | for (i = 0; i < ARRAY_SIZE(pdata->micbias); i++) { | 3205 | for (i = 0; i < ARRAY_SIZE(pdata->micbias); i++) { |
@@ -3236,6 +3281,12 @@ int wm8994_mic_detect(struct snd_soc_codec *codec, struct snd_soc_jack *jack, | |||
3236 | 3281 | ||
3237 | snd_soc_update_bits(codec, WM8994_MICBIAS, WM8994_MICD_ENA, reg); | 3282 | snd_soc_update_bits(codec, WM8994_MICBIAS, WM8994_MICD_ENA, reg); |
3238 | 3283 | ||
3284 | /* enable MICDET and MICSHRT deboune */ | ||
3285 | snd_soc_update_bits(codec, WM8994_IRQ_DEBOUNCE, | ||
3286 | WM8994_MIC1_DET_DB_MASK | WM8994_MIC1_SHRT_DB_MASK | | ||
3287 | WM8994_MIC2_DET_DB_MASK | WM8994_MIC2_SHRT_DB_MASK, | ||
3288 | WM8994_MIC1_DET_DB | WM8994_MIC1_SHRT_DB); | ||
3289 | |||
3239 | snd_soc_dapm_sync(&codec->dapm); | 3290 | snd_soc_dapm_sync(&codec->dapm); |
3240 | 3291 | ||
3241 | return 0; | 3292 | return 0; |
@@ -3253,10 +3304,13 @@ static void wm8994_mic_work(struct work_struct *work) | |||
3253 | int ret; | 3304 | int ret; |
3254 | int report; | 3305 | int report; |
3255 | 3306 | ||
3307 | pm_runtime_get_sync(dev); | ||
3308 | |||
3256 | ret = regmap_read(regmap, WM8994_INTERRUPT_RAW_STATUS_2, ®); | 3309 | ret = regmap_read(regmap, WM8994_INTERRUPT_RAW_STATUS_2, ®); |
3257 | if (ret < 0) { | 3310 | if (ret < 0) { |
3258 | dev_err(dev, "Failed to read microphone status: %d\n", | 3311 | dev_err(dev, "Failed to read microphone status: %d\n", |
3259 | ret); | 3312 | ret); |
3313 | pm_runtime_put(dev); | ||
3260 | return; | 3314 | return; |
3261 | } | 3315 | } |
3262 | 3316 | ||
@@ -3299,12 +3353,14 @@ static void wm8994_mic_work(struct work_struct *work) | |||
3299 | 3353 | ||
3300 | snd_soc_jack_report(priv->micdet[1].jack, report, | 3354 | snd_soc_jack_report(priv->micdet[1].jack, report, |
3301 | SND_JACK_HEADSET | SND_JACK_BTN_0); | 3355 | SND_JACK_HEADSET | SND_JACK_BTN_0); |
3356 | |||
3357 | pm_runtime_put(dev); | ||
3302 | } | 3358 | } |
3303 | 3359 | ||
3304 | static irqreturn_t wm8994_mic_irq(int irq, void *data) | 3360 | static irqreturn_t wm8994_mic_irq(int irq, void *data) |
3305 | { | 3361 | { |
3306 | struct wm8994_priv *priv = data; | 3362 | struct wm8994_priv *priv = data; |
3307 | struct snd_soc_codec *codec = priv->codec; | 3363 | struct snd_soc_codec *codec = priv->hubs.codec; |
3308 | 3364 | ||
3309 | #ifndef CONFIG_SND_SOC_WM8994_MODULE | 3365 | #ifndef CONFIG_SND_SOC_WM8994_MODULE |
3310 | trace_snd_soc_jack_irq(dev_name(codec->dev)); | 3366 | trace_snd_soc_jack_irq(dev_name(codec->dev)); |
@@ -3340,7 +3396,7 @@ static void wm8958_default_micdet(u16 status, void *data) | |||
3340 | 3396 | ||
3341 | snd_soc_jack_report(wm8994->micdet[0].jack, 0, | 3397 | snd_soc_jack_report(wm8994->micdet[0].jack, 0, |
3342 | wm8994->btn_mask | | 3398 | wm8994->btn_mask | |
3343 | SND_JACK_HEADSET); | 3399 | SND_JACK_HEADSET); |
3344 | } | 3400 | } |
3345 | return; | 3401 | return; |
3346 | } | 3402 | } |
@@ -3417,16 +3473,19 @@ static void wm8958_default_micdet(u16 status, void *data) | |||
3417 | static irqreturn_t wm1811_jackdet_irq(int irq, void *data) | 3473 | static irqreturn_t wm1811_jackdet_irq(int irq, void *data) |
3418 | { | 3474 | { |
3419 | struct wm8994_priv *wm8994 = data; | 3475 | struct wm8994_priv *wm8994 = data; |
3420 | struct snd_soc_codec *codec = wm8994->codec; | 3476 | struct snd_soc_codec *codec = wm8994->hubs.codec; |
3421 | int reg; | 3477 | int reg; |
3422 | bool present; | 3478 | bool present; |
3423 | 3479 | ||
3480 | pm_runtime_get_sync(codec->dev); | ||
3481 | |||
3424 | mutex_lock(&wm8994->accdet_lock); | 3482 | mutex_lock(&wm8994->accdet_lock); |
3425 | 3483 | ||
3426 | reg = snd_soc_read(codec, WM1811_JACKDET_CTRL); | 3484 | reg = snd_soc_read(codec, WM1811_JACKDET_CTRL); |
3427 | if (reg < 0) { | 3485 | if (reg < 0) { |
3428 | dev_err(codec->dev, "Failed to read jack status: %d\n", reg); | 3486 | dev_err(codec->dev, "Failed to read jack status: %d\n", reg); |
3429 | mutex_unlock(&wm8994->accdet_lock); | 3487 | mutex_unlock(&wm8994->accdet_lock); |
3488 | pm_runtime_put(codec->dev); | ||
3430 | return IRQ_NONE; | 3489 | return IRQ_NONE; |
3431 | } | 3490 | } |
3432 | 3491 | ||
@@ -3491,9 +3550,22 @@ static irqreturn_t wm1811_jackdet_irq(int irq, void *data) | |||
3491 | SND_JACK_MECHANICAL | SND_JACK_HEADSET | | 3550 | SND_JACK_MECHANICAL | SND_JACK_HEADSET | |
3492 | wm8994->btn_mask); | 3551 | wm8994->btn_mask); |
3493 | 3552 | ||
3553 | /* Since we only report deltas force an update, ensures we | ||
3554 | * avoid bootstrapping issues with the core. */ | ||
3555 | snd_soc_jack_report(wm8994->micdet[0].jack, 0, 0); | ||
3556 | |||
3557 | pm_runtime_put(codec->dev); | ||
3494 | return IRQ_HANDLED; | 3558 | return IRQ_HANDLED; |
3495 | } | 3559 | } |
3496 | 3560 | ||
3561 | static void wm1811_jackdet_bootstrap(struct work_struct *work) | ||
3562 | { | ||
3563 | struct wm8994_priv *wm8994 = container_of(work, | ||
3564 | struct wm8994_priv, | ||
3565 | jackdet_bootstrap.work); | ||
3566 | wm1811_jackdet_irq(0, wm8994); | ||
3567 | } | ||
3568 | |||
3497 | /** | 3569 | /** |
3498 | * wm8958_mic_detect - Enable microphone detection via the WM8958 IRQ | 3570 | * wm8958_mic_detect - Enable microphone detection via the WM8958 IRQ |
3499 | * | 3571 | * |
@@ -3564,6 +3636,10 @@ int wm8958_mic_detect(struct snd_soc_codec *codec, struct snd_soc_jack *jack, | |||
3564 | * otherwise jump straight to microphone detection. | 3636 | * otherwise jump straight to microphone detection. |
3565 | */ | 3637 | */ |
3566 | if (wm8994->jackdet) { | 3638 | if (wm8994->jackdet) { |
3639 | /* Disable debounce for the initial detect */ | ||
3640 | snd_soc_update_bits(codec, WM1811_JACKDET_CTRL, | ||
3641 | WM1811_JACKDET_DB, 0); | ||
3642 | |||
3567 | snd_soc_update_bits(codec, WM8958_MICBIAS2, | 3643 | snd_soc_update_bits(codec, WM8958_MICBIAS2, |
3568 | WM8958_MICB2_DISCH, | 3644 | WM8958_MICB2_DISCH, |
3569 | WM8958_MICB2_DISCH); | 3645 | WM8958_MICB2_DISCH); |
@@ -3591,7 +3667,7 @@ EXPORT_SYMBOL_GPL(wm8958_mic_detect); | |||
3591 | static irqreturn_t wm8958_mic_irq(int irq, void *data) | 3667 | static irqreturn_t wm8958_mic_irq(int irq, void *data) |
3592 | { | 3668 | { |
3593 | struct wm8994_priv *wm8994 = data; | 3669 | struct wm8994_priv *wm8994 = data; |
3594 | struct snd_soc_codec *codec = wm8994->codec; | 3670 | struct snd_soc_codec *codec = wm8994->hubs.codec; |
3595 | int reg, count; | 3671 | int reg, count; |
3596 | 3672 | ||
3597 | /* | 3673 | /* |
@@ -3602,6 +3678,8 @@ static irqreturn_t wm8958_mic_irq(int irq, void *data) | |||
3602 | if (!(snd_soc_read(codec, WM8958_MIC_DETECT_1) & WM8958_MICD_ENA)) | 3678 | if (!(snd_soc_read(codec, WM8958_MIC_DETECT_1) & WM8958_MICD_ENA)) |
3603 | return IRQ_HANDLED; | 3679 | return IRQ_HANDLED; |
3604 | 3680 | ||
3681 | pm_runtime_get_sync(codec->dev); | ||
3682 | |||
3605 | /* We may occasionally read a detection without an impedence | 3683 | /* We may occasionally read a detection without an impedence |
3606 | * range being provided - if that happens loop again. | 3684 | * range being provided - if that happens loop again. |
3607 | */ | 3685 | */ |
@@ -3612,6 +3690,7 @@ static irqreturn_t wm8958_mic_irq(int irq, void *data) | |||
3612 | dev_err(codec->dev, | 3690 | dev_err(codec->dev, |
3613 | "Failed to read mic detect status: %d\n", | 3691 | "Failed to read mic detect status: %d\n", |
3614 | reg); | 3692 | reg); |
3693 | pm_runtime_put(codec->dev); | ||
3615 | return IRQ_NONE; | 3694 | return IRQ_NONE; |
3616 | } | 3695 | } |
3617 | 3696 | ||
@@ -3639,6 +3718,7 @@ static irqreturn_t wm8958_mic_irq(int irq, void *data) | |||
3639 | dev_warn(codec->dev, "Accessory detection with no callback\n"); | 3718 | dev_warn(codec->dev, "Accessory detection with no callback\n"); |
3640 | 3719 | ||
3641 | out: | 3720 | out: |
3721 | pm_runtime_put(codec->dev); | ||
3642 | return IRQ_HANDLED; | 3722 | return IRQ_HANDLED; |
3643 | } | 3723 | } |
3644 | 3724 | ||
@@ -3677,15 +3757,15 @@ static int wm8994_codec_probe(struct snd_soc_codec *codec) | |||
3677 | unsigned int reg; | 3757 | unsigned int reg; |
3678 | int ret, i; | 3758 | int ret, i; |
3679 | 3759 | ||
3680 | wm8994->codec = codec; | 3760 | wm8994->hubs.codec = codec; |
3681 | codec->control_data = control->regmap; | 3761 | codec->control_data = control->regmap; |
3682 | 3762 | ||
3683 | snd_soc_codec_set_cache_io(codec, 16, 16, SND_SOC_REGMAP); | 3763 | snd_soc_codec_set_cache_io(codec, 16, 16, SND_SOC_REGMAP); |
3684 | 3764 | ||
3685 | wm8994->codec = codec; | ||
3686 | |||
3687 | mutex_init(&wm8994->accdet_lock); | 3765 | mutex_init(&wm8994->accdet_lock); |
3688 | INIT_DELAYED_WORK(&wm8994->mic_work, wm8994_mic_work); | 3766 | INIT_DELAYED_WORK(&wm8994->mic_work, wm8994_mic_work); |
3767 | INIT_DELAYED_WORK(&wm8994->jackdet_bootstrap, | ||
3768 | wm1811_jackdet_bootstrap); | ||
3689 | 3769 | ||
3690 | for (i = 0; i < ARRAY_SIZE(wm8994->fll_locked); i++) | 3770 | for (i = 0; i < ARRAY_SIZE(wm8994->fll_locked); i++) |
3691 | init_completion(&wm8994->fll_locked[i]); | 3771 | init_completion(&wm8994->fll_locked[i]); |
diff --git a/sound/soc/codecs/wm8994.h b/sound/soc/codecs/wm8994.h index d77e06f0a675..f142ec198db3 100644 --- a/sound/soc/codecs/wm8994.h +++ b/sound/soc/codecs/wm8994.h | |||
@@ -28,10 +28,11 @@ | |||
28 | #define WM8994_FLL1 1 | 28 | #define WM8994_FLL1 1 |
29 | #define WM8994_FLL2 2 | 29 | #define WM8994_FLL2 2 |
30 | 30 | ||
31 | #define WM8994_FLL_SRC_MCLK1 1 | 31 | #define WM8994_FLL_SRC_MCLK1 1 |
32 | #define WM8994_FLL_SRC_MCLK2 2 | 32 | #define WM8994_FLL_SRC_MCLK2 2 |
33 | #define WM8994_FLL_SRC_LRCLK 3 | 33 | #define WM8994_FLL_SRC_LRCLK 3 |
34 | #define WM8994_FLL_SRC_BCLK 4 | 34 | #define WM8994_FLL_SRC_BCLK 4 |
35 | #define WM8994_FLL_SRC_INTERNAL 5 | ||
35 | 36 | ||
36 | enum wm8994_vmid_mode { | 37 | enum wm8994_vmid_mode { |
37 | WM8994_VMID_NORMAL, | 38 | WM8994_VMID_NORMAL, |
@@ -72,7 +73,6 @@ struct wm8994; | |||
72 | struct wm8994_priv { | 73 | struct wm8994_priv { |
73 | struct wm_hubs_data hubs; | 74 | struct wm_hubs_data hubs; |
74 | struct wm8994 *wm8994; | 75 | struct wm8994 *wm8994; |
75 | struct snd_soc_codec *codec; | ||
76 | int sysclk[2]; | 76 | int sysclk[2]; |
77 | int sysclk_rate[2]; | 77 | int sysclk_rate[2]; |
78 | int mclk[2]; | 78 | int mclk[2]; |
@@ -81,6 +81,7 @@ struct wm8994_priv { | |||
81 | struct completion fll_locked[2]; | 81 | struct completion fll_locked[2]; |
82 | bool fll_locked_irq; | 82 | bool fll_locked_irq; |
83 | bool fll_byp; | 83 | bool fll_byp; |
84 | bool clk_has_run; | ||
84 | 85 | ||
85 | int vmid_refcount; | 86 | int vmid_refcount; |
86 | int active_refcount; | 87 | int active_refcount; |
@@ -134,6 +135,7 @@ struct wm8994_priv { | |||
134 | int btn_mask; | 135 | int btn_mask; |
135 | bool jackdet; | 136 | bool jackdet; |
136 | int jackdet_mode; | 137 | int jackdet_mode; |
138 | struct delayed_work jackdet_bootstrap; | ||
137 | 139 | ||
138 | wm8958_micdet_cb jack_cb; | 140 | wm8958_micdet_cb jack_cb; |
139 | void *jack_cb_data; | 141 | void *jack_cb_data; |
diff --git a/sound/soc/codecs/wm9090.c b/sound/soc/codecs/wm9090.c index 2c2346fdd637..c7ddc56175d1 100644 --- a/sound/soc/codecs/wm9090.c +++ b/sound/soc/codecs/wm9090.c | |||
@@ -695,17 +695,7 @@ static struct i2c_driver wm9090_i2c_driver = { | |||
695 | .id_table = wm9090_id, | 695 | .id_table = wm9090_id, |
696 | }; | 696 | }; |
697 | 697 | ||
698 | static int __init wm9090_init(void) | 698 | module_i2c_driver(wm9090_i2c_driver); |
699 | { | ||
700 | return i2c_add_driver(&wm9090_i2c_driver); | ||
701 | } | ||
702 | module_init(wm9090_init); | ||
703 | |||
704 | static void __exit wm9090_exit(void) | ||
705 | { | ||
706 | i2c_del_driver(&wm9090_i2c_driver); | ||
707 | } | ||
708 | module_exit(wm9090_exit); | ||
709 | 699 | ||
710 | MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>"); | 700 | MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>"); |
711 | MODULE_DESCRIPTION("WM9090 ASoC driver"); | 701 | MODULE_DESCRIPTION("WM9090 ASoC driver"); |
diff --git a/sound/soc/codecs/wm9712.c b/sound/soc/codecs/wm9712.c index 099e6ec32125..6aa1bf8c6897 100644 --- a/sound/soc/codecs/wm9712.c +++ b/sound/soc/codecs/wm9712.c | |||
@@ -132,8 +132,9 @@ SOC_SINGLE("Aux Playback Phone Volume", AC97_CD, 4, 7, 1), | |||
132 | SOC_SINGLE("Phone Volume", AC97_PHONE, 0, 15, 1), | 132 | SOC_SINGLE("Phone Volume", AC97_PHONE, 0, 15, 1), |
133 | SOC_DOUBLE("Line Capture Volume", AC97_LINE, 8, 0, 31, 1), | 133 | SOC_DOUBLE("Line Capture Volume", AC97_LINE, 8, 0, 31, 1), |
134 | 134 | ||
135 | SOC_SINGLE("Capture 20dB Boost Switch", AC97_REC_SEL, 14, 1, 0), | 135 | SOC_SINGLE_TLV("Capture Boost Switch", AC97_REC_SEL, 14, 1, 0, boost_tlv), |
136 | SOC_SINGLE("Capture to Phone 20dB Boost Switch", AC97_REC_SEL, 11, 1, 1), | 136 | SOC_SINGLE_TLV("Capture to Phone Boost Switch", AC97_REC_SEL, 11, 1, 1, |
137 | boost_tlv), | ||
137 | 138 | ||
138 | SOC_SINGLE("3D Upper Cut-off Switch", AC97_3D_CONTROL, 5, 1, 1), | 139 | SOC_SINGLE("3D Upper Cut-off Switch", AC97_3D_CONTROL, 5, 1, 1), |
139 | SOC_SINGLE("3D Lower Cut-off Switch", AC97_3D_CONTROL, 4, 1, 1), | 140 | SOC_SINGLE("3D Lower Cut-off Switch", AC97_3D_CONTROL, 4, 1, 1), |
@@ -146,7 +147,7 @@ SOC_SINGLE("Playback Attenuate (-6dB) Switch", AC97_MASTER_TONE, 6, 1, 0), | |||
146 | SOC_SINGLE("Bass Volume", AC97_MASTER_TONE, 8, 15, 1), | 147 | SOC_SINGLE("Bass Volume", AC97_MASTER_TONE, 8, 15, 1), |
147 | SOC_SINGLE("Treble Volume", AC97_MASTER_TONE, 0, 15, 1), | 148 | SOC_SINGLE("Treble Volume", AC97_MASTER_TONE, 0, 15, 1), |
148 | 149 | ||
149 | SOC_SINGLE("Capture ADC Switch", AC97_REC_GAIN, 15, 1, 1), | 150 | SOC_SINGLE("Capture Switch", AC97_REC_GAIN, 15, 1, 1), |
150 | SOC_ENUM("Capture Volume Steps", wm9712_enum[6]), | 151 | SOC_ENUM("Capture Volume Steps", wm9712_enum[6]), |
151 | SOC_DOUBLE("Capture Volume", AC97_REC_GAIN, 8, 0, 63, 1), | 152 | SOC_DOUBLE("Capture Volume", AC97_REC_GAIN, 8, 0, 63, 1), |
152 | SOC_SINGLE("Capture ZC Switch", AC97_REC_GAIN, 7, 1, 0), | 153 | SOC_SINGLE("Capture ZC Switch", AC97_REC_GAIN, 7, 1, 0), |
@@ -619,6 +620,7 @@ static int wm9712_soc_probe(struct snd_soc_codec *codec) | |||
619 | { | 620 | { |
620 | int ret = 0; | 621 | int ret = 0; |
621 | 622 | ||
623 | codec->control_data = codec; /* we don't use regmap! */ | ||
622 | ret = snd_soc_new_ac97_codec(codec, &soc_ac97_ops, 0); | 624 | ret = snd_soc_new_ac97_codec(codec, &soc_ac97_ops, 0); |
623 | if (ret < 0) { | 625 | if (ret < 0) { |
624 | printk(KERN_ERR "wm9712: failed to register AC97 codec\n"); | 626 | printk(KERN_ERR "wm9712: failed to register AC97 codec\n"); |
@@ -683,8 +685,8 @@ static int __devexit wm9712_remove(struct platform_device *pdev) | |||
683 | 685 | ||
684 | static struct platform_driver wm9712_codec_driver = { | 686 | static struct platform_driver wm9712_codec_driver = { |
685 | .driver = { | 687 | .driver = { |
686 | .name = "wm9712-codec", | 688 | .name = "wm9712-codec", |
687 | .owner = THIS_MODULE, | 689 | .owner = THIS_MODULE, |
688 | }, | 690 | }, |
689 | 691 | ||
690 | .probe = wm9712_probe, | 692 | .probe = wm9712_probe, |
diff --git a/sound/soc/codecs/wm9713.c b/sound/soc/codecs/wm9713.c index 3eb19fb71d17..d0b8a3287a85 100644 --- a/sound/soc/codecs/wm9713.c +++ b/sound/soc/codecs/wm9713.c | |||
@@ -1196,6 +1196,7 @@ static int wm9713_soc_probe(struct snd_soc_codec *codec) | |||
1196 | if (wm9713 == NULL) | 1196 | if (wm9713 == NULL) |
1197 | return -ENOMEM; | 1197 | return -ENOMEM; |
1198 | snd_soc_codec_set_drvdata(codec, wm9713); | 1198 | snd_soc_codec_set_drvdata(codec, wm9713); |
1199 | codec->control_data = wm9713; /* we don't use regmap! */ | ||
1199 | 1200 | ||
1200 | ret = snd_soc_new_ac97_codec(codec, &soc_ac97_ops, 0); | 1201 | ret = snd_soc_new_ac97_codec(codec, &soc_ac97_ops, 0); |
1201 | if (ret < 0) | 1202 | if (ret < 0) |
diff --git a/sound/soc/codecs/wm_hubs.c b/sound/soc/codecs/wm_hubs.c index 61baa48823cb..7a773a835b8e 100644 --- a/sound/soc/codecs/wm_hubs.c +++ b/sound/soc/codecs/wm_hubs.c | |||
@@ -199,15 +199,56 @@ static void wm_hubs_dcs_cache_set(struct snd_soc_codec *codec, u16 dcs_cfg) | |||
199 | list_add_tail(&cache->list, &hubs->dcs_cache); | 199 | list_add_tail(&cache->list, &hubs->dcs_cache); |
200 | } | 200 | } |
201 | 201 | ||
202 | static void wm_hubs_read_dc_servo(struct snd_soc_codec *codec, | ||
203 | u16 *reg_l, u16 *reg_r) | ||
204 | { | ||
205 | struct wm_hubs_data *hubs = snd_soc_codec_get_drvdata(codec); | ||
206 | u16 dcs_reg, reg; | ||
207 | |||
208 | switch (hubs->dcs_readback_mode) { | ||
209 | case 2: | ||
210 | dcs_reg = WM8994_DC_SERVO_4E; | ||
211 | break; | ||
212 | case 1: | ||
213 | dcs_reg = WM8994_DC_SERVO_READBACK; | ||
214 | break; | ||
215 | default: | ||
216 | dcs_reg = WM8993_DC_SERVO_3; | ||
217 | break; | ||
218 | } | ||
219 | |||
220 | /* Different chips in the family support different readback | ||
221 | * methods. | ||
222 | */ | ||
223 | switch (hubs->dcs_readback_mode) { | ||
224 | case 0: | ||
225 | *reg_l = snd_soc_read(codec, WM8993_DC_SERVO_READBACK_1) | ||
226 | & WM8993_DCS_INTEG_CHAN_0_MASK; | ||
227 | *reg_r = snd_soc_read(codec, WM8993_DC_SERVO_READBACK_2) | ||
228 | & WM8993_DCS_INTEG_CHAN_1_MASK; | ||
229 | break; | ||
230 | case 2: | ||
231 | case 1: | ||
232 | reg = snd_soc_read(codec, dcs_reg); | ||
233 | *reg_r = (reg & WM8993_DCS_DAC_WR_VAL_1_MASK) | ||
234 | >> WM8993_DCS_DAC_WR_VAL_1_SHIFT; | ||
235 | *reg_l = reg & WM8993_DCS_DAC_WR_VAL_0_MASK; | ||
236 | break; | ||
237 | default: | ||
238 | WARN(1, "Unknown DCS readback method\n"); | ||
239 | return; | ||
240 | } | ||
241 | } | ||
242 | |||
202 | /* | 243 | /* |
203 | * Startup calibration of the DC servo | 244 | * Startup calibration of the DC servo |
204 | */ | 245 | */ |
205 | static void calibrate_dc_servo(struct snd_soc_codec *codec) | 246 | static void enable_dc_servo(struct snd_soc_codec *codec) |
206 | { | 247 | { |
207 | struct wm_hubs_data *hubs = snd_soc_codec_get_drvdata(codec); | 248 | struct wm_hubs_data *hubs = snd_soc_codec_get_drvdata(codec); |
208 | struct wm_hubs_dcs_cache *cache; | 249 | struct wm_hubs_dcs_cache *cache; |
209 | s8 offset; | 250 | s8 offset; |
210 | u16 reg, reg_l, reg_r, dcs_cfg, dcs_reg; | 251 | u16 reg_l, reg_r, dcs_cfg, dcs_reg; |
211 | 252 | ||
212 | switch (hubs->dcs_readback_mode) { | 253 | switch (hubs->dcs_readback_mode) { |
213 | case 2: | 254 | case 2: |
@@ -245,27 +286,7 @@ static void calibrate_dc_servo(struct snd_soc_codec *codec) | |||
245 | WM8993_DCS_TRIG_STARTUP_1); | 286 | WM8993_DCS_TRIG_STARTUP_1); |
246 | } | 287 | } |
247 | 288 | ||
248 | /* Different chips in the family support different readback | 289 | wm_hubs_read_dc_servo(codec, ®_l, ®_r); |
249 | * methods. | ||
250 | */ | ||
251 | switch (hubs->dcs_readback_mode) { | ||
252 | case 0: | ||
253 | reg_l = snd_soc_read(codec, WM8993_DC_SERVO_READBACK_1) | ||
254 | & WM8993_DCS_INTEG_CHAN_0_MASK; | ||
255 | reg_r = snd_soc_read(codec, WM8993_DC_SERVO_READBACK_2) | ||
256 | & WM8993_DCS_INTEG_CHAN_1_MASK; | ||
257 | break; | ||
258 | case 2: | ||
259 | case 1: | ||
260 | reg = snd_soc_read(codec, dcs_reg); | ||
261 | reg_r = (reg & WM8993_DCS_DAC_WR_VAL_1_MASK) | ||
262 | >> WM8993_DCS_DAC_WR_VAL_1_SHIFT; | ||
263 | reg_l = reg & WM8993_DCS_DAC_WR_VAL_0_MASK; | ||
264 | break; | ||
265 | default: | ||
266 | WARN(1, "Unknown DCS readback method\n"); | ||
267 | return; | ||
268 | } | ||
269 | 290 | ||
270 | dev_dbg(codec->dev, "DCS input: %x %x\n", reg_l, reg_r); | 291 | dev_dbg(codec->dev, "DCS input: %x %x\n", reg_l, reg_r); |
271 | 292 | ||
@@ -276,12 +297,16 @@ static void calibrate_dc_servo(struct snd_soc_codec *codec) | |||
276 | hubs->dcs_codes_l, hubs->dcs_codes_r); | 297 | hubs->dcs_codes_l, hubs->dcs_codes_r); |
277 | 298 | ||
278 | /* HPOUT1R */ | 299 | /* HPOUT1R */ |
279 | offset = reg_r; | 300 | offset = (s8)reg_r; |
301 | dev_dbg(codec->dev, "DCS right %d->%d\n", offset, | ||
302 | offset + hubs->dcs_codes_r); | ||
280 | offset += hubs->dcs_codes_r; | 303 | offset += hubs->dcs_codes_r; |
281 | dcs_cfg = (u8)offset << WM8993_DCS_DAC_WR_VAL_1_SHIFT; | 304 | dcs_cfg = (u8)offset << WM8993_DCS_DAC_WR_VAL_1_SHIFT; |
282 | 305 | ||
283 | /* HPOUT1L */ | 306 | /* HPOUT1L */ |
284 | offset = reg_l; | 307 | offset = (s8)reg_l; |
308 | dev_dbg(codec->dev, "DCS left %d->%d\n", offset, | ||
309 | offset + hubs->dcs_codes_l); | ||
285 | offset += hubs->dcs_codes_l; | 310 | offset += hubs->dcs_codes_l; |
286 | dcs_cfg |= (u8)offset; | 311 | dcs_cfg |= (u8)offset; |
287 | 312 | ||
@@ -535,7 +560,7 @@ static int hp_event(struct snd_soc_dapm_widget *w, | |||
535 | snd_soc_update_bits(codec, WM8993_DC_SERVO_1, | 560 | snd_soc_update_bits(codec, WM8993_DC_SERVO_1, |
536 | WM8993_DCS_TIMER_PERIOD_01_MASK, 0); | 561 | WM8993_DCS_TIMER_PERIOD_01_MASK, 0); |
537 | 562 | ||
538 | calibrate_dc_servo(codec); | 563 | enable_dc_servo(codec); |
539 | 564 | ||
540 | reg |= WM8993_HPOUT1R_OUTP | WM8993_HPOUT1R_RMV_SHORT | | 565 | reg |= WM8993_HPOUT1R_OUTP | WM8993_HPOUT1R_RMV_SHORT | |
541 | WM8993_HPOUT1L_OUTP | WM8993_HPOUT1L_RMV_SHORT; | 566 | WM8993_HPOUT1L_OUTP | WM8993_HPOUT1L_RMV_SHORT; |
@@ -619,6 +644,28 @@ static int lineout_event(struct snd_soc_dapm_widget *w, | |||
619 | return 0; | 644 | return 0; |
620 | } | 645 | } |
621 | 646 | ||
647 | static int micbias_event(struct snd_soc_dapm_widget *w, | ||
648 | struct snd_kcontrol *kcontrol, int event) | ||
649 | { | ||
650 | struct snd_soc_codec *codec = w->codec; | ||
651 | struct wm_hubs_data *hubs = snd_soc_codec_get_drvdata(codec); | ||
652 | |||
653 | switch (w->shift) { | ||
654 | case WM8993_MICB1_ENA_SHIFT: | ||
655 | if (hubs->micb1_delay) | ||
656 | msleep(hubs->micb1_delay); | ||
657 | break; | ||
658 | case WM8993_MICB2_ENA_SHIFT: | ||
659 | if (hubs->micb2_delay) | ||
660 | msleep(hubs->micb2_delay); | ||
661 | break; | ||
662 | default: | ||
663 | return -EINVAL; | ||
664 | } | ||
665 | |||
666 | return 0; | ||
667 | } | ||
668 | |||
622 | void wm_hubs_update_class_w(struct snd_soc_codec *codec) | 669 | void wm_hubs_update_class_w(struct snd_soc_codec *codec) |
623 | { | 670 | { |
624 | struct wm_hubs_data *hubs = snd_soc_codec_get_drvdata(codec); | 671 | struct wm_hubs_data *hubs = snd_soc_codec_get_drvdata(codec); |
@@ -809,8 +856,10 @@ SND_SOC_DAPM_INPUT("IN1RP"), | |||
809 | SND_SOC_DAPM_INPUT("IN2RN"), | 856 | SND_SOC_DAPM_INPUT("IN2RN"), |
810 | SND_SOC_DAPM_INPUT("IN2RP:VXRP"), | 857 | SND_SOC_DAPM_INPUT("IN2RP:VXRP"), |
811 | 858 | ||
812 | SND_SOC_DAPM_SUPPLY("MICBIAS2", WM8993_POWER_MANAGEMENT_1, 5, 0, NULL, 0), | 859 | SND_SOC_DAPM_SUPPLY("MICBIAS2", WM8993_POWER_MANAGEMENT_1, 5, 0, |
813 | SND_SOC_DAPM_SUPPLY("MICBIAS1", WM8993_POWER_MANAGEMENT_1, 4, 0, NULL, 0), | 860 | micbias_event, SND_SOC_DAPM_POST_PMU), |
861 | SND_SOC_DAPM_SUPPLY("MICBIAS1", WM8993_POWER_MANAGEMENT_1, 4, 0, | ||
862 | micbias_event, SND_SOC_DAPM_POST_PMU), | ||
814 | 863 | ||
815 | SND_SOC_DAPM_MIXER("IN1L PGA", WM8993_POWER_MANAGEMENT_2, 6, 0, | 864 | SND_SOC_DAPM_MIXER("IN1L PGA", WM8993_POWER_MANAGEMENT_2, 6, 0, |
816 | in1l_pga, ARRAY_SIZE(in1l_pga)), | 865 | in1l_pga, ARRAY_SIZE(in1l_pga)), |
@@ -1112,6 +1161,8 @@ int wm_hubs_add_analogue_routes(struct snd_soc_codec *codec, | |||
1112 | struct wm_hubs_data *hubs = snd_soc_codec_get_drvdata(codec); | 1161 | struct wm_hubs_data *hubs = snd_soc_codec_get_drvdata(codec); |
1113 | struct snd_soc_dapm_context *dapm = &codec->dapm; | 1162 | struct snd_soc_dapm_context *dapm = &codec->dapm; |
1114 | 1163 | ||
1164 | hubs->codec = codec; | ||
1165 | |||
1115 | INIT_LIST_HEAD(&hubs->dcs_cache); | 1166 | INIT_LIST_HEAD(&hubs->dcs_cache); |
1116 | init_completion(&hubs->dcs_done); | 1167 | init_completion(&hubs->dcs_done); |
1117 | 1168 | ||
@@ -1143,13 +1194,16 @@ EXPORT_SYMBOL_GPL(wm_hubs_add_analogue_routes); | |||
1143 | int wm_hubs_handle_analogue_pdata(struct snd_soc_codec *codec, | 1194 | int wm_hubs_handle_analogue_pdata(struct snd_soc_codec *codec, |
1144 | int lineout1_diff, int lineout2_diff, | 1195 | int lineout1_diff, int lineout2_diff, |
1145 | int lineout1fb, int lineout2fb, | 1196 | int lineout1fb, int lineout2fb, |
1146 | int jd_scthr, int jd_thr, int micbias1_lvl, | 1197 | int jd_scthr, int jd_thr, |
1147 | int micbias2_lvl) | 1198 | int micbias1_delay, int micbias2_delay, |
1199 | int micbias1_lvl, int micbias2_lvl) | ||
1148 | { | 1200 | { |
1149 | struct wm_hubs_data *hubs = snd_soc_codec_get_drvdata(codec); | 1201 | struct wm_hubs_data *hubs = snd_soc_codec_get_drvdata(codec); |
1150 | 1202 | ||
1151 | hubs->lineout1_se = !lineout1_diff; | 1203 | hubs->lineout1_se = !lineout1_diff; |
1152 | hubs->lineout2_se = !lineout2_diff; | 1204 | hubs->lineout2_se = !lineout2_diff; |
1205 | hubs->micb1_delay = micbias1_delay; | ||
1206 | hubs->micb2_delay = micbias2_delay; | ||
1153 | 1207 | ||
1154 | if (!lineout1_diff) | 1208 | if (!lineout1_diff) |
1155 | snd_soc_update_bits(codec, WM8993_LINE_MIXER1, | 1209 | snd_soc_update_bits(codec, WM8993_LINE_MIXER1, |
diff --git a/sound/soc/codecs/wm_hubs.h b/sound/soc/codecs/wm_hubs.h index da2dc899ce6d..24c763df21f9 100644 --- a/sound/soc/codecs/wm_hubs.h +++ b/sound/soc/codecs/wm_hubs.h | |||
@@ -36,6 +36,9 @@ struct wm_hubs_data { | |||
36 | struct list_head dcs_cache; | 36 | struct list_head dcs_cache; |
37 | bool (*check_class_w_digital)(struct snd_soc_codec *); | 37 | bool (*check_class_w_digital)(struct snd_soc_codec *); |
38 | 38 | ||
39 | int micb1_delay; | ||
40 | int micb2_delay; | ||
41 | |||
39 | bool lineout1_se; | 42 | bool lineout1_se; |
40 | bool lineout1n_ena; | 43 | bool lineout1n_ena; |
41 | bool lineout1p_ena; | 44 | bool lineout1p_ena; |
@@ -46,6 +49,8 @@ struct wm_hubs_data { | |||
46 | 49 | ||
47 | bool dcs_done_irq; | 50 | bool dcs_done_irq; |
48 | struct completion dcs_done; | 51 | struct completion dcs_done; |
52 | |||
53 | struct snd_soc_codec *codec; | ||
49 | }; | 54 | }; |
50 | 55 | ||
51 | extern int wm_hubs_add_analogue_controls(struct snd_soc_codec *); | 56 | extern int wm_hubs_add_analogue_controls(struct snd_soc_codec *); |
@@ -54,6 +59,7 @@ extern int wm_hubs_handle_analogue_pdata(struct snd_soc_codec *, | |||
54 | int lineout1_diff, int lineout2_diff, | 59 | int lineout1_diff, int lineout2_diff, |
55 | int lineout1fb, int lineout2fb, | 60 | int lineout1fb, int lineout2fb, |
56 | int jd_scthr, int jd_thr, | 61 | int jd_scthr, int jd_thr, |
62 | int micbias1_dly, int micbias2_dly, | ||
57 | int micbias1_lvl, int micbias2_lvl); | 63 | int micbias1_lvl, int micbias2_lvl); |
58 | 64 | ||
59 | extern irqreturn_t wm_hubs_dcs_done(int irq, void *data); | 65 | extern irqreturn_t wm_hubs_dcs_done(int irq, void *data); |
diff --git a/sound/soc/davinci/davinci-evm.c b/sound/soc/davinci/davinci-evm.c index 10a2d8c788b7..c80c20a89b11 100644 --- a/sound/soc/davinci/davinci-evm.c +++ b/sound/soc/davinci/davinci-evm.c | |||
@@ -24,7 +24,6 @@ | |||
24 | 24 | ||
25 | #include <mach/asp.h> | 25 | #include <mach/asp.h> |
26 | #include <mach/edma.h> | 26 | #include <mach/edma.h> |
27 | #include <mach/mux.h> | ||
28 | 27 | ||
29 | #include "davinci-pcm.h" | 28 | #include "davinci-pcm.h" |
30 | #include "davinci-i2s.h" | 29 | #include "davinci-i2s.h" |
diff --git a/sound/soc/davinci/davinci-mcasp.c b/sound/soc/davinci/davinci-mcasp.c index 95441bfc8190..d919fb8de7a3 100644 --- a/sound/soc/davinci/davinci-mcasp.c +++ b/sound/soc/davinci/davinci-mcasp.c | |||
@@ -21,7 +21,7 @@ | |||
21 | #include <linux/slab.h> | 21 | #include <linux/slab.h> |
22 | #include <linux/delay.h> | 22 | #include <linux/delay.h> |
23 | #include <linux/io.h> | 23 | #include <linux/io.h> |
24 | #include <linux/clk.h> | 24 | #include <linux/pm_runtime.h> |
25 | 25 | ||
26 | #include <sound/core.h> | 26 | #include <sound/core.h> |
27 | #include <sound/pcm.h> | 27 | #include <sound/pcm.h> |
@@ -776,20 +776,17 @@ static int davinci_mcasp_trigger(struct snd_pcm_substream *substream, | |||
776 | case SNDRV_PCM_TRIGGER_RESUME: | 776 | case SNDRV_PCM_TRIGGER_RESUME: |
777 | case SNDRV_PCM_TRIGGER_START: | 777 | case SNDRV_PCM_TRIGGER_START: |
778 | case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: | 778 | case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: |
779 | if (!dev->clk_active) { | 779 | ret = pm_runtime_get_sync(dev->dev); |
780 | clk_enable(dev->clk); | 780 | if (IS_ERR_VALUE(ret)) |
781 | dev->clk_active = 1; | 781 | dev_err(dev->dev, "pm_runtime_get_sync() failed\n"); |
782 | } | ||
783 | davinci_mcasp_start(dev, substream->stream); | 782 | davinci_mcasp_start(dev, substream->stream); |
784 | break; | 783 | break; |
785 | 784 | ||
786 | case SNDRV_PCM_TRIGGER_SUSPEND: | 785 | case SNDRV_PCM_TRIGGER_SUSPEND: |
787 | davinci_mcasp_stop(dev, substream->stream); | 786 | davinci_mcasp_stop(dev, substream->stream); |
788 | if (dev->clk_active) { | 787 | ret = pm_runtime_put_sync(dev->dev); |
789 | clk_disable(dev->clk); | 788 | if (IS_ERR_VALUE(ret)) |
790 | dev->clk_active = 0; | 789 | dev_err(dev->dev, "pm_runtime_put_sync() failed\n"); |
791 | } | ||
792 | |||
793 | break; | 790 | break; |
794 | 791 | ||
795 | case SNDRV_PCM_TRIGGER_STOP: | 792 | case SNDRV_PCM_TRIGGER_STOP: |
@@ -886,12 +883,13 @@ static int davinci_mcasp_probe(struct platform_device *pdev) | |||
886 | } | 883 | } |
887 | 884 | ||
888 | pdata = pdev->dev.platform_data; | 885 | pdata = pdev->dev.platform_data; |
889 | dev->clk = clk_get(&pdev->dev, NULL); | 886 | pm_runtime_enable(&pdev->dev); |
890 | if (IS_ERR(dev->clk)) | ||
891 | return -ENODEV; | ||
892 | 887 | ||
893 | clk_enable(dev->clk); | 888 | ret = pm_runtime_get_sync(&pdev->dev); |
894 | dev->clk_active = 1; | 889 | if (IS_ERR_VALUE(ret)) { |
890 | dev_err(&pdev->dev, "pm_runtime_get_sync() failed\n"); | ||
891 | return ret; | ||
892 | } | ||
895 | 893 | ||
896 | dev->base = devm_ioremap(&pdev->dev, mem->start, resource_size(mem)); | 894 | dev->base = devm_ioremap(&pdev->dev, mem->start, resource_size(mem)); |
897 | if (!dev->base) { | 895 | if (!dev->base) { |
@@ -908,6 +906,7 @@ static int davinci_mcasp_probe(struct platform_device *pdev) | |||
908 | dev->version = pdata->version; | 906 | dev->version = pdata->version; |
909 | dev->txnumevt = pdata->txnumevt; | 907 | dev->txnumevt = pdata->txnumevt; |
910 | dev->rxnumevt = pdata->rxnumevt; | 908 | dev->rxnumevt = pdata->rxnumevt; |
909 | dev->dev = &pdev->dev; | ||
911 | 910 | ||
912 | dma_data = &dev->dma_params[SNDRV_PCM_STREAM_PLAYBACK]; | 911 | dma_data = &dev->dma_params[SNDRV_PCM_STREAM_PLAYBACK]; |
913 | dma_data->asp_chan_q = pdata->asp_chan_q; | 912 | dma_data->asp_chan_q = pdata->asp_chan_q; |
@@ -949,19 +948,18 @@ static int davinci_mcasp_probe(struct platform_device *pdev) | |||
949 | return 0; | 948 | return 0; |
950 | 949 | ||
951 | err_release_clk: | 950 | err_release_clk: |
952 | clk_disable(dev->clk); | 951 | pm_runtime_put_sync(&pdev->dev); |
953 | clk_put(dev->clk); | 952 | pm_runtime_disable(&pdev->dev); |
954 | return ret; | 953 | return ret; |
955 | } | 954 | } |
956 | 955 | ||
957 | static int davinci_mcasp_remove(struct platform_device *pdev) | 956 | static int davinci_mcasp_remove(struct platform_device *pdev) |
958 | { | 957 | { |
959 | struct davinci_audio_dev *dev = dev_get_drvdata(&pdev->dev); | ||
960 | 958 | ||
961 | snd_soc_unregister_dai(&pdev->dev); | 959 | snd_soc_unregister_dai(&pdev->dev); |
962 | clk_disable(dev->clk); | 960 | |
963 | clk_put(dev->clk); | 961 | pm_runtime_put_sync(&pdev->dev); |
964 | dev->clk = NULL; | 962 | pm_runtime_disable(&pdev->dev); |
965 | 963 | ||
966 | return 0; | 964 | return 0; |
967 | } | 965 | } |
diff --git a/sound/soc/davinci/davinci-mcasp.h b/sound/soc/davinci/davinci-mcasp.h index 4681acc63606..51479f9ee909 100644 --- a/sound/soc/davinci/davinci-mcasp.h +++ b/sound/soc/davinci/davinci-mcasp.h | |||
@@ -40,9 +40,8 @@ struct davinci_audio_dev { | |||
40 | struct davinci_pcm_dma_params dma_params[2]; | 40 | struct davinci_pcm_dma_params dma_params[2]; |
41 | void __iomem *base; | 41 | void __iomem *base; |
42 | int sample_rate; | 42 | int sample_rate; |
43 | struct clk *clk; | 43 | struct device *dev; |
44 | unsigned int codec_fmt; | 44 | unsigned int codec_fmt; |
45 | u8 clk_active; | ||
46 | 45 | ||
47 | /* McASP specific data */ | 46 | /* McASP specific data */ |
48 | int tdm_slots; | 47 | int tdm_slots; |
diff --git a/sound/soc/fsl/imx-ssi.c b/sound/soc/fsl/imx-ssi.c index 28dd76c7cb1c..3c520c46fa4a 100644 --- a/sound/soc/fsl/imx-ssi.c +++ b/sound/soc/fsl/imx-ssi.c | |||
@@ -523,7 +523,7 @@ static int imx_ssi_probe(struct platform_device *pdev) | |||
523 | int ret = 0; | 523 | int ret = 0; |
524 | struct snd_soc_dai_driver *dai; | 524 | struct snd_soc_dai_driver *dai; |
525 | 525 | ||
526 | ssi = kzalloc(sizeof(*ssi), GFP_KERNEL); | 526 | ssi = devm_kzalloc(&pdev->dev, sizeof(*ssi), GFP_KERNEL); |
527 | if (!ssi) | 527 | if (!ssi) |
528 | return -ENOMEM; | 528 | return -ENOMEM; |
529 | dev_set_drvdata(&pdev->dev, ssi); | 529 | dev_set_drvdata(&pdev->dev, ssi); |
@@ -536,7 +536,7 @@ static int imx_ssi_probe(struct platform_device *pdev) | |||
536 | 536 | ||
537 | ssi->irq = platform_get_irq(pdev, 0); | 537 | ssi->irq = platform_get_irq(pdev, 0); |
538 | 538 | ||
539 | ssi->clk = clk_get(&pdev->dev, NULL); | 539 | ssi->clk = devm_clk_get(&pdev->dev, NULL); |
540 | if (IS_ERR(ssi->clk)) { | 540 | if (IS_ERR(ssi->clk)) { |
541 | ret = PTR_ERR(ssi->clk); | 541 | ret = PTR_ERR(ssi->clk); |
542 | dev_err(&pdev->dev, "Cannot get the clock: %d\n", | 542 | dev_err(&pdev->dev, "Cannot get the clock: %d\n", |
@@ -551,23 +551,18 @@ static int imx_ssi_probe(struct platform_device *pdev) | |||
551 | goto failed_get_resource; | 551 | goto failed_get_resource; |
552 | } | 552 | } |
553 | 553 | ||
554 | if (!request_mem_region(res->start, resource_size(res), DRV_NAME)) { | 554 | ssi->base = devm_request_and_ioremap(&pdev->dev, res); |
555 | dev_err(&pdev->dev, "request_mem_region failed\n"); | ||
556 | ret = -EBUSY; | ||
557 | goto failed_get_resource; | ||
558 | } | ||
559 | |||
560 | ssi->base = ioremap(res->start, resource_size(res)); | ||
561 | if (!ssi->base) { | 555 | if (!ssi->base) { |
562 | dev_err(&pdev->dev, "ioremap failed\n"); | 556 | dev_err(&pdev->dev, "ioremap failed\n"); |
563 | ret = -ENODEV; | 557 | ret = -ENODEV; |
564 | goto failed_ioremap; | 558 | goto failed_register; |
565 | } | 559 | } |
566 | 560 | ||
567 | if (ssi->flags & IMX_SSI_USE_AC97) { | 561 | if (ssi->flags & IMX_SSI_USE_AC97) { |
568 | if (ac97_ssi) { | 562 | if (ac97_ssi) { |
563 | dev_err(&pdev->dev, "AC'97 SSI already registered\n"); | ||
569 | ret = -EBUSY; | 564 | ret = -EBUSY; |
570 | goto failed_ac97; | 565 | goto failed_register; |
571 | } | 566 | } |
572 | ac97_ssi = ssi; | 567 | ac97_ssi = ssi; |
573 | setup_channel_to_ac97(ssi); | 568 | setup_channel_to_ac97(ssi); |
@@ -636,15 +631,10 @@ failed_pdev_fiq_add: | |||
636 | failed_pdev_fiq_alloc: | 631 | failed_pdev_fiq_alloc: |
637 | snd_soc_unregister_dai(&pdev->dev); | 632 | snd_soc_unregister_dai(&pdev->dev); |
638 | failed_register: | 633 | failed_register: |
639 | failed_ac97: | ||
640 | iounmap(ssi->base); | ||
641 | failed_ioremap: | ||
642 | release_mem_region(res->start, resource_size(res)); | 634 | release_mem_region(res->start, resource_size(res)); |
643 | failed_get_resource: | 635 | failed_get_resource: |
644 | clk_disable_unprepare(ssi->clk); | 636 | clk_disable_unprepare(ssi->clk); |
645 | clk_put(ssi->clk); | ||
646 | failed_clk: | 637 | failed_clk: |
647 | kfree(ssi); | ||
648 | 638 | ||
649 | return ret; | 639 | return ret; |
650 | } | 640 | } |
@@ -662,11 +652,8 @@ static int __devexit imx_ssi_remove(struct platform_device *pdev) | |||
662 | if (ssi->flags & IMX_SSI_USE_AC97) | 652 | if (ssi->flags & IMX_SSI_USE_AC97) |
663 | ac97_ssi = NULL; | 653 | ac97_ssi = NULL; |
664 | 654 | ||
665 | iounmap(ssi->base); | ||
666 | release_mem_region(res->start, resource_size(res)); | 655 | release_mem_region(res->start, resource_size(res)); |
667 | clk_disable_unprepare(ssi->clk); | 656 | clk_disable_unprepare(ssi->clk); |
668 | clk_put(ssi->clk); | ||
669 | kfree(ssi); | ||
670 | 657 | ||
671 | return 0; | 658 | return 0; |
672 | } | 659 | } |
diff --git a/sound/soc/mid-x86/mfld_machine.c b/sound/soc/mid-x86/mfld_machine.c index 2937e54da49e..2cc7782714b5 100644 --- a/sound/soc/mid-x86/mfld_machine.c +++ b/sound/soc/mid-x86/mfld_machine.c | |||
@@ -318,6 +318,15 @@ static struct snd_soc_dai_link mfld_msic_dailink[] = { | |||
318 | .platform_name = "sst-platform", | 318 | .platform_name = "sst-platform", |
319 | .init = NULL, | 319 | .init = NULL, |
320 | }, | 320 | }, |
321 | { | ||
322 | .name = "Medfield Compress", | ||
323 | .stream_name = "Speaker", | ||
324 | .cpu_dai_name = "Compress-cpu-dai", | ||
325 | .codec_dai_name = "SN95031 Speaker", | ||
326 | .codec_name = "sn95031", | ||
327 | .platform_name = "sst-platform", | ||
328 | .init = NULL, | ||
329 | }, | ||
321 | }; | 330 | }; |
322 | 331 | ||
323 | /* SoC card */ | 332 | /* SoC card */ |
diff --git a/sound/soc/mid-x86/sst_dsp.h b/sound/soc/mid-x86/sst_dsp.h new file mode 100644 index 000000000000..0fce1de284ff --- /dev/null +++ b/sound/soc/mid-x86/sst_dsp.h | |||
@@ -0,0 +1,134 @@ | |||
1 | #ifndef __SST_DSP_H__ | ||
2 | #define __SST_DSP_H__ | ||
3 | /* | ||
4 | * sst_dsp.h - Intel SST Driver for audio engine | ||
5 | * | ||
6 | * Copyright (C) 2008-12 Intel Corporation | ||
7 | * Authors: Vinod Koul <vinod.koul@linux.intel.com> | ||
8 | * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | ||
9 | * | ||
10 | * This program is free software; you can redistribute it and/or modify | ||
11 | * it under the terms of the GNU General Public License as published by | ||
12 | * the Free Software Foundation; version 2 of the License. | ||
13 | * | ||
14 | * This program is distributed in the hope that it will be useful, but | ||
15 | * WITHOUT ANY WARRANTY; without even the implied warranty of | ||
16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
17 | * General Public License for more details. | ||
18 | * | ||
19 | * You should have received a copy of the GNU General Public License along | ||
20 | * with this program; if not, write to the Free Software Foundation, Inc., | ||
21 | * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. | ||
22 | * | ||
23 | * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | ||
24 | */ | ||
25 | |||
26 | enum sst_codec_types { | ||
27 | /* AUDIO/MUSIC CODEC Type Definitions */ | ||
28 | SST_CODEC_TYPE_UNKNOWN = 0, | ||
29 | SST_CODEC_TYPE_PCM, /* Pass through Audio codec */ | ||
30 | SST_CODEC_TYPE_MP3, | ||
31 | SST_CODEC_TYPE_MP24, | ||
32 | SST_CODEC_TYPE_AAC, | ||
33 | SST_CODEC_TYPE_AACP, | ||
34 | SST_CODEC_TYPE_eAACP, | ||
35 | }; | ||
36 | |||
37 | enum stream_type { | ||
38 | SST_STREAM_TYPE_NONE = 0, | ||
39 | SST_STREAM_TYPE_MUSIC = 1, | ||
40 | }; | ||
41 | |||
42 | struct snd_pcm_params { | ||
43 | u16 codec; /* codec type */ | ||
44 | u8 num_chan; /* 1=Mono, 2=Stereo */ | ||
45 | u8 pcm_wd_sz; /* 16/24 - bit*/ | ||
46 | u32 reserved; /* Bitrate in bits per second */ | ||
47 | u32 sfreq; /* Sampling rate in Hz */ | ||
48 | u8 use_offload_path; | ||
49 | u8 reserved2; | ||
50 | u16 reserved3; | ||
51 | u8 channel_map[8]; | ||
52 | } __packed; | ||
53 | |||
54 | /* MP3 Music Parameters Message */ | ||
55 | struct snd_mp3_params { | ||
56 | u16 codec; | ||
57 | u8 num_chan; /* 1=Mono, 2=Stereo */ | ||
58 | u8 pcm_wd_sz; /* 16/24 - bit*/ | ||
59 | u8 crc_check; /* crc_check - disable (0) or enable (1) */ | ||
60 | u8 reserved1; /* unused*/ | ||
61 | u16 reserved2; /* Unused */ | ||
62 | } __packed; | ||
63 | |||
64 | #define AAC_BIT_STREAM_ADTS 0 | ||
65 | #define AAC_BIT_STREAM_ADIF 1 | ||
66 | #define AAC_BIT_STREAM_RAW 2 | ||
67 | |||
68 | /* AAC Music Parameters Message */ | ||
69 | struct snd_aac_params { | ||
70 | u16 codec; | ||
71 | u8 num_chan; /* 1=Mono, 2=Stereo*/ | ||
72 | u8 pcm_wd_sz; /* 16/24 - bit*/ | ||
73 | u8 bdownsample; /*SBR downsampling 0 - disable 1 -enabled AAC+ only */ | ||
74 | u8 bs_format; /* input bit stream format adts=0, adif=1, raw=2 */ | ||
75 | u16 reser2; | ||
76 | u32 externalsr; /*sampling rate of basic AAC raw bit stream*/ | ||
77 | u8 sbr_signalling;/*disable/enable/set automode the SBR tool.AAC+*/ | ||
78 | u8 reser1; | ||
79 | u16 reser3; | ||
80 | } __packed; | ||
81 | |||
82 | /* WMA Music Parameters Message */ | ||
83 | struct snd_wma_params { | ||
84 | u16 codec; | ||
85 | u8 num_chan; /* 1=Mono, 2=Stereo */ | ||
86 | u8 pcm_wd_sz; /* 16/24 - bit*/ | ||
87 | u32 brate; /* Use the hard coded value. */ | ||
88 | u32 sfreq; /* Sampling freq eg. 8000, 441000, 48000 */ | ||
89 | u32 channel_mask; /* Channel Mask */ | ||
90 | u16 format_tag; /* Format Tag */ | ||
91 | u16 block_align; /* packet size */ | ||
92 | u16 wma_encode_opt;/* Encoder option */ | ||
93 | u8 op_align; /* op align 0- 16 bit, 1- MSB, 2 LSB */ | ||
94 | u8 reserved; /* reserved */ | ||
95 | } __packed; | ||
96 | |||
97 | /* Codec params struture */ | ||
98 | union snd_sst_codec_params { | ||
99 | struct snd_pcm_params pcm_params; | ||
100 | struct snd_mp3_params mp3_params; | ||
101 | struct snd_aac_params aac_params; | ||
102 | struct snd_wma_params wma_params; | ||
103 | } __packed; | ||
104 | |||
105 | /* Address and size info of a frame buffer */ | ||
106 | struct sst_address_info { | ||
107 | u32 addr; /* Address at IA */ | ||
108 | u32 size; /* Size of the buffer */ | ||
109 | }; | ||
110 | |||
111 | struct snd_sst_alloc_params_ext { | ||
112 | struct sst_address_info ring_buf_info[8]; | ||
113 | u8 sg_count; | ||
114 | u8 reserved; | ||
115 | u16 reserved2; | ||
116 | u32 frag_size; /*Number of samples after which period elapsed | ||
117 | message is sent valid only if path = 0*/ | ||
118 | } __packed; | ||
119 | |||
120 | struct snd_sst_stream_params { | ||
121 | union snd_sst_codec_params uc; | ||
122 | } __packed; | ||
123 | |||
124 | struct snd_sst_params { | ||
125 | u32 stream_id; | ||
126 | u8 codec; | ||
127 | u8 ops; | ||
128 | u8 stream_type; | ||
129 | u8 device_type; | ||
130 | struct snd_sst_stream_params sparams; | ||
131 | struct snd_sst_alloc_params_ext aparams; | ||
132 | }; | ||
133 | |||
134 | #endif /* __SST_DSP_H__ */ | ||
diff --git a/sound/soc/mid-x86/sst_platform.c b/sound/soc/mid-x86/sst_platform.c index d34563b12c3b..a263cbed8624 100644 --- a/sound/soc/mid-x86/sst_platform.c +++ b/sound/soc/mid-x86/sst_platform.c | |||
@@ -1,7 +1,7 @@ | |||
1 | /* | 1 | /* |
2 | * sst_platform.c - Intel MID Platform driver | 2 | * sst_platform.c - Intel MID Platform driver |
3 | * | 3 | * |
4 | * Copyright (C) 2010 Intel Corp | 4 | * Copyright (C) 2010-2012 Intel Corp |
5 | * Author: Vinod Koul <vinod.koul@intel.com> | 5 | * Author: Vinod Koul <vinod.koul@intel.com> |
6 | * Author: Harsha Priya <priya.harsha@intel.com> | 6 | * Author: Harsha Priya <priya.harsha@intel.com> |
7 | * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | 7 | * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
@@ -32,6 +32,7 @@ | |||
32 | #include <sound/pcm.h> | 32 | #include <sound/pcm.h> |
33 | #include <sound/pcm_params.h> | 33 | #include <sound/pcm_params.h> |
34 | #include <sound/soc.h> | 34 | #include <sound/soc.h> |
35 | #include <sound/compress_driver.h> | ||
35 | #include "sst_platform.h" | 36 | #include "sst_platform.h" |
36 | 37 | ||
37 | static struct sst_device *sst; | 38 | static struct sst_device *sst; |
@@ -152,6 +153,16 @@ static struct snd_soc_dai_driver sst_platform_dai[] = { | |||
152 | .formats = SNDRV_PCM_FMTBIT_S24_LE, | 153 | .formats = SNDRV_PCM_FMTBIT_S24_LE, |
153 | }, | 154 | }, |
154 | }, | 155 | }, |
156 | { | ||
157 | .name = "Compress-cpu-dai", | ||
158 | .compress_dai = 1, | ||
159 | .playback = { | ||
160 | .channels_min = SST_STEREO, | ||
161 | .channels_max = SST_STEREO, | ||
162 | .rates = SNDRV_PCM_RATE_44100|SNDRV_PCM_RATE_48000, | ||
163 | .formats = SNDRV_PCM_FMTBIT_S16_LE, | ||
164 | }, | ||
165 | }, | ||
155 | }; | 166 | }; |
156 | 167 | ||
157 | /* helper functions */ | 168 | /* helper functions */ |
@@ -463,8 +474,199 @@ static int sst_pcm_new(struct snd_soc_pcm_runtime *rtd) | |||
463 | } | 474 | } |
464 | return retval; | 475 | return retval; |
465 | } | 476 | } |
477 | |||
478 | /* compress stream operations */ | ||
479 | static void sst_compr_fragment_elapsed(void *arg) | ||
480 | { | ||
481 | struct snd_compr_stream *cstream = (struct snd_compr_stream *)arg; | ||
482 | |||
483 | pr_debug("fragment elapsed by driver\n"); | ||
484 | if (cstream) | ||
485 | snd_compr_fragment_elapsed(cstream); | ||
486 | } | ||
487 | |||
488 | static int sst_platform_compr_open(struct snd_compr_stream *cstream) | ||
489 | { | ||
490 | |||
491 | int ret_val = 0; | ||
492 | struct snd_compr_runtime *runtime = cstream->runtime; | ||
493 | struct sst_runtime_stream *stream; | ||
494 | |||
495 | stream = kzalloc(sizeof(*stream), GFP_KERNEL); | ||
496 | if (!stream) | ||
497 | return -ENOMEM; | ||
498 | |||
499 | spin_lock_init(&stream->status_lock); | ||
500 | |||
501 | /* get the sst ops */ | ||
502 | if (!sst || !try_module_get(sst->dev->driver->owner)) { | ||
503 | pr_err("no device available to run\n"); | ||
504 | ret_val = -ENODEV; | ||
505 | goto out_ops; | ||
506 | } | ||
507 | stream->compr_ops = sst->compr_ops; | ||
508 | |||
509 | stream->id = 0; | ||
510 | sst_set_stream_status(stream, SST_PLATFORM_INIT); | ||
511 | runtime->private_data = stream; | ||
512 | return 0; | ||
513 | out_ops: | ||
514 | kfree(stream); | ||
515 | return ret_val; | ||
516 | } | ||
517 | |||
518 | static int sst_platform_compr_free(struct snd_compr_stream *cstream) | ||
519 | { | ||
520 | struct sst_runtime_stream *stream; | ||
521 | int ret_val = 0, str_id; | ||
522 | |||
523 | stream = cstream->runtime->private_data; | ||
524 | /*need to check*/ | ||
525 | str_id = stream->id; | ||
526 | if (str_id) | ||
527 | ret_val = stream->compr_ops->close(str_id); | ||
528 | module_put(sst->dev->driver->owner); | ||
529 | kfree(stream); | ||
530 | pr_debug("%s: %d\n", __func__, ret_val); | ||
531 | return 0; | ||
532 | } | ||
533 | |||
534 | static int sst_platform_compr_set_params(struct snd_compr_stream *cstream, | ||
535 | struct snd_compr_params *params) | ||
536 | { | ||
537 | struct sst_runtime_stream *stream; | ||
538 | int retval; | ||
539 | struct snd_sst_params str_params; | ||
540 | struct sst_compress_cb cb; | ||
541 | |||
542 | stream = cstream->runtime->private_data; | ||
543 | /* construct fw structure for this*/ | ||
544 | memset(&str_params, 0, sizeof(str_params)); | ||
545 | |||
546 | str_params.ops = STREAM_OPS_PLAYBACK; | ||
547 | str_params.stream_type = SST_STREAM_TYPE_MUSIC; | ||
548 | str_params.device_type = SND_SST_DEVICE_COMPRESS; | ||
549 | |||
550 | switch (params->codec.id) { | ||
551 | case SND_AUDIOCODEC_MP3: { | ||
552 | str_params.codec = SST_CODEC_TYPE_MP3; | ||
553 | str_params.sparams.uc.mp3_params.codec = SST_CODEC_TYPE_MP3; | ||
554 | str_params.sparams.uc.mp3_params.num_chan = params->codec.ch_in; | ||
555 | str_params.sparams.uc.mp3_params.pcm_wd_sz = 16; | ||
556 | break; | ||
557 | } | ||
558 | |||
559 | case SND_AUDIOCODEC_AAC: { | ||
560 | str_params.codec = SST_CODEC_TYPE_AAC; | ||
561 | str_params.sparams.uc.aac_params.codec = SST_CODEC_TYPE_AAC; | ||
562 | str_params.sparams.uc.aac_params.num_chan = params->codec.ch_in; | ||
563 | str_params.sparams.uc.aac_params.pcm_wd_sz = 16; | ||
564 | if (params->codec.format == SND_AUDIOSTREAMFORMAT_MP4ADTS) | ||
565 | str_params.sparams.uc.aac_params.bs_format = | ||
566 | AAC_BIT_STREAM_ADTS; | ||
567 | else if (params->codec.format == SND_AUDIOSTREAMFORMAT_RAW) | ||
568 | str_params.sparams.uc.aac_params.bs_format = | ||
569 | AAC_BIT_STREAM_RAW; | ||
570 | else { | ||
571 | pr_err("Undefined format%d\n", params->codec.format); | ||
572 | return -EINVAL; | ||
573 | } | ||
574 | str_params.sparams.uc.aac_params.externalsr = | ||
575 | params->codec.sample_rate; | ||
576 | break; | ||
577 | } | ||
578 | |||
579 | default: | ||
580 | pr_err("codec not supported, id =%d\n", params->codec.id); | ||
581 | return -EINVAL; | ||
582 | } | ||
583 | |||
584 | str_params.aparams.ring_buf_info[0].addr = | ||
585 | virt_to_phys(cstream->runtime->buffer); | ||
586 | str_params.aparams.ring_buf_info[0].size = | ||
587 | cstream->runtime->buffer_size; | ||
588 | str_params.aparams.sg_count = 1; | ||
589 | str_params.aparams.frag_size = cstream->runtime->fragment_size; | ||
590 | |||
591 | cb.param = cstream; | ||
592 | cb.compr_cb = sst_compr_fragment_elapsed; | ||
593 | |||
594 | retval = stream->compr_ops->open(&str_params, &cb); | ||
595 | if (retval < 0) { | ||
596 | pr_err("stream allocation failed %d\n", retval); | ||
597 | return retval; | ||
598 | } | ||
599 | |||
600 | stream->id = retval; | ||
601 | return 0; | ||
602 | } | ||
603 | |||
604 | static int sst_platform_compr_trigger(struct snd_compr_stream *cstream, int cmd) | ||
605 | { | ||
606 | struct sst_runtime_stream *stream = | ||
607 | cstream->runtime->private_data; | ||
608 | |||
609 | return stream->compr_ops->control(cmd, stream->id); | ||
610 | } | ||
611 | |||
612 | static int sst_platform_compr_pointer(struct snd_compr_stream *cstream, | ||
613 | struct snd_compr_tstamp *tstamp) | ||
614 | { | ||
615 | struct sst_runtime_stream *stream; | ||
616 | |||
617 | stream = cstream->runtime->private_data; | ||
618 | stream->compr_ops->tstamp(stream->id, tstamp); | ||
619 | tstamp->byte_offset = tstamp->copied_total % | ||
620 | (u32)cstream->runtime->buffer_size; | ||
621 | pr_debug("calc bytes offset/copied bytes as %d\n", tstamp->byte_offset); | ||
622 | return 0; | ||
623 | } | ||
624 | |||
625 | static int sst_platform_compr_ack(struct snd_compr_stream *cstream, | ||
626 | size_t bytes) | ||
627 | { | ||
628 | struct sst_runtime_stream *stream; | ||
629 | |||
630 | stream = cstream->runtime->private_data; | ||
631 | stream->compr_ops->ack(stream->id, (unsigned long)bytes); | ||
632 | stream->bytes_written += bytes; | ||
633 | |||
634 | return 0; | ||
635 | } | ||
636 | |||
637 | static int sst_platform_compr_get_caps(struct snd_compr_stream *cstream, | ||
638 | struct snd_compr_caps *caps) | ||
639 | { | ||
640 | struct sst_runtime_stream *stream = | ||
641 | cstream->runtime->private_data; | ||
642 | |||
643 | return stream->compr_ops->get_caps(caps); | ||
644 | } | ||
645 | |||
646 | static int sst_platform_compr_get_codec_caps(struct snd_compr_stream *cstream, | ||
647 | struct snd_compr_codec_caps *codec) | ||
648 | { | ||
649 | struct sst_runtime_stream *stream = | ||
650 | cstream->runtime->private_data; | ||
651 | |||
652 | return stream->compr_ops->get_codec_caps(codec); | ||
653 | } | ||
654 | |||
655 | static struct snd_compr_ops sst_platform_compr_ops = { | ||
656 | |||
657 | .open = sst_platform_compr_open, | ||
658 | .free = sst_platform_compr_free, | ||
659 | .set_params = sst_platform_compr_set_params, | ||
660 | .trigger = sst_platform_compr_trigger, | ||
661 | .pointer = sst_platform_compr_pointer, | ||
662 | .ack = sst_platform_compr_ack, | ||
663 | .get_caps = sst_platform_compr_get_caps, | ||
664 | .get_codec_caps = sst_platform_compr_get_codec_caps, | ||
665 | }; | ||
666 | |||
466 | static struct snd_soc_platform_driver sst_soc_platform_drv = { | 667 | static struct snd_soc_platform_driver sst_soc_platform_drv = { |
467 | .ops = &sst_platform_ops, | 668 | .ops = &sst_platform_ops, |
669 | .compr_ops = &sst_platform_compr_ops, | ||
468 | .pcm_new = sst_pcm_new, | 670 | .pcm_new = sst_pcm_new, |
469 | .pcm_free = sst_pcm_free, | 671 | .pcm_free = sst_pcm_free, |
470 | }; | 672 | }; |
diff --git a/sound/soc/mid-x86/sst_platform.h b/sound/soc/mid-x86/sst_platform.h index f04f4f72daa0..d61c5d514ffa 100644 --- a/sound/soc/mid-x86/sst_platform.h +++ b/sound/soc/mid-x86/sst_platform.h | |||
@@ -27,6 +27,8 @@ | |||
27 | #ifndef __SST_PLATFORMDRV_H__ | 27 | #ifndef __SST_PLATFORMDRV_H__ |
28 | #define __SST_PLATFORMDRV_H__ | 28 | #define __SST_PLATFORMDRV_H__ |
29 | 29 | ||
30 | #include "sst_dsp.h" | ||
31 | |||
30 | #define SST_MONO 1 | 32 | #define SST_MONO 1 |
31 | #define SST_STEREO 2 | 33 | #define SST_STEREO 2 |
32 | #define SST_MAX_CAP 5 | 34 | #define SST_MAX_CAP 5 |
@@ -42,7 +44,6 @@ | |||
42 | #define SST_MIN_PERIODS 2 | 44 | #define SST_MIN_PERIODS 2 |
43 | #define SST_MAX_PERIODS (1024*2) | 45 | #define SST_MAX_PERIODS (1024*2) |
44 | #define SST_FIFO_SIZE 0 | 46 | #define SST_FIFO_SIZE 0 |
45 | #define SST_CODEC_TYPE_PCM 1 | ||
46 | 47 | ||
47 | struct pcm_stream_info { | 48 | struct pcm_stream_info { |
48 | int str_id; | 49 | int str_id; |
@@ -83,6 +84,7 @@ enum sst_audio_device_type { | |||
83 | SND_SST_DEVICE_VIBRA, | 84 | SND_SST_DEVICE_VIBRA, |
84 | SND_SST_DEVICE_HAPTIC, | 85 | SND_SST_DEVICE_HAPTIC, |
85 | SND_SST_DEVICE_CAPTURE, | 86 | SND_SST_DEVICE_CAPTURE, |
87 | SND_SST_DEVICE_COMPRESS, | ||
86 | }; | 88 | }; |
87 | 89 | ||
88 | /* PCM Parameters */ | 90 | /* PCM Parameters */ |
@@ -107,6 +109,24 @@ struct sst_stream_params { | |||
107 | struct sst_pcm_params sparams; | 109 | struct sst_pcm_params sparams; |
108 | }; | 110 | }; |
109 | 111 | ||
112 | struct sst_compress_cb { | ||
113 | void *param; | ||
114 | void (*compr_cb)(void *param); | ||
115 | }; | ||
116 | |||
117 | struct compress_sst_ops { | ||
118 | const char *name; | ||
119 | int (*open) (struct snd_sst_params *str_params, | ||
120 | struct sst_compress_cb *cb); | ||
121 | int (*control) (unsigned int cmd, unsigned int str_id); | ||
122 | int (*tstamp) (unsigned int str_id, struct snd_compr_tstamp *tstamp); | ||
123 | int (*ack) (unsigned int str_id, unsigned long bytes); | ||
124 | int (*close) (unsigned int str_id); | ||
125 | int (*get_caps) (struct snd_compr_caps *caps); | ||
126 | int (*get_codec_caps) (struct snd_compr_codec_caps *codec); | ||
127 | |||
128 | }; | ||
129 | |||
110 | struct sst_ops { | 130 | struct sst_ops { |
111 | int (*open) (struct sst_stream_params *str_param); | 131 | int (*open) (struct sst_stream_params *str_param); |
112 | int (*device_control) (int cmd, void *arg); | 132 | int (*device_control) (int cmd, void *arg); |
@@ -115,8 +135,11 @@ struct sst_ops { | |||
115 | 135 | ||
116 | struct sst_runtime_stream { | 136 | struct sst_runtime_stream { |
117 | int stream_status; | 137 | int stream_status; |
138 | unsigned int id; | ||
139 | size_t bytes_written; | ||
118 | struct pcm_stream_info stream_info; | 140 | struct pcm_stream_info stream_info; |
119 | struct sst_ops *ops; | 141 | struct sst_ops *ops; |
142 | struct compress_sst_ops *compr_ops; | ||
120 | spinlock_t status_lock; | 143 | spinlock_t status_lock; |
121 | }; | 144 | }; |
122 | 145 | ||
@@ -124,6 +147,7 @@ struct sst_device { | |||
124 | char *name; | 147 | char *name; |
125 | struct device *dev; | 148 | struct device *dev; |
126 | struct sst_ops *ops; | 149 | struct sst_ops *ops; |
150 | struct compress_sst_ops *compr_ops; | ||
127 | }; | 151 | }; |
128 | 152 | ||
129 | int sst_register_dsp(struct sst_device *sst); | 153 | int sst_register_dsp(struct sst_device *sst); |
diff --git a/sound/soc/mxs/mxs-saif.c b/sound/soc/mxs/mxs-saif.c index aba71bfa33b1..aa037b292f3d 100644 --- a/sound/soc/mxs/mxs-saif.c +++ b/sound/soc/mxs/mxs-saif.c | |||
@@ -394,9 +394,14 @@ static int mxs_saif_hw_params(struct snd_pcm_substream *substream, | |||
394 | struct snd_soc_dai *cpu_dai) | 394 | struct snd_soc_dai *cpu_dai) |
395 | { | 395 | { |
396 | struct mxs_saif *saif = snd_soc_dai_get_drvdata(cpu_dai); | 396 | struct mxs_saif *saif = snd_soc_dai_get_drvdata(cpu_dai); |
397 | struct mxs_saif *master_saif; | ||
397 | u32 scr, stat; | 398 | u32 scr, stat; |
398 | int ret; | 399 | int ret; |
399 | 400 | ||
401 | master_saif = mxs_saif_get_master(saif); | ||
402 | if (!master_saif) | ||
403 | return -EINVAL; | ||
404 | |||
400 | /* mclk should already be set */ | 405 | /* mclk should already be set */ |
401 | if (!saif->mclk && saif->mclk_in_use) { | 406 | if (!saif->mclk && saif->mclk_in_use) { |
402 | dev_err(cpu_dai->dev, "set mclk first\n"); | 407 | dev_err(cpu_dai->dev, "set mclk first\n"); |
@@ -420,6 +425,25 @@ static int mxs_saif_hw_params(struct snd_pcm_substream *substream, | |||
420 | return ret; | 425 | return ret; |
421 | } | 426 | } |
422 | 427 | ||
428 | /* prepare clk in hw_param, enable in trigger */ | ||
429 | clk_prepare(saif->clk); | ||
430 | if (saif != master_saif) { | ||
431 | /* | ||
432 | * Set an initial clock rate for the saif internal logic to work | ||
433 | * properly. This is important when working in EXTMASTER mode | ||
434 | * that uses the other saif's BITCLK&LRCLK but it still needs a | ||
435 | * basic clock which should be fast enough for the internal | ||
436 | * logic. | ||
437 | */ | ||
438 | clk_enable(saif->clk); | ||
439 | ret = clk_set_rate(saif->clk, 24000000); | ||
440 | clk_disable(saif->clk); | ||
441 | if (ret) | ||
442 | return ret; | ||
443 | |||
444 | clk_prepare(master_saif->clk); | ||
445 | } | ||
446 | |||
423 | scr = __raw_readl(saif->base + SAIF_CTRL); | 447 | scr = __raw_readl(saif->base + SAIF_CTRL); |
424 | 448 | ||
425 | scr &= ~BM_SAIF_CTRL_WORD_LENGTH; | 449 | scr &= ~BM_SAIF_CTRL_WORD_LENGTH; |
@@ -680,7 +704,7 @@ static int __devinit mxs_saif_probe(struct platform_device *pdev) | |||
680 | return ret; | 704 | return ret; |
681 | } | 705 | } |
682 | 706 | ||
683 | saif->clk = clk_get(&pdev->dev, NULL); | 707 | saif->clk = devm_clk_get(&pdev->dev, NULL); |
684 | if (IS_ERR(saif->clk)) { | 708 | if (IS_ERR(saif->clk)) { |
685 | ret = PTR_ERR(saif->clk); | 709 | ret = PTR_ERR(saif->clk); |
686 | dev_err(&pdev->dev, "Cannot get the clock: %d\n", | 710 | dev_err(&pdev->dev, "Cannot get the clock: %d\n", |
@@ -693,8 +717,7 @@ static int __devinit mxs_saif_probe(struct platform_device *pdev) | |||
693 | saif->base = devm_request_and_ioremap(&pdev->dev, iores); | 717 | saif->base = devm_request_and_ioremap(&pdev->dev, iores); |
694 | if (!saif->base) { | 718 | if (!saif->base) { |
695 | dev_err(&pdev->dev, "ioremap failed\n"); | 719 | dev_err(&pdev->dev, "ioremap failed\n"); |
696 | ret = -ENODEV; | 720 | return -ENODEV; |
697 | goto failed_get_resource; | ||
698 | } | 721 | } |
699 | 722 | ||
700 | dmares = platform_get_resource(pdev, IORESOURCE_DMA, 0); | 723 | dmares = platform_get_resource(pdev, IORESOURCE_DMA, 0); |
@@ -707,7 +730,7 @@ static int __devinit mxs_saif_probe(struct platform_device *pdev) | |||
707 | &saif->dma_param.chan_num); | 730 | &saif->dma_param.chan_num); |
708 | if (ret) { | 731 | if (ret) { |
709 | dev_err(&pdev->dev, "failed to get dma channel\n"); | 732 | dev_err(&pdev->dev, "failed to get dma channel\n"); |
710 | goto failed_get_resource; | 733 | return ret; |
711 | } | 734 | } |
712 | } else { | 735 | } else { |
713 | saif->dma_param.chan_num = dmares->start; | 736 | saif->dma_param.chan_num = dmares->start; |
@@ -718,7 +741,7 @@ static int __devinit mxs_saif_probe(struct platform_device *pdev) | |||
718 | ret = saif->irq; | 741 | ret = saif->irq; |
719 | dev_err(&pdev->dev, "failed to get irq resource: %d\n", | 742 | dev_err(&pdev->dev, "failed to get irq resource: %d\n", |
720 | ret); | 743 | ret); |
721 | goto failed_get_resource; | 744 | return ret; |
722 | } | 745 | } |
723 | 746 | ||
724 | saif->dev = &pdev->dev; | 747 | saif->dev = &pdev->dev; |
@@ -726,7 +749,7 @@ static int __devinit mxs_saif_probe(struct platform_device *pdev) | |||
726 | "mxs-saif", saif); | 749 | "mxs-saif", saif); |
727 | if (ret) { | 750 | if (ret) { |
728 | dev_err(&pdev->dev, "failed to request irq\n"); | 751 | dev_err(&pdev->dev, "failed to request irq\n"); |
729 | goto failed_get_resource; | 752 | return ret; |
730 | } | 753 | } |
731 | 754 | ||
732 | saif->dma_param.chan_irq = platform_get_irq(pdev, 1); | 755 | saif->dma_param.chan_irq = platform_get_irq(pdev, 1); |
@@ -734,7 +757,7 @@ static int __devinit mxs_saif_probe(struct platform_device *pdev) | |||
734 | ret = saif->dma_param.chan_irq; | 757 | ret = saif->dma_param.chan_irq; |
735 | dev_err(&pdev->dev, "failed to get dma irq resource: %d\n", | 758 | dev_err(&pdev->dev, "failed to get dma irq resource: %d\n", |
736 | ret); | 759 | ret); |
737 | goto failed_get_resource; | 760 | return ret; |
738 | } | 761 | } |
739 | 762 | ||
740 | platform_set_drvdata(pdev, saif); | 763 | platform_set_drvdata(pdev, saif); |
@@ -742,7 +765,7 @@ static int __devinit mxs_saif_probe(struct platform_device *pdev) | |||
742 | ret = snd_soc_register_dai(&pdev->dev, &mxs_saif_dai); | 765 | ret = snd_soc_register_dai(&pdev->dev, &mxs_saif_dai); |
743 | if (ret) { | 766 | if (ret) { |
744 | dev_err(&pdev->dev, "register DAI failed\n"); | 767 | dev_err(&pdev->dev, "register DAI failed\n"); |
745 | goto failed_get_resource; | 768 | return ret; |
746 | } | 769 | } |
747 | 770 | ||
748 | ret = mxs_pcm_platform_register(&pdev->dev); | 771 | ret = mxs_pcm_platform_register(&pdev->dev); |
@@ -755,19 +778,14 @@ static int __devinit mxs_saif_probe(struct platform_device *pdev) | |||
755 | 778 | ||
756 | failed_pdev_alloc: | 779 | failed_pdev_alloc: |
757 | snd_soc_unregister_dai(&pdev->dev); | 780 | snd_soc_unregister_dai(&pdev->dev); |
758 | failed_get_resource: | ||
759 | clk_put(saif->clk); | ||
760 | 781 | ||
761 | return ret; | 782 | return ret; |
762 | } | 783 | } |
763 | 784 | ||
764 | static int __devexit mxs_saif_remove(struct platform_device *pdev) | 785 | static int __devexit mxs_saif_remove(struct platform_device *pdev) |
765 | { | 786 | { |
766 | struct mxs_saif *saif = platform_get_drvdata(pdev); | ||
767 | |||
768 | mxs_pcm_platform_unregister(&pdev->dev); | 787 | mxs_pcm_platform_unregister(&pdev->dev); |
769 | snd_soc_unregister_dai(&pdev->dev); | 788 | snd_soc_unregister_dai(&pdev->dev); |
770 | clk_put(saif->clk); | ||
771 | 789 | ||
772 | return 0; | 790 | return 0; |
773 | } | 791 | } |
diff --git a/sound/soc/omap/omap-abe-twl6040.c b/sound/soc/omap/omap-abe-twl6040.c index 9d93793d3077..be525dfe9faa 100644 --- a/sound/soc/omap/omap-abe-twl6040.c +++ b/sound/soc/omap/omap-abe-twl6040.c | |||
@@ -25,6 +25,7 @@ | |||
25 | #include <linux/mfd/twl6040.h> | 25 | #include <linux/mfd/twl6040.h> |
26 | #include <linux/platform_data/omap-abe-twl6040.h> | 26 | #include <linux/platform_data/omap-abe-twl6040.h> |
27 | #include <linux/module.h> | 27 | #include <linux/module.h> |
28 | #include <linux/of.h> | ||
28 | 29 | ||
29 | #include <sound/core.h> | 30 | #include <sound/core.h> |
30 | #include <sound/pcm.h> | 31 | #include <sound/pcm.h> |
@@ -43,6 +44,8 @@ | |||
43 | struct abe_twl6040 { | 44 | struct abe_twl6040 { |
44 | int jack_detection; /* board can detect jack events */ | 45 | int jack_detection; /* board can detect jack events */ |
45 | int mclk_freq; /* MCLK frequency speed for twl6040 */ | 46 | int mclk_freq; /* MCLK frequency speed for twl6040 */ |
47 | |||
48 | struct platform_device *dmic_codec_dev; | ||
46 | }; | 49 | }; |
47 | 50 | ||
48 | static int omap_abe_hw_params(struct snd_pcm_substream *substream, | 51 | static int omap_abe_hw_params(struct snd_pcm_substream *substream, |
@@ -185,17 +188,6 @@ static int omap_abe_twl6040_init(struct snd_soc_pcm_runtime *rtd) | |||
185 | int hs_trim; | 188 | int hs_trim; |
186 | int ret = 0; | 189 | int ret = 0; |
187 | 190 | ||
188 | /* Disable not connected paths if not used */ | ||
189 | twl6040_disconnect_pin(dapm, pdata->has_hs, "Headset Stereophone"); | ||
190 | twl6040_disconnect_pin(dapm, pdata->has_hf, "Ext Spk"); | ||
191 | twl6040_disconnect_pin(dapm, pdata->has_ep, "Earphone Spk"); | ||
192 | twl6040_disconnect_pin(dapm, pdata->has_aux, "Line Out"); | ||
193 | twl6040_disconnect_pin(dapm, pdata->has_vibra, "Vinrator"); | ||
194 | twl6040_disconnect_pin(dapm, pdata->has_hsmic, "Headset Mic"); | ||
195 | twl6040_disconnect_pin(dapm, pdata->has_mainmic, "Main Handset Mic"); | ||
196 | twl6040_disconnect_pin(dapm, pdata->has_submic, "Sub Handset Mic"); | ||
197 | twl6040_disconnect_pin(dapm, pdata->has_afm, "Line In"); | ||
198 | |||
199 | /* | 191 | /* |
200 | * Configure McPDM offset cancellation based on the HSOTRIM value from | 192 | * Configure McPDM offset cancellation based on the HSOTRIM value from |
201 | * twl6040. | 193 | * twl6040. |
@@ -216,6 +208,24 @@ static int omap_abe_twl6040_init(struct snd_soc_pcm_runtime *rtd) | |||
216 | twl6040_hs_jack_detect(codec, &hs_jack, SND_JACK_HEADSET); | 208 | twl6040_hs_jack_detect(codec, &hs_jack, SND_JACK_HEADSET); |
217 | } | 209 | } |
218 | 210 | ||
211 | /* | ||
212 | * NULL pdata means we booted with DT. In this case the routing is | ||
213 | * provided and the card is fully routed, no need to mark pins. | ||
214 | */ | ||
215 | if (!pdata) | ||
216 | return ret; | ||
217 | |||
218 | /* Disable not connected paths if not used */ | ||
219 | twl6040_disconnect_pin(dapm, pdata->has_hs, "Headset Stereophone"); | ||
220 | twl6040_disconnect_pin(dapm, pdata->has_hf, "Ext Spk"); | ||
221 | twl6040_disconnect_pin(dapm, pdata->has_ep, "Earphone Spk"); | ||
222 | twl6040_disconnect_pin(dapm, pdata->has_aux, "Line Out"); | ||
223 | twl6040_disconnect_pin(dapm, pdata->has_vibra, "Vinrator"); | ||
224 | twl6040_disconnect_pin(dapm, pdata->has_hsmic, "Headset Mic"); | ||
225 | twl6040_disconnect_pin(dapm, pdata->has_mainmic, "Main Handset Mic"); | ||
226 | twl6040_disconnect_pin(dapm, pdata->has_submic, "Sub Handset Mic"); | ||
227 | twl6040_disconnect_pin(dapm, pdata->has_afm, "Line In"); | ||
228 | |||
219 | return ret; | 229 | return ret; |
220 | } | 230 | } |
221 | 231 | ||
@@ -270,52 +280,116 @@ static struct snd_soc_card omap_abe_card = { | |||
270 | static __devinit int omap_abe_probe(struct platform_device *pdev) | 280 | static __devinit int omap_abe_probe(struct platform_device *pdev) |
271 | { | 281 | { |
272 | struct omap_abe_twl6040_data *pdata = dev_get_platdata(&pdev->dev); | 282 | struct omap_abe_twl6040_data *pdata = dev_get_platdata(&pdev->dev); |
283 | struct device_node *node = pdev->dev.of_node; | ||
273 | struct snd_soc_card *card = &omap_abe_card; | 284 | struct snd_soc_card *card = &omap_abe_card; |
274 | struct abe_twl6040 *priv; | 285 | struct abe_twl6040 *priv; |
275 | int num_links = 0; | 286 | int num_links = 0; |
276 | int ret; | 287 | int ret = 0; |
277 | 288 | ||
278 | card->dev = &pdev->dev; | 289 | card->dev = &pdev->dev; |
279 | 290 | ||
280 | if (!pdata) { | ||
281 | dev_err(&pdev->dev, "Missing pdata\n"); | ||
282 | return -ENODEV; | ||
283 | } | ||
284 | |||
285 | priv = devm_kzalloc(&pdev->dev, sizeof(struct abe_twl6040), GFP_KERNEL); | 291 | priv = devm_kzalloc(&pdev->dev, sizeof(struct abe_twl6040), GFP_KERNEL); |
286 | if (priv == NULL) | 292 | if (priv == NULL) |
287 | return -ENOMEM; | 293 | return -ENOMEM; |
288 | 294 | ||
289 | if (pdata->card_name) { | 295 | priv->dmic_codec_dev = ERR_PTR(-EINVAL); |
290 | card->name = pdata->card_name; | 296 | |
297 | if (node) { | ||
298 | struct device_node *dai_node; | ||
299 | |||
300 | if (snd_soc_of_parse_card_name(card, "ti,model")) { | ||
301 | dev_err(&pdev->dev, "Card name is not provided\n"); | ||
302 | return -ENODEV; | ||
303 | } | ||
304 | |||
305 | ret = snd_soc_of_parse_audio_routing(card, | ||
306 | "ti,audio-routing"); | ||
307 | if (ret) { | ||
308 | dev_err(&pdev->dev, | ||
309 | "Error while parsing DAPM routing\n"); | ||
310 | return ret; | ||
311 | } | ||
312 | |||
313 | dai_node = of_parse_phandle(node, "ti,mcpdm", 0); | ||
314 | if (!dai_node) { | ||
315 | dev_err(&pdev->dev, "McPDM node is not provided\n"); | ||
316 | return -EINVAL; | ||
317 | } | ||
318 | abe_twl6040_dai_links[0].cpu_dai_name = NULL; | ||
319 | abe_twl6040_dai_links[0].cpu_of_node = dai_node; | ||
320 | |||
321 | dai_node = of_parse_phandle(node, "ti,dmic", 0); | ||
322 | if (dai_node) { | ||
323 | num_links = 2; | ||
324 | abe_twl6040_dai_links[1].cpu_dai_name = NULL; | ||
325 | abe_twl6040_dai_links[1].cpu_of_node = dai_node; | ||
326 | |||
327 | priv->dmic_codec_dev = platform_device_register_simple( | ||
328 | "dmic-codec", -1, NULL, 0); | ||
329 | if (IS_ERR(priv->dmic_codec_dev)) { | ||
330 | dev_err(&pdev->dev, | ||
331 | "Can't instantiate dmic-codec\n"); | ||
332 | return PTR_ERR(priv->dmic_codec_dev); | ||
333 | } | ||
334 | } else { | ||
335 | num_links = 1; | ||
336 | } | ||
337 | |||
338 | of_property_read_u32(node, "ti,jack-detection", | ||
339 | &priv->jack_detection); | ||
340 | of_property_read_u32(node, "ti,mclk-freq", | ||
341 | &priv->mclk_freq); | ||
342 | if (!priv->mclk_freq) { | ||
343 | dev_err(&pdev->dev, "MCLK frequency not provided\n"); | ||
344 | ret = -EINVAL; | ||
345 | goto err_unregister; | ||
346 | } | ||
347 | |||
348 | omap_abe_card.fully_routed = 1; | ||
349 | } else if (pdata) { | ||
350 | if (pdata->card_name) { | ||
351 | card->name = pdata->card_name; | ||
352 | } else { | ||
353 | dev_err(&pdev->dev, "Card name is not provided\n"); | ||
354 | return -ENODEV; | ||
355 | } | ||
356 | |||
357 | if (pdata->has_dmic) | ||
358 | num_links = 2; | ||
359 | else | ||
360 | num_links = 1; | ||
361 | |||
362 | priv->jack_detection = pdata->jack_detection; | ||
363 | priv->mclk_freq = pdata->mclk_freq; | ||
291 | } else { | 364 | } else { |
292 | dev_err(&pdev->dev, "Card name is not provided\n"); | 365 | dev_err(&pdev->dev, "Missing pdata\n"); |
293 | return -ENODEV; | 366 | return -ENODEV; |
294 | } | 367 | } |
295 | 368 | ||
296 | priv->jack_detection = pdata->jack_detection; | ||
297 | priv->mclk_freq = pdata->mclk_freq; | ||
298 | |||
299 | 369 | ||
300 | if (!priv->mclk_freq) { | 370 | if (!priv->mclk_freq) { |
301 | dev_err(&pdev->dev, "MCLK frequency missing\n"); | 371 | dev_err(&pdev->dev, "MCLK frequency missing\n"); |
302 | return -ENODEV; | 372 | ret = -ENODEV; |
373 | goto err_unregister; | ||
303 | } | 374 | } |
304 | 375 | ||
305 | if (pdata->has_dmic) | ||
306 | num_links = 2; | ||
307 | else | ||
308 | num_links = 1; | ||
309 | |||
310 | card->dai_link = abe_twl6040_dai_links; | 376 | card->dai_link = abe_twl6040_dai_links; |
311 | card->num_links = num_links; | 377 | card->num_links = num_links; |
312 | 378 | ||
313 | snd_soc_card_set_drvdata(card, priv); | 379 | snd_soc_card_set_drvdata(card, priv); |
314 | 380 | ||
315 | ret = snd_soc_register_card(card); | 381 | ret = snd_soc_register_card(card); |
316 | if (ret) | 382 | if (ret) { |
317 | dev_err(&pdev->dev, "snd_soc_register_card() failed: %d\n", | 383 | dev_err(&pdev->dev, "snd_soc_register_card() failed: %d\n", |
318 | ret); | 384 | ret); |
385 | goto err_unregister; | ||
386 | } | ||
387 | |||
388 | return 0; | ||
389 | |||
390 | err_unregister: | ||
391 | if (!IS_ERR(priv->dmic_codec_dev)) | ||
392 | platform_device_unregister(priv->dmic_codec_dev); | ||
319 | 393 | ||
320 | return ret; | 394 | return ret; |
321 | } | 395 | } |
@@ -323,17 +397,28 @@ static __devinit int omap_abe_probe(struct platform_device *pdev) | |||
323 | static int __devexit omap_abe_remove(struct platform_device *pdev) | 397 | static int __devexit omap_abe_remove(struct platform_device *pdev) |
324 | { | 398 | { |
325 | struct snd_soc_card *card = platform_get_drvdata(pdev); | 399 | struct snd_soc_card *card = platform_get_drvdata(pdev); |
400 | struct abe_twl6040 *priv = snd_soc_card_get_drvdata(card); | ||
326 | 401 | ||
327 | snd_soc_unregister_card(card); | 402 | snd_soc_unregister_card(card); |
328 | 403 | ||
404 | if (!IS_ERR(priv->dmic_codec_dev)) | ||
405 | platform_device_unregister(priv->dmic_codec_dev); | ||
406 | |||
329 | return 0; | 407 | return 0; |
330 | } | 408 | } |
331 | 409 | ||
410 | static const struct of_device_id omap_abe_of_match[] = { | ||
411 | {.compatible = "ti,abe-twl6040", }, | ||
412 | { }, | ||
413 | }; | ||
414 | MODULE_DEVICE_TABLE(of, omap_abe_of_match); | ||
415 | |||
332 | static struct platform_driver omap_abe_driver = { | 416 | static struct platform_driver omap_abe_driver = { |
333 | .driver = { | 417 | .driver = { |
334 | .name = "omap-abe-twl6040", | 418 | .name = "omap-abe-twl6040", |
335 | .owner = THIS_MODULE, | 419 | .owner = THIS_MODULE, |
336 | .pm = &snd_soc_pm_ops, | 420 | .pm = &snd_soc_pm_ops, |
421 | .of_match_table = omap_abe_of_match, | ||
337 | }, | 422 | }, |
338 | .probe = omap_abe_probe, | 423 | .probe = omap_abe_probe, |
339 | .remove = __devexit_p(omap_abe_remove), | 424 | .remove = __devexit_p(omap_abe_remove), |
diff --git a/sound/soc/omap/omap-mcbsp.c b/sound/soc/omap/omap-mcbsp.c index 2e1750e2ab31..d6de066ad7ea 100644 --- a/sound/soc/omap/omap-mcbsp.c +++ b/sound/soc/omap/omap-mcbsp.c | |||
@@ -860,3 +860,4 @@ module_platform_driver(asoc_mcbsp_driver); | |||
860 | MODULE_AUTHOR("Jarkko Nikula <jarkko.nikula@bitmer.com>"); | 860 | MODULE_AUTHOR("Jarkko Nikula <jarkko.nikula@bitmer.com>"); |
861 | MODULE_DESCRIPTION("OMAP I2S SoC Interface"); | 861 | MODULE_DESCRIPTION("OMAP I2S SoC Interface"); |
862 | MODULE_LICENSE("GPL"); | 862 | MODULE_LICENSE("GPL"); |
863 | MODULE_ALIAS("platform:omap-mcbsp"); | ||
diff --git a/sound/soc/omap/omap-mcpdm.c b/sound/soc/omap/omap-mcpdm.c index 2c66e2498a45..f7babb374a37 100644 --- a/sound/soc/omap/omap-mcpdm.c +++ b/sound/soc/omap/omap-mcpdm.c | |||
@@ -445,9 +445,8 @@ static __devinit int asoc_mcpdm_probe(struct platform_device *pdev) | |||
445 | { | 445 | { |
446 | struct omap_mcpdm *mcpdm; | 446 | struct omap_mcpdm *mcpdm; |
447 | struct resource *res; | 447 | struct resource *res; |
448 | int ret = 0; | ||
449 | 448 | ||
450 | mcpdm = kzalloc(sizeof(struct omap_mcpdm), GFP_KERNEL); | 449 | mcpdm = devm_kzalloc(&pdev->dev, sizeof(struct omap_mcpdm), GFP_KERNEL); |
451 | if (!mcpdm) | 450 | if (!mcpdm) |
452 | return -ENOMEM; | 451 | return -ENOMEM; |
453 | 452 | ||
@@ -456,55 +455,30 @@ static __devinit int asoc_mcpdm_probe(struct platform_device *pdev) | |||
456 | mutex_init(&mcpdm->mutex); | 455 | mutex_init(&mcpdm->mutex); |
457 | 456 | ||
458 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 457 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
459 | if (res == NULL) { | 458 | if (res == NULL) |
460 | dev_err(&pdev->dev, "no resource\n"); | 459 | return -ENOMEM; |
461 | goto err_res; | ||
462 | } | ||
463 | 460 | ||
464 | if (!request_mem_region(res->start, resource_size(res), "McPDM")) { | 461 | if (!devm_request_mem_region(&pdev->dev, res->start, |
465 | ret = -EBUSY; | 462 | resource_size(res), "McPDM")) |
466 | goto err_res; | 463 | return -EBUSY; |
467 | } | ||
468 | 464 | ||
469 | mcpdm->io_base = ioremap(res->start, resource_size(res)); | 465 | mcpdm->io_base = devm_ioremap(&pdev->dev, res->start, |
470 | if (!mcpdm->io_base) { | 466 | resource_size(res)); |
471 | ret = -ENOMEM; | 467 | if (!mcpdm->io_base) |
472 | goto err_iomap; | 468 | return -ENOMEM; |
473 | } | ||
474 | 469 | ||
475 | mcpdm->irq = platform_get_irq(pdev, 0); | 470 | mcpdm->irq = platform_get_irq(pdev, 0); |
476 | if (mcpdm->irq < 0) { | 471 | if (mcpdm->irq < 0) |
477 | ret = mcpdm->irq; | 472 | return mcpdm->irq; |
478 | goto err_irq; | ||
479 | } | ||
480 | 473 | ||
481 | mcpdm->dev = &pdev->dev; | 474 | mcpdm->dev = &pdev->dev; |
482 | 475 | ||
483 | ret = snd_soc_register_dai(&pdev->dev, &omap_mcpdm_dai); | 476 | return snd_soc_register_dai(&pdev->dev, &omap_mcpdm_dai); |
484 | if (!ret) | ||
485 | return 0; | ||
486 | |||
487 | err_irq: | ||
488 | iounmap(mcpdm->io_base); | ||
489 | err_iomap: | ||
490 | release_mem_region(res->start, resource_size(res)); | ||
491 | err_res: | ||
492 | kfree(mcpdm); | ||
493 | return ret; | ||
494 | } | 477 | } |
495 | 478 | ||
496 | static int __devexit asoc_mcpdm_remove(struct platform_device *pdev) | 479 | static int __devexit asoc_mcpdm_remove(struct platform_device *pdev) |
497 | { | 480 | { |
498 | struct omap_mcpdm *mcpdm = platform_get_drvdata(pdev); | ||
499 | struct resource *res; | ||
500 | |||
501 | snd_soc_unregister_dai(&pdev->dev); | 481 | snd_soc_unregister_dai(&pdev->dev); |
502 | |||
503 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
504 | iounmap(mcpdm->io_base); | ||
505 | release_mem_region(res->start, resource_size(res)); | ||
506 | |||
507 | kfree(mcpdm); | ||
508 | return 0; | 482 | return 0; |
509 | } | 483 | } |
510 | 484 | ||
diff --git a/sound/soc/omap/omap-pcm.c b/sound/soc/omap/omap-pcm.c index 5a649da9122a..f0feb06615f8 100644 --- a/sound/soc/omap/omap-pcm.c +++ b/sound/soc/omap/omap-pcm.c | |||
@@ -441,3 +441,4 @@ module_platform_driver(omap_pcm_driver); | |||
441 | MODULE_AUTHOR("Jarkko Nikula <jarkko.nikula@bitmer.com>"); | 441 | MODULE_AUTHOR("Jarkko Nikula <jarkko.nikula@bitmer.com>"); |
442 | MODULE_DESCRIPTION("OMAP PCM DMA module"); | 442 | MODULE_DESCRIPTION("OMAP PCM DMA module"); |
443 | MODULE_LICENSE("GPL"); | 443 | MODULE_LICENSE("GPL"); |
444 | MODULE_ALIAS("platform:omap-pcm-audio"); | ||
diff --git a/sound/soc/samsung/Kconfig b/sound/soc/samsung/Kconfig index fe3995ce9b38..fb5600083612 100644 --- a/sound/soc/samsung/Kconfig +++ b/sound/soc/samsung/Kconfig | |||
@@ -199,6 +199,14 @@ config SND_SOC_TOBERMORY | |||
199 | select SND_SAMSUNG_I2S | 199 | select SND_SAMSUNG_I2S |
200 | select SND_SOC_WM8962 | 200 | select SND_SOC_WM8962 |
201 | 201 | ||
202 | config SND_SOC_BELLS | ||
203 | tristate "Audio support for Wolfson Bells" | ||
204 | depends on SND_SOC_SAMSUNG && MACH_WLF_CRAGG_6410 | ||
205 | select SND_SAMSUNG_I2S | ||
206 | select SND_SOC_WM5102 | ||
207 | select SND_SOC_WM5110 | ||
208 | select SND_SOC_WM9081 | ||
209 | |||
202 | config SND_SOC_LOWLAND | 210 | config SND_SOC_LOWLAND |
203 | tristate "Audio support for Wolfson Lowland" | 211 | tristate "Audio support for Wolfson Lowland" |
204 | depends on SND_SOC_SAMSUNG && MACH_WLF_CRAGG_6410 | 212 | depends on SND_SOC_SAMSUNG && MACH_WLF_CRAGG_6410 |
diff --git a/sound/soc/samsung/Makefile b/sound/soc/samsung/Makefile index 9d03beb40c86..709f6059ad67 100644 --- a/sound/soc/samsung/Makefile +++ b/sound/soc/samsung/Makefile | |||
@@ -42,6 +42,7 @@ snd-soc-speyside-objs := speyside.o | |||
42 | snd-soc-tobermory-objs := tobermory.o | 42 | snd-soc-tobermory-objs := tobermory.o |
43 | snd-soc-lowland-objs := lowland.o | 43 | snd-soc-lowland-objs := lowland.o |
44 | snd-soc-littlemill-objs := littlemill.o | 44 | snd-soc-littlemill-objs := littlemill.o |
45 | snd-soc-bells-objs := bells.o | ||
45 | 46 | ||
46 | obj-$(CONFIG_SND_SOC_SAMSUNG_JIVE_WM8750) += snd-soc-jive-wm8750.o | 47 | obj-$(CONFIG_SND_SOC_SAMSUNG_JIVE_WM8750) += snd-soc-jive-wm8750.o |
47 | obj-$(CONFIG_SND_SOC_SAMSUNG_NEO1973_WM8753) += snd-soc-neo1973-wm8753.o | 48 | obj-$(CONFIG_SND_SOC_SAMSUNG_NEO1973_WM8753) += snd-soc-neo1973-wm8753.o |
@@ -65,3 +66,4 @@ obj-$(CONFIG_SND_SOC_SPEYSIDE) += snd-soc-speyside.o | |||
65 | obj-$(CONFIG_SND_SOC_TOBERMORY) += snd-soc-tobermory.o | 66 | obj-$(CONFIG_SND_SOC_TOBERMORY) += snd-soc-tobermory.o |
66 | obj-$(CONFIG_SND_SOC_LOWLAND) += snd-soc-lowland.o | 67 | obj-$(CONFIG_SND_SOC_LOWLAND) += snd-soc-lowland.o |
67 | obj-$(CONFIG_SND_SOC_LITTLEMILL) += snd-soc-littlemill.o | 68 | obj-$(CONFIG_SND_SOC_LITTLEMILL) += snd-soc-littlemill.o |
69 | obj-$(CONFIG_SND_SOC_BELLS) += snd-soc-bells.o | ||
diff --git a/sound/soc/samsung/bells.c b/sound/soc/samsung/bells.c new file mode 100644 index 000000000000..5dc10dfc0d42 --- /dev/null +++ b/sound/soc/samsung/bells.c | |||
@@ -0,0 +1,346 @@ | |||
1 | /* | ||
2 | * Bells audio support | ||
3 | * | ||
4 | * Copyright 2012 Wolfson Microelectronics | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify it | ||
7 | * under the terms of the GNU General Public License as published by the | ||
8 | * Free Software Foundation; either version 2 of the License, or (at your | ||
9 | * option) any later version. | ||
10 | */ | ||
11 | |||
12 | #include <sound/soc.h> | ||
13 | #include <sound/soc-dapm.h> | ||
14 | #include <sound/jack.h> | ||
15 | #include <linux/gpio.h> | ||
16 | #include <linux/module.h> | ||
17 | |||
18 | #include "../codecs/wm5102.h" | ||
19 | #include "../codecs/wm9081.h" | ||
20 | |||
21 | /* | ||
22 | * 44.1kHz based clocks for the SYSCLK domain, use a very high clock | ||
23 | * to allow all the DSP functionality to be enabled if desired. | ||
24 | */ | ||
25 | #define SYSCLK_RATE (44100 * 1024) | ||
26 | |||
27 | /* 48kHz based clocks for the ASYNC domain */ | ||
28 | #define ASYNCCLK_RATE (48000 * 512) | ||
29 | |||
30 | /* BCLK2 is fixed at this currently */ | ||
31 | #define BCLK2_RATE (64 * 8000) | ||
32 | |||
33 | /* | ||
34 | * Expect a 24.576MHz crystal if one is fitted (the driver will function | ||
35 | * if this is not fitted). | ||
36 | */ | ||
37 | #define MCLK_RATE 24576000 | ||
38 | |||
39 | #define WM9081_AUDIO_RATE 44100 | ||
40 | #define WM9081_MCLK_RATE (WM9081_AUDIO_RATE * 256) | ||
41 | |||
42 | static int bells_set_bias_level(struct snd_soc_card *card, | ||
43 | struct snd_soc_dapm_context *dapm, | ||
44 | enum snd_soc_bias_level level) | ||
45 | { | ||
46 | struct snd_soc_dai *codec_dai = card->rtd[0].codec_dai; | ||
47 | struct snd_soc_codec *codec = codec_dai->codec; | ||
48 | int ret; | ||
49 | |||
50 | if (dapm->dev != codec_dai->dev) | ||
51 | return 0; | ||
52 | |||
53 | switch (level) { | ||
54 | case SND_SOC_BIAS_PREPARE: | ||
55 | if (dapm->bias_level == SND_SOC_BIAS_STANDBY) { | ||
56 | ret = snd_soc_codec_set_pll(codec, WM5102_FLL1, | ||
57 | ARIZONA_FLL_SRC_MCLK1, | ||
58 | MCLK_RATE, | ||
59 | SYSCLK_RATE); | ||
60 | if (ret < 0) | ||
61 | pr_err("Failed to start FLL: %d\n", ret); | ||
62 | |||
63 | ret = snd_soc_codec_set_pll(codec, WM5102_FLL2, | ||
64 | ARIZONA_FLL_SRC_AIF2BCLK, | ||
65 | BCLK2_RATE, | ||
66 | ASYNCCLK_RATE); | ||
67 | if (ret < 0) | ||
68 | pr_err("Failed to start FLL: %d\n", ret); | ||
69 | } | ||
70 | break; | ||
71 | |||
72 | default: | ||
73 | break; | ||
74 | } | ||
75 | |||
76 | return 0; | ||
77 | } | ||
78 | |||
79 | static int bells_set_bias_level_post(struct snd_soc_card *card, | ||
80 | struct snd_soc_dapm_context *dapm, | ||
81 | enum snd_soc_bias_level level) | ||
82 | { | ||
83 | struct snd_soc_dai *codec_dai = card->rtd[0].codec_dai; | ||
84 | struct snd_soc_codec *codec = codec_dai->codec; | ||
85 | int ret; | ||
86 | |||
87 | if (dapm->dev != codec_dai->dev) | ||
88 | return 0; | ||
89 | |||
90 | switch (level) { | ||
91 | case SND_SOC_BIAS_STANDBY: | ||
92 | ret = snd_soc_codec_set_pll(codec, WM5102_FLL1, 0, 0, 0); | ||
93 | if (ret < 0) { | ||
94 | pr_err("Failed to stop FLL: %d\n", ret); | ||
95 | return ret; | ||
96 | } | ||
97 | |||
98 | ret = snd_soc_codec_set_pll(codec, WM5102_FLL2, 0, 0, 0); | ||
99 | if (ret < 0) { | ||
100 | pr_err("Failed to stop FLL: %d\n", ret); | ||
101 | return ret; | ||
102 | } | ||
103 | break; | ||
104 | |||
105 | default: | ||
106 | break; | ||
107 | } | ||
108 | |||
109 | dapm->bias_level = level; | ||
110 | |||
111 | return 0; | ||
112 | } | ||
113 | |||
114 | static int bells_late_probe(struct snd_soc_card *card) | ||
115 | { | ||
116 | struct snd_soc_codec *codec = card->rtd[0].codec; | ||
117 | struct snd_soc_dai *aif1_dai = card->rtd[0].codec_dai; | ||
118 | struct snd_soc_dai *aif2_dai = card->rtd[1].cpu_dai; | ||
119 | struct snd_soc_dai *aif3_dai = card->rtd[2].cpu_dai; | ||
120 | struct snd_soc_dai *wm9081_dai = card->rtd[2].codec_dai; | ||
121 | int ret; | ||
122 | |||
123 | ret = snd_soc_dai_set_sysclk(aif1_dai, ARIZONA_CLK_SYSCLK, 0, 0); | ||
124 | if (ret != 0) { | ||
125 | dev_err(aif1_dai->dev, "Failed to set AIF1 clock: %d\n", ret); | ||
126 | return ret; | ||
127 | } | ||
128 | |||
129 | ret = snd_soc_dai_set_sysclk(aif2_dai, ARIZONA_CLK_ASYNCCLK, 0, 0); | ||
130 | if (ret != 0) { | ||
131 | dev_err(aif2_dai->dev, "Failed to set AIF2 clock: %d\n", ret); | ||
132 | return ret; | ||
133 | } | ||
134 | |||
135 | ret = snd_soc_dai_set_sysclk(aif3_dai, ARIZONA_CLK_SYSCLK, 0, 0); | ||
136 | if (ret != 0) { | ||
137 | dev_err(aif1_dai->dev, "Failed to set AIF1 clock: %d\n", ret); | ||
138 | return ret; | ||
139 | } | ||
140 | |||
141 | ret = snd_soc_codec_set_sysclk(codec, ARIZONA_CLK_SYSCLK, | ||
142 | ARIZONA_CLK_SRC_FLL1, SYSCLK_RATE, | ||
143 | SND_SOC_CLOCK_IN); | ||
144 | if (ret != 0) { | ||
145 | dev_err(codec->dev, "Failed to set SYSCLK: %d\n", ret); | ||
146 | return ret; | ||
147 | } | ||
148 | |||
149 | ret = snd_soc_codec_set_sysclk(codec, ARIZONA_CLK_OPCLK, 0, | ||
150 | WM9081_MCLK_RATE, SND_SOC_CLOCK_OUT); | ||
151 | if (ret != 0) { | ||
152 | dev_err(codec->dev, "Failed to set OPCLK: %d\n", ret); | ||
153 | return ret; | ||
154 | } | ||
155 | |||
156 | ret = snd_soc_codec_set_sysclk(codec, ARIZONA_CLK_ASYNCCLK, | ||
157 | ARIZONA_CLK_SRC_FLL2, ASYNCCLK_RATE, | ||
158 | SND_SOC_CLOCK_IN); | ||
159 | if (ret != 0) { | ||
160 | dev_err(codec->dev, "Failed to set SYSCLK: %d\n", ret); | ||
161 | return ret; | ||
162 | } | ||
163 | |||
164 | ret = snd_soc_codec_set_sysclk(wm9081_dai->codec, WM9081_SYSCLK_MCLK, | ||
165 | 0, WM9081_MCLK_RATE, 0); | ||
166 | if (ret != 0) { | ||
167 | dev_err(wm9081_dai->dev, "Failed to set MCLK: %d\n", ret); | ||
168 | return ret; | ||
169 | } | ||
170 | |||
171 | return 0; | ||
172 | } | ||
173 | |||
174 | static const struct snd_soc_pcm_stream baseband_params = { | ||
175 | .formats = SNDRV_PCM_FMTBIT_S32_LE, | ||
176 | .rate_min = 8000, | ||
177 | .rate_max = 8000, | ||
178 | .channels_min = 2, | ||
179 | .channels_max = 2, | ||
180 | }; | ||
181 | |||
182 | static const struct snd_soc_pcm_stream sub_params = { | ||
183 | .formats = SNDRV_PCM_FMTBIT_S32_LE, | ||
184 | .rate_min = WM9081_AUDIO_RATE, | ||
185 | .rate_max = WM9081_AUDIO_RATE, | ||
186 | .channels_min = 2, | ||
187 | .channels_max = 2, | ||
188 | }; | ||
189 | |||
190 | static struct snd_soc_dai_link bells_dai_wm5102[] = { | ||
191 | { | ||
192 | .name = "CPU", | ||
193 | .stream_name = "CPU", | ||
194 | .cpu_dai_name = "samsung-i2s.0", | ||
195 | .codec_dai_name = "wm5102-aif1", | ||
196 | .platform_name = "samsung-audio", | ||
197 | .codec_name = "wm5102-codec", | ||
198 | .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | ||
199 | | SND_SOC_DAIFMT_CBM_CFM, | ||
200 | }, | ||
201 | { | ||
202 | .name = "Baseband", | ||
203 | .stream_name = "Baseband", | ||
204 | .cpu_dai_name = "wm5102-aif2", | ||
205 | .codec_dai_name = "wm1250-ev1", | ||
206 | .codec_name = "wm1250-ev1.1-0027", | ||
207 | .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | ||
208 | | SND_SOC_DAIFMT_CBM_CFM, | ||
209 | .ignore_suspend = 1, | ||
210 | .params = &baseband_params, | ||
211 | }, | ||
212 | { | ||
213 | .name = "Sub", | ||
214 | .stream_name = "Sub", | ||
215 | .cpu_dai_name = "wm5102-aif3", | ||
216 | .codec_dai_name = "wm9081-hifi", | ||
217 | .codec_name = "wm9081.1-006c", | ||
218 | .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | ||
219 | | SND_SOC_DAIFMT_CBS_CFS, | ||
220 | .ignore_suspend = 1, | ||
221 | .params = &sub_params, | ||
222 | }, | ||
223 | }; | ||
224 | |||
225 | static struct snd_soc_dai_link bells_dai_wm5110[] = { | ||
226 | { | ||
227 | .name = "CPU", | ||
228 | .stream_name = "CPU", | ||
229 | .cpu_dai_name = "samsung-i2s.0", | ||
230 | .codec_dai_name = "wm5110-aif1", | ||
231 | .platform_name = "samsung-audio", | ||
232 | .codec_name = "wm5110-codec", | ||
233 | .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | ||
234 | | SND_SOC_DAIFMT_CBM_CFM, | ||
235 | }, | ||
236 | { | ||
237 | .name = "Baseband", | ||
238 | .stream_name = "Baseband", | ||
239 | .cpu_dai_name = "wm5110-aif2", | ||
240 | .codec_dai_name = "wm1250-ev1", | ||
241 | .codec_name = "wm1250-ev1.1-0027", | ||
242 | .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | ||
243 | | SND_SOC_DAIFMT_CBM_CFM, | ||
244 | .ignore_suspend = 1, | ||
245 | .params = &baseband_params, | ||
246 | }, | ||
247 | { | ||
248 | .name = "Sub", | ||
249 | .stream_name = "Sub", | ||
250 | .cpu_dai_name = "wm5102-aif3", | ||
251 | .codec_dai_name = "wm9081-hifi", | ||
252 | .codec_name = "wm9081.1-006c", | ||
253 | .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | ||
254 | | SND_SOC_DAIFMT_CBS_CFS, | ||
255 | .ignore_suspend = 1, | ||
256 | .params = &sub_params, | ||
257 | }, | ||
258 | }; | ||
259 | |||
260 | static struct snd_soc_codec_conf bells_codec_conf[] = { | ||
261 | { | ||
262 | .dev_name = "wm9081.1-006c", | ||
263 | .name_prefix = "Sub", | ||
264 | }, | ||
265 | }; | ||
266 | |||
267 | static struct snd_soc_dapm_route bells_routes[] = { | ||
268 | { "Sub CLK_SYS", NULL, "OPCLK" }, | ||
269 | }; | ||
270 | |||
271 | static struct snd_soc_card bells_cards[] = { | ||
272 | { | ||
273 | .name = "Bells WM5102", | ||
274 | .owner = THIS_MODULE, | ||
275 | .dai_link = bells_dai_wm5102, | ||
276 | .num_links = ARRAY_SIZE(bells_dai_wm5102), | ||
277 | .codec_conf = bells_codec_conf, | ||
278 | .num_configs = ARRAY_SIZE(bells_codec_conf), | ||
279 | |||
280 | .late_probe = bells_late_probe, | ||
281 | |||
282 | .dapm_routes = bells_routes, | ||
283 | .num_dapm_routes = ARRAY_SIZE(bells_routes), | ||
284 | |||
285 | .set_bias_level = bells_set_bias_level, | ||
286 | .set_bias_level_post = bells_set_bias_level_post, | ||
287 | }, | ||
288 | { | ||
289 | .name = "Bells WM5110", | ||
290 | .owner = THIS_MODULE, | ||
291 | .dai_link = bells_dai_wm5110, | ||
292 | .num_links = ARRAY_SIZE(bells_dai_wm5110), | ||
293 | .codec_conf = bells_codec_conf, | ||
294 | .num_configs = ARRAY_SIZE(bells_codec_conf), | ||
295 | |||
296 | .late_probe = bells_late_probe, | ||
297 | |||
298 | .dapm_routes = bells_routes, | ||
299 | .num_dapm_routes = ARRAY_SIZE(bells_routes), | ||
300 | |||
301 | .set_bias_level = bells_set_bias_level, | ||
302 | .set_bias_level_post = bells_set_bias_level_post, | ||
303 | }, | ||
304 | }; | ||
305 | |||
306 | |||
307 | static __devinit int bells_probe(struct platform_device *pdev) | ||
308 | { | ||
309 | int ret; | ||
310 | |||
311 | bells_cards[pdev->id].dev = &pdev->dev; | ||
312 | |||
313 | ret = snd_soc_register_card(&bells_cards[pdev->id]); | ||
314 | if (ret) { | ||
315 | dev_err(&pdev->dev, | ||
316 | "snd_soc_register_card(%s) failed: %d\n", | ||
317 | bells_cards[pdev->id].name, ret); | ||
318 | return ret; | ||
319 | } | ||
320 | |||
321 | return 0; | ||
322 | } | ||
323 | |||
324 | static int __devexit bells_remove(struct platform_device *pdev) | ||
325 | { | ||
326 | snd_soc_unregister_card(&bells_cards[pdev->id]); | ||
327 | |||
328 | return 0; | ||
329 | } | ||
330 | |||
331 | static struct platform_driver bells_driver = { | ||
332 | .driver = { | ||
333 | .name = "bells", | ||
334 | .owner = THIS_MODULE, | ||
335 | .pm = &snd_soc_pm_ops, | ||
336 | }, | ||
337 | .probe = bells_probe, | ||
338 | .remove = __devexit_p(bells_remove), | ||
339 | }; | ||
340 | |||
341 | module_platform_driver(bells_driver); | ||
342 | |||
343 | MODULE_DESCRIPTION("Bells audio support"); | ||
344 | MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>"); | ||
345 | MODULE_LICENSE("GPL"); | ||
346 | MODULE_ALIAS("platform:bells"); | ||
diff --git a/sound/soc/soc-compress.c b/sound/soc/soc-compress.c new file mode 100644 index 000000000000..967d0e173e1b --- /dev/null +++ b/sound/soc/soc-compress.c | |||
@@ -0,0 +1,294 @@ | |||
1 | /* | ||
2 | * soc-compress.c -- ALSA SoC Compress | ||
3 | * | ||
4 | * Copyright (C) 2012 Intel Corp. | ||
5 | * | ||
6 | * Authors: Namarta Kohli <namartax.kohli@intel.com> | ||
7 | * Ramesh Babu K V <ramesh.babu@linux.intel.com> | ||
8 | * Vinod Koul <vinod.koul@linux.intel.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 | |||
17 | #include <linux/kernel.h> | ||
18 | #include <linux/init.h> | ||
19 | #include <linux/delay.h> | ||
20 | #include <linux/slab.h> | ||
21 | #include <linux/workqueue.h> | ||
22 | #include <sound/core.h> | ||
23 | #include <sound/compress_params.h> | ||
24 | #include <sound/compress_driver.h> | ||
25 | #include <sound/soc.h> | ||
26 | #include <sound/initval.h> | ||
27 | |||
28 | static int soc_compr_open(struct snd_compr_stream *cstream) | ||
29 | { | ||
30 | struct snd_soc_pcm_runtime *rtd = cstream->private_data; | ||
31 | struct snd_soc_platform *platform = rtd->platform; | ||
32 | struct snd_soc_dai *cpu_dai = rtd->cpu_dai; | ||
33 | struct snd_soc_dai *codec_dai = rtd->codec_dai; | ||
34 | int ret = 0; | ||
35 | |||
36 | if (platform->driver->compr_ops && platform->driver->compr_ops->open) { | ||
37 | ret = platform->driver->compr_ops->open(cstream); | ||
38 | if (ret < 0) { | ||
39 | pr_err("compress asoc: can't open platform %s\n", platform->name); | ||
40 | goto out; | ||
41 | } | ||
42 | } | ||
43 | |||
44 | if (rtd->dai_link->compr_ops && rtd->dai_link->compr_ops->startup) { | ||
45 | ret = rtd->dai_link->compr_ops->startup(cstream); | ||
46 | if (ret < 0) { | ||
47 | pr_err("compress asoc: %s startup failed\n", rtd->dai_link->name); | ||
48 | goto machine_err; | ||
49 | } | ||
50 | } | ||
51 | |||
52 | if (cstream->direction == SND_COMPRESS_PLAYBACK) { | ||
53 | cpu_dai->playback_active++; | ||
54 | codec_dai->playback_active++; | ||
55 | } else { | ||
56 | cpu_dai->capture_active++; | ||
57 | codec_dai->capture_active++; | ||
58 | } | ||
59 | |||
60 | cpu_dai->active++; | ||
61 | codec_dai->active++; | ||
62 | rtd->codec->active++; | ||
63 | |||
64 | return 0; | ||
65 | |||
66 | machine_err: | ||
67 | if (platform->driver->compr_ops && platform->driver->compr_ops->free) | ||
68 | platform->driver->compr_ops->free(cstream); | ||
69 | out: | ||
70 | return ret; | ||
71 | } | ||
72 | |||
73 | static int soc_compr_free(struct snd_compr_stream *cstream) | ||
74 | { | ||
75 | struct snd_soc_pcm_runtime *rtd = cstream->private_data; | ||
76 | struct snd_soc_platform *platform = rtd->platform; | ||
77 | struct snd_soc_dai *cpu_dai = rtd->cpu_dai; | ||
78 | struct snd_soc_dai *codec_dai = rtd->codec_dai; | ||
79 | struct snd_soc_codec *codec = rtd->codec; | ||
80 | |||
81 | if (cstream->direction == SND_COMPRESS_PLAYBACK) { | ||
82 | cpu_dai->playback_active--; | ||
83 | codec_dai->playback_active--; | ||
84 | } else { | ||
85 | cpu_dai->capture_active--; | ||
86 | codec_dai->capture_active--; | ||
87 | } | ||
88 | |||
89 | snd_soc_dai_digital_mute(codec_dai, 1); | ||
90 | |||
91 | cpu_dai->active--; | ||
92 | codec_dai->active--; | ||
93 | codec->active--; | ||
94 | |||
95 | if (!cpu_dai->active) | ||
96 | cpu_dai->rate = 0; | ||
97 | |||
98 | if (!codec_dai->active) | ||
99 | codec_dai->rate = 0; | ||
100 | |||
101 | |||
102 | if (rtd->dai_link->compr_ops && rtd->dai_link->compr_ops->shutdown) | ||
103 | rtd->dai_link->compr_ops->shutdown(cstream); | ||
104 | |||
105 | if (platform->driver->compr_ops && platform->driver->compr_ops->free) | ||
106 | platform->driver->compr_ops->free(cstream); | ||
107 | cpu_dai->runtime = NULL; | ||
108 | |||
109 | if (cstream->direction == SND_COMPRESS_PLAYBACK) { | ||
110 | if (!rtd->pmdown_time || codec->ignore_pmdown_time || | ||
111 | rtd->dai_link->ignore_pmdown_time) { | ||
112 | snd_soc_dapm_stream_event(rtd, | ||
113 | SNDRV_PCM_STREAM_PLAYBACK, | ||
114 | SND_SOC_DAPM_STREAM_STOP); | ||
115 | } else | ||
116 | codec_dai->pop_wait = 1; | ||
117 | schedule_delayed_work(&rtd->delayed_work, | ||
118 | msecs_to_jiffies(rtd->pmdown_time)); | ||
119 | } else { | ||
120 | /* capture streams can be powered down now */ | ||
121 | snd_soc_dapm_stream_event(rtd, | ||
122 | SNDRV_PCM_STREAM_CAPTURE, | ||
123 | SND_SOC_DAPM_STREAM_STOP); | ||
124 | } | ||
125 | |||
126 | return 0; | ||
127 | } | ||
128 | |||
129 | static int soc_compr_trigger(struct snd_compr_stream *cstream, int cmd) | ||
130 | { | ||
131 | |||
132 | struct snd_soc_pcm_runtime *rtd = cstream->private_data; | ||
133 | struct snd_soc_platform *platform = rtd->platform; | ||
134 | struct snd_soc_dai *codec_dai = rtd->codec_dai; | ||
135 | int ret = 0; | ||
136 | |||
137 | if (platform->driver->compr_ops && platform->driver->compr_ops->trigger) { | ||
138 | ret = platform->driver->compr_ops->trigger(cstream, cmd); | ||
139 | if (ret < 0) | ||
140 | return ret; | ||
141 | } | ||
142 | |||
143 | if (cmd == SNDRV_PCM_TRIGGER_START) | ||
144 | snd_soc_dai_digital_mute(codec_dai, 0); | ||
145 | else if (cmd == SNDRV_PCM_TRIGGER_STOP) | ||
146 | snd_soc_dai_digital_mute(codec_dai, 1); | ||
147 | |||
148 | return ret; | ||
149 | } | ||
150 | |||
151 | static int soc_compr_set_params(struct snd_compr_stream *cstream, | ||
152 | struct snd_compr_params *params) | ||
153 | { | ||
154 | struct snd_soc_pcm_runtime *rtd = cstream->private_data; | ||
155 | struct snd_soc_platform *platform = rtd->platform; | ||
156 | int ret = 0; | ||
157 | |||
158 | /* first we call set_params for the platform driver | ||
159 | * this should configure the soc side | ||
160 | * if the machine has compressed ops then we call that as well | ||
161 | * expectation is that platform and machine will configure everything | ||
162 | * for this compress path, like configuring pcm port for codec | ||
163 | */ | ||
164 | if (platform->driver->compr_ops && platform->driver->compr_ops->set_params) { | ||
165 | ret = platform->driver->compr_ops->set_params(cstream, params); | ||
166 | if (ret < 0) | ||
167 | return ret; | ||
168 | } | ||
169 | |||
170 | if (rtd->dai_link->compr_ops && rtd->dai_link->compr_ops->set_params) { | ||
171 | ret = rtd->dai_link->compr_ops->set_params(cstream); | ||
172 | if (ret < 0) | ||
173 | return ret; | ||
174 | } | ||
175 | |||
176 | snd_soc_dapm_stream_event(rtd, SNDRV_PCM_STREAM_PLAYBACK, | ||
177 | SND_SOC_DAPM_STREAM_START); | ||
178 | |||
179 | return ret; | ||
180 | } | ||
181 | |||
182 | static int soc_compr_get_params(struct snd_compr_stream *cstream, | ||
183 | struct snd_codec *params) | ||
184 | { | ||
185 | struct snd_soc_pcm_runtime *rtd = cstream->private_data; | ||
186 | struct snd_soc_platform *platform = rtd->platform; | ||
187 | int ret = 0; | ||
188 | |||
189 | if (platform->driver->compr_ops && platform->driver->compr_ops->get_params) | ||
190 | ret = platform->driver->compr_ops->get_params(cstream, params); | ||
191 | |||
192 | return ret; | ||
193 | } | ||
194 | |||
195 | static int soc_compr_get_caps(struct snd_compr_stream *cstream, | ||
196 | struct snd_compr_caps *caps) | ||
197 | { | ||
198 | struct snd_soc_pcm_runtime *rtd = cstream->private_data; | ||
199 | struct snd_soc_platform *platform = rtd->platform; | ||
200 | int ret = 0; | ||
201 | |||
202 | if (platform->driver->compr_ops && platform->driver->compr_ops->get_caps) | ||
203 | ret = platform->driver->compr_ops->get_caps(cstream, caps); | ||
204 | |||
205 | return ret; | ||
206 | } | ||
207 | |||
208 | static int soc_compr_get_codec_caps(struct snd_compr_stream *cstream, | ||
209 | struct snd_compr_codec_caps *codec) | ||
210 | { | ||
211 | struct snd_soc_pcm_runtime *rtd = cstream->private_data; | ||
212 | struct snd_soc_platform *platform = rtd->platform; | ||
213 | int ret = 0; | ||
214 | |||
215 | if (platform->driver->compr_ops && platform->driver->compr_ops->get_codec_caps) | ||
216 | ret = platform->driver->compr_ops->get_codec_caps(cstream, codec); | ||
217 | |||
218 | return ret; | ||
219 | } | ||
220 | |||
221 | static int soc_compr_ack(struct snd_compr_stream *cstream, size_t bytes) | ||
222 | { | ||
223 | struct snd_soc_pcm_runtime *rtd = cstream->private_data; | ||
224 | struct snd_soc_platform *platform = rtd->platform; | ||
225 | int ret = 0; | ||
226 | |||
227 | if (platform->driver->compr_ops && platform->driver->compr_ops->ack) | ||
228 | ret = platform->driver->compr_ops->ack(cstream, bytes); | ||
229 | |||
230 | return ret; | ||
231 | } | ||
232 | |||
233 | static int soc_compr_pointer(struct snd_compr_stream *cstream, | ||
234 | struct snd_compr_tstamp *tstamp) | ||
235 | { | ||
236 | struct snd_soc_pcm_runtime *rtd = cstream->private_data; | ||
237 | struct snd_soc_platform *platform = rtd->platform; | ||
238 | |||
239 | if (platform->driver->compr_ops && platform->driver->compr_ops->pointer) | ||
240 | platform->driver->compr_ops->pointer(cstream, tstamp); | ||
241 | |||
242 | return 0; | ||
243 | } | ||
244 | |||
245 | /* ASoC Compress operations */ | ||
246 | static struct snd_compr_ops soc_compr_ops = { | ||
247 | .open = soc_compr_open, | ||
248 | .free = soc_compr_free, | ||
249 | .set_params = soc_compr_set_params, | ||
250 | .get_params = soc_compr_get_params, | ||
251 | .trigger = soc_compr_trigger, | ||
252 | .pointer = soc_compr_pointer, | ||
253 | .ack = soc_compr_ack, | ||
254 | .get_caps = soc_compr_get_caps, | ||
255 | .get_codec_caps = soc_compr_get_codec_caps | ||
256 | }; | ||
257 | |||
258 | /* create a new compress */ | ||
259 | int soc_new_compress(struct snd_soc_pcm_runtime *rtd, int num) | ||
260 | { | ||
261 | struct snd_soc_codec *codec = rtd->codec; | ||
262 | struct snd_soc_dai *codec_dai = rtd->codec_dai; | ||
263 | struct snd_soc_dai *cpu_dai = rtd->cpu_dai; | ||
264 | struct snd_compr *compr; | ||
265 | char new_name[64]; | ||
266 | int ret = 0, direction = 0; | ||
267 | |||
268 | /* check client and interface hw capabilities */ | ||
269 | snprintf(new_name, sizeof(new_name), "%s %s-%d", | ||
270 | rtd->dai_link->stream_name, codec_dai->name, num); | ||
271 | direction = SND_COMPRESS_PLAYBACK; | ||
272 | compr = kzalloc(sizeof(*compr), GFP_KERNEL); | ||
273 | if (compr == NULL) { | ||
274 | snd_printk(KERN_ERR "Cannot allocate compr\n"); | ||
275 | return -ENOMEM; | ||
276 | } | ||
277 | |||
278 | compr->ops = &soc_compr_ops; | ||
279 | mutex_init(&compr->lock); | ||
280 | ret = snd_compress_new(rtd->card->snd_card, num, direction, compr); | ||
281 | if (ret < 0) { | ||
282 | pr_err("compress asoc: can't create compress for codec %s\n", | ||
283 | codec->name); | ||
284 | kfree(compr); | ||
285 | return ret; | ||
286 | } | ||
287 | |||
288 | rtd->compr = compr; | ||
289 | compr->private_data = rtd; | ||
290 | |||
291 | printk(KERN_INFO "compress asoc: %s <-> %s mapping ok\n", codec_dai->name, | ||
292 | cpu_dai->name); | ||
293 | return ret; | ||
294 | } | ||
diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c index f219b2f7ee68..c7a00fd8cc66 100644 --- a/sound/soc/soc-core.c +++ b/sound/soc/soc-core.c | |||
@@ -1096,7 +1096,7 @@ static int soc_probe_codec(struct snd_soc_card *card, | |||
1096 | } | 1096 | } |
1097 | 1097 | ||
1098 | /* If the driver didn't set I/O up try regmap */ | 1098 | /* If the driver didn't set I/O up try regmap */ |
1099 | if (!codec->control_data) | 1099 | if (!codec->write && dev_get_regmap(codec->dev, NULL)) |
1100 | snd_soc_codec_set_cache_io(codec, 0, 0, SND_SOC_REGMAP); | 1100 | snd_soc_codec_set_cache_io(codec, 0, 0, SND_SOC_REGMAP); |
1101 | 1101 | ||
1102 | if (driver->controls) | 1102 | if (driver->controls) |
@@ -1388,37 +1388,48 @@ static int soc_probe_link_dais(struct snd_soc_card *card, int num, int order) | |||
1388 | if (ret < 0) | 1388 | if (ret < 0) |
1389 | pr_warn("asoc: failed to add pmdown_time sysfs:%d\n", ret); | 1389 | pr_warn("asoc: failed to add pmdown_time sysfs:%d\n", ret); |
1390 | 1390 | ||
1391 | if (!dai_link->params) { | 1391 | if (cpu_dai->driver->compress_dai) { |
1392 | /* create the pcm */ | 1392 | /*create compress_device"*/ |
1393 | ret = soc_new_pcm(rtd, num); | 1393 | ret = soc_new_compress(rtd, num); |
1394 | if (ret < 0) { | 1394 | if (ret < 0) { |
1395 | pr_err("asoc: can't create pcm %s :%d\n", | 1395 | pr_err("asoc: can't create compress %s\n", |
1396 | dai_link->stream_name, ret); | 1396 | dai_link->stream_name); |
1397 | return ret; | 1397 | return ret; |
1398 | } | 1398 | } |
1399 | } else { | 1399 | } else { |
1400 | /* link the DAI widgets */ | 1400 | |
1401 | play_w = codec_dai->playback_widget; | 1401 | if (!dai_link->params) { |
1402 | capture_w = cpu_dai->capture_widget; | 1402 | /* create the pcm */ |
1403 | if (play_w && capture_w) { | 1403 | ret = soc_new_pcm(rtd, num); |
1404 | ret = snd_soc_dapm_new_pcm(card, dai_link->params, | 1404 | if (ret < 0) { |
1405 | capture_w, play_w); | 1405 | pr_err("asoc: can't create pcm %s :%d\n", |
1406 | if (ret != 0) { | 1406 | dai_link->stream_name, ret); |
1407 | dev_err(card->dev, "Can't link %s to %s: %d\n", | ||
1408 | play_w->name, capture_w->name, ret); | ||
1409 | return ret; | 1407 | return ret; |
1410 | } | 1408 | } |
1411 | } | 1409 | } else { |
1410 | /* link the DAI widgets */ | ||
1411 | play_w = codec_dai->playback_widget; | ||
1412 | capture_w = cpu_dai->capture_widget; | ||
1413 | if (play_w && capture_w) { | ||
1414 | ret = snd_soc_dapm_new_pcm(card, dai_link->params, | ||
1415 | capture_w, play_w); | ||
1416 | if (ret != 0) { | ||
1417 | dev_err(card->dev, "Can't link %s to %s: %d\n", | ||
1418 | play_w->name, capture_w->name, ret); | ||
1419 | return ret; | ||
1420 | } | ||
1421 | } | ||
1412 | 1422 | ||
1413 | play_w = cpu_dai->playback_widget; | 1423 | play_w = cpu_dai->playback_widget; |
1414 | capture_w = codec_dai->capture_widget; | 1424 | capture_w = codec_dai->capture_widget; |
1415 | if (play_w && capture_w) { | 1425 | if (play_w && capture_w) { |
1416 | ret = snd_soc_dapm_new_pcm(card, dai_link->params, | 1426 | ret = snd_soc_dapm_new_pcm(card, dai_link->params, |
1417 | capture_w, play_w); | 1427 | capture_w, play_w); |
1418 | if (ret != 0) { | 1428 | if (ret != 0) { |
1419 | dev_err(card->dev, "Can't link %s to %s: %d\n", | 1429 | dev_err(card->dev, "Can't link %s to %s: %d\n", |
1420 | play_w->name, capture_w->name, ret); | 1430 | play_w->name, capture_w->name, ret); |
1421 | return ret; | 1431 | return ret; |
1432 | } | ||
1422 | } | 1433 | } |
1423 | } | 1434 | } |
1424 | } | 1435 | } |
@@ -1814,7 +1825,6 @@ base_error: | |||
1814 | static int soc_probe(struct platform_device *pdev) | 1825 | static int soc_probe(struct platform_device *pdev) |
1815 | { | 1826 | { |
1816 | struct snd_soc_card *card = platform_get_drvdata(pdev); | 1827 | struct snd_soc_card *card = platform_get_drvdata(pdev); |
1817 | int ret = 0; | ||
1818 | 1828 | ||
1819 | /* | 1829 | /* |
1820 | * no card, so machine driver should be registering card | 1830 | * no card, so machine driver should be registering card |
@@ -1830,13 +1840,7 @@ static int soc_probe(struct platform_device *pdev) | |||
1830 | /* Bodge while we unpick instantiation */ | 1840 | /* Bodge while we unpick instantiation */ |
1831 | card->dev = &pdev->dev; | 1841 | card->dev = &pdev->dev; |
1832 | 1842 | ||
1833 | ret = snd_soc_register_card(card); | 1843 | return snd_soc_register_card(card); |
1834 | if (ret != 0) { | ||
1835 | dev_err(&pdev->dev, "Failed to register card\n"); | ||
1836 | return ret; | ||
1837 | } | ||
1838 | |||
1839 | return 0; | ||
1840 | } | 1844 | } |
1841 | 1845 | ||
1842 | static int soc_cleanup_card_resources(struct snd_soc_card *card) | 1846 | static int soc_cleanup_card_resources(struct snd_soc_card *card) |
@@ -3715,6 +3719,9 @@ int snd_soc_register_dai(struct device *dev, | |||
3715 | } | 3719 | } |
3716 | } | 3720 | } |
3717 | 3721 | ||
3722 | if (!dai->codec) | ||
3723 | dai->dapm.idle_bias_off = 1; | ||
3724 | |||
3718 | list_add(&dai->list, &dai_list); | 3725 | list_add(&dai->list, &dai_list); |
3719 | 3726 | ||
3720 | mutex_unlock(&client_mutex); | 3727 | mutex_unlock(&client_mutex); |
@@ -3803,6 +3810,9 @@ int snd_soc_register_dais(struct device *dev, | |||
3803 | } | 3810 | } |
3804 | } | 3811 | } |
3805 | 3812 | ||
3813 | if (!dai->codec) | ||
3814 | dai->dapm.idle_bias_off = 1; | ||
3815 | |||
3806 | list_add(&dai->list, &dai_list); | 3816 | list_add(&dai->list, &dai_list); |
3807 | 3817 | ||
3808 | mutex_unlock(&client_mutex); | 3818 | mutex_unlock(&client_mutex); |
diff --git a/sound/soc/soc-jack.c b/sound/soc/soc-jack.c index 7f8b3b7428bb..2ca3c734a288 100644 --- a/sound/soc/soc-jack.c +++ b/sound/soc/soc-jack.c | |||
@@ -83,11 +83,6 @@ void snd_soc_jack_report(struct snd_soc_jack *jack, int status, int mask) | |||
83 | jack->status &= ~mask; | 83 | jack->status &= ~mask; |
84 | jack->status |= status & mask; | 84 | jack->status |= status & mask; |
85 | 85 | ||
86 | /* The DAPM sync is expensive enough to be worth skipping. | ||
87 | * However, empty mask means pin synchronization is desired. */ | ||
88 | if (mask && (jack->status == oldstatus)) | ||
89 | goto out; | ||
90 | |||
91 | trace_snd_soc_jack_notify(jack, status); | 86 | trace_snd_soc_jack_notify(jack, status); |
92 | 87 | ||
93 | list_for_each_entry(pin, &jack->pins, list) { | 88 | list_for_each_entry(pin, &jack->pins, list) { |
@@ -109,7 +104,6 @@ void snd_soc_jack_report(struct snd_soc_jack *jack, int status, int mask) | |||
109 | 104 | ||
110 | snd_jack_report(jack->jack, jack->status); | 105 | snd_jack_report(jack->jack, jack->status); |
111 | 106 | ||
112 | out: | ||
113 | mutex_unlock(&jack->mutex); | 107 | mutex_unlock(&jack->mutex); |
114 | } | 108 | } |
115 | EXPORT_SYMBOL_GPL(snd_soc_jack_report); | 109 | EXPORT_SYMBOL_GPL(snd_soc_jack_report); |
diff --git a/sound/soc/tegra/tegra_alc5632.c b/sound/soc/tegra/tegra_alc5632.c index d684df294c0c..e463529b38bb 100644 --- a/sound/soc/tegra/tegra_alc5632.c +++ b/sound/soc/tegra/tegra_alc5632.c | |||
@@ -177,7 +177,7 @@ static __devinit int tegra_alc5632_probe(struct platform_device *pdev) | |||
177 | } | 177 | } |
178 | 178 | ||
179 | alc5632->gpio_hp_det = of_get_named_gpio(np, "nvidia,hp-det-gpios", 0); | 179 | alc5632->gpio_hp_det = of_get_named_gpio(np, "nvidia,hp-det-gpios", 0); |
180 | if (alc5632->gpio_hp_det == -ENODEV) | 180 | if (alc5632->gpio_hp_det == -EPROBE_DEFER) |
181 | return -EPROBE_DEFER; | 181 | return -EPROBE_DEFER; |
182 | 182 | ||
183 | ret = snd_soc_of_parse_card_name(card, "nvidia,model"); | 183 | ret = snd_soc_of_parse_card_name(card, "nvidia,model"); |
diff --git a/sound/soc/tegra/tegra_wm8903.c b/sound/soc/tegra/tegra_wm8903.c index 0c5bb33d258e..d4f14e492341 100644 --- a/sound/soc/tegra/tegra_wm8903.c +++ b/sound/soc/tegra/tegra_wm8903.c | |||
@@ -284,27 +284,27 @@ static __devinit int tegra_wm8903_driver_probe(struct platform_device *pdev) | |||
284 | } else if (np) { | 284 | } else if (np) { |
285 | pdata->gpio_spkr_en = of_get_named_gpio(np, | 285 | pdata->gpio_spkr_en = of_get_named_gpio(np, |
286 | "nvidia,spkr-en-gpios", 0); | 286 | "nvidia,spkr-en-gpios", 0); |
287 | if (pdata->gpio_spkr_en == -ENODEV) | 287 | if (pdata->gpio_spkr_en == -EPROBE_DEFER) |
288 | return -EPROBE_DEFER; | 288 | return -EPROBE_DEFER; |
289 | 289 | ||
290 | pdata->gpio_hp_mute = of_get_named_gpio(np, | 290 | pdata->gpio_hp_mute = of_get_named_gpio(np, |
291 | "nvidia,hp-mute-gpios", 0); | 291 | "nvidia,hp-mute-gpios", 0); |
292 | if (pdata->gpio_hp_mute == -ENODEV) | 292 | if (pdata->gpio_hp_mute == -EPROBE_DEFER) |
293 | return -EPROBE_DEFER; | 293 | return -EPROBE_DEFER; |
294 | 294 | ||
295 | pdata->gpio_hp_det = of_get_named_gpio(np, | 295 | pdata->gpio_hp_det = of_get_named_gpio(np, |
296 | "nvidia,hp-det-gpios", 0); | 296 | "nvidia,hp-det-gpios", 0); |
297 | if (pdata->gpio_hp_det == -ENODEV) | 297 | if (pdata->gpio_hp_det == -EPROBE_DEFER) |
298 | return -EPROBE_DEFER; | 298 | return -EPROBE_DEFER; |
299 | 299 | ||
300 | pdata->gpio_int_mic_en = of_get_named_gpio(np, | 300 | pdata->gpio_int_mic_en = of_get_named_gpio(np, |
301 | "nvidia,int-mic-en-gpios", 0); | 301 | "nvidia,int-mic-en-gpios", 0); |
302 | if (pdata->gpio_int_mic_en == -ENODEV) | 302 | if (pdata->gpio_int_mic_en == -EPROBE_DEFER) |
303 | return -EPROBE_DEFER; | 303 | return -EPROBE_DEFER; |
304 | 304 | ||
305 | pdata->gpio_ext_mic_en = of_get_named_gpio(np, | 305 | pdata->gpio_ext_mic_en = of_get_named_gpio(np, |
306 | "nvidia,ext-mic-en-gpios", 0); | 306 | "nvidia,ext-mic-en-gpios", 0); |
307 | if (pdata->gpio_ext_mic_en == -ENODEV) | 307 | if (pdata->gpio_ext_mic_en == -EPROBE_DEFER) |
308 | return -EPROBE_DEFER; | 308 | return -EPROBE_DEFER; |
309 | } | 309 | } |
310 | 310 | ||
diff --git a/sound/soc/ux500/ux500_msp_dai.c b/sound/soc/ux500/ux500_msp_dai.c index 62ac0285bfaf..772cb19d2fb3 100644 --- a/sound/soc/ux500/ux500_msp_dai.c +++ b/sound/soc/ux500/ux500_msp_dai.c | |||
@@ -21,7 +21,7 @@ | |||
21 | #include <linux/mfd/dbx500-prcmu.h> | 21 | #include <linux/mfd/dbx500-prcmu.h> |
22 | 22 | ||
23 | #include <mach/hardware.h> | 23 | #include <mach/hardware.h> |
24 | #include <mach/board-mop500-msp.h> | 24 | #include <mach/msp.h> |
25 | 25 | ||
26 | #include <sound/soc.h> | 26 | #include <sound/soc.h> |
27 | #include <sound/soc-dai.h> | 27 | #include <sound/soc-dai.h> |
@@ -760,6 +760,9 @@ static int __devinit ux500_msp_drv_probe(struct platform_device *pdev) | |||
760 | drvdata = devm_kzalloc(&pdev->dev, | 760 | drvdata = devm_kzalloc(&pdev->dev, |
761 | sizeof(struct ux500_msp_i2s_drvdata), | 761 | sizeof(struct ux500_msp_i2s_drvdata), |
762 | GFP_KERNEL); | 762 | GFP_KERNEL); |
763 | if (!drvdata) | ||
764 | return -ENOMEM; | ||
765 | |||
763 | drvdata->fmt = 0; | 766 | drvdata->fmt = 0; |
764 | drvdata->slots = 1; | 767 | drvdata->slots = 1; |
765 | drvdata->tx_mask = 0x01; | 768 | drvdata->tx_mask = 0x01; |
diff --git a/sound/soc/ux500/ux500_msp_i2s.c b/sound/soc/ux500/ux500_msp_i2s.c index ee14d2dac2f5..36be11e47ad6 100644 --- a/sound/soc/ux500/ux500_msp_i2s.c +++ b/sound/soc/ux500/ux500_msp_i2s.c | |||
@@ -19,7 +19,7 @@ | |||
19 | #include <linux/slab.h> | 19 | #include <linux/slab.h> |
20 | 20 | ||
21 | #include <mach/hardware.h> | 21 | #include <mach/hardware.h> |
22 | #include <mach/board-mop500-msp.h> | 22 | #include <mach/msp.h> |
23 | 23 | ||
24 | #include <sound/soc.h> | 24 | #include <sound/soc.h> |
25 | 25 | ||
@@ -673,6 +673,8 @@ int ux500_msp_i2s_init_msp(struct platform_device *pdev, | |||
673 | 673 | ||
674 | *msp_p = devm_kzalloc(&pdev->dev, sizeof(struct ux500_msp), GFP_KERNEL); | 674 | *msp_p = devm_kzalloc(&pdev->dev, sizeof(struct ux500_msp), GFP_KERNEL); |
675 | msp = *msp_p; | 675 | msp = *msp_p; |
676 | if (!msp) | ||
677 | return -ENOMEM; | ||
676 | 678 | ||
677 | msp->id = platform_data->id; | 679 | msp->id = platform_data->id; |
678 | msp->dev = &pdev->dev; | 680 | msp->dev = &pdev->dev; |
diff --git a/sound/soc/ux500/ux500_msp_i2s.h b/sound/soc/ux500/ux500_msp_i2s.h index 7f71b4a0d4bc..2d9136da9865 100644 --- a/sound/soc/ux500/ux500_msp_i2s.h +++ b/sound/soc/ux500/ux500_msp_i2s.h | |||
@@ -17,7 +17,7 @@ | |||
17 | 17 | ||
18 | #include <linux/platform_device.h> | 18 | #include <linux/platform_device.h> |
19 | 19 | ||
20 | #include <mach/board-mop500-msp.h> | 20 | #include <mach/msp.h> |
21 | 21 | ||
22 | #define MSP_INPUT_FREQ_APB 48000000 | 22 | #define MSP_INPUT_FREQ_APB 48000000 |
23 | 23 | ||