diff options
-rw-r--r-- | Documentation/devicetree/bindings/sound/samsung-i2s.txt | 22 | ||||
-rw-r--r-- | arch/arm/boot/dts/exynos4.dtsi | 9 | ||||
-rw-r--r-- | arch/arm/boot/dts/exynos4412-odroid-common.dtsi | 27 | ||||
-rw-r--r-- | arch/arm/boot/dts/exynos4412-odroidu3.dts | 8 | ||||
-rw-r--r-- | arch/arm/boot/dts/exynos4412-odroidx2.dts | 8 | ||||
-rw-r--r-- | include/dt-bindings/sound/samsung-i2s.h | 8 | ||||
-rw-r--r-- | sound/soc/codecs/Kconfig | 2 | ||||
-rw-r--r-- | sound/soc/codecs/rt5670.c | 1 | ||||
-rw-r--r-- | sound/soc/codecs/rt5677.c | 3 | ||||
-rw-r--r-- | sound/soc/omap/rx51.c | 8 | ||||
-rw-r--r-- | sound/soc/samsung/Kconfig | 15 | ||||
-rw-r--r-- | sound/soc/samsung/Makefile | 2 | ||||
-rw-r--r-- | sound/soc/samsung/goni_wm8994.c | 289 | ||||
-rw-r--r-- | sound/soc/samsung/i2s.c | 362 | ||||
-rw-r--r-- | sound/soc/samsung/jive_wm8750.c | 18 | ||||
-rw-r--r-- | sound/soc/samsung/odroidx2_max98090.c | 6 | ||||
-rw-r--r-- | sound/soc/samsung/smdk_wm8580.c | 5 | ||||
-rw-r--r-- | sound/soc/sh/dma-sh7760.c | 6 | ||||
-rw-r--r-- | sound/soc/sh/fsi.c | 6 | ||||
-rw-r--r-- | sound/soc/sh/siu_pcm.c | 1 |
20 files changed, 306 insertions, 500 deletions
diff --git a/Documentation/devicetree/bindings/sound/samsung-i2s.txt b/Documentation/devicetree/bindings/sound/samsung-i2s.txt index d188296bb6ec..09e0e18591ae 100644 --- a/Documentation/devicetree/bindings/sound/samsung-i2s.txt +++ b/Documentation/devicetree/bindings/sound/samsung-i2s.txt | |||
@@ -33,6 +33,25 @@ Required SoC Specific Properties: | |||
33 | "iis" is the i2s bus clock and i2s_opclk0, i2s_opclk1 are sources of the root | 33 | "iis" is the i2s bus clock and i2s_opclk0, i2s_opclk1 are sources of the root |
34 | clk. i2s0 has internal mux to select the source of root clk and i2s1 and i2s2 | 34 | clk. i2s0 has internal mux to select the source of root clk and i2s1 and i2s2 |
35 | doesn't have any such mux. | 35 | doesn't have any such mux. |
36 | - #clock-cells: should be 1, this property must be present if the I2S device | ||
37 | is a clock provider in terms of the common clock bindings, described in | ||
38 | ../clock/clock-bindings.txt. | ||
39 | - clock-output-names: from the common clock bindings, names of the CDCLK | ||
40 | I2S output clocks, suggested values are "i2s_cdclk0", "i2s_cdclk1", | ||
41 | "i2s_cdclk3" for the I2S0, I2S1, I2S2 devices recpectively. | ||
42 | |||
43 | There are following clocks available at the I2S device nodes: | ||
44 | CLK_I2S_CDCLK - the CDCLK (CODECLKO) gate clock, | ||
45 | CLK_I2S_RCLK_PSR - the RCLK prescaler divider clock (corresponding to the | ||
46 | IISPSR register), | ||
47 | CLK_I2S_RCLK_SRC - the RCLKSRC mux clock (corresponding to RCLKSRC bit in | ||
48 | IISMOD register). | ||
49 | |||
50 | Refer to the SoC datasheet for availability of the above clocks. | ||
51 | The CLK_I2S_RCLK_PSR and CLK_I2S_RCLK_SRC clocks are usually only available | ||
52 | in the IIS Multi Audio Interface (I2S0). | ||
53 | Note: Old DTs may not have the #clock-cells, clock-output-names properties | ||
54 | and then not use the I2S node as a clock supplier. | ||
36 | 55 | ||
37 | Optional SoC Specific Properties: | 56 | Optional SoC Specific Properties: |
38 | 57 | ||
@@ -41,6 +60,7 @@ Optional SoC Specific Properties: | |||
41 | - pinctrl-0: Should specify pin control groups used for this controller. | 60 | - pinctrl-0: Should specify pin control groups used for this controller. |
42 | - pinctrl-names: Should contain only one value - "default". | 61 | - pinctrl-names: Should contain only one value - "default". |
43 | 62 | ||
63 | |||
44 | Example: | 64 | Example: |
45 | 65 | ||
46 | i2s0: i2s@03830000 { | 66 | i2s0: i2s@03830000 { |
@@ -54,6 +74,8 @@ i2s0: i2s@03830000 { | |||
54 | <&clock_audss EXYNOS_I2S_BUS>, | 74 | <&clock_audss EXYNOS_I2S_BUS>, |
55 | <&clock_audss EXYNOS_SCLK_I2S>; | 75 | <&clock_audss EXYNOS_SCLK_I2S>; |
56 | clock-names = "iis", "i2s_opclk0", "i2s_opclk1"; | 76 | clock-names = "iis", "i2s_opclk0", "i2s_opclk1"; |
77 | #clock-cells; | ||
78 | clock-output-names = "i2s_cdclk0"; | ||
57 | samsung,idma-addr = <0x03000000>; | 79 | samsung,idma-addr = <0x03000000>; |
58 | pinctrl-names = "default"; | 80 | pinctrl-names = "default"; |
59 | pinctrl-0 = <&i2s0_bus>; | 81 | pinctrl-0 = <&i2s0_bus>; |
diff --git a/arch/arm/boot/dts/exynos4.dtsi b/arch/arm/boot/dts/exynos4.dtsi index 24ff27049ce0..cb6001085f1a 100644 --- a/arch/arm/boot/dts/exynos4.dtsi +++ b/arch/arm/boot/dts/exynos4.dtsi | |||
@@ -61,9 +61,12 @@ | |||
61 | reg = <0x03830000 0x100>; | 61 | reg = <0x03830000 0x100>; |
62 | clocks = <&clock_audss EXYNOS_I2S_BUS>; | 62 | clocks = <&clock_audss EXYNOS_I2S_BUS>; |
63 | clock-names = "iis"; | 63 | clock-names = "iis"; |
64 | #clock-cells = <1>; | ||
65 | clock-output-names = "i2s_cdclk0"; | ||
64 | dmas = <&pdma0 12>, <&pdma0 11>, <&pdma0 10>; | 66 | dmas = <&pdma0 12>, <&pdma0 11>, <&pdma0 10>; |
65 | dma-names = "tx", "rx", "tx-sec"; | 67 | dma-names = "tx", "rx", "tx-sec"; |
66 | samsung,idma-addr = <0x03000000>; | 68 | samsung,idma-addr = <0x03000000>; |
69 | #sound-dai-cells = <1>; | ||
67 | status = "disabled"; | 70 | status = "disabled"; |
68 | }; | 71 | }; |
69 | 72 | ||
@@ -372,8 +375,11 @@ | |||
372 | reg = <0x13960000 0x100>; | 375 | reg = <0x13960000 0x100>; |
373 | clocks = <&clock CLK_I2S1>; | 376 | clocks = <&clock CLK_I2S1>; |
374 | clock-names = "iis"; | 377 | clock-names = "iis"; |
378 | #clock-cells = <1>; | ||
379 | clock-output-names = "i2s_cdclk1"; | ||
375 | dmas = <&pdma1 12>, <&pdma1 11>; | 380 | dmas = <&pdma1 12>, <&pdma1 11>; |
376 | dma-names = "tx", "rx"; | 381 | dma-names = "tx", "rx"; |
382 | #sound-dai-cells = <1>; | ||
377 | status = "disabled"; | 383 | status = "disabled"; |
378 | }; | 384 | }; |
379 | 385 | ||
@@ -382,8 +388,11 @@ | |||
382 | reg = <0x13970000 0x100>; | 388 | reg = <0x13970000 0x100>; |
383 | clocks = <&clock CLK_I2S2>; | 389 | clocks = <&clock CLK_I2S2>; |
384 | clock-names = "iis"; | 390 | clock-names = "iis"; |
391 | #clock-cells = <1>; | ||
392 | clock-output-names = "i2s_cdclk2"; | ||
385 | dmas = <&pdma0 14>, <&pdma0 13>; | 393 | dmas = <&pdma0 14>, <&pdma0 13>; |
386 | dma-names = "tx", "rx"; | 394 | dma-names = "tx", "rx"; |
395 | #sound-dai-cells = <1>; | ||
387 | status = "disabled"; | 396 | status = "disabled"; |
388 | }; | 397 | }; |
389 | 398 | ||
diff --git a/arch/arm/boot/dts/exynos4412-odroid-common.dtsi b/arch/arm/boot/dts/exynos4412-odroid-common.dtsi index 3fbf588682b9..abd63366298a 100644 --- a/arch/arm/boot/dts/exynos4412-odroid-common.dtsi +++ b/arch/arm/boot/dts/exynos4412-odroid-common.dtsi | |||
@@ -7,6 +7,7 @@ | |||
7 | * published by the Free Software Foundation. | 7 | * published by the Free Software Foundation. |
8 | */ | 8 | */ |
9 | 9 | ||
10 | #include <dt-bindings/sound/samsung-i2s.h> | ||
10 | #include <dt-bindings/input/input.h> | 11 | #include <dt-bindings/input/input.h> |
11 | #include "exynos4412.dtsi" | 12 | #include "exynos4412.dtsi" |
12 | 13 | ||
@@ -37,14 +38,13 @@ | |||
37 | pinctrl-names = "default"; | 38 | pinctrl-names = "default"; |
38 | status = "okay"; | 39 | status = "okay"; |
39 | clocks = <&clock_audss EXYNOS_I2S_BUS>, | 40 | clocks = <&clock_audss EXYNOS_I2S_BUS>, |
40 | <&clock_audss EXYNOS_DOUT_AUD_BUS>; | 41 | <&clock_audss EXYNOS_DOUT_AUD_BUS>, |
41 | clock-names = "iis", "i2s_opclk0"; | 42 | <&clock_audss EXYNOS_SCLK_I2S>; |
43 | clock-names = "iis", "i2s_opclk0", "i2s_opclk1"; | ||
42 | }; | 44 | }; |
43 | 45 | ||
44 | sound: sound { | 46 | sound: sound { |
45 | compatible = "samsung,odroidx2-audio"; | 47 | compatible = "simple-audio-card"; |
46 | samsung,i2s-controller = <&i2s0>; | ||
47 | samsung,audio-codec = <&max98090>; | ||
48 | assigned-clocks = <&clock_audss EXYNOS_MOUT_AUDSS>, | 48 | assigned-clocks = <&clock_audss EXYNOS_MOUT_AUDSS>, |
49 | <&clock_audss EXYNOS_MOUT_I2S>, | 49 | <&clock_audss EXYNOS_MOUT_I2S>, |
50 | <&clock_audss EXYNOS_DOUT_SRP>, | 50 | <&clock_audss EXYNOS_DOUT_SRP>, |
@@ -55,6 +55,20 @@ | |||
55 | <0>, | 55 | <0>, |
56 | <192000000>, | 56 | <192000000>, |
57 | <19200000>; | 57 | <19200000>; |
58 | |||
59 | simple-audio-card,format = "i2s"; | ||
60 | simple-audio-card,bitclock-master = <&link0_codec>; | ||
61 | simple-audio-card,frame-master = <&link0_codec>; | ||
62 | |||
63 | simple-audio-card,cpu { | ||
64 | sound-dai = <&i2s0 0>; | ||
65 | system-clock-frequency = <19200000>; | ||
66 | }; | ||
67 | |||
68 | link0_codec: simple-audio-card,codec { | ||
69 | sound-dai = <&max98090>; | ||
70 | clocks = <&i2s0 CLK_I2S_CDCLK>; | ||
71 | }; | ||
58 | }; | 72 | }; |
59 | 73 | ||
60 | mmc@12550000 { | 74 | mmc@12550000 { |
@@ -373,6 +387,9 @@ | |||
373 | reg = <0x10>; | 387 | reg = <0x10>; |
374 | interrupt-parent = <&gpx0>; | 388 | interrupt-parent = <&gpx0>; |
375 | interrupts = <0 0>; | 389 | interrupts = <0 0>; |
390 | clocks = <&i2s0 CLK_I2S_CDCLK>; | ||
391 | clock-names = "mclk"; | ||
392 | #sound-dai-cells = <0>; | ||
376 | }; | 393 | }; |
377 | }; | 394 | }; |
378 | 395 | ||
diff --git a/arch/arm/boot/dts/exynos4412-odroidu3.dts b/arch/arm/boot/dts/exynos4412-odroidu3.dts index c8a64be55d07..44684e57ead1 100644 --- a/arch/arm/boot/dts/exynos4412-odroidu3.dts +++ b/arch/arm/boot/dts/exynos4412-odroidu3.dts | |||
@@ -49,9 +49,11 @@ | |||
49 | }; | 49 | }; |
50 | 50 | ||
51 | &sound { | 51 | &sound { |
52 | compatible = "samsung,odroidu3-audio"; | 52 | simple-audio-card,name = "Odroid-U3"; |
53 | samsung,model = "Odroid-U3"; | 53 | simple-audio-card,widgets = |
54 | samsung,audio-routing = | 54 | "Headphone", "Headphone Jack", |
55 | "Speakers", "Speakers"; | ||
56 | simple-audio-card,routing = | ||
55 | "Headphone Jack", "HPL", | 57 | "Headphone Jack", "HPL", |
56 | "Headphone Jack", "HPR", | 58 | "Headphone Jack", "HPR", |
57 | "Headphone Jack", "MICBIAS", | 59 | "Headphone Jack", "MICBIAS", |
diff --git a/arch/arm/boot/dts/exynos4412-odroidx2.dts b/arch/arm/boot/dts/exynos4412-odroidx2.dts index 96b43f4497cc..6e33678562ae 100644 --- a/arch/arm/boot/dts/exynos4412-odroidx2.dts +++ b/arch/arm/boot/dts/exynos4412-odroidx2.dts | |||
@@ -23,8 +23,12 @@ | |||
23 | }; | 23 | }; |
24 | 24 | ||
25 | &sound { | 25 | &sound { |
26 | samsung,model = "Odroid-X2"; | 26 | simple-audio-card,name = "Odroid-X2"; |
27 | samsung,audio-routing = | 27 | simple-audio-card,widgets = |
28 | "Headphone", "Headphone Jack", | ||
29 | "Microphone", "Mic Jack", | ||
30 | "Microphone", "DMIC"; | ||
31 | simple-audio-card,routing = | ||
28 | "Headphone Jack", "HPL", | 32 | "Headphone Jack", "HPL", |
29 | "Headphone Jack", "HPR", | 33 | "Headphone Jack", "HPR", |
30 | "IN1", "Mic Jack", | 34 | "IN1", "Mic Jack", |
diff --git a/include/dt-bindings/sound/samsung-i2s.h b/include/dt-bindings/sound/samsung-i2s.h new file mode 100644 index 000000000000..0c69818d530c --- /dev/null +++ b/include/dt-bindings/sound/samsung-i2s.h | |||
@@ -0,0 +1,8 @@ | |||
1 | #ifndef _DT_BINDINGS_SAMSUNG_I2S_H | ||
2 | #define _DT_BINDINGS_SAMSUNG_I2S_H | ||
3 | |||
4 | #define CLK_I2S_CDCLK 0 | ||
5 | #define CLK_I2S_RCLK_SRC 1 | ||
6 | #define CLK_I2S_RCLK_PSR 2 | ||
7 | |||
8 | #endif /* _DT_BINDINGS_SAMSUNG_I2S_H */ | ||
diff --git a/sound/soc/codecs/Kconfig b/sound/soc/codecs/Kconfig index 6ecac1e4428e..1471fad19cfa 100644 --- a/sound/soc/codecs/Kconfig +++ b/sound/soc/codecs/Kconfig | |||
@@ -529,7 +529,7 @@ config SND_SOC_RT5677 | |||
529 | 529 | ||
530 | config SND_SOC_RT5677_SPI | 530 | config SND_SOC_RT5677_SPI |
531 | tristate | 531 | tristate |
532 | default SND_SOC_RT5677 | 532 | default SND_SOC_RT5677 && SPI |
533 | 533 | ||
534 | #Freescale sgtl5000 codec | 534 | #Freescale sgtl5000 codec |
535 | config SND_SOC_SGTL5000 | 535 | config SND_SOC_SGTL5000 |
diff --git a/sound/soc/codecs/rt5670.c b/sound/soc/codecs/rt5670.c index 7b3d6b5992f1..e1a4a45c57e2 100644 --- a/sound/soc/codecs/rt5670.c +++ b/sound/soc/codecs/rt5670.c | |||
@@ -2616,6 +2616,7 @@ static struct snd_soc_codec_driver soc_codec_dev_rt5670 = { | |||
2616 | static const struct regmap_config rt5670_regmap = { | 2616 | static const struct regmap_config rt5670_regmap = { |
2617 | .reg_bits = 8, | 2617 | .reg_bits = 8, |
2618 | .val_bits = 16, | 2618 | .val_bits = 16, |
2619 | .use_single_rw = true, | ||
2619 | .max_register = RT5670_VENDOR_ID2 + 1 + (ARRAY_SIZE(rt5670_ranges) * | 2620 | .max_register = RT5670_VENDOR_ID2 + 1 + (ARRAY_SIZE(rt5670_ranges) * |
2620 | RT5670_PR_SPACING), | 2621 | RT5670_PR_SPACING), |
2621 | .volatile_reg = rt5670_volatile_register, | 2622 | .volatile_reg = rt5670_volatile_register, |
diff --git a/sound/soc/codecs/rt5677.c b/sound/soc/codecs/rt5677.c index 26fc538f03b1..5d0bb8748dd1 100644 --- a/sound/soc/codecs/rt5677.c +++ b/sound/soc/codecs/rt5677.c | |||
@@ -702,6 +702,9 @@ static int rt5677_set_dsp_vad(struct snd_soc_codec *codec, bool on) | |||
702 | static bool activity; | 702 | static bool activity; |
703 | int ret; | 703 | int ret; |
704 | 704 | ||
705 | if (!IS_ENABLED(CONFIG_SND_SOC_RT5677_SPI)) | ||
706 | return -ENXIO; | ||
707 | |||
705 | if (on && !activity) { | 708 | if (on && !activity) { |
706 | activity = true; | 709 | activity = true; |
707 | 710 | ||
diff --git a/sound/soc/omap/rx51.c b/sound/soc/omap/rx51.c index 04896d6252a2..7f299357c2d2 100644 --- a/sound/soc/omap/rx51.c +++ b/sound/soc/omap/rx51.c | |||
@@ -250,14 +250,14 @@ static const struct snd_soc_dapm_route audio_map[] = { | |||
250 | {"FM Transmitter", NULL, "LLOUT"}, | 250 | {"FM Transmitter", NULL, "LLOUT"}, |
251 | {"FM Transmitter", NULL, "RLOUT"}, | 251 | {"FM Transmitter", NULL, "RLOUT"}, |
252 | 252 | ||
253 | {"DMic Rate 64", NULL, "Mic Bias"}, | 253 | {"DMic Rate 64", NULL, "DMic"}, |
254 | {"Mic Bias", NULL, "DMic"}, | 254 | {"DMic", NULL, "Mic Bias"}, |
255 | 255 | ||
256 | {"b LINE2R", NULL, "MONO_LOUT"}, | 256 | {"b LINE2R", NULL, "MONO_LOUT"}, |
257 | {"Earphone", NULL, "b HPLOUT"}, | 257 | {"Earphone", NULL, "b HPLOUT"}, |
258 | 258 | ||
259 | {"LINE1L", NULL, "b Mic Bias"}, | 259 | {"LINE1L", NULL, "HS Mic"}, |
260 | {"b Mic Bias", NULL, "HS Mic"} | 260 | {"HS Mic", NULL, "b Mic Bias"}, |
261 | }; | 261 | }; |
262 | 262 | ||
263 | static const char * const spk_function[] = {"Off", "On"}; | 263 | static const char * const spk_function[] = {"Off", "On"}; |
diff --git a/sound/soc/samsung/Kconfig b/sound/soc/samsung/Kconfig index fc67f97f19f6..3cebf6ca03df 100644 --- a/sound/soc/samsung/Kconfig +++ b/sound/soc/samsung/Kconfig | |||
@@ -54,7 +54,7 @@ config SND_SOC_SAMSUNG_JIVE_WM8750 | |||
54 | config SND_SOC_SAMSUNG_SMDK_WM8580 | 54 | config SND_SOC_SAMSUNG_SMDK_WM8580 |
55 | tristate "SoC I2S Audio support for WM8580 on SMDK" | 55 | tristate "SoC I2S Audio support for WM8580 on SMDK" |
56 | depends on SND_SOC_SAMSUNG && (MACH_SMDK6410 || MACH_SMDKC100 || MACH_SMDKV210 || MACH_SMDKC110) | 56 | depends on SND_SOC_SAMSUNG && (MACH_SMDK6410 || MACH_SMDKC100 || MACH_SMDKV210 || MACH_SMDKC110) |
57 | depends on REGMAP_I2C | 57 | depends on I2C |
58 | select SND_SOC_WM8580 | 58 | select SND_SOC_WM8580 |
59 | select SND_SAMSUNG_I2S | 59 | select SND_SAMSUNG_I2S |
60 | help | 60 | help |
@@ -146,17 +146,6 @@ config SND_SOC_SMARTQ | |||
146 | select SND_SAMSUNG_I2S | 146 | select SND_SAMSUNG_I2S |
147 | select SND_SOC_WM8750 | 147 | select SND_SOC_WM8750 |
148 | 148 | ||
149 | config SND_SOC_GONI_AQUILA_WM8994 | ||
150 | tristate "SoC I2S Audio support for AQUILA/GONI - WM8994" | ||
151 | depends on SND_SOC_SAMSUNG && (MACH_GONI || MACH_AQUILA) | ||
152 | depends on I2C=y | ||
153 | select SND_SAMSUNG_I2S | ||
154 | select MFD_WM8994 | ||
155 | select SND_SOC_WM8994 | ||
156 | help | ||
157 | Say Y if you want to add support for SoC audio on goni or aquila | ||
158 | with the WM8994. | ||
159 | |||
160 | config SND_SOC_SAMSUNG_SMDK_SPDIF | 149 | config SND_SOC_SAMSUNG_SMDK_SPDIF |
161 | tristate "SoC S/PDIF Audio support for SMDK" | 150 | tristate "SoC S/PDIF Audio support for SMDK" |
162 | depends on SND_SOC_SAMSUNG | 151 | depends on SND_SOC_SAMSUNG |
@@ -167,7 +156,7 @@ config SND_SOC_SAMSUNG_SMDK_SPDIF | |||
167 | config SND_SOC_SMDK_WM8580_PCM | 156 | config SND_SOC_SMDK_WM8580_PCM |
168 | tristate "SoC PCM Audio support for WM8580 on SMDK" | 157 | tristate "SoC PCM Audio support for WM8580 on SMDK" |
169 | depends on SND_SOC_SAMSUNG && (MACH_SMDKV210 || MACH_SMDKC110) | 158 | depends on SND_SOC_SAMSUNG && (MACH_SMDKV210 || MACH_SMDKC110) |
170 | depends on REGMAP_I2C | 159 | depends on I2C |
171 | select SND_SOC_WM8580 | 160 | select SND_SOC_WM8580 |
172 | select SND_SAMSUNG_PCM | 161 | select SND_SAMSUNG_PCM |
173 | help | 162 | help |
diff --git a/sound/soc/samsung/Makefile b/sound/soc/samsung/Makefile index 31e3dba7e3b5..052fe71be518 100644 --- a/sound/soc/samsung/Makefile +++ b/sound/soc/samsung/Makefile | |||
@@ -35,7 +35,6 @@ snd-soc-smdk-wm8994-objs := smdk_wm8994.o | |||
35 | snd-soc-snow-objs := snow.o | 35 | snd-soc-snow-objs := snow.o |
36 | snd-soc-smdk-wm9713-objs := smdk_wm9713.o | 36 | snd-soc-smdk-wm9713-objs := smdk_wm9713.o |
37 | snd-soc-s3c64xx-smartq-wm8987-objs := smartq_wm8987.o | 37 | snd-soc-s3c64xx-smartq-wm8987-objs := smartq_wm8987.o |
38 | snd-soc-goni-wm8994-objs := goni_wm8994.o | ||
39 | snd-soc-smdk-spdif-objs := smdk_spdif.o | 38 | snd-soc-smdk-spdif-objs := smdk_spdif.o |
40 | snd-soc-smdk-wm8580pcm-objs := smdk_wm8580pcm.o | 39 | snd-soc-smdk-wm8580pcm-objs := smdk_wm8580pcm.o |
41 | snd-soc-smdk-wm8994pcm-objs := smdk_wm8994pcm.o | 40 | snd-soc-smdk-wm8994pcm-objs := smdk_wm8994pcm.o |
@@ -63,7 +62,6 @@ obj-$(CONFIG_SND_SOC_SNOW) += snd-soc-snow.o | |||
63 | obj-$(CONFIG_SND_SOC_SAMSUNG_SMDK_WM9713) += snd-soc-smdk-wm9713.o | 62 | obj-$(CONFIG_SND_SOC_SAMSUNG_SMDK_WM9713) += snd-soc-smdk-wm9713.o |
64 | obj-$(CONFIG_SND_SOC_SMARTQ) += snd-soc-s3c64xx-smartq-wm8987.o | 63 | obj-$(CONFIG_SND_SOC_SMARTQ) += snd-soc-s3c64xx-smartq-wm8987.o |
65 | obj-$(CONFIG_SND_SOC_SAMSUNG_SMDK_SPDIF) += snd-soc-smdk-spdif.o | 64 | obj-$(CONFIG_SND_SOC_SAMSUNG_SMDK_SPDIF) += snd-soc-smdk-spdif.o |
66 | obj-$(CONFIG_SND_SOC_GONI_AQUILA_WM8994) += snd-soc-goni-wm8994.o | ||
67 | obj-$(CONFIG_SND_SOC_SMDK_WM8580_PCM) += snd-soc-smdk-wm8580pcm.o | 65 | obj-$(CONFIG_SND_SOC_SMDK_WM8580_PCM) += snd-soc-smdk-wm8580pcm.o |
68 | obj-$(CONFIG_SND_SOC_SMDK_WM8994_PCM) += snd-soc-smdk-wm8994pcm.o | 66 | obj-$(CONFIG_SND_SOC_SMDK_WM8994_PCM) += snd-soc-smdk-wm8994pcm.o |
69 | obj-$(CONFIG_SND_SOC_SPEYSIDE) += snd-soc-speyside.o | 67 | obj-$(CONFIG_SND_SOC_SPEYSIDE) += snd-soc-speyside.o |
diff --git a/sound/soc/samsung/goni_wm8994.c b/sound/soc/samsung/goni_wm8994.c deleted file mode 100644 index fad56b9e7369..000000000000 --- a/sound/soc/samsung/goni_wm8994.c +++ /dev/null | |||
@@ -1,289 +0,0 @@ | |||
1 | /* | ||
2 | * goni_wm8994.c | ||
3 | * | ||
4 | * Copyright (C) 2010 Samsung Electronics Co.Ltd | ||
5 | * Author: Chanwoo Choi <cw00.choi@samsung.com> | ||
6 | * | ||
7 | * This program is free software; you can redistribute it and/or modify it | ||
8 | * under the terms of the GNU General Public License as published by the | ||
9 | * Free Software Foundation; either version 2 of the License, or (at your | ||
10 | * option) any later version. | ||
11 | * | ||
12 | */ | ||
13 | |||
14 | #include <linux/module.h> | ||
15 | #include <sound/soc.h> | ||
16 | #include <sound/jack.h> | ||
17 | |||
18 | #include <asm/mach-types.h> | ||
19 | #include <mach/gpio-samsung.h> | ||
20 | |||
21 | #include "../codecs/wm8994.h" | ||
22 | |||
23 | #define MACHINE_NAME 0 | ||
24 | #define CPU_VOICE_DAI 1 | ||
25 | |||
26 | static const char *aquila_str[] = { | ||
27 | [MACHINE_NAME] = "aquila", | ||
28 | [CPU_VOICE_DAI] = "aquila-voice-dai", | ||
29 | }; | ||
30 | |||
31 | static struct snd_soc_card goni; | ||
32 | static struct platform_device *goni_snd_device; | ||
33 | |||
34 | /* 3.5 pie jack */ | ||
35 | static struct snd_soc_jack jack; | ||
36 | |||
37 | /* 3.5 pie jack detection DAPM pins */ | ||
38 | static struct snd_soc_jack_pin jack_pins[] = { | ||
39 | { | ||
40 | .pin = "Headset Mic", | ||
41 | .mask = SND_JACK_MICROPHONE, | ||
42 | }, { | ||
43 | .pin = "Headset Stereophone", | ||
44 | .mask = SND_JACK_HEADPHONE | SND_JACK_MECHANICAL | | ||
45 | SND_JACK_AVOUT, | ||
46 | }, | ||
47 | }; | ||
48 | |||
49 | /* 3.5 pie jack detection gpios */ | ||
50 | static struct snd_soc_jack_gpio jack_gpios[] = { | ||
51 | { | ||
52 | .gpio = S5PV210_GPH0(6), | ||
53 | .name = "DET_3.5", | ||
54 | .report = SND_JACK_HEADSET | SND_JACK_MECHANICAL | | ||
55 | SND_JACK_AVOUT, | ||
56 | .debounce_time = 200, | ||
57 | }, | ||
58 | }; | ||
59 | |||
60 | static const struct snd_soc_dapm_widget goni_dapm_widgets[] = { | ||
61 | SND_SOC_DAPM_SPK("Ext Left Spk", NULL), | ||
62 | SND_SOC_DAPM_SPK("Ext Right Spk", NULL), | ||
63 | SND_SOC_DAPM_SPK("Ext Rcv", NULL), | ||
64 | SND_SOC_DAPM_HP("Headset Stereophone", NULL), | ||
65 | SND_SOC_DAPM_MIC("Headset Mic", NULL), | ||
66 | SND_SOC_DAPM_MIC("Main Mic", NULL), | ||
67 | SND_SOC_DAPM_MIC("2nd Mic", NULL), | ||
68 | SND_SOC_DAPM_LINE("Radio In", NULL), | ||
69 | }; | ||
70 | |||
71 | static const struct snd_soc_dapm_route goni_dapm_routes[] = { | ||
72 | {"Ext Left Spk", NULL, "SPKOUTLP"}, | ||
73 | {"Ext Left Spk", NULL, "SPKOUTLN"}, | ||
74 | |||
75 | {"Ext Right Spk", NULL, "SPKOUTRP"}, | ||
76 | {"Ext Right Spk", NULL, "SPKOUTRN"}, | ||
77 | |||
78 | {"Ext Rcv", NULL, "HPOUT2N"}, | ||
79 | {"Ext Rcv", NULL, "HPOUT2P"}, | ||
80 | |||
81 | {"Headset Stereophone", NULL, "HPOUT1L"}, | ||
82 | {"Headset Stereophone", NULL, "HPOUT1R"}, | ||
83 | |||
84 | {"IN1RN", NULL, "Headset Mic"}, | ||
85 | {"IN1RP", NULL, "Headset Mic"}, | ||
86 | |||
87 | {"IN1RN", NULL, "2nd Mic"}, | ||
88 | {"IN1RP", NULL, "2nd Mic"}, | ||
89 | |||
90 | {"IN1LN", NULL, "Main Mic"}, | ||
91 | {"IN1LP", NULL, "Main Mic"}, | ||
92 | |||
93 | {"IN2LN", NULL, "Radio In"}, | ||
94 | {"IN2RN", NULL, "Radio In"}, | ||
95 | }; | ||
96 | |||
97 | static int goni_wm8994_init(struct snd_soc_pcm_runtime *rtd) | ||
98 | { | ||
99 | struct snd_soc_codec *codec = rtd->codec; | ||
100 | struct snd_soc_dapm_context *dapm = &codec->dapm; | ||
101 | int ret; | ||
102 | |||
103 | /* set endpoints to not connected */ | ||
104 | snd_soc_dapm_nc_pin(dapm, "IN2LP:VXRN"); | ||
105 | snd_soc_dapm_nc_pin(dapm, "IN2RP:VXRP"); | ||
106 | snd_soc_dapm_nc_pin(dapm, "LINEOUT1N"); | ||
107 | snd_soc_dapm_nc_pin(dapm, "LINEOUT1P"); | ||
108 | snd_soc_dapm_nc_pin(dapm, "LINEOUT2N"); | ||
109 | snd_soc_dapm_nc_pin(dapm, "LINEOUT2P"); | ||
110 | |||
111 | if (machine_is_aquila()) { | ||
112 | snd_soc_dapm_nc_pin(dapm, "SPKOUTRN"); | ||
113 | snd_soc_dapm_nc_pin(dapm, "SPKOUTRP"); | ||
114 | } | ||
115 | |||
116 | /* Headset jack detection */ | ||
117 | ret = snd_soc_jack_new(codec, "Headset Jack", | ||
118 | SND_JACK_HEADSET | SND_JACK_MECHANICAL | SND_JACK_AVOUT, | ||
119 | &jack); | ||
120 | if (ret) | ||
121 | return ret; | ||
122 | |||
123 | ret = snd_soc_jack_add_pins(&jack, ARRAY_SIZE(jack_pins), jack_pins); | ||
124 | if (ret) | ||
125 | return ret; | ||
126 | |||
127 | ret = snd_soc_jack_add_gpios(&jack, ARRAY_SIZE(jack_gpios), jack_gpios); | ||
128 | if (ret) | ||
129 | return ret; | ||
130 | |||
131 | return 0; | ||
132 | } | ||
133 | |||
134 | static int goni_hifi_hw_params(struct snd_pcm_substream *substream, | ||
135 | struct snd_pcm_hw_params *params) | ||
136 | { | ||
137 | struct snd_soc_pcm_runtime *rtd = substream->private_data; | ||
138 | struct snd_soc_dai *codec_dai = rtd->codec_dai; | ||
139 | unsigned int pll_out = 24000000; | ||
140 | int ret = 0; | ||
141 | |||
142 | /* set the codec FLL */ | ||
143 | ret = snd_soc_dai_set_pll(codec_dai, WM8994_FLL1, 0, pll_out, | ||
144 | params_rate(params) * 256); | ||
145 | if (ret < 0) | ||
146 | return ret; | ||
147 | |||
148 | /* set the codec system clock */ | ||
149 | ret = snd_soc_dai_set_sysclk(codec_dai, WM8994_SYSCLK_FLL1, | ||
150 | params_rate(params) * 256, SND_SOC_CLOCK_IN); | ||
151 | if (ret < 0) | ||
152 | return ret; | ||
153 | |||
154 | return 0; | ||
155 | } | ||
156 | |||
157 | static struct snd_soc_ops goni_hifi_ops = { | ||
158 | .hw_params = goni_hifi_hw_params, | ||
159 | }; | ||
160 | |||
161 | static int goni_voice_hw_params(struct snd_pcm_substream *substream, | ||
162 | struct snd_pcm_hw_params *params) | ||
163 | { | ||
164 | struct snd_soc_pcm_runtime *rtd = substream->private_data; | ||
165 | struct snd_soc_dai *codec_dai = rtd->codec_dai; | ||
166 | unsigned int pll_out = 24000000; | ||
167 | int ret = 0; | ||
168 | |||
169 | if (params_rate(params) != 8000) | ||
170 | return -EINVAL; | ||
171 | |||
172 | /* set the codec FLL */ | ||
173 | ret = snd_soc_dai_set_pll(codec_dai, WM8994_FLL2, 0, pll_out, | ||
174 | params_rate(params) * 256); | ||
175 | if (ret < 0) | ||
176 | return ret; | ||
177 | |||
178 | /* set the codec system clock */ | ||
179 | ret = snd_soc_dai_set_sysclk(codec_dai, WM8994_SYSCLK_FLL2, | ||
180 | params_rate(params) * 256, SND_SOC_CLOCK_IN); | ||
181 | if (ret < 0) | ||
182 | return ret; | ||
183 | |||
184 | return 0; | ||
185 | } | ||
186 | |||
187 | static struct snd_soc_dai_driver voice_dai = { | ||
188 | .name = "goni-voice-dai", | ||
189 | .id = 0, | ||
190 | .playback = { | ||
191 | .channels_min = 1, | ||
192 | .channels_max = 2, | ||
193 | .rates = SNDRV_PCM_RATE_8000, | ||
194 | .formats = SNDRV_PCM_FMTBIT_S16_LE,}, | ||
195 | .capture = { | ||
196 | .channels_min = 1, | ||
197 | .channels_max = 2, | ||
198 | .rates = SNDRV_PCM_RATE_8000, | ||
199 | .formats = SNDRV_PCM_FMTBIT_S16_LE,}, | ||
200 | }; | ||
201 | |||
202 | static const struct snd_soc_component_driver voice_component = { | ||
203 | .name = "goni-voice", | ||
204 | }; | ||
205 | |||
206 | static struct snd_soc_ops goni_voice_ops = { | ||
207 | .hw_params = goni_voice_hw_params, | ||
208 | }; | ||
209 | |||
210 | static struct snd_soc_dai_link goni_dai[] = { | ||
211 | { | ||
212 | .name = "WM8994", | ||
213 | .stream_name = "WM8994 HiFi", | ||
214 | .cpu_dai_name = "samsung-i2s.0", | ||
215 | .codec_dai_name = "wm8994-aif1", | ||
216 | .platform_name = "samsung-i2s.0", | ||
217 | .codec_name = "wm8994-codec.0-001a", | ||
218 | .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | | ||
219 | SND_SOC_DAIFMT_CBM_CFM, | ||
220 | .init = goni_wm8994_init, | ||
221 | .ops = &goni_hifi_ops, | ||
222 | }, { | ||
223 | .name = "WM8994 Voice", | ||
224 | .stream_name = "Voice", | ||
225 | .cpu_dai_name = "goni-voice-dai", | ||
226 | .codec_dai_name = "wm8994-aif2", | ||
227 | .codec_name = "wm8994-codec.0-001a", | ||
228 | .dai_fmt = SND_SOC_DAIFMT_LEFT_J | SND_SOC_DAIFMT_IB_IF | | ||
229 | SND_SOC_DAIFMT_CBM_CFM, | ||
230 | .ops = &goni_voice_ops, | ||
231 | }, | ||
232 | }; | ||
233 | |||
234 | static struct snd_soc_card goni = { | ||
235 | .name = "goni", | ||
236 | .owner = THIS_MODULE, | ||
237 | .dai_link = goni_dai, | ||
238 | .num_links = ARRAY_SIZE(goni_dai), | ||
239 | |||
240 | .dapm_widgets = goni_dapm_widgets, | ||
241 | .num_dapm_widgets = ARRAY_SIZE(goni_dapm_widgets), | ||
242 | .dapm_routes = goni_dapm_routes, | ||
243 | .num_dapm_routes = ARRAY_SIZE(goni_dapm_routes), | ||
244 | }; | ||
245 | |||
246 | static int __init goni_init(void) | ||
247 | { | ||
248 | int ret; | ||
249 | |||
250 | if (machine_is_aquila()) { | ||
251 | voice_dai.name = aquila_str[CPU_VOICE_DAI]; | ||
252 | goni_dai[1].cpu_dai_name = aquila_str[CPU_VOICE_DAI]; | ||
253 | goni.name = aquila_str[MACHINE_NAME]; | ||
254 | } else if (!machine_is_goni()) | ||
255 | return -ENODEV; | ||
256 | |||
257 | goni_snd_device = platform_device_alloc("soc-audio", -1); | ||
258 | if (!goni_snd_device) | ||
259 | return -ENOMEM; | ||
260 | |||
261 | /* register voice DAI here */ | ||
262 | ret = devm_snd_soc_register_component(&goni_snd_device->dev, | ||
263 | &voice_component, &voice_dai, 1); | ||
264 | if (ret) { | ||
265 | platform_device_put(goni_snd_device); | ||
266 | return ret; | ||
267 | } | ||
268 | |||
269 | platform_set_drvdata(goni_snd_device, &goni); | ||
270 | ret = platform_device_add(goni_snd_device); | ||
271 | |||
272 | if (ret) | ||
273 | platform_device_put(goni_snd_device); | ||
274 | |||
275 | return ret; | ||
276 | } | ||
277 | |||
278 | static void __exit goni_exit(void) | ||
279 | { | ||
280 | platform_device_unregister(goni_snd_device); | ||
281 | } | ||
282 | |||
283 | module_init(goni_init); | ||
284 | module_exit(goni_exit); | ||
285 | |||
286 | /* Module information */ | ||
287 | MODULE_DESCRIPTION("ALSA SoC WM8994 GONI(S5PV210)"); | ||
288 | MODULE_AUTHOR("Chanwoo Choi <cw00.choi@samsung.com>"); | ||
289 | MODULE_LICENSE("GPL"); | ||
diff --git a/sound/soc/samsung/i2s.c b/sound/soc/samsung/i2s.c index b5a80c528d86..b92ab40d2be6 100644 --- a/sound/soc/samsung/i2s.c +++ b/sound/soc/samsung/i2s.c | |||
@@ -10,9 +10,11 @@ | |||
10 | * published by the Free Software Foundation. | 10 | * published by the Free Software Foundation. |
11 | */ | 11 | */ |
12 | 12 | ||
13 | #include <dt-bindings/sound/samsung-i2s.h> | ||
13 | #include <linux/delay.h> | 14 | #include <linux/delay.h> |
14 | #include <linux/slab.h> | 15 | #include <linux/slab.h> |
15 | #include <linux/clk.h> | 16 | #include <linux/clk.h> |
17 | #include <linux/clk-provider.h> | ||
16 | #include <linux/io.h> | 18 | #include <linux/io.h> |
17 | #include <linux/module.h> | 19 | #include <linux/module.h> |
18 | #include <linux/of.h> | 20 | #include <linux/of.h> |
@@ -59,10 +61,8 @@ struct samsung_i2s_dai_data { | |||
59 | struct i2s_dai { | 61 | struct i2s_dai { |
60 | /* Platform device for this DAI */ | 62 | /* Platform device for this DAI */ |
61 | struct platform_device *pdev; | 63 | struct platform_device *pdev; |
62 | /* IOREMAP'd SFRs */ | 64 | /* Memory mapped SFR region */ |
63 | void __iomem *addr; | 65 | void __iomem *addr; |
64 | /* Physical base address of SFRs */ | ||
65 | u32 base; | ||
66 | /* Rate of RCLK source clock */ | 66 | /* Rate of RCLK source clock */ |
67 | unsigned long rclk_srcrate; | 67 | unsigned long rclk_srcrate; |
68 | /* Frame Clock */ | 68 | /* Frame Clock */ |
@@ -83,8 +83,6 @@ struct i2s_dai { | |||
83 | #define DAI_OPENED (1 << 0) /* Dai is opened */ | 83 | #define DAI_OPENED (1 << 0) /* Dai is opened */ |
84 | #define DAI_MANAGER (1 << 1) /* Dai is the manager */ | 84 | #define DAI_MANAGER (1 << 1) /* Dai is the manager */ |
85 | unsigned mode; | 85 | unsigned mode; |
86 | /* CDCLK pin direction: 0 - input, 1 - output */ | ||
87 | unsigned int cdclk_out:1; | ||
88 | /* Driver for this DAI */ | 86 | /* Driver for this DAI */ |
89 | struct snd_soc_dai_driver i2s_dai_drv; | 87 | struct snd_soc_dai_driver i2s_dai_drv; |
90 | /* DMA parameters */ | 88 | /* DMA parameters */ |
@@ -95,8 +93,15 @@ struct i2s_dai { | |||
95 | u32 suspend_i2smod; | 93 | u32 suspend_i2smod; |
96 | u32 suspend_i2scon; | 94 | u32 suspend_i2scon; |
97 | u32 suspend_i2spsr; | 95 | u32 suspend_i2spsr; |
98 | unsigned long gpios[7]; /* i2s gpio line numbers */ | ||
99 | const struct samsung_i2s_variant_regs *variant_regs; | 96 | const struct samsung_i2s_variant_regs *variant_regs; |
97 | |||
98 | /* Spinlock protecting access to the device's registers */ | ||
99 | spinlock_t spinlock; | ||
100 | spinlock_t *lock; | ||
101 | |||
102 | /* Below fields are only valid if this is the primary FIFO */ | ||
103 | struct clk *clk_table[3]; | ||
104 | struct clk_onecell_data clk_data; | ||
100 | }; | 105 | }; |
101 | 106 | ||
102 | /* Lock for cross i/f checks */ | 107 | /* Lock for cross i/f checks */ |
@@ -133,10 +138,16 @@ static inline bool tx_active(struct i2s_dai *i2s) | |||
133 | return active ? true : false; | 138 | return active ? true : false; |
134 | } | 139 | } |
135 | 140 | ||
141 | /* Return pointer to the other DAI */ | ||
142 | static inline struct i2s_dai *get_other_dai(struct i2s_dai *i2s) | ||
143 | { | ||
144 | return i2s->pri_dai ? : i2s->sec_dai; | ||
145 | } | ||
146 | |||
136 | /* If the other interface of the controller is transmitting data */ | 147 | /* If the other interface of the controller is transmitting data */ |
137 | static inline bool other_tx_active(struct i2s_dai *i2s) | 148 | static inline bool other_tx_active(struct i2s_dai *i2s) |
138 | { | 149 | { |
139 | struct i2s_dai *other = i2s->pri_dai ? : i2s->sec_dai; | 150 | struct i2s_dai *other = get_other_dai(i2s); |
140 | 151 | ||
141 | return tx_active(other); | 152 | return tx_active(other); |
142 | } | 153 | } |
@@ -163,7 +174,7 @@ static inline bool rx_active(struct i2s_dai *i2s) | |||
163 | /* If the other interface of the controller is receiving data */ | 174 | /* If the other interface of the controller is receiving data */ |
164 | static inline bool other_rx_active(struct i2s_dai *i2s) | 175 | static inline bool other_rx_active(struct i2s_dai *i2s) |
165 | { | 176 | { |
166 | struct i2s_dai *other = i2s->pri_dai ? : i2s->sec_dai; | 177 | struct i2s_dai *other = get_other_dai(i2s); |
167 | 178 | ||
168 | return rx_active(other); | 179 | return rx_active(other); |
169 | } | 180 | } |
@@ -464,18 +475,23 @@ static int i2s_set_sysclk(struct snd_soc_dai *dai, | |||
464 | int clk_id, unsigned int rfs, int dir) | 475 | int clk_id, unsigned int rfs, int dir) |
465 | { | 476 | { |
466 | struct i2s_dai *i2s = to_info(dai); | 477 | struct i2s_dai *i2s = to_info(dai); |
467 | struct i2s_dai *other = i2s->pri_dai ? : i2s->sec_dai; | 478 | struct i2s_dai *other = get_other_dai(i2s); |
468 | u32 mod = readl(i2s->addr + I2SMOD); | ||
469 | const struct samsung_i2s_variant_regs *i2s_regs = i2s->variant_regs; | 479 | const struct samsung_i2s_variant_regs *i2s_regs = i2s->variant_regs; |
470 | unsigned int cdcon_mask = 1 << i2s_regs->cdclkcon_off; | 480 | unsigned int cdcon_mask = 1 << i2s_regs->cdclkcon_off; |
471 | unsigned int rsrc_mask = 1 << i2s_regs->rclksrc_off; | 481 | unsigned int rsrc_mask = 1 << i2s_regs->rclksrc_off; |
482 | u32 mod, mask, val = 0; | ||
483 | |||
484 | spin_lock(i2s->lock); | ||
485 | mod = readl(i2s->addr + I2SMOD); | ||
486 | spin_unlock(i2s->lock); | ||
472 | 487 | ||
473 | switch (clk_id) { | 488 | switch (clk_id) { |
474 | case SAMSUNG_I2S_OPCLK: | 489 | case SAMSUNG_I2S_OPCLK: |
475 | mod &= ~MOD_OPCLK_MASK; | 490 | mask = MOD_OPCLK_MASK; |
476 | mod |= dir; | 491 | val = dir; |
477 | break; | 492 | break; |
478 | case SAMSUNG_I2S_CDCLK: | 493 | case SAMSUNG_I2S_CDCLK: |
494 | mask = 1 << i2s_regs->cdclkcon_off; | ||
479 | /* Shouldn't matter in GATING(CLOCK_IN) mode */ | 495 | /* Shouldn't matter in GATING(CLOCK_IN) mode */ |
480 | if (dir == SND_SOC_CLOCK_IN) | 496 | if (dir == SND_SOC_CLOCK_IN) |
481 | rfs = 0; | 497 | rfs = 0; |
@@ -492,15 +508,15 @@ static int i2s_set_sysclk(struct snd_soc_dai *dai, | |||
492 | } | 508 | } |
493 | 509 | ||
494 | if (dir == SND_SOC_CLOCK_IN) | 510 | if (dir == SND_SOC_CLOCK_IN) |
495 | mod |= 1 << i2s_regs->cdclkcon_off; | 511 | val = 1 << i2s_regs->cdclkcon_off; |
496 | else | ||
497 | mod &= ~(1 << i2s_regs->cdclkcon_off); | ||
498 | 512 | ||
499 | i2s->rfs = rfs; | 513 | i2s->rfs = rfs; |
500 | break; | 514 | break; |
501 | 515 | ||
502 | case SAMSUNG_I2S_RCLKSRC_0: /* clock corrsponding to IISMOD[10] := 0 */ | 516 | case SAMSUNG_I2S_RCLKSRC_0: /* clock corrsponding to IISMOD[10] := 0 */ |
503 | case SAMSUNG_I2S_RCLKSRC_1: /* clock corrsponding to IISMOD[10] := 1 */ | 517 | case SAMSUNG_I2S_RCLKSRC_1: /* clock corrsponding to IISMOD[10] := 1 */ |
518 | mask = 1 << i2s_regs->rclksrc_off; | ||
519 | |||
504 | if ((i2s->quirks & QUIRK_NO_MUXPSR) | 520 | if ((i2s->quirks & QUIRK_NO_MUXPSR) |
505 | || (clk_id == SAMSUNG_I2S_RCLKSRC_0)) | 521 | || (clk_id == SAMSUNG_I2S_RCLKSRC_0)) |
506 | clk_id = 0; | 522 | clk_id = 0; |
@@ -550,18 +566,19 @@ static int i2s_set_sysclk(struct snd_soc_dai *dai, | |||
550 | return 0; | 566 | return 0; |
551 | } | 567 | } |
552 | 568 | ||
553 | if (clk_id == 0) | 569 | if (clk_id == 1) |
554 | mod &= ~(1 << i2s_regs->rclksrc_off); | 570 | val = 1 << i2s_regs->rclksrc_off; |
555 | else | ||
556 | mod |= 1 << i2s_regs->rclksrc_off; | ||
557 | |||
558 | break; | 571 | break; |
559 | default: | 572 | default: |
560 | dev_err(&i2s->pdev->dev, "We don't serve that!\n"); | 573 | dev_err(&i2s->pdev->dev, "We don't serve that!\n"); |
561 | return -EINVAL; | 574 | return -EINVAL; |
562 | } | 575 | } |
563 | 576 | ||
577 | spin_lock(i2s->lock); | ||
578 | mod = readl(i2s->addr + I2SMOD); | ||
579 | mod = (mod & ~mask) | val; | ||
564 | writel(mod, i2s->addr + I2SMOD); | 580 | writel(mod, i2s->addr + I2SMOD); |
581 | spin_unlock(i2s->lock); | ||
565 | 582 | ||
566 | return 0; | 583 | return 0; |
567 | } | 584 | } |
@@ -570,9 +587,8 @@ static int i2s_set_fmt(struct snd_soc_dai *dai, | |||
570 | unsigned int fmt) | 587 | unsigned int fmt) |
571 | { | 588 | { |
572 | struct i2s_dai *i2s = to_info(dai); | 589 | struct i2s_dai *i2s = to_info(dai); |
573 | u32 mod = readl(i2s->addr + I2SMOD); | ||
574 | int lrp_shift, sdf_shift, sdf_mask, lrp_rlow, mod_slave; | 590 | int lrp_shift, sdf_shift, sdf_mask, lrp_rlow, mod_slave; |
575 | u32 tmp = 0; | 591 | u32 mod, tmp = 0; |
576 | 592 | ||
577 | lrp_shift = i2s->variant_regs->lrp_off; | 593 | lrp_shift = i2s->variant_regs->lrp_off; |
578 | sdf_shift = i2s->variant_regs->sdf_off; | 594 | sdf_shift = i2s->variant_regs->sdf_off; |
@@ -632,12 +648,15 @@ static int i2s_set_fmt(struct snd_soc_dai *dai, | |||
632 | return -EINVAL; | 648 | return -EINVAL; |
633 | } | 649 | } |
634 | 650 | ||
651 | spin_lock(i2s->lock); | ||
652 | mod = readl(i2s->addr + I2SMOD); | ||
635 | /* | 653 | /* |
636 | * Don't change the I2S mode if any controller is active on this | 654 | * Don't change the I2S mode if any controller is active on this |
637 | * channel. | 655 | * channel. |
638 | */ | 656 | */ |
639 | if (any_active(i2s) && | 657 | if (any_active(i2s) && |
640 | ((mod & (sdf_mask | lrp_rlow | mod_slave)) != tmp)) { | 658 | ((mod & (sdf_mask | lrp_rlow | mod_slave)) != tmp)) { |
659 | spin_unlock(i2s->lock); | ||
641 | dev_err(&i2s->pdev->dev, | 660 | dev_err(&i2s->pdev->dev, |
642 | "%s:%d Other DAI busy\n", __func__, __LINE__); | 661 | "%s:%d Other DAI busy\n", __func__, __LINE__); |
643 | return -EAGAIN; | 662 | return -EAGAIN; |
@@ -646,6 +665,7 @@ static int i2s_set_fmt(struct snd_soc_dai *dai, | |||
646 | mod &= ~(sdf_mask | lrp_rlow | mod_slave); | 665 | mod &= ~(sdf_mask | lrp_rlow | mod_slave); |
647 | mod |= tmp; | 666 | mod |= tmp; |
648 | writel(mod, i2s->addr + I2SMOD); | 667 | writel(mod, i2s->addr + I2SMOD); |
668 | spin_unlock(i2s->lock); | ||
649 | 669 | ||
650 | return 0; | 670 | return 0; |
651 | } | 671 | } |
@@ -654,16 +674,16 @@ static int i2s_hw_params(struct snd_pcm_substream *substream, | |||
654 | struct snd_pcm_hw_params *params, struct snd_soc_dai *dai) | 674 | struct snd_pcm_hw_params *params, struct snd_soc_dai *dai) |
655 | { | 675 | { |
656 | struct i2s_dai *i2s = to_info(dai); | 676 | struct i2s_dai *i2s = to_info(dai); |
657 | u32 mod = readl(i2s->addr + I2SMOD); | 677 | u32 mod, mask = 0, val = 0; |
658 | 678 | ||
659 | if (!is_secondary(i2s)) | 679 | if (!is_secondary(i2s)) |
660 | mod &= ~(MOD_DC2_EN | MOD_DC1_EN); | 680 | mask |= (MOD_DC2_EN | MOD_DC1_EN); |
661 | 681 | ||
662 | switch (params_channels(params)) { | 682 | switch (params_channels(params)) { |
663 | case 6: | 683 | case 6: |
664 | mod |= MOD_DC2_EN; | 684 | val |= MOD_DC2_EN; |
665 | case 4: | 685 | case 4: |
666 | mod |= MOD_DC1_EN; | 686 | val |= MOD_DC1_EN; |
667 | break; | 687 | break; |
668 | case 2: | 688 | case 2: |
669 | if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) | 689 | if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) |
@@ -685,44 +705,49 @@ static int i2s_hw_params(struct snd_pcm_substream *substream, | |||
685 | } | 705 | } |
686 | 706 | ||
687 | if (is_secondary(i2s)) | 707 | if (is_secondary(i2s)) |
688 | mod &= ~MOD_BLCS_MASK; | 708 | mask |= MOD_BLCS_MASK; |
689 | else | 709 | else |
690 | mod &= ~MOD_BLCP_MASK; | 710 | mask |= MOD_BLCP_MASK; |
691 | 711 | ||
692 | if (is_manager(i2s)) | 712 | if (is_manager(i2s)) |
693 | mod &= ~MOD_BLC_MASK; | 713 | mask |= MOD_BLC_MASK; |
694 | 714 | ||
695 | switch (params_width(params)) { | 715 | switch (params_width(params)) { |
696 | case 8: | 716 | case 8: |
697 | if (is_secondary(i2s)) | 717 | if (is_secondary(i2s)) |
698 | mod |= MOD_BLCS_8BIT; | 718 | val |= MOD_BLCS_8BIT; |
699 | else | 719 | else |
700 | mod |= MOD_BLCP_8BIT; | 720 | val |= MOD_BLCP_8BIT; |
701 | if (is_manager(i2s)) | 721 | if (is_manager(i2s)) |
702 | mod |= MOD_BLC_8BIT; | 722 | val |= MOD_BLC_8BIT; |
703 | break; | 723 | break; |
704 | case 16: | 724 | case 16: |
705 | if (is_secondary(i2s)) | 725 | if (is_secondary(i2s)) |
706 | mod |= MOD_BLCS_16BIT; | 726 | val |= MOD_BLCS_16BIT; |
707 | else | 727 | else |
708 | mod |= MOD_BLCP_16BIT; | 728 | val |= MOD_BLCP_16BIT; |
709 | if (is_manager(i2s)) | 729 | if (is_manager(i2s)) |
710 | mod |= MOD_BLC_16BIT; | 730 | val |= MOD_BLC_16BIT; |
711 | break; | 731 | break; |
712 | case 24: | 732 | case 24: |
713 | if (is_secondary(i2s)) | 733 | if (is_secondary(i2s)) |
714 | mod |= MOD_BLCS_24BIT; | 734 | val |= MOD_BLCS_24BIT; |
715 | else | 735 | else |
716 | mod |= MOD_BLCP_24BIT; | 736 | val |= MOD_BLCP_24BIT; |
717 | if (is_manager(i2s)) | 737 | if (is_manager(i2s)) |
718 | mod |= MOD_BLC_24BIT; | 738 | val |= MOD_BLC_24BIT; |
719 | break; | 739 | break; |
720 | default: | 740 | default: |
721 | dev_err(&i2s->pdev->dev, "Format(%d) not supported\n", | 741 | dev_err(&i2s->pdev->dev, "Format(%d) not supported\n", |
722 | params_format(params)); | 742 | params_format(params)); |
723 | return -EINVAL; | 743 | return -EINVAL; |
724 | } | 744 | } |
745 | |||
746 | spin_lock(i2s->lock); | ||
747 | mod = readl(i2s->addr + I2SMOD); | ||
748 | mod = (mod & ~mask) | val; | ||
725 | writel(mod, i2s->addr + I2SMOD); | 749 | writel(mod, i2s->addr + I2SMOD); |
750 | spin_unlock(i2s->lock); | ||
726 | 751 | ||
727 | samsung_asoc_init_dma_data(dai, &i2s->dma_playback, &i2s->dma_capture); | 752 | samsung_asoc_init_dma_data(dai, &i2s->dma_playback, &i2s->dma_capture); |
728 | 753 | ||
@@ -736,7 +761,7 @@ static int i2s_startup(struct snd_pcm_substream *substream, | |||
736 | struct snd_soc_dai *dai) | 761 | struct snd_soc_dai *dai) |
737 | { | 762 | { |
738 | struct i2s_dai *i2s = to_info(dai); | 763 | struct i2s_dai *i2s = to_info(dai); |
739 | struct i2s_dai *other = i2s->pri_dai ? : i2s->sec_dai; | 764 | struct i2s_dai *other = get_other_dai(i2s); |
740 | unsigned long flags; | 765 | unsigned long flags; |
741 | 766 | ||
742 | spin_lock_irqsave(&lock, flags); | 767 | spin_lock_irqsave(&lock, flags); |
@@ -753,9 +778,6 @@ static int i2s_startup(struct snd_pcm_substream *substream, | |||
753 | 778 | ||
754 | spin_unlock_irqrestore(&lock, flags); | 779 | spin_unlock_irqrestore(&lock, flags); |
755 | 780 | ||
756 | if (!is_opened(other) && i2s->cdclk_out) | ||
757 | i2s_set_sysclk(dai, SAMSUNG_I2S_CDCLK, | ||
758 | 0, SND_SOC_CLOCK_OUT); | ||
759 | return 0; | 781 | return 0; |
760 | } | 782 | } |
761 | 783 | ||
@@ -763,38 +785,27 @@ static void i2s_shutdown(struct snd_pcm_substream *substream, | |||
763 | struct snd_soc_dai *dai) | 785 | struct snd_soc_dai *dai) |
764 | { | 786 | { |
765 | struct i2s_dai *i2s = to_info(dai); | 787 | struct i2s_dai *i2s = to_info(dai); |
766 | struct i2s_dai *other = i2s->pri_dai ? : i2s->sec_dai; | 788 | struct i2s_dai *other = get_other_dai(i2s); |
767 | unsigned long flags; | 789 | unsigned long flags; |
768 | const struct samsung_i2s_variant_regs *i2s_regs = i2s->variant_regs; | ||
769 | 790 | ||
770 | spin_lock_irqsave(&lock, flags); | 791 | spin_lock_irqsave(&lock, flags); |
771 | 792 | ||
772 | i2s->mode &= ~DAI_OPENED; | 793 | i2s->mode &= ~DAI_OPENED; |
773 | i2s->mode &= ~DAI_MANAGER; | 794 | i2s->mode &= ~DAI_MANAGER; |
774 | 795 | ||
775 | if (is_opened(other)) { | 796 | if (is_opened(other)) |
776 | other->mode |= DAI_MANAGER; | 797 | other->mode |= DAI_MANAGER; |
777 | } else { | 798 | |
778 | u32 mod = readl(i2s->addr + I2SMOD); | ||
779 | i2s->cdclk_out = !(mod & (1 << i2s_regs->cdclkcon_off)); | ||
780 | if (other) | ||
781 | other->cdclk_out = i2s->cdclk_out; | ||
782 | } | ||
783 | /* Reset any constraint on RFS and BFS */ | 799 | /* Reset any constraint on RFS and BFS */ |
784 | i2s->rfs = 0; | 800 | i2s->rfs = 0; |
785 | i2s->bfs = 0; | 801 | i2s->bfs = 0; |
786 | 802 | ||
787 | spin_unlock_irqrestore(&lock, flags); | 803 | spin_unlock_irqrestore(&lock, flags); |
788 | |||
789 | /* Gate CDCLK by default */ | ||
790 | if (!is_opened(other)) | ||
791 | i2s_set_sysclk(dai, SAMSUNG_I2S_CDCLK, | ||
792 | 0, SND_SOC_CLOCK_IN); | ||
793 | } | 804 | } |
794 | 805 | ||
795 | static int config_setup(struct i2s_dai *i2s) | 806 | static int config_setup(struct i2s_dai *i2s) |
796 | { | 807 | { |
797 | struct i2s_dai *other = i2s->pri_dai ? : i2s->sec_dai; | 808 | struct i2s_dai *other = get_other_dai(i2s); |
798 | unsigned rfs, bfs, blc; | 809 | unsigned rfs, bfs, blc; |
799 | u32 psr; | 810 | u32 psr; |
800 | 811 | ||
@@ -864,10 +875,10 @@ static int i2s_trigger(struct snd_pcm_substream *substream, | |||
864 | case SNDRV_PCM_TRIGGER_START: | 875 | case SNDRV_PCM_TRIGGER_START: |
865 | case SNDRV_PCM_TRIGGER_RESUME: | 876 | case SNDRV_PCM_TRIGGER_RESUME: |
866 | case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: | 877 | case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: |
867 | local_irq_save(flags); | 878 | spin_lock_irqsave(i2s->lock, flags); |
868 | 879 | ||
869 | if (config_setup(i2s)) { | 880 | if (config_setup(i2s)) { |
870 | local_irq_restore(flags); | 881 | spin_unlock_irqrestore(i2s->lock, flags); |
871 | return -EINVAL; | 882 | return -EINVAL; |
872 | } | 883 | } |
873 | 884 | ||
@@ -876,12 +887,12 @@ static int i2s_trigger(struct snd_pcm_substream *substream, | |||
876 | else | 887 | else |
877 | i2s_txctrl(i2s, 1); | 888 | i2s_txctrl(i2s, 1); |
878 | 889 | ||
879 | local_irq_restore(flags); | 890 | spin_unlock_irqrestore(i2s->lock, flags); |
880 | break; | 891 | break; |
881 | case SNDRV_PCM_TRIGGER_STOP: | 892 | case SNDRV_PCM_TRIGGER_STOP: |
882 | case SNDRV_PCM_TRIGGER_SUSPEND: | 893 | case SNDRV_PCM_TRIGGER_SUSPEND: |
883 | case SNDRV_PCM_TRIGGER_PAUSE_PUSH: | 894 | case SNDRV_PCM_TRIGGER_PAUSE_PUSH: |
884 | local_irq_save(flags); | 895 | spin_lock_irqsave(i2s->lock, flags); |
885 | 896 | ||
886 | if (capture) { | 897 | if (capture) { |
887 | i2s_rxctrl(i2s, 0); | 898 | i2s_rxctrl(i2s, 0); |
@@ -891,7 +902,7 @@ static int i2s_trigger(struct snd_pcm_substream *substream, | |||
891 | i2s_fifo(i2s, FIC_TXFLUSH); | 902 | i2s_fifo(i2s, FIC_TXFLUSH); |
892 | } | 903 | } |
893 | 904 | ||
894 | local_irq_restore(flags); | 905 | spin_unlock_irqrestore(i2s->lock, flags); |
895 | break; | 906 | break; |
896 | } | 907 | } |
897 | 908 | ||
@@ -902,7 +913,7 @@ static int i2s_set_clkdiv(struct snd_soc_dai *dai, | |||
902 | int div_id, int div) | 913 | int div_id, int div) |
903 | { | 914 | { |
904 | struct i2s_dai *i2s = to_info(dai); | 915 | struct i2s_dai *i2s = to_info(dai); |
905 | struct i2s_dai *other = i2s->pri_dai ? : i2s->sec_dai; | 916 | struct i2s_dai *other = get_other_dai(i2s); |
906 | 917 | ||
907 | switch (div_id) { | 918 | switch (div_id) { |
908 | case SAMSUNG_I2S_DIV_BCLK: | 919 | case SAMSUNG_I2S_DIV_BCLK: |
@@ -971,58 +982,36 @@ static int i2s_resume(struct snd_soc_dai *dai) | |||
971 | static int samsung_i2s_dai_probe(struct snd_soc_dai *dai) | 982 | static int samsung_i2s_dai_probe(struct snd_soc_dai *dai) |
972 | { | 983 | { |
973 | struct i2s_dai *i2s = to_info(dai); | 984 | struct i2s_dai *i2s = to_info(dai); |
974 | struct i2s_dai *other = i2s->pri_dai ? : i2s->sec_dai; | 985 | struct i2s_dai *other = get_other_dai(i2s); |
975 | int ret; | 986 | unsigned long flags; |
976 | 987 | ||
977 | if (other && other->clk) { /* If this is probe on secondary */ | 988 | if (is_secondary(i2s)) { /* If this is probe on the secondary DAI */ |
978 | samsung_asoc_init_dma_data(dai, &other->sec_dai->dma_playback, | 989 | samsung_asoc_init_dma_data(dai, &other->sec_dai->dma_playback, |
979 | NULL); | 990 | NULL); |
980 | goto probe_exit; | 991 | } else { |
981 | } | 992 | samsung_asoc_init_dma_data(dai, &i2s->dma_playback, |
982 | 993 | &i2s->dma_capture); | |
983 | i2s->addr = ioremap(i2s->base, 0x100); | ||
984 | if (i2s->addr == NULL) { | ||
985 | dev_err(&i2s->pdev->dev, "cannot ioremap registers\n"); | ||
986 | return -ENXIO; | ||
987 | } | ||
988 | |||
989 | i2s->clk = clk_get(&i2s->pdev->dev, "iis"); | ||
990 | if (IS_ERR(i2s->clk)) { | ||
991 | dev_err(&i2s->pdev->dev, "failed to get i2s_clock\n"); | ||
992 | iounmap(i2s->addr); | ||
993 | return PTR_ERR(i2s->clk); | ||
994 | } | ||
995 | |||
996 | ret = clk_prepare_enable(i2s->clk); | ||
997 | if (ret != 0) { | ||
998 | dev_err(&i2s->pdev->dev, "failed to enable clock: %d\n", ret); | ||
999 | return ret; | ||
1000 | } | ||
1001 | |||
1002 | samsung_asoc_init_dma_data(dai, &i2s->dma_playback, &i2s->dma_capture); | ||
1003 | |||
1004 | if (other) { | ||
1005 | other->addr = i2s->addr; | ||
1006 | other->clk = i2s->clk; | ||
1007 | } | ||
1008 | 994 | ||
1009 | if (i2s->quirks & QUIRK_NEED_RSTCLR) | 995 | if (i2s->quirks & QUIRK_NEED_RSTCLR) |
1010 | writel(CON_RSTCLR, i2s->addr + I2SCON); | 996 | writel(CON_RSTCLR, i2s->addr + I2SCON); |
1011 | 997 | ||
1012 | if (i2s->quirks & QUIRK_SUPPORTS_IDMA) | 998 | if (i2s->quirks & QUIRK_SUPPORTS_IDMA) |
1013 | idma_reg_addr_init(i2s->addr, | 999 | idma_reg_addr_init(i2s->addr, |
1014 | i2s->sec_dai->idma_playback.dma_addr); | 1000 | i2s->sec_dai->idma_playback.dma_addr); |
1001 | } | ||
1015 | 1002 | ||
1016 | probe_exit: | ||
1017 | /* Reset any constraint on RFS and BFS */ | 1003 | /* Reset any constraint on RFS and BFS */ |
1018 | i2s->rfs = 0; | 1004 | i2s->rfs = 0; |
1019 | i2s->bfs = 0; | 1005 | i2s->bfs = 0; |
1020 | i2s->rclk_srcrate = 0; | 1006 | i2s->rclk_srcrate = 0; |
1007 | |||
1008 | spin_lock_irqsave(i2s->lock, flags); | ||
1021 | i2s_txctrl(i2s, 0); | 1009 | i2s_txctrl(i2s, 0); |
1022 | i2s_rxctrl(i2s, 0); | 1010 | i2s_rxctrl(i2s, 0); |
1023 | i2s_fifo(i2s, FIC_TXFLUSH); | 1011 | i2s_fifo(i2s, FIC_TXFLUSH); |
1024 | i2s_fifo(other, FIC_TXFLUSH); | 1012 | i2s_fifo(other, FIC_TXFLUSH); |
1025 | i2s_fifo(i2s, FIC_RXFLUSH); | 1013 | i2s_fifo(i2s, FIC_RXFLUSH); |
1014 | spin_unlock_irqrestore(i2s->lock, flags); | ||
1026 | 1015 | ||
1027 | /* Gate CDCLK by default */ | 1016 | /* Gate CDCLK by default */ |
1028 | if (!is_opened(other)) | 1017 | if (!is_opened(other)) |
@@ -1035,21 +1024,15 @@ probe_exit: | |||
1035 | static int samsung_i2s_dai_remove(struct snd_soc_dai *dai) | 1024 | static int samsung_i2s_dai_remove(struct snd_soc_dai *dai) |
1036 | { | 1025 | { |
1037 | struct i2s_dai *i2s = snd_soc_dai_get_drvdata(dai); | 1026 | struct i2s_dai *i2s = snd_soc_dai_get_drvdata(dai); |
1038 | struct i2s_dai *other = i2s->pri_dai ? : i2s->sec_dai; | ||
1039 | |||
1040 | if (!other || !other->clk) { | ||
1041 | 1027 | ||
1042 | if (i2s->quirks & QUIRK_NEED_RSTCLR) | 1028 | if (!is_secondary(i2s)) { |
1029 | if (i2s->quirks & QUIRK_NEED_RSTCLR) { | ||
1030 | spin_lock(i2s->lock); | ||
1043 | writel(0, i2s->addr + I2SCON); | 1031 | writel(0, i2s->addr + I2SCON); |
1044 | 1032 | spin_unlock(i2s->lock); | |
1045 | clk_disable_unprepare(i2s->clk); | 1033 | } |
1046 | clk_put(i2s->clk); | ||
1047 | |||
1048 | iounmap(i2s->addr); | ||
1049 | } | 1034 | } |
1050 | 1035 | ||
1051 | i2s->clk = NULL; | ||
1052 | |||
1053 | return 0; | 1036 | return 0; |
1054 | } | 1037 | } |
1055 | 1038 | ||
@@ -1124,15 +1107,14 @@ static const struct of_device_id exynos_i2s_match[]; | |||
1124 | static inline const struct samsung_i2s_dai_data *samsung_i2s_get_driver_data( | 1107 | static inline const struct samsung_i2s_dai_data *samsung_i2s_get_driver_data( |
1125 | struct platform_device *pdev) | 1108 | struct platform_device *pdev) |
1126 | { | 1109 | { |
1127 | #ifdef CONFIG_OF | 1110 | if (IS_ENABLED(CONFIG_OF) && pdev->dev.of_node) { |
1128 | if (pdev->dev.of_node) { | ||
1129 | const struct of_device_id *match; | 1111 | const struct of_device_id *match; |
1130 | match = of_match_node(exynos_i2s_match, pdev->dev.of_node); | 1112 | match = of_match_node(exynos_i2s_match, pdev->dev.of_node); |
1131 | return match->data; | 1113 | return match ? match->data : NULL; |
1132 | } else | 1114 | } else { |
1133 | #endif | ||
1134 | return (struct samsung_i2s_dai_data *) | 1115 | return (struct samsung_i2s_dai_data *) |
1135 | platform_get_device_id(pdev)->driver_data; | 1116 | platform_get_device_id(pdev)->driver_data; |
1117 | } | ||
1136 | } | 1118 | } |
1137 | 1119 | ||
1138 | #ifdef CONFIG_PM | 1120 | #ifdef CONFIG_PM |
@@ -1155,6 +1137,87 @@ static int i2s_runtime_resume(struct device *dev) | |||
1155 | } | 1137 | } |
1156 | #endif /* CONFIG_PM */ | 1138 | #endif /* CONFIG_PM */ |
1157 | 1139 | ||
1140 | static void i2s_unregister_clocks(struct i2s_dai *i2s) | ||
1141 | { | ||
1142 | int i; | ||
1143 | |||
1144 | for (i = 0; i < i2s->clk_data.clk_num; i++) { | ||
1145 | if (!IS_ERR(i2s->clk_table[i])) | ||
1146 | clk_unregister(i2s->clk_table[i]); | ||
1147 | } | ||
1148 | } | ||
1149 | |||
1150 | static void i2s_unregister_clock_provider(struct platform_device *pdev) | ||
1151 | { | ||
1152 | struct i2s_dai *i2s = dev_get_drvdata(&pdev->dev); | ||
1153 | |||
1154 | of_clk_del_provider(pdev->dev.of_node); | ||
1155 | i2s_unregister_clocks(i2s); | ||
1156 | } | ||
1157 | |||
1158 | static int i2s_register_clock_provider(struct platform_device *pdev) | ||
1159 | { | ||
1160 | struct device *dev = &pdev->dev; | ||
1161 | struct i2s_dai *i2s = dev_get_drvdata(dev); | ||
1162 | const char *clk_name[2] = { "i2s_opclk0", "i2s_opclk1" }; | ||
1163 | const char *p_names[2] = { NULL }; | ||
1164 | const struct samsung_i2s_variant_regs *reg_info = i2s->variant_regs; | ||
1165 | struct clk *rclksrc; | ||
1166 | int ret, i; | ||
1167 | |||
1168 | /* Register the clock provider only if it's expected in the DTB */ | ||
1169 | if (!of_find_property(dev->of_node, "#clock-cells", NULL)) | ||
1170 | return 0; | ||
1171 | |||
1172 | /* Get the RCLKSRC mux clock parent clock names */ | ||
1173 | for (i = 0; i < ARRAY_SIZE(p_names); i++) { | ||
1174 | rclksrc = clk_get(dev, clk_name[i]); | ||
1175 | if (IS_ERR(rclksrc)) | ||
1176 | continue; | ||
1177 | p_names[i] = __clk_get_name(rclksrc); | ||
1178 | clk_put(rclksrc); | ||
1179 | } | ||
1180 | |||
1181 | if (!(i2s->quirks & QUIRK_NO_MUXPSR)) { | ||
1182 | /* Activate the prescaler */ | ||
1183 | u32 val = readl(i2s->addr + I2SPSR); | ||
1184 | writel(val | PSR_PSREN, i2s->addr + I2SPSR); | ||
1185 | |||
1186 | i2s->clk_table[CLK_I2S_RCLK_SRC] = clk_register_mux(NULL, | ||
1187 | "i2s_rclksrc", p_names, ARRAY_SIZE(p_names), | ||
1188 | CLK_SET_RATE_NO_REPARENT | CLK_SET_RATE_PARENT, | ||
1189 | i2s->addr + I2SMOD, reg_info->rclksrc_off, | ||
1190 | 1, 0, i2s->lock); | ||
1191 | |||
1192 | i2s->clk_table[CLK_I2S_RCLK_PSR] = clk_register_divider(NULL, | ||
1193 | "i2s_presc", "i2s_rclksrc", | ||
1194 | CLK_SET_RATE_PARENT, | ||
1195 | i2s->addr + I2SPSR, 8, 6, 0, i2s->lock); | ||
1196 | |||
1197 | p_names[0] = "i2s_presc"; | ||
1198 | i2s->clk_data.clk_num = 2; | ||
1199 | } | ||
1200 | of_property_read_string_index(dev->of_node, | ||
1201 | "clock-output-names", 0, &clk_name[0]); | ||
1202 | |||
1203 | i2s->clk_table[CLK_I2S_CDCLK] = clk_register_gate(NULL, clk_name[0], | ||
1204 | p_names[0], CLK_SET_RATE_PARENT, | ||
1205 | i2s->addr + I2SMOD, reg_info->cdclkcon_off, | ||
1206 | CLK_GATE_SET_TO_DISABLE, i2s->lock); | ||
1207 | |||
1208 | i2s->clk_data.clk_num += 1; | ||
1209 | i2s->clk_data.clks = i2s->clk_table; | ||
1210 | |||
1211 | ret = of_clk_add_provider(dev->of_node, of_clk_src_onecell_get, | ||
1212 | &i2s->clk_data); | ||
1213 | if (ret < 0) { | ||
1214 | dev_err(dev, "failed to add clock provider: %d\n", ret); | ||
1215 | i2s_unregister_clocks(i2s); | ||
1216 | } | ||
1217 | |||
1218 | return ret; | ||
1219 | } | ||
1220 | |||
1158 | static int samsung_i2s_probe(struct platform_device *pdev) | 1221 | static int samsung_i2s_probe(struct platform_device *pdev) |
1159 | { | 1222 | { |
1160 | struct i2s_dai *pri_dai, *sec_dai = NULL; | 1223 | struct i2s_dai *pri_dai, *sec_dai = NULL; |
@@ -1164,7 +1227,7 @@ static int samsung_i2s_probe(struct platform_device *pdev) | |||
1164 | u32 regs_base, quirks = 0, idma_addr = 0; | 1227 | u32 regs_base, quirks = 0, idma_addr = 0; |
1165 | struct device_node *np = pdev->dev.of_node; | 1228 | struct device_node *np = pdev->dev.of_node; |
1166 | const struct samsung_i2s_dai_data *i2s_dai_data; | 1229 | const struct samsung_i2s_dai_data *i2s_dai_data; |
1167 | int ret = 0; | 1230 | int ret; |
1168 | 1231 | ||
1169 | /* Call during Seconday interface registration */ | 1232 | /* Call during Seconday interface registration */ |
1170 | i2s_dai_data = samsung_i2s_get_driver_data(pdev); | 1233 | i2s_dai_data = samsung_i2s_get_driver_data(pdev); |
@@ -1175,11 +1238,13 @@ static int samsung_i2s_probe(struct platform_device *pdev) | |||
1175 | dev_err(&pdev->dev, "Unable to get drvdata\n"); | 1238 | dev_err(&pdev->dev, "Unable to get drvdata\n"); |
1176 | return -EFAULT; | 1239 | return -EFAULT; |
1177 | } | 1240 | } |
1178 | devm_snd_soc_register_component(&sec_dai->pdev->dev, | 1241 | ret = devm_snd_soc_register_component(&sec_dai->pdev->dev, |
1179 | &samsung_i2s_component, | 1242 | &samsung_i2s_component, |
1180 | &sec_dai->i2s_dai_drv, 1); | 1243 | &sec_dai->i2s_dai_drv, 1); |
1181 | samsung_asoc_dma_platform_register(&pdev->dev); | 1244 | if (ret != 0) |
1182 | return 0; | 1245 | return ret; |
1246 | |||
1247 | return samsung_asoc_dma_platform_register(&pdev->dev); | ||
1183 | } | 1248 | } |
1184 | 1249 | ||
1185 | pri_dai = i2s_alloc_dai(pdev, false); | 1250 | pri_dai = i2s_alloc_dai(pdev, false); |
@@ -1188,6 +1253,9 @@ static int samsung_i2s_probe(struct platform_device *pdev) | |||
1188 | return -ENOMEM; | 1253 | return -ENOMEM; |
1189 | } | 1254 | } |
1190 | 1255 | ||
1256 | spin_lock_init(&pri_dai->spinlock); | ||
1257 | pri_dai->lock = &pri_dai->spinlock; | ||
1258 | |||
1191 | if (!np) { | 1259 | if (!np) { |
1192 | res = platform_get_resource(pdev, IORESOURCE_DMA, 0); | 1260 | res = platform_get_resource(pdev, IORESOURCE_DMA, 0); |
1193 | if (!res) { | 1261 | if (!res) { |
@@ -1229,25 +1297,29 @@ static int samsung_i2s_probe(struct platform_device *pdev) | |||
1229 | } | 1297 | } |
1230 | 1298 | ||
1231 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 1299 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
1232 | if (!res) { | 1300 | pri_dai->addr = devm_ioremap_resource(&pdev->dev, res); |
1233 | dev_err(&pdev->dev, "Unable to get I2S SFR address\n"); | 1301 | if (IS_ERR(pri_dai->addr)) |
1234 | return -ENXIO; | 1302 | return PTR_ERR(pri_dai->addr); |
1235 | } | ||
1236 | 1303 | ||
1237 | if (!request_mem_region(res->start, resource_size(res), | ||
1238 | "samsung-i2s")) { | ||
1239 | dev_err(&pdev->dev, "Unable to request SFR region\n"); | ||
1240 | return -EBUSY; | ||
1241 | } | ||
1242 | regs_base = res->start; | 1304 | regs_base = res->start; |
1243 | 1305 | ||
1306 | pri_dai->clk = devm_clk_get(&pdev->dev, "iis"); | ||
1307 | if (IS_ERR(pri_dai->clk)) { | ||
1308 | dev_err(&pdev->dev, "Failed to get iis clock\n"); | ||
1309 | return PTR_ERR(pri_dai->clk); | ||
1310 | } | ||
1311 | |||
1312 | ret = clk_prepare_enable(pri_dai->clk); | ||
1313 | if (ret != 0) { | ||
1314 | dev_err(&pdev->dev, "failed to enable clock: %d\n", ret); | ||
1315 | return ret; | ||
1316 | } | ||
1244 | pri_dai->dma_playback.dma_addr = regs_base + I2STXD; | 1317 | pri_dai->dma_playback.dma_addr = regs_base + I2STXD; |
1245 | pri_dai->dma_capture.dma_addr = regs_base + I2SRXD; | 1318 | pri_dai->dma_capture.dma_addr = regs_base + I2SRXD; |
1246 | pri_dai->dma_playback.ch_name = "tx"; | 1319 | pri_dai->dma_playback.ch_name = "tx"; |
1247 | pri_dai->dma_capture.ch_name = "rx"; | 1320 | pri_dai->dma_capture.ch_name = "rx"; |
1248 | pri_dai->dma_playback.dma_size = 4; | 1321 | pri_dai->dma_playback.dma_size = 4; |
1249 | pri_dai->dma_capture.dma_size = 4; | 1322 | pri_dai->dma_capture.dma_size = 4; |
1250 | pri_dai->base = regs_base; | ||
1251 | pri_dai->quirks = quirks; | 1323 | pri_dai->quirks = quirks; |
1252 | pri_dai->variant_regs = i2s_dai_data->i2s_variant_regs; | 1324 | pri_dai->variant_regs = i2s_dai_data->i2s_variant_regs; |
1253 | 1325 | ||
@@ -1258,10 +1330,10 @@ static int samsung_i2s_probe(struct platform_device *pdev) | |||
1258 | sec_dai = i2s_alloc_dai(pdev, true); | 1330 | sec_dai = i2s_alloc_dai(pdev, true); |
1259 | if (!sec_dai) { | 1331 | if (!sec_dai) { |
1260 | dev_err(&pdev->dev, "Unable to alloc I2S_sec\n"); | 1332 | dev_err(&pdev->dev, "Unable to alloc I2S_sec\n"); |
1261 | ret = -ENOMEM; | 1333 | return -ENOMEM; |
1262 | goto err; | ||
1263 | } | 1334 | } |
1264 | 1335 | ||
1336 | sec_dai->lock = &pri_dai->spinlock; | ||
1265 | sec_dai->variant_regs = pri_dai->variant_regs; | 1337 | sec_dai->variant_regs = pri_dai->variant_regs; |
1266 | sec_dai->dma_playback.dma_addr = regs_base + I2STXDS; | 1338 | sec_dai->dma_playback.dma_addr = regs_base + I2STXDS; |
1267 | sec_dai->dma_playback.ch_name = "tx-sec"; | 1339 | sec_dai->dma_playback.ch_name = "tx-sec"; |
@@ -1273,7 +1345,8 @@ static int samsung_i2s_probe(struct platform_device *pdev) | |||
1273 | } | 1345 | } |
1274 | 1346 | ||
1275 | sec_dai->dma_playback.dma_size = 4; | 1347 | sec_dai->dma_playback.dma_size = 4; |
1276 | sec_dai->base = regs_base; | 1348 | sec_dai->addr = pri_dai->addr; |
1349 | sec_dai->clk = pri_dai->clk; | ||
1277 | sec_dai->quirks = quirks; | 1350 | sec_dai->quirks = quirks; |
1278 | sec_dai->idma_playback.dma_addr = idma_addr; | 1351 | sec_dai->idma_playback.dma_addr = idma_addr; |
1279 | sec_dai->pri_dai = pri_dai; | 1352 | sec_dai->pri_dai = pri_dai; |
@@ -1282,8 +1355,7 @@ static int samsung_i2s_probe(struct platform_device *pdev) | |||
1282 | 1355 | ||
1283 | if (i2s_pdata && i2s_pdata->cfg_gpio && i2s_pdata->cfg_gpio(pdev)) { | 1356 | if (i2s_pdata && i2s_pdata->cfg_gpio && i2s_pdata->cfg_gpio(pdev)) { |
1284 | dev_err(&pdev->dev, "Unable to configure gpio\n"); | 1357 | dev_err(&pdev->dev, "Unable to configure gpio\n"); |
1285 | ret = -EINVAL; | 1358 | return -EINVAL; |
1286 | goto err; | ||
1287 | } | 1359 | } |
1288 | 1360 | ||
1289 | devm_snd_soc_register_component(&pri_dai->pdev->dev, | 1361 | devm_snd_soc_register_component(&pri_dai->pdev->dev, |
@@ -1292,32 +1364,30 @@ static int samsung_i2s_probe(struct platform_device *pdev) | |||
1292 | 1364 | ||
1293 | pm_runtime_enable(&pdev->dev); | 1365 | pm_runtime_enable(&pdev->dev); |
1294 | 1366 | ||
1295 | samsung_asoc_dma_platform_register(&pdev->dev); | 1367 | ret = samsung_asoc_dma_platform_register(&pdev->dev); |
1296 | 1368 | if (ret != 0) | |
1297 | return 0; | 1369 | return ret; |
1298 | err: | ||
1299 | if (res) | ||
1300 | release_mem_region(regs_base, resource_size(res)); | ||
1301 | 1370 | ||
1302 | return ret; | 1371 | return i2s_register_clock_provider(pdev); |
1303 | } | 1372 | } |
1304 | 1373 | ||
1305 | static int samsung_i2s_remove(struct platform_device *pdev) | 1374 | static int samsung_i2s_remove(struct platform_device *pdev) |
1306 | { | 1375 | { |
1307 | struct i2s_dai *i2s, *other; | 1376 | struct i2s_dai *i2s, *other; |
1308 | struct resource *res; | ||
1309 | 1377 | ||
1310 | i2s = dev_get_drvdata(&pdev->dev); | 1378 | i2s = dev_get_drvdata(&pdev->dev); |
1311 | other = i2s->pri_dai ? : i2s->sec_dai; | 1379 | other = get_other_dai(i2s); |
1312 | 1380 | ||
1313 | if (other) { | 1381 | if (other) { |
1314 | other->pri_dai = NULL; | 1382 | other->pri_dai = NULL; |
1315 | other->sec_dai = NULL; | 1383 | other->sec_dai = NULL; |
1316 | } else { | 1384 | } else { |
1317 | pm_runtime_disable(&pdev->dev); | 1385 | pm_runtime_disable(&pdev->dev); |
1318 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 1386 | } |
1319 | if (res) | 1387 | |
1320 | release_mem_region(res->start, resource_size(res)); | 1388 | if (!is_secondary(i2s)) { |
1389 | i2s_unregister_clock_provider(pdev); | ||
1390 | clk_disable_unprepare(i2s->clk); | ||
1321 | } | 1391 | } |
1322 | 1392 | ||
1323 | i2s->pri_dai = NULL; | 1393 | i2s->pri_dai = NULL; |
diff --git a/sound/soc/samsung/jive_wm8750.c b/sound/soc/samsung/jive_wm8750.c index 6c3b359bb4c1..7fcb51faa2a0 100644 --- a/sound/soc/samsung/jive_wm8750.c +++ b/sound/soc/samsung/jive_wm8750.c | |||
@@ -83,22 +83,6 @@ static struct snd_soc_ops jive_ops = { | |||
83 | .hw_params = jive_hw_params, | 83 | .hw_params = jive_hw_params, |
84 | }; | 84 | }; |
85 | 85 | ||
86 | static int jive_wm8750_init(struct snd_soc_pcm_runtime *rtd) | ||
87 | { | ||
88 | struct snd_soc_codec *codec = rtd->codec; | ||
89 | struct snd_soc_dapm_context *dapm = &codec->dapm; | ||
90 | |||
91 | /* These endpoints are not being used. */ | ||
92 | snd_soc_dapm_nc_pin(dapm, "LINPUT2"); | ||
93 | snd_soc_dapm_nc_pin(dapm, "RINPUT2"); | ||
94 | snd_soc_dapm_nc_pin(dapm, "LINPUT3"); | ||
95 | snd_soc_dapm_nc_pin(dapm, "RINPUT3"); | ||
96 | snd_soc_dapm_nc_pin(dapm, "OUT3"); | ||
97 | snd_soc_dapm_nc_pin(dapm, "MONO"); | ||
98 | |||
99 | return 0; | ||
100 | } | ||
101 | |||
102 | static struct snd_soc_dai_link jive_dai = { | 86 | static struct snd_soc_dai_link jive_dai = { |
103 | .name = "wm8750", | 87 | .name = "wm8750", |
104 | .stream_name = "WM8750", | 88 | .stream_name = "WM8750", |
@@ -106,7 +90,6 @@ static struct snd_soc_dai_link jive_dai = { | |||
106 | .codec_dai_name = "wm8750-hifi", | 90 | .codec_dai_name = "wm8750-hifi", |
107 | .platform_name = "s3c2412-i2s", | 91 | .platform_name = "s3c2412-i2s", |
108 | .codec_name = "wm8750.0-001a", | 92 | .codec_name = "wm8750.0-001a", |
109 | .init = jive_wm8750_init, | ||
110 | .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | | 93 | .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | |
111 | SND_SOC_DAIFMT_CBS_CFS, | 94 | SND_SOC_DAIFMT_CBS_CFS, |
112 | .ops = &jive_ops, | 95 | .ops = &jive_ops, |
@@ -123,6 +106,7 @@ static struct snd_soc_card snd_soc_machine_jive = { | |||
123 | .num_dapm_widgets = ARRAY_SIZE(wm8750_dapm_widgets), | 106 | .num_dapm_widgets = ARRAY_SIZE(wm8750_dapm_widgets), |
124 | .dapm_routes = audio_map, | 107 | .dapm_routes = audio_map, |
125 | .num_dapm_routes = ARRAY_SIZE(audio_map), | 108 | .num_dapm_routes = ARRAY_SIZE(audio_map), |
109 | .fully_routed = true, | ||
126 | }; | 110 | }; |
127 | 111 | ||
128 | static struct platform_device *jive_snd_device; | 112 | static struct platform_device *jive_snd_device; |
diff --git a/sound/soc/samsung/odroidx2_max98090.c b/sound/soc/samsung/odroidx2_max98090.c index fa4f1d2f69bf..596f1180a369 100644 --- a/sound/soc/samsung/odroidx2_max98090.c +++ b/sound/soc/samsung/odroidx2_max98090.c | |||
@@ -21,6 +21,8 @@ struct odroidx2_drv_data { | |||
21 | /* The I2S CDCLK output clock frequency for the MAX98090 codec */ | 21 | /* The I2S CDCLK output clock frequency for the MAX98090 codec */ |
22 | #define MAX98090_MCLK 19200000 | 22 | #define MAX98090_MCLK 19200000 |
23 | 23 | ||
24 | static struct snd_soc_dai_link odroidx2_dai[]; | ||
25 | |||
24 | static int odroidx2_late_probe(struct snd_soc_card *card) | 26 | static int odroidx2_late_probe(struct snd_soc_card *card) |
25 | { | 27 | { |
26 | struct snd_soc_dai *codec_dai = card->rtd[0].codec_dai; | 28 | struct snd_soc_dai *codec_dai = card->rtd[0].codec_dai; |
@@ -29,7 +31,9 @@ static int odroidx2_late_probe(struct snd_soc_card *card) | |||
29 | 31 | ||
30 | ret = snd_soc_dai_set_sysclk(codec_dai, 0, MAX98090_MCLK, | 32 | ret = snd_soc_dai_set_sysclk(codec_dai, 0, MAX98090_MCLK, |
31 | SND_SOC_CLOCK_IN); | 33 | SND_SOC_CLOCK_IN); |
32 | if (ret < 0) | 34 | |
35 | if (ret < 0 || of_find_property(odroidx2_dai[0].codec_of_node, | ||
36 | "clocks", NULL)) | ||
33 | return ret; | 37 | return ret; |
34 | 38 | ||
35 | /* Set the cpu DAI configuration in order to use CDCLK */ | 39 | /* Set the cpu DAI configuration in order to use CDCLK */ |
diff --git a/sound/soc/samsung/smdk_wm8580.c b/sound/soc/samsung/smdk_wm8580.c index 17a2f717ec02..548bfd993788 100644 --- a/sound/soc/samsung/smdk_wm8580.c +++ b/sound/soc/samsung/smdk_wm8580.c | |||
@@ -136,13 +136,10 @@ static const struct snd_soc_dapm_route smdk_wm8580_audio_map[] = { | |||
136 | 136 | ||
137 | static int smdk_wm8580_init_paiftx(struct snd_soc_pcm_runtime *rtd) | 137 | static int smdk_wm8580_init_paiftx(struct snd_soc_pcm_runtime *rtd) |
138 | { | 138 | { |
139 | struct snd_soc_codec *codec = rtd->codec; | ||
140 | struct snd_soc_dapm_context *dapm = &codec->dapm; | ||
141 | |||
142 | /* Enabling the microphone requires the fitting of a 0R | 139 | /* Enabling the microphone requires the fitting of a 0R |
143 | * resistor to connect the line from the microphone jack. | 140 | * resistor to connect the line from the microphone jack. |
144 | */ | 141 | */ |
145 | snd_soc_dapm_disable_pin(dapm, "MicIn"); | 142 | snd_soc_dapm_disable_pin(&rtd->card->dapm, "MicIn"); |
146 | 143 | ||
147 | return 0; | 144 | return 0; |
148 | } | 145 | } |
diff --git a/sound/soc/sh/dma-sh7760.c b/sound/soc/sh/dma-sh7760.c index a5b2c4ea90d9..fd11404a3bc7 100644 --- a/sound/soc/sh/dma-sh7760.c +++ b/sound/soc/sh/dma-sh7760.c | |||
@@ -305,11 +305,6 @@ static struct snd_pcm_ops camelot_pcm_ops = { | |||
305 | .pointer = camelot_pos, | 305 | .pointer = camelot_pos, |
306 | }; | 306 | }; |
307 | 307 | ||
308 | static void camelot_pcm_free(struct snd_pcm *pcm) | ||
309 | { | ||
310 | snd_pcm_lib_preallocate_free_for_all(pcm); | ||
311 | } | ||
312 | |||
313 | static int camelot_pcm_new(struct snd_soc_pcm_runtime *rtd) | 308 | static int camelot_pcm_new(struct snd_soc_pcm_runtime *rtd) |
314 | { | 309 | { |
315 | struct snd_pcm *pcm = rtd->pcm; | 310 | struct snd_pcm *pcm = rtd->pcm; |
@@ -328,7 +323,6 @@ static int camelot_pcm_new(struct snd_soc_pcm_runtime *rtd) | |||
328 | static struct snd_soc_platform_driver sh7760_soc_platform = { | 323 | static struct snd_soc_platform_driver sh7760_soc_platform = { |
329 | .ops = &camelot_pcm_ops, | 324 | .ops = &camelot_pcm_ops, |
330 | .pcm_new = camelot_pcm_new, | 325 | .pcm_new = camelot_pcm_new, |
331 | .pcm_free = camelot_pcm_free, | ||
332 | }; | 326 | }; |
333 | 327 | ||
334 | static int sh7760_soc_platform_probe(struct platform_device *pdev) | 328 | static int sh7760_soc_platform_probe(struct platform_device *pdev) |
diff --git a/sound/soc/sh/fsi.c b/sound/soc/sh/fsi.c index d49f25f9efd3..b87b22e88e43 100644 --- a/sound/soc/sh/fsi.c +++ b/sound/soc/sh/fsi.c | |||
@@ -1762,11 +1762,6 @@ static struct snd_pcm_ops fsi_pcm_ops = { | |||
1762 | #define PREALLOC_BUFFER (32 * 1024) | 1762 | #define PREALLOC_BUFFER (32 * 1024) |
1763 | #define PREALLOC_BUFFER_MAX (32 * 1024) | 1763 | #define PREALLOC_BUFFER_MAX (32 * 1024) |
1764 | 1764 | ||
1765 | static void fsi_pcm_free(struct snd_pcm *pcm) | ||
1766 | { | ||
1767 | snd_pcm_lib_preallocate_free_for_all(pcm); | ||
1768 | } | ||
1769 | |||
1770 | static int fsi_pcm_new(struct snd_soc_pcm_runtime *rtd) | 1765 | static int fsi_pcm_new(struct snd_soc_pcm_runtime *rtd) |
1771 | { | 1766 | { |
1772 | return snd_pcm_lib_preallocate_pages_for_all( | 1767 | return snd_pcm_lib_preallocate_pages_for_all( |
@@ -1818,7 +1813,6 @@ static struct snd_soc_dai_driver fsi_soc_dai[] = { | |||
1818 | static struct snd_soc_platform_driver fsi_soc_platform = { | 1813 | static struct snd_soc_platform_driver fsi_soc_platform = { |
1819 | .ops = &fsi_pcm_ops, | 1814 | .ops = &fsi_pcm_ops, |
1820 | .pcm_new = fsi_pcm_new, | 1815 | .pcm_new = fsi_pcm_new, |
1821 | .pcm_free = fsi_pcm_free, | ||
1822 | }; | 1816 | }; |
1823 | 1817 | ||
1824 | static const struct snd_soc_component_driver fsi_soc_component = { | 1818 | static const struct snd_soc_component_driver fsi_soc_component = { |
diff --git a/sound/soc/sh/siu_pcm.c b/sound/soc/sh/siu_pcm.c index 32eb6da2d2bd..82902f56e82f 100644 --- a/sound/soc/sh/siu_pcm.c +++ b/sound/soc/sh/siu_pcm.c | |||
@@ -589,7 +589,6 @@ static void siu_pcm_free(struct snd_pcm *pcm) | |||
589 | tasklet_kill(&port_info->playback.tasklet); | 589 | tasklet_kill(&port_info->playback.tasklet); |
590 | 590 | ||
591 | siu_free_port(port_info); | 591 | siu_free_port(port_info); |
592 | snd_pcm_lib_preallocate_free_for_all(pcm); | ||
593 | 592 | ||
594 | dev_dbg(pcm->card->dev, "%s\n", __func__); | 593 | dev_dbg(pcm->card->dev, "%s\n", __func__); |
595 | } | 594 | } |