diff options
408 files changed, 16518 insertions, 3986 deletions
diff --git a/Documentation/devicetree/bindings/sound/nau8810.txt b/Documentation/devicetree/bindings/sound/nau8810.txt new file mode 100644 index 000000000000..05830e477acd --- /dev/null +++ b/Documentation/devicetree/bindings/sound/nau8810.txt | |||
@@ -0,0 +1,16 @@ | |||
1 | NAU8810 audio CODEC | ||
2 | |||
3 | This device supports I2C only. | ||
4 | |||
5 | Required properties: | ||
6 | |||
7 | - compatible : "nuvoton,nau8810" | ||
8 | |||
9 | - reg : the I2C address of the device. | ||
10 | |||
11 | Example: | ||
12 | |||
13 | codec: nau8810@1a { | ||
14 | compatible = "nuvoton,nau8810"; | ||
15 | reg = <0x1a>; | ||
16 | }; | ||
diff --git a/Documentation/devicetree/bindings/sound/nvidia,tegra-audio-sgtl5000.txt b/Documentation/devicetree/bindings/sound/nvidia,tegra-audio-sgtl5000.txt new file mode 100644 index 000000000000..5da7da4ea07a --- /dev/null +++ b/Documentation/devicetree/bindings/sound/nvidia,tegra-audio-sgtl5000.txt | |||
@@ -0,0 +1,42 @@ | |||
1 | NVIDIA Tegra audio complex, with SGTL5000 CODEC | ||
2 | |||
3 | Required properties: | ||
4 | - compatible : "nvidia,tegra-audio-sgtl5000" | ||
5 | - clocks : Must contain an entry for each entry in clock-names. | ||
6 | See ../clocks/clock-bindings.txt for details. | ||
7 | - clock-names : Must include the following entries: | ||
8 | - pll_a | ||
9 | - pll_a_out0 | ||
10 | - mclk (The Tegra cdev1/extern1 clock, which feeds the CODEC's mclk) | ||
11 | - nvidia,model : The user-visible name of this sound complex. | ||
12 | - nvidia,audio-routing : A list of the connections between audio components. | ||
13 | Each entry is a pair of strings, the first being the connection's sink, | ||
14 | the second being the connection's source. Valid names for sources and | ||
15 | sinks are the SGTL5000's pins (as documented in its binding), and the jacks | ||
16 | on the board: | ||
17 | |||
18 | * Headphone Jack | ||
19 | * Line In Jack | ||
20 | * Mic Jack | ||
21 | |||
22 | - nvidia,i2s-controller : The phandle of the Tegra I2S controller that's | ||
23 | connected to the CODEC. | ||
24 | - nvidia,audio-codec : The phandle of the SGTL5000 audio codec. | ||
25 | |||
26 | Example: | ||
27 | |||
28 | sound { | ||
29 | compatible = "toradex,tegra-audio-sgtl5000-apalis_t30", | ||
30 | "nvidia,tegra-audio-sgtl5000"; | ||
31 | nvidia,model = "Toradex Apalis T30"; | ||
32 | nvidia,audio-routing = | ||
33 | "Headphone Jack", "HP_OUT", | ||
34 | "LINE_IN", "Line In Jack", | ||
35 | "MIC_IN", "Mic Jack"; | ||
36 | nvidia,i2s-controller = <&tegra_i2s2>; | ||
37 | nvidia,audio-codec = <&sgtl5000>; | ||
38 | clocks = <&tegra_car TEGRA30_CLK_PLL_A>, | ||
39 | <&tegra_car TEGRA30_CLK_PLL_A_OUT0>, | ||
40 | <&tegra_car TEGRA30_CLK_EXTERN1>; | ||
41 | clock-names = "pll_a", "pll_a_out0", "mclk"; | ||
42 | }; | ||
diff --git a/Documentation/devicetree/bindings/sound/qcom,apq8016-sbc.txt b/Documentation/devicetree/bindings/sound/qcom,apq8016-sbc.txt index 48129368d4d9..d9d8635ff94c 100644 --- a/Documentation/devicetree/bindings/sound/qcom,apq8016-sbc.txt +++ b/Documentation/devicetree/bindings/sound/qcom,apq8016-sbc.txt | |||
@@ -16,6 +16,24 @@ Required properties: | |||
16 | * "spkr-iomux" | 16 | * "spkr-iomux" |
17 | - qcom,model : Name of the sound card. | 17 | - qcom,model : Name of the sound card. |
18 | 18 | ||
19 | - qcom,audio-routing : A list of the connections between audio components. | ||
20 | Each entry is a pair of strings, the first being the | ||
21 | connection's sink, the second being the connection's | ||
22 | source. Valid names could be power supplies, MicBias | ||
23 | of msm8x16_wcd codec and the jacks on the board: | ||
24 | |||
25 | Power supplies: | ||
26 | * MIC BIAS External1 | ||
27 | * MIC BIAS External2 | ||
28 | * MIC BIAS Internal1 | ||
29 | * MIC BIAS Internal2 | ||
30 | |||
31 | Board connectors: | ||
32 | * Headset Mic | ||
33 | * Secondary Mic", | ||
34 | * DMIC | ||
35 | * Ext Spk | ||
36 | |||
19 | Dai-link subnode properties and subnodes: | 37 | Dai-link subnode properties and subnodes: |
20 | 38 | ||
21 | Required dai-link subnodes: | 39 | Required dai-link subnodes: |
@@ -37,6 +55,18 @@ sound: sound { | |||
37 | reg-names = "mic-iomux", "spkr-iomux"; | 55 | reg-names = "mic-iomux", "spkr-iomux"; |
38 | qcom,model = "DB410c"; | 56 | qcom,model = "DB410c"; |
39 | 57 | ||
58 | qcom,audio-routing = | ||
59 | "MIC BIAS External1", "Handset Mic", | ||
60 | "MIC BIAS Internal2", "Headset Mic", | ||
61 | "MIC BIAS External1", "Secondary Mic", | ||
62 | "AMIC1", "MIC BIAS External1", | ||
63 | "AMIC2", "MIC BIAS Internal2", | ||
64 | "AMIC3", "MIC BIAS External1", | ||
65 | "DMIC1", "MIC BIAS Internal1", | ||
66 | "MIC BIAS Internal1", "Digital Mic1", | ||
67 | "DMIC2", "MIC BIAS Internal1", | ||
68 | "MIC BIAS Internal1", "Digital Mic2"; | ||
69 | |||
40 | /* I2S - Internal codec */ | 70 | /* I2S - Internal codec */ |
41 | internal-dai-link@0 { | 71 | internal-dai-link@0 { |
42 | cpu { /* PRIMARY */ | 72 | cpu { /* PRIMARY */ |
diff --git a/Documentation/devicetree/bindings/sound/renesas,rsrc-card.txt b/Documentation/devicetree/bindings/sound/renesas,rsrc-card.txt deleted file mode 100644 index 255ece3043ad..000000000000 --- a/Documentation/devicetree/bindings/sound/renesas,rsrc-card.txt +++ /dev/null | |||
@@ -1,75 +0,0 @@ | |||
1 | Renesas Sampling Rate Convert Sound Card: | ||
2 | |||
3 | Renesas Sampling Rate Convert Sound Card specifies audio DAI connections of SoC <-> codec. | ||
4 | |||
5 | Required properties: | ||
6 | |||
7 | - compatible : "renesas,rsrc-card{,<board>}" | ||
8 | Examples with boards are: | ||
9 | - "renesas,rsrc-card" | ||
10 | - "renesas,rsrc-card,lager" | ||
11 | - "renesas,rsrc-card,koelsch" | ||
12 | Optional properties: | ||
13 | |||
14 | - card_name : User specified audio sound card name, one string | ||
15 | property. | ||
16 | - cpu : CPU sub-node | ||
17 | - codec : CODEC sub-node | ||
18 | |||
19 | Optional subnode properties: | ||
20 | |||
21 | - format : CPU/CODEC common audio format. | ||
22 | "i2s", "right_j", "left_j" , "dsp_a" | ||
23 | "dsp_b", "ac97", "pdm", "msb", "lsb" | ||
24 | - frame-master : Indicates dai-link frame master. | ||
25 | phandle to a cpu or codec subnode. | ||
26 | - bitclock-master : Indicates dai-link bit clock master. | ||
27 | phandle to a cpu or codec subnode. | ||
28 | - bitclock-inversion : bool property. Add this if the | ||
29 | dai-link uses bit clock inversion. | ||
30 | - frame-inversion : bool property. Add this if the | ||
31 | dai-link uses frame clock inversion. | ||
32 | - convert-rate : platform specified sampling rate convert | ||
33 | - convert-channels : platform specified converted channel size (2 - 8 ch) | ||
34 | - audio-prefix : see audio-routing | ||
35 | - audio-routing : A list of the connections between audio components. | ||
36 | Each entry is a pair of strings, the first being the connection's sink, | ||
37 | the second being the connection's source. Valid names for sources. | ||
38 | use audio-prefix if some components is using same sink/sources naming. | ||
39 | it can be used if compatible was "renesas,rsrc-card"; | ||
40 | |||
41 | Required CPU/CODEC subnodes properties: | ||
42 | |||
43 | - sound-dai : phandle and port of CPU/CODEC | ||
44 | |||
45 | Optional CPU/CODEC subnodes properties: | ||
46 | |||
47 | - clocks / system-clock-frequency : specify subnode's clock if needed. | ||
48 | it can be specified via "clocks" if system has | ||
49 | clock node (= common clock), or "system-clock-frequency" | ||
50 | (if system doens't support common clock) | ||
51 | If a clock is specified, it is | ||
52 | enabled with clk_prepare_enable() | ||
53 | in dai startup() and disabled with | ||
54 | clk_disable_unprepare() in dai | ||
55 | shutdown(). | ||
56 | |||
57 | Example | ||
58 | |||
59 | sound { | ||
60 | compatible = "renesas,rsrc-card,lager"; | ||
61 | |||
62 | card-name = "rsnd-ak4643"; | ||
63 | format = "left_j"; | ||
64 | bitclock-master = <&sndcodec>; | ||
65 | frame-master = <&sndcodec>; | ||
66 | |||
67 | sndcpu: cpu { | ||
68 | sound-dai = <&rcar_sound>; | ||
69 | }; | ||
70 | |||
71 | sndcodec: codec { | ||
72 | sound-dai = <&ak4643>; | ||
73 | system-clock-frequency = <11289600>; | ||
74 | }; | ||
75 | }; | ||
diff --git a/Documentation/devicetree/bindings/sound/rockchip,rk3399-gru-sound.txt b/Documentation/devicetree/bindings/sound/rockchip,rk3399-gru-sound.txt new file mode 100644 index 000000000000..eac91db07178 --- /dev/null +++ b/Documentation/devicetree/bindings/sound/rockchip,rk3399-gru-sound.txt | |||
@@ -0,0 +1,22 @@ | |||
1 | ROCKCHIP with MAX98357A/RT5514/DA7219 codecs on GRU boards | ||
2 | |||
3 | Required properties: | ||
4 | - compatible: "rockchip,rk3399-gru-sound" | ||
5 | - rockchip,cpu: The phandle of the Rockchip I2S controller that's | ||
6 | connected to the codecs | ||
7 | - rockchip,codec: The phandle of the MAX98357A/RT5514/DA7219 codecs | ||
8 | |||
9 | Optional properties: | ||
10 | - dmic-wakeup-delay-ms : specify delay time (ms) for DMIC ready. | ||
11 | If this option is specified, which means it's required dmic need | ||
12 | delay for DMIC to ready so that rt5514 can avoid recording before | ||
13 | DMIC send valid data | ||
14 | |||
15 | Example: | ||
16 | |||
17 | sound { | ||
18 | compatible = "rockchip,rk3399-gru-sound"; | ||
19 | rockchip,cpu = <&i2s0>; | ||
20 | rockchip,codec = <&max98357a &rt5514 &da7219>; | ||
21 | dmic-wakeup-delay-ms = <20>; | ||
22 | }; | ||
diff --git a/Documentation/devicetree/bindings/sound/rt5659.txt b/Documentation/devicetree/bindings/sound/rt5659.txt index 5f79e7fde032..1766e0543fc5 100644 --- a/Documentation/devicetree/bindings/sound/rt5659.txt +++ b/Documentation/devicetree/bindings/sound/rt5659.txt | |||
@@ -12,6 +12,9 @@ Required properties: | |||
12 | 12 | ||
13 | Optional properties: | 13 | Optional properties: |
14 | 14 | ||
15 | - clocks: The phandle of the master clock to the CODEC | ||
16 | - clock-names: Should be "mclk" | ||
17 | |||
15 | - realtek,in1-differential | 18 | - realtek,in1-differential |
16 | - realtek,in3-differential | 19 | - realtek,in3-differential |
17 | - realtek,in4-differential | 20 | - realtek,in4-differential |
diff --git a/Documentation/devicetree/bindings/sound/rt5660.txt b/Documentation/devicetree/bindings/sound/rt5660.txt new file mode 100644 index 000000000000..30be5f921930 --- /dev/null +++ b/Documentation/devicetree/bindings/sound/rt5660.txt | |||
@@ -0,0 +1,47 @@ | |||
1 | RT5660 audio CODEC | ||
2 | |||
3 | This device supports I2C only. | ||
4 | |||
5 | Required properties: | ||
6 | |||
7 | - compatible : "realtek,rt5660". | ||
8 | |||
9 | - reg : The I2C address of the device. | ||
10 | |||
11 | Optional properties: | ||
12 | |||
13 | - clocks: The phandle of the master clock to the CODEC | ||
14 | - clock-names: Should be "mclk" | ||
15 | |||
16 | - realtek,in1-differential | ||
17 | - realtek,in3-differential | ||
18 | Boolean. Indicate MIC1/3 input are differential, rather than single-ended. | ||
19 | |||
20 | - realtek,poweroff-in-suspend | ||
21 | Boolean. If the codec will be powered off in suspend, the resume should be | ||
22 | added delay time for waiting codec power ready. | ||
23 | |||
24 | - realtek,dmic1-data-pin | ||
25 | 0: dmic1 is not used | ||
26 | 1: using GPIO2 pin as dmic1 data pin | ||
27 | 2: using IN1P pin as dmic1 data pin | ||
28 | |||
29 | Pins on the device (for linking into audio routes) for RT5660: | ||
30 | |||
31 | * DMIC L1 | ||
32 | * DMIC R1 | ||
33 | * IN1P | ||
34 | * IN1N | ||
35 | * IN2P | ||
36 | * IN3P | ||
37 | * IN3N | ||
38 | * SPO | ||
39 | * LOUTL | ||
40 | * LOUTR | ||
41 | |||
42 | Example: | ||
43 | |||
44 | rt5660 { | ||
45 | compatible = "realtek,rt5660"; | ||
46 | reg = <0x1c>; | ||
47 | }; | ||
diff --git a/Documentation/devicetree/bindings/sound/rt5663.txt b/Documentation/devicetree/bindings/sound/rt5663.txt new file mode 100644 index 000000000000..7d3c974c6e2e --- /dev/null +++ b/Documentation/devicetree/bindings/sound/rt5663.txt | |||
@@ -0,0 +1,30 @@ | |||
1 | RT5663/RT5668 audio CODEC | ||
2 | |||
3 | This device supports I2C only. | ||
4 | |||
5 | Required properties: | ||
6 | |||
7 | - compatible : One of "realtek,rt5663" or "realtek,rt5668". | ||
8 | |||
9 | - reg : The I2C address of the device. | ||
10 | |||
11 | - interrupts : The CODEC's interrupt output. | ||
12 | |||
13 | Optional properties: | ||
14 | |||
15 | Pins on the device (for linking into audio routes) for RT5663/RT5668: | ||
16 | |||
17 | * IN1P | ||
18 | * IN1N | ||
19 | * IN2P | ||
20 | * IN2N | ||
21 | * HPOL | ||
22 | * HPOR | ||
23 | |||
24 | Example: | ||
25 | |||
26 | codec: rt5663@12 { | ||
27 | compatible = "realtek,rt5663"; | ||
28 | reg = <0x12>; | ||
29 | interrupts = <7 IRQ_TYPE_EDGE_FALLING>; | ||
30 | }; | ||
diff --git a/Documentation/devicetree/bindings/sound/simple-card.txt b/Documentation/devicetree/bindings/sound/simple-card.txt index 59d862801e59..c7a93931fad2 100644 --- a/Documentation/devicetree/bindings/sound/simple-card.txt +++ b/Documentation/devicetree/bindings/sound/simple-card.txt | |||
@@ -22,6 +22,8 @@ Optional properties: | |||
22 | headphones are attached. | 22 | headphones are attached. |
23 | - simple-audio-card,mic-det-gpio : Reference to GPIO that signals when | 23 | - simple-audio-card,mic-det-gpio : Reference to GPIO that signals when |
24 | a microphone is attached. | 24 | a microphone is attached. |
25 | - simple-audio-card,aux-devs : List of phandles pointing to auxiliary devices, such | ||
26 | as amplifiers, to be added to the sound card. | ||
25 | 27 | ||
26 | Optional subnodes: | 28 | Optional subnodes: |
27 | 29 | ||
@@ -162,3 +164,38 @@ sound { | |||
162 | }; | 164 | }; |
163 | }; | 165 | }; |
164 | }; | 166 | }; |
167 | |||
168 | Example 3 - route audio from IMX6 SSI2 through TLV320DAC3100 codec | ||
169 | through TPA6130A2 amplifier to headphones: | ||
170 | |||
171 | &i2c0 { | ||
172 | codec: tlv320dac3100@18 { | ||
173 | compatible = "ti,tlv320dac3100"; | ||
174 | ... | ||
175 | } | ||
176 | |||
177 | amp: tpa6130a2@60 { | ||
178 | compatible = "ti,tpa6130a2"; | ||
179 | ... | ||
180 | } | ||
181 | } | ||
182 | |||
183 | sound { | ||
184 | compatible = "simple-audio-card"; | ||
185 | ... | ||
186 | simple-audio-card,widgets = | ||
187 | "Headphone", "Headphone Jack"; | ||
188 | simple-audio-card,routing = | ||
189 | "Headphone Jack", "HPLEFT", | ||
190 | "Headphone Jack", "HPRIGHT", | ||
191 | "LEFTIN", "HPL", | ||
192 | "RIGHTIN", "HPR"; | ||
193 | simple-audio-card,aux-devs = <&>; | ||
194 | simple-audio-card,cpu { | ||
195 | sound-dai = <&ssi2>; | ||
196 | }; | ||
197 | simple-audio-card,codec { | ||
198 | sound-dai = <&codec>; | ||
199 | clocks = ... | ||
200 | }; | ||
201 | }; | ||
diff --git a/Documentation/devicetree/bindings/sound/simple-scu-card.txt b/Documentation/devicetree/bindings/sound/simple-scu-card.txt new file mode 100644 index 000000000000..d6fe47ed09af --- /dev/null +++ b/Documentation/devicetree/bindings/sound/simple-scu-card.txt | |||
@@ -0,0 +1,110 @@ | |||
1 | ASoC simple SCU Sound Card | ||
2 | |||
3 | Simple-Card specifies audio DAI connections of SoC <-> codec. | ||
4 | |||
5 | Required properties: | ||
6 | |||
7 | - compatible : "simple-scu-audio-card" | ||
8 | "renesas,rsrc-card" | ||
9 | |||
10 | Optional properties: | ||
11 | |||
12 | - simple-audio-card,name : User specified audio sound card name, one string | ||
13 | property. | ||
14 | - simple-audio-card,cpu : CPU sub-node | ||
15 | - simple-audio-card,codec : CODEC sub-node | ||
16 | |||
17 | Optional subnode properties: | ||
18 | |||
19 | - simple-audio-card,format : CPU/CODEC common audio format. | ||
20 | "i2s", "right_j", "left_j" , "dsp_a" | ||
21 | "dsp_b", "ac97", "pdm", "msb", "lsb" | ||
22 | - simple-audio-card,frame-master : Indicates dai-link frame master. | ||
23 | phandle to a cpu or codec subnode. | ||
24 | - simple-audio-card,bitclock-master : Indicates dai-link bit clock master. | ||
25 | phandle to a cpu or codec subnode. | ||
26 | - simple-audio-card,bitclock-inversion : bool property. Add this if the | ||
27 | dai-link uses bit clock inversion. | ||
28 | - simple-audio-card,frame-inversion : bool property. Add this if the | ||
29 | dai-link uses frame clock inversion. | ||
30 | - simple-audio-card,convert-rate : platform specified sampling rate convert | ||
31 | - simple-audio-card,convert-channels : platform specified converted channel size (2 - 8 ch) | ||
32 | - simple-audio-card,prefix : see audio-routing | ||
33 | - simple-audio-card,routing : A list of the connections between audio components. | ||
34 | Each entry is a pair of strings, the first being the connection's sink, | ||
35 | the second being the connection's source. Valid names for sources. | ||
36 | use audio-prefix if some components is using same sink/sources naming. | ||
37 | it can be used if compatible was "renesas,rsrc-card"; | ||
38 | |||
39 | Required CPU/CODEC subnodes properties: | ||
40 | |||
41 | - sound-dai : phandle and port of CPU/CODEC | ||
42 | |||
43 | Optional CPU/CODEC subnodes properties: | ||
44 | |||
45 | - clocks / system-clock-frequency : specify subnode's clock if needed. | ||
46 | it can be specified via "clocks" if system has | ||
47 | clock node (= common clock), or "system-clock-frequency" | ||
48 | (if system doens't support common clock) | ||
49 | If a clock is specified, it is | ||
50 | enabled with clk_prepare_enable() | ||
51 | in dai startup() and disabled with | ||
52 | clk_disable_unprepare() in dai | ||
53 | shutdown(). | ||
54 | |||
55 | Example 1. Sampling Rate Covert | ||
56 | |||
57 | sound { | ||
58 | compatible = "simple-scu-audio-card"; | ||
59 | |||
60 | simple-audio-card,name = "rsnd-ak4643"; | ||
61 | simple-audio-card,format = "left_j"; | ||
62 | simple-audio-card,format = "left_j"; | ||
63 | simple-audio-card,bitclock-master = <&sndcodec>; | ||
64 | simple-audio-card,frame-master = <&sndcodec>; | ||
65 | |||
66 | simple-audio-card,convert-rate = <48000>; /* see audio_clk_a */ | ||
67 | |||
68 | simple-audio-card,prefix = "ak4642"; | ||
69 | simple-audio-card,routing = "ak4642 Playback", "DAI0 Playback", | ||
70 | "DAI0 Capture", "ak4642 Capture"; | ||
71 | |||
72 | sndcpu: simple-audio-card,cpu { | ||
73 | sound-dai = <&rcar_sound>; | ||
74 | }; | ||
75 | |||
76 | sndcodec: simple-audio-card,codec { | ||
77 | sound-dai = <&ak4643>; | ||
78 | system-clock-frequency = <11289600>; | ||
79 | }; | ||
80 | }; | ||
81 | |||
82 | Example 2. 2 CPU 1 Codec | ||
83 | |||
84 | sound { | ||
85 | compatible = "renesas,rsrc-card"; | ||
86 | |||
87 | card-name = "rsnd-ak4643"; | ||
88 | format = "left_j"; | ||
89 | bitclock-master = <&dpcmcpu>; | ||
90 | frame-master = <&dpcmcpu>; | ||
91 | |||
92 | convert-rate = <48000>; /* see audio_clk_a */ | ||
93 | |||
94 | audio-prefix = "ak4642"; | ||
95 | audio-routing = "ak4642 Playback", "DAI0 Playback", | ||
96 | "ak4642 Playback", "DAI1 Playback"; | ||
97 | |||
98 | dpcmcpu: cpu@0 { | ||
99 | sound-dai = <&rcar_sound 0>; | ||
100 | }; | ||
101 | |||
102 | cpu@1 { | ||
103 | sound-dai = <&rcar_sound 1>; | ||
104 | }; | ||
105 | |||
106 | codec { | ||
107 | sound-dai = <&ak4643>; | ||
108 | clocks = <&audio_clock>; | ||
109 | }; | ||
110 | }; | ||
diff --git a/Documentation/devicetree/bindings/sound/st,sti-asoc-card.txt b/Documentation/devicetree/bindings/sound/st,sti-asoc-card.txt index 16bcdfb6760e..745dc62f76ea 100644 --- a/Documentation/devicetree/bindings/sound/st,sti-asoc-card.txt +++ b/Documentation/devicetree/bindings/sound/st,sti-asoc-card.txt | |||
@@ -11,7 +11,9 @@ Documentation/devicetree/bindings/sound/simple-card.txt. | |||
11 | --------------------------------------- | 11 | --------------------------------------- |
12 | 12 | ||
13 | Required properties: | 13 | Required properties: |
14 | - compatible: "st,sti-uni-player" or "st,sti-uni-reader" | 14 | - compatible: "st,stih407-uni-player-hdmi", "st,stih407-uni-player-pcm-out", |
15 | "st,stih407-uni-player-dac", "st,stih407-uni-player-spdif", | ||
16 | "st,stih407-uni-reader-pcm_in", "st,stih407-uni-reader-hdmi", | ||
15 | 17 | ||
16 | - st,syscfg: phandle to boot-device system configuration registers | 18 | - st,syscfg: phandle to boot-device system configuration registers |
17 | 19 | ||
@@ -33,32 +35,24 @@ Required properties: | |||
33 | "tx" for "st,sti-uni-player" compatibility | 35 | "tx" for "st,sti-uni-player" compatibility |
34 | "rx" for "st,sti-uni-reader" compatibility | 36 | "rx" for "st,sti-uni-reader" compatibility |
35 | 37 | ||
36 | - st,version: IP version integrated in SOC. | ||
37 | |||
38 | - dai-name: DAI name that describes the IP. | ||
39 | |||
40 | - st,mode: IP working mode depending on associated codec. | ||
41 | "HDMI" connected to HDMI codec and support IEC HDMI formats (player only). | ||
42 | "SPDIF" connected to SPDIF codec and support SPDIF formats (player only). | ||
43 | "PCM" PCM standard mode for I2S or TDM bus. | ||
44 | "TDM" TDM mode for TDM bus. | ||
45 | |||
46 | Required properties ("st,sti-uni-player" compatibility only): | 38 | Required properties ("st,sti-uni-player" compatibility only): |
47 | - clocks: CPU_DAI IP clock source, listed in the same order than the | 39 | - clocks: CPU_DAI IP clock source, listed in the same order than the |
48 | CPU_DAI properties. | 40 | CPU_DAI properties. |
49 | 41 | ||
50 | - st,uniperiph-id: internal SOC IP instance ID. | ||
51 | |||
52 | Optional properties: | 42 | Optional properties: |
53 | - pinctrl-0: defined for CPU_DAI@1 and CPU_DAI@4 to describe I2S PIOs for | 43 | - pinctrl-0: defined for CPU_DAI@1 and CPU_DAI@4 to describe I2S PIOs for |
54 | external codecs connection. | 44 | external codecs connection. |
55 | 45 | ||
56 | - pinctrl-names: should contain only one value - "default". | 46 | - pinctrl-names: should contain only one value - "default". |
57 | 47 | ||
48 | - st,tdm-mode: to declare to set TDM mode for unireader and uniplayer IPs. | ||
49 | Only compartible with IPs in charge of the external I2S/TDM bus. | ||
50 | Should be declared depending on associated codec. | ||
51 | |||
58 | Example: | 52 | Example: |
59 | 53 | ||
60 | sti_uni_player1: sti-uni-player@1 { | 54 | sti_uni_player1: sti-uni-player@0x8D81000 { |
61 | compatible = "st,sti-uni-player"; | 55 | compatible = "st,stih407-uni-player-hdmi"; |
62 | status = "okay"; | 56 | status = "okay"; |
63 | #sound-dai-cells = <0>; | 57 | #sound-dai-cells = <0>; |
64 | st,syscfg = <&syscfg_core>; | 58 | st,syscfg = <&syscfg_core>; |
@@ -66,15 +60,12 @@ Example: | |||
66 | reg = <0x8D81000 0x158>; | 60 | reg = <0x8D81000 0x158>; |
67 | interrupts = <GIC_SPI 85 IRQ_TYPE_NONE>; | 61 | interrupts = <GIC_SPI 85 IRQ_TYPE_NONE>; |
68 | dmas = <&fdma0 3 0 1>; | 62 | dmas = <&fdma0 3 0 1>; |
69 | st,dai-name = "Uni Player #1 (I2S)"; | ||
70 | dma-names = "tx"; | 63 | dma-names = "tx"; |
71 | st,uniperiph-id = <1>; | 64 | st,tdm-mode = <1>; |
72 | st,version = <5>; | ||
73 | st,mode = "TDM"; | ||
74 | }; | 65 | }; |
75 | 66 | ||
76 | sti_uni_player2: sti-uni-player@2 { | 67 | sti_uni_player2: sti-uni-player@0x8D82000 { |
77 | compatible = "st,sti-uni-player"; | 68 | compatible = "st,stih407-uni-player-pcm-out"; |
78 | status = "okay"; | 69 | status = "okay"; |
79 | #sound-dai-cells = <0>; | 70 | #sound-dai-cells = <0>; |
80 | st,syscfg = <&syscfg_core>; | 71 | st,syscfg = <&syscfg_core>; |
@@ -82,15 +73,11 @@ Example: | |||
82 | reg = <0x8D82000 0x158>; | 73 | reg = <0x8D82000 0x158>; |
83 | interrupts = <GIC_SPI 86 IRQ_TYPE_NONE>; | 74 | interrupts = <GIC_SPI 86 IRQ_TYPE_NONE>; |
84 | dmas = <&fdma0 4 0 1>; | 75 | dmas = <&fdma0 4 0 1>; |
85 | dai-name = "Uni Player #2 (DAC)"; | ||
86 | dma-names = "tx"; | 76 | dma-names = "tx"; |
87 | st,uniperiph-id = <2>; | ||
88 | st,version = <5>; | ||
89 | st,mode = "PCM"; | ||
90 | }; | 77 | }; |
91 | 78 | ||
92 | sti_uni_player3: sti-uni-player@3 { | 79 | sti_uni_player3: sti-uni-player@0x8D85000 { |
93 | compatible = "st,sti-uni-player"; | 80 | compatible = "st,stih407-uni-player-spdif"; |
94 | status = "okay"; | 81 | status = "okay"; |
95 | #sound-dai-cells = <0>; | 82 | #sound-dai-cells = <0>; |
96 | st,syscfg = <&syscfg_core>; | 83 | st,syscfg = <&syscfg_core>; |
@@ -99,14 +86,10 @@ Example: | |||
99 | interrupts = <GIC_SPI 89 IRQ_TYPE_NONE>; | 86 | interrupts = <GIC_SPI 89 IRQ_TYPE_NONE>; |
100 | dmas = <&fdma0 7 0 1>; | 87 | dmas = <&fdma0 7 0 1>; |
101 | dma-names = "tx"; | 88 | dma-names = "tx"; |
102 | dai-name = "Uni Player #3 (SPDIF)"; | ||
103 | st,uniperiph-id = <3>; | ||
104 | st,version = <5>; | ||
105 | st,mode = "SPDIF"; | ||
106 | }; | 89 | }; |
107 | 90 | ||
108 | sti_uni_reader1: sti-uni-reader@1 { | 91 | sti_uni_reader1: sti-uni-reader@0x8D84000 { |
109 | compatible = "st,sti-uni-reader"; | 92 | compatible = "st,stih407-uni-reader-hdmi"; |
110 | status = "disabled"; | 93 | status = "disabled"; |
111 | #sound-dai-cells = <0>; | 94 | #sound-dai-cells = <0>; |
112 | st,syscfg = <&syscfg_core>; | 95 | st,syscfg = <&syscfg_core>; |
@@ -114,9 +97,6 @@ Example: | |||
114 | interrupts = <GIC_SPI 88 IRQ_TYPE_NONE>; | 97 | interrupts = <GIC_SPI 88 IRQ_TYPE_NONE>; |
115 | dmas = <&fdma0 6 0 1>; | 98 | dmas = <&fdma0 6 0 1>; |
116 | dma-names = "rx"; | 99 | dma-names = "rx"; |
117 | dai-name = "Uni Reader #1 (HDMI RX)"; | ||
118 | st,version = <3>; | ||
119 | st,mode = "PCM"; | ||
120 | }; | 100 | }; |
121 | 101 | ||
122 | 2) sti-sas-codec: internal audio codec IPs driver | 102 | 2) sti-sas-codec: internal audio codec IPs driver |
diff --git a/Documentation/devicetree/bindings/sound/sunxi,sun4i-spdif.txt b/Documentation/devicetree/bindings/sound/sunxi,sun4i-spdif.txt index 13503aa505a9..0230c4d20506 100644 --- a/Documentation/devicetree/bindings/sound/sunxi,sun4i-spdif.txt +++ b/Documentation/devicetree/bindings/sound/sunxi,sun4i-spdif.txt | |||
@@ -9,6 +9,7 @@ Required properties: | |||
9 | 9 | ||
10 | - compatible : should be one of the following: | 10 | - compatible : should be one of the following: |
11 | - "allwinner,sun4i-a10-spdif": for the Allwinner A10 SoC | 11 | - "allwinner,sun4i-a10-spdif": for the Allwinner A10 SoC |
12 | - "allwinner,sun6i-a31-spdif": for the Allwinner A31 SoC | ||
12 | 13 | ||
13 | - reg : Offset and length of the register set for the device. | 14 | - reg : Offset and length of the register set for the device. |
14 | 15 | ||
@@ -25,6 +26,8 @@ Required properties: | |||
25 | "apb" clock for the spdif bus. | 26 | "apb" clock for the spdif bus. |
26 | "spdif" clock for spdif controller. | 27 | "spdif" clock for spdif controller. |
27 | 28 | ||
29 | - resets : reset specifier for the ahb reset (A31 and newer only) | ||
30 | |||
28 | Example: | 31 | Example: |
29 | 32 | ||
30 | spdif: spdif@01c21000 { | 33 | spdif: spdif@01c21000 { |
diff --git a/Documentation/devicetree/bindings/sound/tlv320aic31xx.txt b/Documentation/devicetree/bindings/sound/tlv320aic31xx.txt index eff12be5e789..9340d2ddcc54 100644 --- a/Documentation/devicetree/bindings/sound/tlv320aic31xx.txt +++ b/Documentation/devicetree/bindings/sound/tlv320aic31xx.txt | |||
@@ -11,6 +11,7 @@ Required properties: | |||
11 | "ti,tlv320aic3110" - TLV320AIC3110 (stereo speaker amp, no MiniDSP) | 11 | "ti,tlv320aic3110" - TLV320AIC3110 (stereo speaker amp, no MiniDSP) |
12 | "ti,tlv320aic3120" - TLV320AIC3120 (mono speaker amp, MiniDSP) | 12 | "ti,tlv320aic3120" - TLV320AIC3120 (mono speaker amp, MiniDSP) |
13 | "ti,tlv320aic3111" - TLV320AIC3111 (stereo speaker amp, MiniDSP) | 13 | "ti,tlv320aic3111" - TLV320AIC3111 (stereo speaker amp, MiniDSP) |
14 | "ti,tlv320dac3100" - TLV320DAC3100 (no ADC, mono speaker amp, no MiniDSP) | ||
14 | 15 | ||
15 | - reg - <int> - I2C slave address | 16 | - reg - <int> - I2C slave address |
16 | - HPVDD-supply, SPRVDD-supply, SPLVDD-supply, AVDD-supply, IOVDD-supply, | 17 | - HPVDD-supply, SPRVDD-supply, SPLVDD-supply, AVDD-supply, IOVDD-supply, |
@@ -37,9 +38,11 @@ CODEC output pins: | |||
37 | * MICBIAS | 38 | * MICBIAS |
38 | 39 | ||
39 | CODEC input pins: | 40 | CODEC input pins: |
40 | * MIC1LP | 41 | * MIC1LP, devices with ADC |
41 | * MIC1RP | 42 | * MIC1RP, devices with ADC |
42 | * MIC1LM | 43 | * MIC1LM, devices with ADC |
44 | * AIN1, devices without ADC | ||
45 | * AIN2, devices without ADC | ||
43 | 46 | ||
44 | The pins can be used in referring sound node's audio-routing property. | 47 | The pins can be used in referring sound node's audio-routing property. |
45 | 48 | ||
diff --git a/arch/arm/mach-s3c24xx/mach-mini2440.c b/arch/arm/mach-s3c24xx/mach-mini2440.c index a8521684a7f5..13999c1c46cf 100644 --- a/arch/arm/mach-s3c24xx/mach-mini2440.c +++ b/arch/arm/mach-s3c24xx/mach-mini2440.c | |||
@@ -497,9 +497,28 @@ static struct i2c_board_info mini2440_i2c_devs[] __initdata = { | |||
497 | }, | 497 | }, |
498 | }; | 498 | }; |
499 | 499 | ||
500 | static struct uda134x_platform_data s3c24xx_uda134x = { | ||
501 | .l3 = { | ||
502 | .gpio_clk = S3C2410_GPB(4), | ||
503 | .gpio_data = S3C2410_GPB(3), | ||
504 | .gpio_mode = S3C2410_GPB(2), | ||
505 | .use_gpios = 1, | ||
506 | .data_hold = 1, | ||
507 | .data_setup = 1, | ||
508 | .clock_high = 1, | ||
509 | .mode_hold = 1, | ||
510 | .mode = 1, | ||
511 | .mode_setup = 1, | ||
512 | }, | ||
513 | .model = UDA134X_UDA1341, | ||
514 | }; | ||
515 | |||
500 | static struct platform_device uda1340_codec = { | 516 | static struct platform_device uda1340_codec = { |
501 | .name = "uda134x-codec", | 517 | .name = "uda134x-codec", |
502 | .id = -1, | 518 | .id = -1, |
519 | .dev = { | ||
520 | .platform_data = &s3c24xx_uda134x, | ||
521 | }, | ||
503 | }; | 522 | }; |
504 | 523 | ||
505 | static struct platform_device *mini2440_devices[] __initdata = { | 524 | static struct platform_device *mini2440_devices[] __initdata = { |
diff --git a/include/sound/da7219.h b/include/sound/da7219.h index 02876acdc840..409ef1397fd3 100644 --- a/include/sound/da7219.h +++ b/include/sound/da7219.h | |||
@@ -34,6 +34,8 @@ enum da7219_mic_amp_in_sel { | |||
34 | struct da7219_aad_pdata; | 34 | struct da7219_aad_pdata; |
35 | 35 | ||
36 | struct da7219_pdata { | 36 | struct da7219_pdata { |
37 | bool wakeup_source; | ||
38 | |||
37 | /* Mic */ | 39 | /* Mic */ |
38 | enum da7219_micbias_voltage micbias_lvl; | 40 | enum da7219_micbias_voltage micbias_lvl; |
39 | enum da7219_mic_amp_in_sel mic_amp_in_sel; | 41 | enum da7219_mic_amp_in_sel mic_amp_in_sel; |
diff --git a/include/sound/hda_register.h b/include/sound/hda_register.h index ff1aecf325e8..0013063db7f2 100644 --- a/include/sound/hda_register.h +++ b/include/sound/hda_register.h | |||
@@ -89,6 +89,19 @@ enum { SDI0, SDI1, SDI2, SDI3, SDO0, SDO1, SDO2, SDO3 }; | |||
89 | #define AZX_REG_SD_BDLPL 0x18 | 89 | #define AZX_REG_SD_BDLPL 0x18 |
90 | #define AZX_REG_SD_BDLPU 0x1c | 90 | #define AZX_REG_SD_BDLPU 0x1c |
91 | 91 | ||
92 | /* GTS registers */ | ||
93 | #define AZX_REG_LLCH 0x14 | ||
94 | |||
95 | #define AZX_REG_GTS_BASE 0x520 | ||
96 | |||
97 | #define AZX_REG_GTSCC (AZX_REG_GTS_BASE + 0x00) | ||
98 | #define AZX_REG_WALFCC (AZX_REG_GTS_BASE + 0x04) | ||
99 | #define AZX_REG_TSCCL (AZX_REG_GTS_BASE + 0x08) | ||
100 | #define AZX_REG_TSCCU (AZX_REG_GTS_BASE + 0x0C) | ||
101 | #define AZX_REG_LLPFOC (AZX_REG_GTS_BASE + 0x14) | ||
102 | #define AZX_REG_LLPCL (AZX_REG_GTS_BASE + 0x18) | ||
103 | #define AZX_REG_LLPCU (AZX_REG_GTS_BASE + 0x1C) | ||
104 | |||
92 | /* Haswell/Broadwell display HD-A controller Extended Mode registers */ | 105 | /* Haswell/Broadwell display HD-A controller Extended Mode registers */ |
93 | #define AZX_REG_HSW_EM4 0x100c | 106 | #define AZX_REG_HSW_EM4 0x100c |
94 | #define AZX_REG_HSW_EM5 0x1010 | 107 | #define AZX_REG_HSW_EM5 0x1010 |
@@ -242,6 +255,29 @@ enum { SDI0, SDI1, SDI2, SDI3, SDO0, SDO1, SDO2, SDO3 }; | |||
242 | /* Interval used to calculate the iterating register offset */ | 255 | /* Interval used to calculate the iterating register offset */ |
243 | #define AZX_DRSM_INTERVAL 0x08 | 256 | #define AZX_DRSM_INTERVAL 0x08 |
244 | 257 | ||
258 | /* Global time synchronization registers */ | ||
259 | #define GTSCC_TSCCD_MASK 0x80000000 | ||
260 | #define GTSCC_TSCCD_SHIFT BIT(31) | ||
261 | #define GTSCC_TSCCI_MASK 0x20 | ||
262 | #define GTSCC_CDMAS_DMA_DIR_SHIFT 4 | ||
263 | |||
264 | #define WALFCC_CIF_MASK 0x1FF | ||
265 | #define WALFCC_FN_SHIFT 9 | ||
266 | #define HDA_CLK_CYCLES_PER_FRAME 512 | ||
267 | |||
268 | /* | ||
269 | * An error occurs near frame "rollover". The clocks in frame value indicates | ||
270 | * whether this error may have occurred. Here we use the value of 10. Please | ||
271 | * see the errata for the right number [<10] | ||
272 | */ | ||
273 | #define HDA_MAX_CYCLE_VALUE 499 | ||
274 | #define HDA_MAX_CYCLE_OFFSET 10 | ||
275 | #define HDA_MAX_CYCLE_READ_RETRY 10 | ||
276 | |||
277 | #define TSCCU_CCU_SHIFT 32 | ||
278 | #define LLPC_CCU_SHIFT 32 | ||
279 | |||
280 | |||
245 | /* | 281 | /* |
246 | * helpers to read the stream position | 282 | * helpers to read the stream position |
247 | */ | 283 | */ |
diff --git a/include/sound/hdaudio.h b/include/sound/hdaudio.h index 93e63c56f48f..56004ec8d441 100644 --- a/include/sound/hdaudio.h +++ b/include/sound/hdaudio.h | |||
@@ -245,6 +245,12 @@ struct hdac_rb { | |||
245 | 245 | ||
246 | /* | 246 | /* |
247 | * HD-audio bus base driver | 247 | * HD-audio bus base driver |
248 | * | ||
249 | * @ppcap: pp capabilities pointer | ||
250 | * @spbcap: SPIB capabilities pointer | ||
251 | * @mlcap: MultiLink capabilities pointer | ||
252 | * @gtscap: gts capabilities pointer | ||
253 | * @drsmcap: dma resume capabilities pointer | ||
248 | */ | 254 | */ |
249 | struct hdac_bus { | 255 | struct hdac_bus { |
250 | struct device *dev; | 256 | struct device *dev; |
@@ -256,6 +262,12 @@ struct hdac_bus { | |||
256 | void __iomem *remap_addr; | 262 | void __iomem *remap_addr; |
257 | int irq; | 263 | int irq; |
258 | 264 | ||
265 | void __iomem *ppcap; | ||
266 | void __iomem *spbcap; | ||
267 | void __iomem *mlcap; | ||
268 | void __iomem *gtscap; | ||
269 | void __iomem *drsmcap; | ||
270 | |||
259 | /* codec linked list */ | 271 | /* codec linked list */ |
260 | struct list_head codec_list; | 272 | struct list_head codec_list; |
261 | unsigned int num_codecs; | 273 | unsigned int num_codecs; |
@@ -335,6 +347,7 @@ static inline void snd_hdac_codec_link_down(struct hdac_device *codec) | |||
335 | int snd_hdac_bus_send_cmd(struct hdac_bus *bus, unsigned int val); | 347 | int snd_hdac_bus_send_cmd(struct hdac_bus *bus, unsigned int val); |
336 | int snd_hdac_bus_get_response(struct hdac_bus *bus, unsigned int addr, | 348 | int snd_hdac_bus_get_response(struct hdac_bus *bus, unsigned int addr, |
337 | unsigned int *res); | 349 | unsigned int *res); |
350 | int snd_hdac_bus_parse_capabilities(struct hdac_bus *bus); | ||
338 | int snd_hdac_link_power(struct hdac_device *codec, bool enable); | 351 | int snd_hdac_link_power(struct hdac_device *codec, bool enable); |
339 | 352 | ||
340 | bool snd_hdac_bus_init_chip(struct hdac_bus *bus, bool full_reset); | 353 | bool snd_hdac_bus_init_chip(struct hdac_bus *bus, bool full_reset); |
diff --git a/include/sound/hdaudio_ext.h b/include/sound/hdaudio_ext.h index b9593b201599..8660a7f10851 100644 --- a/include/sound/hdaudio_ext.h +++ b/include/sound/hdaudio_ext.h | |||
@@ -8,11 +8,6 @@ | |||
8 | * | 8 | * |
9 | * @bus: hdac bus | 9 | * @bus: hdac bus |
10 | * @num_streams: streams supported | 10 | * @num_streams: streams supported |
11 | * @ppcap: pp capabilities pointer | ||
12 | * @spbcap: SPIB capabilities pointer | ||
13 | * @mlcap: MultiLink capabilities pointer | ||
14 | * @gtscap: gts capabilities pointer | ||
15 | * @drsmcap: dma resume capabilities pointer | ||
16 | * @hlink_list: link list of HDA links | 11 | * @hlink_list: link list of HDA links |
17 | * @lock: lock for link mgmt | 12 | * @lock: lock for link mgmt |
18 | * @cmd_dma_state: state of cmd DMAs: CORB and RIRB | 13 | * @cmd_dma_state: state of cmd DMAs: CORB and RIRB |
@@ -22,12 +17,6 @@ struct hdac_ext_bus { | |||
22 | int num_streams; | 17 | int num_streams; |
23 | int idx; | 18 | int idx; |
24 | 19 | ||
25 | void __iomem *ppcap; | ||
26 | void __iomem *spbcap; | ||
27 | void __iomem *mlcap; | ||
28 | void __iomem *gtscap; | ||
29 | void __iomem *drsmcap; | ||
30 | |||
31 | struct list_head hlink_list; | 20 | struct list_head hlink_list; |
32 | 21 | ||
33 | struct mutex lock; | 22 | struct mutex lock; |
@@ -54,7 +43,6 @@ void snd_hdac_ext_bus_device_remove(struct hdac_ext_bus *ebus); | |||
54 | #define HDA_CODEC_EXT_ENTRY(_vid, _revid, _name, _drv_data) \ | 43 | #define HDA_CODEC_EXT_ENTRY(_vid, _revid, _name, _drv_data) \ |
55 | HDA_CODEC_REV_EXT_ENTRY(_vid, _revid, _name, _drv_data) | 44 | HDA_CODEC_REV_EXT_ENTRY(_vid, _revid, _name, _drv_data) |
56 | 45 | ||
57 | int snd_hdac_ext_bus_parse_capabilities(struct hdac_ext_bus *sbus); | ||
58 | void snd_hdac_ext_bus_ppcap_enable(struct hdac_ext_bus *chip, bool enable); | 46 | void snd_hdac_ext_bus_ppcap_enable(struct hdac_ext_bus *chip, bool enable); |
59 | void snd_hdac_ext_bus_ppcap_int_enable(struct hdac_ext_bus *chip, bool enable); | 47 | void snd_hdac_ext_bus_ppcap_int_enable(struct hdac_ext_bus *chip, bool enable); |
60 | 48 | ||
diff --git a/include/sound/l3.h b/include/sound/l3.h index 423a08f0f1b0..1471da22adad 100644 --- a/include/sound/l3.h +++ b/include/sound/l3.h | |||
@@ -2,9 +2,15 @@ | |||
2 | #define _L3_H_ 1 | 2 | #define _L3_H_ 1 |
3 | 3 | ||
4 | struct l3_pins { | 4 | struct l3_pins { |
5 | void (*setdat)(int); | 5 | void (*setdat)(struct l3_pins *, int); |
6 | void (*setclk)(int); | 6 | void (*setclk)(struct l3_pins *, int); |
7 | void (*setmode)(int); | 7 | void (*setmode)(struct l3_pins *, int); |
8 | |||
9 | int gpio_data; | ||
10 | int gpio_clk; | ||
11 | int gpio_mode; | ||
12 | int use_gpios; | ||
13 | |||
8 | int data_hold; | 14 | int data_hold; |
9 | int data_setup; | 15 | int data_setup; |
10 | int clock_high; | 16 | int clock_high; |
@@ -13,6 +19,9 @@ struct l3_pins { | |||
13 | int mode_setup; | 19 | int mode_setup; |
14 | }; | 20 | }; |
15 | 21 | ||
22 | struct device; | ||
23 | |||
16 | int l3_write(struct l3_pins *adap, u8 addr, u8 *data, int len); | 24 | int l3_write(struct l3_pins *adap, u8 addr, u8 *data, int len); |
25 | int l3_set_gpio_ops(struct device *dev, struct l3_pins *adap); | ||
17 | 26 | ||
18 | #endif | 27 | #endif |
diff --git a/include/sound/rt5660.h b/include/sound/rt5660.h new file mode 100644 index 000000000000..065f83a24db6 --- /dev/null +++ b/include/sound/rt5660.h | |||
@@ -0,0 +1,31 @@ | |||
1 | /* | ||
2 | * linux/sound/rt5660.h -- Platform data for RT5660 | ||
3 | * | ||
4 | * Copyright 2016 Realtek Semiconductor Corp. | ||
5 | * Author: Oder Chiou <oder_chiou@realtek.com> | ||
6 | * | ||
7 | * This program is free software; you can redistribute it and/or modify | ||
8 | * it under the terms of the GNU General Public License version 2 as | ||
9 | * published by the Free Software Foundation. | ||
10 | */ | ||
11 | |||
12 | #ifndef __LINUX_SND_RT5660_H | ||
13 | #define __LINUX_SND_RT5660_H | ||
14 | |||
15 | enum rt5660_dmic1_data_pin { | ||
16 | RT5660_DMIC1_NULL, | ||
17 | RT5660_DMIC1_DATA_GPIO2, | ||
18 | RT5660_DMIC1_DATA_IN1P, | ||
19 | }; | ||
20 | |||
21 | struct rt5660_platform_data { | ||
22 | /* IN1 & IN3 can optionally be differential */ | ||
23 | bool in1_diff; | ||
24 | bool in3_diff; | ||
25 | bool use_ldo2; | ||
26 | bool poweroff_codec_in_suspend; | ||
27 | |||
28 | enum rt5660_dmic1_data_pin dmic1_data_pin; | ||
29 | }; | ||
30 | |||
31 | #endif | ||
diff --git a/include/sound/s3c24xx_uda134x.h b/include/sound/s3c24xx_uda134x.h index 33df4cb909d3..ffaf1f098c8e 100644 --- a/include/sound/s3c24xx_uda134x.h +++ b/include/sound/s3c24xx_uda134x.h | |||
@@ -7,7 +7,6 @@ struct s3c24xx_uda134x_platform_data { | |||
7 | int l3_clk; | 7 | int l3_clk; |
8 | int l3_mode; | 8 | int l3_mode; |
9 | int l3_data; | 9 | int l3_data; |
10 | void (*power) (int); | ||
11 | int model; | 10 | int model; |
12 | }; | 11 | }; |
13 | 12 | ||
diff --git a/include/sound/simple_card_utils.h b/include/sound/simple_card_utils.h index 86088aed9002..fd6412551145 100644 --- a/include/sound/simple_card_utils.h +++ b/include/sound/simple_card_utils.h | |||
@@ -27,10 +27,45 @@ int asoc_simple_card_parse_daifmt(struct device *dev, | |||
27 | struct device_node *codec, | 27 | struct device_node *codec, |
28 | char *prefix, | 28 | char *prefix, |
29 | unsigned int *retfmt); | 29 | unsigned int *retfmt); |
30 | __printf(3, 4) | ||
30 | int asoc_simple_card_set_dailink_name(struct device *dev, | 31 | int asoc_simple_card_set_dailink_name(struct device *dev, |
31 | struct snd_soc_dai_link *dai_link, | 32 | struct snd_soc_dai_link *dai_link, |
32 | const char *fmt, ...); | 33 | const char *fmt, ...); |
33 | int asoc_simple_card_parse_card_name(struct snd_soc_card *card, | 34 | int asoc_simple_card_parse_card_name(struct snd_soc_card *card, |
34 | char *prefix); | 35 | char *prefix); |
35 | 36 | ||
37 | #define asoc_simple_card_parse_clk_cpu(node, dai_link, simple_dai) \ | ||
38 | asoc_simple_card_parse_clk(node, dai_link->cpu_of_node, simple_dai) | ||
39 | #define asoc_simple_card_parse_clk_codec(node, dai_link, simple_dai) \ | ||
40 | asoc_simple_card_parse_clk(node, dai_link->codec_of_node, simple_dai) | ||
41 | int asoc_simple_card_parse_clk(struct device_node *node, | ||
42 | struct device_node *dai_of_node, | ||
43 | struct asoc_simple_dai *simple_dai); | ||
44 | |||
45 | #define asoc_simple_card_parse_cpu(node, dai_link, \ | ||
46 | list_name, cells_name, is_single_link) \ | ||
47 | asoc_simple_card_parse_dai(node, &dai_link->cpu_of_node, \ | ||
48 | &dai_link->cpu_dai_name, list_name, cells_name, is_single_link) | ||
49 | #define asoc_simple_card_parse_codec(node, dai_link, list_name, cells_name) \ | ||
50 | asoc_simple_card_parse_dai(node, &dai_link->codec_of_node, \ | ||
51 | &dai_link->codec_dai_name, list_name, cells_name, NULL) | ||
52 | #define asoc_simple_card_parse_platform(node, dai_link, list_name, cells_name) \ | ||
53 | asoc_simple_card_parse_dai(node, &dai_link->platform_of_node, \ | ||
54 | NULL, list_name, cells_name, NULL) | ||
55 | int asoc_simple_card_parse_dai(struct device_node *node, | ||
56 | struct device_node **endpoint_np, | ||
57 | const char **dai_name, | ||
58 | const char *list_name, | ||
59 | const char *cells_name, | ||
60 | int *is_single_links); | ||
61 | |||
62 | int asoc_simple_card_init_dai(struct snd_soc_dai *dai, | ||
63 | struct asoc_simple_dai *simple_dai); | ||
64 | |||
65 | int asoc_simple_card_canonicalize_dailink(struct snd_soc_dai_link *dai_link); | ||
66 | void asoc_simple_card_canonicalize_cpu(struct snd_soc_dai_link *dai_link, | ||
67 | int is_single_links); | ||
68 | |||
69 | int asoc_simple_card_clean_reference(struct snd_soc_card *card); | ||
70 | |||
36 | #endif /* __SIMPLE_CARD_CORE_H */ | 71 | #endif /* __SIMPLE_CARD_CORE_H */ |
diff --git a/include/sound/soc.h b/include/sound/soc.h index 6144882cc96a..4f1c784e44f6 100644 --- a/include/sound/soc.h +++ b/include/sound/soc.h | |||
@@ -898,14 +898,6 @@ struct snd_soc_codec_driver { | |||
898 | int (*resume)(struct snd_soc_codec *); | 898 | int (*resume)(struct snd_soc_codec *); |
899 | struct snd_soc_component_driver component_driver; | 899 | struct snd_soc_component_driver component_driver; |
900 | 900 | ||
901 | /* Default control and setup, added after probe() is run */ | ||
902 | const struct snd_kcontrol_new *controls; | ||
903 | int num_controls; | ||
904 | const struct snd_soc_dapm_widget *dapm_widgets; | ||
905 | int num_dapm_widgets; | ||
906 | const struct snd_soc_dapm_route *dapm_routes; | ||
907 | int num_dapm_routes; | ||
908 | |||
909 | /* codec wide operations */ | 901 | /* codec wide operations */ |
910 | int (*set_sysclk)(struct snd_soc_codec *codec, | 902 | int (*set_sysclk)(struct snd_soc_codec *codec, |
911 | int clk_id, int source, unsigned int freq, int dir); | 903 | int clk_id, int source, unsigned int freq, int dir); |
@@ -1547,17 +1539,6 @@ static inline void *snd_soc_platform_get_drvdata(struct snd_soc_platform *platfo | |||
1547 | return snd_soc_component_get_drvdata(&platform->component); | 1539 | return snd_soc_component_get_drvdata(&platform->component); |
1548 | } | 1540 | } |
1549 | 1541 | ||
1550 | static inline void snd_soc_pcm_set_drvdata(struct snd_soc_pcm_runtime *rtd, | ||
1551 | void *data) | ||
1552 | { | ||
1553 | dev_set_drvdata(rtd->dev, data); | ||
1554 | } | ||
1555 | |||
1556 | static inline void *snd_soc_pcm_get_drvdata(struct snd_soc_pcm_runtime *rtd) | ||
1557 | { | ||
1558 | return dev_get_drvdata(rtd->dev); | ||
1559 | } | ||
1560 | |||
1561 | static inline void snd_soc_initialize_card_lists(struct snd_soc_card *card) | 1542 | static inline void snd_soc_initialize_card_lists(struct snd_soc_card *card) |
1562 | { | 1543 | { |
1563 | INIT_LIST_HEAD(&card->codec_dev_list); | 1544 | INIT_LIST_HEAD(&card->codec_dev_list); |
diff --git a/include/sound/tlv.h b/include/sound/tlv.h index df97d1966468..3677ebb928d5 100644 --- a/include/sound/tlv.h +++ b/include/sound/tlv.h | |||
@@ -22,67 +22,39 @@ | |||
22 | * | 22 | * |
23 | */ | 23 | */ |
24 | 24 | ||
25 | /* | ||
26 | * TLV structure is right behind the struct snd_ctl_tlv: | ||
27 | * unsigned int type - see SNDRV_CTL_TLVT_* | ||
28 | * unsigned int length | ||
29 | * .... data aligned to sizeof(unsigned int), use | ||
30 | * block_length = (length + (sizeof(unsigned int) - 1)) & | ||
31 | * ~(sizeof(unsigned int) - 1)) .... | ||
32 | */ | ||
33 | |||
34 | #include <uapi/sound/tlv.h> | 25 | #include <uapi/sound/tlv.h> |
35 | 26 | ||
36 | #define TLV_ITEM(type, ...) \ | 27 | /* For historical reasons, these macros are aliases to the ones in UAPI. */ |
37 | (type), TLV_LENGTH(__VA_ARGS__), __VA_ARGS__ | 28 | #define TLV_ITEM SNDRV_CTL_TLVD_ITEM |
38 | #define TLV_LENGTH(...) \ | 29 | #define TLV_LENGTH SNDRV_CTL_TLVD_LENGTH |
39 | ((unsigned int)sizeof((const unsigned int[]) { __VA_ARGS__ })) | 30 | |
31 | #define TLV_CONTAINER_ITEM SNDRV_CTL_TLVD_CONTAINER_ITEM | ||
32 | #define DECLARE_TLV_CONTAINER SNDRV_CTL_TLVD_DECLARE_CONTAINER | ||
40 | 33 | ||
41 | #define TLV_CONTAINER_ITEM(...) \ | 34 | #define TLV_DB_SCALE_MASK SNDRV_CTL_TLVD_DB_SCALE_MASK |
42 | TLV_ITEM(SNDRV_CTL_TLVT_CONTAINER, __VA_ARGS__) | 35 | #define TLV_DB_SCALE_MUTE SNDRV_CTL_TLVD_DB_SCALE_MUTE |
43 | #define DECLARE_TLV_CONTAINER(name, ...) \ | 36 | #define TLV_DB_SCALE_ITEM SNDRV_CTL_TLVD_DB_SCALE_ITEM |
44 | unsigned int name[] = { TLV_CONTAINER_ITEM(__VA_ARGS__) } | 37 | #define DECLARE_TLV_DB_SCALE SNDRV_CTL_TLVD_DECLARE_DB_SCALE |
45 | 38 | ||
46 | #define TLV_DB_SCALE_MASK 0xffff | 39 | #define TLV_DB_MINMAX_ITEM SNDRV_CTL_TLVD_DB_MINMAX_ITEM |
47 | #define TLV_DB_SCALE_MUTE 0x10000 | 40 | #define TLV_DB_MINMAX_MUTE_ITEM SNDRV_CTL_TLVD_DB_MINMAX_MUTE_ITEM |
48 | #define TLV_DB_SCALE_ITEM(min, step, mute) \ | 41 | #define DECLARE_TLV_DB_MINMAX SNDRV_CTL_TLVD_DECLARE_DB_MINMAX |
49 | TLV_ITEM(SNDRV_CTL_TLVT_DB_SCALE, \ | 42 | #define DECLARE_TLV_DB_MINMAX_MUTE SNDRV_CTL_TLVD_DECLARE_DB_MINMAX_MUTE |
50 | (min), \ | ||
51 | ((step) & TLV_DB_SCALE_MASK) | \ | ||
52 | ((mute) ? TLV_DB_SCALE_MUTE : 0)) | ||
53 | #define DECLARE_TLV_DB_SCALE(name, min, step, mute) \ | ||
54 | unsigned int name[] = { TLV_DB_SCALE_ITEM(min, step, mute) } | ||
55 | 43 | ||
56 | /* dB scale specified with min/max values instead of step */ | 44 | #define TLV_DB_LINEAR_ITEM SNDRV_CTL_TLVD_DB_LINEAR_ITEM |
57 | #define TLV_DB_MINMAX_ITEM(min_dB, max_dB) \ | 45 | #define DECLARE_TLV_DB_LINEAR SNDRV_CTL_TLVD_DECLARE_DB_LINEAR |
58 | TLV_ITEM(SNDRV_CTL_TLVT_DB_MINMAX, (min_dB), (max_dB)) | ||
59 | #define TLV_DB_MINMAX_MUTE_ITEM(min_dB, max_dB) \ | ||
60 | TLV_ITEM(SNDRV_CTL_TLVT_DB_MINMAX_MUTE, (min_dB), (max_dB)) | ||
61 | #define DECLARE_TLV_DB_MINMAX(name, min_dB, max_dB) \ | ||
62 | unsigned int name[] = { TLV_DB_MINMAX_ITEM(min_dB, max_dB) } | ||
63 | #define DECLARE_TLV_DB_MINMAX_MUTE(name, min_dB, max_dB) \ | ||
64 | unsigned int name[] = { TLV_DB_MINMAX_MUTE_ITEM(min_dB, max_dB) } | ||
65 | 46 | ||
66 | /* linear volume between min_dB and max_dB (.01dB unit) */ | 47 | #define TLV_DB_RANGE_ITEM SNDRV_CTL_TLVD_DB_RANGE_ITEM |
67 | #define TLV_DB_LINEAR_ITEM(min_dB, max_dB) \ | 48 | #define DECLARE_TLV_DB_RANGE SNDRV_CTL_TLVD_DECLARE_DB_RANGE |
68 | TLV_ITEM(SNDRV_CTL_TLVT_DB_LINEAR, (min_dB), (max_dB)) | ||
69 | #define DECLARE_TLV_DB_LINEAR(name, min_dB, max_dB) \ | ||
70 | unsigned int name[] = { TLV_DB_LINEAR_ITEM(min_dB, max_dB) } | ||
71 | 49 | ||
72 | /* dB range container: | 50 | #define TLV_DB_GAIN_MUTE SNDRV_CTL_TLVD_DB_GAIN_MUTE |
73 | * Items in dB range container must be ordered by their values and by their | 51 | |
74 | * dB values. This implies that larger values must correspond with larger | 52 | /* |
75 | * dB values (which is also required for all other mixer controls). | 53 | * The below assumes that each item TLV is 4 words like DB_SCALE or LINEAR. |
54 | * This is an old fasion and obsoleted by commit bf1d1c9b6179("ALSA: tlv: add | ||
55 | * DECLARE_TLV_DB_RANGE()"). | ||
76 | */ | 56 | */ |
77 | /* Each item is: <min> <max> <TLV> */ | 57 | #define TLV_DB_RANGE_HEAD(num) \ |
78 | #define TLV_DB_RANGE_ITEM(...) \ | ||
79 | TLV_ITEM(SNDRV_CTL_TLVT_DB_RANGE, __VA_ARGS__) | ||
80 | #define DECLARE_TLV_DB_RANGE(name, ...) \ | ||
81 | unsigned int name[] = { TLV_DB_RANGE_ITEM(__VA_ARGS__) } | ||
82 | /* The below assumes that each item TLV is 4 words like DB_SCALE or LINEAR */ | ||
83 | #define TLV_DB_RANGE_HEAD(num) \ | ||
84 | SNDRV_CTL_TLVT_DB_RANGE, 6 * (num) * sizeof(unsigned int) | 58 | SNDRV_CTL_TLVT_DB_RANGE, 6 * (num) * sizeof(unsigned int) |
85 | 59 | ||
86 | #define TLV_DB_GAIN_MUTE -9999999 | ||
87 | |||
88 | #endif /* __SOUND_TLV_H */ | 60 | #endif /* __SOUND_TLV_H */ |
diff --git a/include/uapi/sound/Kbuild b/include/uapi/sound/Kbuild index 691984cb0b91..9578d8bdbf31 100644 --- a/include/uapi/sound/Kbuild +++ b/include/uapi/sound/Kbuild | |||
@@ -13,3 +13,4 @@ header-y += sb16_csp.h | |||
13 | header-y += sfnt_info.h | 13 | header-y += sfnt_info.h |
14 | header-y += tlv.h | 14 | header-y += tlv.h |
15 | header-y += usb_stream.h | 15 | header-y += usb_stream.h |
16 | header-y += snd_sst_tokens.h | ||
diff --git a/include/uapi/sound/asoc.h b/include/uapi/sound/asoc.h index e4701a3c6331..33d00a4ce656 100644 --- a/include/uapi/sound/asoc.h +++ b/include/uapi/sound/asoc.h | |||
@@ -83,7 +83,7 @@ | |||
83 | #define SND_SOC_TPLG_NUM_TEXTS 16 | 83 | #define SND_SOC_TPLG_NUM_TEXTS 16 |
84 | 84 | ||
85 | /* ABI version */ | 85 | /* ABI version */ |
86 | #define SND_SOC_TPLG_ABI_VERSION 0x4 | 86 | #define SND_SOC_TPLG_ABI_VERSION 0x5 |
87 | 87 | ||
88 | /* Max size of TLV data */ | 88 | /* Max size of TLV data */ |
89 | #define SND_SOC_TPLG_TLV_SIZE 32 | 89 | #define SND_SOC_TPLG_TLV_SIZE 32 |
@@ -105,7 +105,8 @@ | |||
105 | #define SND_SOC_TPLG_TYPE_CODEC_LINK 9 | 105 | #define SND_SOC_TPLG_TYPE_CODEC_LINK 9 |
106 | #define SND_SOC_TPLG_TYPE_BACKEND_LINK 10 | 106 | #define SND_SOC_TPLG_TYPE_BACKEND_LINK 10 |
107 | #define SND_SOC_TPLG_TYPE_PDATA 11 | 107 | #define SND_SOC_TPLG_TYPE_PDATA 11 |
108 | #define SND_SOC_TPLG_TYPE_MAX SND_SOC_TPLG_TYPE_PDATA | 108 | #define SND_SOC_TPLG_TYPE_BE_DAI 12 |
109 | #define SND_SOC_TPLG_TYPE_MAX SND_SOC_TPLG_TYPE_BE_DAI | ||
109 | 110 | ||
110 | /* vendor block IDs - please add new vendor types to end */ | 111 | /* vendor block IDs - please add new vendor types to end */ |
111 | #define SND_SOC_TPLG_TYPE_VENDOR_FW 1000 | 112 | #define SND_SOC_TPLG_TYPE_VENDOR_FW 1000 |
@@ -124,6 +125,11 @@ | |||
124 | #define SND_SOC_TPLG_TUPLE_TYPE_WORD 4 | 125 | #define SND_SOC_TPLG_TUPLE_TYPE_WORD 4 |
125 | #define SND_SOC_TPLG_TUPLE_TYPE_SHORT 5 | 126 | #define SND_SOC_TPLG_TUPLE_TYPE_SHORT 5 |
126 | 127 | ||
128 | /* BE DAI flags */ | ||
129 | #define SND_SOC_TPLG_DAI_FLGBIT_SYMMETRIC_RATES (1 << 0) | ||
130 | #define SND_SOC_TPLG_DAI_FLGBIT_SYMMETRIC_CHANNELS (1 << 1) | ||
131 | #define SND_SOC_TPLG_DAI_FLGBIT_SYMMETRIC_SAMPLEBITS (1 << 2) | ||
132 | |||
127 | /* | 133 | /* |
128 | * Block Header. | 134 | * Block Header. |
129 | * This header precedes all object and object arrays below. | 135 | * This header precedes all object and object arrays below. |
@@ -251,6 +257,7 @@ struct snd_soc_tplg_stream_caps { | |||
251 | __le32 period_size_max; /* max period size bytes */ | 257 | __le32 period_size_max; /* max period size bytes */ |
252 | __le32 buffer_size_min; /* min buffer size bytes */ | 258 | __le32 buffer_size_min; /* min buffer size bytes */ |
253 | __le32 buffer_size_max; /* max buffer size bytes */ | 259 | __le32 buffer_size_max; /* max buffer size bytes */ |
260 | __le32 sig_bits; /* number of bits of content */ | ||
254 | } __attribute__((packed)); | 261 | } __attribute__((packed)); |
255 | 262 | ||
256 | /* | 263 | /* |
@@ -285,6 +292,8 @@ struct snd_soc_tplg_manifest { | |||
285 | __le32 graph_elems; /* number of graph elements */ | 292 | __le32 graph_elems; /* number of graph elements */ |
286 | __le32 pcm_elems; /* number of PCM elements */ | 293 | __le32 pcm_elems; /* number of PCM elements */ |
287 | __le32 dai_link_elems; /* number of DAI link elements */ | 294 | __le32 dai_link_elems; /* number of DAI link elements */ |
295 | __le32 be_dai_elems; /* number of BE DAI elements */ | ||
296 | __le32 reserved[20]; /* reserved for new ABI element types */ | ||
288 | struct snd_soc_tplg_private priv; | 297 | struct snd_soc_tplg_private priv; |
289 | } __attribute__((packed)); | 298 | } __attribute__((packed)); |
290 | 299 | ||
@@ -450,4 +459,26 @@ struct snd_soc_tplg_link_config { | |||
450 | struct snd_soc_tplg_stream stream[SND_SOC_TPLG_STREAM_CONFIG_MAX]; /* supported configs playback and captrure */ | 459 | struct snd_soc_tplg_stream stream[SND_SOC_TPLG_STREAM_CONFIG_MAX]; /* supported configs playback and captrure */ |
451 | __le32 num_streams; /* number of streams */ | 460 | __le32 num_streams; /* number of streams */ |
452 | } __attribute__((packed)); | 461 | } __attribute__((packed)); |
462 | |||
463 | /* | ||
464 | * Describes SW/FW specific features of BE DAI. | ||
465 | * | ||
466 | * File block representation for BE DAI :- | ||
467 | * +-----------------------------------+-----+ | ||
468 | * | struct snd_soc_tplg_hdr | 1 | | ||
469 | * +-----------------------------------+-----+ | ||
470 | * | struct snd_soc_tplg_be_dai | N | | ||
471 | * +-----------------------------------+-----+ | ||
472 | */ | ||
473 | struct snd_soc_tplg_be_dai { | ||
474 | __le32 size; /* in bytes of this structure */ | ||
475 | char dai_name[SNDRV_CTL_ELEM_ID_NAME_MAXLEN]; /* name - used to match */ | ||
476 | __le32 dai_id; /* unique ID - used to match */ | ||
477 | __le32 playback; /* supports playback mode */ | ||
478 | __le32 capture; /* supports capture mode */ | ||
479 | struct snd_soc_tplg_stream_caps caps[2]; /* playback and capture for DAI */ | ||
480 | __le32 flag_mask; /* bitmask of flags to configure */ | ||
481 | __le32 flags; /* SND_SOC_TPLG_DAI_FLGBIT_* */ | ||
482 | struct snd_soc_tplg_private priv; | ||
483 | } __attribute__((packed)); | ||
453 | #endif | 484 | #endif |
diff --git a/include/uapi/sound/asound.h b/include/uapi/sound/asound.h index 609cadb8739d..be353a78c303 100644 --- a/include/uapi/sound/asound.h +++ b/include/uapi/sound/asound.h | |||
@@ -106,9 +106,10 @@ enum { | |||
106 | SNDRV_HWDEP_IFACE_FW_OXFW, /* Oxford OXFW970/971 based device */ | 106 | SNDRV_HWDEP_IFACE_FW_OXFW, /* Oxford OXFW970/971 based device */ |
107 | SNDRV_HWDEP_IFACE_FW_DIGI00X, /* Digidesign Digi 002/003 family */ | 107 | SNDRV_HWDEP_IFACE_FW_DIGI00X, /* Digidesign Digi 002/003 family */ |
108 | SNDRV_HWDEP_IFACE_FW_TASCAM, /* TASCAM FireWire series */ | 108 | SNDRV_HWDEP_IFACE_FW_TASCAM, /* TASCAM FireWire series */ |
109 | SNDRV_HWDEP_IFACE_LINE6, /* Line6 USB processors */ | ||
109 | 110 | ||
110 | /* Don't forget to change the following: */ | 111 | /* Don't forget to change the following: */ |
111 | SNDRV_HWDEP_IFACE_LAST = SNDRV_HWDEP_IFACE_FW_TASCAM | 112 | SNDRV_HWDEP_IFACE_LAST = SNDRV_HWDEP_IFACE_LINE6 |
112 | }; | 113 | }; |
113 | 114 | ||
114 | struct snd_hwdep_info { | 115 | struct snd_hwdep_info { |
diff --git a/include/uapi/sound/snd_sst_tokens.h b/include/uapi/sound/snd_sst_tokens.h new file mode 100644 index 000000000000..1ee2e943d66a --- /dev/null +++ b/include/uapi/sound/snd_sst_tokens.h | |||
@@ -0,0 +1,214 @@ | |||
1 | /* | ||
2 | * snd_sst_tokens.h - Intel SST tokens definition | ||
3 | * | ||
4 | * Copyright (C) 2016 Intel Corp | ||
5 | * Author: Shreyas NC <shreyas.nc@intel.com> | ||
6 | * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or modify | ||
9 | * it under the terms of the GNU General Public License as version 2, as | ||
10 | * published by the Free Software Foundation. | ||
11 | * | ||
12 | * This program is distributed in the hope that it will be useful, but | ||
13 | * WITHOUT ANY WARRANTY; without even the implied warranty of | ||
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
15 | * General Public License for more details. | ||
16 | */ | ||
17 | #ifndef __SND_SST_TOKENS_H__ | ||
18 | #define __SND_SST_TOKENS_H__ | ||
19 | |||
20 | /** | ||
21 | * %SKL_TKN_UUID: Module UUID | ||
22 | * | ||
23 | * %SKL_TKN_U8_BLOCK_TYPE: Type of the private data block.Can be: | ||
24 | * tuples, bytes, short and words | ||
25 | * | ||
26 | * %SKL_TKN_U8_IN_PIN_TYPE: Input pin type, | ||
27 | * homogenous=0, heterogenous=1 | ||
28 | * | ||
29 | * %SKL_TKN_U8_OUT_PIN_TYPE: Output pin type, | ||
30 | * homogenous=0, heterogenous=1 | ||
31 | * %SKL_TKN_U8_DYN_IN_PIN: Configure Input pin dynamically | ||
32 | * if true | ||
33 | * | ||
34 | * %SKL_TKN_U8_DYN_OUT_PIN: Configure Output pin dynamically | ||
35 | * if true | ||
36 | * | ||
37 | * %SKL_TKN_U8_IN_QUEUE_COUNT: Store the number of Input pins | ||
38 | * | ||
39 | * %SKL_TKN_U8_OUT_QUEUE_COUNT: Store the number of Output pins | ||
40 | * | ||
41 | * %SKL_TKN_U8_TIME_SLOT: TDM slot number | ||
42 | * | ||
43 | * %SKL_TKN_U8_CORE_ID: Stores module affinity value.Can take | ||
44 | * the values: | ||
45 | * SKL_AFFINITY_CORE_0 = 0, | ||
46 | * SKL_AFFINITY_CORE_1, | ||
47 | * SKL_AFFINITY_CORE_MAX | ||
48 | * | ||
49 | * %SKL_TKN_U8_MOD_TYPE: Module type value. | ||
50 | * | ||
51 | * %SKL_TKN_U8_CONN_TYPE: Module connection type can be a FE, | ||
52 | * BE or NONE as defined : | ||
53 | * SKL_PIPE_CONN_TYPE_NONE = 0, | ||
54 | * SKL_PIPE_CONN_TYPE_FE = 1 (HOST_DMA) | ||
55 | * SKL_PIPE_CONN_TYPE_BE = 2 (LINK_DMA) | ||
56 | * | ||
57 | * %SKL_TKN_U8_DEV_TYPE: Type of device to which the module is | ||
58 | * connected | ||
59 | * Can take the values: | ||
60 | * SKL_DEVICE_BT = 0x0, | ||
61 | * SKL_DEVICE_DMIC = 0x1, | ||
62 | * SKL_DEVICE_I2S = 0x2, | ||
63 | * SKL_DEVICE_SLIMBUS = 0x3, | ||
64 | * SKL_DEVICE_HDALINK = 0x4, | ||
65 | * SKL_DEVICE_HDAHOST = 0x5, | ||
66 | * SKL_DEVICE_NONE | ||
67 | * | ||
68 | * %SKL_TKN_U8_HW_CONN_TYPE: Connection type of the HW to which the | ||
69 | * module is connected | ||
70 | * SKL_CONN_NONE = 0, | ||
71 | * SKL_CONN_SOURCE = 1, | ||
72 | * SKL_CONN_SINK = 2 | ||
73 | * | ||
74 | * %SKL_TKN_U16_PIN_INST_ID: Stores the pin instance id | ||
75 | * | ||
76 | * %SKL_TKN_U16_MOD_INST_ID: Stores the mdule instance id | ||
77 | * | ||
78 | * %SKL_TKN_U32_MAX_MCPS: Module max mcps value | ||
79 | * | ||
80 | * %SKL_TKN_U32_MEM_PAGES: Module resource pages | ||
81 | * | ||
82 | * %SKL_TKN_U32_OBS: Stores Output Buffer size | ||
83 | * | ||
84 | * %SKL_TKN_U32_IBS: Stores input buffer size | ||
85 | * | ||
86 | * %SKL_TKN_U32_VBUS_ID: Module VBUS_ID. PDM=0, SSP0=0, | ||
87 | * SSP1=1,SSP2=2, | ||
88 | * SSP3=3, SSP4=4, | ||
89 | * SSP5=5, SSP6=6,INVALID | ||
90 | * | ||
91 | * %SKL_TKN_U32_PARAMS_FIXUP: Module Params fixup mask | ||
92 | * %SKL_TKN_U32_CONVERTER: Module params converter mask | ||
93 | * %SKL_TKN_U32_PIPE_ID: Stores the pipe id | ||
94 | * | ||
95 | * %SKL_TKN_U32_PIPE_CONN_TYPE: Type of the token to which the pipe is | ||
96 | * connected to. It can be | ||
97 | * SKL_PIPE_CONN_TYPE_NONE = 0, | ||
98 | * SKL_PIPE_CONN_TYPE_FE = 1 (HOST_DMA), | ||
99 | * SKL_PIPE_CONN_TYPE_BE = 2 (LINK_DMA), | ||
100 | * | ||
101 | * %SKL_TKN_U32_PIPE_PRIORITY: Pipe priority value | ||
102 | * %SKL_TKN_U32_PIPE_MEM_PGS: Pipe resource pages | ||
103 | * | ||
104 | * %SKL_TKN_U32_DIR_PIN_COUNT: Value for the direction to set input/output | ||
105 | * formats and the pin count. | ||
106 | * The first 4 bits have the direction | ||
107 | * value and the next 4 have | ||
108 | * the pin count value. | ||
109 | * SKL_DIR_IN = 0, SKL_DIR_OUT = 1. | ||
110 | * The input and output formats | ||
111 | * share the same set of tokens | ||
112 | * with the distinction between input | ||
113 | * and output made by reading direction | ||
114 | * token. | ||
115 | * | ||
116 | * %SKL_TKN_U32_FMT_CH: Supported channel count | ||
117 | * | ||
118 | * %SKL_TKN_U32_FMT_FREQ: Supported frequency/sample rate | ||
119 | * | ||
120 | * %SKL_TKN_U32_FMT_BIT_DEPTH: Supported container size | ||
121 | * | ||
122 | * %SKL_TKN_U32_FMT_SAMPLE_SIZE:Number of samples in the container | ||
123 | * | ||
124 | * %SKL_TKN_U32_FMT_CH_CONFIG: Supported channel configurations for the | ||
125 | * input/output. | ||
126 | * | ||
127 | * %SKL_TKN_U32_FMT_INTERLEAVE: Interleaving style which can be per | ||
128 | * channel or per sample. The values can be : | ||
129 | * SKL_INTERLEAVING_PER_CHANNEL = 0, | ||
130 | * SKL_INTERLEAVING_PER_SAMPLE = 1, | ||
131 | * | ||
132 | * %SKL_TKN_U32_FMT_SAMPLE_TYPE: | ||
133 | * Specifies the sample type. Can take the | ||
134 | * values: SKL_SAMPLE_TYPE_INT_MSB = 0, | ||
135 | * SKL_SAMPLE_TYPE_INT_LSB = 1, | ||
136 | * SKL_SAMPLE_TYPE_INT_SIGNED = 2, | ||
137 | * SKL_SAMPLE_TYPE_INT_UNSIGNED = 3, | ||
138 | * SKL_SAMPLE_TYPE_FLOAT = 4 | ||
139 | * | ||
140 | * %SKL_TKN_U32_CH_MAP: Channel map values | ||
141 | * %SKL_TKN_U32_MOD_SET_PARAMS: It can take these values: | ||
142 | * SKL_PARAM_DEFAULT, SKL_PARAM_INIT, | ||
143 | * SKL_PARAM_SET, SKL_PARAM_BIND | ||
144 | * | ||
145 | * %SKL_TKN_U32_MOD_PARAM_ID: ID of the module params | ||
146 | * | ||
147 | * %SKL_TKN_U32_CAPS_SET_PARAMS: | ||
148 | * Set params value | ||
149 | * | ||
150 | * %SKL_TKN_U32_CAPS_PARAMS_ID: Params ID | ||
151 | * | ||
152 | * %SKL_TKN_U32_CAPS_SIZE: Caps size | ||
153 | * | ||
154 | * %SKL_TKN_U32_PROC_DOMAIN: Specify processing domain | ||
155 | * | ||
156 | * %SKL_TKN_U32_LIB_COUNT: Specifies the number of libraries | ||
157 | * | ||
158 | * %SKL_TKN_STR_LIB_NAME: Specifies the library name | ||
159 | * | ||
160 | * module_id and loadable flags dont have tokens as these values will be | ||
161 | * read from the DSP FW manifest | ||
162 | */ | ||
163 | enum SKL_TKNS { | ||
164 | SKL_TKN_UUID = 1, | ||
165 | SKL_TKN_U8_NUM_BLOCKS, | ||
166 | SKL_TKN_U8_BLOCK_TYPE, | ||
167 | SKL_TKN_U8_IN_PIN_TYPE, | ||
168 | SKL_TKN_U8_OUT_PIN_TYPE, | ||
169 | SKL_TKN_U8_DYN_IN_PIN, | ||
170 | SKL_TKN_U8_DYN_OUT_PIN, | ||
171 | SKL_TKN_U8_IN_QUEUE_COUNT, | ||
172 | SKL_TKN_U8_OUT_QUEUE_COUNT, | ||
173 | SKL_TKN_U8_TIME_SLOT, | ||
174 | SKL_TKN_U8_CORE_ID, | ||
175 | SKL_TKN_U8_MOD_TYPE, | ||
176 | SKL_TKN_U8_CONN_TYPE, | ||
177 | SKL_TKN_U8_DEV_TYPE, | ||
178 | SKL_TKN_U8_HW_CONN_TYPE, | ||
179 | SKL_TKN_U16_MOD_INST_ID, | ||
180 | SKL_TKN_U16_BLOCK_SIZE, | ||
181 | SKL_TKN_U32_MAX_MCPS, | ||
182 | SKL_TKN_U32_MEM_PAGES, | ||
183 | SKL_TKN_U32_OBS, | ||
184 | SKL_TKN_U32_IBS, | ||
185 | SKL_TKN_U32_VBUS_ID, | ||
186 | SKL_TKN_U32_PARAMS_FIXUP, | ||
187 | SKL_TKN_U32_CONVERTER, | ||
188 | SKL_TKN_U32_PIPE_ID, | ||
189 | SKL_TKN_U32_PIPE_CONN_TYPE, | ||
190 | SKL_TKN_U32_PIPE_PRIORITY, | ||
191 | SKL_TKN_U32_PIPE_MEM_PGS, | ||
192 | SKL_TKN_U32_DIR_PIN_COUNT, | ||
193 | SKL_TKN_U32_FMT_CH, | ||
194 | SKL_TKN_U32_FMT_FREQ, | ||
195 | SKL_TKN_U32_FMT_BIT_DEPTH, | ||
196 | SKL_TKN_U32_FMT_SAMPLE_SIZE, | ||
197 | SKL_TKN_U32_FMT_CH_CONFIG, | ||
198 | SKL_TKN_U32_FMT_INTERLEAVE, | ||
199 | SKL_TKN_U32_FMT_SAMPLE_TYPE, | ||
200 | SKL_TKN_U32_FMT_CH_MAP, | ||
201 | SKL_TKN_U32_PIN_MOD_ID, | ||
202 | SKL_TKN_U32_PIN_INST_ID, | ||
203 | SKL_TKN_U32_MOD_SET_PARAMS, | ||
204 | SKL_TKN_U32_MOD_PARAM_ID, | ||
205 | SKL_TKN_U32_CAPS_SET_PARAMS, | ||
206 | SKL_TKN_U32_CAPS_PARAMS_ID, | ||
207 | SKL_TKN_U32_CAPS_SIZE, | ||
208 | SKL_TKN_U32_PROC_DOMAIN, | ||
209 | SKL_TKN_U32_LIB_COUNT, | ||
210 | SKL_TKN_STR_LIB_NAME, | ||
211 | SKL_TKN_MAX = SKL_TKN_STR_LIB_NAME, | ||
212 | }; | ||
213 | |||
214 | #endif | ||
diff --git a/include/uapi/sound/tlv.h b/include/uapi/sound/tlv.h index ffc4f203146c..b4df440c015b 100644 --- a/include/uapi/sound/tlv.h +++ b/include/uapi/sound/tlv.h | |||
@@ -28,4 +28,73 @@ | |||
28 | #define SNDRV_CTL_TLVT_CHMAP_VAR 0x102 /* channels freely swappable */ | 28 | #define SNDRV_CTL_TLVT_CHMAP_VAR 0x102 /* channels freely swappable */ |
29 | #define SNDRV_CTL_TLVT_CHMAP_PAIRED 0x103 /* pair-wise swappable */ | 29 | #define SNDRV_CTL_TLVT_CHMAP_PAIRED 0x103 /* pair-wise swappable */ |
30 | 30 | ||
31 | /* | ||
32 | * TLV structure is right behind the struct snd_ctl_tlv: | ||
33 | * unsigned int type - see SNDRV_CTL_TLVT_* | ||
34 | * unsigned int length | ||
35 | * .... data aligned to sizeof(unsigned int), use | ||
36 | * block_length = (length + (sizeof(unsigned int) - 1)) & | ||
37 | * ~(sizeof(unsigned int) - 1)) .... | ||
38 | */ | ||
39 | #define SNDRV_CTL_TLVD_ITEM(type, ...) \ | ||
40 | (type), SNDRV_CTL_TLVD_LENGTH(__VA_ARGS__), __VA_ARGS__ | ||
41 | #define SNDRV_CTL_TLVD_LENGTH(...) \ | ||
42 | ((unsigned int)sizeof((const unsigned int[]) { __VA_ARGS__ })) | ||
43 | |||
44 | #define SNDRV_CTL_TLVD_CONTAINER_ITEM(...) \ | ||
45 | SNDRV_CTL_TLVD_ITEM(SNDRV_CTL_TLVT_CONTAINER, __VA_ARGS__) | ||
46 | #define SNDRV_CTL_TLVD_DECLARE_CONTAINER(name, ...) \ | ||
47 | unsigned int name[] = { \ | ||
48 | SNDRV_CTL_TLVD_CONTAINER_ITEM(__VA_ARGS__) \ | ||
49 | } | ||
50 | |||
51 | #define SNDRV_CTL_TLVD_DB_SCALE_MASK 0xffff | ||
52 | #define SNDRV_CTL_TLVD_DB_SCALE_MUTE 0x10000 | ||
53 | #define SNDRV_CTL_TLVD_DB_SCALE_ITEM(min, step, mute) \ | ||
54 | SNDRV_CTL_TLVD_ITEM(SNDRV_CTL_TLVT_DB_SCALE, \ | ||
55 | (min), \ | ||
56 | ((step) & SNDRV_CTL_TLVD_DB_SCALE_MASK) | \ | ||
57 | ((mute) ? SNDRV_CTL_TLVD_DB_SCALE_MUTE : 0)) | ||
58 | #define SNDRV_CTL_TLVD_DECLARE_DB_SCALE(name, min, step, mute) \ | ||
59 | unsigned int name[] = { \ | ||
60 | SNDRV_CTL_TLVD_DB_SCALE_ITEM(min, step, mute) \ | ||
61 | } | ||
62 | |||
63 | /* dB scale specified with min/max values instead of step */ | ||
64 | #define SNDRV_CTL_TLVD_DB_MINMAX_ITEM(min_dB, max_dB) \ | ||
65 | SNDRV_CTL_TLVD_ITEM(SNDRV_CTL_TLVT_DB_MINMAX, (min_dB), (max_dB)) | ||
66 | #define SNDRV_CTL_TLVD_DB_MINMAX_MUTE_ITEM(min_dB, max_dB) \ | ||
67 | SNDRV_CTL_TLVD_ITEM(SNDRV_CTL_TLVT_DB_MINMAX_MUTE, (min_dB), (max_dB)) | ||
68 | #define SNDRV_CTL_TLVD_DECLARE_DB_MINMAX(name, min_dB, max_dB) \ | ||
69 | unsigned int name[] = { \ | ||
70 | SNDRV_CTL_TLVD_DB_MINMAX_ITEM(min_dB, max_dB) \ | ||
71 | } | ||
72 | #define SNDRV_CTL_TLVD_DECLARE_DB_MINMAX_MUTE(name, min_dB, max_dB) \ | ||
73 | unsigned int name[] = { \ | ||
74 | SNDRV_CTL_TLVD_DB_MINMAX_MUTE_ITEM(min_dB, max_dB) \ | ||
75 | } | ||
76 | |||
77 | /* linear volume between min_dB and max_dB (.01dB unit) */ | ||
78 | #define SNDRV_CTL_TLVD_DB_LINEAR_ITEM(min_dB, max_dB) \ | ||
79 | SNDRV_CTL_TLVD_ITEM(SNDRV_CTL_TLVT_DB_LINEAR, (min_dB), (max_dB)) | ||
80 | #define SNDRV_CTL_TLVD_DECLARE_DB_LINEAR(name, min_dB, max_dB) \ | ||
81 | unsigned int name[] = { \ | ||
82 | SNDRV_CTL_TLVD_DB_LINEAR_ITEM(min_dB, max_dB) \ | ||
83 | } | ||
84 | |||
85 | /* dB range container: | ||
86 | * Items in dB range container must be ordered by their values and by their | ||
87 | * dB values. This implies that larger values must correspond with larger | ||
88 | * dB values (which is also required for all other mixer controls). | ||
89 | */ | ||
90 | /* Each item is: <min> <max> <TLV> */ | ||
91 | #define SNDRV_CTL_TLVD_DB_RANGE_ITEM(...) \ | ||
92 | SNDRV_CTL_TLVD_ITEM(SNDRV_CTL_TLVT_DB_RANGE, __VA_ARGS__) | ||
93 | #define SNDRV_CTL_TLVD_DECLARE_DB_RANGE(name, ...) \ | ||
94 | unsigned int name[] = { \ | ||
95 | SNDRV_CTL_TLVD_DB_RANGE_ITEM(__VA_ARGS__) \ | ||
96 | } | ||
97 | |||
98 | #define SNDRV_CTL_TLVD_DB_GAIN_MUTE -9999999 | ||
99 | |||
31 | #endif | 100 | #endif |
diff --git a/sound/aoa/fabrics/layout.c b/sound/aoa/fabrics/layout.c index 8f71f7e4d966..a0c4a5de809c 100644 --- a/sound/aoa/fabrics/layout.c +++ b/sound/aoa/fabrics/layout.c | |||
@@ -112,6 +112,7 @@ MODULE_ALIAS("sound-layout-100"); | |||
112 | 112 | ||
113 | MODULE_ALIAS("aoa-device-id-14"); | 113 | MODULE_ALIAS("aoa-device-id-14"); |
114 | MODULE_ALIAS("aoa-device-id-22"); | 114 | MODULE_ALIAS("aoa-device-id-22"); |
115 | MODULE_ALIAS("aoa-device-id-31"); | ||
115 | MODULE_ALIAS("aoa-device-id-35"); | 116 | MODULE_ALIAS("aoa-device-id-35"); |
116 | MODULE_ALIAS("aoa-device-id-44"); | 117 | MODULE_ALIAS("aoa-device-id-44"); |
117 | 118 | ||
@@ -362,6 +363,13 @@ static struct layout layouts[] = { | |||
362 | .connections = tas_connections_nolineout, | 363 | .connections = tas_connections_nolineout, |
363 | }, | 364 | }, |
364 | }, | 365 | }, |
366 | /* PowerBook6,1 */ | ||
367 | { .device_id = 31, | ||
368 | .codecs[0] = { | ||
369 | .name = "tas", | ||
370 | .connections = tas_connections_nolineout, | ||
371 | }, | ||
372 | }, | ||
365 | /* PowerBook6,5 */ | 373 | /* PowerBook6,5 */ |
366 | { .device_id = 44, | 374 | { .device_id = 44, |
367 | .codecs[0] = { | 375 | .codecs[0] = { |
@@ -1161,12 +1169,7 @@ static struct soundbus_driver aoa_soundbus_driver = { | |||
1161 | 1169 | ||
1162 | static int __init aoa_fabric_layout_init(void) | 1170 | static int __init aoa_fabric_layout_init(void) |
1163 | { | 1171 | { |
1164 | int err; | 1172 | return soundbus_register_driver(&aoa_soundbus_driver); |
1165 | |||
1166 | err = soundbus_register_driver(&aoa_soundbus_driver); | ||
1167 | if (err) | ||
1168 | return err; | ||
1169 | return 0; | ||
1170 | } | 1173 | } |
1171 | 1174 | ||
1172 | static void __exit aoa_fabric_layout_exit(void) | 1175 | static void __exit aoa_fabric_layout_exit(void) |
diff --git a/sound/aoa/soundbus/i2sbus/core.c b/sound/aoa/soundbus/i2sbus/core.c index 1cbf210080a1..000b58522106 100644 --- a/sound/aoa/soundbus/i2sbus/core.c +++ b/sound/aoa/soundbus/i2sbus/core.c | |||
@@ -197,7 +197,7 @@ static int i2sbus_add_dev(struct macio_dev *macio, | |||
197 | * so restrict to those we do handle for now. | 197 | * so restrict to those we do handle for now. |
198 | */ | 198 | */ |
199 | if (id && (*id == 22 || *id == 14 || *id == 35 || | 199 | if (id && (*id == 22 || *id == 14 || *id == 35 || |
200 | *id == 44)) { | 200 | *id == 31 || *id == 44)) { |
201 | snprintf(dev->sound.modalias, 32, | 201 | snprintf(dev->sound.modalias, 32, |
202 | "aoa-device-id-%d", *id); | 202 | "aoa-device-id-%d", *id); |
203 | ok = 1; | 203 | ok = 1; |
diff --git a/sound/core/compress_offload.c b/sound/core/compress_offload.c index 2c498488af6c..fec1dfdb14ad 100644 --- a/sound/core/compress_offload.c +++ b/sound/core/compress_offload.c | |||
@@ -553,13 +553,9 @@ snd_compr_set_params(struct snd_compr_stream *stream, unsigned long arg) | |||
553 | * we should allow parameter change only when stream has been | 553 | * we should allow parameter change only when stream has been |
554 | * opened not in other cases | 554 | * opened not in other cases |
555 | */ | 555 | */ |
556 | params = kmalloc(sizeof(*params), GFP_KERNEL); | 556 | params = memdup_user((void __user *)arg, sizeof(*params)); |
557 | if (!params) | 557 | if (IS_ERR(params)) |
558 | return -ENOMEM; | 558 | return PTR_ERR(params); |
559 | if (copy_from_user(params, (void __user *)arg, sizeof(*params))) { | ||
560 | retval = -EFAULT; | ||
561 | goto out; | ||
562 | } | ||
563 | 559 | ||
564 | retval = snd_compress_check_input(params); | 560 | retval = snd_compress_check_input(params); |
565 | if (retval) | 561 | if (retval) |
@@ -784,7 +780,7 @@ static int snd_compress_wait_for_drain(struct snd_compr_stream *stream) | |||
784 | ret = wait_event_interruptible(stream->runtime->sleep, | 780 | ret = wait_event_interruptible(stream->runtime->sleep, |
785 | (stream->runtime->state != SNDRV_PCM_STATE_DRAINING)); | 781 | (stream->runtime->state != SNDRV_PCM_STATE_DRAINING)); |
786 | if (ret == -ERESTARTSYS) | 782 | if (ret == -ERESTARTSYS) |
787 | pr_debug("wait aborted by a signal"); | 783 | pr_debug("wait aborted by a signal\n"); |
788 | else if (ret) | 784 | else if (ret) |
789 | pr_debug("wait for drain failed with %d\n", ret); | 785 | pr_debug("wait for drain failed with %d\n", ret); |
790 | 786 | ||
@@ -966,7 +962,7 @@ static int snd_compress_dev_register(struct snd_device *device) | |||
966 | compr->card, compr->device, | 962 | compr->card, compr->device, |
967 | &snd_compr_file_ops, compr, &compr->dev); | 963 | &snd_compr_file_ops, compr, &compr->dev); |
968 | if (ret < 0) { | 964 | if (ret < 0) { |
969 | pr_err("snd_register_device failed\n %d", ret); | 965 | pr_err("snd_register_device failed %d\n", ret); |
970 | return ret; | 966 | return ret; |
971 | } | 967 | } |
972 | return ret; | 968 | return ret; |
diff --git a/sound/core/pcm_native.c b/sound/core/pcm_native.c index c61fd50f771f..9d33c1e85c79 100644 --- a/sound/core/pcm_native.c +++ b/sound/core/pcm_native.c | |||
@@ -2637,9 +2637,11 @@ static int snd_pcm_hwsync(struct snd_pcm_substream *substream) | |||
2637 | break; | 2637 | break; |
2638 | /* Fall through */ | 2638 | /* Fall through */ |
2639 | case SNDRV_PCM_STATE_PREPARED: | 2639 | case SNDRV_PCM_STATE_PREPARED: |
2640 | case SNDRV_PCM_STATE_SUSPENDED: | ||
2641 | err = 0; | 2640 | err = 0; |
2642 | break; | 2641 | break; |
2642 | case SNDRV_PCM_STATE_SUSPENDED: | ||
2643 | err = -ESTRPIPE; | ||
2644 | break; | ||
2643 | case SNDRV_PCM_STATE_XRUN: | 2645 | case SNDRV_PCM_STATE_XRUN: |
2644 | err = -EPIPE; | 2646 | err = -EPIPE; |
2645 | break; | 2647 | break; |
diff --git a/sound/core/seq/seq_clientmgr.c b/sound/core/seq/seq_clientmgr.c index d6d9419d8bac..4c935202ce23 100644 --- a/sound/core/seq/seq_clientmgr.c +++ b/sound/core/seq/seq_clientmgr.c | |||
@@ -87,21 +87,6 @@ static int snd_seq_deliver_single_event(struct snd_seq_client *client, | |||
87 | 87 | ||
88 | /* | 88 | /* |
89 | */ | 89 | */ |
90 | |||
91 | static inline mm_segment_t snd_enter_user(void) | ||
92 | { | ||
93 | mm_segment_t fs = get_fs(); | ||
94 | set_fs(get_ds()); | ||
95 | return fs; | ||
96 | } | ||
97 | |||
98 | static inline void snd_leave_user(mm_segment_t fs) | ||
99 | { | ||
100 | set_fs(fs); | ||
101 | } | ||
102 | |||
103 | /* | ||
104 | */ | ||
105 | static inline unsigned short snd_seq_file_flags(struct file *file) | 90 | static inline unsigned short snd_seq_file_flags(struct file *file) |
106 | { | 91 | { |
107 | switch (file->f_mode & (FMODE_READ | FMODE_WRITE)) { | 92 | switch (file->f_mode & (FMODE_READ | FMODE_WRITE)) { |
@@ -1128,59 +1113,69 @@ static unsigned int snd_seq_poll(struct file *file, poll_table * wait) | |||
1128 | 1113 | ||
1129 | /*-----------------------------------------------------*/ | 1114 | /*-----------------------------------------------------*/ |
1130 | 1115 | ||
1116 | static int snd_seq_ioctl_pversion(struct snd_seq_client *client, void *arg) | ||
1117 | { | ||
1118 | int *pversion = arg; | ||
1119 | |||
1120 | *pversion = SNDRV_SEQ_VERSION; | ||
1121 | return 0; | ||
1122 | } | ||
1123 | |||
1124 | static int snd_seq_ioctl_client_id(struct snd_seq_client *client, void *arg) | ||
1125 | { | ||
1126 | int *client_id = arg; | ||
1127 | |||
1128 | *client_id = client->number; | ||
1129 | return 0; | ||
1130 | } | ||
1131 | 1131 | ||
1132 | /* SYSTEM_INFO ioctl() */ | 1132 | /* SYSTEM_INFO ioctl() */ |
1133 | static int snd_seq_ioctl_system_info(struct snd_seq_client *client, void __user *arg) | 1133 | static int snd_seq_ioctl_system_info(struct snd_seq_client *client, void *arg) |
1134 | { | 1134 | { |
1135 | struct snd_seq_system_info info; | 1135 | struct snd_seq_system_info *info = arg; |
1136 | 1136 | ||
1137 | memset(&info, 0, sizeof(info)); | 1137 | memset(info, 0, sizeof(*info)); |
1138 | /* fill the info fields */ | 1138 | /* fill the info fields */ |
1139 | info.queues = SNDRV_SEQ_MAX_QUEUES; | 1139 | info->queues = SNDRV_SEQ_MAX_QUEUES; |
1140 | info.clients = SNDRV_SEQ_MAX_CLIENTS; | 1140 | info->clients = SNDRV_SEQ_MAX_CLIENTS; |
1141 | info.ports = SNDRV_SEQ_MAX_PORTS; | 1141 | info->ports = SNDRV_SEQ_MAX_PORTS; |
1142 | info.channels = 256; /* fixed limit */ | 1142 | info->channels = 256; /* fixed limit */ |
1143 | info.cur_clients = client_usage.cur; | 1143 | info->cur_clients = client_usage.cur; |
1144 | info.cur_queues = snd_seq_queue_get_cur_queues(); | 1144 | info->cur_queues = snd_seq_queue_get_cur_queues(); |
1145 | 1145 | ||
1146 | if (copy_to_user(arg, &info, sizeof(info))) | ||
1147 | return -EFAULT; | ||
1148 | return 0; | 1146 | return 0; |
1149 | } | 1147 | } |
1150 | 1148 | ||
1151 | 1149 | ||
1152 | /* RUNNING_MODE ioctl() */ | 1150 | /* RUNNING_MODE ioctl() */ |
1153 | static int snd_seq_ioctl_running_mode(struct snd_seq_client *client, void __user *arg) | 1151 | static int snd_seq_ioctl_running_mode(struct snd_seq_client *client, void *arg) |
1154 | { | 1152 | { |
1155 | struct snd_seq_running_info info; | 1153 | struct snd_seq_running_info *info = arg; |
1156 | struct snd_seq_client *cptr; | 1154 | struct snd_seq_client *cptr; |
1157 | int err = 0; | 1155 | int err = 0; |
1158 | 1156 | ||
1159 | if (copy_from_user(&info, arg, sizeof(info))) | ||
1160 | return -EFAULT; | ||
1161 | |||
1162 | /* requested client number */ | 1157 | /* requested client number */ |
1163 | cptr = snd_seq_client_use_ptr(info.client); | 1158 | cptr = snd_seq_client_use_ptr(info->client); |
1164 | if (cptr == NULL) | 1159 | if (cptr == NULL) |
1165 | return -ENOENT; /* don't change !!! */ | 1160 | return -ENOENT; /* don't change !!! */ |
1166 | 1161 | ||
1167 | #ifdef SNDRV_BIG_ENDIAN | 1162 | #ifdef SNDRV_BIG_ENDIAN |
1168 | if (! info.big_endian) { | 1163 | if (!info->big_endian) { |
1169 | err = -EINVAL; | 1164 | err = -EINVAL; |
1170 | goto __err; | 1165 | goto __err; |
1171 | } | 1166 | } |
1172 | #else | 1167 | #else |
1173 | if (info.big_endian) { | 1168 | if (info->big_endian) { |
1174 | err = -EINVAL; | 1169 | err = -EINVAL; |
1175 | goto __err; | 1170 | goto __err; |
1176 | } | 1171 | } |
1177 | 1172 | ||
1178 | #endif | 1173 | #endif |
1179 | if (info.cpu_mode > sizeof(long)) { | 1174 | if (info->cpu_mode > sizeof(long)) { |
1180 | err = -EINVAL; | 1175 | err = -EINVAL; |
1181 | goto __err; | 1176 | goto __err; |
1182 | } | 1177 | } |
1183 | cptr->convert32 = (info.cpu_mode < sizeof(long)); | 1178 | cptr->convert32 = (info->cpu_mode < sizeof(long)); |
1184 | __err: | 1179 | __err: |
1185 | snd_seq_client_unlock(cptr); | 1180 | snd_seq_client_unlock(cptr); |
1186 | return err; | 1181 | return err; |
@@ -1214,51 +1209,43 @@ static void get_client_info(struct snd_seq_client *cptr, | |||
1214 | } | 1209 | } |
1215 | 1210 | ||
1216 | static int snd_seq_ioctl_get_client_info(struct snd_seq_client *client, | 1211 | static int snd_seq_ioctl_get_client_info(struct snd_seq_client *client, |
1217 | void __user *arg) | 1212 | void *arg) |
1218 | { | 1213 | { |
1214 | struct snd_seq_client_info *client_info = arg; | ||
1219 | struct snd_seq_client *cptr; | 1215 | struct snd_seq_client *cptr; |
1220 | struct snd_seq_client_info client_info; | ||
1221 | |||
1222 | if (copy_from_user(&client_info, arg, sizeof(client_info))) | ||
1223 | return -EFAULT; | ||
1224 | 1216 | ||
1225 | /* requested client number */ | 1217 | /* requested client number */ |
1226 | cptr = snd_seq_client_use_ptr(client_info.client); | 1218 | cptr = snd_seq_client_use_ptr(client_info->client); |
1227 | if (cptr == NULL) | 1219 | if (cptr == NULL) |
1228 | return -ENOENT; /* don't change !!! */ | 1220 | return -ENOENT; /* don't change !!! */ |
1229 | 1221 | ||
1230 | get_client_info(cptr, &client_info); | 1222 | get_client_info(cptr, client_info); |
1231 | snd_seq_client_unlock(cptr); | 1223 | snd_seq_client_unlock(cptr); |
1232 | 1224 | ||
1233 | if (copy_to_user(arg, &client_info, sizeof(client_info))) | ||
1234 | return -EFAULT; | ||
1235 | return 0; | 1225 | return 0; |
1236 | } | 1226 | } |
1237 | 1227 | ||
1238 | 1228 | ||
1239 | /* CLIENT_INFO ioctl() */ | 1229 | /* CLIENT_INFO ioctl() */ |
1240 | static int snd_seq_ioctl_set_client_info(struct snd_seq_client *client, | 1230 | static int snd_seq_ioctl_set_client_info(struct snd_seq_client *client, |
1241 | void __user *arg) | 1231 | void *arg) |
1242 | { | 1232 | { |
1243 | struct snd_seq_client_info client_info; | 1233 | struct snd_seq_client_info *client_info = arg; |
1244 | |||
1245 | if (copy_from_user(&client_info, arg, sizeof(client_info))) | ||
1246 | return -EFAULT; | ||
1247 | 1234 | ||
1248 | /* it is not allowed to set the info fields for an another client */ | 1235 | /* it is not allowed to set the info fields for an another client */ |
1249 | if (client->number != client_info.client) | 1236 | if (client->number != client_info->client) |
1250 | return -EPERM; | 1237 | return -EPERM; |
1251 | /* also client type must be set now */ | 1238 | /* also client type must be set now */ |
1252 | if (client->type != client_info.type) | 1239 | if (client->type != client_info->type) |
1253 | return -EINVAL; | 1240 | return -EINVAL; |
1254 | 1241 | ||
1255 | /* fill the info fields */ | 1242 | /* fill the info fields */ |
1256 | if (client_info.name[0]) | 1243 | if (client_info->name[0]) |
1257 | strlcpy(client->name, client_info.name, sizeof(client->name)); | 1244 | strlcpy(client->name, client_info->name, sizeof(client->name)); |
1258 | 1245 | ||
1259 | client->filter = client_info.filter; | 1246 | client->filter = client_info->filter; |
1260 | client->event_lost = client_info.event_lost; | 1247 | client->event_lost = client_info->event_lost; |
1261 | memcpy(client->event_filter, client_info.event_filter, 32); | 1248 | memcpy(client->event_filter, client_info->event_filter, 32); |
1262 | 1249 | ||
1263 | return 0; | 1250 | return 0; |
1264 | } | 1251 | } |
@@ -1267,30 +1254,26 @@ static int snd_seq_ioctl_set_client_info(struct snd_seq_client *client, | |||
1267 | /* | 1254 | /* |
1268 | * CREATE PORT ioctl() | 1255 | * CREATE PORT ioctl() |
1269 | */ | 1256 | */ |
1270 | static int snd_seq_ioctl_create_port(struct snd_seq_client *client, | 1257 | static int snd_seq_ioctl_create_port(struct snd_seq_client *client, void *arg) |
1271 | void __user *arg) | ||
1272 | { | 1258 | { |
1259 | struct snd_seq_port_info *info = arg; | ||
1273 | struct snd_seq_client_port *port; | 1260 | struct snd_seq_client_port *port; |
1274 | struct snd_seq_port_info info; | ||
1275 | struct snd_seq_port_callback *callback; | 1261 | struct snd_seq_port_callback *callback; |
1276 | 1262 | ||
1277 | if (copy_from_user(&info, arg, sizeof(info))) | ||
1278 | return -EFAULT; | ||
1279 | |||
1280 | /* it is not allowed to create the port for an another client */ | 1263 | /* it is not allowed to create the port for an another client */ |
1281 | if (info.addr.client != client->number) | 1264 | if (info->addr.client != client->number) |
1282 | return -EPERM; | 1265 | return -EPERM; |
1283 | 1266 | ||
1284 | port = snd_seq_create_port(client, (info.flags & SNDRV_SEQ_PORT_FLG_GIVEN_PORT) ? info.addr.port : -1); | 1267 | port = snd_seq_create_port(client, (info->flags & SNDRV_SEQ_PORT_FLG_GIVEN_PORT) ? info->addr.port : -1); |
1285 | if (port == NULL) | 1268 | if (port == NULL) |
1286 | return -ENOMEM; | 1269 | return -ENOMEM; |
1287 | 1270 | ||
1288 | if (client->type == USER_CLIENT && info.kernel) { | 1271 | if (client->type == USER_CLIENT && info->kernel) { |
1289 | snd_seq_delete_port(client, port->addr.port); | 1272 | snd_seq_delete_port(client, port->addr.port); |
1290 | return -EINVAL; | 1273 | return -EINVAL; |
1291 | } | 1274 | } |
1292 | if (client->type == KERNEL_CLIENT) { | 1275 | if (client->type == KERNEL_CLIENT) { |
1293 | if ((callback = info.kernel) != NULL) { | 1276 | if ((callback = info->kernel) != NULL) { |
1294 | if (callback->owner) | 1277 | if (callback->owner) |
1295 | port->owner = callback->owner; | 1278 | port->owner = callback->owner; |
1296 | port->private_data = callback->private_data; | 1279 | port->private_data = callback->private_data; |
@@ -1303,37 +1286,29 @@ static int snd_seq_ioctl_create_port(struct snd_seq_client *client, | |||
1303 | } | 1286 | } |
1304 | } | 1287 | } |
1305 | 1288 | ||
1306 | info.addr = port->addr; | 1289 | info->addr = port->addr; |
1307 | 1290 | ||
1308 | snd_seq_set_port_info(port, &info); | 1291 | snd_seq_set_port_info(port, info); |
1309 | snd_seq_system_client_ev_port_start(port->addr.client, port->addr.port); | 1292 | snd_seq_system_client_ev_port_start(port->addr.client, port->addr.port); |
1310 | 1293 | ||
1311 | if (copy_to_user(arg, &info, sizeof(info))) | ||
1312 | return -EFAULT; | ||
1313 | |||
1314 | return 0; | 1294 | return 0; |
1315 | } | 1295 | } |
1316 | 1296 | ||
1317 | /* | 1297 | /* |
1318 | * DELETE PORT ioctl() | 1298 | * DELETE PORT ioctl() |
1319 | */ | 1299 | */ |
1320 | static int snd_seq_ioctl_delete_port(struct snd_seq_client *client, | 1300 | static int snd_seq_ioctl_delete_port(struct snd_seq_client *client, void *arg) |
1321 | void __user *arg) | ||
1322 | { | 1301 | { |
1323 | struct snd_seq_port_info info; | 1302 | struct snd_seq_port_info *info = arg; |
1324 | int err; | 1303 | int err; |
1325 | 1304 | ||
1326 | /* set passed parameters */ | ||
1327 | if (copy_from_user(&info, arg, sizeof(info))) | ||
1328 | return -EFAULT; | ||
1329 | |||
1330 | /* it is not allowed to remove the port for an another client */ | 1305 | /* it is not allowed to remove the port for an another client */ |
1331 | if (info.addr.client != client->number) | 1306 | if (info->addr.client != client->number) |
1332 | return -EPERM; | 1307 | return -EPERM; |
1333 | 1308 | ||
1334 | err = snd_seq_delete_port(client, info.addr.port); | 1309 | err = snd_seq_delete_port(client, info->addr.port); |
1335 | if (err >= 0) | 1310 | if (err >= 0) |
1336 | snd_seq_system_client_ev_port_exit(client->number, info.addr.port); | 1311 | snd_seq_system_client_ev_port_exit(client->number, info->addr.port); |
1337 | return err; | 1312 | return err; |
1338 | } | 1313 | } |
1339 | 1314 | ||
@@ -1341,32 +1316,27 @@ static int snd_seq_ioctl_delete_port(struct snd_seq_client *client, | |||
1341 | /* | 1316 | /* |
1342 | * GET_PORT_INFO ioctl() (on any client) | 1317 | * GET_PORT_INFO ioctl() (on any client) |
1343 | */ | 1318 | */ |
1344 | static int snd_seq_ioctl_get_port_info(struct snd_seq_client *client, | 1319 | static int snd_seq_ioctl_get_port_info(struct snd_seq_client *client, void *arg) |
1345 | void __user *arg) | ||
1346 | { | 1320 | { |
1321 | struct snd_seq_port_info *info = arg; | ||
1347 | struct snd_seq_client *cptr; | 1322 | struct snd_seq_client *cptr; |
1348 | struct snd_seq_client_port *port; | 1323 | struct snd_seq_client_port *port; |
1349 | struct snd_seq_port_info info; | ||
1350 | 1324 | ||
1351 | if (copy_from_user(&info, arg, sizeof(info))) | 1325 | cptr = snd_seq_client_use_ptr(info->addr.client); |
1352 | return -EFAULT; | ||
1353 | cptr = snd_seq_client_use_ptr(info.addr.client); | ||
1354 | if (cptr == NULL) | 1326 | if (cptr == NULL) |
1355 | return -ENXIO; | 1327 | return -ENXIO; |
1356 | 1328 | ||
1357 | port = snd_seq_port_use_ptr(cptr, info.addr.port); | 1329 | port = snd_seq_port_use_ptr(cptr, info->addr.port); |
1358 | if (port == NULL) { | 1330 | if (port == NULL) { |
1359 | snd_seq_client_unlock(cptr); | 1331 | snd_seq_client_unlock(cptr); |
1360 | return -ENOENT; /* don't change */ | 1332 | return -ENOENT; /* don't change */ |
1361 | } | 1333 | } |
1362 | 1334 | ||
1363 | /* get port info */ | 1335 | /* get port info */ |
1364 | snd_seq_get_port_info(port, &info); | 1336 | snd_seq_get_port_info(port, info); |
1365 | snd_seq_port_unlock(port); | 1337 | snd_seq_port_unlock(port); |
1366 | snd_seq_client_unlock(cptr); | 1338 | snd_seq_client_unlock(cptr); |
1367 | 1339 | ||
1368 | if (copy_to_user(arg, &info, sizeof(info))) | ||
1369 | return -EFAULT; | ||
1370 | return 0; | 1340 | return 0; |
1371 | } | 1341 | } |
1372 | 1342 | ||
@@ -1374,20 +1344,16 @@ static int snd_seq_ioctl_get_port_info(struct snd_seq_client *client, | |||
1374 | /* | 1344 | /* |
1375 | * SET_PORT_INFO ioctl() (only ports on this/own client) | 1345 | * SET_PORT_INFO ioctl() (only ports on this/own client) |
1376 | */ | 1346 | */ |
1377 | static int snd_seq_ioctl_set_port_info(struct snd_seq_client *client, | 1347 | static int snd_seq_ioctl_set_port_info(struct snd_seq_client *client, void *arg) |
1378 | void __user *arg) | ||
1379 | { | 1348 | { |
1349 | struct snd_seq_port_info *info = arg; | ||
1380 | struct snd_seq_client_port *port; | 1350 | struct snd_seq_client_port *port; |
1381 | struct snd_seq_port_info info; | ||
1382 | |||
1383 | if (copy_from_user(&info, arg, sizeof(info))) | ||
1384 | return -EFAULT; | ||
1385 | 1351 | ||
1386 | if (info.addr.client != client->number) /* only set our own ports ! */ | 1352 | if (info->addr.client != client->number) /* only set our own ports ! */ |
1387 | return -EPERM; | 1353 | return -EPERM; |
1388 | port = snd_seq_port_use_ptr(client, info.addr.port); | 1354 | port = snd_seq_port_use_ptr(client, info->addr.port); |
1389 | if (port) { | 1355 | if (port) { |
1390 | snd_seq_set_port_info(port, &info); | 1356 | snd_seq_set_port_info(port, info); |
1391 | snd_seq_port_unlock(port); | 1357 | snd_seq_port_unlock(port); |
1392 | } | 1358 | } |
1393 | return 0; | 1359 | return 0; |
@@ -1453,34 +1419,31 @@ int snd_seq_client_notify_subscription(int client, int port, | |||
1453 | * add to port's subscription list IOCTL interface | 1419 | * add to port's subscription list IOCTL interface |
1454 | */ | 1420 | */ |
1455 | static int snd_seq_ioctl_subscribe_port(struct snd_seq_client *client, | 1421 | static int snd_seq_ioctl_subscribe_port(struct snd_seq_client *client, |
1456 | void __user *arg) | 1422 | void *arg) |
1457 | { | 1423 | { |
1424 | struct snd_seq_port_subscribe *subs = arg; | ||
1458 | int result = -EINVAL; | 1425 | int result = -EINVAL; |
1459 | struct snd_seq_client *receiver = NULL, *sender = NULL; | 1426 | struct snd_seq_client *receiver = NULL, *sender = NULL; |
1460 | struct snd_seq_client_port *sport = NULL, *dport = NULL; | 1427 | struct snd_seq_client_port *sport = NULL, *dport = NULL; |
1461 | struct snd_seq_port_subscribe subs; | ||
1462 | |||
1463 | if (copy_from_user(&subs, arg, sizeof(subs))) | ||
1464 | return -EFAULT; | ||
1465 | 1428 | ||
1466 | if ((receiver = snd_seq_client_use_ptr(subs.dest.client)) == NULL) | 1429 | if ((receiver = snd_seq_client_use_ptr(subs->dest.client)) == NULL) |
1467 | goto __end; | 1430 | goto __end; |
1468 | if ((sender = snd_seq_client_use_ptr(subs.sender.client)) == NULL) | 1431 | if ((sender = snd_seq_client_use_ptr(subs->sender.client)) == NULL) |
1469 | goto __end; | 1432 | goto __end; |
1470 | if ((sport = snd_seq_port_use_ptr(sender, subs.sender.port)) == NULL) | 1433 | if ((sport = snd_seq_port_use_ptr(sender, subs->sender.port)) == NULL) |
1471 | goto __end; | 1434 | goto __end; |
1472 | if ((dport = snd_seq_port_use_ptr(receiver, subs.dest.port)) == NULL) | 1435 | if ((dport = snd_seq_port_use_ptr(receiver, subs->dest.port)) == NULL) |
1473 | goto __end; | 1436 | goto __end; |
1474 | 1437 | ||
1475 | result = check_subscription_permission(client, sport, dport, &subs); | 1438 | result = check_subscription_permission(client, sport, dport, subs); |
1476 | if (result < 0) | 1439 | if (result < 0) |
1477 | goto __end; | 1440 | goto __end; |
1478 | 1441 | ||
1479 | /* connect them */ | 1442 | /* connect them */ |
1480 | result = snd_seq_port_connect(client, sender, sport, receiver, dport, &subs); | 1443 | result = snd_seq_port_connect(client, sender, sport, receiver, dport, subs); |
1481 | if (! result) /* broadcast announce */ | 1444 | if (! result) /* broadcast announce */ |
1482 | snd_seq_client_notify_subscription(SNDRV_SEQ_ADDRESS_SUBSCRIBERS, 0, | 1445 | snd_seq_client_notify_subscription(SNDRV_SEQ_ADDRESS_SUBSCRIBERS, 0, |
1483 | &subs, SNDRV_SEQ_EVENT_PORT_SUBSCRIBED); | 1446 | subs, SNDRV_SEQ_EVENT_PORT_SUBSCRIBED); |
1484 | __end: | 1447 | __end: |
1485 | if (sport) | 1448 | if (sport) |
1486 | snd_seq_port_unlock(sport); | 1449 | snd_seq_port_unlock(sport); |
@@ -1498,33 +1461,30 @@ static int snd_seq_ioctl_subscribe_port(struct snd_seq_client *client, | |||
1498 | * remove from port's subscription list | 1461 | * remove from port's subscription list |
1499 | */ | 1462 | */ |
1500 | static int snd_seq_ioctl_unsubscribe_port(struct snd_seq_client *client, | 1463 | static int snd_seq_ioctl_unsubscribe_port(struct snd_seq_client *client, |
1501 | void __user *arg) | 1464 | void *arg) |
1502 | { | 1465 | { |
1466 | struct snd_seq_port_subscribe *subs = arg; | ||
1503 | int result = -ENXIO; | 1467 | int result = -ENXIO; |
1504 | struct snd_seq_client *receiver = NULL, *sender = NULL; | 1468 | struct snd_seq_client *receiver = NULL, *sender = NULL; |
1505 | struct snd_seq_client_port *sport = NULL, *dport = NULL; | 1469 | struct snd_seq_client_port *sport = NULL, *dport = NULL; |
1506 | struct snd_seq_port_subscribe subs; | ||
1507 | |||
1508 | if (copy_from_user(&subs, arg, sizeof(subs))) | ||
1509 | return -EFAULT; | ||
1510 | 1470 | ||
1511 | if ((receiver = snd_seq_client_use_ptr(subs.dest.client)) == NULL) | 1471 | if ((receiver = snd_seq_client_use_ptr(subs->dest.client)) == NULL) |
1512 | goto __end; | 1472 | goto __end; |
1513 | if ((sender = snd_seq_client_use_ptr(subs.sender.client)) == NULL) | 1473 | if ((sender = snd_seq_client_use_ptr(subs->sender.client)) == NULL) |
1514 | goto __end; | 1474 | goto __end; |
1515 | if ((sport = snd_seq_port_use_ptr(sender, subs.sender.port)) == NULL) | 1475 | if ((sport = snd_seq_port_use_ptr(sender, subs->sender.port)) == NULL) |
1516 | goto __end; | 1476 | goto __end; |
1517 | if ((dport = snd_seq_port_use_ptr(receiver, subs.dest.port)) == NULL) | 1477 | if ((dport = snd_seq_port_use_ptr(receiver, subs->dest.port)) == NULL) |
1518 | goto __end; | 1478 | goto __end; |
1519 | 1479 | ||
1520 | result = check_subscription_permission(client, sport, dport, &subs); | 1480 | result = check_subscription_permission(client, sport, dport, subs); |
1521 | if (result < 0) | 1481 | if (result < 0) |
1522 | goto __end; | 1482 | goto __end; |
1523 | 1483 | ||
1524 | result = snd_seq_port_disconnect(client, sender, sport, receiver, dport, &subs); | 1484 | result = snd_seq_port_disconnect(client, sender, sport, receiver, dport, subs); |
1525 | if (! result) /* broadcast announce */ | 1485 | if (! result) /* broadcast announce */ |
1526 | snd_seq_client_notify_subscription(SNDRV_SEQ_ADDRESS_SUBSCRIBERS, 0, | 1486 | snd_seq_client_notify_subscription(SNDRV_SEQ_ADDRESS_SUBSCRIBERS, 0, |
1527 | &subs, SNDRV_SEQ_EVENT_PORT_UNSUBSCRIBED); | 1487 | subs, SNDRV_SEQ_EVENT_PORT_UNSUBSCRIBED); |
1528 | __end: | 1488 | __end: |
1529 | if (sport) | 1489 | if (sport) |
1530 | snd_seq_port_unlock(sport); | 1490 | snd_seq_port_unlock(sport); |
@@ -1539,17 +1499,13 @@ static int snd_seq_ioctl_unsubscribe_port(struct snd_seq_client *client, | |||
1539 | 1499 | ||
1540 | 1500 | ||
1541 | /* CREATE_QUEUE ioctl() */ | 1501 | /* CREATE_QUEUE ioctl() */ |
1542 | static int snd_seq_ioctl_create_queue(struct snd_seq_client *client, | 1502 | static int snd_seq_ioctl_create_queue(struct snd_seq_client *client, void *arg) |
1543 | void __user *arg) | ||
1544 | { | 1503 | { |
1545 | struct snd_seq_queue_info info; | 1504 | struct snd_seq_queue_info *info = arg; |
1546 | int result; | 1505 | int result; |
1547 | struct snd_seq_queue *q; | 1506 | struct snd_seq_queue *q; |
1548 | 1507 | ||
1549 | if (copy_from_user(&info, arg, sizeof(info))) | 1508 | result = snd_seq_queue_alloc(client->number, info->locked, info->flags); |
1550 | return -EFAULT; | ||
1551 | |||
1552 | result = snd_seq_queue_alloc(client->number, info.locked, info.flags); | ||
1553 | if (result < 0) | 1509 | if (result < 0) |
1554 | return result; | 1510 | return result; |
1555 | 1511 | ||
@@ -1557,181 +1513,150 @@ static int snd_seq_ioctl_create_queue(struct snd_seq_client *client, | |||
1557 | if (q == NULL) | 1513 | if (q == NULL) |
1558 | return -EINVAL; | 1514 | return -EINVAL; |
1559 | 1515 | ||
1560 | info.queue = q->queue; | 1516 | info->queue = q->queue; |
1561 | info.locked = q->locked; | 1517 | info->locked = q->locked; |
1562 | info.owner = q->owner; | 1518 | info->owner = q->owner; |
1563 | 1519 | ||
1564 | /* set queue name */ | 1520 | /* set queue name */ |
1565 | if (! info.name[0]) | 1521 | if (!info->name[0]) |
1566 | snprintf(info.name, sizeof(info.name), "Queue-%d", q->queue); | 1522 | snprintf(info->name, sizeof(info->name), "Queue-%d", q->queue); |
1567 | strlcpy(q->name, info.name, sizeof(q->name)); | 1523 | strlcpy(q->name, info->name, sizeof(q->name)); |
1568 | queuefree(q); | 1524 | queuefree(q); |
1569 | 1525 | ||
1570 | if (copy_to_user(arg, &info, sizeof(info))) | ||
1571 | return -EFAULT; | ||
1572 | |||
1573 | return 0; | 1526 | return 0; |
1574 | } | 1527 | } |
1575 | 1528 | ||
1576 | /* DELETE_QUEUE ioctl() */ | 1529 | /* DELETE_QUEUE ioctl() */ |
1577 | static int snd_seq_ioctl_delete_queue(struct snd_seq_client *client, | 1530 | static int snd_seq_ioctl_delete_queue(struct snd_seq_client *client, void *arg) |
1578 | void __user *arg) | ||
1579 | { | 1531 | { |
1580 | struct snd_seq_queue_info info; | 1532 | struct snd_seq_queue_info *info = arg; |
1581 | |||
1582 | if (copy_from_user(&info, arg, sizeof(info))) | ||
1583 | return -EFAULT; | ||
1584 | 1533 | ||
1585 | return snd_seq_queue_delete(client->number, info.queue); | 1534 | return snd_seq_queue_delete(client->number, info->queue); |
1586 | } | 1535 | } |
1587 | 1536 | ||
1588 | /* GET_QUEUE_INFO ioctl() */ | 1537 | /* GET_QUEUE_INFO ioctl() */ |
1589 | static int snd_seq_ioctl_get_queue_info(struct snd_seq_client *client, | 1538 | static int snd_seq_ioctl_get_queue_info(struct snd_seq_client *client, |
1590 | void __user *arg) | 1539 | void *arg) |
1591 | { | 1540 | { |
1592 | struct snd_seq_queue_info info; | 1541 | struct snd_seq_queue_info *info = arg; |
1593 | struct snd_seq_queue *q; | 1542 | struct snd_seq_queue *q; |
1594 | 1543 | ||
1595 | if (copy_from_user(&info, arg, sizeof(info))) | 1544 | q = queueptr(info->queue); |
1596 | return -EFAULT; | ||
1597 | |||
1598 | q = queueptr(info.queue); | ||
1599 | if (q == NULL) | 1545 | if (q == NULL) |
1600 | return -EINVAL; | 1546 | return -EINVAL; |
1601 | 1547 | ||
1602 | memset(&info, 0, sizeof(info)); | 1548 | memset(info, 0, sizeof(*info)); |
1603 | info.queue = q->queue; | 1549 | info->queue = q->queue; |
1604 | info.owner = q->owner; | 1550 | info->owner = q->owner; |
1605 | info.locked = q->locked; | 1551 | info->locked = q->locked; |
1606 | strlcpy(info.name, q->name, sizeof(info.name)); | 1552 | strlcpy(info->name, q->name, sizeof(info->name)); |
1607 | queuefree(q); | 1553 | queuefree(q); |
1608 | 1554 | ||
1609 | if (copy_to_user(arg, &info, sizeof(info))) | ||
1610 | return -EFAULT; | ||
1611 | |||
1612 | return 0; | 1555 | return 0; |
1613 | } | 1556 | } |
1614 | 1557 | ||
1615 | /* SET_QUEUE_INFO ioctl() */ | 1558 | /* SET_QUEUE_INFO ioctl() */ |
1616 | static int snd_seq_ioctl_set_queue_info(struct snd_seq_client *client, | 1559 | static int snd_seq_ioctl_set_queue_info(struct snd_seq_client *client, |
1617 | void __user *arg) | 1560 | void *arg) |
1618 | { | 1561 | { |
1619 | struct snd_seq_queue_info info; | 1562 | struct snd_seq_queue_info *info = arg; |
1620 | struct snd_seq_queue *q; | 1563 | struct snd_seq_queue *q; |
1621 | 1564 | ||
1622 | if (copy_from_user(&info, arg, sizeof(info))) | 1565 | if (info->owner != client->number) |
1623 | return -EFAULT; | ||
1624 | |||
1625 | if (info.owner != client->number) | ||
1626 | return -EINVAL; | 1566 | return -EINVAL; |
1627 | 1567 | ||
1628 | /* change owner/locked permission */ | 1568 | /* change owner/locked permission */ |
1629 | if (snd_seq_queue_check_access(info.queue, client->number)) { | 1569 | if (snd_seq_queue_check_access(info->queue, client->number)) { |
1630 | if (snd_seq_queue_set_owner(info.queue, client->number, info.locked) < 0) | 1570 | if (snd_seq_queue_set_owner(info->queue, client->number, info->locked) < 0) |
1631 | return -EPERM; | 1571 | return -EPERM; |
1632 | if (info.locked) | 1572 | if (info->locked) |
1633 | snd_seq_queue_use(info.queue, client->number, 1); | 1573 | snd_seq_queue_use(info->queue, client->number, 1); |
1634 | } else { | 1574 | } else { |
1635 | return -EPERM; | 1575 | return -EPERM; |
1636 | } | 1576 | } |
1637 | 1577 | ||
1638 | q = queueptr(info.queue); | 1578 | q = queueptr(info->queue); |
1639 | if (! q) | 1579 | if (! q) |
1640 | return -EINVAL; | 1580 | return -EINVAL; |
1641 | if (q->owner != client->number) { | 1581 | if (q->owner != client->number) { |
1642 | queuefree(q); | 1582 | queuefree(q); |
1643 | return -EPERM; | 1583 | return -EPERM; |
1644 | } | 1584 | } |
1645 | strlcpy(q->name, info.name, sizeof(q->name)); | 1585 | strlcpy(q->name, info->name, sizeof(q->name)); |
1646 | queuefree(q); | 1586 | queuefree(q); |
1647 | 1587 | ||
1648 | return 0; | 1588 | return 0; |
1649 | } | 1589 | } |
1650 | 1590 | ||
1651 | /* GET_NAMED_QUEUE ioctl() */ | 1591 | /* GET_NAMED_QUEUE ioctl() */ |
1652 | static int snd_seq_ioctl_get_named_queue(struct snd_seq_client *client, void __user *arg) | 1592 | static int snd_seq_ioctl_get_named_queue(struct snd_seq_client *client, |
1593 | void *arg) | ||
1653 | { | 1594 | { |
1654 | struct snd_seq_queue_info info; | 1595 | struct snd_seq_queue_info *info = arg; |
1655 | struct snd_seq_queue *q; | 1596 | struct snd_seq_queue *q; |
1656 | 1597 | ||
1657 | if (copy_from_user(&info, arg, sizeof(info))) | 1598 | q = snd_seq_queue_find_name(info->name); |
1658 | return -EFAULT; | ||
1659 | |||
1660 | q = snd_seq_queue_find_name(info.name); | ||
1661 | if (q == NULL) | 1599 | if (q == NULL) |
1662 | return -EINVAL; | 1600 | return -EINVAL; |
1663 | info.queue = q->queue; | 1601 | info->queue = q->queue; |
1664 | info.owner = q->owner; | 1602 | info->owner = q->owner; |
1665 | info.locked = q->locked; | 1603 | info->locked = q->locked; |
1666 | queuefree(q); | 1604 | queuefree(q); |
1667 | 1605 | ||
1668 | if (copy_to_user(arg, &info, sizeof(info))) | ||
1669 | return -EFAULT; | ||
1670 | |||
1671 | return 0; | 1606 | return 0; |
1672 | } | 1607 | } |
1673 | 1608 | ||
1674 | /* GET_QUEUE_STATUS ioctl() */ | 1609 | /* GET_QUEUE_STATUS ioctl() */ |
1675 | static int snd_seq_ioctl_get_queue_status(struct snd_seq_client *client, | 1610 | static int snd_seq_ioctl_get_queue_status(struct snd_seq_client *client, |
1676 | void __user *arg) | 1611 | void *arg) |
1677 | { | 1612 | { |
1678 | struct snd_seq_queue_status status; | 1613 | struct snd_seq_queue_status *status = arg; |
1679 | struct snd_seq_queue *queue; | 1614 | struct snd_seq_queue *queue; |
1680 | struct snd_seq_timer *tmr; | 1615 | struct snd_seq_timer *tmr; |
1681 | 1616 | ||
1682 | if (copy_from_user(&status, arg, sizeof(status))) | 1617 | queue = queueptr(status->queue); |
1683 | return -EFAULT; | ||
1684 | |||
1685 | queue = queueptr(status.queue); | ||
1686 | if (queue == NULL) | 1618 | if (queue == NULL) |
1687 | return -EINVAL; | 1619 | return -EINVAL; |
1688 | memset(&status, 0, sizeof(status)); | 1620 | memset(status, 0, sizeof(*status)); |
1689 | status.queue = queue->queue; | 1621 | status->queue = queue->queue; |
1690 | 1622 | ||
1691 | tmr = queue->timer; | 1623 | tmr = queue->timer; |
1692 | status.events = queue->tickq->cells + queue->timeq->cells; | 1624 | status->events = queue->tickq->cells + queue->timeq->cells; |
1693 | 1625 | ||
1694 | status.time = snd_seq_timer_get_cur_time(tmr); | 1626 | status->time = snd_seq_timer_get_cur_time(tmr); |
1695 | status.tick = snd_seq_timer_get_cur_tick(tmr); | 1627 | status->tick = snd_seq_timer_get_cur_tick(tmr); |
1696 | 1628 | ||
1697 | status.running = tmr->running; | 1629 | status->running = tmr->running; |
1698 | 1630 | ||
1699 | status.flags = queue->flags; | 1631 | status->flags = queue->flags; |
1700 | queuefree(queue); | 1632 | queuefree(queue); |
1701 | 1633 | ||
1702 | if (copy_to_user(arg, &status, sizeof(status))) | ||
1703 | return -EFAULT; | ||
1704 | return 0; | 1634 | return 0; |
1705 | } | 1635 | } |
1706 | 1636 | ||
1707 | 1637 | ||
1708 | /* GET_QUEUE_TEMPO ioctl() */ | 1638 | /* GET_QUEUE_TEMPO ioctl() */ |
1709 | static int snd_seq_ioctl_get_queue_tempo(struct snd_seq_client *client, | 1639 | static int snd_seq_ioctl_get_queue_tempo(struct snd_seq_client *client, |
1710 | void __user *arg) | 1640 | void *arg) |
1711 | { | 1641 | { |
1712 | struct snd_seq_queue_tempo tempo; | 1642 | struct snd_seq_queue_tempo *tempo = arg; |
1713 | struct snd_seq_queue *queue; | 1643 | struct snd_seq_queue *queue; |
1714 | struct snd_seq_timer *tmr; | 1644 | struct snd_seq_timer *tmr; |
1715 | 1645 | ||
1716 | if (copy_from_user(&tempo, arg, sizeof(tempo))) | 1646 | queue = queueptr(tempo->queue); |
1717 | return -EFAULT; | ||
1718 | |||
1719 | queue = queueptr(tempo.queue); | ||
1720 | if (queue == NULL) | 1647 | if (queue == NULL) |
1721 | return -EINVAL; | 1648 | return -EINVAL; |
1722 | memset(&tempo, 0, sizeof(tempo)); | 1649 | memset(tempo, 0, sizeof(*tempo)); |
1723 | tempo.queue = queue->queue; | 1650 | tempo->queue = queue->queue; |
1724 | 1651 | ||
1725 | tmr = queue->timer; | 1652 | tmr = queue->timer; |
1726 | 1653 | ||
1727 | tempo.tempo = tmr->tempo; | 1654 | tempo->tempo = tmr->tempo; |
1728 | tempo.ppq = tmr->ppq; | 1655 | tempo->ppq = tmr->ppq; |
1729 | tempo.skew_value = tmr->skew; | 1656 | tempo->skew_value = tmr->skew; |
1730 | tempo.skew_base = tmr->skew_base; | 1657 | tempo->skew_base = tmr->skew_base; |
1731 | queuefree(queue); | 1658 | queuefree(queue); |
1732 | 1659 | ||
1733 | if (copy_to_user(arg, &tempo, sizeof(tempo))) | ||
1734 | return -EFAULT; | ||
1735 | return 0; | 1660 | return 0; |
1736 | } | 1661 | } |
1737 | 1662 | ||
@@ -1747,31 +1672,25 @@ int snd_seq_set_queue_tempo(int client, struct snd_seq_queue_tempo *tempo) | |||
1747 | EXPORT_SYMBOL(snd_seq_set_queue_tempo); | 1672 | EXPORT_SYMBOL(snd_seq_set_queue_tempo); |
1748 | 1673 | ||
1749 | static int snd_seq_ioctl_set_queue_tempo(struct snd_seq_client *client, | 1674 | static int snd_seq_ioctl_set_queue_tempo(struct snd_seq_client *client, |
1750 | void __user *arg) | 1675 | void *arg) |
1751 | { | 1676 | { |
1677 | struct snd_seq_queue_tempo *tempo = arg; | ||
1752 | int result; | 1678 | int result; |
1753 | struct snd_seq_queue_tempo tempo; | ||
1754 | |||
1755 | if (copy_from_user(&tempo, arg, sizeof(tempo))) | ||
1756 | return -EFAULT; | ||
1757 | 1679 | ||
1758 | result = snd_seq_set_queue_tempo(client->number, &tempo); | 1680 | result = snd_seq_set_queue_tempo(client->number, tempo); |
1759 | return result < 0 ? result : 0; | 1681 | return result < 0 ? result : 0; |
1760 | } | 1682 | } |
1761 | 1683 | ||
1762 | 1684 | ||
1763 | /* GET_QUEUE_TIMER ioctl() */ | 1685 | /* GET_QUEUE_TIMER ioctl() */ |
1764 | static int snd_seq_ioctl_get_queue_timer(struct snd_seq_client *client, | 1686 | static int snd_seq_ioctl_get_queue_timer(struct snd_seq_client *client, |
1765 | void __user *arg) | 1687 | void *arg) |
1766 | { | 1688 | { |
1767 | struct snd_seq_queue_timer timer; | 1689 | struct snd_seq_queue_timer *timer = arg; |
1768 | struct snd_seq_queue *queue; | 1690 | struct snd_seq_queue *queue; |
1769 | struct snd_seq_timer *tmr; | 1691 | struct snd_seq_timer *tmr; |
1770 | 1692 | ||
1771 | if (copy_from_user(&timer, arg, sizeof(timer))) | 1693 | queue = queueptr(timer->queue); |
1772 | return -EFAULT; | ||
1773 | |||
1774 | queue = queueptr(timer.queue); | ||
1775 | if (queue == NULL) | 1694 | if (queue == NULL) |
1776 | return -EINVAL; | 1695 | return -EINVAL; |
1777 | 1696 | ||
@@ -1780,41 +1699,36 @@ static int snd_seq_ioctl_get_queue_timer(struct snd_seq_client *client, | |||
1780 | return -ERESTARTSYS; | 1699 | return -ERESTARTSYS; |
1781 | } | 1700 | } |
1782 | tmr = queue->timer; | 1701 | tmr = queue->timer; |
1783 | memset(&timer, 0, sizeof(timer)); | 1702 | memset(timer, 0, sizeof(*timer)); |
1784 | timer.queue = queue->queue; | 1703 | timer->queue = queue->queue; |
1785 | 1704 | ||
1786 | timer.type = tmr->type; | 1705 | timer->type = tmr->type; |
1787 | if (tmr->type == SNDRV_SEQ_TIMER_ALSA) { | 1706 | if (tmr->type == SNDRV_SEQ_TIMER_ALSA) { |
1788 | timer.u.alsa.id = tmr->alsa_id; | 1707 | timer->u.alsa.id = tmr->alsa_id; |
1789 | timer.u.alsa.resolution = tmr->preferred_resolution; | 1708 | timer->u.alsa.resolution = tmr->preferred_resolution; |
1790 | } | 1709 | } |
1791 | mutex_unlock(&queue->timer_mutex); | 1710 | mutex_unlock(&queue->timer_mutex); |
1792 | queuefree(queue); | 1711 | queuefree(queue); |
1793 | 1712 | ||
1794 | if (copy_to_user(arg, &timer, sizeof(timer))) | ||
1795 | return -EFAULT; | ||
1796 | return 0; | 1713 | return 0; |
1797 | } | 1714 | } |
1798 | 1715 | ||
1799 | 1716 | ||
1800 | /* SET_QUEUE_TIMER ioctl() */ | 1717 | /* SET_QUEUE_TIMER ioctl() */ |
1801 | static int snd_seq_ioctl_set_queue_timer(struct snd_seq_client *client, | 1718 | static int snd_seq_ioctl_set_queue_timer(struct snd_seq_client *client, |
1802 | void __user *arg) | 1719 | void *arg) |
1803 | { | 1720 | { |
1721 | struct snd_seq_queue_timer *timer = arg; | ||
1804 | int result = 0; | 1722 | int result = 0; |
1805 | struct snd_seq_queue_timer timer; | ||
1806 | |||
1807 | if (copy_from_user(&timer, arg, sizeof(timer))) | ||
1808 | return -EFAULT; | ||
1809 | 1723 | ||
1810 | if (timer.type != SNDRV_SEQ_TIMER_ALSA) | 1724 | if (timer->type != SNDRV_SEQ_TIMER_ALSA) |
1811 | return -EINVAL; | 1725 | return -EINVAL; |
1812 | 1726 | ||
1813 | if (snd_seq_queue_check_access(timer.queue, client->number)) { | 1727 | if (snd_seq_queue_check_access(timer->queue, client->number)) { |
1814 | struct snd_seq_queue *q; | 1728 | struct snd_seq_queue *q; |
1815 | struct snd_seq_timer *tmr; | 1729 | struct snd_seq_timer *tmr; |
1816 | 1730 | ||
1817 | q = queueptr(timer.queue); | 1731 | q = queueptr(timer->queue); |
1818 | if (q == NULL) | 1732 | if (q == NULL) |
1819 | return -ENXIO; | 1733 | return -ENXIO; |
1820 | if (mutex_lock_interruptible(&q->timer_mutex)) { | 1734 | if (mutex_lock_interruptible(&q->timer_mutex)) { |
@@ -1822,13 +1736,13 @@ static int snd_seq_ioctl_set_queue_timer(struct snd_seq_client *client, | |||
1822 | return -ERESTARTSYS; | 1736 | return -ERESTARTSYS; |
1823 | } | 1737 | } |
1824 | tmr = q->timer; | 1738 | tmr = q->timer; |
1825 | snd_seq_queue_timer_close(timer.queue); | 1739 | snd_seq_queue_timer_close(timer->queue); |
1826 | tmr->type = timer.type; | 1740 | tmr->type = timer->type; |
1827 | if (tmr->type == SNDRV_SEQ_TIMER_ALSA) { | 1741 | if (tmr->type == SNDRV_SEQ_TIMER_ALSA) { |
1828 | tmr->alsa_id = timer.u.alsa.id; | 1742 | tmr->alsa_id = timer->u.alsa.id; |
1829 | tmr->preferred_resolution = timer.u.alsa.resolution; | 1743 | tmr->preferred_resolution = timer->u.alsa.resolution; |
1830 | } | 1744 | } |
1831 | result = snd_seq_queue_timer_open(timer.queue); | 1745 | result = snd_seq_queue_timer_open(timer->queue); |
1832 | mutex_unlock(&q->timer_mutex); | 1746 | mutex_unlock(&q->timer_mutex); |
1833 | queuefree(q); | 1747 | queuefree(q); |
1834 | } else { | 1748 | } else { |
@@ -1841,38 +1755,30 @@ static int snd_seq_ioctl_set_queue_timer(struct snd_seq_client *client, | |||
1841 | 1755 | ||
1842 | /* GET_QUEUE_CLIENT ioctl() */ | 1756 | /* GET_QUEUE_CLIENT ioctl() */ |
1843 | static int snd_seq_ioctl_get_queue_client(struct snd_seq_client *client, | 1757 | static int snd_seq_ioctl_get_queue_client(struct snd_seq_client *client, |
1844 | void __user *arg) | 1758 | void *arg) |
1845 | { | 1759 | { |
1846 | struct snd_seq_queue_client info; | 1760 | struct snd_seq_queue_client *info = arg; |
1847 | int used; | 1761 | int used; |
1848 | 1762 | ||
1849 | if (copy_from_user(&info, arg, sizeof(info))) | 1763 | used = snd_seq_queue_is_used(info->queue, client->number); |
1850 | return -EFAULT; | ||
1851 | |||
1852 | used = snd_seq_queue_is_used(info.queue, client->number); | ||
1853 | if (used < 0) | 1764 | if (used < 0) |
1854 | return -EINVAL; | 1765 | return -EINVAL; |
1855 | info.used = used; | 1766 | info->used = used; |
1856 | info.client = client->number; | 1767 | info->client = client->number; |
1857 | 1768 | ||
1858 | if (copy_to_user(arg, &info, sizeof(info))) | ||
1859 | return -EFAULT; | ||
1860 | return 0; | 1769 | return 0; |
1861 | } | 1770 | } |
1862 | 1771 | ||
1863 | 1772 | ||
1864 | /* SET_QUEUE_CLIENT ioctl() */ | 1773 | /* SET_QUEUE_CLIENT ioctl() */ |
1865 | static int snd_seq_ioctl_set_queue_client(struct snd_seq_client *client, | 1774 | static int snd_seq_ioctl_set_queue_client(struct snd_seq_client *client, |
1866 | void __user *arg) | 1775 | void *arg) |
1867 | { | 1776 | { |
1777 | struct snd_seq_queue_client *info = arg; | ||
1868 | int err; | 1778 | int err; |
1869 | struct snd_seq_queue_client info; | ||
1870 | |||
1871 | if (copy_from_user(&info, arg, sizeof(info))) | ||
1872 | return -EFAULT; | ||
1873 | 1779 | ||
1874 | if (info.used >= 0) { | 1780 | if (info->used >= 0) { |
1875 | err = snd_seq_queue_use(info.queue, client->number, info.used); | 1781 | err = snd_seq_queue_use(info->queue, client->number, info->used); |
1876 | if (err < 0) | 1782 | if (err < 0) |
1877 | return err; | 1783 | return err; |
1878 | } | 1784 | } |
@@ -1883,78 +1789,70 @@ static int snd_seq_ioctl_set_queue_client(struct snd_seq_client *client, | |||
1883 | 1789 | ||
1884 | /* GET_CLIENT_POOL ioctl() */ | 1790 | /* GET_CLIENT_POOL ioctl() */ |
1885 | static int snd_seq_ioctl_get_client_pool(struct snd_seq_client *client, | 1791 | static int snd_seq_ioctl_get_client_pool(struct snd_seq_client *client, |
1886 | void __user *arg) | 1792 | void *arg) |
1887 | { | 1793 | { |
1888 | struct snd_seq_client_pool info; | 1794 | struct snd_seq_client_pool *info = arg; |
1889 | struct snd_seq_client *cptr; | 1795 | struct snd_seq_client *cptr; |
1890 | 1796 | ||
1891 | if (copy_from_user(&info, arg, sizeof(info))) | 1797 | cptr = snd_seq_client_use_ptr(info->client); |
1892 | return -EFAULT; | ||
1893 | |||
1894 | cptr = snd_seq_client_use_ptr(info.client); | ||
1895 | if (cptr == NULL) | 1798 | if (cptr == NULL) |
1896 | return -ENOENT; | 1799 | return -ENOENT; |
1897 | memset(&info, 0, sizeof(info)); | 1800 | memset(info, 0, sizeof(*info)); |
1898 | info.client = cptr->number; | 1801 | info->client = cptr->number; |
1899 | info.output_pool = cptr->pool->size; | 1802 | info->output_pool = cptr->pool->size; |
1900 | info.output_room = cptr->pool->room; | 1803 | info->output_room = cptr->pool->room; |
1901 | info.output_free = info.output_pool; | 1804 | info->output_free = info->output_pool; |
1902 | info.output_free = snd_seq_unused_cells(cptr->pool); | 1805 | info->output_free = snd_seq_unused_cells(cptr->pool); |
1903 | if (cptr->type == USER_CLIENT) { | 1806 | if (cptr->type == USER_CLIENT) { |
1904 | info.input_pool = cptr->data.user.fifo_pool_size; | 1807 | info->input_pool = cptr->data.user.fifo_pool_size; |
1905 | info.input_free = info.input_pool; | 1808 | info->input_free = info->input_pool; |
1906 | if (cptr->data.user.fifo) | 1809 | if (cptr->data.user.fifo) |
1907 | info.input_free = snd_seq_unused_cells(cptr->data.user.fifo->pool); | 1810 | info->input_free = snd_seq_unused_cells(cptr->data.user.fifo->pool); |
1908 | } else { | 1811 | } else { |
1909 | info.input_pool = 0; | 1812 | info->input_pool = 0; |
1910 | info.input_free = 0; | 1813 | info->input_free = 0; |
1911 | } | 1814 | } |
1912 | snd_seq_client_unlock(cptr); | 1815 | snd_seq_client_unlock(cptr); |
1913 | 1816 | ||
1914 | if (copy_to_user(arg, &info, sizeof(info))) | ||
1915 | return -EFAULT; | ||
1916 | return 0; | 1817 | return 0; |
1917 | } | 1818 | } |
1918 | 1819 | ||
1919 | /* SET_CLIENT_POOL ioctl() */ | 1820 | /* SET_CLIENT_POOL ioctl() */ |
1920 | static int snd_seq_ioctl_set_client_pool(struct snd_seq_client *client, | 1821 | static int snd_seq_ioctl_set_client_pool(struct snd_seq_client *client, |
1921 | void __user *arg) | 1822 | void *arg) |
1922 | { | 1823 | { |
1923 | struct snd_seq_client_pool info; | 1824 | struct snd_seq_client_pool *info = arg; |
1924 | int rc; | 1825 | int rc; |
1925 | 1826 | ||
1926 | if (copy_from_user(&info, arg, sizeof(info))) | 1827 | if (client->number != info->client) |
1927 | return -EFAULT; | ||
1928 | |||
1929 | if (client->number != info.client) | ||
1930 | return -EINVAL; /* can't change other clients */ | 1828 | return -EINVAL; /* can't change other clients */ |
1931 | 1829 | ||
1932 | if (info.output_pool >= 1 && info.output_pool <= SNDRV_SEQ_MAX_EVENTS && | 1830 | if (info->output_pool >= 1 && info->output_pool <= SNDRV_SEQ_MAX_EVENTS && |
1933 | (! snd_seq_write_pool_allocated(client) || | 1831 | (! snd_seq_write_pool_allocated(client) || |
1934 | info.output_pool != client->pool->size)) { | 1832 | info->output_pool != client->pool->size)) { |
1935 | if (snd_seq_write_pool_allocated(client)) { | 1833 | if (snd_seq_write_pool_allocated(client)) { |
1936 | /* remove all existing cells */ | 1834 | /* remove all existing cells */ |
1937 | snd_seq_queue_client_leave_cells(client->number); | 1835 | snd_seq_queue_client_leave_cells(client->number); |
1938 | snd_seq_pool_done(client->pool); | 1836 | snd_seq_pool_done(client->pool); |
1939 | } | 1837 | } |
1940 | client->pool->size = info.output_pool; | 1838 | client->pool->size = info->output_pool; |
1941 | rc = snd_seq_pool_init(client->pool); | 1839 | rc = snd_seq_pool_init(client->pool); |
1942 | if (rc < 0) | 1840 | if (rc < 0) |
1943 | return rc; | 1841 | return rc; |
1944 | } | 1842 | } |
1945 | if (client->type == USER_CLIENT && client->data.user.fifo != NULL && | 1843 | if (client->type == USER_CLIENT && client->data.user.fifo != NULL && |
1946 | info.input_pool >= 1 && | 1844 | info->input_pool >= 1 && |
1947 | info.input_pool <= SNDRV_SEQ_MAX_CLIENT_EVENTS && | 1845 | info->input_pool <= SNDRV_SEQ_MAX_CLIENT_EVENTS && |
1948 | info.input_pool != client->data.user.fifo_pool_size) { | 1846 | info->input_pool != client->data.user.fifo_pool_size) { |
1949 | /* change pool size */ | 1847 | /* change pool size */ |
1950 | rc = snd_seq_fifo_resize(client->data.user.fifo, info.input_pool); | 1848 | rc = snd_seq_fifo_resize(client->data.user.fifo, info->input_pool); |
1951 | if (rc < 0) | 1849 | if (rc < 0) |
1952 | return rc; | 1850 | return rc; |
1953 | client->data.user.fifo_pool_size = info.input_pool; | 1851 | client->data.user.fifo_pool_size = info->input_pool; |
1954 | } | 1852 | } |
1955 | if (info.output_room >= 1 && | 1853 | if (info->output_room >= 1 && |
1956 | info.output_room <= client->pool->size) { | 1854 | info->output_room <= client->pool->size) { |
1957 | client->pool->room = info.output_room; | 1855 | client->pool->room = info->output_room; |
1958 | } | 1856 | } |
1959 | 1857 | ||
1960 | return snd_seq_ioctl_get_client_pool(client, arg); | 1858 | return snd_seq_ioctl_get_client_pool(client, arg); |
@@ -1963,17 +1861,14 @@ static int snd_seq_ioctl_set_client_pool(struct snd_seq_client *client, | |||
1963 | 1861 | ||
1964 | /* REMOVE_EVENTS ioctl() */ | 1862 | /* REMOVE_EVENTS ioctl() */ |
1965 | static int snd_seq_ioctl_remove_events(struct snd_seq_client *client, | 1863 | static int snd_seq_ioctl_remove_events(struct snd_seq_client *client, |
1966 | void __user *arg) | 1864 | void *arg) |
1967 | { | 1865 | { |
1968 | struct snd_seq_remove_events info; | 1866 | struct snd_seq_remove_events *info = arg; |
1969 | |||
1970 | if (copy_from_user(&info, arg, sizeof(info))) | ||
1971 | return -EFAULT; | ||
1972 | 1867 | ||
1973 | /* | 1868 | /* |
1974 | * Input mostly not implemented XXX. | 1869 | * Input mostly not implemented XXX. |
1975 | */ | 1870 | */ |
1976 | if (info.remove_mode & SNDRV_SEQ_REMOVE_INPUT) { | 1871 | if (info->remove_mode & SNDRV_SEQ_REMOVE_INPUT) { |
1977 | /* | 1872 | /* |
1978 | * No restrictions so for a user client we can clear | 1873 | * No restrictions so for a user client we can clear |
1979 | * the whole fifo | 1874 | * the whole fifo |
@@ -1982,8 +1877,8 @@ static int snd_seq_ioctl_remove_events(struct snd_seq_client *client, | |||
1982 | snd_seq_fifo_clear(client->data.user.fifo); | 1877 | snd_seq_fifo_clear(client->data.user.fifo); |
1983 | } | 1878 | } |
1984 | 1879 | ||
1985 | if (info.remove_mode & SNDRV_SEQ_REMOVE_OUTPUT) | 1880 | if (info->remove_mode & SNDRV_SEQ_REMOVE_OUTPUT) |
1986 | snd_seq_queue_remove_cells(client->number, &info); | 1881 | snd_seq_queue_remove_cells(client->number, info); |
1987 | 1882 | ||
1988 | return 0; | 1883 | return 0; |
1989 | } | 1884 | } |
@@ -1993,26 +1888,23 @@ static int snd_seq_ioctl_remove_events(struct snd_seq_client *client, | |||
1993 | * get subscription info | 1888 | * get subscription info |
1994 | */ | 1889 | */ |
1995 | static int snd_seq_ioctl_get_subscription(struct snd_seq_client *client, | 1890 | static int snd_seq_ioctl_get_subscription(struct snd_seq_client *client, |
1996 | void __user *arg) | 1891 | void *arg) |
1997 | { | 1892 | { |
1893 | struct snd_seq_port_subscribe *subs = arg; | ||
1998 | int result; | 1894 | int result; |
1999 | struct snd_seq_client *sender = NULL; | 1895 | struct snd_seq_client *sender = NULL; |
2000 | struct snd_seq_client_port *sport = NULL; | 1896 | struct snd_seq_client_port *sport = NULL; |
2001 | struct snd_seq_port_subscribe subs; | ||
2002 | struct snd_seq_subscribers *p; | 1897 | struct snd_seq_subscribers *p; |
2003 | 1898 | ||
2004 | if (copy_from_user(&subs, arg, sizeof(subs))) | ||
2005 | return -EFAULT; | ||
2006 | |||
2007 | result = -EINVAL; | 1899 | result = -EINVAL; |
2008 | if ((sender = snd_seq_client_use_ptr(subs.sender.client)) == NULL) | 1900 | if ((sender = snd_seq_client_use_ptr(subs->sender.client)) == NULL) |
2009 | goto __end; | 1901 | goto __end; |
2010 | if ((sport = snd_seq_port_use_ptr(sender, subs.sender.port)) == NULL) | 1902 | if ((sport = snd_seq_port_use_ptr(sender, subs->sender.port)) == NULL) |
2011 | goto __end; | 1903 | goto __end; |
2012 | p = snd_seq_port_get_subscription(&sport->c_src, &subs.dest); | 1904 | p = snd_seq_port_get_subscription(&sport->c_src, &subs->dest); |
2013 | if (p) { | 1905 | if (p) { |
2014 | result = 0; | 1906 | result = 0; |
2015 | subs = p->info; | 1907 | *subs = p->info; |
2016 | } else | 1908 | } else |
2017 | result = -ENOENT; | 1909 | result = -ENOENT; |
2018 | 1910 | ||
@@ -2021,10 +1913,7 @@ static int snd_seq_ioctl_get_subscription(struct snd_seq_client *client, | |||
2021 | snd_seq_port_unlock(sport); | 1913 | snd_seq_port_unlock(sport); |
2022 | if (sender) | 1914 | if (sender) |
2023 | snd_seq_client_unlock(sender); | 1915 | snd_seq_client_unlock(sender); |
2024 | if (result >= 0) { | 1916 | |
2025 | if (copy_to_user(arg, &subs, sizeof(subs))) | ||
2026 | return -EFAULT; | ||
2027 | } | ||
2028 | return result; | 1917 | return result; |
2029 | } | 1918 | } |
2030 | 1919 | ||
@@ -2032,26 +1921,22 @@ static int snd_seq_ioctl_get_subscription(struct snd_seq_client *client, | |||
2032 | /* | 1921 | /* |
2033 | * get subscription info - check only its presence | 1922 | * get subscription info - check only its presence |
2034 | */ | 1923 | */ |
2035 | static int snd_seq_ioctl_query_subs(struct snd_seq_client *client, | 1924 | static int snd_seq_ioctl_query_subs(struct snd_seq_client *client, void *arg) |
2036 | void __user *arg) | ||
2037 | { | 1925 | { |
1926 | struct snd_seq_query_subs *subs = arg; | ||
2038 | int result = -ENXIO; | 1927 | int result = -ENXIO; |
2039 | struct snd_seq_client *cptr = NULL; | 1928 | struct snd_seq_client *cptr = NULL; |
2040 | struct snd_seq_client_port *port = NULL; | 1929 | struct snd_seq_client_port *port = NULL; |
2041 | struct snd_seq_query_subs subs; | ||
2042 | struct snd_seq_port_subs_info *group; | 1930 | struct snd_seq_port_subs_info *group; |
2043 | struct list_head *p; | 1931 | struct list_head *p; |
2044 | int i; | 1932 | int i; |
2045 | 1933 | ||
2046 | if (copy_from_user(&subs, arg, sizeof(subs))) | 1934 | if ((cptr = snd_seq_client_use_ptr(subs->root.client)) == NULL) |
2047 | return -EFAULT; | ||
2048 | |||
2049 | if ((cptr = snd_seq_client_use_ptr(subs.root.client)) == NULL) | ||
2050 | goto __end; | 1935 | goto __end; |
2051 | if ((port = snd_seq_port_use_ptr(cptr, subs.root.port)) == NULL) | 1936 | if ((port = snd_seq_port_use_ptr(cptr, subs->root.port)) == NULL) |
2052 | goto __end; | 1937 | goto __end; |
2053 | 1938 | ||
2054 | switch (subs.type) { | 1939 | switch (subs->type) { |
2055 | case SNDRV_SEQ_QUERY_SUBS_READ: | 1940 | case SNDRV_SEQ_QUERY_SUBS_READ: |
2056 | group = &port->c_src; | 1941 | group = &port->c_src; |
2057 | break; | 1942 | break; |
@@ -2064,22 +1949,22 @@ static int snd_seq_ioctl_query_subs(struct snd_seq_client *client, | |||
2064 | 1949 | ||
2065 | down_read(&group->list_mutex); | 1950 | down_read(&group->list_mutex); |
2066 | /* search for the subscriber */ | 1951 | /* search for the subscriber */ |
2067 | subs.num_subs = group->count; | 1952 | subs->num_subs = group->count; |
2068 | i = 0; | 1953 | i = 0; |
2069 | result = -ENOENT; | 1954 | result = -ENOENT; |
2070 | list_for_each(p, &group->list_head) { | 1955 | list_for_each(p, &group->list_head) { |
2071 | if (i++ == subs.index) { | 1956 | if (i++ == subs->index) { |
2072 | /* found! */ | 1957 | /* found! */ |
2073 | struct snd_seq_subscribers *s; | 1958 | struct snd_seq_subscribers *s; |
2074 | if (subs.type == SNDRV_SEQ_QUERY_SUBS_READ) { | 1959 | if (subs->type == SNDRV_SEQ_QUERY_SUBS_READ) { |
2075 | s = list_entry(p, struct snd_seq_subscribers, src_list); | 1960 | s = list_entry(p, struct snd_seq_subscribers, src_list); |
2076 | subs.addr = s->info.dest; | 1961 | subs->addr = s->info.dest; |
2077 | } else { | 1962 | } else { |
2078 | s = list_entry(p, struct snd_seq_subscribers, dest_list); | 1963 | s = list_entry(p, struct snd_seq_subscribers, dest_list); |
2079 | subs.addr = s->info.sender; | 1964 | subs->addr = s->info.sender; |
2080 | } | 1965 | } |
2081 | subs.flags = s->info.flags; | 1966 | subs->flags = s->info.flags; |
2082 | subs.queue = s->info.queue; | 1967 | subs->queue = s->info.queue; |
2083 | result = 0; | 1968 | result = 0; |
2084 | break; | 1969 | break; |
2085 | } | 1970 | } |
@@ -2091,10 +1976,7 @@ static int snd_seq_ioctl_query_subs(struct snd_seq_client *client, | |||
2091 | snd_seq_port_unlock(port); | 1976 | snd_seq_port_unlock(port); |
2092 | if (cptr) | 1977 | if (cptr) |
2093 | snd_seq_client_unlock(cptr); | 1978 | snd_seq_client_unlock(cptr); |
2094 | if (result >= 0) { | 1979 | |
2095 | if (copy_to_user(arg, &subs, sizeof(subs))) | ||
2096 | return -EFAULT; | ||
2097 | } | ||
2098 | return result; | 1980 | return result; |
2099 | } | 1981 | } |
2100 | 1982 | ||
@@ -2103,31 +1985,26 @@ static int snd_seq_ioctl_query_subs(struct snd_seq_client *client, | |||
2103 | * query next client | 1985 | * query next client |
2104 | */ | 1986 | */ |
2105 | static int snd_seq_ioctl_query_next_client(struct snd_seq_client *client, | 1987 | static int snd_seq_ioctl_query_next_client(struct snd_seq_client *client, |
2106 | void __user *arg) | 1988 | void *arg) |
2107 | { | 1989 | { |
1990 | struct snd_seq_client_info *info = arg; | ||
2108 | struct snd_seq_client *cptr = NULL; | 1991 | struct snd_seq_client *cptr = NULL; |
2109 | struct snd_seq_client_info info; | ||
2110 | |||
2111 | if (copy_from_user(&info, arg, sizeof(info))) | ||
2112 | return -EFAULT; | ||
2113 | 1992 | ||
2114 | /* search for next client */ | 1993 | /* search for next client */ |
2115 | info.client++; | 1994 | info->client++; |
2116 | if (info.client < 0) | 1995 | if (info->client < 0) |
2117 | info.client = 0; | 1996 | info->client = 0; |
2118 | for (; info.client < SNDRV_SEQ_MAX_CLIENTS; info.client++) { | 1997 | for (; info->client < SNDRV_SEQ_MAX_CLIENTS; info->client++) { |
2119 | cptr = snd_seq_client_use_ptr(info.client); | 1998 | cptr = snd_seq_client_use_ptr(info->client); |
2120 | if (cptr) | 1999 | if (cptr) |
2121 | break; /* found */ | 2000 | break; /* found */ |
2122 | } | 2001 | } |
2123 | if (cptr == NULL) | 2002 | if (cptr == NULL) |
2124 | return -ENOENT; | 2003 | return -ENOENT; |
2125 | 2004 | ||
2126 | get_client_info(cptr, &info); | 2005 | get_client_info(cptr, info); |
2127 | snd_seq_client_unlock(cptr); | 2006 | snd_seq_client_unlock(cptr); |
2128 | 2007 | ||
2129 | if (copy_to_user(arg, &info, sizeof(info))) | ||
2130 | return -EFAULT; | ||
2131 | return 0; | 2008 | return 0; |
2132 | } | 2009 | } |
2133 | 2010 | ||
@@ -2135,43 +2012,41 @@ static int snd_seq_ioctl_query_next_client(struct snd_seq_client *client, | |||
2135 | * query next port | 2012 | * query next port |
2136 | */ | 2013 | */ |
2137 | static int snd_seq_ioctl_query_next_port(struct snd_seq_client *client, | 2014 | static int snd_seq_ioctl_query_next_port(struct snd_seq_client *client, |
2138 | void __user *arg) | 2015 | void *arg) |
2139 | { | 2016 | { |
2017 | struct snd_seq_port_info *info = arg; | ||
2140 | struct snd_seq_client *cptr; | 2018 | struct snd_seq_client *cptr; |
2141 | struct snd_seq_client_port *port = NULL; | 2019 | struct snd_seq_client_port *port = NULL; |
2142 | struct snd_seq_port_info info; | ||
2143 | 2020 | ||
2144 | if (copy_from_user(&info, arg, sizeof(info))) | 2021 | cptr = snd_seq_client_use_ptr(info->addr.client); |
2145 | return -EFAULT; | ||
2146 | cptr = snd_seq_client_use_ptr(info.addr.client); | ||
2147 | if (cptr == NULL) | 2022 | if (cptr == NULL) |
2148 | return -ENXIO; | 2023 | return -ENXIO; |
2149 | 2024 | ||
2150 | /* search for next port */ | 2025 | /* search for next port */ |
2151 | info.addr.port++; | 2026 | info->addr.port++; |
2152 | port = snd_seq_port_query_nearest(cptr, &info); | 2027 | port = snd_seq_port_query_nearest(cptr, info); |
2153 | if (port == NULL) { | 2028 | if (port == NULL) { |
2154 | snd_seq_client_unlock(cptr); | 2029 | snd_seq_client_unlock(cptr); |
2155 | return -ENOENT; | 2030 | return -ENOENT; |
2156 | } | 2031 | } |
2157 | 2032 | ||
2158 | /* get port info */ | 2033 | /* get port info */ |
2159 | info.addr = port->addr; | 2034 | info->addr = port->addr; |
2160 | snd_seq_get_port_info(port, &info); | 2035 | snd_seq_get_port_info(port, info); |
2161 | snd_seq_port_unlock(port); | 2036 | snd_seq_port_unlock(port); |
2162 | snd_seq_client_unlock(cptr); | 2037 | snd_seq_client_unlock(cptr); |
2163 | 2038 | ||
2164 | if (copy_to_user(arg, &info, sizeof(info))) | ||
2165 | return -EFAULT; | ||
2166 | return 0; | 2039 | return 0; |
2167 | } | 2040 | } |
2168 | 2041 | ||
2169 | /* -------------------------------------------------------- */ | 2042 | /* -------------------------------------------------------- */ |
2170 | 2043 | ||
2171 | static struct seq_ioctl_table { | 2044 | static const struct ioctl_handler { |
2172 | unsigned int cmd; | 2045 | unsigned int cmd; |
2173 | int (*func)(struct snd_seq_client *client, void __user * arg); | 2046 | int (*func)(struct snd_seq_client *client, void *arg); |
2174 | } ioctl_tables[] = { | 2047 | } ioctl_handlers[] = { |
2048 | { SNDRV_SEQ_IOCTL_PVERSION, snd_seq_ioctl_pversion }, | ||
2049 | { SNDRV_SEQ_IOCTL_CLIENT_ID, snd_seq_ioctl_client_id }, | ||
2175 | { SNDRV_SEQ_IOCTL_SYSTEM_INFO, snd_seq_ioctl_system_info }, | 2050 | { SNDRV_SEQ_IOCTL_SYSTEM_INFO, snd_seq_ioctl_system_info }, |
2176 | { SNDRV_SEQ_IOCTL_RUNNING_MODE, snd_seq_ioctl_running_mode }, | 2051 | { SNDRV_SEQ_IOCTL_RUNNING_MODE, snd_seq_ioctl_running_mode }, |
2177 | { SNDRV_SEQ_IOCTL_GET_CLIENT_INFO, snd_seq_ioctl_get_client_info }, | 2052 | { SNDRV_SEQ_IOCTL_GET_CLIENT_INFO, snd_seq_ioctl_get_client_info }, |
@@ -2204,40 +2079,65 @@ static struct seq_ioctl_table { | |||
2204 | { 0, NULL }, | 2079 | { 0, NULL }, |
2205 | }; | 2080 | }; |
2206 | 2081 | ||
2207 | static int snd_seq_do_ioctl(struct snd_seq_client *client, unsigned int cmd, | 2082 | static long snd_seq_ioctl(struct file *file, unsigned int cmd, |
2208 | void __user *arg) | 2083 | unsigned long arg) |
2209 | { | 2084 | { |
2210 | struct seq_ioctl_table *p; | 2085 | struct snd_seq_client *client = file->private_data; |
2086 | /* To use kernel stack for ioctl data. */ | ||
2087 | union { | ||
2088 | int pversion; | ||
2089 | int client_id; | ||
2090 | struct snd_seq_system_info system_info; | ||
2091 | struct snd_seq_running_info running_info; | ||
2092 | struct snd_seq_client_info client_info; | ||
2093 | struct snd_seq_port_info port_info; | ||
2094 | struct snd_seq_port_subscribe port_subscribe; | ||
2095 | struct snd_seq_queue_info queue_info; | ||
2096 | struct snd_seq_queue_status queue_status; | ||
2097 | struct snd_seq_queue_tempo tempo; | ||
2098 | struct snd_seq_queue_timer queue_timer; | ||
2099 | struct snd_seq_queue_client queue_client; | ||
2100 | struct snd_seq_client_pool client_pool; | ||
2101 | struct snd_seq_remove_events remove_events; | ||
2102 | struct snd_seq_query_subs query_subs; | ||
2103 | } buf; | ||
2104 | const struct ioctl_handler *handler; | ||
2105 | unsigned long size; | ||
2106 | int err; | ||
2211 | 2107 | ||
2212 | switch (cmd) { | 2108 | if (snd_BUG_ON(!client)) |
2213 | case SNDRV_SEQ_IOCTL_PVERSION: | 2109 | return -ENXIO; |
2214 | /* return sequencer version number */ | ||
2215 | return put_user(SNDRV_SEQ_VERSION, (int __user *)arg) ? -EFAULT : 0; | ||
2216 | case SNDRV_SEQ_IOCTL_CLIENT_ID: | ||
2217 | /* return the id of this client */ | ||
2218 | return put_user(client->number, (int __user *)arg) ? -EFAULT : 0; | ||
2219 | } | ||
2220 | 2110 | ||
2221 | if (! arg) | 2111 | for (handler = ioctl_handlers; handler->cmd > 0; ++handler) { |
2222 | return -EFAULT; | 2112 | if (handler->cmd == cmd) |
2223 | for (p = ioctl_tables; p->cmd; p++) { | 2113 | break; |
2224 | if (p->cmd == cmd) | ||
2225 | return p->func(client, arg); | ||
2226 | } | 2114 | } |
2227 | pr_debug("ALSA: seq unknown ioctl() 0x%x (type='%c', number=0x%02x)\n", | 2115 | if (handler->cmd == 0) |
2228 | cmd, _IOC_TYPE(cmd), _IOC_NR(cmd)); | 2116 | return -ENOTTY; |
2229 | return -ENOTTY; | ||
2230 | } | ||
2231 | 2117 | ||
2118 | memset(&buf, 0, sizeof(buf)); | ||
2232 | 2119 | ||
2233 | static long snd_seq_ioctl(struct file *file, unsigned int cmd, unsigned long arg) | 2120 | /* |
2234 | { | 2121 | * All of ioctl commands for ALSA sequencer get an argument of size |
2235 | struct snd_seq_client *client = file->private_data; | 2122 | * within 13 bits. We can safely pick up the size from the command. |
2123 | */ | ||
2124 | size = _IOC_SIZE(handler->cmd); | ||
2125 | if (handler->cmd & IOC_IN) { | ||
2126 | if (copy_from_user(&buf, (const void __user *)arg, size)) | ||
2127 | return -EFAULT; | ||
2128 | } | ||
2236 | 2129 | ||
2237 | if (snd_BUG_ON(!client)) | 2130 | err = handler->func(client, &buf); |
2238 | return -ENXIO; | 2131 | if (err >= 0) { |
2239 | 2132 | /* Some commands includes a bug in 'dir' field. */ | |
2240 | return snd_seq_do_ioctl(client, cmd, (void __user *) arg); | 2133 | if (handler->cmd == SNDRV_SEQ_IOCTL_SET_QUEUE_CLIENT || |
2134 | handler->cmd == SNDRV_SEQ_IOCTL_SET_CLIENT_POOL || | ||
2135 | (handler->cmd & IOC_OUT)) | ||
2136 | if (copy_to_user((void __user *)arg, &buf, size)) | ||
2137 | return -EFAULT; | ||
2138 | } | ||
2139 | |||
2140 | return err; | ||
2241 | } | 2141 | } |
2242 | 2142 | ||
2243 | #ifdef CONFIG_COMPAT | 2143 | #ifdef CONFIG_COMPAT |
@@ -2423,23 +2323,35 @@ int snd_seq_kernel_client_dispatch(int client, struct snd_seq_event * ev, | |||
2423 | 2323 | ||
2424 | EXPORT_SYMBOL(snd_seq_kernel_client_dispatch); | 2324 | EXPORT_SYMBOL(snd_seq_kernel_client_dispatch); |
2425 | 2325 | ||
2426 | /* | 2326 | /** |
2427 | * exported, called by kernel clients to perform same functions as with | 2327 | * snd_seq_kernel_client_ctl - operate a command for a client with data in |
2428 | * userland ioctl() | 2328 | * kernel space. |
2329 | * @clientid: A numerical ID for a client. | ||
2330 | * @cmd: An ioctl(2) command for ALSA sequencer operation. | ||
2331 | * @arg: A pointer to data in kernel space. | ||
2332 | * | ||
2333 | * Against its name, both kernel/application client can be handled by this | ||
2334 | * kernel API. A pointer of 'arg' argument should be in kernel space. | ||
2335 | * | ||
2336 | * Return: 0 at success. Negative error code at failure. | ||
2429 | */ | 2337 | */ |
2430 | int snd_seq_kernel_client_ctl(int clientid, unsigned int cmd, void *arg) | 2338 | int snd_seq_kernel_client_ctl(int clientid, unsigned int cmd, void *arg) |
2431 | { | 2339 | { |
2340 | const struct ioctl_handler *handler; | ||
2432 | struct snd_seq_client *client; | 2341 | struct snd_seq_client *client; |
2433 | mm_segment_t fs; | ||
2434 | int result; | ||
2435 | 2342 | ||
2436 | client = clientptr(clientid); | 2343 | client = clientptr(clientid); |
2437 | if (client == NULL) | 2344 | if (client == NULL) |
2438 | return -ENXIO; | 2345 | return -ENXIO; |
2439 | fs = snd_enter_user(); | 2346 | |
2440 | result = snd_seq_do_ioctl(client, cmd, (void __force __user *)arg); | 2347 | for (handler = ioctl_handlers; handler->cmd > 0; ++handler) { |
2441 | snd_leave_user(fs); | 2348 | if (handler->cmd == cmd) |
2442 | return result; | 2349 | return handler->func(client, arg); |
2350 | } | ||
2351 | |||
2352 | pr_debug("ALSA: seq unknown ioctl() 0x%x (type='%c', number=0x%02x)\n", | ||
2353 | cmd, _IOC_TYPE(cmd), _IOC_NR(cmd)); | ||
2354 | return -ENOTTY; | ||
2443 | } | 2355 | } |
2444 | 2356 | ||
2445 | EXPORT_SYMBOL(snd_seq_kernel_client_ctl); | 2357 | EXPORT_SYMBOL(snd_seq_kernel_client_ctl); |
diff --git a/sound/core/seq/seq_compat.c b/sound/core/seq/seq_compat.c index 65175902a68a..fce5697e4261 100644 --- a/sound/core/seq/seq_compat.c +++ b/sound/core/seq/seq_compat.c | |||
@@ -47,7 +47,6 @@ static int snd_seq_call_port_info_ioctl(struct snd_seq_client *client, unsigned | |||
47 | { | 47 | { |
48 | int err = -EFAULT; | 48 | int err = -EFAULT; |
49 | struct snd_seq_port_info *data; | 49 | struct snd_seq_port_info *data; |
50 | mm_segment_t fs; | ||
51 | 50 | ||
52 | data = kmalloc(sizeof(*data), GFP_KERNEL); | 51 | data = kmalloc(sizeof(*data), GFP_KERNEL); |
53 | if (!data) | 52 | if (!data) |
@@ -59,9 +58,7 @@ static int snd_seq_call_port_info_ioctl(struct snd_seq_client *client, unsigned | |||
59 | goto error; | 58 | goto error; |
60 | data->kernel = NULL; | 59 | data->kernel = NULL; |
61 | 60 | ||
62 | fs = snd_enter_user(); | 61 | err = snd_seq_kernel_client_ctl(client->number, cmd, &data); |
63 | err = snd_seq_do_ioctl(client, cmd, data); | ||
64 | snd_leave_user(fs); | ||
65 | if (err < 0) | 62 | if (err < 0) |
66 | goto error; | 63 | goto error; |
67 | 64 | ||
@@ -123,7 +120,7 @@ static long snd_seq_ioctl_compat(struct file *file, unsigned int cmd, unsigned l | |||
123 | case SNDRV_SEQ_IOCTL_GET_SUBSCRIPTION: | 120 | case SNDRV_SEQ_IOCTL_GET_SUBSCRIPTION: |
124 | case SNDRV_SEQ_IOCTL_QUERY_NEXT_CLIENT: | 121 | case SNDRV_SEQ_IOCTL_QUERY_NEXT_CLIENT: |
125 | case SNDRV_SEQ_IOCTL_RUNNING_MODE: | 122 | case SNDRV_SEQ_IOCTL_RUNNING_MODE: |
126 | return snd_seq_do_ioctl(client, cmd, argp); | 123 | return snd_seq_ioctl(file, cmd, arg); |
127 | case SNDRV_SEQ_IOCTL_CREATE_PORT32: | 124 | case SNDRV_SEQ_IOCTL_CREATE_PORT32: |
128 | return snd_seq_call_port_info_ioctl(client, SNDRV_SEQ_IOCTL_CREATE_PORT, argp); | 125 | return snd_seq_call_port_info_ioctl(client, SNDRV_SEQ_IOCTL_CREATE_PORT, argp); |
129 | case SNDRV_SEQ_IOCTL_DELETE_PORT32: | 126 | case SNDRV_SEQ_IOCTL_DELETE_PORT32: |
diff --git a/sound/firewire/bebob/Makefile b/sound/firewire/bebob/Makefile index af7ed6643266..dd454867240d 100644 --- a/sound/firewire/bebob/Makefile +++ b/sound/firewire/bebob/Makefile | |||
@@ -1,4 +1,5 @@ | |||
1 | snd-bebob-objs := bebob_command.o bebob_stream.o bebob_proc.o bebob_midi.o \ | 1 | snd-bebob-objs := bebob_command.o bebob_stream.o bebob_proc.o bebob_midi.o \ |
2 | bebob_pcm.o bebob_hwdep.o bebob_terratec.o bebob_yamaha.o \ | 2 | bebob_pcm.o bebob_hwdep.o bebob_terratec.o \ |
3 | bebob_focusrite.o bebob_maudio.o bebob.o | 3 | bebob_yamaha_terratec.o bebob_focusrite.o bebob_maudio.o \ |
4 | bebob.o | ||
4 | obj-$(CONFIG_SND_BEBOB) += snd-bebob.o | 5 | obj-$(CONFIG_SND_BEBOB) += snd-bebob.o |
diff --git a/sound/firewire/bebob/bebob.c b/sound/firewire/bebob/bebob.c index f7e2cbd2a313..3469ac14c89c 100644 --- a/sound/firewire/bebob/bebob.c +++ b/sound/firewire/bebob/bebob.c | |||
@@ -458,17 +458,17 @@ static const struct ieee1394_device_id bebob_id_table[] = { | |||
458 | /* TerraTec Electronic GmbH, PHASE 88 Rack FW */ | 458 | /* TerraTec Electronic GmbH, PHASE 88 Rack FW */ |
459 | SND_BEBOB_DEV_ENTRY(VEN_TERRATEC, 0x00000003, &phase88_rack_spec), | 459 | SND_BEBOB_DEV_ENTRY(VEN_TERRATEC, 0x00000003, &phase88_rack_spec), |
460 | /* TerraTec Electronic GmbH, PHASE 24 FW */ | 460 | /* TerraTec Electronic GmbH, PHASE 24 FW */ |
461 | SND_BEBOB_DEV_ENTRY(VEN_TERRATEC, 0x00000004, &phase24_series_spec), | 461 | SND_BEBOB_DEV_ENTRY(VEN_TERRATEC, 0x00000004, &yamaha_terratec_spec), |
462 | /* TerraTec Electronic GmbH, Phase X24 FW */ | 462 | /* TerraTec Electronic GmbH, Phase X24 FW */ |
463 | SND_BEBOB_DEV_ENTRY(VEN_TERRATEC, 0x00000007, &phase24_series_spec), | 463 | SND_BEBOB_DEV_ENTRY(VEN_TERRATEC, 0x00000007, &yamaha_terratec_spec), |
464 | /* TerraTec Electronic GmbH, EWS MIC2/MIC8 */ | 464 | /* TerraTec Electronic GmbH, EWS MIC2/MIC8 */ |
465 | SND_BEBOB_DEV_ENTRY(VEN_TERRATEC, 0x00000005, &spec_normal), | 465 | SND_BEBOB_DEV_ENTRY(VEN_TERRATEC, 0x00000005, &spec_normal), |
466 | /* Terratec Electronic GmbH, Aureon 7.1 Firewire */ | 466 | /* Terratec Electronic GmbH, Aureon 7.1 Firewire */ |
467 | SND_BEBOB_DEV_ENTRY(VEN_TERRATEC, 0x00000002, &spec_normal), | 467 | SND_BEBOB_DEV_ENTRY(VEN_TERRATEC, 0x00000002, &spec_normal), |
468 | /* Yamaha, GO44 */ | 468 | /* Yamaha, GO44 */ |
469 | SND_BEBOB_DEV_ENTRY(VEN_YAMAHA, 0x0010000b, &yamaha_go_spec), | 469 | SND_BEBOB_DEV_ENTRY(VEN_YAMAHA, 0x0010000b, &yamaha_terratec_spec), |
470 | /* YAMAHA, GO46 */ | 470 | /* YAMAHA, GO46 */ |
471 | SND_BEBOB_DEV_ENTRY(VEN_YAMAHA, 0x0010000c, &yamaha_go_spec), | 471 | SND_BEBOB_DEV_ENTRY(VEN_YAMAHA, 0x0010000c, &yamaha_terratec_spec), |
472 | /* Focusrite, SaffirePro 26 I/O */ | 472 | /* Focusrite, SaffirePro 26 I/O */ |
473 | SND_BEBOB_DEV_ENTRY(VEN_FOCUSRITE, 0x00000003, &saffirepro_26_spec), | 473 | SND_BEBOB_DEV_ENTRY(VEN_FOCUSRITE, 0x00000003, &saffirepro_26_spec), |
474 | /* Focusrite, SaffirePro 10 I/O */ | 474 | /* Focusrite, SaffirePro 10 I/O */ |
diff --git a/sound/firewire/bebob/bebob.h b/sound/firewire/bebob/bebob.h index e7f1bb925b12..175da875162d 100644 --- a/sound/firewire/bebob/bebob.h +++ b/sound/firewire/bebob/bebob.h | |||
@@ -235,8 +235,7 @@ int snd_bebob_create_hwdep_device(struct snd_bebob *bebob); | |||
235 | 235 | ||
236 | /* model specific operations */ | 236 | /* model specific operations */ |
237 | extern const struct snd_bebob_spec phase88_rack_spec; | 237 | extern const struct snd_bebob_spec phase88_rack_spec; |
238 | extern const struct snd_bebob_spec phase24_series_spec; | 238 | extern const struct snd_bebob_spec yamaha_terratec_spec; |
239 | extern const struct snd_bebob_spec yamaha_go_spec; | ||
240 | extern const struct snd_bebob_spec saffirepro_26_spec; | 239 | extern const struct snd_bebob_spec saffirepro_26_spec; |
241 | extern const struct snd_bebob_spec saffirepro_10_spec; | 240 | extern const struct snd_bebob_spec saffirepro_10_spec; |
242 | extern const struct snd_bebob_spec saffire_le_spec; | 241 | extern const struct snd_bebob_spec saffire_le_spec; |
diff --git a/sound/firewire/bebob/bebob_terratec.c b/sound/firewire/bebob/bebob_terratec.c index c38358b82ada..2fdaf93e7a8d 100644 --- a/sound/firewire/bebob/bebob_terratec.c +++ b/sound/firewire/bebob/bebob_terratec.c | |||
@@ -36,25 +36,6 @@ end: | |||
36 | return err; | 36 | return err; |
37 | } | 37 | } |
38 | 38 | ||
39 | static enum snd_bebob_clock_type phase24_series_clk_src_types[] = { | ||
40 | SND_BEBOB_CLOCK_TYPE_INTERNAL, | ||
41 | SND_BEBOB_CLOCK_TYPE_EXTERNAL, /* S/PDIF */ | ||
42 | }; | ||
43 | static int | ||
44 | phase24_series_clk_src_get(struct snd_bebob *bebob, unsigned int *id) | ||
45 | { | ||
46 | int err; | ||
47 | |||
48 | err = avc_audio_get_selector(bebob->unit, 0, 4, id); | ||
49 | if (err < 0) | ||
50 | return err; | ||
51 | |||
52 | if (*id >= ARRAY_SIZE(phase24_series_clk_src_types)) | ||
53 | return -EIO; | ||
54 | |||
55 | return 0; | ||
56 | } | ||
57 | |||
58 | static const struct snd_bebob_rate_spec phase_series_rate_spec = { | 39 | static const struct snd_bebob_rate_spec phase_series_rate_spec = { |
59 | .get = &snd_bebob_stream_get_rate, | 40 | .get = &snd_bebob_stream_get_rate, |
60 | .set = &snd_bebob_stream_set_rate, | 41 | .set = &snd_bebob_stream_set_rate, |
@@ -71,15 +52,3 @@ const struct snd_bebob_spec phase88_rack_spec = { | |||
71 | .rate = &phase_series_rate_spec, | 52 | .rate = &phase_series_rate_spec, |
72 | .meter = NULL | 53 | .meter = NULL |
73 | }; | 54 | }; |
74 | |||
75 | /* 'PHASE 24 FW' and 'PHASE X24 FW' */ | ||
76 | static const struct snd_bebob_clock_spec phase24_series_clk = { | ||
77 | .num = ARRAY_SIZE(phase24_series_clk_src_types), | ||
78 | .types = phase24_series_clk_src_types, | ||
79 | .get = &phase24_series_clk_src_get, | ||
80 | }; | ||
81 | const struct snd_bebob_spec phase24_series_spec = { | ||
82 | .clock = &phase24_series_clk, | ||
83 | .rate = &phase_series_rate_spec, | ||
84 | .meter = NULL | ||
85 | }; | ||
diff --git a/sound/firewire/bebob/bebob_yamaha.c b/sound/firewire/bebob/bebob_yamaha_terratec.c index 90d4404f77ce..a6be3e7138e0 100644 --- a/sound/firewire/bebob/bebob_yamaha.c +++ b/sound/firewire/bebob/bebob_yamaha_terratec.c | |||
@@ -14,7 +14,7 @@ | |||
14 | * must be accompanied. If changing the state, a LED on the device starts to | 14 | * must be accompanied. If changing the state, a LED on the device starts to |
15 | * blink and its sync status is false. In this state, the device sounds nothing | 15 | * blink and its sync status is false. In this state, the device sounds nothing |
16 | * even if streaming. To start streaming at the current sampling rate is only | 16 | * even if streaming. To start streaming at the current sampling rate is only |
17 | * way to revocer this state. GO46 is better for stand-alone mixer. | 17 | * way to recover this state. GO46 is better for stand-alone mixer. |
18 | * | 18 | * |
19 | * Both of them have a capability to change its sampling rate up to 192.0kHz. | 19 | * Both of them have a capability to change its sampling rate up to 192.0kHz. |
20 | * At 192.0kHz, the device reports 4 PCM-in, 1 MIDI-in, 6 PCM-out, 1 MIDI-out. | 20 | * At 192.0kHz, the device reports 4 PCM-in, 1 MIDI-in, 6 PCM-out, 1 MIDI-out. |
@@ -25,7 +25,10 @@ | |||
25 | * streaming with many asynchronous transactions brings sounds with noises. | 25 | * streaming with many asynchronous transactions brings sounds with noises. |
26 | * Unfortunately current 'ffado-mixer' generated many asynchronous transaction | 26 | * Unfortunately current 'ffado-mixer' generated many asynchronous transaction |
27 | * to observe device's state, mainly check cmp connection and signal format. I | 27 | * to observe device's state, mainly check cmp connection and signal format. I |
28 | * reccomend users to close ffado-mixer at 192.0kHz if mixer is needless. | 28 | * recommend users to close ffado-mixer at 192.0kHz if mixer is needless. |
29 | * | ||
30 | * Terratec PHASE 24 FW and PHASE X24 FW are internally the same as | ||
31 | * Yamaha GO 44 and GO 46. Yamaha and Terratec had cooperated for these models. | ||
29 | */ | 32 | */ |
30 | 33 | ||
31 | static enum snd_bebob_clock_type clk_src_types[] = { | 34 | static enum snd_bebob_clock_type clk_src_types[] = { |
@@ -55,7 +58,7 @@ static const struct snd_bebob_rate_spec rate_spec = { | |||
55 | .get = &snd_bebob_stream_get_rate, | 58 | .get = &snd_bebob_stream_get_rate, |
56 | .set = &snd_bebob_stream_set_rate, | 59 | .set = &snd_bebob_stream_set_rate, |
57 | }; | 60 | }; |
58 | const struct snd_bebob_spec yamaha_go_spec = { | 61 | const struct snd_bebob_spec yamaha_terratec_spec = { |
59 | .clock = &clock_spec, | 62 | .clock = &clock_spec, |
60 | .rate = &rate_spec, | 63 | .rate = &rate_spec, |
61 | .meter = NULL | 64 | .meter = NULL |
diff --git a/sound/firewire/dice/dice-pcm.c b/sound/firewire/dice/dice-pcm.c index 4aa0249826fd..6074fe1f00f7 100644 --- a/sound/firewire/dice/dice-pcm.c +++ b/sound/firewire/dice/dice-pcm.c | |||
@@ -302,7 +302,7 @@ static snd_pcm_uframes_t playback_pointer(struct snd_pcm_substream *substream) | |||
302 | 302 | ||
303 | int snd_dice_create_pcm(struct snd_dice *dice) | 303 | int snd_dice_create_pcm(struct snd_dice *dice) |
304 | { | 304 | { |
305 | static struct snd_pcm_ops capture_ops = { | 305 | static const struct snd_pcm_ops capture_ops = { |
306 | .open = pcm_open, | 306 | .open = pcm_open, |
307 | .close = pcm_close, | 307 | .close = pcm_close, |
308 | .ioctl = snd_pcm_lib_ioctl, | 308 | .ioctl = snd_pcm_lib_ioctl, |
@@ -314,7 +314,7 @@ int snd_dice_create_pcm(struct snd_dice *dice) | |||
314 | .page = snd_pcm_lib_get_vmalloc_page, | 314 | .page = snd_pcm_lib_get_vmalloc_page, |
315 | .mmap = snd_pcm_lib_mmap_vmalloc, | 315 | .mmap = snd_pcm_lib_mmap_vmalloc, |
316 | }; | 316 | }; |
317 | static struct snd_pcm_ops playback_ops = { | 317 | static const struct snd_pcm_ops playback_ops = { |
318 | .open = pcm_open, | 318 | .open = pcm_open, |
319 | .close = pcm_close, | 319 | .close = pcm_close, |
320 | .ioctl = snd_pcm_lib_ioctl, | 320 | .ioctl = snd_pcm_lib_ioctl, |
diff --git a/sound/firewire/digi00x/digi00x-pcm.c b/sound/firewire/digi00x/digi00x-pcm.c index cac28f70aef7..613f05872770 100644 --- a/sound/firewire/digi00x/digi00x-pcm.c +++ b/sound/firewire/digi00x/digi00x-pcm.c | |||
@@ -329,7 +329,7 @@ static snd_pcm_uframes_t pcm_playback_pointer(struct snd_pcm_substream *sbstrm) | |||
329 | return amdtp_stream_pcm_pointer(&dg00x->rx_stream); | 329 | return amdtp_stream_pcm_pointer(&dg00x->rx_stream); |
330 | } | 330 | } |
331 | 331 | ||
332 | static struct snd_pcm_ops pcm_capture_ops = { | 332 | static const struct snd_pcm_ops pcm_capture_ops = { |
333 | .open = pcm_open, | 333 | .open = pcm_open, |
334 | .close = pcm_close, | 334 | .close = pcm_close, |
335 | .ioctl = snd_pcm_lib_ioctl, | 335 | .ioctl = snd_pcm_lib_ioctl, |
@@ -341,7 +341,7 @@ static struct snd_pcm_ops pcm_capture_ops = { | |||
341 | .page = snd_pcm_lib_get_vmalloc_page, | 341 | .page = snd_pcm_lib_get_vmalloc_page, |
342 | }; | 342 | }; |
343 | 343 | ||
344 | static struct snd_pcm_ops pcm_playback_ops = { | 344 | static const struct snd_pcm_ops pcm_playback_ops = { |
345 | .open = pcm_open, | 345 | .open = pcm_open, |
346 | .close = pcm_close, | 346 | .close = pcm_close, |
347 | .ioctl = snd_pcm_lib_ioctl, | 347 | .ioctl = snd_pcm_lib_ioctl, |
diff --git a/sound/firewire/oxfw/oxfw-pcm.c b/sound/firewire/oxfw/oxfw-pcm.c index 8d233417695d..f3530f89a025 100644 --- a/sound/firewire/oxfw/oxfw-pcm.c +++ b/sound/firewire/oxfw/oxfw-pcm.c | |||
@@ -388,7 +388,7 @@ static snd_pcm_uframes_t pcm_playback_pointer(struct snd_pcm_substream *sbstm) | |||
388 | 388 | ||
389 | int snd_oxfw_create_pcm(struct snd_oxfw *oxfw) | 389 | int snd_oxfw_create_pcm(struct snd_oxfw *oxfw) |
390 | { | 390 | { |
391 | static struct snd_pcm_ops capture_ops = { | 391 | static const struct snd_pcm_ops capture_ops = { |
392 | .open = pcm_open, | 392 | .open = pcm_open, |
393 | .close = pcm_close, | 393 | .close = pcm_close, |
394 | .ioctl = snd_pcm_lib_ioctl, | 394 | .ioctl = snd_pcm_lib_ioctl, |
@@ -400,7 +400,7 @@ int snd_oxfw_create_pcm(struct snd_oxfw *oxfw) | |||
400 | .page = snd_pcm_lib_get_vmalloc_page, | 400 | .page = snd_pcm_lib_get_vmalloc_page, |
401 | .mmap = snd_pcm_lib_mmap_vmalloc, | 401 | .mmap = snd_pcm_lib_mmap_vmalloc, |
402 | }; | 402 | }; |
403 | static struct snd_pcm_ops playback_ops = { | 403 | static const struct snd_pcm_ops playback_ops = { |
404 | .open = pcm_open, | 404 | .open = pcm_open, |
405 | .close = pcm_close, | 405 | .close = pcm_close, |
406 | .ioctl = snd_pcm_lib_ioctl, | 406 | .ioctl = snd_pcm_lib_ioctl, |
diff --git a/sound/firewire/tascam/tascam-pcm.c b/sound/firewire/tascam/tascam-pcm.c index 380d3db969a5..79db1b651f5c 100644 --- a/sound/firewire/tascam/tascam-pcm.c +++ b/sound/firewire/tascam/tascam-pcm.c | |||
@@ -268,7 +268,7 @@ static snd_pcm_uframes_t pcm_playback_pointer(struct snd_pcm_substream *sbstrm) | |||
268 | return amdtp_stream_pcm_pointer(&tscm->rx_stream); | 268 | return amdtp_stream_pcm_pointer(&tscm->rx_stream); |
269 | } | 269 | } |
270 | 270 | ||
271 | static struct snd_pcm_ops pcm_capture_ops = { | 271 | static const struct snd_pcm_ops pcm_capture_ops = { |
272 | .open = pcm_open, | 272 | .open = pcm_open, |
273 | .close = pcm_close, | 273 | .close = pcm_close, |
274 | .ioctl = snd_pcm_lib_ioctl, | 274 | .ioctl = snd_pcm_lib_ioctl, |
@@ -280,7 +280,7 @@ static struct snd_pcm_ops pcm_capture_ops = { | |||
280 | .page = snd_pcm_lib_get_vmalloc_page, | 280 | .page = snd_pcm_lib_get_vmalloc_page, |
281 | }; | 281 | }; |
282 | 282 | ||
283 | static struct snd_pcm_ops pcm_playback_ops = { | 283 | static const struct snd_pcm_ops pcm_playback_ops = { |
284 | .open = pcm_open, | 284 | .open = pcm_open, |
285 | .close = pcm_close, | 285 | .close = pcm_close, |
286 | .ioctl = snd_pcm_lib_ioctl, | 286 | .ioctl = snd_pcm_lib_ioctl, |
diff --git a/sound/hda/ext/hdac_ext_controller.c b/sound/hda/ext/hdac_ext_controller.c index 860f8cad6602..261469188566 100644 --- a/sound/hda/ext/hdac_ext_controller.c +++ b/sound/hda/ext/hdac_ext_controller.c | |||
@@ -29,81 +29,6 @@ | |||
29 | */ | 29 | */ |
30 | #define HDAC_MAX_CAPS 10 | 30 | #define HDAC_MAX_CAPS 10 |
31 | 31 | ||
32 | /** | ||
33 | * snd_hdac_ext_bus_parse_capabilities - parse capablity structure | ||
34 | * @ebus: the pointer to extended bus object | ||
35 | * | ||
36 | * Returns 0 if successful, or a negative error code. | ||
37 | */ | ||
38 | int snd_hdac_ext_bus_parse_capabilities(struct hdac_ext_bus *ebus) | ||
39 | { | ||
40 | unsigned int cur_cap; | ||
41 | unsigned int offset; | ||
42 | struct hdac_bus *bus = &ebus->bus; | ||
43 | unsigned int counter = 0; | ||
44 | |||
45 | offset = snd_hdac_chip_readl(bus, LLCH); | ||
46 | |||
47 | /* Lets walk the linked capabilities list */ | ||
48 | do { | ||
49 | cur_cap = _snd_hdac_chip_read(l, bus, offset); | ||
50 | |||
51 | dev_dbg(bus->dev, "Capability version: 0x%x\n", | ||
52 | ((cur_cap & AZX_CAP_HDR_VER_MASK) >> AZX_CAP_HDR_VER_OFF)); | ||
53 | |||
54 | dev_dbg(bus->dev, "HDA capability ID: 0x%x\n", | ||
55 | (cur_cap & AZX_CAP_HDR_ID_MASK) >> AZX_CAP_HDR_ID_OFF); | ||
56 | |||
57 | switch ((cur_cap & AZX_CAP_HDR_ID_MASK) >> AZX_CAP_HDR_ID_OFF) { | ||
58 | case AZX_ML_CAP_ID: | ||
59 | dev_dbg(bus->dev, "Found ML capability\n"); | ||
60 | ebus->mlcap = bus->remap_addr + offset; | ||
61 | break; | ||
62 | |||
63 | case AZX_GTS_CAP_ID: | ||
64 | dev_dbg(bus->dev, "Found GTS capability offset=%x\n", offset); | ||
65 | ebus->gtscap = bus->remap_addr + offset; | ||
66 | break; | ||
67 | |||
68 | case AZX_PP_CAP_ID: | ||
69 | /* PP capability found, the Audio DSP is present */ | ||
70 | dev_dbg(bus->dev, "Found PP capability offset=%x\n", offset); | ||
71 | ebus->ppcap = bus->remap_addr + offset; | ||
72 | break; | ||
73 | |||
74 | case AZX_SPB_CAP_ID: | ||
75 | /* SPIB capability found, handler function */ | ||
76 | dev_dbg(bus->dev, "Found SPB capability\n"); | ||
77 | ebus->spbcap = bus->remap_addr + offset; | ||
78 | break; | ||
79 | |||
80 | case AZX_DRSM_CAP_ID: | ||
81 | /* DMA resume capability found, handler function */ | ||
82 | dev_dbg(bus->dev, "Found DRSM capability\n"); | ||
83 | ebus->drsmcap = bus->remap_addr + offset; | ||
84 | break; | ||
85 | |||
86 | default: | ||
87 | dev_dbg(bus->dev, "Unknown capability %d\n", cur_cap); | ||
88 | break; | ||
89 | } | ||
90 | |||
91 | counter++; | ||
92 | |||
93 | if (counter > HDAC_MAX_CAPS) { | ||
94 | dev_err(bus->dev, "We exceeded HDAC Ext capablities!!!\n"); | ||
95 | break; | ||
96 | } | ||
97 | |||
98 | /* read the offset of next capabiity */ | ||
99 | offset = cur_cap & AZX_CAP_HDR_NXT_PTR_MASK; | ||
100 | |||
101 | } while (offset); | ||
102 | |||
103 | return 0; | ||
104 | } | ||
105 | EXPORT_SYMBOL_GPL(snd_hdac_ext_bus_parse_capabilities); | ||
106 | |||
107 | /* | 32 | /* |
108 | * processing pipe helpers - these helpers are useful for dealing with HDA | 33 | * processing pipe helpers - these helpers are useful for dealing with HDA |
109 | * new capability of processing pipelines | 34 | * new capability of processing pipelines |
@@ -118,15 +43,15 @@ void snd_hdac_ext_bus_ppcap_enable(struct hdac_ext_bus *ebus, bool enable) | |||
118 | { | 43 | { |
119 | struct hdac_bus *bus = &ebus->bus; | 44 | struct hdac_bus *bus = &ebus->bus; |
120 | 45 | ||
121 | if (!ebus->ppcap) { | 46 | if (!bus->ppcap) { |
122 | dev_err(bus->dev, "Address of PP capability is NULL"); | 47 | dev_err(bus->dev, "Address of PP capability is NULL"); |
123 | return; | 48 | return; |
124 | } | 49 | } |
125 | 50 | ||
126 | if (enable) | 51 | if (enable) |
127 | snd_hdac_updatel(ebus->ppcap, AZX_REG_PP_PPCTL, 0, AZX_PPCTL_GPROCEN); | 52 | snd_hdac_updatel(bus->ppcap, AZX_REG_PP_PPCTL, 0, AZX_PPCTL_GPROCEN); |
128 | else | 53 | else |
129 | snd_hdac_updatel(ebus->ppcap, AZX_REG_PP_PPCTL, AZX_PPCTL_GPROCEN, 0); | 54 | snd_hdac_updatel(bus->ppcap, AZX_REG_PP_PPCTL, AZX_PPCTL_GPROCEN, 0); |
130 | } | 55 | } |
131 | EXPORT_SYMBOL_GPL(snd_hdac_ext_bus_ppcap_enable); | 56 | EXPORT_SYMBOL_GPL(snd_hdac_ext_bus_ppcap_enable); |
132 | 57 | ||
@@ -139,15 +64,15 @@ void snd_hdac_ext_bus_ppcap_int_enable(struct hdac_ext_bus *ebus, bool enable) | |||
139 | { | 64 | { |
140 | struct hdac_bus *bus = &ebus->bus; | 65 | struct hdac_bus *bus = &ebus->bus; |
141 | 66 | ||
142 | if (!ebus->ppcap) { | 67 | if (!bus->ppcap) { |
143 | dev_err(bus->dev, "Address of PP capability is NULL\n"); | 68 | dev_err(bus->dev, "Address of PP capability is NULL\n"); |
144 | return; | 69 | return; |
145 | } | 70 | } |
146 | 71 | ||
147 | if (enable) | 72 | if (enable) |
148 | snd_hdac_updatel(ebus->ppcap, AZX_REG_PP_PPCTL, 0, AZX_PPCTL_PIE); | 73 | snd_hdac_updatel(bus->ppcap, AZX_REG_PP_PPCTL, 0, AZX_PPCTL_PIE); |
149 | else | 74 | else |
150 | snd_hdac_updatel(ebus->ppcap, AZX_REG_PP_PPCTL, AZX_PPCTL_PIE, 0); | 75 | snd_hdac_updatel(bus->ppcap, AZX_REG_PP_PPCTL, AZX_PPCTL_PIE, 0); |
151 | } | 76 | } |
152 | EXPORT_SYMBOL_GPL(snd_hdac_ext_bus_ppcap_int_enable); | 77 | EXPORT_SYMBOL_GPL(snd_hdac_ext_bus_ppcap_int_enable); |
153 | 78 | ||
@@ -171,7 +96,7 @@ int snd_hdac_ext_bus_get_ml_capabilities(struct hdac_ext_bus *ebus) | |||
171 | struct hdac_ext_link *hlink; | 96 | struct hdac_ext_link *hlink; |
172 | struct hdac_bus *bus = &ebus->bus; | 97 | struct hdac_bus *bus = &ebus->bus; |
173 | 98 | ||
174 | link_count = readl(ebus->mlcap + AZX_REG_ML_MLCD) + 1; | 99 | link_count = readl(bus->mlcap + AZX_REG_ML_MLCD) + 1; |
175 | 100 | ||
176 | dev_dbg(bus->dev, "In %s Link count: %d\n", __func__, link_count); | 101 | dev_dbg(bus->dev, "In %s Link count: %d\n", __func__, link_count); |
177 | 102 | ||
@@ -181,7 +106,7 @@ int snd_hdac_ext_bus_get_ml_capabilities(struct hdac_ext_bus *ebus) | |||
181 | return -ENOMEM; | 106 | return -ENOMEM; |
182 | hlink->index = idx; | 107 | hlink->index = idx; |
183 | hlink->bus = bus; | 108 | hlink->bus = bus; |
184 | hlink->ml_addr = ebus->mlcap + AZX_ML_BASE + | 109 | hlink->ml_addr = bus->mlcap + AZX_ML_BASE + |
185 | (AZX_ML_INTERVAL * idx); | 110 | (AZX_ML_INTERVAL * idx); |
186 | hlink->lcaps = readl(hlink->ml_addr + AZX_REG_ML_LCAP); | 111 | hlink->lcaps = readl(hlink->ml_addr + AZX_REG_ML_LCAP); |
187 | hlink->lsdiid = readw(hlink->ml_addr + AZX_REG_ML_LSDIID); | 112 | hlink->lsdiid = readw(hlink->ml_addr + AZX_REG_ML_LSDIID); |
diff --git a/sound/hda/ext/hdac_ext_stream.c b/sound/hda/ext/hdac_ext_stream.c index 626f3bb24c55..3be051ab5533 100644 --- a/sound/hda/ext/hdac_ext_stream.c +++ b/sound/hda/ext/hdac_ext_stream.c | |||
@@ -40,27 +40,27 @@ void snd_hdac_ext_stream_init(struct hdac_ext_bus *ebus, | |||
40 | { | 40 | { |
41 | struct hdac_bus *bus = &ebus->bus; | 41 | struct hdac_bus *bus = &ebus->bus; |
42 | 42 | ||
43 | if (ebus->ppcap) { | 43 | if (bus->ppcap) { |
44 | stream->pphc_addr = ebus->ppcap + AZX_PPHC_BASE + | 44 | stream->pphc_addr = bus->ppcap + AZX_PPHC_BASE + |
45 | AZX_PPHC_INTERVAL * idx; | 45 | AZX_PPHC_INTERVAL * idx; |
46 | 46 | ||
47 | stream->pplc_addr = ebus->ppcap + AZX_PPLC_BASE + | 47 | stream->pplc_addr = bus->ppcap + AZX_PPLC_BASE + |
48 | AZX_PPLC_MULTI * ebus->num_streams + | 48 | AZX_PPLC_MULTI * ebus->num_streams + |
49 | AZX_PPLC_INTERVAL * idx; | 49 | AZX_PPLC_INTERVAL * idx; |
50 | } | 50 | } |
51 | 51 | ||
52 | if (ebus->spbcap) { | 52 | if (bus->spbcap) { |
53 | stream->spib_addr = ebus->spbcap + AZX_SPB_BASE + | 53 | stream->spib_addr = bus->spbcap + AZX_SPB_BASE + |
54 | AZX_SPB_INTERVAL * idx + | 54 | AZX_SPB_INTERVAL * idx + |
55 | AZX_SPB_SPIB; | 55 | AZX_SPB_SPIB; |
56 | 56 | ||
57 | stream->fifo_addr = ebus->spbcap + AZX_SPB_BASE + | 57 | stream->fifo_addr = bus->spbcap + AZX_SPB_BASE + |
58 | AZX_SPB_INTERVAL * idx + | 58 | AZX_SPB_INTERVAL * idx + |
59 | AZX_SPB_MAXFIFO; | 59 | AZX_SPB_MAXFIFO; |
60 | } | 60 | } |
61 | 61 | ||
62 | if (ebus->drsmcap) | 62 | if (bus->drsmcap) |
63 | stream->dpibr_addr = ebus->drsmcap + AZX_DRSM_BASE + | 63 | stream->dpibr_addr = bus->drsmcap + AZX_DRSM_BASE + |
64 | AZX_DRSM_INTERVAL * idx; | 64 | AZX_DRSM_INTERVAL * idx; |
65 | 65 | ||
66 | stream->decoupled = false; | 66 | stream->decoupled = false; |
@@ -131,10 +131,10 @@ void snd_hdac_ext_stream_decouple(struct hdac_ext_bus *ebus, | |||
131 | 131 | ||
132 | spin_lock_irq(&bus->reg_lock); | 132 | spin_lock_irq(&bus->reg_lock); |
133 | if (decouple) | 133 | if (decouple) |
134 | snd_hdac_updatel(ebus->ppcap, AZX_REG_PP_PPCTL, 0, | 134 | snd_hdac_updatel(bus->ppcap, AZX_REG_PP_PPCTL, 0, |
135 | AZX_PPCTL_PROCEN(hstream->index)); | 135 | AZX_PPCTL_PROCEN(hstream->index)); |
136 | else | 136 | else |
137 | snd_hdac_updatel(ebus->ppcap, AZX_REG_PP_PPCTL, | 137 | snd_hdac_updatel(bus->ppcap, AZX_REG_PP_PPCTL, |
138 | AZX_PPCTL_PROCEN(hstream->index), 0); | 138 | AZX_PPCTL_PROCEN(hstream->index), 0); |
139 | stream->decoupled = decouple; | 139 | stream->decoupled = decouple; |
140 | spin_unlock_irq(&bus->reg_lock); | 140 | spin_unlock_irq(&bus->reg_lock); |
@@ -255,7 +255,7 @@ hdac_ext_link_stream_assign(struct hdac_ext_bus *ebus, | |||
255 | struct hdac_stream *stream = NULL; | 255 | struct hdac_stream *stream = NULL; |
256 | struct hdac_bus *hbus = &ebus->bus; | 256 | struct hdac_bus *hbus = &ebus->bus; |
257 | 257 | ||
258 | if (!ebus->ppcap) { | 258 | if (!hbus->ppcap) { |
259 | dev_err(hbus->dev, "stream type not supported\n"); | 259 | dev_err(hbus->dev, "stream type not supported\n"); |
260 | return NULL; | 260 | return NULL; |
261 | } | 261 | } |
@@ -296,7 +296,7 @@ hdac_ext_host_stream_assign(struct hdac_ext_bus *ebus, | |||
296 | struct hdac_stream *stream = NULL; | 296 | struct hdac_stream *stream = NULL; |
297 | struct hdac_bus *hbus = &ebus->bus; | 297 | struct hdac_bus *hbus = &ebus->bus; |
298 | 298 | ||
299 | if (!ebus->ppcap) { | 299 | if (!hbus->ppcap) { |
300 | dev_err(hbus->dev, "stream type not supported\n"); | 300 | dev_err(hbus->dev, "stream type not supported\n"); |
301 | return NULL; | 301 | return NULL; |
302 | } | 302 | } |
@@ -423,21 +423,21 @@ void snd_hdac_ext_stream_spbcap_enable(struct hdac_ext_bus *ebus, | |||
423 | u32 register_mask = 0; | 423 | u32 register_mask = 0; |
424 | struct hdac_bus *bus = &ebus->bus; | 424 | struct hdac_bus *bus = &ebus->bus; |
425 | 425 | ||
426 | if (!ebus->spbcap) { | 426 | if (!bus->spbcap) { |
427 | dev_err(bus->dev, "Address of SPB capability is NULL"); | 427 | dev_err(bus->dev, "Address of SPB capability is NULL\n"); |
428 | return; | 428 | return; |
429 | } | 429 | } |
430 | 430 | ||
431 | mask |= (1 << index); | 431 | mask |= (1 << index); |
432 | 432 | ||
433 | register_mask = readl(ebus->spbcap + AZX_REG_SPB_SPBFCCTL); | 433 | register_mask = readl(bus->spbcap + AZX_REG_SPB_SPBFCCTL); |
434 | 434 | ||
435 | mask |= register_mask; | 435 | mask |= register_mask; |
436 | 436 | ||
437 | if (enable) | 437 | if (enable) |
438 | snd_hdac_updatel(ebus->spbcap, AZX_REG_SPB_SPBFCCTL, 0, mask); | 438 | snd_hdac_updatel(bus->spbcap, AZX_REG_SPB_SPBFCCTL, 0, mask); |
439 | else | 439 | else |
440 | snd_hdac_updatel(ebus->spbcap, AZX_REG_SPB_SPBFCCTL, mask, 0); | 440 | snd_hdac_updatel(bus->spbcap, AZX_REG_SPB_SPBFCCTL, mask, 0); |
441 | } | 441 | } |
442 | EXPORT_SYMBOL_GPL(snd_hdac_ext_stream_spbcap_enable); | 442 | EXPORT_SYMBOL_GPL(snd_hdac_ext_stream_spbcap_enable); |
443 | 443 | ||
@@ -452,8 +452,8 @@ int snd_hdac_ext_stream_set_spib(struct hdac_ext_bus *ebus, | |||
452 | { | 452 | { |
453 | struct hdac_bus *bus = &ebus->bus; | 453 | struct hdac_bus *bus = &ebus->bus; |
454 | 454 | ||
455 | if (!ebus->spbcap) { | 455 | if (!bus->spbcap) { |
456 | dev_err(bus->dev, "Address of SPB capability is NULL"); | 456 | dev_err(bus->dev, "Address of SPB capability is NULL\n"); |
457 | return -EINVAL; | 457 | return -EINVAL; |
458 | } | 458 | } |
459 | 459 | ||
@@ -475,8 +475,8 @@ int snd_hdac_ext_stream_get_spbmaxfifo(struct hdac_ext_bus *ebus, | |||
475 | { | 475 | { |
476 | struct hdac_bus *bus = &ebus->bus; | 476 | struct hdac_bus *bus = &ebus->bus; |
477 | 477 | ||
478 | if (!ebus->spbcap) { | 478 | if (!bus->spbcap) { |
479 | dev_err(bus->dev, "Address of SPB capability is NULL"); | 479 | dev_err(bus->dev, "Address of SPB capability is NULL\n"); |
480 | return -EINVAL; | 480 | return -EINVAL; |
481 | } | 481 | } |
482 | 482 | ||
@@ -515,21 +515,21 @@ void snd_hdac_ext_stream_drsm_enable(struct hdac_ext_bus *ebus, | |||
515 | u32 register_mask = 0; | 515 | u32 register_mask = 0; |
516 | struct hdac_bus *bus = &ebus->bus; | 516 | struct hdac_bus *bus = &ebus->bus; |
517 | 517 | ||
518 | if (!ebus->drsmcap) { | 518 | if (!bus->drsmcap) { |
519 | dev_err(bus->dev, "Address of DRSM capability is NULL"); | 519 | dev_err(bus->dev, "Address of DRSM capability is NULL\n"); |
520 | return; | 520 | return; |
521 | } | 521 | } |
522 | 522 | ||
523 | mask |= (1 << index); | 523 | mask |= (1 << index); |
524 | 524 | ||
525 | register_mask = readl(ebus->drsmcap + AZX_REG_SPB_SPBFCCTL); | 525 | register_mask = readl(bus->drsmcap + AZX_REG_SPB_SPBFCCTL); |
526 | 526 | ||
527 | mask |= register_mask; | 527 | mask |= register_mask; |
528 | 528 | ||
529 | if (enable) | 529 | if (enable) |
530 | snd_hdac_updatel(ebus->drsmcap, AZX_REG_DRSM_CTL, 0, mask); | 530 | snd_hdac_updatel(bus->drsmcap, AZX_REG_DRSM_CTL, 0, mask); |
531 | else | 531 | else |
532 | snd_hdac_updatel(ebus->drsmcap, AZX_REG_DRSM_CTL, mask, 0); | 532 | snd_hdac_updatel(bus->drsmcap, AZX_REG_DRSM_CTL, mask, 0); |
533 | } | 533 | } |
534 | EXPORT_SYMBOL_GPL(snd_hdac_ext_stream_drsm_enable); | 534 | EXPORT_SYMBOL_GPL(snd_hdac_ext_stream_drsm_enable); |
535 | 535 | ||
@@ -544,8 +544,8 @@ int snd_hdac_ext_stream_set_dpibr(struct hdac_ext_bus *ebus, | |||
544 | { | 544 | { |
545 | struct hdac_bus *bus = &ebus->bus; | 545 | struct hdac_bus *bus = &ebus->bus; |
546 | 546 | ||
547 | if (!ebus->drsmcap) { | 547 | if (!bus->drsmcap) { |
548 | dev_err(bus->dev, "Address of DRSM capability is NULL"); | 548 | dev_err(bus->dev, "Address of DRSM capability is NULL\n"); |
549 | return -EINVAL; | 549 | return -EINVAL; |
550 | } | 550 | } |
551 | 551 | ||
diff --git a/sound/hda/hdac_controller.c b/sound/hda/hdac_controller.c index 9fee464e5d49..043065867656 100644 --- a/sound/hda/hdac_controller.c +++ b/sound/hda/hdac_controller.c | |||
@@ -255,6 +255,81 @@ int snd_hdac_bus_get_response(struct hdac_bus *bus, unsigned int addr, | |||
255 | } | 255 | } |
256 | EXPORT_SYMBOL_GPL(snd_hdac_bus_get_response); | 256 | EXPORT_SYMBOL_GPL(snd_hdac_bus_get_response); |
257 | 257 | ||
258 | #define HDAC_MAX_CAPS 10 | ||
259 | /** | ||
260 | * snd_hdac_bus_parse_capabilities - parse capability structure | ||
261 | * @bus: the pointer to bus object | ||
262 | * | ||
263 | * Returns 0 if successful, or a negative error code. | ||
264 | */ | ||
265 | int snd_hdac_bus_parse_capabilities(struct hdac_bus *bus) | ||
266 | { | ||
267 | unsigned int cur_cap; | ||
268 | unsigned int offset; | ||
269 | unsigned int counter = 0; | ||
270 | |||
271 | offset = snd_hdac_chip_readl(bus, LLCH); | ||
272 | |||
273 | /* Lets walk the linked capabilities list */ | ||
274 | do { | ||
275 | cur_cap = _snd_hdac_chip_read(l, bus, offset); | ||
276 | |||
277 | dev_dbg(bus->dev, "Capability version: 0x%x\n", | ||
278 | (cur_cap & AZX_CAP_HDR_VER_MASK) >> AZX_CAP_HDR_VER_OFF); | ||
279 | |||
280 | dev_dbg(bus->dev, "HDA capability ID: 0x%x\n", | ||
281 | (cur_cap & AZX_CAP_HDR_ID_MASK) >> AZX_CAP_HDR_ID_OFF); | ||
282 | |||
283 | switch ((cur_cap & AZX_CAP_HDR_ID_MASK) >> AZX_CAP_HDR_ID_OFF) { | ||
284 | case AZX_ML_CAP_ID: | ||
285 | dev_dbg(bus->dev, "Found ML capability\n"); | ||
286 | bus->mlcap = bus->remap_addr + offset; | ||
287 | break; | ||
288 | |||
289 | case AZX_GTS_CAP_ID: | ||
290 | dev_dbg(bus->dev, "Found GTS capability offset=%x\n", offset); | ||
291 | bus->gtscap = bus->remap_addr + offset; | ||
292 | break; | ||
293 | |||
294 | case AZX_PP_CAP_ID: | ||
295 | /* PP capability found, the Audio DSP is present */ | ||
296 | dev_dbg(bus->dev, "Found PP capability offset=%x\n", offset); | ||
297 | bus->ppcap = bus->remap_addr + offset; | ||
298 | break; | ||
299 | |||
300 | case AZX_SPB_CAP_ID: | ||
301 | /* SPIB capability found, handler function */ | ||
302 | dev_dbg(bus->dev, "Found SPB capability\n"); | ||
303 | bus->spbcap = bus->remap_addr + offset; | ||
304 | break; | ||
305 | |||
306 | case AZX_DRSM_CAP_ID: | ||
307 | /* DMA resume capability found, handler function */ | ||
308 | dev_dbg(bus->dev, "Found DRSM capability\n"); | ||
309 | bus->drsmcap = bus->remap_addr + offset; | ||
310 | break; | ||
311 | |||
312 | default: | ||
313 | dev_dbg(bus->dev, "Unknown capability %d\n", cur_cap); | ||
314 | break; | ||
315 | } | ||
316 | |||
317 | counter++; | ||
318 | |||
319 | if (counter > HDAC_MAX_CAPS) { | ||
320 | dev_err(bus->dev, "We exceeded HDAC capabilities!!!\n"); | ||
321 | break; | ||
322 | } | ||
323 | |||
324 | /* read the offset of next capability */ | ||
325 | offset = cur_cap & AZX_CAP_HDR_NXT_PTR_MASK; | ||
326 | |||
327 | } while (offset); | ||
328 | |||
329 | return 0; | ||
330 | } | ||
331 | EXPORT_SYMBOL_GPL(snd_hdac_bus_parse_capabilities); | ||
332 | |||
258 | /* | 333 | /* |
259 | * Lowlevel interface | 334 | * Lowlevel interface |
260 | */ | 335 | */ |
diff --git a/sound/pci/ad1889.c b/sound/pci/ad1889.c index 1fc6d8bc09e5..8c36990e26f6 100644 --- a/sound/pci/ad1889.c +++ b/sound/pci/ad1889.c | |||
@@ -571,7 +571,7 @@ snd_ad1889_capture_pointer(struct snd_pcm_substream *ss) | |||
571 | return bytes_to_frames(ss->runtime, ptr); | 571 | return bytes_to_frames(ss->runtime, ptr); |
572 | } | 572 | } |
573 | 573 | ||
574 | static struct snd_pcm_ops snd_ad1889_playback_ops = { | 574 | static const struct snd_pcm_ops snd_ad1889_playback_ops = { |
575 | .open = snd_ad1889_playback_open, | 575 | .open = snd_ad1889_playback_open, |
576 | .close = snd_ad1889_playback_close, | 576 | .close = snd_ad1889_playback_close, |
577 | .ioctl = snd_pcm_lib_ioctl, | 577 | .ioctl = snd_pcm_lib_ioctl, |
@@ -582,7 +582,7 @@ static struct snd_pcm_ops snd_ad1889_playback_ops = { | |||
582 | .pointer = snd_ad1889_playback_pointer, | 582 | .pointer = snd_ad1889_playback_pointer, |
583 | }; | 583 | }; |
584 | 584 | ||
585 | static struct snd_pcm_ops snd_ad1889_capture_ops = { | 585 | static const struct snd_pcm_ops snd_ad1889_capture_ops = { |
586 | .open = snd_ad1889_capture_open, | 586 | .open = snd_ad1889_capture_open, |
587 | .close = snd_ad1889_capture_close, | 587 | .close = snd_ad1889_capture_close, |
588 | .ioctl = snd_pcm_lib_ioctl, | 588 | .ioctl = snd_pcm_lib_ioctl, |
diff --git a/sound/pci/ali5451/ali5451.c b/sound/pci/ali5451/ali5451.c index 36470af7eda7..92b819e4f729 100644 --- a/sound/pci/ali5451/ali5451.c +++ b/sound/pci/ali5451/ali5451.c | |||
@@ -1408,6 +1408,7 @@ snd_ali_playback_pointer(struct snd_pcm_substream *substream) | |||
1408 | spin_unlock(&codec->reg_lock); | 1408 | spin_unlock(&codec->reg_lock); |
1409 | dev_dbg(codec->card->dev, "playback pointer returned cso=%xh.\n", cso); | 1409 | dev_dbg(codec->card->dev, "playback pointer returned cso=%xh.\n", cso); |
1410 | 1410 | ||
1411 | cso %= runtime->buffer_size; | ||
1411 | return cso; | 1412 | return cso; |
1412 | } | 1413 | } |
1413 | 1414 | ||
@@ -1428,6 +1429,7 @@ static snd_pcm_uframes_t snd_ali_pointer(struct snd_pcm_substream *substream) | |||
1428 | cso = inw(ALI_REG(codec, ALI_CSO_ALPHA_FMS + 2)); | 1429 | cso = inw(ALI_REG(codec, ALI_CSO_ALPHA_FMS + 2)); |
1429 | spin_unlock(&codec->reg_lock); | 1430 | spin_unlock(&codec->reg_lock); |
1430 | 1431 | ||
1432 | cso %= runtime->buffer_size; | ||
1431 | return cso; | 1433 | return cso; |
1432 | } | 1434 | } |
1433 | 1435 | ||
diff --git a/sound/pci/als300.c b/sound/pci/als300.c index add3176398d3..ab75601d7c2c 100644 --- a/sound/pci/als300.c +++ b/sound/pci/als300.c | |||
@@ -563,7 +563,7 @@ static snd_pcm_uframes_t snd_als300_pointer(struct snd_pcm_substream *substream) | |||
563 | return bytes_to_frames(substream->runtime, current_ptr); | 563 | return bytes_to_frames(substream->runtime, current_ptr); |
564 | } | 564 | } |
565 | 565 | ||
566 | static struct snd_pcm_ops snd_als300_playback_ops = { | 566 | static const struct snd_pcm_ops snd_als300_playback_ops = { |
567 | .open = snd_als300_playback_open, | 567 | .open = snd_als300_playback_open, |
568 | .close = snd_als300_playback_close, | 568 | .close = snd_als300_playback_close, |
569 | .ioctl = snd_pcm_lib_ioctl, | 569 | .ioctl = snd_pcm_lib_ioctl, |
@@ -574,7 +574,7 @@ static struct snd_pcm_ops snd_als300_playback_ops = { | |||
574 | .pointer = snd_als300_pointer, | 574 | .pointer = snd_als300_pointer, |
575 | }; | 575 | }; |
576 | 576 | ||
577 | static struct snd_pcm_ops snd_als300_capture_ops = { | 577 | static const struct snd_pcm_ops snd_als300_capture_ops = { |
578 | .open = snd_als300_capture_open, | 578 | .open = snd_als300_capture_open, |
579 | .close = snd_als300_capture_close, | 579 | .close = snd_als300_capture_close, |
580 | .ioctl = snd_pcm_lib_ioctl, | 580 | .ioctl = snd_pcm_lib_ioctl, |
diff --git a/sound/pci/als4000.c b/sound/pci/als4000.c index ff39a0c7277b..edabe1371660 100644 --- a/sound/pci/als4000.c +++ b/sound/pci/als4000.c | |||
@@ -672,7 +672,7 @@ static int snd_als4000_capture_close(struct snd_pcm_substream *substream) | |||
672 | 672 | ||
673 | /******************************************************************/ | 673 | /******************************************************************/ |
674 | 674 | ||
675 | static struct snd_pcm_ops snd_als4000_playback_ops = { | 675 | static const struct snd_pcm_ops snd_als4000_playback_ops = { |
676 | .open = snd_als4000_playback_open, | 676 | .open = snd_als4000_playback_open, |
677 | .close = snd_als4000_playback_close, | 677 | .close = snd_als4000_playback_close, |
678 | .ioctl = snd_pcm_lib_ioctl, | 678 | .ioctl = snd_pcm_lib_ioctl, |
@@ -683,7 +683,7 @@ static struct snd_pcm_ops snd_als4000_playback_ops = { | |||
683 | .pointer = snd_als4000_playback_pointer | 683 | .pointer = snd_als4000_playback_pointer |
684 | }; | 684 | }; |
685 | 685 | ||
686 | static struct snd_pcm_ops snd_als4000_capture_ops = { | 686 | static const struct snd_pcm_ops snd_als4000_capture_ops = { |
687 | .open = snd_als4000_capture_open, | 687 | .open = snd_als4000_capture_open, |
688 | .close = snd_als4000_capture_close, | 688 | .close = snd_als4000_capture_close, |
689 | .ioctl = snd_pcm_lib_ioctl, | 689 | .ioctl = snd_pcm_lib_ioctl, |
diff --git a/sound/pci/asihpi/asihpi.c b/sound/pci/asihpi/asihpi.c index 1039eccbb895..976a3d23557e 100644 --- a/sound/pci/asihpi/asihpi.c +++ b/sound/pci/asihpi/asihpi.c | |||
@@ -1138,7 +1138,7 @@ static int snd_card_asihpi_playback_close(struct snd_pcm_substream *substream) | |||
1138 | return 0; | 1138 | return 0; |
1139 | } | 1139 | } |
1140 | 1140 | ||
1141 | static struct snd_pcm_ops snd_card_asihpi_playback_mmap_ops = { | 1141 | static const struct snd_pcm_ops snd_card_asihpi_playback_mmap_ops = { |
1142 | .open = snd_card_asihpi_playback_open, | 1142 | .open = snd_card_asihpi_playback_open, |
1143 | .close = snd_card_asihpi_playback_close, | 1143 | .close = snd_card_asihpi_playback_close, |
1144 | .ioctl = snd_card_asihpi_playback_ioctl, | 1144 | .ioctl = snd_card_asihpi_playback_ioctl, |
@@ -1305,7 +1305,7 @@ static int snd_card_asihpi_capture_close(struct snd_pcm_substream *substream) | |||
1305 | return 0; | 1305 | return 0; |
1306 | } | 1306 | } |
1307 | 1307 | ||
1308 | static struct snd_pcm_ops snd_card_asihpi_capture_mmap_ops = { | 1308 | static const struct snd_pcm_ops snd_card_asihpi_capture_mmap_ops = { |
1309 | .open = snd_card_asihpi_capture_open, | 1309 | .open = snd_card_asihpi_capture_open, |
1310 | .close = snd_card_asihpi_capture_close, | 1310 | .close = snd_card_asihpi_capture_close, |
1311 | .ioctl = snd_card_asihpi_capture_ioctl, | 1311 | .ioctl = snd_card_asihpi_capture_ioctl, |
diff --git a/sound/pci/asihpi/hpifunc.c b/sound/pci/asihpi/hpifunc.c index 510e56cffd31..f9b57647b319 100644 --- a/sound/pci/asihpi/hpifunc.c +++ b/sound/pci/asihpi/hpifunc.c | |||
@@ -2323,11 +2323,8 @@ u16 hpi_sample_clock_get_source_index(u32 h_control, u16 *pw_source_index) | |||
2323 | u16 hpi_sample_clock_query_local_rate(const u32 h_clock, const u32 index, | 2323 | u16 hpi_sample_clock_query_local_rate(const u32 h_clock, const u32 index, |
2324 | u32 *prate) | 2324 | u32 *prate) |
2325 | { | 2325 | { |
2326 | u16 err; | 2326 | return hpi_control_query(h_clock, HPI_SAMPLECLOCK_LOCAL_SAMPLERATE, |
2327 | err = hpi_control_query(h_clock, HPI_SAMPLECLOCK_LOCAL_SAMPLERATE, | 2327 | index, 0, prate); |
2328 | index, 0, prate); | ||
2329 | |||
2330 | return err; | ||
2331 | } | 2328 | } |
2332 | 2329 | ||
2333 | u16 hpi_sample_clock_set_local_rate(u32 h_control, u32 sample_rate) | 2330 | u16 hpi_sample_clock_set_local_rate(u32 h_control, u32 sample_rate) |
diff --git a/sound/pci/atiixp.c b/sound/pci/atiixp.c index 2ce0022dbc46..a40c918c8dff 100644 --- a/sound/pci/atiixp.c +++ b/sound/pci/atiixp.c | |||
@@ -1148,7 +1148,7 @@ static int snd_atiixp_spdif_close(struct snd_pcm_substream *substream) | |||
1148 | } | 1148 | } |
1149 | 1149 | ||
1150 | /* AC97 playback */ | 1150 | /* AC97 playback */ |
1151 | static struct snd_pcm_ops snd_atiixp_playback_ops = { | 1151 | static const struct snd_pcm_ops snd_atiixp_playback_ops = { |
1152 | .open = snd_atiixp_playback_open, | 1152 | .open = snd_atiixp_playback_open, |
1153 | .close = snd_atiixp_playback_close, | 1153 | .close = snd_atiixp_playback_close, |
1154 | .ioctl = snd_pcm_lib_ioctl, | 1154 | .ioctl = snd_pcm_lib_ioctl, |
@@ -1160,7 +1160,7 @@ static struct snd_pcm_ops snd_atiixp_playback_ops = { | |||
1160 | }; | 1160 | }; |
1161 | 1161 | ||
1162 | /* AC97 capture */ | 1162 | /* AC97 capture */ |
1163 | static struct snd_pcm_ops snd_atiixp_capture_ops = { | 1163 | static const struct snd_pcm_ops snd_atiixp_capture_ops = { |
1164 | .open = snd_atiixp_capture_open, | 1164 | .open = snd_atiixp_capture_open, |
1165 | .close = snd_atiixp_capture_close, | 1165 | .close = snd_atiixp_capture_close, |
1166 | .ioctl = snd_pcm_lib_ioctl, | 1166 | .ioctl = snd_pcm_lib_ioctl, |
@@ -1172,7 +1172,7 @@ static struct snd_pcm_ops snd_atiixp_capture_ops = { | |||
1172 | }; | 1172 | }; |
1173 | 1173 | ||
1174 | /* SPDIF playback */ | 1174 | /* SPDIF playback */ |
1175 | static struct snd_pcm_ops snd_atiixp_spdif_ops = { | 1175 | static const struct snd_pcm_ops snd_atiixp_spdif_ops = { |
1176 | .open = snd_atiixp_spdif_open, | 1176 | .open = snd_atiixp_spdif_open, |
1177 | .close = snd_atiixp_spdif_close, | 1177 | .close = snd_atiixp_spdif_close, |
1178 | .ioctl = snd_pcm_lib_ioctl, | 1178 | .ioctl = snd_pcm_lib_ioctl, |
diff --git a/sound/pci/atiixp_modem.c b/sound/pci/atiixp_modem.c index c534552963e7..40152feef1e7 100644 --- a/sound/pci/atiixp_modem.c +++ b/sound/pci/atiixp_modem.c | |||
@@ -947,7 +947,7 @@ static int snd_atiixp_capture_close(struct snd_pcm_substream *substream) | |||
947 | 947 | ||
948 | 948 | ||
949 | /* AC97 playback */ | 949 | /* AC97 playback */ |
950 | static struct snd_pcm_ops snd_atiixp_playback_ops = { | 950 | static const struct snd_pcm_ops snd_atiixp_playback_ops = { |
951 | .open = snd_atiixp_playback_open, | 951 | .open = snd_atiixp_playback_open, |
952 | .close = snd_atiixp_playback_close, | 952 | .close = snd_atiixp_playback_close, |
953 | .ioctl = snd_pcm_lib_ioctl, | 953 | .ioctl = snd_pcm_lib_ioctl, |
@@ -959,7 +959,7 @@ static struct snd_pcm_ops snd_atiixp_playback_ops = { | |||
959 | }; | 959 | }; |
960 | 960 | ||
961 | /* AC97 capture */ | 961 | /* AC97 capture */ |
962 | static struct snd_pcm_ops snd_atiixp_capture_ops = { | 962 | static const struct snd_pcm_ops snd_atiixp_capture_ops = { |
963 | .open = snd_atiixp_capture_open, | 963 | .open = snd_atiixp_capture_open, |
964 | .close = snd_atiixp_capture_close, | 964 | .close = snd_atiixp_capture_close, |
965 | .ioctl = snd_pcm_lib_ioctl, | 965 | .ioctl = snd_pcm_lib_ioctl, |
diff --git a/sound/pci/au88x0/au88x0_core.c b/sound/pci/au88x0/au88x0_core.c index d3125c169684..e1af24f87566 100644 --- a/sound/pci/au88x0/au88x0_core.c +++ b/sound/pci/au88x0/au88x0_core.c | |||
@@ -1043,7 +1043,7 @@ static void vortex_fifo_init(vortex_t * vortex) | |||
1043 | for (x = NR_ADB - 1; x >= 0; x--) { | 1043 | for (x = NR_ADB - 1; x >= 0; x--) { |
1044 | hwwrite(vortex->mmio, addr, (FIFO_U0 | FIFO_U1)); | 1044 | hwwrite(vortex->mmio, addr, (FIFO_U0 | FIFO_U1)); |
1045 | if (hwread(vortex->mmio, addr) != (FIFO_U0 | FIFO_U1)) | 1045 | if (hwread(vortex->mmio, addr) != (FIFO_U0 | FIFO_U1)) |
1046 | dev_err(vortex->card->dev, "bad adb fifo reset!"); | 1046 | dev_err(vortex->card->dev, "bad adb fifo reset!\n"); |
1047 | vortex_fifo_clearadbdata(vortex, x, FIFO_SIZE); | 1047 | vortex_fifo_clearadbdata(vortex, x, FIFO_SIZE); |
1048 | addr -= 4; | 1048 | addr -= 4; |
1049 | } | 1049 | } |
diff --git a/sound/pci/aw2/aw2-alsa.c b/sound/pci/aw2/aw2-alsa.c index 167714303070..57bbb87d0c62 100644 --- a/sound/pci/aw2/aw2-alsa.c +++ b/sound/pci/aw2/aw2-alsa.c | |||
@@ -179,7 +179,7 @@ static struct pci_driver aw2_driver = { | |||
179 | module_pci_driver(aw2_driver); | 179 | module_pci_driver(aw2_driver); |
180 | 180 | ||
181 | /* operators for playback PCM alsa interface */ | 181 | /* operators for playback PCM alsa interface */ |
182 | static struct snd_pcm_ops snd_aw2_playback_ops = { | 182 | static const struct snd_pcm_ops snd_aw2_playback_ops = { |
183 | .open = snd_aw2_pcm_playback_open, | 183 | .open = snd_aw2_pcm_playback_open, |
184 | .close = snd_aw2_pcm_playback_close, | 184 | .close = snd_aw2_pcm_playback_close, |
185 | .ioctl = snd_pcm_lib_ioctl, | 185 | .ioctl = snd_pcm_lib_ioctl, |
@@ -191,7 +191,7 @@ static struct snd_pcm_ops snd_aw2_playback_ops = { | |||
191 | }; | 191 | }; |
192 | 192 | ||
193 | /* operators for capture PCM alsa interface */ | 193 | /* operators for capture PCM alsa interface */ |
194 | static struct snd_pcm_ops snd_aw2_capture_ops = { | 194 | static const struct snd_pcm_ops snd_aw2_capture_ops = { |
195 | .open = snd_aw2_pcm_capture_open, | 195 | .open = snd_aw2_pcm_capture_open, |
196 | .close = snd_aw2_pcm_capture_close, | 196 | .close = snd_aw2_pcm_capture_close, |
197 | .ioctl = snd_pcm_lib_ioctl, | 197 | .ioctl = snd_pcm_lib_ioctl, |
diff --git a/sound/pci/azt3328.c b/sound/pci/azt3328.c index 5e2ef0bb7057..80c4a4456197 100644 --- a/sound/pci/azt3328.c +++ b/sound/pci/azt3328.c | |||
@@ -2090,7 +2090,7 @@ snd_azf3328_pcm_close(struct snd_pcm_substream *substream | |||
2090 | 2090 | ||
2091 | /******************************************************************/ | 2091 | /******************************************************************/ |
2092 | 2092 | ||
2093 | static struct snd_pcm_ops snd_azf3328_playback_ops = { | 2093 | static const struct snd_pcm_ops snd_azf3328_playback_ops = { |
2094 | .open = snd_azf3328_pcm_playback_open, | 2094 | .open = snd_azf3328_pcm_playback_open, |
2095 | .close = snd_azf3328_pcm_close, | 2095 | .close = snd_azf3328_pcm_close, |
2096 | .ioctl = snd_pcm_lib_ioctl, | 2096 | .ioctl = snd_pcm_lib_ioctl, |
@@ -2101,7 +2101,7 @@ static struct snd_pcm_ops snd_azf3328_playback_ops = { | |||
2101 | .pointer = snd_azf3328_pcm_pointer | 2101 | .pointer = snd_azf3328_pcm_pointer |
2102 | }; | 2102 | }; |
2103 | 2103 | ||
2104 | static struct snd_pcm_ops snd_azf3328_capture_ops = { | 2104 | static const struct snd_pcm_ops snd_azf3328_capture_ops = { |
2105 | .open = snd_azf3328_pcm_capture_open, | 2105 | .open = snd_azf3328_pcm_capture_open, |
2106 | .close = snd_azf3328_pcm_close, | 2106 | .close = snd_azf3328_pcm_close, |
2107 | .ioctl = snd_pcm_lib_ioctl, | 2107 | .ioctl = snd_pcm_lib_ioctl, |
@@ -2112,7 +2112,7 @@ static struct snd_pcm_ops snd_azf3328_capture_ops = { | |||
2112 | .pointer = snd_azf3328_pcm_pointer | 2112 | .pointer = snd_azf3328_pcm_pointer |
2113 | }; | 2113 | }; |
2114 | 2114 | ||
2115 | static struct snd_pcm_ops snd_azf3328_i2s_out_ops = { | 2115 | static const struct snd_pcm_ops snd_azf3328_i2s_out_ops = { |
2116 | .open = snd_azf3328_pcm_i2s_out_open, | 2116 | .open = snd_azf3328_pcm_i2s_out_open, |
2117 | .close = snd_azf3328_pcm_close, | 2117 | .close = snd_azf3328_pcm_close, |
2118 | .ioctl = snd_pcm_lib_ioctl, | 2118 | .ioctl = snd_pcm_lib_ioctl, |
diff --git a/sound/pci/bt87x.c b/sound/pci/bt87x.c index 5925b7170e25..f2c0709d7441 100644 --- a/sound/pci/bt87x.c +++ b/sound/pci/bt87x.c | |||
@@ -550,7 +550,7 @@ static snd_pcm_uframes_t snd_bt87x_pointer(struct snd_pcm_substream *substream) | |||
550 | return (snd_pcm_uframes_t)bytes_to_frames(runtime, chip->current_line * chip->line_bytes); | 550 | return (snd_pcm_uframes_t)bytes_to_frames(runtime, chip->current_line * chip->line_bytes); |
551 | } | 551 | } |
552 | 552 | ||
553 | static struct snd_pcm_ops snd_bt87x_pcm_ops = { | 553 | static const struct snd_pcm_ops snd_bt87x_pcm_ops = { |
554 | .open = snd_bt87x_pcm_open, | 554 | .open = snd_bt87x_pcm_open, |
555 | .close = snd_bt87x_close, | 555 | .close = snd_bt87x_close, |
556 | .ioctl = snd_pcm_lib_ioctl, | 556 | .ioctl = snd_pcm_lib_ioctl, |
diff --git a/sound/pci/ca0106/ca0106_main.c b/sound/pci/ca0106/ca0106_main.c index d3cd95633ee2..6165a57a94ae 100644 --- a/sound/pci/ca0106/ca0106_main.c +++ b/sound/pci/ca0106/ca0106_main.c | |||
@@ -1109,7 +1109,7 @@ snd_ca0106_pcm_pointer_capture(struct snd_pcm_substream *substream) | |||
1109 | } | 1109 | } |
1110 | 1110 | ||
1111 | /* operators */ | 1111 | /* operators */ |
1112 | static struct snd_pcm_ops snd_ca0106_playback_front_ops = { | 1112 | static const struct snd_pcm_ops snd_ca0106_playback_front_ops = { |
1113 | .open = snd_ca0106_pcm_open_playback_front, | 1113 | .open = snd_ca0106_pcm_open_playback_front, |
1114 | .close = snd_ca0106_pcm_close_playback, | 1114 | .close = snd_ca0106_pcm_close_playback, |
1115 | .ioctl = snd_pcm_lib_ioctl, | 1115 | .ioctl = snd_pcm_lib_ioctl, |
@@ -1120,7 +1120,7 @@ static struct snd_pcm_ops snd_ca0106_playback_front_ops = { | |||
1120 | .pointer = snd_ca0106_pcm_pointer_playback, | 1120 | .pointer = snd_ca0106_pcm_pointer_playback, |
1121 | }; | 1121 | }; |
1122 | 1122 | ||
1123 | static struct snd_pcm_ops snd_ca0106_capture_0_ops = { | 1123 | static const struct snd_pcm_ops snd_ca0106_capture_0_ops = { |
1124 | .open = snd_ca0106_pcm_open_0_capture, | 1124 | .open = snd_ca0106_pcm_open_0_capture, |
1125 | .close = snd_ca0106_pcm_close_capture, | 1125 | .close = snd_ca0106_pcm_close_capture, |
1126 | .ioctl = snd_pcm_lib_ioctl, | 1126 | .ioctl = snd_pcm_lib_ioctl, |
@@ -1131,7 +1131,7 @@ static struct snd_pcm_ops snd_ca0106_capture_0_ops = { | |||
1131 | .pointer = snd_ca0106_pcm_pointer_capture, | 1131 | .pointer = snd_ca0106_pcm_pointer_capture, |
1132 | }; | 1132 | }; |
1133 | 1133 | ||
1134 | static struct snd_pcm_ops snd_ca0106_capture_1_ops = { | 1134 | static const struct snd_pcm_ops snd_ca0106_capture_1_ops = { |
1135 | .open = snd_ca0106_pcm_open_1_capture, | 1135 | .open = snd_ca0106_pcm_open_1_capture, |
1136 | .close = snd_ca0106_pcm_close_capture, | 1136 | .close = snd_ca0106_pcm_close_capture, |
1137 | .ioctl = snd_pcm_lib_ioctl, | 1137 | .ioctl = snd_pcm_lib_ioctl, |
@@ -1142,7 +1142,7 @@ static struct snd_pcm_ops snd_ca0106_capture_1_ops = { | |||
1142 | .pointer = snd_ca0106_pcm_pointer_capture, | 1142 | .pointer = snd_ca0106_pcm_pointer_capture, |
1143 | }; | 1143 | }; |
1144 | 1144 | ||
1145 | static struct snd_pcm_ops snd_ca0106_capture_2_ops = { | 1145 | static const struct snd_pcm_ops snd_ca0106_capture_2_ops = { |
1146 | .open = snd_ca0106_pcm_open_2_capture, | 1146 | .open = snd_ca0106_pcm_open_2_capture, |
1147 | .close = snd_ca0106_pcm_close_capture, | 1147 | .close = snd_ca0106_pcm_close_capture, |
1148 | .ioctl = snd_pcm_lib_ioctl, | 1148 | .ioctl = snd_pcm_lib_ioctl, |
@@ -1153,7 +1153,7 @@ static struct snd_pcm_ops snd_ca0106_capture_2_ops = { | |||
1153 | .pointer = snd_ca0106_pcm_pointer_capture, | 1153 | .pointer = snd_ca0106_pcm_pointer_capture, |
1154 | }; | 1154 | }; |
1155 | 1155 | ||
1156 | static struct snd_pcm_ops snd_ca0106_capture_3_ops = { | 1156 | static const struct snd_pcm_ops snd_ca0106_capture_3_ops = { |
1157 | .open = snd_ca0106_pcm_open_3_capture, | 1157 | .open = snd_ca0106_pcm_open_3_capture, |
1158 | .close = snd_ca0106_pcm_close_capture, | 1158 | .close = snd_ca0106_pcm_close_capture, |
1159 | .ioctl = snd_pcm_lib_ioctl, | 1159 | .ioctl = snd_pcm_lib_ioctl, |
@@ -1164,7 +1164,7 @@ static struct snd_pcm_ops snd_ca0106_capture_3_ops = { | |||
1164 | .pointer = snd_ca0106_pcm_pointer_capture, | 1164 | .pointer = snd_ca0106_pcm_pointer_capture, |
1165 | }; | 1165 | }; |
1166 | 1166 | ||
1167 | static struct snd_pcm_ops snd_ca0106_playback_center_lfe_ops = { | 1167 | static const struct snd_pcm_ops snd_ca0106_playback_center_lfe_ops = { |
1168 | .open = snd_ca0106_pcm_open_playback_center_lfe, | 1168 | .open = snd_ca0106_pcm_open_playback_center_lfe, |
1169 | .close = snd_ca0106_pcm_close_playback, | 1169 | .close = snd_ca0106_pcm_close_playback, |
1170 | .ioctl = snd_pcm_lib_ioctl, | 1170 | .ioctl = snd_pcm_lib_ioctl, |
@@ -1175,7 +1175,7 @@ static struct snd_pcm_ops snd_ca0106_playback_center_lfe_ops = { | |||
1175 | .pointer = snd_ca0106_pcm_pointer_playback, | 1175 | .pointer = snd_ca0106_pcm_pointer_playback, |
1176 | }; | 1176 | }; |
1177 | 1177 | ||
1178 | static struct snd_pcm_ops snd_ca0106_playback_unknown_ops = { | 1178 | static const struct snd_pcm_ops snd_ca0106_playback_unknown_ops = { |
1179 | .open = snd_ca0106_pcm_open_playback_unknown, | 1179 | .open = snd_ca0106_pcm_open_playback_unknown, |
1180 | .close = snd_ca0106_pcm_close_playback, | 1180 | .close = snd_ca0106_pcm_close_playback, |
1181 | .ioctl = snd_pcm_lib_ioctl, | 1181 | .ioctl = snd_pcm_lib_ioctl, |
@@ -1186,7 +1186,7 @@ static struct snd_pcm_ops snd_ca0106_playback_unknown_ops = { | |||
1186 | .pointer = snd_ca0106_pcm_pointer_playback, | 1186 | .pointer = snd_ca0106_pcm_pointer_playback, |
1187 | }; | 1187 | }; |
1188 | 1188 | ||
1189 | static struct snd_pcm_ops snd_ca0106_playback_rear_ops = { | 1189 | static const struct snd_pcm_ops snd_ca0106_playback_rear_ops = { |
1190 | .open = snd_ca0106_pcm_open_playback_rear, | 1190 | .open = snd_ca0106_pcm_open_playback_rear, |
1191 | .close = snd_ca0106_pcm_close_playback, | 1191 | .close = snd_ca0106_pcm_close_playback, |
1192 | .ioctl = snd_pcm_lib_ioctl, | 1192 | .ioctl = snd_pcm_lib_ioctl, |
diff --git a/sound/pci/cmipci.c b/sound/pci/cmipci.c index 24cdcba06d27..73f593526b2d 100644 --- a/sound/pci/cmipci.c +++ b/sound/pci/cmipci.c | |||
@@ -1838,7 +1838,7 @@ static int snd_cmipci_capture_spdif_close(struct snd_pcm_substream *substream) | |||
1838 | /* | 1838 | /* |
1839 | */ | 1839 | */ |
1840 | 1840 | ||
1841 | static struct snd_pcm_ops snd_cmipci_playback_ops = { | 1841 | static const struct snd_pcm_ops snd_cmipci_playback_ops = { |
1842 | .open = snd_cmipci_playback_open, | 1842 | .open = snd_cmipci_playback_open, |
1843 | .close = snd_cmipci_playback_close, | 1843 | .close = snd_cmipci_playback_close, |
1844 | .ioctl = snd_pcm_lib_ioctl, | 1844 | .ioctl = snd_pcm_lib_ioctl, |
@@ -1849,7 +1849,7 @@ static struct snd_pcm_ops snd_cmipci_playback_ops = { | |||
1849 | .pointer = snd_cmipci_playback_pointer, | 1849 | .pointer = snd_cmipci_playback_pointer, |
1850 | }; | 1850 | }; |
1851 | 1851 | ||
1852 | static struct snd_pcm_ops snd_cmipci_capture_ops = { | 1852 | static const struct snd_pcm_ops snd_cmipci_capture_ops = { |
1853 | .open = snd_cmipci_capture_open, | 1853 | .open = snd_cmipci_capture_open, |
1854 | .close = snd_cmipci_capture_close, | 1854 | .close = snd_cmipci_capture_close, |
1855 | .ioctl = snd_pcm_lib_ioctl, | 1855 | .ioctl = snd_pcm_lib_ioctl, |
@@ -1860,7 +1860,7 @@ static struct snd_pcm_ops snd_cmipci_capture_ops = { | |||
1860 | .pointer = snd_cmipci_capture_pointer, | 1860 | .pointer = snd_cmipci_capture_pointer, |
1861 | }; | 1861 | }; |
1862 | 1862 | ||
1863 | static struct snd_pcm_ops snd_cmipci_playback2_ops = { | 1863 | static const struct snd_pcm_ops snd_cmipci_playback2_ops = { |
1864 | .open = snd_cmipci_playback2_open, | 1864 | .open = snd_cmipci_playback2_open, |
1865 | .close = snd_cmipci_playback2_close, | 1865 | .close = snd_cmipci_playback2_close, |
1866 | .ioctl = snd_pcm_lib_ioctl, | 1866 | .ioctl = snd_pcm_lib_ioctl, |
@@ -1871,7 +1871,7 @@ static struct snd_pcm_ops snd_cmipci_playback2_ops = { | |||
1871 | .pointer = snd_cmipci_capture_pointer, /* channel B */ | 1871 | .pointer = snd_cmipci_capture_pointer, /* channel B */ |
1872 | }; | 1872 | }; |
1873 | 1873 | ||
1874 | static struct snd_pcm_ops snd_cmipci_playback_spdif_ops = { | 1874 | static const struct snd_pcm_ops snd_cmipci_playback_spdif_ops = { |
1875 | .open = snd_cmipci_playback_spdif_open, | 1875 | .open = snd_cmipci_playback_spdif_open, |
1876 | .close = snd_cmipci_playback_spdif_close, | 1876 | .close = snd_cmipci_playback_spdif_close, |
1877 | .ioctl = snd_pcm_lib_ioctl, | 1877 | .ioctl = snd_pcm_lib_ioctl, |
@@ -1882,7 +1882,7 @@ static struct snd_pcm_ops snd_cmipci_playback_spdif_ops = { | |||
1882 | .pointer = snd_cmipci_playback_pointer, | 1882 | .pointer = snd_cmipci_playback_pointer, |
1883 | }; | 1883 | }; |
1884 | 1884 | ||
1885 | static struct snd_pcm_ops snd_cmipci_capture_spdif_ops = { | 1885 | static const struct snd_pcm_ops snd_cmipci_capture_spdif_ops = { |
1886 | .open = snd_cmipci_capture_spdif_open, | 1886 | .open = snd_cmipci_capture_spdif_open, |
1887 | .close = snd_cmipci_capture_spdif_close, | 1887 | .close = snd_cmipci_capture_spdif_close, |
1888 | .ioctl = snd_pcm_lib_ioctl, | 1888 | .ioctl = snd_pcm_lib_ioctl, |
diff --git a/sound/pci/cs4281.c b/sound/pci/cs4281.c index c296fd0dbc9c..615d8a99d8c8 100644 --- a/sound/pci/cs4281.c +++ b/sound/pci/cs4281.c | |||
@@ -951,7 +951,7 @@ static int snd_cs4281_capture_close(struct snd_pcm_substream *substream) | |||
951 | return 0; | 951 | return 0; |
952 | } | 952 | } |
953 | 953 | ||
954 | static struct snd_pcm_ops snd_cs4281_playback_ops = { | 954 | static const struct snd_pcm_ops snd_cs4281_playback_ops = { |
955 | .open = snd_cs4281_playback_open, | 955 | .open = snd_cs4281_playback_open, |
956 | .close = snd_cs4281_playback_close, | 956 | .close = snd_cs4281_playback_close, |
957 | .ioctl = snd_pcm_lib_ioctl, | 957 | .ioctl = snd_pcm_lib_ioctl, |
@@ -962,7 +962,7 @@ static struct snd_pcm_ops snd_cs4281_playback_ops = { | |||
962 | .pointer = snd_cs4281_pointer, | 962 | .pointer = snd_cs4281_pointer, |
963 | }; | 963 | }; |
964 | 964 | ||
965 | static struct snd_pcm_ops snd_cs4281_capture_ops = { | 965 | static const struct snd_pcm_ops snd_cs4281_capture_ops = { |
966 | .open = snd_cs4281_capture_open, | 966 | .open = snd_cs4281_capture_open, |
967 | .close = snd_cs4281_capture_close, | 967 | .close = snd_cs4281_capture_close, |
968 | .ioctl = snd_pcm_lib_ioctl, | 968 | .ioctl = snd_pcm_lib_ioctl, |
diff --git a/sound/pci/cs46xx/cs46xx_lib.c b/sound/pci/cs46xx/cs46xx_lib.c index 2706f271a83b..528102cc2d5d 100644 --- a/sound/pci/cs46xx/cs46xx_lib.c +++ b/sound/pci/cs46xx/cs46xx_lib.c | |||
@@ -2460,7 +2460,7 @@ static int cs46xx_detect_codec(struct snd_cs46xx *chip, int codec) | |||
2460 | udelay(10); | 2460 | udelay(10); |
2461 | if (snd_cs46xx_codec_read(chip, AC97_RESET, codec) & 0x8000) { | 2461 | if (snd_cs46xx_codec_read(chip, AC97_RESET, codec) & 0x8000) { |
2462 | dev_dbg(chip->card->dev, | 2462 | dev_dbg(chip->card->dev, |
2463 | "seconadry codec not present\n"); | 2463 | "secondary codec not present\n"); |
2464 | return -ENXIO; | 2464 | return -ENXIO; |
2465 | } | 2465 | } |
2466 | } | 2466 | } |
@@ -2503,7 +2503,7 @@ int snd_cs46xx_mixer(struct snd_cs46xx *chip, int spdif_device) | |||
2503 | chip->nr_ac97_codecs = 1; | 2503 | chip->nr_ac97_codecs = 1; |
2504 | 2504 | ||
2505 | #ifdef CONFIG_SND_CS46XX_NEW_DSP | 2505 | #ifdef CONFIG_SND_CS46XX_NEW_DSP |
2506 | dev_dbg(chip->card->dev, "detecting seconadry codec\n"); | 2506 | dev_dbg(chip->card->dev, "detecting secondary codec\n"); |
2507 | /* try detect a secondary codec */ | 2507 | /* try detect a secondary codec */ |
2508 | if (! cs46xx_detect_codec(chip, CS46XX_SECONDARY_CODEC_INDEX)) | 2508 | if (! cs46xx_detect_codec(chip, CS46XX_SECONDARY_CODEC_INDEX)) |
2509 | chip->nr_ac97_codecs = 2; | 2509 | chip->nr_ac97_codecs = 2; |
diff --git a/sound/pci/cs46xx/dsp_spos.c b/sound/pci/cs46xx/dsp_spos.c index d2951ed4bf71..4a0cbd2241d8 100644 --- a/sound/pci/cs46xx/dsp_spos.c +++ b/sound/pci/cs46xx/dsp_spos.c | |||
@@ -1441,7 +1441,7 @@ int cs46xx_dsp_scb_and_task_init (struct snd_cs46xx *chip) | |||
1441 | 1441 | ||
1442 | if (chip->nr_ac97_codecs == 2) { | 1442 | if (chip->nr_ac97_codecs == 2) { |
1443 | /* create CODEC tasklet for rear Center/LFE output | 1443 | /* create CODEC tasklet for rear Center/LFE output |
1444 | slot 6 and 9 on seconadry CODEC */ | 1444 | slot 6 and 9 on secondary CODEC */ |
1445 | clfe_codec_out_scb = cs46xx_dsp_create_codec_out_scb(chip,"CodecOutSCB_CLFE",0x0030,0x0030, | 1445 | clfe_codec_out_scb = cs46xx_dsp_create_codec_out_scb(chip,"CodecOutSCB_CLFE",0x0030,0x0030, |
1446 | CLFE_MIXER_SCB_ADDR, | 1446 | CLFE_MIXER_SCB_ADDR, |
1447 | CLFE_CODEC_SCB_ADDR, | 1447 | CLFE_CODEC_SCB_ADDR, |
diff --git a/sound/pci/cs5535audio/cs5535audio_pcm.c b/sound/pci/cs5535audio/cs5535audio_pcm.c index 27fa57da8dc4..c208c1d8dbb2 100644 --- a/sound/pci/cs5535audio/cs5535audio_pcm.c +++ b/sound/pci/cs5535audio/cs5535audio_pcm.c | |||
@@ -380,7 +380,7 @@ static int snd_cs5535audio_capture_prepare(struct snd_pcm_substream *substream) | |||
380 | substream->runtime->rate); | 380 | substream->runtime->rate); |
381 | } | 381 | } |
382 | 382 | ||
383 | static struct snd_pcm_ops snd_cs5535audio_playback_ops = { | 383 | static const struct snd_pcm_ops snd_cs5535audio_playback_ops = { |
384 | .open = snd_cs5535audio_playback_open, | 384 | .open = snd_cs5535audio_playback_open, |
385 | .close = snd_cs5535audio_playback_close, | 385 | .close = snd_cs5535audio_playback_close, |
386 | .ioctl = snd_pcm_lib_ioctl, | 386 | .ioctl = snd_pcm_lib_ioctl, |
@@ -391,7 +391,7 @@ static struct snd_pcm_ops snd_cs5535audio_playback_ops = { | |||
391 | .pointer = snd_cs5535audio_pcm_pointer, | 391 | .pointer = snd_cs5535audio_pcm_pointer, |
392 | }; | 392 | }; |
393 | 393 | ||
394 | static struct snd_pcm_ops snd_cs5535audio_capture_ops = { | 394 | static const struct snd_pcm_ops snd_cs5535audio_capture_ops = { |
395 | .open = snd_cs5535audio_capture_open, | 395 | .open = snd_cs5535audio_capture_open, |
396 | .close = snd_cs5535audio_capture_close, | 396 | .close = snd_cs5535audio_capture_close, |
397 | .ioctl = snd_pcm_lib_ioctl, | 397 | .ioctl = snd_pcm_lib_ioctl, |
diff --git a/sound/pci/ctxfi/ctatc.c b/sound/pci/ctxfi/ctatc.c index 977a59855fa6..908658a00377 100644 --- a/sound/pci/ctxfi/ctatc.c +++ b/sound/pci/ctxfi/ctatc.c | |||
@@ -1623,7 +1623,7 @@ static int atc_resume(struct ct_atc *atc) | |||
1623 | } | 1623 | } |
1624 | #endif | 1624 | #endif |
1625 | 1625 | ||
1626 | static struct ct_atc atc_preset = { | 1626 | static const struct ct_atc atc_preset = { |
1627 | .map_audio_buffer = ct_map_audio_buffer, | 1627 | .map_audio_buffer = ct_map_audio_buffer, |
1628 | .unmap_audio_buffer = ct_unmap_audio_buffer, | 1628 | .unmap_audio_buffer = ct_unmap_audio_buffer, |
1629 | .pcm_playback_prepare = atc_pcm_playback_prepare, | 1629 | .pcm_playback_prepare = atc_pcm_playback_prepare, |
diff --git a/sound/pci/ctxfi/ctpcm.c b/sound/pci/ctxfi/ctpcm.c index d86c474ca5b6..974978041558 100644 --- a/sound/pci/ctxfi/ctpcm.c +++ b/sound/pci/ctxfi/ctpcm.c | |||
@@ -372,7 +372,7 @@ ct_pcm_capture_pointer(struct snd_pcm_substream *substream) | |||
372 | } | 372 | } |
373 | 373 | ||
374 | /* PCM operators for playback */ | 374 | /* PCM operators for playback */ |
375 | static struct snd_pcm_ops ct_pcm_playback_ops = { | 375 | static const struct snd_pcm_ops ct_pcm_playback_ops = { |
376 | .open = ct_pcm_playback_open, | 376 | .open = ct_pcm_playback_open, |
377 | .close = ct_pcm_playback_close, | 377 | .close = ct_pcm_playback_close, |
378 | .ioctl = snd_pcm_lib_ioctl, | 378 | .ioctl = snd_pcm_lib_ioctl, |
@@ -385,7 +385,7 @@ static struct snd_pcm_ops ct_pcm_playback_ops = { | |||
385 | }; | 385 | }; |
386 | 386 | ||
387 | /* PCM operators for capture */ | 387 | /* PCM operators for capture */ |
388 | static struct snd_pcm_ops ct_pcm_capture_ops = { | 388 | static const struct snd_pcm_ops ct_pcm_capture_ops = { |
389 | .open = ct_pcm_capture_open, | 389 | .open = ct_pcm_capture_open, |
390 | .close = ct_pcm_capture_close, | 390 | .close = ct_pcm_capture_close, |
391 | .ioctl = snd_pcm_lib_ioctl, | 391 | .ioctl = snd_pcm_lib_ioctl, |
diff --git a/sound/pci/ctxfi/ctvmem.c b/sound/pci/ctxfi/ctvmem.c index 419306ef825f..520e19bc649f 100644 --- a/sound/pci/ctxfi/ctvmem.c +++ b/sound/pci/ctxfi/ctvmem.c | |||
@@ -166,11 +166,7 @@ static void ct_vm_unmap(struct ct_vm *vm, struct ct_vm_block *block) | |||
166 | static dma_addr_t | 166 | static dma_addr_t |
167 | ct_get_ptp_phys(struct ct_vm *vm, int index) | 167 | ct_get_ptp_phys(struct ct_vm *vm, int index) |
168 | { | 168 | { |
169 | dma_addr_t addr; | 169 | return (index >= CT_PTP_NUM) ? ~0UL : vm->ptp[index].addr; |
170 | |||
171 | addr = (index >= CT_PTP_NUM) ? ~0UL : vm->ptp[index].addr; | ||
172 | |||
173 | return addr; | ||
174 | } | 170 | } |
175 | 171 | ||
176 | int ct_vm_create(struct ct_vm **rvm, struct pci_dev *pci) | 172 | int ct_vm_create(struct ct_vm **rvm, struct pci_dev *pci) |
diff --git a/sound/pci/emu10k1/emu10k1x.c b/sound/pci/emu10k1/emu10k1x.c index 6d1b98d14327..921037ed8468 100644 --- a/sound/pci/emu10k1/emu10k1x.c +++ b/sound/pci/emu10k1/emu10k1x.c | |||
@@ -548,7 +548,7 @@ snd_emu10k1x_pcm_pointer(struct snd_pcm_substream *substream) | |||
548 | } | 548 | } |
549 | 549 | ||
550 | /* operators */ | 550 | /* operators */ |
551 | static struct snd_pcm_ops snd_emu10k1x_playback_ops = { | 551 | static const struct snd_pcm_ops snd_emu10k1x_playback_ops = { |
552 | .open = snd_emu10k1x_playback_open, | 552 | .open = snd_emu10k1x_playback_open, |
553 | .close = snd_emu10k1x_playback_close, | 553 | .close = snd_emu10k1x_playback_close, |
554 | .ioctl = snd_pcm_lib_ioctl, | 554 | .ioctl = snd_pcm_lib_ioctl, |
@@ -694,7 +694,7 @@ snd_emu10k1x_pcm_pointer_capture(struct snd_pcm_substream *substream) | |||
694 | return ptr; | 694 | return ptr; |
695 | } | 695 | } |
696 | 696 | ||
697 | static struct snd_pcm_ops snd_emu10k1x_capture_ops = { | 697 | static const struct snd_pcm_ops snd_emu10k1x_capture_ops = { |
698 | .open = snd_emu10k1x_pcm_open_capture, | 698 | .open = snd_emu10k1x_pcm_open_capture, |
699 | .close = snd_emu10k1x_pcm_close_capture, | 699 | .close = snd_emu10k1x_pcm_close_capture, |
700 | .ioctl = snd_pcm_lib_ioctl, | 700 | .ioctl = snd_pcm_lib_ioctl, |
diff --git a/sound/pci/emu10k1/emupcm.c b/sound/pci/emu10k1/emupcm.c index 14a305bd8a98..37be1e14d756 100644 --- a/sound/pci/emu10k1/emupcm.c +++ b/sound/pci/emu10k1/emupcm.c | |||
@@ -1364,7 +1364,7 @@ static int snd_emu10k1_capture_efx_close(struct snd_pcm_substream *substream) | |||
1364 | return 0; | 1364 | return 0; |
1365 | } | 1365 | } |
1366 | 1366 | ||
1367 | static struct snd_pcm_ops snd_emu10k1_playback_ops = { | 1367 | static const struct snd_pcm_ops snd_emu10k1_playback_ops = { |
1368 | .open = snd_emu10k1_playback_open, | 1368 | .open = snd_emu10k1_playback_open, |
1369 | .close = snd_emu10k1_playback_close, | 1369 | .close = snd_emu10k1_playback_close, |
1370 | .ioctl = snd_pcm_lib_ioctl, | 1370 | .ioctl = snd_pcm_lib_ioctl, |
@@ -1376,7 +1376,7 @@ static struct snd_pcm_ops snd_emu10k1_playback_ops = { | |||
1376 | .page = snd_pcm_sgbuf_ops_page, | 1376 | .page = snd_pcm_sgbuf_ops_page, |
1377 | }; | 1377 | }; |
1378 | 1378 | ||
1379 | static struct snd_pcm_ops snd_emu10k1_capture_ops = { | 1379 | static const struct snd_pcm_ops snd_emu10k1_capture_ops = { |
1380 | .open = snd_emu10k1_capture_open, | 1380 | .open = snd_emu10k1_capture_open, |
1381 | .close = snd_emu10k1_capture_close, | 1381 | .close = snd_emu10k1_capture_close, |
1382 | .ioctl = snd_pcm_lib_ioctl, | 1382 | .ioctl = snd_pcm_lib_ioctl, |
@@ -1388,7 +1388,7 @@ static struct snd_pcm_ops snd_emu10k1_capture_ops = { | |||
1388 | }; | 1388 | }; |
1389 | 1389 | ||
1390 | /* EFX playback */ | 1390 | /* EFX playback */ |
1391 | static struct snd_pcm_ops snd_emu10k1_efx_playback_ops = { | 1391 | static const struct snd_pcm_ops snd_emu10k1_efx_playback_ops = { |
1392 | .open = snd_emu10k1_efx_playback_open, | 1392 | .open = snd_emu10k1_efx_playback_open, |
1393 | .close = snd_emu10k1_efx_playback_close, | 1393 | .close = snd_emu10k1_efx_playback_close, |
1394 | .ioctl = snd_pcm_lib_ioctl, | 1394 | .ioctl = snd_pcm_lib_ioctl, |
@@ -1455,7 +1455,7 @@ int snd_emu10k1_pcm_multi(struct snd_emu10k1 *emu, int device) | |||
1455 | } | 1455 | } |
1456 | 1456 | ||
1457 | 1457 | ||
1458 | static struct snd_pcm_ops snd_emu10k1_capture_mic_ops = { | 1458 | static const struct snd_pcm_ops snd_emu10k1_capture_mic_ops = { |
1459 | .open = snd_emu10k1_capture_mic_open, | 1459 | .open = snd_emu10k1_capture_mic_open, |
1460 | .close = snd_emu10k1_capture_mic_close, | 1460 | .close = snd_emu10k1_capture_mic_close, |
1461 | .ioctl = snd_pcm_lib_ioctl, | 1461 | .ioctl = snd_pcm_lib_ioctl, |
@@ -1550,7 +1550,7 @@ static struct snd_kcontrol_new snd_emu10k1_pcm_efx_voices_mask = { | |||
1550 | .put = snd_emu10k1_pcm_efx_voices_mask_put | 1550 | .put = snd_emu10k1_pcm_efx_voices_mask_put |
1551 | }; | 1551 | }; |
1552 | 1552 | ||
1553 | static struct snd_pcm_ops snd_emu10k1_capture_efx_ops = { | 1553 | static const struct snd_pcm_ops snd_emu10k1_capture_efx_ops = { |
1554 | .open = snd_emu10k1_capture_efx_open, | 1554 | .open = snd_emu10k1_capture_efx_open, |
1555 | .close = snd_emu10k1_capture_efx_close, | 1555 | .close = snd_emu10k1_capture_efx_close, |
1556 | .ioctl = snd_pcm_lib_ioctl, | 1556 | .ioctl = snd_pcm_lib_ioctl, |
@@ -1791,7 +1791,7 @@ static int snd_emu10k1_fx8010_playback_close(struct snd_pcm_substream *substream | |||
1791 | return 0; | 1791 | return 0; |
1792 | } | 1792 | } |
1793 | 1793 | ||
1794 | static struct snd_pcm_ops snd_emu10k1_fx8010_playback_ops = { | 1794 | static const struct snd_pcm_ops snd_emu10k1_fx8010_playback_ops = { |
1795 | .open = snd_emu10k1_fx8010_playback_open, | 1795 | .open = snd_emu10k1_fx8010_playback_open, |
1796 | .close = snd_emu10k1_fx8010_playback_close, | 1796 | .close = snd_emu10k1_fx8010_playback_close, |
1797 | .ioctl = snd_pcm_lib_ioctl, | 1797 | .ioctl = snd_pcm_lib_ioctl, |
diff --git a/sound/pci/emu10k1/p16v.c b/sound/pci/emu10k1/p16v.c index 3c60b433de9f..c11f1a29f35d 100644 --- a/sound/pci/emu10k1/p16v.c +++ b/sound/pci/emu10k1/p16v.c | |||
@@ -300,37 +300,29 @@ static int snd_p16v_pcm_open_capture(struct snd_pcm_substream *substream) | |||
300 | static int snd_p16v_pcm_hw_params_playback(struct snd_pcm_substream *substream, | 300 | static int snd_p16v_pcm_hw_params_playback(struct snd_pcm_substream *substream, |
301 | struct snd_pcm_hw_params *hw_params) | 301 | struct snd_pcm_hw_params *hw_params) |
302 | { | 302 | { |
303 | int result; | 303 | return snd_pcm_lib_malloc_pages(substream, |
304 | result = snd_pcm_lib_malloc_pages(substream, | ||
305 | params_buffer_bytes(hw_params)); | 304 | params_buffer_bytes(hw_params)); |
306 | return result; | ||
307 | } | 305 | } |
308 | 306 | ||
309 | /* hw_params callback */ | 307 | /* hw_params callback */ |
310 | static int snd_p16v_pcm_hw_params_capture(struct snd_pcm_substream *substream, | 308 | static int snd_p16v_pcm_hw_params_capture(struct snd_pcm_substream *substream, |
311 | struct snd_pcm_hw_params *hw_params) | 309 | struct snd_pcm_hw_params *hw_params) |
312 | { | 310 | { |
313 | int result; | 311 | return snd_pcm_lib_malloc_pages(substream, |
314 | result = snd_pcm_lib_malloc_pages(substream, | ||
315 | params_buffer_bytes(hw_params)); | 312 | params_buffer_bytes(hw_params)); |
316 | return result; | ||
317 | } | 313 | } |
318 | 314 | ||
319 | 315 | ||
320 | /* hw_free callback */ | 316 | /* hw_free callback */ |
321 | static int snd_p16v_pcm_hw_free_playback(struct snd_pcm_substream *substream) | 317 | static int snd_p16v_pcm_hw_free_playback(struct snd_pcm_substream *substream) |
322 | { | 318 | { |
323 | int result; | 319 | return snd_pcm_lib_free_pages(substream); |
324 | result = snd_pcm_lib_free_pages(substream); | ||
325 | return result; | ||
326 | } | 320 | } |
327 | 321 | ||
328 | /* hw_free callback */ | 322 | /* hw_free callback */ |
329 | static int snd_p16v_pcm_hw_free_capture(struct snd_pcm_substream *substream) | 323 | static int snd_p16v_pcm_hw_free_capture(struct snd_pcm_substream *substream) |
330 | { | 324 | { |
331 | int result; | 325 | return snd_pcm_lib_free_pages(substream); |
332 | result = snd_pcm_lib_free_pages(substream); | ||
333 | return result; | ||
334 | } | 326 | } |
335 | 327 | ||
336 | 328 | ||
@@ -601,7 +593,7 @@ snd_p16v_pcm_pointer_capture(struct snd_pcm_substream *substream) | |||
601 | } | 593 | } |
602 | 594 | ||
603 | /* operators */ | 595 | /* operators */ |
604 | static struct snd_pcm_ops snd_p16v_playback_front_ops = { | 596 | static const struct snd_pcm_ops snd_p16v_playback_front_ops = { |
605 | .open = snd_p16v_pcm_open_playback_front, | 597 | .open = snd_p16v_pcm_open_playback_front, |
606 | .close = snd_p16v_pcm_close_playback, | 598 | .close = snd_p16v_pcm_close_playback, |
607 | .ioctl = snd_pcm_lib_ioctl, | 599 | .ioctl = snd_pcm_lib_ioctl, |
@@ -612,7 +604,7 @@ static struct snd_pcm_ops snd_p16v_playback_front_ops = { | |||
612 | .pointer = snd_p16v_pcm_pointer_playback, | 604 | .pointer = snd_p16v_pcm_pointer_playback, |
613 | }; | 605 | }; |
614 | 606 | ||
615 | static struct snd_pcm_ops snd_p16v_capture_ops = { | 607 | static const struct snd_pcm_ops snd_p16v_capture_ops = { |
616 | .open = snd_p16v_pcm_open_capture, | 608 | .open = snd_p16v_pcm_open_capture, |
617 | .close = snd_p16v_pcm_close_capture, | 609 | .close = snd_p16v_pcm_close_capture, |
618 | .ioctl = snd_pcm_lib_ioctl, | 610 | .ioctl = snd_pcm_lib_ioctl, |
diff --git a/sound/pci/ens1370.c b/sound/pci/ens1370.c index 626cd2167d29..7e760fed0728 100644 --- a/sound/pci/ens1370.c +++ b/sound/pci/ens1370.c | |||
@@ -1227,7 +1227,7 @@ static int snd_ensoniq_capture_close(struct snd_pcm_substream *substream) | |||
1227 | return 0; | 1227 | return 0; |
1228 | } | 1228 | } |
1229 | 1229 | ||
1230 | static struct snd_pcm_ops snd_ensoniq_playback1_ops = { | 1230 | static const struct snd_pcm_ops snd_ensoniq_playback1_ops = { |
1231 | .open = snd_ensoniq_playback1_open, | 1231 | .open = snd_ensoniq_playback1_open, |
1232 | .close = snd_ensoniq_playback1_close, | 1232 | .close = snd_ensoniq_playback1_close, |
1233 | .ioctl = snd_pcm_lib_ioctl, | 1233 | .ioctl = snd_pcm_lib_ioctl, |
@@ -1238,7 +1238,7 @@ static struct snd_pcm_ops snd_ensoniq_playback1_ops = { | |||
1238 | .pointer = snd_ensoniq_playback1_pointer, | 1238 | .pointer = snd_ensoniq_playback1_pointer, |
1239 | }; | 1239 | }; |
1240 | 1240 | ||
1241 | static struct snd_pcm_ops snd_ensoniq_playback2_ops = { | 1241 | static const struct snd_pcm_ops snd_ensoniq_playback2_ops = { |
1242 | .open = snd_ensoniq_playback2_open, | 1242 | .open = snd_ensoniq_playback2_open, |
1243 | .close = snd_ensoniq_playback2_close, | 1243 | .close = snd_ensoniq_playback2_close, |
1244 | .ioctl = snd_pcm_lib_ioctl, | 1244 | .ioctl = snd_pcm_lib_ioctl, |
@@ -1249,7 +1249,7 @@ static struct snd_pcm_ops snd_ensoniq_playback2_ops = { | |||
1249 | .pointer = snd_ensoniq_playback2_pointer, | 1249 | .pointer = snd_ensoniq_playback2_pointer, |
1250 | }; | 1250 | }; |
1251 | 1251 | ||
1252 | static struct snd_pcm_ops snd_ensoniq_capture_ops = { | 1252 | static const struct snd_pcm_ops snd_ensoniq_capture_ops = { |
1253 | .open = snd_ensoniq_capture_open, | 1253 | .open = snd_ensoniq_capture_open, |
1254 | .close = snd_ensoniq_capture_close, | 1254 | .close = snd_ensoniq_capture_close, |
1255 | .ioctl = snd_pcm_lib_ioctl, | 1255 | .ioctl = snd_pcm_lib_ioctl, |
diff --git a/sound/pci/es1938.c b/sound/pci/es1938.c index 8963d7688fb0..681355829484 100644 --- a/sound/pci/es1938.c +++ b/sound/pci/es1938.c | |||
@@ -992,7 +992,7 @@ static int snd_es1938_playback_close(struct snd_pcm_substream *substream) | |||
992 | return 0; | 992 | return 0; |
993 | } | 993 | } |
994 | 994 | ||
995 | static struct snd_pcm_ops snd_es1938_playback_ops = { | 995 | static const struct snd_pcm_ops snd_es1938_playback_ops = { |
996 | .open = snd_es1938_playback_open, | 996 | .open = snd_es1938_playback_open, |
997 | .close = snd_es1938_playback_close, | 997 | .close = snd_es1938_playback_close, |
998 | .ioctl = snd_pcm_lib_ioctl, | 998 | .ioctl = snd_pcm_lib_ioctl, |
@@ -1003,7 +1003,7 @@ static struct snd_pcm_ops snd_es1938_playback_ops = { | |||
1003 | .pointer = snd_es1938_playback_pointer, | 1003 | .pointer = snd_es1938_playback_pointer, |
1004 | }; | 1004 | }; |
1005 | 1005 | ||
1006 | static struct snd_pcm_ops snd_es1938_capture_ops = { | 1006 | static const struct snd_pcm_ops snd_es1938_capture_ops = { |
1007 | .open = snd_es1938_capture_open, | 1007 | .open = snd_es1938_capture_open, |
1008 | .close = snd_es1938_capture_close, | 1008 | .close = snd_es1938_capture_close, |
1009 | .ioctl = snd_pcm_lib_ioctl, | 1009 | .ioctl = snd_pcm_lib_ioctl, |
diff --git a/sound/pci/es1968.c b/sound/pci/es1968.c index 514f2604086e..8146fb76a4ad 100644 --- a/sound/pci/es1968.c +++ b/sound/pci/es1968.c | |||
@@ -1677,7 +1677,7 @@ static int snd_es1968_capture_close(struct snd_pcm_substream *substream) | |||
1677 | return 0; | 1677 | return 0; |
1678 | } | 1678 | } |
1679 | 1679 | ||
1680 | static struct snd_pcm_ops snd_es1968_playback_ops = { | 1680 | static const struct snd_pcm_ops snd_es1968_playback_ops = { |
1681 | .open = snd_es1968_playback_open, | 1681 | .open = snd_es1968_playback_open, |
1682 | .close = snd_es1968_playback_close, | 1682 | .close = snd_es1968_playback_close, |
1683 | .ioctl = snd_pcm_lib_ioctl, | 1683 | .ioctl = snd_pcm_lib_ioctl, |
@@ -1688,7 +1688,7 @@ static struct snd_pcm_ops snd_es1968_playback_ops = { | |||
1688 | .pointer = snd_es1968_pcm_pointer, | 1688 | .pointer = snd_es1968_pcm_pointer, |
1689 | }; | 1689 | }; |
1690 | 1690 | ||
1691 | static struct snd_pcm_ops snd_es1968_capture_ops = { | 1691 | static const struct snd_pcm_ops snd_es1968_capture_ops = { |
1692 | .open = snd_es1968_capture_open, | 1692 | .open = snd_es1968_capture_open, |
1693 | .close = snd_es1968_capture_close, | 1693 | .close = snd_es1968_capture_close, |
1694 | .ioctl = snd_pcm_lib_ioctl, | 1694 | .ioctl = snd_pcm_lib_ioctl, |
diff --git a/sound/pci/fm801.c b/sound/pci/fm801.c index bade9b907b92..c47287d79306 100644 --- a/sound/pci/fm801.c +++ b/sound/pci/fm801.c | |||
@@ -691,7 +691,7 @@ static int snd_fm801_capture_close(struct snd_pcm_substream *substream) | |||
691 | return 0; | 691 | return 0; |
692 | } | 692 | } |
693 | 693 | ||
694 | static struct snd_pcm_ops snd_fm801_playback_ops = { | 694 | static const struct snd_pcm_ops snd_fm801_playback_ops = { |
695 | .open = snd_fm801_playback_open, | 695 | .open = snd_fm801_playback_open, |
696 | .close = snd_fm801_playback_close, | 696 | .close = snd_fm801_playback_close, |
697 | .ioctl = snd_pcm_lib_ioctl, | 697 | .ioctl = snd_pcm_lib_ioctl, |
@@ -702,7 +702,7 @@ static struct snd_pcm_ops snd_fm801_playback_ops = { | |||
702 | .pointer = snd_fm801_playback_pointer, | 702 | .pointer = snd_fm801_playback_pointer, |
703 | }; | 703 | }; |
704 | 704 | ||
705 | static struct snd_pcm_ops snd_fm801_capture_ops = { | 705 | static const struct snd_pcm_ops snd_fm801_capture_ops = { |
706 | .open = snd_fm801_capture_open, | 706 | .open = snd_fm801_capture_open, |
707 | .close = snd_fm801_capture_close, | 707 | .close = snd_fm801_capture_close, |
708 | .ioctl = snd_pcm_lib_ioctl, | 708 | .ioctl = snd_pcm_lib_ioctl, |
diff --git a/sound/pci/hda/hda_controller.c b/sound/pci/hda/hda_controller.c index 27de8015717d..500878556578 100644 --- a/sound/pci/hda/hda_controller.c +++ b/sound/pci/hda/hda_controller.c | |||
@@ -27,6 +27,12 @@ | |||
27 | #include <linux/module.h> | 27 | #include <linux/module.h> |
28 | #include <linux/pm_runtime.h> | 28 | #include <linux/pm_runtime.h> |
29 | #include <linux/slab.h> | 29 | #include <linux/slab.h> |
30 | |||
31 | #ifdef CONFIG_X86 | ||
32 | /* for art-tsc conversion */ | ||
33 | #include <asm/tsc.h> | ||
34 | #endif | ||
35 | |||
30 | #include <sound/core.h> | 36 | #include <sound/core.h> |
31 | #include <sound/initval.h> | 37 | #include <sound/initval.h> |
32 | #include "hda_controller.h" | 38 | #include "hda_controller.h" |
@@ -337,12 +343,173 @@ static snd_pcm_uframes_t azx_pcm_pointer(struct snd_pcm_substream *substream) | |||
337 | azx_get_position(chip, azx_dev)); | 343 | azx_get_position(chip, azx_dev)); |
338 | } | 344 | } |
339 | 345 | ||
346 | /* | ||
347 | * azx_scale64: Scale base by mult/div while not overflowing sanely | ||
348 | * | ||
349 | * Derived from scale64_check_overflow in kernel/time/timekeeping.c | ||
350 | * | ||
351 | * The tmestamps for a 48Khz stream can overflow after (2^64/10^9)/48K which | ||
352 | * is about 384307 ie ~4.5 days. | ||
353 | * | ||
354 | * This scales the calculation so that overflow will happen but after 2^64 / | ||
355 | * 48000 secs, which is pretty large! | ||
356 | * | ||
357 | * In caln below: | ||
358 | * base may overflow, but since there isn’t any additional division | ||
359 | * performed on base it’s OK | ||
360 | * rem can’t overflow because both are 32-bit values | ||
361 | */ | ||
362 | |||
363 | #ifdef CONFIG_X86 | ||
364 | static u64 azx_scale64(u64 base, u32 num, u32 den) | ||
365 | { | ||
366 | u64 rem; | ||
367 | |||
368 | rem = do_div(base, den); | ||
369 | |||
370 | base *= num; | ||
371 | rem *= num; | ||
372 | |||
373 | do_div(rem, den); | ||
374 | |||
375 | return base + rem; | ||
376 | } | ||
377 | |||
378 | static int azx_get_sync_time(ktime_t *device, | ||
379 | struct system_counterval_t *system, void *ctx) | ||
380 | { | ||
381 | struct snd_pcm_substream *substream = ctx; | ||
382 | struct azx_dev *azx_dev = get_azx_dev(substream); | ||
383 | struct azx_pcm *apcm = snd_pcm_substream_chip(substream); | ||
384 | struct azx *chip = apcm->chip; | ||
385 | struct snd_pcm_runtime *runtime; | ||
386 | u64 ll_counter, ll_counter_l, ll_counter_h; | ||
387 | u64 tsc_counter, tsc_counter_l, tsc_counter_h; | ||
388 | u32 wallclk_ctr, wallclk_cycles; | ||
389 | bool direction; | ||
390 | u32 dma_select; | ||
391 | u32 timeout = 200; | ||
392 | u32 retry_count = 0; | ||
393 | |||
394 | runtime = substream->runtime; | ||
395 | |||
396 | if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) | ||
397 | direction = 1; | ||
398 | else | ||
399 | direction = 0; | ||
400 | |||
401 | /* 0th stream tag is not used, so DMA ch 0 is for 1st stream tag */ | ||
402 | do { | ||
403 | timeout = 100; | ||
404 | dma_select = (direction << GTSCC_CDMAS_DMA_DIR_SHIFT) | | ||
405 | (azx_dev->core.stream_tag - 1); | ||
406 | snd_hdac_chip_writel(azx_bus(chip), GTSCC, dma_select); | ||
407 | |||
408 | /* Enable the capture */ | ||
409 | snd_hdac_chip_updatel(azx_bus(chip), GTSCC, 0, GTSCC_TSCCI_MASK); | ||
410 | |||
411 | while (timeout) { | ||
412 | if (snd_hdac_chip_readl(azx_bus(chip), GTSCC) & | ||
413 | GTSCC_TSCCD_MASK) | ||
414 | break; | ||
415 | |||
416 | timeout--; | ||
417 | } | ||
418 | |||
419 | if (!timeout) { | ||
420 | dev_err(chip->card->dev, "GTSCC capture Timedout!\n"); | ||
421 | return -EIO; | ||
422 | } | ||
423 | |||
424 | /* Read wall clock counter */ | ||
425 | wallclk_ctr = snd_hdac_chip_readl(azx_bus(chip), WALFCC); | ||
426 | |||
427 | /* Read TSC counter */ | ||
428 | tsc_counter_l = snd_hdac_chip_readl(azx_bus(chip), TSCCL); | ||
429 | tsc_counter_h = snd_hdac_chip_readl(azx_bus(chip), TSCCU); | ||
430 | |||
431 | /* Read Link counter */ | ||
432 | ll_counter_l = snd_hdac_chip_readl(azx_bus(chip), LLPCL); | ||
433 | ll_counter_h = snd_hdac_chip_readl(azx_bus(chip), LLPCU); | ||
434 | |||
435 | /* Ack: registers read done */ | ||
436 | snd_hdac_chip_writel(azx_bus(chip), GTSCC, GTSCC_TSCCD_SHIFT); | ||
437 | |||
438 | tsc_counter = (tsc_counter_h << TSCCU_CCU_SHIFT) | | ||
439 | tsc_counter_l; | ||
440 | |||
441 | ll_counter = (ll_counter_h << LLPC_CCU_SHIFT) | ll_counter_l; | ||
442 | wallclk_cycles = wallclk_ctr & WALFCC_CIF_MASK; | ||
443 | |||
444 | /* | ||
445 | * An error occurs near frame "rollover". The clocks in | ||
446 | * frame value indicates whether this error may have | ||
447 | * occurred. Here we use the value of 10 i.e., | ||
448 | * HDA_MAX_CYCLE_OFFSET | ||
449 | */ | ||
450 | if (wallclk_cycles < HDA_MAX_CYCLE_VALUE - HDA_MAX_CYCLE_OFFSET | ||
451 | && wallclk_cycles > HDA_MAX_CYCLE_OFFSET) | ||
452 | break; | ||
453 | |||
454 | /* | ||
455 | * Sleep before we read again, else we may again get | ||
456 | * value near to MAX_CYCLE. Try to sleep for different | ||
457 | * amount of time so we dont hit the same number again | ||
458 | */ | ||
459 | udelay(retry_count++); | ||
460 | |||
461 | } while (retry_count != HDA_MAX_CYCLE_READ_RETRY); | ||
462 | |||
463 | if (retry_count == HDA_MAX_CYCLE_READ_RETRY) { | ||
464 | dev_err_ratelimited(chip->card->dev, | ||
465 | "Error in WALFCC cycle count\n"); | ||
466 | return -EIO; | ||
467 | } | ||
468 | |||
469 | *device = ns_to_ktime(azx_scale64(ll_counter, | ||
470 | NSEC_PER_SEC, runtime->rate)); | ||
471 | *device = ktime_add_ns(*device, (wallclk_cycles * NSEC_PER_SEC) / | ||
472 | ((HDA_MAX_CYCLE_VALUE + 1) * runtime->rate)); | ||
473 | |||
474 | *system = convert_art_to_tsc(tsc_counter); | ||
475 | |||
476 | return 0; | ||
477 | } | ||
478 | |||
479 | #else | ||
480 | static int azx_get_sync_time(ktime_t *device, | ||
481 | struct system_counterval_t *system, void *ctx) | ||
482 | { | ||
483 | return -ENXIO; | ||
484 | } | ||
485 | #endif | ||
486 | |||
487 | static int azx_get_crosststamp(struct snd_pcm_substream *substream, | ||
488 | struct system_device_crosststamp *xtstamp) | ||
489 | { | ||
490 | return get_device_system_crosststamp(azx_get_sync_time, | ||
491 | substream, NULL, xtstamp); | ||
492 | } | ||
493 | |||
494 | static inline bool is_link_time_supported(struct snd_pcm_runtime *runtime, | ||
495 | struct snd_pcm_audio_tstamp_config *ts) | ||
496 | { | ||
497 | if (runtime->hw.info & SNDRV_PCM_INFO_HAS_LINK_SYNCHRONIZED_ATIME) | ||
498 | if (ts->type_requested == SNDRV_PCM_AUDIO_TSTAMP_TYPE_LINK_SYNCHRONIZED) | ||
499 | return true; | ||
500 | |||
501 | return false; | ||
502 | } | ||
503 | |||
340 | static int azx_get_time_info(struct snd_pcm_substream *substream, | 504 | static int azx_get_time_info(struct snd_pcm_substream *substream, |
341 | struct timespec *system_ts, struct timespec *audio_ts, | 505 | struct timespec *system_ts, struct timespec *audio_ts, |
342 | struct snd_pcm_audio_tstamp_config *audio_tstamp_config, | 506 | struct snd_pcm_audio_tstamp_config *audio_tstamp_config, |
343 | struct snd_pcm_audio_tstamp_report *audio_tstamp_report) | 507 | struct snd_pcm_audio_tstamp_report *audio_tstamp_report) |
344 | { | 508 | { |
345 | struct azx_dev *azx_dev = get_azx_dev(substream); | 509 | struct azx_dev *azx_dev = get_azx_dev(substream); |
510 | struct snd_pcm_runtime *runtime = substream->runtime; | ||
511 | struct system_device_crosststamp xtstamp; | ||
512 | int ret; | ||
346 | u64 nsec; | 513 | u64 nsec; |
347 | 514 | ||
348 | if ((substream->runtime->hw.info & SNDRV_PCM_INFO_HAS_LINK_ATIME) && | 515 | if ((substream->runtime->hw.info & SNDRV_PCM_INFO_HAS_LINK_ATIME) && |
@@ -361,8 +528,37 @@ static int azx_get_time_info(struct snd_pcm_substream *substream, | |||
361 | audio_tstamp_report->accuracy_report = 1; /* rest of structure is valid */ | 528 | audio_tstamp_report->accuracy_report = 1; /* rest of structure is valid */ |
362 | audio_tstamp_report->accuracy = 42; /* 24 MHz WallClock == 42ns resolution */ | 529 | audio_tstamp_report->accuracy = 42; /* 24 MHz WallClock == 42ns resolution */ |
363 | 530 | ||
364 | } else | 531 | } else if (is_link_time_supported(runtime, audio_tstamp_config)) { |
532 | |||
533 | ret = azx_get_crosststamp(substream, &xtstamp); | ||
534 | if (ret) | ||
535 | return ret; | ||
536 | |||
537 | switch (runtime->tstamp_type) { | ||
538 | case SNDRV_PCM_TSTAMP_TYPE_MONOTONIC: | ||
539 | return -EINVAL; | ||
540 | |||
541 | case SNDRV_PCM_TSTAMP_TYPE_MONOTONIC_RAW: | ||
542 | *system_ts = ktime_to_timespec(xtstamp.sys_monoraw); | ||
543 | break; | ||
544 | |||
545 | default: | ||
546 | *system_ts = ktime_to_timespec(xtstamp.sys_realtime); | ||
547 | break; | ||
548 | |||
549 | } | ||
550 | |||
551 | *audio_ts = ktime_to_timespec(xtstamp.device); | ||
552 | |||
553 | audio_tstamp_report->actual_type = | ||
554 | SNDRV_PCM_AUDIO_TSTAMP_TYPE_LINK_SYNCHRONIZED; | ||
555 | audio_tstamp_report->accuracy_report = 1; | ||
556 | /* 24 MHz WallClock == 42ns resolution */ | ||
557 | audio_tstamp_report->accuracy = 42; | ||
558 | |||
559 | } else { | ||
365 | audio_tstamp_report->actual_type = SNDRV_PCM_AUDIO_TSTAMP_TYPE_DEFAULT; | 560 | audio_tstamp_report->actual_type = SNDRV_PCM_AUDIO_TSTAMP_TYPE_DEFAULT; |
561 | } | ||
366 | 562 | ||
367 | return 0; | 563 | return 0; |
368 | } | 564 | } |
@@ -412,6 +608,11 @@ static int azx_pcm_open(struct snd_pcm_substream *substream) | |||
412 | goto unlock; | 608 | goto unlock; |
413 | } | 609 | } |
414 | runtime->private_data = azx_dev; | 610 | runtime->private_data = azx_dev; |
611 | |||
612 | if (chip->gts_present) | ||
613 | azx_pcm_hw.info = azx_pcm_hw.info | | ||
614 | SNDRV_PCM_INFO_HAS_LINK_SYNCHRONIZED_ATIME; | ||
615 | |||
415 | runtime->hw = azx_pcm_hw; | 616 | runtime->hw = azx_pcm_hw; |
416 | runtime->hw.channels_min = hinfo->channels_min; | 617 | runtime->hw.channels_min = hinfo->channels_min; |
417 | runtime->hw.channels_max = hinfo->channels_max; | 618 | runtime->hw.channels_max = hinfo->channels_max; |
@@ -495,7 +696,7 @@ static int azx_pcm_mmap(struct snd_pcm_substream *substream, | |||
495 | return snd_pcm_lib_default_mmap(substream, area); | 696 | return snd_pcm_lib_default_mmap(substream, area); |
496 | } | 697 | } |
497 | 698 | ||
498 | static struct snd_pcm_ops azx_pcm_ops = { | 699 | static const struct snd_pcm_ops azx_pcm_ops = { |
499 | .open = azx_pcm_open, | 700 | .open = azx_pcm_open, |
500 | .close = azx_pcm_close, | 701 | .close = azx_pcm_close, |
501 | .ioctl = snd_pcm_lib_ioctl, | 702 | .ioctl = snd_pcm_lib_ioctl, |
diff --git a/sound/pci/hda/hda_controller.h b/sound/pci/hda/hda_controller.h index ec63bbf1ec6d..a50e0532622a 100644 --- a/sound/pci/hda/hda_controller.h +++ b/sound/pci/hda/hda_controller.h | |||
@@ -159,6 +159,9 @@ struct azx { | |||
159 | unsigned int region_requested:1; | 159 | unsigned int region_requested:1; |
160 | unsigned int disabled:1; /* disabled by vga_switcheroo */ | 160 | unsigned int disabled:1; /* disabled by vga_switcheroo */ |
161 | 161 | ||
162 | /* GTS present */ | ||
163 | unsigned int gts_present:1; | ||
164 | |||
162 | #ifdef CONFIG_SND_HDA_DSP_LOADER | 165 | #ifdef CONFIG_SND_HDA_DSP_LOADER |
163 | struct azx_dev saved_azx_dev; | 166 | struct azx_dev saved_azx_dev; |
164 | #endif | 167 | #endif |
diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c index 160c7f713722..c3469f756ec2 100644 --- a/sound/pci/hda/hda_intel.c +++ b/sound/pci/hda/hda_intel.c | |||
@@ -54,6 +54,7 @@ | |||
54 | /* for snoop control */ | 54 | /* for snoop control */ |
55 | #include <asm/pgtable.h> | 55 | #include <asm/pgtable.h> |
56 | #include <asm/cacheflush.h> | 56 | #include <asm/cacheflush.h> |
57 | #include <asm/cpufeature.h> | ||
57 | #endif | 58 | #endif |
58 | #include <sound/core.h> | 59 | #include <sound/core.h> |
59 | #include <sound/initval.h> | 60 | #include <sound/initval.h> |
@@ -1663,6 +1664,22 @@ static int azx_first_init(struct azx *chip) | |||
1663 | return -ENXIO; | 1664 | return -ENXIO; |
1664 | } | 1665 | } |
1665 | 1666 | ||
1667 | if (IS_SKL_PLUS(pci)) | ||
1668 | snd_hdac_bus_parse_capabilities(bus); | ||
1669 | |||
1670 | /* | ||
1671 | * Some Intel CPUs has always running timer (ART) feature and | ||
1672 | * controller may have Global time sync reporting capability, so | ||
1673 | * check both of these before declaring synchronized time reporting | ||
1674 | * capability SNDRV_PCM_INFO_HAS_LINK_SYNCHRONIZED_ATIME | ||
1675 | */ | ||
1676 | chip->gts_present = false; | ||
1677 | |||
1678 | #ifdef CONFIG_X86 | ||
1679 | if (bus->ppcap && boot_cpu_has(X86_FEATURE_ART)) | ||
1680 | chip->gts_present = true; | ||
1681 | #endif | ||
1682 | |||
1666 | if (chip->msi) { | 1683 | if (chip->msi) { |
1667 | if (chip->driver_caps & AZX_DCAPS_NO_MSI64) { | 1684 | if (chip->driver_caps & AZX_DCAPS_NO_MSI64) { |
1668 | dev_dbg(card->dev, "Disabling 64bit MSI\n"); | 1685 | dev_dbg(card->dev, "Disabling 64bit MSI\n"); |
diff --git a/sound/pci/hda/patch_ca0132.c b/sound/pci/hda/patch_ca0132.c index 9ceb2bc36e68..ad06866d7c69 100644 --- a/sound/pci/hda/patch_ca0132.c +++ b/sound/pci/hda/patch_ca0132.c | |||
@@ -4018,7 +4018,7 @@ static int ca0132_build_controls(struct hda_codec *codec) | |||
4018 | /* | 4018 | /* |
4019 | * PCM | 4019 | * PCM |
4020 | */ | 4020 | */ |
4021 | static struct hda_pcm_stream ca0132_pcm_analog_playback = { | 4021 | static const struct hda_pcm_stream ca0132_pcm_analog_playback = { |
4022 | .substreams = 1, | 4022 | .substreams = 1, |
4023 | .channels_min = 2, | 4023 | .channels_min = 2, |
4024 | .channels_max = 6, | 4024 | .channels_max = 6, |
@@ -4029,7 +4029,7 @@ static struct hda_pcm_stream ca0132_pcm_analog_playback = { | |||
4029 | }, | 4029 | }, |
4030 | }; | 4030 | }; |
4031 | 4031 | ||
4032 | static struct hda_pcm_stream ca0132_pcm_analog_capture = { | 4032 | static const struct hda_pcm_stream ca0132_pcm_analog_capture = { |
4033 | .substreams = 1, | 4033 | .substreams = 1, |
4034 | .channels_min = 2, | 4034 | .channels_min = 2, |
4035 | .channels_max = 2, | 4035 | .channels_max = 2, |
@@ -4040,7 +4040,7 @@ static struct hda_pcm_stream ca0132_pcm_analog_capture = { | |||
4040 | }, | 4040 | }, |
4041 | }; | 4041 | }; |
4042 | 4042 | ||
4043 | static struct hda_pcm_stream ca0132_pcm_digital_playback = { | 4043 | static const struct hda_pcm_stream ca0132_pcm_digital_playback = { |
4044 | .substreams = 1, | 4044 | .substreams = 1, |
4045 | .channels_min = 2, | 4045 | .channels_min = 2, |
4046 | .channels_max = 2, | 4046 | .channels_max = 2, |
@@ -4052,7 +4052,7 @@ static struct hda_pcm_stream ca0132_pcm_digital_playback = { | |||
4052 | }, | 4052 | }, |
4053 | }; | 4053 | }; |
4054 | 4054 | ||
4055 | static struct hda_pcm_stream ca0132_pcm_digital_capture = { | 4055 | static const struct hda_pcm_stream ca0132_pcm_digital_capture = { |
4056 | .substreams = 1, | 4056 | .substreams = 1, |
4057 | .channels_min = 2, | 4057 | .channels_min = 2, |
4058 | .channels_max = 2, | 4058 | .channels_max = 2, |
@@ -4614,7 +4614,7 @@ static void ca0132_free(struct hda_codec *codec) | |||
4614 | kfree(codec->spec); | 4614 | kfree(codec->spec); |
4615 | } | 4615 | } |
4616 | 4616 | ||
4617 | static struct hda_codec_ops ca0132_patch_ops = { | 4617 | static const struct hda_codec_ops ca0132_patch_ops = { |
4618 | .build_controls = ca0132_build_controls, | 4618 | .build_controls = ca0132_build_controls, |
4619 | .build_pcms = ca0132_build_pcms, | 4619 | .build_pcms = ca0132_build_pcms, |
4620 | .init = ca0132_init, | 4620 | .init = ca0132_init, |
diff --git a/sound/pci/hda/patch_conexant.c b/sound/pci/hda/patch_conexant.c index 56fefbd85782..ed62748a6d55 100644 --- a/sound/pci/hda/patch_conexant.c +++ b/sound/pci/hda/patch_conexant.c | |||
@@ -261,6 +261,7 @@ enum { | |||
261 | CXT_FIXUP_HP_530, | 261 | CXT_FIXUP_HP_530, |
262 | CXT_FIXUP_CAP_MIX_AMP_5047, | 262 | CXT_FIXUP_CAP_MIX_AMP_5047, |
263 | CXT_FIXUP_MUTE_LED_EAPD, | 263 | CXT_FIXUP_MUTE_LED_EAPD, |
264 | CXT_FIXUP_HP_SPECTRE, | ||
264 | }; | 265 | }; |
265 | 266 | ||
266 | /* for hda_fixup_thinkpad_acpi() */ | 267 | /* for hda_fixup_thinkpad_acpi() */ |
@@ -765,6 +766,14 @@ static const struct hda_fixup cxt_fixups[] = { | |||
765 | .type = HDA_FIXUP_FUNC, | 766 | .type = HDA_FIXUP_FUNC, |
766 | .v.func = cxt_fixup_mute_led_eapd, | 767 | .v.func = cxt_fixup_mute_led_eapd, |
767 | }, | 768 | }, |
769 | [CXT_FIXUP_HP_SPECTRE] = { | ||
770 | .type = HDA_FIXUP_PINS, | ||
771 | .v.pins = (const struct hda_pintbl[]) { | ||
772 | /* enable NID 0x1d for the speaker on top */ | ||
773 | { 0x1d, 0x91170111 }, | ||
774 | { } | ||
775 | } | ||
776 | }, | ||
768 | }; | 777 | }; |
769 | 778 | ||
770 | static const struct snd_pci_quirk cxt5045_fixups[] = { | 779 | static const struct snd_pci_quirk cxt5045_fixups[] = { |
@@ -814,6 +823,7 @@ static const struct snd_pci_quirk cxt5066_fixups[] = { | |||
814 | SND_PCI_QUIRK(0x1025, 0x0543, "Acer Aspire One 522", CXT_FIXUP_STEREO_DMIC), | 823 | SND_PCI_QUIRK(0x1025, 0x0543, "Acer Aspire One 522", CXT_FIXUP_STEREO_DMIC), |
815 | SND_PCI_QUIRK(0x1025, 0x054c, "Acer Aspire 3830TG", CXT_FIXUP_ASPIRE_DMIC), | 824 | SND_PCI_QUIRK(0x1025, 0x054c, "Acer Aspire 3830TG", CXT_FIXUP_ASPIRE_DMIC), |
816 | SND_PCI_QUIRK(0x1025, 0x054f, "Acer Aspire 4830T", CXT_FIXUP_ASPIRE_DMIC), | 825 | SND_PCI_QUIRK(0x1025, 0x054f, "Acer Aspire 4830T", CXT_FIXUP_ASPIRE_DMIC), |
826 | SND_PCI_QUIRK(0x103c, 0x8174, "HP Spectre x360", CXT_FIXUP_HP_SPECTRE), | ||
817 | SND_PCI_QUIRK(0x1043, 0x138d, "Asus", CXT_FIXUP_HEADPHONE_MIC_PIN), | 827 | SND_PCI_QUIRK(0x1043, 0x138d, "Asus", CXT_FIXUP_HEADPHONE_MIC_PIN), |
818 | SND_PCI_QUIRK(0x152d, 0x0833, "OLPC XO-1.5", CXT_FIXUP_OLPC_XO), | 828 | SND_PCI_QUIRK(0x152d, 0x0833, "OLPC XO-1.5", CXT_FIXUP_OLPC_XO), |
819 | SND_PCI_QUIRK(0x17aa, 0x20f2, "Lenovo T400", CXT_PINCFG_LENOVO_TP410), | 829 | SND_PCI_QUIRK(0x17aa, 0x20f2, "Lenovo T400", CXT_PINCFG_LENOVO_TP410), |
diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index 575cefd8cc4a..b58e8c76346a 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c | |||
@@ -5264,6 +5264,8 @@ static const struct hda_fixup alc269_fixups[] = { | |||
5264 | [ALC269_FIXUP_THINKPAD_ACPI] = { | 5264 | [ALC269_FIXUP_THINKPAD_ACPI] = { |
5265 | .type = HDA_FIXUP_FUNC, | 5265 | .type = HDA_FIXUP_FUNC, |
5266 | .v.func = hda_fixup_thinkpad_acpi, | 5266 | .v.func = hda_fixup_thinkpad_acpi, |
5267 | .chained = true, | ||
5268 | .chain_id = ALC269_FIXUP_SKU_IGNORE, | ||
5267 | }, | 5269 | }, |
5268 | [ALC269_FIXUP_DMIC_THINKPAD_ACPI] = { | 5270 | [ALC269_FIXUP_DMIC_THINKPAD_ACPI] = { |
5269 | .type = HDA_FIXUP_FUNC, | 5271 | .type = HDA_FIXUP_FUNC, |
@@ -5806,6 +5808,13 @@ static const struct hda_model_fixup alc269_fixup_models[] = { | |||
5806 | {0x14, 0x90170110}, \ | 5808 | {0x14, 0x90170110}, \ |
5807 | {0x15, 0x0221401f} | 5809 | {0x15, 0x0221401f} |
5808 | 5810 | ||
5811 | #define ALC295_STANDARD_PINS \ | ||
5812 | {0x12, 0xb7a60130}, \ | ||
5813 | {0x14, 0x90170110}, \ | ||
5814 | {0x17, 0x21014020}, \ | ||
5815 | {0x18, 0x21a19030}, \ | ||
5816 | {0x21, 0x04211020} | ||
5817 | |||
5809 | #define ALC298_STANDARD_PINS \ | 5818 | #define ALC298_STANDARD_PINS \ |
5810 | {0x12, 0x90a60130}, \ | 5819 | {0x12, 0x90a60130}, \ |
5811 | {0x21, 0x03211020} | 5820 | {0x21, 0x03211020} |
@@ -5846,6 +5855,10 @@ static const struct snd_hda_pin_quirk alc269_pin_fixup_tbl[] = { | |||
5846 | {0x14, 0x90170120}, | 5855 | {0x14, 0x90170120}, |
5847 | {0x21, 0x02211030}), | 5856 | {0x21, 0x02211030}), |
5848 | SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE, | 5857 | SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE, |
5858 | {0x14, 0x90170110}, | ||
5859 | {0x1b, 0x02011020}, | ||
5860 | {0x21, 0x0221101f}), | ||
5861 | SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE, | ||
5849 | {0x14, 0x90170130}, | 5862 | {0x14, 0x90170130}, |
5850 | {0x1b, 0x01014020}, | 5863 | {0x1b, 0x01014020}, |
5851 | {0x21, 0x0221103f}), | 5864 | {0x21, 0x0221103f}), |
@@ -5911,6 +5924,10 @@ static const struct snd_hda_pin_quirk alc269_pin_fixup_tbl[] = { | |||
5911 | {0x14, 0x90170120}, | 5924 | {0x14, 0x90170120}, |
5912 | {0x21, 0x02211030}), | 5925 | {0x21, 0x02211030}), |
5913 | SND_HDA_PIN_QUIRK(0x10ec0256, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE, | 5926 | SND_HDA_PIN_QUIRK(0x10ec0256, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE, |
5927 | {0x12, 0xb7a60130}, | ||
5928 | {0x14, 0x90170110}, | ||
5929 | {0x21, 0x02211020}), | ||
5930 | SND_HDA_PIN_QUIRK(0x10ec0256, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE, | ||
5914 | ALC256_STANDARD_PINS), | 5931 | ALC256_STANDARD_PINS), |
5915 | SND_HDA_PIN_QUIRK(0x10ec0280, 0x103c, "HP", ALC280_FIXUP_HP_GPIO4, | 5932 | SND_HDA_PIN_QUIRK(0x10ec0280, 0x103c, "HP", ALC280_FIXUP_HP_GPIO4, |
5916 | {0x12, 0x90a60130}, | 5933 | {0x12, 0x90a60130}, |
@@ -6021,6 +6038,8 @@ static const struct snd_hda_pin_quirk alc269_pin_fixup_tbl[] = { | |||
6021 | SND_HDA_PIN_QUIRK(0x10ec0293, 0x1028, "Dell", ALC293_FIXUP_DELL1_MIC_NO_PRESENCE, | 6038 | SND_HDA_PIN_QUIRK(0x10ec0293, 0x1028, "Dell", ALC293_FIXUP_DELL1_MIC_NO_PRESENCE, |
6022 | ALC292_STANDARD_PINS, | 6039 | ALC292_STANDARD_PINS, |
6023 | {0x13, 0x90a60140}), | 6040 | {0x13, 0x90a60140}), |
6041 | SND_HDA_PIN_QUIRK(0x10ec0295, 0x1028, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE, | ||
6042 | ALC295_STANDARD_PINS), | ||
6024 | SND_HDA_PIN_QUIRK(0x10ec0298, 0x1028, "Dell", ALC298_FIXUP_DELL1_MIC_NO_PRESENCE, | 6043 | SND_HDA_PIN_QUIRK(0x10ec0298, 0x1028, "Dell", ALC298_FIXUP_DELL1_MIC_NO_PRESENCE, |
6025 | ALC298_STANDARD_PINS, | 6044 | ALC298_STANDARD_PINS, |
6026 | {0x17, 0x90170110}), | 6045 | {0x17, 0x90170110}), |
diff --git a/sound/pci/ice1712/ice1712.c b/sound/pci/ice1712/ice1712.c index 8ae3bb7975d1..b4aa4c1370a8 100644 --- a/sound/pci/ice1712/ice1712.c +++ b/sound/pci/ice1712/ice1712.c | |||
@@ -847,7 +847,7 @@ static int snd_ice1712_capture_close(struct snd_pcm_substream *substream) | |||
847 | return 0; | 847 | return 0; |
848 | } | 848 | } |
849 | 849 | ||
850 | static struct snd_pcm_ops snd_ice1712_playback_ops = { | 850 | static const struct snd_pcm_ops snd_ice1712_playback_ops = { |
851 | .open = snd_ice1712_playback_open, | 851 | .open = snd_ice1712_playback_open, |
852 | .close = snd_ice1712_playback_close, | 852 | .close = snd_ice1712_playback_close, |
853 | .ioctl = snd_pcm_lib_ioctl, | 853 | .ioctl = snd_pcm_lib_ioctl, |
@@ -858,7 +858,7 @@ static struct snd_pcm_ops snd_ice1712_playback_ops = { | |||
858 | .pointer = snd_ice1712_playback_pointer, | 858 | .pointer = snd_ice1712_playback_pointer, |
859 | }; | 859 | }; |
860 | 860 | ||
861 | static struct snd_pcm_ops snd_ice1712_playback_ds_ops = { | 861 | static const struct snd_pcm_ops snd_ice1712_playback_ds_ops = { |
862 | .open = snd_ice1712_playback_ds_open, | 862 | .open = snd_ice1712_playback_ds_open, |
863 | .close = snd_ice1712_playback_ds_close, | 863 | .close = snd_ice1712_playback_ds_close, |
864 | .ioctl = snd_pcm_lib_ioctl, | 864 | .ioctl = snd_pcm_lib_ioctl, |
@@ -869,7 +869,7 @@ static struct snd_pcm_ops snd_ice1712_playback_ds_ops = { | |||
869 | .pointer = snd_ice1712_playback_ds_pointer, | 869 | .pointer = snd_ice1712_playback_ds_pointer, |
870 | }; | 870 | }; |
871 | 871 | ||
872 | static struct snd_pcm_ops snd_ice1712_capture_ops = { | 872 | static const struct snd_pcm_ops snd_ice1712_capture_ops = { |
873 | .open = snd_ice1712_capture_open, | 873 | .open = snd_ice1712_capture_open, |
874 | .close = snd_ice1712_capture_close, | 874 | .close = snd_ice1712_capture_close, |
875 | .ioctl = snd_pcm_lib_ioctl, | 875 | .ioctl = snd_pcm_lib_ioctl, |
@@ -1228,7 +1228,7 @@ static int snd_ice1712_capture_pro_close(struct snd_pcm_substream *substream) | |||
1228 | return 0; | 1228 | return 0; |
1229 | } | 1229 | } |
1230 | 1230 | ||
1231 | static struct snd_pcm_ops snd_ice1712_playback_pro_ops = { | 1231 | static const struct snd_pcm_ops snd_ice1712_playback_pro_ops = { |
1232 | .open = snd_ice1712_playback_pro_open, | 1232 | .open = snd_ice1712_playback_pro_open, |
1233 | .close = snd_ice1712_playback_pro_close, | 1233 | .close = snd_ice1712_playback_pro_close, |
1234 | .ioctl = snd_pcm_lib_ioctl, | 1234 | .ioctl = snd_pcm_lib_ioctl, |
@@ -1239,7 +1239,7 @@ static struct snd_pcm_ops snd_ice1712_playback_pro_ops = { | |||
1239 | .pointer = snd_ice1712_playback_pro_pointer, | 1239 | .pointer = snd_ice1712_playback_pro_pointer, |
1240 | }; | 1240 | }; |
1241 | 1241 | ||
1242 | static struct snd_pcm_ops snd_ice1712_capture_pro_ops = { | 1242 | static const struct snd_pcm_ops snd_ice1712_capture_pro_ops = { |
1243 | .open = snd_ice1712_capture_pro_open, | 1243 | .open = snd_ice1712_capture_pro_open, |
1244 | .close = snd_ice1712_capture_pro_close, | 1244 | .close = snd_ice1712_capture_pro_close, |
1245 | .ioctl = snd_pcm_lib_ioctl, | 1245 | .ioctl = snd_pcm_lib_ioctl, |
diff --git a/sound/pci/ice1712/ice1724.c b/sound/pci/ice1712/ice1724.c index 0b22c00642bb..e5c52ed9b674 100644 --- a/sound/pci/ice1712/ice1724.c +++ b/sound/pci/ice1712/ice1724.c | |||
@@ -620,9 +620,7 @@ static const unsigned int stdclock_rate_list[16] = { | |||
620 | 620 | ||
621 | static unsigned int stdclock_get_rate(struct snd_ice1712 *ice) | 621 | static unsigned int stdclock_get_rate(struct snd_ice1712 *ice) |
622 | { | 622 | { |
623 | unsigned int rate; | 623 | return stdclock_rate_list[inb(ICEMT1724(ice, RATE)) & 15]; |
624 | rate = stdclock_rate_list[inb(ICEMT1724(ice, RATE)) & 15]; | ||
625 | return rate; | ||
626 | } | 624 | } |
627 | 625 | ||
628 | static void stdclock_set_rate(struct snd_ice1712 *ice, unsigned int rate) | 626 | static void stdclock_set_rate(struct snd_ice1712 *ice, unsigned int rate) |
@@ -1113,7 +1111,7 @@ static int snd_vt1724_capture_pro_close(struct snd_pcm_substream *substream) | |||
1113 | return 0; | 1111 | return 0; |
1114 | } | 1112 | } |
1115 | 1113 | ||
1116 | static struct snd_pcm_ops snd_vt1724_playback_pro_ops = { | 1114 | static const struct snd_pcm_ops snd_vt1724_playback_pro_ops = { |
1117 | .open = snd_vt1724_playback_pro_open, | 1115 | .open = snd_vt1724_playback_pro_open, |
1118 | .close = snd_vt1724_playback_pro_close, | 1116 | .close = snd_vt1724_playback_pro_close, |
1119 | .ioctl = snd_pcm_lib_ioctl, | 1117 | .ioctl = snd_pcm_lib_ioctl, |
@@ -1124,7 +1122,7 @@ static struct snd_pcm_ops snd_vt1724_playback_pro_ops = { | |||
1124 | .pointer = snd_vt1724_playback_pro_pointer, | 1122 | .pointer = snd_vt1724_playback_pro_pointer, |
1125 | }; | 1123 | }; |
1126 | 1124 | ||
1127 | static struct snd_pcm_ops snd_vt1724_capture_pro_ops = { | 1125 | static const struct snd_pcm_ops snd_vt1724_capture_pro_ops = { |
1128 | .open = snd_vt1724_capture_pro_open, | 1126 | .open = snd_vt1724_capture_pro_open, |
1129 | .close = snd_vt1724_capture_pro_close, | 1127 | .close = snd_vt1724_capture_pro_close, |
1130 | .ioctl = snd_pcm_lib_ioctl, | 1128 | .ioctl = snd_pcm_lib_ioctl, |
@@ -1292,7 +1290,7 @@ static int snd_vt1724_capture_spdif_close(struct snd_pcm_substream *substream) | |||
1292 | return 0; | 1290 | return 0; |
1293 | } | 1291 | } |
1294 | 1292 | ||
1295 | static struct snd_pcm_ops snd_vt1724_playback_spdif_ops = { | 1293 | static const struct snd_pcm_ops snd_vt1724_playback_spdif_ops = { |
1296 | .open = snd_vt1724_playback_spdif_open, | 1294 | .open = snd_vt1724_playback_spdif_open, |
1297 | .close = snd_vt1724_playback_spdif_close, | 1295 | .close = snd_vt1724_playback_spdif_close, |
1298 | .ioctl = snd_pcm_lib_ioctl, | 1296 | .ioctl = snd_pcm_lib_ioctl, |
@@ -1303,7 +1301,7 @@ static struct snd_pcm_ops snd_vt1724_playback_spdif_ops = { | |||
1303 | .pointer = snd_vt1724_pcm_pointer, | 1301 | .pointer = snd_vt1724_pcm_pointer, |
1304 | }; | 1302 | }; |
1305 | 1303 | ||
1306 | static struct snd_pcm_ops snd_vt1724_capture_spdif_ops = { | 1304 | static const struct snd_pcm_ops snd_vt1724_capture_spdif_ops = { |
1307 | .open = snd_vt1724_capture_spdif_open, | 1305 | .open = snd_vt1724_capture_spdif_open, |
1308 | .close = snd_vt1724_capture_spdif_close, | 1306 | .close = snd_vt1724_capture_spdif_close, |
1309 | .ioctl = snd_pcm_lib_ioctl, | 1307 | .ioctl = snd_pcm_lib_ioctl, |
@@ -1437,7 +1435,7 @@ static int snd_vt1724_playback_indep_close(struct snd_pcm_substream *substream) | |||
1437 | return 0; | 1435 | return 0; |
1438 | } | 1436 | } |
1439 | 1437 | ||
1440 | static struct snd_pcm_ops snd_vt1724_playback_indep_ops = { | 1438 | static const struct snd_pcm_ops snd_vt1724_playback_indep_ops = { |
1441 | .open = snd_vt1724_playback_indep_open, | 1439 | .open = snd_vt1724_playback_indep_open, |
1442 | .close = snd_vt1724_playback_indep_close, | 1440 | .close = snd_vt1724_playback_indep_close, |
1443 | .ioctl = snd_pcm_lib_ioctl, | 1441 | .ioctl = snd_pcm_lib_ioctl, |
diff --git a/sound/pci/korg1212/korg1212.c b/sound/pci/korg1212/korg1212.c index 9e1ad119a3ce..565f7f55c3ca 100644 --- a/sound/pci/korg1212/korg1212.c +++ b/sound/pci/korg1212/korg1212.c | |||
@@ -1681,7 +1681,7 @@ static int snd_korg1212_capture_copy(struct snd_pcm_substream *substream, | |||
1681 | return snd_korg1212_copy_to(korg1212, dst, pos, count, 0, korg1212->channels * 2); | 1681 | return snd_korg1212_copy_to(korg1212, dst, pos, count, 0, korg1212->channels * 2); |
1682 | } | 1682 | } |
1683 | 1683 | ||
1684 | static struct snd_pcm_ops snd_korg1212_playback_ops = { | 1684 | static const struct snd_pcm_ops snd_korg1212_playback_ops = { |
1685 | .open = snd_korg1212_playback_open, | 1685 | .open = snd_korg1212_playback_open, |
1686 | .close = snd_korg1212_playback_close, | 1686 | .close = snd_korg1212_playback_close, |
1687 | .ioctl = snd_korg1212_ioctl, | 1687 | .ioctl = snd_korg1212_ioctl, |
@@ -1693,7 +1693,7 @@ static struct snd_pcm_ops snd_korg1212_playback_ops = { | |||
1693 | .silence = snd_korg1212_playback_silence, | 1693 | .silence = snd_korg1212_playback_silence, |
1694 | }; | 1694 | }; |
1695 | 1695 | ||
1696 | static struct snd_pcm_ops snd_korg1212_capture_ops = { | 1696 | static const struct snd_pcm_ops snd_korg1212_capture_ops = { |
1697 | .open = snd_korg1212_capture_open, | 1697 | .open = snd_korg1212_capture_open, |
1698 | .close = snd_korg1212_capture_close, | 1698 | .close = snd_korg1212_capture_close, |
1699 | .ioctl = snd_korg1212_ioctl, | 1699 | .ioctl = snd_korg1212_ioctl, |
diff --git a/sound/pci/lola/lola_pcm.c b/sound/pci/lola/lola_pcm.c index 3bd6985430e8..1268ba329016 100644 --- a/sound/pci/lola/lola_pcm.c +++ b/sound/pci/lola/lola_pcm.c | |||
@@ -586,7 +586,7 @@ void lola_pcm_update(struct lola *chip, struct lola_pcm *pcm, unsigned int bits) | |||
586 | } | 586 | } |
587 | } | 587 | } |
588 | 588 | ||
589 | static struct snd_pcm_ops lola_pcm_ops = { | 589 | static const struct snd_pcm_ops lola_pcm_ops = { |
590 | .open = lola_pcm_open, | 590 | .open = lola_pcm_open, |
591 | .close = lola_pcm_close, | 591 | .close = lola_pcm_close, |
592 | .ioctl = snd_pcm_lib_ioctl, | 592 | .ioctl = snd_pcm_lib_ioctl, |
diff --git a/sound/pci/lx6464es/lx6464es.c b/sound/pci/lx6464es/lx6464es.c index 8b8e2e54fba3..c0f0c349c3ec 100644 --- a/sound/pci/lx6464es/lx6464es.c +++ b/sound/pci/lx6464es/lx6464es.c | |||
@@ -804,7 +804,7 @@ mac_ready: | |||
804 | return err; | 804 | return err; |
805 | } | 805 | } |
806 | 806 | ||
807 | static struct snd_pcm_ops lx_ops_playback = { | 807 | static const struct snd_pcm_ops lx_ops_playback = { |
808 | .open = lx_pcm_open, | 808 | .open = lx_pcm_open, |
809 | .close = lx_pcm_close, | 809 | .close = lx_pcm_close, |
810 | .ioctl = snd_pcm_lib_ioctl, | 810 | .ioctl = snd_pcm_lib_ioctl, |
@@ -815,7 +815,7 @@ static struct snd_pcm_ops lx_ops_playback = { | |||
815 | .pointer = lx_pcm_stream_pointer, | 815 | .pointer = lx_pcm_stream_pointer, |
816 | }; | 816 | }; |
817 | 817 | ||
818 | static struct snd_pcm_ops lx_ops_capture = { | 818 | static const struct snd_pcm_ops lx_ops_capture = { |
819 | .open = lx_pcm_open, | 819 | .open = lx_pcm_open, |
820 | .close = lx_pcm_close, | 820 | .close = lx_pcm_close, |
821 | .ioctl = snd_pcm_lib_ioctl, | 821 | .ioctl = snd_pcm_lib_ioctl, |
diff --git a/sound/pci/maestro3.c b/sound/pci/maestro3.c index 17ae92613de4..cafea6dc5c01 100644 --- a/sound/pci/maestro3.c +++ b/sound/pci/maestro3.c | |||
@@ -1834,7 +1834,7 @@ snd_m3_capture_close(struct snd_pcm_substream *subs) | |||
1834 | * create pcm instance | 1834 | * create pcm instance |
1835 | */ | 1835 | */ |
1836 | 1836 | ||
1837 | static struct snd_pcm_ops snd_m3_playback_ops = { | 1837 | static const struct snd_pcm_ops snd_m3_playback_ops = { |
1838 | .open = snd_m3_playback_open, | 1838 | .open = snd_m3_playback_open, |
1839 | .close = snd_m3_playback_close, | 1839 | .close = snd_m3_playback_close, |
1840 | .ioctl = snd_pcm_lib_ioctl, | 1840 | .ioctl = snd_pcm_lib_ioctl, |
@@ -1845,7 +1845,7 @@ static struct snd_pcm_ops snd_m3_playback_ops = { | |||
1845 | .pointer = snd_m3_pcm_pointer, | 1845 | .pointer = snd_m3_pcm_pointer, |
1846 | }; | 1846 | }; |
1847 | 1847 | ||
1848 | static struct snd_pcm_ops snd_m3_capture_ops = { | 1848 | static const struct snd_pcm_ops snd_m3_capture_ops = { |
1849 | .open = snd_m3_capture_open, | 1849 | .open = snd_m3_capture_open, |
1850 | .close = snd_m3_capture_close, | 1850 | .close = snd_m3_capture_close, |
1851 | .ioctl = snd_pcm_lib_ioctl, | 1851 | .ioctl = snd_pcm_lib_ioctl, |
diff --git a/sound/pci/mixart/mixart.c b/sound/pci/mixart/mixart.c index 25c0ddd3a53b..80d439944cb5 100644 --- a/sound/pci/mixart/mixart.c +++ b/sound/pci/mixart/mixart.c | |||
@@ -922,7 +922,7 @@ static snd_pcm_uframes_t snd_mixart_stream_pointer(struct snd_pcm_substream *sub | |||
922 | 922 | ||
923 | 923 | ||
924 | 924 | ||
925 | static struct snd_pcm_ops snd_mixart_playback_ops = { | 925 | static const struct snd_pcm_ops snd_mixart_playback_ops = { |
926 | .open = snd_mixart_playback_open, | 926 | .open = snd_mixart_playback_open, |
927 | .close = snd_mixart_close, | 927 | .close = snd_mixart_close, |
928 | .ioctl = snd_pcm_lib_ioctl, | 928 | .ioctl = snd_pcm_lib_ioctl, |
@@ -933,7 +933,7 @@ static struct snd_pcm_ops snd_mixart_playback_ops = { | |||
933 | .pointer = snd_mixart_stream_pointer, | 933 | .pointer = snd_mixart_stream_pointer, |
934 | }; | 934 | }; |
935 | 935 | ||
936 | static struct snd_pcm_ops snd_mixart_capture_ops = { | 936 | static const struct snd_pcm_ops snd_mixart_capture_ops = { |
937 | .open = snd_mixart_capture_open, | 937 | .open = snd_mixart_capture_open, |
938 | .close = snd_mixart_close, | 938 | .close = snd_mixart_close, |
939 | .ioctl = snd_pcm_lib_ioctl, | 939 | .ioctl = snd_pcm_lib_ioctl, |
diff --git a/sound/pci/nm256/nm256.c b/sound/pci/nm256/nm256.c index 4735e27cc773..103fe311e5a9 100644 --- a/sound/pci/nm256/nm256.c +++ b/sound/pci/nm256/nm256.c | |||
@@ -902,7 +902,7 @@ snd_nm256_capture_close(struct snd_pcm_substream *substream) | |||
902 | /* | 902 | /* |
903 | * create a pcm instance | 903 | * create a pcm instance |
904 | */ | 904 | */ |
905 | static struct snd_pcm_ops snd_nm256_playback_ops = { | 905 | static const struct snd_pcm_ops snd_nm256_playback_ops = { |
906 | .open = snd_nm256_playback_open, | 906 | .open = snd_nm256_playback_open, |
907 | .close = snd_nm256_playback_close, | 907 | .close = snd_nm256_playback_close, |
908 | .ioctl = snd_pcm_lib_ioctl, | 908 | .ioctl = snd_pcm_lib_ioctl, |
@@ -917,7 +917,7 @@ static struct snd_pcm_ops snd_nm256_playback_ops = { | |||
917 | .mmap = snd_pcm_lib_mmap_iomem, | 917 | .mmap = snd_pcm_lib_mmap_iomem, |
918 | }; | 918 | }; |
919 | 919 | ||
920 | static struct snd_pcm_ops snd_nm256_capture_ops = { | 920 | static const struct snd_pcm_ops snd_nm256_capture_ops = { |
921 | .open = snd_nm256_capture_open, | 921 | .open = snd_nm256_capture_open, |
922 | .close = snd_nm256_capture_close, | 922 | .close = snd_nm256_capture_close, |
923 | .ioctl = snd_pcm_lib_ioctl, | 923 | .ioctl = snd_pcm_lib_ioctl, |
diff --git a/sound/pci/oxygen/oxygen_pcm.c b/sound/pci/oxygen/oxygen_pcm.c index aa2ebd1d6d12..042a2439fea5 100644 --- a/sound/pci/oxygen/oxygen_pcm.c +++ b/sound/pci/oxygen/oxygen_pcm.c | |||
@@ -631,7 +631,7 @@ static snd_pcm_uframes_t oxygen_pointer(struct snd_pcm_substream *substream) | |||
631 | return bytes_to_frames(runtime, curr_addr - (u32)runtime->dma_addr); | 631 | return bytes_to_frames(runtime, curr_addr - (u32)runtime->dma_addr); |
632 | } | 632 | } |
633 | 633 | ||
634 | static struct snd_pcm_ops oxygen_rec_a_ops = { | 634 | static const struct snd_pcm_ops oxygen_rec_a_ops = { |
635 | .open = oxygen_rec_a_open, | 635 | .open = oxygen_rec_a_open, |
636 | .close = oxygen_close, | 636 | .close = oxygen_close, |
637 | .ioctl = snd_pcm_lib_ioctl, | 637 | .ioctl = snd_pcm_lib_ioctl, |
@@ -642,7 +642,7 @@ static struct snd_pcm_ops oxygen_rec_a_ops = { | |||
642 | .pointer = oxygen_pointer, | 642 | .pointer = oxygen_pointer, |
643 | }; | 643 | }; |
644 | 644 | ||
645 | static struct snd_pcm_ops oxygen_rec_b_ops = { | 645 | static const struct snd_pcm_ops oxygen_rec_b_ops = { |
646 | .open = oxygen_rec_b_open, | 646 | .open = oxygen_rec_b_open, |
647 | .close = oxygen_close, | 647 | .close = oxygen_close, |
648 | .ioctl = snd_pcm_lib_ioctl, | 648 | .ioctl = snd_pcm_lib_ioctl, |
@@ -653,7 +653,7 @@ static struct snd_pcm_ops oxygen_rec_b_ops = { | |||
653 | .pointer = oxygen_pointer, | 653 | .pointer = oxygen_pointer, |
654 | }; | 654 | }; |
655 | 655 | ||
656 | static struct snd_pcm_ops oxygen_rec_c_ops = { | 656 | static const struct snd_pcm_ops oxygen_rec_c_ops = { |
657 | .open = oxygen_rec_c_open, | 657 | .open = oxygen_rec_c_open, |
658 | .close = oxygen_close, | 658 | .close = oxygen_close, |
659 | .ioctl = snd_pcm_lib_ioctl, | 659 | .ioctl = snd_pcm_lib_ioctl, |
@@ -664,7 +664,7 @@ static struct snd_pcm_ops oxygen_rec_c_ops = { | |||
664 | .pointer = oxygen_pointer, | 664 | .pointer = oxygen_pointer, |
665 | }; | 665 | }; |
666 | 666 | ||
667 | static struct snd_pcm_ops oxygen_spdif_ops = { | 667 | static const struct snd_pcm_ops oxygen_spdif_ops = { |
668 | .open = oxygen_spdif_open, | 668 | .open = oxygen_spdif_open, |
669 | .close = oxygen_close, | 669 | .close = oxygen_close, |
670 | .ioctl = snd_pcm_lib_ioctl, | 670 | .ioctl = snd_pcm_lib_ioctl, |
@@ -675,7 +675,7 @@ static struct snd_pcm_ops oxygen_spdif_ops = { | |||
675 | .pointer = oxygen_pointer, | 675 | .pointer = oxygen_pointer, |
676 | }; | 676 | }; |
677 | 677 | ||
678 | static struct snd_pcm_ops oxygen_multich_ops = { | 678 | static const struct snd_pcm_ops oxygen_multich_ops = { |
679 | .open = oxygen_multich_open, | 679 | .open = oxygen_multich_open, |
680 | .close = oxygen_close, | 680 | .close = oxygen_close, |
681 | .ioctl = snd_pcm_lib_ioctl, | 681 | .ioctl = snd_pcm_lib_ioctl, |
@@ -686,7 +686,7 @@ static struct snd_pcm_ops oxygen_multich_ops = { | |||
686 | .pointer = oxygen_pointer, | 686 | .pointer = oxygen_pointer, |
687 | }; | 687 | }; |
688 | 688 | ||
689 | static struct snd_pcm_ops oxygen_ac97_ops = { | 689 | static const struct snd_pcm_ops oxygen_ac97_ops = { |
690 | .open = oxygen_ac97_open, | 690 | .open = oxygen_ac97_open, |
691 | .close = oxygen_close, | 691 | .close = oxygen_close, |
692 | .ioctl = snd_pcm_lib_ioctl, | 692 | .ioctl = snd_pcm_lib_ioctl, |
diff --git a/sound/pci/pcxhr/pcxhr.c b/sound/pci/pcxhr/pcxhr.c index 9293235281dc..bb7eee9d0c2b 100644 --- a/sound/pci/pcxhr/pcxhr.c +++ b/sound/pci/pcxhr/pcxhr.c | |||
@@ -1146,7 +1146,7 @@ static snd_pcm_uframes_t pcxhr_stream_pointer(struct snd_pcm_substream *subs) | |||
1146 | } | 1146 | } |
1147 | 1147 | ||
1148 | 1148 | ||
1149 | static struct snd_pcm_ops pcxhr_ops = { | 1149 | static const struct snd_pcm_ops pcxhr_ops = { |
1150 | .open = pcxhr_open, | 1150 | .open = pcxhr_open, |
1151 | .close = pcxhr_close, | 1151 | .close = pcxhr_close, |
1152 | .ioctl = snd_pcm_lib_ioctl, | 1152 | .ioctl = snd_pcm_lib_ioctl, |
diff --git a/sound/pci/riptide/riptide.c b/sound/pci/riptide/riptide.c index 067a91207d8e..ada5f01d479c 100644 --- a/sound/pci/riptide/riptide.c +++ b/sound/pci/riptide/riptide.c | |||
@@ -644,7 +644,7 @@ static struct lbuspath lbus_play_paths[] = { | |||
644 | .mono = lbus_play_mono3, | 644 | .mono = lbus_play_mono3, |
645 | }, | 645 | }, |
646 | }; | 646 | }; |
647 | static struct lbuspath lbus_rec_path = { | 647 | static const struct lbuspath lbus_rec_path = { |
648 | .noconv = lbus_rec_noconv1, | 648 | .noconv = lbus_rec_noconv1, |
649 | .stereo = lbus_rec_stereo1, | 649 | .stereo = lbus_rec_stereo1, |
650 | .mono = lbus_rec_mono1, | 650 | .mono = lbus_rec_mono1, |
@@ -1669,7 +1669,7 @@ static int snd_riptide_capture_close(struct snd_pcm_substream *substream) | |||
1669 | return 0; | 1669 | return 0; |
1670 | } | 1670 | } |
1671 | 1671 | ||
1672 | static struct snd_pcm_ops snd_riptide_playback_ops = { | 1672 | static const struct snd_pcm_ops snd_riptide_playback_ops = { |
1673 | .open = snd_riptide_playback_open, | 1673 | .open = snd_riptide_playback_open, |
1674 | .close = snd_riptide_playback_close, | 1674 | .close = snd_riptide_playback_close, |
1675 | .ioctl = snd_pcm_lib_ioctl, | 1675 | .ioctl = snd_pcm_lib_ioctl, |
@@ -1680,7 +1680,7 @@ static struct snd_pcm_ops snd_riptide_playback_ops = { | |||
1680 | .trigger = snd_riptide_trigger, | 1680 | .trigger = snd_riptide_trigger, |
1681 | .pointer = snd_riptide_pointer, | 1681 | .pointer = snd_riptide_pointer, |
1682 | }; | 1682 | }; |
1683 | static struct snd_pcm_ops snd_riptide_capture_ops = { | 1683 | static const struct snd_pcm_ops snd_riptide_capture_ops = { |
1684 | .open = snd_riptide_capture_open, | 1684 | .open = snd_riptide_capture_open, |
1685 | .close = snd_riptide_capture_close, | 1685 | .close = snd_riptide_capture_close, |
1686 | .ioctl = snd_pcm_lib_ioctl, | 1686 | .ioctl = snd_pcm_lib_ioctl, |
diff --git a/sound/pci/rme32.c b/sound/pci/rme32.c index cd94ac548ba3..96d15db65dfd 100644 --- a/sound/pci/rme32.c +++ b/sound/pci/rme32.c | |||
@@ -1196,7 +1196,7 @@ snd_rme32_capture_fd_pointer(struct snd_pcm_substream *substream) | |||
1196 | } | 1196 | } |
1197 | 1197 | ||
1198 | /* for halfduplex mode */ | 1198 | /* for halfduplex mode */ |
1199 | static struct snd_pcm_ops snd_rme32_playback_spdif_ops = { | 1199 | static const struct snd_pcm_ops snd_rme32_playback_spdif_ops = { |
1200 | .open = snd_rme32_playback_spdif_open, | 1200 | .open = snd_rme32_playback_spdif_open, |
1201 | .close = snd_rme32_playback_close, | 1201 | .close = snd_rme32_playback_close, |
1202 | .ioctl = snd_pcm_lib_ioctl, | 1202 | .ioctl = snd_pcm_lib_ioctl, |
@@ -1210,7 +1210,7 @@ static struct snd_pcm_ops snd_rme32_playback_spdif_ops = { | |||
1210 | .mmap = snd_pcm_lib_mmap_iomem, | 1210 | .mmap = snd_pcm_lib_mmap_iomem, |
1211 | }; | 1211 | }; |
1212 | 1212 | ||
1213 | static struct snd_pcm_ops snd_rme32_capture_spdif_ops = { | 1213 | static const struct snd_pcm_ops snd_rme32_capture_spdif_ops = { |
1214 | .open = snd_rme32_capture_spdif_open, | 1214 | .open = snd_rme32_capture_spdif_open, |
1215 | .close = snd_rme32_capture_close, | 1215 | .close = snd_rme32_capture_close, |
1216 | .ioctl = snd_pcm_lib_ioctl, | 1216 | .ioctl = snd_pcm_lib_ioctl, |
@@ -1223,7 +1223,7 @@ static struct snd_pcm_ops snd_rme32_capture_spdif_ops = { | |||
1223 | .mmap = snd_pcm_lib_mmap_iomem, | 1223 | .mmap = snd_pcm_lib_mmap_iomem, |
1224 | }; | 1224 | }; |
1225 | 1225 | ||
1226 | static struct snd_pcm_ops snd_rme32_playback_adat_ops = { | 1226 | static const struct snd_pcm_ops snd_rme32_playback_adat_ops = { |
1227 | .open = snd_rme32_playback_adat_open, | 1227 | .open = snd_rme32_playback_adat_open, |
1228 | .close = snd_rme32_playback_close, | 1228 | .close = snd_rme32_playback_close, |
1229 | .ioctl = snd_pcm_lib_ioctl, | 1229 | .ioctl = snd_pcm_lib_ioctl, |
@@ -1236,7 +1236,7 @@ static struct snd_pcm_ops snd_rme32_playback_adat_ops = { | |||
1236 | .mmap = snd_pcm_lib_mmap_iomem, | 1236 | .mmap = snd_pcm_lib_mmap_iomem, |
1237 | }; | 1237 | }; |
1238 | 1238 | ||
1239 | static struct snd_pcm_ops snd_rme32_capture_adat_ops = { | 1239 | static const struct snd_pcm_ops snd_rme32_capture_adat_ops = { |
1240 | .open = snd_rme32_capture_adat_open, | 1240 | .open = snd_rme32_capture_adat_open, |
1241 | .close = snd_rme32_capture_close, | 1241 | .close = snd_rme32_capture_close, |
1242 | .ioctl = snd_pcm_lib_ioctl, | 1242 | .ioctl = snd_pcm_lib_ioctl, |
@@ -1249,7 +1249,7 @@ static struct snd_pcm_ops snd_rme32_capture_adat_ops = { | |||
1249 | }; | 1249 | }; |
1250 | 1250 | ||
1251 | /* for fullduplex mode */ | 1251 | /* for fullduplex mode */ |
1252 | static struct snd_pcm_ops snd_rme32_playback_spdif_fd_ops = { | 1252 | static const struct snd_pcm_ops snd_rme32_playback_spdif_fd_ops = { |
1253 | .open = snd_rme32_playback_spdif_open, | 1253 | .open = snd_rme32_playback_spdif_open, |
1254 | .close = snd_rme32_playback_close, | 1254 | .close = snd_rme32_playback_close, |
1255 | .ioctl = snd_pcm_lib_ioctl, | 1255 | .ioctl = snd_pcm_lib_ioctl, |
@@ -1261,7 +1261,7 @@ static struct snd_pcm_ops snd_rme32_playback_spdif_fd_ops = { | |||
1261 | .ack = snd_rme32_playback_fd_ack, | 1261 | .ack = snd_rme32_playback_fd_ack, |
1262 | }; | 1262 | }; |
1263 | 1263 | ||
1264 | static struct snd_pcm_ops snd_rme32_capture_spdif_fd_ops = { | 1264 | static const struct snd_pcm_ops snd_rme32_capture_spdif_fd_ops = { |
1265 | .open = snd_rme32_capture_spdif_open, | 1265 | .open = snd_rme32_capture_spdif_open, |
1266 | .close = snd_rme32_capture_close, | 1266 | .close = snd_rme32_capture_close, |
1267 | .ioctl = snd_pcm_lib_ioctl, | 1267 | .ioctl = snd_pcm_lib_ioctl, |
@@ -1273,7 +1273,7 @@ static struct snd_pcm_ops snd_rme32_capture_spdif_fd_ops = { | |||
1273 | .ack = snd_rme32_capture_fd_ack, | 1273 | .ack = snd_rme32_capture_fd_ack, |
1274 | }; | 1274 | }; |
1275 | 1275 | ||
1276 | static struct snd_pcm_ops snd_rme32_playback_adat_fd_ops = { | 1276 | static const struct snd_pcm_ops snd_rme32_playback_adat_fd_ops = { |
1277 | .open = snd_rme32_playback_adat_open, | 1277 | .open = snd_rme32_playback_adat_open, |
1278 | .close = snd_rme32_playback_close, | 1278 | .close = snd_rme32_playback_close, |
1279 | .ioctl = snd_pcm_lib_ioctl, | 1279 | .ioctl = snd_pcm_lib_ioctl, |
@@ -1284,7 +1284,7 @@ static struct snd_pcm_ops snd_rme32_playback_adat_fd_ops = { | |||
1284 | .ack = snd_rme32_playback_fd_ack, | 1284 | .ack = snd_rme32_playback_fd_ack, |
1285 | }; | 1285 | }; |
1286 | 1286 | ||
1287 | static struct snd_pcm_ops snd_rme32_capture_adat_fd_ops = { | 1287 | static const struct snd_pcm_ops snd_rme32_capture_adat_fd_ops = { |
1288 | .open = snd_rme32_capture_adat_open, | 1288 | .open = snd_rme32_capture_adat_open, |
1289 | .close = snd_rme32_capture_close, | 1289 | .close = snd_rme32_capture_close, |
1290 | .ioctl = snd_pcm_lib_ioctl, | 1290 | .ioctl = snd_pcm_lib_ioctl, |
diff --git a/sound/pci/rme96.c b/sound/pci/rme96.c index 41c31db65039..05b9da30990d 100644 --- a/sound/pci/rme96.c +++ b/sound/pci/rme96.c | |||
@@ -1505,7 +1505,7 @@ snd_rme96_capture_pointer(struct snd_pcm_substream *substream) | |||
1505 | return snd_rme96_capture_ptr(rme96); | 1505 | return snd_rme96_capture_ptr(rme96); |
1506 | } | 1506 | } |
1507 | 1507 | ||
1508 | static struct snd_pcm_ops snd_rme96_playback_spdif_ops = { | 1508 | static const struct snd_pcm_ops snd_rme96_playback_spdif_ops = { |
1509 | .open = snd_rme96_playback_spdif_open, | 1509 | .open = snd_rme96_playback_spdif_open, |
1510 | .close = snd_rme96_playback_close, | 1510 | .close = snd_rme96_playback_close, |
1511 | .ioctl = snd_pcm_lib_ioctl, | 1511 | .ioctl = snd_pcm_lib_ioctl, |
@@ -1518,7 +1518,7 @@ static struct snd_pcm_ops snd_rme96_playback_spdif_ops = { | |||
1518 | .mmap = snd_pcm_lib_mmap_iomem, | 1518 | .mmap = snd_pcm_lib_mmap_iomem, |
1519 | }; | 1519 | }; |
1520 | 1520 | ||
1521 | static struct snd_pcm_ops snd_rme96_capture_spdif_ops = { | 1521 | static const struct snd_pcm_ops snd_rme96_capture_spdif_ops = { |
1522 | .open = snd_rme96_capture_spdif_open, | 1522 | .open = snd_rme96_capture_spdif_open, |
1523 | .close = snd_rme96_capture_close, | 1523 | .close = snd_rme96_capture_close, |
1524 | .ioctl = snd_pcm_lib_ioctl, | 1524 | .ioctl = snd_pcm_lib_ioctl, |
@@ -1530,7 +1530,7 @@ static struct snd_pcm_ops snd_rme96_capture_spdif_ops = { | |||
1530 | .mmap = snd_pcm_lib_mmap_iomem, | 1530 | .mmap = snd_pcm_lib_mmap_iomem, |
1531 | }; | 1531 | }; |
1532 | 1532 | ||
1533 | static struct snd_pcm_ops snd_rme96_playback_adat_ops = { | 1533 | static const struct snd_pcm_ops snd_rme96_playback_adat_ops = { |
1534 | .open = snd_rme96_playback_adat_open, | 1534 | .open = snd_rme96_playback_adat_open, |
1535 | .close = snd_rme96_playback_close, | 1535 | .close = snd_rme96_playback_close, |
1536 | .ioctl = snd_pcm_lib_ioctl, | 1536 | .ioctl = snd_pcm_lib_ioctl, |
@@ -1543,7 +1543,7 @@ static struct snd_pcm_ops snd_rme96_playback_adat_ops = { | |||
1543 | .mmap = snd_pcm_lib_mmap_iomem, | 1543 | .mmap = snd_pcm_lib_mmap_iomem, |
1544 | }; | 1544 | }; |
1545 | 1545 | ||
1546 | static struct snd_pcm_ops snd_rme96_capture_adat_ops = { | 1546 | static const struct snd_pcm_ops snd_rme96_capture_adat_ops = { |
1547 | .open = snd_rme96_capture_adat_open, | 1547 | .open = snd_rme96_capture_adat_open, |
1548 | .close = snd_rme96_capture_close, | 1548 | .close = snd_rme96_capture_close, |
1549 | .ioctl = snd_pcm_lib_ioctl, | 1549 | .ioctl = snd_pcm_lib_ioctl, |
diff --git a/sound/pci/rme9652/hdsp.c b/sound/pci/rme9652/hdsp.c index 7c8941b8b2de..b94fc6357139 100644 --- a/sound/pci/rme9652/hdsp.c +++ b/sound/pci/rme9652/hdsp.c | |||
@@ -4861,7 +4861,7 @@ static int snd_hdsp_hwdep_ioctl(struct snd_hwdep *hw, struct file *file, unsigne | |||
4861 | return 0; | 4861 | return 0; |
4862 | } | 4862 | } |
4863 | 4863 | ||
4864 | static struct snd_pcm_ops snd_hdsp_playback_ops = { | 4864 | static const struct snd_pcm_ops snd_hdsp_playback_ops = { |
4865 | .open = snd_hdsp_playback_open, | 4865 | .open = snd_hdsp_playback_open, |
4866 | .close = snd_hdsp_playback_release, | 4866 | .close = snd_hdsp_playback_release, |
4867 | .ioctl = snd_hdsp_ioctl, | 4867 | .ioctl = snd_hdsp_ioctl, |
@@ -4873,7 +4873,7 @@ static struct snd_pcm_ops snd_hdsp_playback_ops = { | |||
4873 | .silence = snd_hdsp_hw_silence, | 4873 | .silence = snd_hdsp_hw_silence, |
4874 | }; | 4874 | }; |
4875 | 4875 | ||
4876 | static struct snd_pcm_ops snd_hdsp_capture_ops = { | 4876 | static const struct snd_pcm_ops snd_hdsp_capture_ops = { |
4877 | .open = snd_hdsp_capture_open, | 4877 | .open = snd_hdsp_capture_open, |
4878 | .close = snd_hdsp_capture_release, | 4878 | .close = snd_hdsp_capture_release, |
4879 | .ioctl = snd_hdsp_ioctl, | 4879 | .ioctl = snd_hdsp_ioctl, |
diff --git a/sound/pci/rme9652/hdspm.c b/sound/pci/rme9652/hdspm.c index a4a999a0317e..14bbf55c1ef9 100644 --- a/sound/pci/rme9652/hdspm.c +++ b/sound/pci/rme9652/hdspm.c | |||
@@ -1666,7 +1666,7 @@ static int hdspm_set_rate(struct hdspm * hdspm, int rate, int called_internally) | |||
1666 | HDSPM_AUTOSYNC_FROM_NONE) { | 1666 | HDSPM_AUTOSYNC_FROM_NONE) { |
1667 | 1667 | ||
1668 | dev_warn(hdspm->card->dev, | 1668 | dev_warn(hdspm->card->dev, |
1669 | "Detected no Externel Sync\n"); | 1669 | "Detected no External Sync\n"); |
1670 | not_set = 1; | 1670 | not_set = 1; |
1671 | 1671 | ||
1672 | } else if (rate != external_freq) { | 1672 | } else if (rate != external_freq) { |
@@ -6361,7 +6361,7 @@ static int snd_hdspm_hwdep_ioctl(struct snd_hwdep *hw, struct file *file, | |||
6361 | return 0; | 6361 | return 0; |
6362 | } | 6362 | } |
6363 | 6363 | ||
6364 | static struct snd_pcm_ops snd_hdspm_ops = { | 6364 | static const struct snd_pcm_ops snd_hdspm_ops = { |
6365 | .open = snd_hdspm_open, | 6365 | .open = snd_hdspm_open, |
6366 | .close = snd_hdspm_release, | 6366 | .close = snd_hdspm_release, |
6367 | .ioctl = snd_hdspm_ioctl, | 6367 | .ioctl = snd_hdspm_ioctl, |
diff --git a/sound/pci/rme9652/rme9652.c b/sound/pci/rme9652/rme9652.c index fdbc0aa2776a..55172c689991 100644 --- a/sound/pci/rme9652/rme9652.c +++ b/sound/pci/rme9652/rme9652.c | |||
@@ -2368,7 +2368,7 @@ static int snd_rme9652_capture_release(struct snd_pcm_substream *substream) | |||
2368 | return 0; | 2368 | return 0; |
2369 | } | 2369 | } |
2370 | 2370 | ||
2371 | static struct snd_pcm_ops snd_rme9652_playback_ops = { | 2371 | static const struct snd_pcm_ops snd_rme9652_playback_ops = { |
2372 | .open = snd_rme9652_playback_open, | 2372 | .open = snd_rme9652_playback_open, |
2373 | .close = snd_rme9652_playback_release, | 2373 | .close = snd_rme9652_playback_release, |
2374 | .ioctl = snd_rme9652_ioctl, | 2374 | .ioctl = snd_rme9652_ioctl, |
@@ -2380,7 +2380,7 @@ static struct snd_pcm_ops snd_rme9652_playback_ops = { | |||
2380 | .silence = snd_rme9652_hw_silence, | 2380 | .silence = snd_rme9652_hw_silence, |
2381 | }; | 2381 | }; |
2382 | 2382 | ||
2383 | static struct snd_pcm_ops snd_rme9652_capture_ops = { | 2383 | static const struct snd_pcm_ops snd_rme9652_capture_ops = { |
2384 | .open = snd_rme9652_capture_open, | 2384 | .open = snd_rme9652_capture_open, |
2385 | .close = snd_rme9652_capture_release, | 2385 | .close = snd_rme9652_capture_release, |
2386 | .ioctl = snd_rme9652_ioctl, | 2386 | .ioctl = snd_rme9652_ioctl, |
diff --git a/sound/pci/sonicvibes.c b/sound/pci/sonicvibes.c index 1b6fad7d4d56..e1a13870bb80 100644 --- a/sound/pci/sonicvibes.c +++ b/sound/pci/sonicvibes.c | |||
@@ -857,7 +857,7 @@ static int snd_sonicvibes_capture_close(struct snd_pcm_substream *substream) | |||
857 | return 0; | 857 | return 0; |
858 | } | 858 | } |
859 | 859 | ||
860 | static struct snd_pcm_ops snd_sonicvibes_playback_ops = { | 860 | static const struct snd_pcm_ops snd_sonicvibes_playback_ops = { |
861 | .open = snd_sonicvibes_playback_open, | 861 | .open = snd_sonicvibes_playback_open, |
862 | .close = snd_sonicvibes_playback_close, | 862 | .close = snd_sonicvibes_playback_close, |
863 | .ioctl = snd_pcm_lib_ioctl, | 863 | .ioctl = snd_pcm_lib_ioctl, |
@@ -868,7 +868,7 @@ static struct snd_pcm_ops snd_sonicvibes_playback_ops = { | |||
868 | .pointer = snd_sonicvibes_playback_pointer, | 868 | .pointer = snd_sonicvibes_playback_pointer, |
869 | }; | 869 | }; |
870 | 870 | ||
871 | static struct snd_pcm_ops snd_sonicvibes_capture_ops = { | 871 | static const struct snd_pcm_ops snd_sonicvibes_capture_ops = { |
872 | .open = snd_sonicvibes_capture_open, | 872 | .open = snd_sonicvibes_capture_open, |
873 | .close = snd_sonicvibes_capture_close, | 873 | .close = snd_sonicvibes_capture_close, |
874 | .ioctl = snd_pcm_lib_ioctl, | 874 | .ioctl = snd_pcm_lib_ioctl, |
diff --git a/sound/pci/trident/trident_main.c b/sound/pci/trident/trident_main.c index 599d2b7eb5b8..27f0ed840979 100644 --- a/sound/pci/trident/trident_main.c +++ b/sound/pci/trident/trident_main.c | |||
@@ -2070,7 +2070,7 @@ static int snd_trident_foldback_close(struct snd_pcm_substream *substream) | |||
2070 | PCM operations | 2070 | PCM operations |
2071 | ---------------------------------------------------------------------------*/ | 2071 | ---------------------------------------------------------------------------*/ |
2072 | 2072 | ||
2073 | static struct snd_pcm_ops snd_trident_playback_ops = { | 2073 | static const struct snd_pcm_ops snd_trident_playback_ops = { |
2074 | .open = snd_trident_playback_open, | 2074 | .open = snd_trident_playback_open, |
2075 | .close = snd_trident_playback_close, | 2075 | .close = snd_trident_playback_close, |
2076 | .ioctl = snd_trident_ioctl, | 2076 | .ioctl = snd_trident_ioctl, |
@@ -2081,7 +2081,7 @@ static struct snd_pcm_ops snd_trident_playback_ops = { | |||
2081 | .pointer = snd_trident_playback_pointer, | 2081 | .pointer = snd_trident_playback_pointer, |
2082 | }; | 2082 | }; |
2083 | 2083 | ||
2084 | static struct snd_pcm_ops snd_trident_nx_playback_ops = { | 2084 | static const struct snd_pcm_ops snd_trident_nx_playback_ops = { |
2085 | .open = snd_trident_playback_open, | 2085 | .open = snd_trident_playback_open, |
2086 | .close = snd_trident_playback_close, | 2086 | .close = snd_trident_playback_close, |
2087 | .ioctl = snd_trident_ioctl, | 2087 | .ioctl = snd_trident_ioctl, |
@@ -2115,7 +2115,7 @@ static struct snd_pcm_ops snd_trident_si7018_capture_ops = { | |||
2115 | .pointer = snd_trident_playback_pointer, | 2115 | .pointer = snd_trident_playback_pointer, |
2116 | }; | 2116 | }; |
2117 | 2117 | ||
2118 | static struct snd_pcm_ops snd_trident_foldback_ops = { | 2118 | static const struct snd_pcm_ops snd_trident_foldback_ops = { |
2119 | .open = snd_trident_foldback_open, | 2119 | .open = snd_trident_foldback_open, |
2120 | .close = snd_trident_foldback_close, | 2120 | .close = snd_trident_foldback_close, |
2121 | .ioctl = snd_trident_ioctl, | 2121 | .ioctl = snd_trident_ioctl, |
@@ -2126,7 +2126,7 @@ static struct snd_pcm_ops snd_trident_foldback_ops = { | |||
2126 | .pointer = snd_trident_playback_pointer, | 2126 | .pointer = snd_trident_playback_pointer, |
2127 | }; | 2127 | }; |
2128 | 2128 | ||
2129 | static struct snd_pcm_ops snd_trident_nx_foldback_ops = { | 2129 | static const struct snd_pcm_ops snd_trident_nx_foldback_ops = { |
2130 | .open = snd_trident_foldback_open, | 2130 | .open = snd_trident_foldback_open, |
2131 | .close = snd_trident_foldback_close, | 2131 | .close = snd_trident_foldback_close, |
2132 | .ioctl = snd_trident_ioctl, | 2132 | .ioctl = snd_trident_ioctl, |
@@ -2138,7 +2138,7 @@ static struct snd_pcm_ops snd_trident_nx_foldback_ops = { | |||
2138 | .page = snd_pcm_sgbuf_ops_page, | 2138 | .page = snd_pcm_sgbuf_ops_page, |
2139 | }; | 2139 | }; |
2140 | 2140 | ||
2141 | static struct snd_pcm_ops snd_trident_spdif_ops = { | 2141 | static const struct snd_pcm_ops snd_trident_spdif_ops = { |
2142 | .open = snd_trident_spdif_open, | 2142 | .open = snd_trident_spdif_open, |
2143 | .close = snd_trident_spdif_close, | 2143 | .close = snd_trident_spdif_close, |
2144 | .ioctl = snd_trident_ioctl, | 2144 | .ioctl = snd_trident_ioctl, |
@@ -2149,7 +2149,7 @@ static struct snd_pcm_ops snd_trident_spdif_ops = { | |||
2149 | .pointer = snd_trident_spdif_pointer, | 2149 | .pointer = snd_trident_spdif_pointer, |
2150 | }; | 2150 | }; |
2151 | 2151 | ||
2152 | static struct snd_pcm_ops snd_trident_spdif_7018_ops = { | 2152 | static const struct snd_pcm_ops snd_trident_spdif_7018_ops = { |
2153 | .open = snd_trident_spdif_open, | 2153 | .open = snd_trident_spdif_open, |
2154 | .close = snd_trident_spdif_close, | 2154 | .close = snd_trident_spdif_close, |
2155 | .ioctl = snd_trident_ioctl, | 2155 | .ioctl = snd_trident_ioctl, |
diff --git a/sound/pci/via82xx.c b/sound/pci/via82xx.c index 3dd038bdb204..38a17b4342a6 100644 --- a/sound/pci/via82xx.c +++ b/sound/pci/via82xx.c | |||
@@ -1366,7 +1366,7 @@ static int snd_via8233_playback_close(struct snd_pcm_substream *substream) | |||
1366 | 1366 | ||
1367 | 1367 | ||
1368 | /* via686 playback callbacks */ | 1368 | /* via686 playback callbacks */ |
1369 | static struct snd_pcm_ops snd_via686_playback_ops = { | 1369 | static const struct snd_pcm_ops snd_via686_playback_ops = { |
1370 | .open = snd_via686_playback_open, | 1370 | .open = snd_via686_playback_open, |
1371 | .close = snd_via82xx_pcm_close, | 1371 | .close = snd_via82xx_pcm_close, |
1372 | .ioctl = snd_pcm_lib_ioctl, | 1372 | .ioctl = snd_pcm_lib_ioctl, |
@@ -1379,7 +1379,7 @@ static struct snd_pcm_ops snd_via686_playback_ops = { | |||
1379 | }; | 1379 | }; |
1380 | 1380 | ||
1381 | /* via686 capture callbacks */ | 1381 | /* via686 capture callbacks */ |
1382 | static struct snd_pcm_ops snd_via686_capture_ops = { | 1382 | static const struct snd_pcm_ops snd_via686_capture_ops = { |
1383 | .open = snd_via82xx_capture_open, | 1383 | .open = snd_via82xx_capture_open, |
1384 | .close = snd_via82xx_pcm_close, | 1384 | .close = snd_via82xx_pcm_close, |
1385 | .ioctl = snd_pcm_lib_ioctl, | 1385 | .ioctl = snd_pcm_lib_ioctl, |
@@ -1392,7 +1392,7 @@ static struct snd_pcm_ops snd_via686_capture_ops = { | |||
1392 | }; | 1392 | }; |
1393 | 1393 | ||
1394 | /* via823x DSX playback callbacks */ | 1394 | /* via823x DSX playback callbacks */ |
1395 | static struct snd_pcm_ops snd_via8233_playback_ops = { | 1395 | static const struct snd_pcm_ops snd_via8233_playback_ops = { |
1396 | .open = snd_via8233_playback_open, | 1396 | .open = snd_via8233_playback_open, |
1397 | .close = snd_via8233_playback_close, | 1397 | .close = snd_via8233_playback_close, |
1398 | .ioctl = snd_pcm_lib_ioctl, | 1398 | .ioctl = snd_pcm_lib_ioctl, |
@@ -1405,7 +1405,7 @@ static struct snd_pcm_ops snd_via8233_playback_ops = { | |||
1405 | }; | 1405 | }; |
1406 | 1406 | ||
1407 | /* via823x multi-channel playback callbacks */ | 1407 | /* via823x multi-channel playback callbacks */ |
1408 | static struct snd_pcm_ops snd_via8233_multi_ops = { | 1408 | static const struct snd_pcm_ops snd_via8233_multi_ops = { |
1409 | .open = snd_via8233_multi_open, | 1409 | .open = snd_via8233_multi_open, |
1410 | .close = snd_via82xx_pcm_close, | 1410 | .close = snd_via82xx_pcm_close, |
1411 | .ioctl = snd_pcm_lib_ioctl, | 1411 | .ioctl = snd_pcm_lib_ioctl, |
@@ -1418,7 +1418,7 @@ static struct snd_pcm_ops snd_via8233_multi_ops = { | |||
1418 | }; | 1418 | }; |
1419 | 1419 | ||
1420 | /* via823x capture callbacks */ | 1420 | /* via823x capture callbacks */ |
1421 | static struct snd_pcm_ops snd_via8233_capture_ops = { | 1421 | static const struct snd_pcm_ops snd_via8233_capture_ops = { |
1422 | .open = snd_via82xx_capture_open, | 1422 | .open = snd_via82xx_capture_open, |
1423 | .close = snd_via82xx_pcm_close, | 1423 | .close = snd_via82xx_pcm_close, |
1424 | .ioctl = snd_pcm_lib_ioctl, | 1424 | .ioctl = snd_pcm_lib_ioctl, |
diff --git a/sound/pci/via82xx_modem.c b/sound/pci/via82xx_modem.c index 99b9137bc677..2f6d40f10618 100644 --- a/sound/pci/via82xx_modem.c +++ b/sound/pci/via82xx_modem.c | |||
@@ -804,7 +804,7 @@ static int snd_via82xx_pcm_close(struct snd_pcm_substream *substream) | |||
804 | 804 | ||
805 | 805 | ||
806 | /* via686 playback callbacks */ | 806 | /* via686 playback callbacks */ |
807 | static struct snd_pcm_ops snd_via686_playback_ops = { | 807 | static const struct snd_pcm_ops snd_via686_playback_ops = { |
808 | .open = snd_via82xx_playback_open, | 808 | .open = snd_via82xx_playback_open, |
809 | .close = snd_via82xx_pcm_close, | 809 | .close = snd_via82xx_pcm_close, |
810 | .ioctl = snd_pcm_lib_ioctl, | 810 | .ioctl = snd_pcm_lib_ioctl, |
@@ -817,7 +817,7 @@ static struct snd_pcm_ops snd_via686_playback_ops = { | |||
817 | }; | 817 | }; |
818 | 818 | ||
819 | /* via686 capture callbacks */ | 819 | /* via686 capture callbacks */ |
820 | static struct snd_pcm_ops snd_via686_capture_ops = { | 820 | static const struct snd_pcm_ops snd_via686_capture_ops = { |
821 | .open = snd_via82xx_capture_open, | 821 | .open = snd_via82xx_capture_open, |
822 | .close = snd_via82xx_pcm_close, | 822 | .close = snd_via82xx_pcm_close, |
823 | .ioctl = snd_pcm_lib_ioctl, | 823 | .ioctl = snd_pcm_lib_ioctl, |
diff --git a/sound/pci/ymfpci/ymfpci_main.c b/sound/pci/ymfpci/ymfpci_main.c index 4c26076dbf78..ffee284898b3 100644 --- a/sound/pci/ymfpci/ymfpci_main.c +++ b/sound/pci/ymfpci/ymfpci_main.c | |||
@@ -1123,7 +1123,7 @@ static int snd_ymfpci_capture_close(struct snd_pcm_substream *substream) | |||
1123 | return 0; | 1123 | return 0; |
1124 | } | 1124 | } |
1125 | 1125 | ||
1126 | static struct snd_pcm_ops snd_ymfpci_playback_ops = { | 1126 | static const struct snd_pcm_ops snd_ymfpci_playback_ops = { |
1127 | .open = snd_ymfpci_playback_open, | 1127 | .open = snd_ymfpci_playback_open, |
1128 | .close = snd_ymfpci_playback_close, | 1128 | .close = snd_ymfpci_playback_close, |
1129 | .ioctl = snd_pcm_lib_ioctl, | 1129 | .ioctl = snd_pcm_lib_ioctl, |
@@ -1134,7 +1134,7 @@ static struct snd_pcm_ops snd_ymfpci_playback_ops = { | |||
1134 | .pointer = snd_ymfpci_playback_pointer, | 1134 | .pointer = snd_ymfpci_playback_pointer, |
1135 | }; | 1135 | }; |
1136 | 1136 | ||
1137 | static struct snd_pcm_ops snd_ymfpci_capture_rec_ops = { | 1137 | static const struct snd_pcm_ops snd_ymfpci_capture_rec_ops = { |
1138 | .open = snd_ymfpci_capture_rec_open, | 1138 | .open = snd_ymfpci_capture_rec_open, |
1139 | .close = snd_ymfpci_capture_close, | 1139 | .close = snd_ymfpci_capture_close, |
1140 | .ioctl = snd_pcm_lib_ioctl, | 1140 | .ioctl = snd_pcm_lib_ioctl, |
@@ -1169,7 +1169,7 @@ int snd_ymfpci_pcm(struct snd_ymfpci *chip, int device) | |||
1169 | snd_pcm_std_chmaps, 2, 0, NULL); | 1169 | snd_pcm_std_chmaps, 2, 0, NULL); |
1170 | } | 1170 | } |
1171 | 1171 | ||
1172 | static struct snd_pcm_ops snd_ymfpci_capture_ac97_ops = { | 1172 | static const struct snd_pcm_ops snd_ymfpci_capture_ac97_ops = { |
1173 | .open = snd_ymfpci_capture_ac97_open, | 1173 | .open = snd_ymfpci_capture_ac97_open, |
1174 | .close = snd_ymfpci_capture_close, | 1174 | .close = snd_ymfpci_capture_close, |
1175 | .ioctl = snd_pcm_lib_ioctl, | 1175 | .ioctl = snd_pcm_lib_ioctl, |
@@ -1203,7 +1203,7 @@ int snd_ymfpci_pcm2(struct snd_ymfpci *chip, int device) | |||
1203 | return 0; | 1203 | return 0; |
1204 | } | 1204 | } |
1205 | 1205 | ||
1206 | static struct snd_pcm_ops snd_ymfpci_playback_spdif_ops = { | 1206 | static const struct snd_pcm_ops snd_ymfpci_playback_spdif_ops = { |
1207 | .open = snd_ymfpci_playback_spdif_open, | 1207 | .open = snd_ymfpci_playback_spdif_open, |
1208 | .close = snd_ymfpci_playback_spdif_close, | 1208 | .close = snd_ymfpci_playback_spdif_close, |
1209 | .ioctl = snd_pcm_lib_ioctl, | 1209 | .ioctl = snd_pcm_lib_ioctl, |
@@ -1236,7 +1236,7 @@ int snd_ymfpci_pcm_spdif(struct snd_ymfpci *chip, int device) | |||
1236 | return 0; | 1236 | return 0; |
1237 | } | 1237 | } |
1238 | 1238 | ||
1239 | static struct snd_pcm_ops snd_ymfpci_playback_4ch_ops = { | 1239 | static const struct snd_pcm_ops snd_ymfpci_playback_4ch_ops = { |
1240 | .open = snd_ymfpci_playback_4ch_open, | 1240 | .open = snd_ymfpci_playback_4ch_open, |
1241 | .close = snd_ymfpci_playback_4ch_close, | 1241 | .close = snd_ymfpci_playback_4ch_close, |
1242 | .ioctl = snd_pcm_lib_ioctl, | 1242 | .ioctl = snd_pcm_lib_ioctl, |
diff --git a/sound/ppc/snd_ps3.c b/sound/ppc/snd_ps3.c index 368242519279..b84d7d34f188 100644 --- a/sound/ppc/snd_ps3.c +++ b/sound/ppc/snd_ps3.c | |||
@@ -564,9 +564,7 @@ static int snd_ps3_pcm_hw_params(struct snd_pcm_substream *substream, | |||
564 | 564 | ||
565 | static int snd_ps3_pcm_hw_free(struct snd_pcm_substream *substream) | 565 | static int snd_ps3_pcm_hw_free(struct snd_pcm_substream *substream) |
566 | { | 566 | { |
567 | int ret; | 567 | return snd_pcm_lib_free_pages(substream); |
568 | ret = snd_pcm_lib_free_pages(substream); | ||
569 | return ret; | ||
570 | }; | 568 | }; |
571 | 569 | ||
572 | static int snd_ps3_delay_to_bytes(struct snd_pcm_substream *substream, | 570 | static int snd_ps3_delay_to_bytes(struct snd_pcm_substream *substream, |
diff --git a/sound/soc/amd/acp-pcm-dma.c b/sound/soc/amd/acp-pcm-dma.c index d1fb035f44db..504c7cd7f58a 100644 --- a/sound/soc/amd/acp-pcm-dma.c +++ b/sound/soc/amd/acp-pcm-dma.c | |||
@@ -897,7 +897,7 @@ static int acp_dma_close(struct snd_pcm_substream *substream) | |||
897 | return 0; | 897 | return 0; |
898 | } | 898 | } |
899 | 899 | ||
900 | static struct snd_pcm_ops acp_dma_ops = { | 900 | static const struct snd_pcm_ops acp_dma_ops = { |
901 | .open = acp_dma_open, | 901 | .open = acp_dma_open, |
902 | .close = acp_dma_close, | 902 | .close = acp_dma_close, |
903 | .ioctl = snd_pcm_lib_ioctl, | 903 | .ioctl = snd_pcm_lib_ioctl, |
diff --git a/sound/soc/atmel/atmel-classd.c b/sound/soc/atmel/atmel-classd.c index 6d9b8b44e2da..89ac5f5a93eb 100644 --- a/sound/soc/atmel/atmel-classd.c +++ b/sound/soc/atmel/atmel-classd.c | |||
@@ -308,9 +308,11 @@ static struct regmap *atmel_classd_codec_get_remap(struct device *dev) | |||
308 | 308 | ||
309 | static struct snd_soc_codec_driver soc_codec_dev_classd = { | 309 | static struct snd_soc_codec_driver soc_codec_dev_classd = { |
310 | .probe = atmel_classd_codec_probe, | 310 | .probe = atmel_classd_codec_probe, |
311 | .controls = atmel_classd_snd_controls, | ||
312 | .num_controls = ARRAY_SIZE(atmel_classd_snd_controls), | ||
313 | .get_regmap = atmel_classd_codec_get_remap, | 311 | .get_regmap = atmel_classd_codec_get_remap, |
312 | .component_driver = { | ||
313 | .controls = atmel_classd_snd_controls, | ||
314 | .num_controls = ARRAY_SIZE(atmel_classd_snd_controls), | ||
315 | }, | ||
314 | }; | 316 | }; |
315 | 317 | ||
316 | /* codec dai component */ | 318 | /* codec dai component */ |
diff --git a/sound/soc/atmel/atmel-pcm-pdc.c b/sound/soc/atmel/atmel-pcm-pdc.c index da861b44413f..91b7069c3499 100644 --- a/sound/soc/atmel/atmel-pcm-pdc.c +++ b/sound/soc/atmel/atmel-pcm-pdc.c | |||
@@ -381,7 +381,7 @@ static int atmel_pcm_close(struct snd_pcm_substream *substream) | |||
381 | return 0; | 381 | return 0; |
382 | } | 382 | } |
383 | 383 | ||
384 | static struct snd_pcm_ops atmel_pcm_ops = { | 384 | static const struct snd_pcm_ops atmel_pcm_ops = { |
385 | .open = atmel_pcm_open, | 385 | .open = atmel_pcm_open, |
386 | .close = atmel_pcm_close, | 386 | .close = atmel_pcm_close, |
387 | .ioctl = snd_pcm_lib_ioctl, | 387 | .ioctl = snd_pcm_lib_ioctl, |
diff --git a/sound/soc/atmel/atmel-pdmic.c b/sound/soc/atmel/atmel-pdmic.c index 5f56da60c92f..c917df7715d1 100644 --- a/sound/soc/atmel/atmel-pdmic.c +++ b/sound/soc/atmel/atmel-pdmic.c | |||
@@ -80,7 +80,7 @@ static struct atmel_pdmic_pdata *atmel_pdmic_dt_init(struct device *dev) | |||
80 | 80 | ||
81 | if (pdata->mic_max_freq < pdata->mic_min_freq) { | 81 | if (pdata->mic_max_freq < pdata->mic_min_freq) { |
82 | dev_err(dev, | 82 | dev_err(dev, |
83 | "mic-max-freq should not less than mic-min-freq\n"); | 83 | "mic-max-freq should not be less than mic-min-freq\n"); |
84 | return ERR_PTR(-EINVAL); | 84 | return ERR_PTR(-EINVAL); |
85 | } | 85 | } |
86 | 86 | ||
@@ -115,8 +115,10 @@ static int atmel_pdmic_cpu_dai_startup(struct snd_pcm_substream *substream, | |||
115 | return ret; | 115 | return ret; |
116 | 116 | ||
117 | ret = clk_prepare_enable(dd->pclk); | 117 | ret = clk_prepare_enable(dd->pclk); |
118 | if (ret) | 118 | if (ret) { |
119 | clk_disable_unprepare(dd->gclk); | ||
119 | return ret; | 120 | return ret; |
121 | } | ||
120 | 122 | ||
121 | /* Clear all bits in the Control Register(PDMIC_CR) */ | 123 | /* Clear all bits in the Control Register(PDMIC_CR) */ |
122 | regmap_write(dd->regmap, PDMIC_CR, 0); | 124 | regmap_write(dd->regmap, PDMIC_CR, 0); |
@@ -283,7 +285,7 @@ static const DECLARE_TLV_DB_RANGE(mic_gain_tlv, | |||
283 | 8, ARRAY_SIZE(mic_gain_table)-1, TLV_DB_SCALE_ITEM(-6500, 100, 0), | 285 | 8, ARRAY_SIZE(mic_gain_table)-1, TLV_DB_SCALE_ITEM(-6500, 100, 0), |
284 | ); | 286 | ); |
285 | 287 | ||
286 | int pdmic_get_mic_volsw(struct snd_kcontrol *kcontrol, | 288 | static int pdmic_get_mic_volsw(struct snd_kcontrol *kcontrol, |
287 | struct snd_ctl_elem_value *ucontrol) | 289 | struct snd_ctl_elem_value *ucontrol) |
288 | { | 290 | { |
289 | struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); | 291 | struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); |
@@ -357,8 +359,10 @@ static int atmel_pdmic_codec_probe(struct snd_soc_codec *codec) | |||
357 | 359 | ||
358 | static struct snd_soc_codec_driver soc_codec_dev_pdmic = { | 360 | static struct snd_soc_codec_driver soc_codec_dev_pdmic = { |
359 | .probe = atmel_pdmic_codec_probe, | 361 | .probe = atmel_pdmic_codec_probe, |
360 | .controls = atmel_pdmic_snd_controls, | 362 | .component_driver = { |
361 | .num_controls = ARRAY_SIZE(atmel_pdmic_snd_controls), | 363 | .controls = atmel_pdmic_snd_controls, |
364 | .num_controls = ARRAY_SIZE(atmel_pdmic_snd_controls), | ||
365 | }, | ||
362 | }; | 366 | }; |
363 | 367 | ||
364 | /* codec dai component */ | 368 | /* codec dai component */ |
@@ -596,7 +600,7 @@ static int atmel_pdmic_probe(struct platform_device *pdev) | |||
596 | dd->irq = platform_get_irq(pdev, 0); | 600 | dd->irq = platform_get_irq(pdev, 0); |
597 | if (dd->irq < 0) { | 601 | if (dd->irq < 0) { |
598 | ret = dd->irq; | 602 | ret = dd->irq; |
599 | dev_err(dev, "failed to could not get irq: %d\n", ret); | 603 | dev_err(dev, "failed to get irq: %d\n", ret); |
600 | return ret; | 604 | return ret; |
601 | } | 605 | } |
602 | 606 | ||
@@ -614,7 +618,7 @@ static int atmel_pdmic_probe(struct platform_device *pdev) | |||
614 | return ret; | 618 | return ret; |
615 | } | 619 | } |
616 | 620 | ||
617 | /* The gclk clock frequency must always be tree times | 621 | /* The gclk clock frequency must always be three times |
618 | * lower than the pclk clock frequency | 622 | * lower than the pclk clock frequency |
619 | */ | 623 | */ |
620 | ret = clk_set_rate(dd->gclk, clk_get_rate(dd->pclk)/3); | 624 | ret = clk_set_rate(dd->gclk, clk_get_rate(dd->pclk)/3); |
@@ -649,7 +653,7 @@ static int atmel_pdmic_probe(struct platform_device *pdev) | |||
649 | return ret; | 653 | return ret; |
650 | } | 654 | } |
651 | 655 | ||
652 | /* Get the minimal and maximal sample rate that micphone supports */ | 656 | /* Get the minimal and maximal sample rate that the microphone supports */ |
653 | atmel_pdmic_get_sample_rate(dd, &rate_min, &rate_max); | 657 | atmel_pdmic_get_sample_rate(dd, &rate_min, &rate_max); |
654 | 658 | ||
655 | /* register cpu dai */ | 659 | /* register cpu dai */ |
diff --git a/sound/soc/codecs/88pm860x-codec.c b/sound/soc/codecs/88pm860x-codec.c index e8bed6b0c9db..b013a4c62b63 100644 --- a/sound/soc/codecs/88pm860x-codec.c +++ b/sound/soc/codecs/88pm860x-codec.c | |||
@@ -1361,12 +1361,14 @@ static struct snd_soc_codec_driver soc_codec_dev_pm860x = { | |||
1361 | .set_bias_level = pm860x_set_bias_level, | 1361 | .set_bias_level = pm860x_set_bias_level, |
1362 | .get_regmap = pm860x_get_regmap, | 1362 | .get_regmap = pm860x_get_regmap, |
1363 | 1363 | ||
1364 | .controls = pm860x_snd_controls, | 1364 | .component_driver = { |
1365 | .num_controls = ARRAY_SIZE(pm860x_snd_controls), | 1365 | .controls = pm860x_snd_controls, |
1366 | .dapm_widgets = pm860x_dapm_widgets, | 1366 | .num_controls = ARRAY_SIZE(pm860x_snd_controls), |
1367 | .num_dapm_widgets = ARRAY_SIZE(pm860x_dapm_widgets), | 1367 | .dapm_widgets = pm860x_dapm_widgets, |
1368 | .dapm_routes = pm860x_dapm_routes, | 1368 | .num_dapm_widgets = ARRAY_SIZE(pm860x_dapm_widgets), |
1369 | .num_dapm_routes = ARRAY_SIZE(pm860x_dapm_routes), | 1369 | .dapm_routes = pm860x_dapm_routes, |
1370 | .num_dapm_routes = ARRAY_SIZE(pm860x_dapm_routes), | ||
1371 | }, | ||
1370 | }; | 1372 | }; |
1371 | 1373 | ||
1372 | static int pm860x_codec_probe(struct platform_device *pdev) | 1374 | static int pm860x_codec_probe(struct platform_device *pdev) |
diff --git a/sound/soc/codecs/Kconfig b/sound/soc/codecs/Kconfig index 1cd6ab344d67..c67667bb970f 100644 --- a/sound/soc/codecs/Kconfig +++ b/sound/soc/codecs/Kconfig | |||
@@ -92,6 +92,7 @@ config SND_SOC_ALL_CODECS | |||
92 | select SND_SOC_MAX9877 if I2C | 92 | select SND_SOC_MAX9877 if I2C |
93 | select SND_SOC_MC13783 if MFD_MC13XXX | 93 | select SND_SOC_MC13783 if MFD_MC13XXX |
94 | select SND_SOC_ML26124 if I2C | 94 | select SND_SOC_ML26124 if I2C |
95 | select SND_SOC_NAU8810 if I2C | ||
95 | select SND_SOC_NAU8825 if I2C | 96 | select SND_SOC_NAU8825 if I2C |
96 | select SND_SOC_HDMI_CODEC | 97 | select SND_SOC_HDMI_CODEC |
97 | select SND_SOC_PCM1681 if I2C | 98 | select SND_SOC_PCM1681 if I2C |
@@ -112,6 +113,8 @@ config SND_SOC_ALL_CODECS | |||
112 | select SND_SOC_RT5645 if I2C | 113 | select SND_SOC_RT5645 if I2C |
113 | select SND_SOC_RT5651 if I2C | 114 | select SND_SOC_RT5651 if I2C |
114 | select SND_SOC_RT5659 if I2C | 115 | select SND_SOC_RT5659 if I2C |
116 | select SND_SOC_RT5660 if I2C | ||
117 | select SND_SOC_RT5663 if I2C | ||
115 | select SND_SOC_RT5670 if I2C | 118 | select SND_SOC_RT5670 if I2C |
116 | select SND_SOC_RT5677 if I2C && SPI_MASTER | 119 | select SND_SOC_RT5677 if I2C && SPI_MASTER |
117 | select SND_SOC_SGTL5000 if I2C | 120 | select SND_SOC_SGTL5000 if I2C |
@@ -645,6 +648,8 @@ config SND_SOC_RL6231 | |||
645 | default y if SND_SOC_RT5645=y | 648 | default y if SND_SOC_RT5645=y |
646 | default y if SND_SOC_RT5651=y | 649 | default y if SND_SOC_RT5651=y |
647 | default y if SND_SOC_RT5659=y | 650 | default y if SND_SOC_RT5659=y |
651 | default y if SND_SOC_RT5660=y | ||
652 | default y if SND_SOC_RT5663=y | ||
648 | default y if SND_SOC_RT5670=y | 653 | default y if SND_SOC_RT5670=y |
649 | default y if SND_SOC_RT5677=y | 654 | default y if SND_SOC_RT5677=y |
650 | default m if SND_SOC_RT5514=m | 655 | default m if SND_SOC_RT5514=m |
@@ -653,6 +658,8 @@ config SND_SOC_RL6231 | |||
653 | default m if SND_SOC_RT5645=m | 658 | default m if SND_SOC_RT5645=m |
654 | default m if SND_SOC_RT5651=m | 659 | default m if SND_SOC_RT5651=m |
655 | default m if SND_SOC_RT5659=m | 660 | default m if SND_SOC_RT5659=m |
661 | default m if SND_SOC_RT5660=m | ||
662 | default m if SND_SOC_RT5663=m | ||
656 | default m if SND_SOC_RT5670=m | 663 | default m if SND_SOC_RT5670=m |
657 | default m if SND_SOC_RT5677=m | 664 | default m if SND_SOC_RT5677=m |
658 | 665 | ||
@@ -665,6 +672,7 @@ config SND_SOC_RL6347A | |||
665 | 672 | ||
666 | config SND_SOC_RT286 | 673 | config SND_SOC_RT286 |
667 | tristate | 674 | tristate |
675 | select SND_SOC_RT5663 | ||
668 | depends on I2C | 676 | depends on I2C |
669 | 677 | ||
670 | config SND_SOC_RT298 | 678 | config SND_SOC_RT298 |
@@ -697,6 +705,12 @@ config SND_SOC_RT5651 | |||
697 | config SND_SOC_RT5659 | 705 | config SND_SOC_RT5659 |
698 | tristate | 706 | tristate |
699 | 707 | ||
708 | config SND_SOC_RT5660 | ||
709 | tristate | ||
710 | |||
711 | config SND_SOC_RT5663 | ||
712 | tristate | ||
713 | |||
700 | config SND_SOC_RT5670 | 714 | config SND_SOC_RT5670 |
701 | tristate | 715 | tristate |
702 | 716 | ||
@@ -1064,6 +1078,10 @@ config SND_SOC_MC13783 | |||
1064 | config SND_SOC_ML26124 | 1078 | config SND_SOC_ML26124 |
1065 | tristate | 1079 | tristate |
1066 | 1080 | ||
1081 | config SND_SOC_NAU8810 | ||
1082 | tristate "Nuvoton Technology Corporation NAU88C10 CODEC" | ||
1083 | depends on I2C | ||
1084 | |||
1067 | config SND_SOC_NAU8825 | 1085 | config SND_SOC_NAU8825 |
1068 | tristate | 1086 | tristate |
1069 | 1087 | ||
diff --git a/sound/soc/codecs/Makefile b/sound/soc/codecs/Makefile index 58036af2c7d9..958cd4912fbc 100644 --- a/sound/soc/codecs/Makefile +++ b/sound/soc/codecs/Makefile | |||
@@ -86,6 +86,7 @@ snd-soc-max9850-objs := max9850.o | |||
86 | snd-soc-max9860-objs := max9860.o | 86 | snd-soc-max9860-objs := max9860.o |
87 | snd-soc-mc13783-objs := mc13783.o | 87 | snd-soc-mc13783-objs := mc13783.o |
88 | snd-soc-ml26124-objs := ml26124.o | 88 | snd-soc-ml26124-objs := ml26124.o |
89 | snd-soc-nau8810-objs := nau8810.o | ||
89 | snd-soc-nau8825-objs := nau8825.o | 90 | snd-soc-nau8825-objs := nau8825.o |
90 | snd-soc-hdmi-codec-objs := hdmi-codec.o | 91 | snd-soc-hdmi-codec-objs := hdmi-codec.o |
91 | snd-soc-pcm1681-objs := pcm1681.o | 92 | snd-soc-pcm1681-objs := pcm1681.o |
@@ -112,6 +113,8 @@ snd-soc-rt5640-objs := rt5640.o | |||
112 | snd-soc-rt5645-objs := rt5645.o | 113 | snd-soc-rt5645-objs := rt5645.o |
113 | snd-soc-rt5651-objs := rt5651.o | 114 | snd-soc-rt5651-objs := rt5651.o |
114 | snd-soc-rt5659-objs := rt5659.o | 115 | snd-soc-rt5659-objs := rt5659.o |
116 | snd-soc-rt5660-objs := rt5660.o | ||
117 | snd-soc-rt5663-objs := rt5663.o | ||
115 | snd-soc-rt5670-objs := rt5670.o | 118 | snd-soc-rt5670-objs := rt5670.o |
116 | snd-soc-rt5677-objs := rt5677.o | 119 | snd-soc-rt5677-objs := rt5677.o |
117 | snd-soc-rt5677-spi-objs := rt5677-spi.o | 120 | snd-soc-rt5677-spi-objs := rt5677-spi.o |
@@ -307,6 +310,7 @@ obj-$(CONFIG_SND_SOC_MAX9850) += snd-soc-max9850.o | |||
307 | obj-$(CONFIG_SND_SOC_MAX9860) += snd-soc-max9860.o | 310 | obj-$(CONFIG_SND_SOC_MAX9860) += snd-soc-max9860.o |
308 | obj-$(CONFIG_SND_SOC_MC13783) += snd-soc-mc13783.o | 311 | obj-$(CONFIG_SND_SOC_MC13783) += snd-soc-mc13783.o |
309 | obj-$(CONFIG_SND_SOC_ML26124) += snd-soc-ml26124.o | 312 | obj-$(CONFIG_SND_SOC_ML26124) += snd-soc-ml26124.o |
313 | obj-$(CONFIG_SND_SOC_NAU8810) += snd-soc-nau8810.o | ||
310 | obj-$(CONFIG_SND_SOC_NAU8825) += snd-soc-nau8825.o | 314 | obj-$(CONFIG_SND_SOC_NAU8825) += snd-soc-nau8825.o |
311 | obj-$(CONFIG_SND_SOC_HDMI_CODEC) += snd-soc-hdmi-codec.o | 315 | obj-$(CONFIG_SND_SOC_HDMI_CODEC) += snd-soc-hdmi-codec.o |
312 | obj-$(CONFIG_SND_SOC_PCM1681) += snd-soc-pcm1681.o | 316 | obj-$(CONFIG_SND_SOC_PCM1681) += snd-soc-pcm1681.o |
@@ -333,6 +337,8 @@ obj-$(CONFIG_SND_SOC_RT5640) += snd-soc-rt5640.o | |||
333 | obj-$(CONFIG_SND_SOC_RT5645) += snd-soc-rt5645.o | 337 | obj-$(CONFIG_SND_SOC_RT5645) += snd-soc-rt5645.o |
334 | obj-$(CONFIG_SND_SOC_RT5651) += snd-soc-rt5651.o | 338 | obj-$(CONFIG_SND_SOC_RT5651) += snd-soc-rt5651.o |
335 | obj-$(CONFIG_SND_SOC_RT5659) += snd-soc-rt5659.o | 339 | obj-$(CONFIG_SND_SOC_RT5659) += snd-soc-rt5659.o |
340 | obj-$(CONFIG_SND_SOC_RT5660) += snd-soc-rt5660.o | ||
341 | obj-$(CONFIG_SND_SOC_RT5663) += snd-soc-rt5663.o | ||
336 | obj-$(CONFIG_SND_SOC_RT5670) += snd-soc-rt5670.o | 342 | obj-$(CONFIG_SND_SOC_RT5670) += snd-soc-rt5670.o |
337 | obj-$(CONFIG_SND_SOC_RT5677) += snd-soc-rt5677.o | 343 | obj-$(CONFIG_SND_SOC_RT5677) += snd-soc-rt5677.o |
338 | obj-$(CONFIG_SND_SOC_RT5677_SPI) += snd-soc-rt5677-spi.o | 344 | obj-$(CONFIG_SND_SOC_RT5677_SPI) += snd-soc-rt5677-spi.o |
diff --git a/sound/soc/codecs/ab8500-codec.c b/sound/soc/codecs/ab8500-codec.c index 2fc89155f14a..935ff7cb71c5 100644 --- a/sound/soc/codecs/ab8500-codec.c +++ b/sound/soc/codecs/ab8500-codec.c | |||
@@ -2408,28 +2408,28 @@ static void ab8500_codec_of_probe(struct device *dev, struct device_node *np, | |||
2408 | { | 2408 | { |
2409 | u32 value; | 2409 | u32 value; |
2410 | 2410 | ||
2411 | if (of_get_property(np, "stericsson,amic1-type-single-ended", NULL)) | 2411 | if (of_property_read_bool(np, "stericsson,amic1-type-single-ended")) |
2412 | codec->amics.mic1_type = AMIC_TYPE_SINGLE_ENDED; | 2412 | codec->amics.mic1_type = AMIC_TYPE_SINGLE_ENDED; |
2413 | else | 2413 | else |
2414 | codec->amics.mic1_type = AMIC_TYPE_DIFFERENTIAL; | 2414 | codec->amics.mic1_type = AMIC_TYPE_DIFFERENTIAL; |
2415 | 2415 | ||
2416 | if (of_get_property(np, "stericsson,amic2-type-single-ended", NULL)) | 2416 | if (of_property_read_bool(np, "stericsson,amic2-type-single-ended")) |
2417 | codec->amics.mic2_type = AMIC_TYPE_SINGLE_ENDED; | 2417 | codec->amics.mic2_type = AMIC_TYPE_SINGLE_ENDED; |
2418 | else | 2418 | else |
2419 | codec->amics.mic2_type = AMIC_TYPE_DIFFERENTIAL; | 2419 | codec->amics.mic2_type = AMIC_TYPE_DIFFERENTIAL; |
2420 | 2420 | ||
2421 | /* Has a non-standard Vamic been requested? */ | 2421 | /* Has a non-standard Vamic been requested? */ |
2422 | if (of_get_property(np, "stericsson,amic1a-bias-vamic2", NULL)) | 2422 | if (of_property_read_bool(np, "stericsson,amic1a-bias-vamic2")) |
2423 | codec->amics.mic1a_micbias = AMIC_MICBIAS_VAMIC2; | 2423 | codec->amics.mic1a_micbias = AMIC_MICBIAS_VAMIC2; |
2424 | else | 2424 | else |
2425 | codec->amics.mic1a_micbias = AMIC_MICBIAS_VAMIC1; | 2425 | codec->amics.mic1a_micbias = AMIC_MICBIAS_VAMIC1; |
2426 | 2426 | ||
2427 | if (of_get_property(np, "stericsson,amic1b-bias-vamic2", NULL)) | 2427 | if (of_property_read_bool(np, "stericsson,amic1b-bias-vamic2")) |
2428 | codec->amics.mic1b_micbias = AMIC_MICBIAS_VAMIC2; | 2428 | codec->amics.mic1b_micbias = AMIC_MICBIAS_VAMIC2; |
2429 | else | 2429 | else |
2430 | codec->amics.mic1b_micbias = AMIC_MICBIAS_VAMIC1; | 2430 | codec->amics.mic1b_micbias = AMIC_MICBIAS_VAMIC1; |
2431 | 2431 | ||
2432 | if (of_get_property(np, "stericsson,amic2-bias-vamic1", NULL)) | 2432 | if (of_property_read_bool(np, "stericsson,amic2-bias-vamic1")) |
2433 | codec->amics.mic2_micbias = AMIC_MICBIAS_VAMIC1; | 2433 | codec->amics.mic2_micbias = AMIC_MICBIAS_VAMIC1; |
2434 | else | 2434 | else |
2435 | codec->amics.mic2_micbias = AMIC_MICBIAS_VAMIC2; | 2435 | codec->amics.mic2_micbias = AMIC_MICBIAS_VAMIC2; |
@@ -2525,12 +2525,14 @@ static int ab8500_codec_probe(struct snd_soc_codec *codec) | |||
2525 | 2525 | ||
2526 | static struct snd_soc_codec_driver ab8500_codec_driver = { | 2526 | static struct snd_soc_codec_driver ab8500_codec_driver = { |
2527 | .probe = ab8500_codec_probe, | 2527 | .probe = ab8500_codec_probe, |
2528 | .controls = ab8500_ctrls, | 2528 | .component_driver = { |
2529 | .num_controls = ARRAY_SIZE(ab8500_ctrls), | 2529 | .controls = ab8500_ctrls, |
2530 | .dapm_widgets = ab8500_dapm_widgets, | 2530 | .num_controls = ARRAY_SIZE(ab8500_ctrls), |
2531 | .num_dapm_widgets = ARRAY_SIZE(ab8500_dapm_widgets), | 2531 | .dapm_widgets = ab8500_dapm_widgets, |
2532 | .dapm_routes = ab8500_dapm_routes, | 2532 | .num_dapm_widgets = ARRAY_SIZE(ab8500_dapm_widgets), |
2533 | .num_dapm_routes = ARRAY_SIZE(ab8500_dapm_routes), | 2533 | .dapm_routes = ab8500_dapm_routes, |
2534 | .num_dapm_routes = ARRAY_SIZE(ab8500_dapm_routes), | ||
2535 | }, | ||
2534 | }; | 2536 | }; |
2535 | 2537 | ||
2536 | static int ab8500_codec_driver_probe(struct platform_device *pdev) | 2538 | static int ab8500_codec_driver_probe(struct platform_device *pdev) |
diff --git a/sound/soc/codecs/ac97.c b/sound/soc/codecs/ac97.c index 5b3224c63943..f7f04c6be01e 100644 --- a/sound/soc/codecs/ac97.c +++ b/sound/soc/codecs/ac97.c | |||
@@ -117,10 +117,12 @@ static struct snd_soc_codec_driver soc_codec_dev_ac97 = { | |||
117 | .suspend = ac97_soc_suspend, | 117 | .suspend = ac97_soc_suspend, |
118 | .resume = ac97_soc_resume, | 118 | .resume = ac97_soc_resume, |
119 | 119 | ||
120 | .dapm_widgets = ac97_widgets, | 120 | .component_driver = { |
121 | .num_dapm_widgets = ARRAY_SIZE(ac97_widgets), | 121 | .dapm_widgets = ac97_widgets, |
122 | .dapm_routes = ac97_routes, | 122 | .num_dapm_widgets = ARRAY_SIZE(ac97_widgets), |
123 | .num_dapm_routes = ARRAY_SIZE(ac97_routes), | 123 | .dapm_routes = ac97_routes, |
124 | .num_dapm_routes = ARRAY_SIZE(ac97_routes), | ||
125 | }, | ||
124 | }; | 126 | }; |
125 | 127 | ||
126 | static int ac97_probe(struct platform_device *pdev) | 128 | static int ac97_probe(struct platform_device *pdev) |
diff --git a/sound/soc/codecs/ad1836.c b/sound/soc/codecs/ad1836.c index e2ce6c4d7ece..a478239aadac 100644 --- a/sound/soc/codecs/ad1836.c +++ b/sound/soc/codecs/ad1836.c | |||
@@ -327,12 +327,14 @@ static struct snd_soc_codec_driver soc_codec_dev_ad1836 = { | |||
327 | .suspend = ad1836_suspend, | 327 | .suspend = ad1836_suspend, |
328 | .resume = ad1836_resume, | 328 | .resume = ad1836_resume, |
329 | 329 | ||
330 | .controls = ad183x_controls, | 330 | .component_driver = { |
331 | .num_controls = ARRAY_SIZE(ad183x_controls), | 331 | .controls = ad183x_controls, |
332 | .dapm_widgets = ad183x_dapm_widgets, | 332 | .num_controls = ARRAY_SIZE(ad183x_controls), |
333 | .num_dapm_widgets = ARRAY_SIZE(ad183x_dapm_widgets), | 333 | .dapm_widgets = ad183x_dapm_widgets, |
334 | .dapm_routes = ad183x_dapm_routes, | 334 | .num_dapm_widgets = ARRAY_SIZE(ad183x_dapm_widgets), |
335 | .num_dapm_routes = ARRAY_SIZE(ad183x_dapm_routes), | 335 | .dapm_routes = ad183x_dapm_routes, |
336 | .num_dapm_routes = ARRAY_SIZE(ad183x_dapm_routes), | ||
337 | }, | ||
336 | }; | 338 | }; |
337 | 339 | ||
338 | static const struct reg_default ad1836_reg_defaults[] = { | 340 | static const struct reg_default ad1836_reg_defaults[] = { |
diff --git a/sound/soc/codecs/ad193x.c b/sound/soc/codecs/ad193x.c index 3a3f3f2343d7..d643557d89a7 100644 --- a/sound/soc/codecs/ad193x.c +++ b/sound/soc/codecs/ad193x.c | |||
@@ -410,12 +410,14 @@ static int ad193x_codec_probe(struct snd_soc_codec *codec) | |||
410 | 410 | ||
411 | static struct snd_soc_codec_driver soc_codec_dev_ad193x = { | 411 | static struct snd_soc_codec_driver soc_codec_dev_ad193x = { |
412 | .probe = ad193x_codec_probe, | 412 | .probe = ad193x_codec_probe, |
413 | .controls = ad193x_snd_controls, | 413 | .component_driver = { |
414 | .num_controls = ARRAY_SIZE(ad193x_snd_controls), | 414 | .controls = ad193x_snd_controls, |
415 | .dapm_widgets = ad193x_dapm_widgets, | 415 | .num_controls = ARRAY_SIZE(ad193x_snd_controls), |
416 | .num_dapm_widgets = ARRAY_SIZE(ad193x_dapm_widgets), | 416 | .dapm_widgets = ad193x_dapm_widgets, |
417 | .dapm_routes = audio_paths, | 417 | .num_dapm_widgets = ARRAY_SIZE(ad193x_dapm_widgets), |
418 | .num_dapm_routes = ARRAY_SIZE(audio_paths), | 418 | .dapm_routes = audio_paths, |
419 | .num_dapm_routes = ARRAY_SIZE(audio_paths), | ||
420 | }, | ||
419 | }; | 421 | }; |
420 | 422 | ||
421 | const struct regmap_config ad193x_regmap_config = { | 423 | const struct regmap_config ad193x_regmap_config = { |
diff --git a/sound/soc/codecs/ad1980.c b/sound/soc/codecs/ad1980.c index 9ef20dbccbe3..b7c1b9f4bf5f 100644 --- a/sound/soc/codecs/ad1980.c +++ b/sound/soc/codecs/ad1980.c | |||
@@ -299,12 +299,14 @@ static struct snd_soc_codec_driver soc_codec_dev_ad1980 = { | |||
299 | .probe = ad1980_soc_probe, | 299 | .probe = ad1980_soc_probe, |
300 | .remove = ad1980_soc_remove, | 300 | .remove = ad1980_soc_remove, |
301 | 301 | ||
302 | .controls = ad1980_snd_ac97_controls, | 302 | .component_driver = { |
303 | .num_controls = ARRAY_SIZE(ad1980_snd_ac97_controls), | 303 | .controls = ad1980_snd_ac97_controls, |
304 | .dapm_widgets = ad1980_dapm_widgets, | 304 | .num_controls = ARRAY_SIZE(ad1980_snd_ac97_controls), |
305 | .num_dapm_widgets = ARRAY_SIZE(ad1980_dapm_widgets), | 305 | .dapm_widgets = ad1980_dapm_widgets, |
306 | .dapm_routes = ad1980_dapm_routes, | 306 | .num_dapm_widgets = ARRAY_SIZE(ad1980_dapm_widgets), |
307 | .num_dapm_routes = ARRAY_SIZE(ad1980_dapm_routes), | 307 | .dapm_routes = ad1980_dapm_routes, |
308 | .num_dapm_routes = ARRAY_SIZE(ad1980_dapm_routes), | ||
309 | }, | ||
308 | }; | 310 | }; |
309 | 311 | ||
310 | static int ad1980_probe(struct platform_device *pdev) | 312 | static int ad1980_probe(struct platform_device *pdev) |
diff --git a/sound/soc/codecs/ad73311.c b/sound/soc/codecs/ad73311.c index a9400aef60b5..3e358a49442d 100644 --- a/sound/soc/codecs/ad73311.c +++ b/sound/soc/codecs/ad73311.c | |||
@@ -55,10 +55,12 @@ static struct snd_soc_dai_driver ad73311_dai = { | |||
55 | }; | 55 | }; |
56 | 56 | ||
57 | static struct snd_soc_codec_driver soc_codec_dev_ad73311 = { | 57 | static struct snd_soc_codec_driver soc_codec_dev_ad73311 = { |
58 | .dapm_widgets = ad73311_dapm_widgets, | 58 | .component_driver = { |
59 | .num_dapm_widgets = ARRAY_SIZE(ad73311_dapm_widgets), | 59 | .dapm_widgets = ad73311_dapm_widgets, |
60 | .dapm_routes = ad73311_dapm_routes, | 60 | .num_dapm_widgets = ARRAY_SIZE(ad73311_dapm_widgets), |
61 | .num_dapm_routes = ARRAY_SIZE(ad73311_dapm_routes), | 61 | .dapm_routes = ad73311_dapm_routes, |
62 | .num_dapm_routes = ARRAY_SIZE(ad73311_dapm_routes), | ||
63 | }, | ||
62 | }; | 64 | }; |
63 | 65 | ||
64 | static int ad73311_probe(struct platform_device *pdev) | 66 | static int ad73311_probe(struct platform_device *pdev) |
diff --git a/sound/soc/codecs/adau1373.c b/sound/soc/codecs/adau1373.c index 1556b360fa15..8fa9045571ff 100644 --- a/sound/soc/codecs/adau1373.c +++ b/sound/soc/codecs/adau1373.c | |||
@@ -1466,12 +1466,14 @@ static struct snd_soc_codec_driver adau1373_codec_driver = { | |||
1466 | 1466 | ||
1467 | .set_pll = adau1373_set_pll, | 1467 | .set_pll = adau1373_set_pll, |
1468 | 1468 | ||
1469 | .controls = adau1373_controls, | 1469 | .component_driver = { |
1470 | .num_controls = ARRAY_SIZE(adau1373_controls), | 1470 | .controls = adau1373_controls, |
1471 | .dapm_widgets = adau1373_dapm_widgets, | 1471 | .num_controls = ARRAY_SIZE(adau1373_controls), |
1472 | .num_dapm_widgets = ARRAY_SIZE(adau1373_dapm_widgets), | 1472 | .dapm_widgets = adau1373_dapm_widgets, |
1473 | .dapm_routes = adau1373_dapm_routes, | 1473 | .num_dapm_widgets = ARRAY_SIZE(adau1373_dapm_widgets), |
1474 | .num_dapm_routes = ARRAY_SIZE(adau1373_dapm_routes), | 1474 | .dapm_routes = adau1373_dapm_routes, |
1475 | .num_dapm_routes = ARRAY_SIZE(adau1373_dapm_routes), | ||
1476 | }, | ||
1475 | }; | 1477 | }; |
1476 | 1478 | ||
1477 | static int adau1373_i2c_probe(struct i2c_client *client, | 1479 | static int adau1373_i2c_probe(struct i2c_client *client, |
diff --git a/sound/soc/codecs/adau1701.c b/sound/soc/codecs/adau1701.c index de53c0d7bf10..3bad1bc8c00a 100644 --- a/sound/soc/codecs/adau1701.c +++ b/sound/soc/codecs/adau1701.c | |||
@@ -765,13 +765,14 @@ static struct snd_soc_codec_driver adau1701_codec_drv = { | |||
765 | .set_bias_level = adau1701_set_bias_level, | 765 | .set_bias_level = adau1701_set_bias_level, |
766 | .idle_bias_off = true, | 766 | .idle_bias_off = true, |
767 | 767 | ||
768 | .controls = adau1701_controls, | 768 | .component_driver = { |
769 | .num_controls = ARRAY_SIZE(adau1701_controls), | 769 | .controls = adau1701_controls, |
770 | .dapm_widgets = adau1701_dapm_widgets, | 770 | .num_controls = ARRAY_SIZE(adau1701_controls), |
771 | .num_dapm_widgets = ARRAY_SIZE(adau1701_dapm_widgets), | 771 | .dapm_widgets = adau1701_dapm_widgets, |
772 | .dapm_routes = adau1701_dapm_routes, | 772 | .num_dapm_widgets = ARRAY_SIZE(adau1701_dapm_widgets), |
773 | .num_dapm_routes = ARRAY_SIZE(adau1701_dapm_routes), | 773 | .dapm_routes = adau1701_dapm_routes, |
774 | 774 | .num_dapm_routes = ARRAY_SIZE(adau1701_dapm_routes), | |
775 | }, | ||
775 | .set_sysclk = adau1701_set_sysclk, | 776 | .set_sysclk = adau1701_set_sysclk, |
776 | }; | 777 | }; |
777 | 778 | ||
diff --git a/sound/soc/codecs/adau1761.c b/sound/soc/codecs/adau1761.c index b95d29dbd13d..3bc3cc559dde 100644 --- a/sound/soc/codecs/adau1761.c +++ b/sound/soc/codecs/adau1761.c | |||
@@ -719,12 +719,14 @@ static const struct snd_soc_codec_driver adau1761_codec_driver = { | |||
719 | .set_bias_level = adau1761_set_bias_level, | 719 | .set_bias_level = adau1761_set_bias_level, |
720 | .suspend_bias_off = true, | 720 | .suspend_bias_off = true, |
721 | 721 | ||
722 | .controls = adau1761_controls, | 722 | .component_driver = { |
723 | .num_controls = ARRAY_SIZE(adau1761_controls), | 723 | .controls = adau1761_controls, |
724 | .dapm_widgets = adau1x61_dapm_widgets, | 724 | .num_controls = ARRAY_SIZE(adau1761_controls), |
725 | .num_dapm_widgets = ARRAY_SIZE(adau1x61_dapm_widgets), | 725 | .dapm_widgets = adau1x61_dapm_widgets, |
726 | .dapm_routes = adau1x61_dapm_routes, | 726 | .num_dapm_widgets = ARRAY_SIZE(adau1x61_dapm_widgets), |
727 | .num_dapm_routes = ARRAY_SIZE(adau1x61_dapm_routes), | 727 | .dapm_routes = adau1x61_dapm_routes, |
728 | .num_dapm_routes = ARRAY_SIZE(adau1x61_dapm_routes), | ||
729 | }, | ||
728 | }; | 730 | }; |
729 | 731 | ||
730 | #define ADAU1761_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE | \ | 732 | #define ADAU1761_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE | \ |
diff --git a/sound/soc/codecs/adau1781.c b/sound/soc/codecs/adau1781.c index bc1bb56dae63..546071c6c0d0 100644 --- a/sound/soc/codecs/adau1781.c +++ b/sound/soc/codecs/adau1781.c | |||
@@ -432,12 +432,14 @@ static const struct snd_soc_codec_driver adau1781_codec_driver = { | |||
432 | .set_bias_level = adau1781_set_bias_level, | 432 | .set_bias_level = adau1781_set_bias_level, |
433 | .suspend_bias_off = true, | 433 | .suspend_bias_off = true, |
434 | 434 | ||
435 | .controls = adau1781_controls, | 435 | .component_driver = { |
436 | .num_controls = ARRAY_SIZE(adau1781_controls), | 436 | .controls = adau1781_controls, |
437 | .dapm_widgets = adau1781_dapm_widgets, | 437 | .num_controls = ARRAY_SIZE(adau1781_controls), |
438 | .num_dapm_widgets = ARRAY_SIZE(adau1781_dapm_widgets), | 438 | .dapm_widgets = adau1781_dapm_widgets, |
439 | .dapm_routes = adau1781_dapm_routes, | 439 | .num_dapm_widgets = ARRAY_SIZE(adau1781_dapm_widgets), |
440 | .num_dapm_routes = ARRAY_SIZE(adau1781_dapm_routes), | 440 | .dapm_routes = adau1781_dapm_routes, |
441 | .num_dapm_routes = ARRAY_SIZE(adau1781_dapm_routes), | ||
442 | }, | ||
441 | }; | 443 | }; |
442 | 444 | ||
443 | #define ADAU1781_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE | \ | 445 | #define ADAU1781_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE | \ |
diff --git a/sound/soc/codecs/adau1977.c b/sound/soc/codecs/adau1977.c index 9bdd15f408c1..b319db6a69f8 100644 --- a/sound/soc/codecs/adau1977.c +++ b/sound/soc/codecs/adau1977.c | |||
@@ -873,12 +873,14 @@ static struct snd_soc_codec_driver adau1977_codec_driver = { | |||
873 | .set_sysclk = adau1977_set_sysclk, | 873 | .set_sysclk = adau1977_set_sysclk, |
874 | .idle_bias_off = true, | 874 | .idle_bias_off = true, |
875 | 875 | ||
876 | .controls = adau1977_snd_controls, | 876 | .component_driver = { |
877 | .num_controls = ARRAY_SIZE(adau1977_snd_controls), | 877 | .controls = adau1977_snd_controls, |
878 | .dapm_widgets = adau1977_dapm_widgets, | 878 | .num_controls = ARRAY_SIZE(adau1977_snd_controls), |
879 | .num_dapm_widgets = ARRAY_SIZE(adau1977_dapm_widgets), | 879 | .dapm_widgets = adau1977_dapm_widgets, |
880 | .dapm_routes = adau1977_dapm_routes, | 880 | .num_dapm_widgets = ARRAY_SIZE(adau1977_dapm_widgets), |
881 | .num_dapm_routes = ARRAY_SIZE(adau1977_dapm_routes), | 881 | .dapm_routes = adau1977_dapm_routes, |
882 | .num_dapm_routes = ARRAY_SIZE(adau1977_dapm_routes), | ||
883 | }, | ||
882 | }; | 884 | }; |
883 | 885 | ||
884 | static int adau1977_setup_micbias(struct adau1977 *adau1977) | 886 | static int adau1977_setup_micbias(struct adau1977 *adau1977) |
diff --git a/sound/soc/codecs/adau7002.c b/sound/soc/codecs/adau7002.c index 9df72c6adcca..6384c5491de8 100644 --- a/sound/soc/codecs/adau7002.c +++ b/sound/soc/codecs/adau7002.c | |||
@@ -39,10 +39,12 @@ static struct snd_soc_dai_driver adau7002_dai = { | |||
39 | }; | 39 | }; |
40 | 40 | ||
41 | static const struct snd_soc_codec_driver adau7002_codec_driver = { | 41 | static const struct snd_soc_codec_driver adau7002_codec_driver = { |
42 | .dapm_widgets = adau7002_widgets, | 42 | .component_driver = { |
43 | .num_dapm_widgets = ARRAY_SIZE(adau7002_widgets), | 43 | .dapm_widgets = adau7002_widgets, |
44 | .dapm_routes = adau7002_routes, | 44 | .num_dapm_widgets = ARRAY_SIZE(adau7002_widgets), |
45 | .num_dapm_routes = ARRAY_SIZE(adau7002_routes), | 45 | .dapm_routes = adau7002_routes, |
46 | .num_dapm_routes = ARRAY_SIZE(adau7002_routes), | ||
47 | }, | ||
46 | }; | 48 | }; |
47 | 49 | ||
48 | static int adau7002_probe(struct platform_device *pdev) | 50 | static int adau7002_probe(struct platform_device *pdev) |
diff --git a/sound/soc/codecs/adav80x.c b/sound/soc/codecs/adav80x.c index acff8d62059c..6e793ebb5883 100644 --- a/sound/soc/codecs/adav80x.c +++ b/sound/soc/codecs/adav80x.c | |||
@@ -834,12 +834,14 @@ static struct snd_soc_codec_driver adav80x_codec_driver = { | |||
834 | .set_pll = adav80x_set_pll, | 834 | .set_pll = adav80x_set_pll, |
835 | .set_sysclk = adav80x_set_sysclk, | 835 | .set_sysclk = adav80x_set_sysclk, |
836 | 836 | ||
837 | .controls = adav80x_controls, | 837 | .component_driver = { |
838 | .num_controls = ARRAY_SIZE(adav80x_controls), | 838 | .controls = adav80x_controls, |
839 | .dapm_widgets = adav80x_dapm_widgets, | 839 | .num_controls = ARRAY_SIZE(adav80x_controls), |
840 | .num_dapm_widgets = ARRAY_SIZE(adav80x_dapm_widgets), | 840 | .dapm_widgets = adav80x_dapm_widgets, |
841 | .dapm_routes = adav80x_dapm_routes, | 841 | .num_dapm_widgets = ARRAY_SIZE(adav80x_dapm_widgets), |
842 | .num_dapm_routes = ARRAY_SIZE(adav80x_dapm_routes), | 842 | .dapm_routes = adav80x_dapm_routes, |
843 | .num_dapm_routes = ARRAY_SIZE(adav80x_dapm_routes), | ||
844 | }, | ||
843 | }; | 845 | }; |
844 | 846 | ||
845 | int adav80x_bus_probe(struct device *dev, struct regmap *regmap) | 847 | int adav80x_bus_probe(struct device *dev, struct regmap *regmap) |
diff --git a/sound/soc/codecs/ads117x.c b/sound/soc/codecs/ads117x.c index c5be1bdc2c9a..90c756d183b4 100644 --- a/sound/soc/codecs/ads117x.c +++ b/sound/soc/codecs/ads117x.c | |||
@@ -59,10 +59,12 @@ static struct snd_soc_dai_driver ads117x_dai = { | |||
59 | }; | 59 | }; |
60 | 60 | ||
61 | static struct snd_soc_codec_driver soc_codec_dev_ads117x = { | 61 | static struct snd_soc_codec_driver soc_codec_dev_ads117x = { |
62 | .dapm_widgets = ads117x_dapm_widgets, | 62 | .component_driver = { |
63 | .num_dapm_widgets = ARRAY_SIZE(ads117x_dapm_widgets), | 63 | .dapm_widgets = ads117x_dapm_widgets, |
64 | .dapm_routes = ads117x_dapm_routes, | 64 | .num_dapm_widgets = ARRAY_SIZE(ads117x_dapm_widgets), |
65 | .num_dapm_routes = ARRAY_SIZE(ads117x_dapm_routes), | 65 | .dapm_routes = ads117x_dapm_routes, |
66 | .num_dapm_routes = ARRAY_SIZE(ads117x_dapm_routes), | ||
67 | }, | ||
66 | }; | 68 | }; |
67 | 69 | ||
68 | static int ads117x_probe(struct platform_device *pdev) | 70 | static int ads117x_probe(struct platform_device *pdev) |
diff --git a/sound/soc/codecs/ak4104.c b/sound/soc/codecs/ak4104.c index 595d02d7602c..1a9d233c94d0 100644 --- a/sound/soc/codecs/ak4104.c +++ b/sound/soc/codecs/ak4104.c | |||
@@ -163,7 +163,10 @@ static struct snd_soc_dai_driver ak4104_dai = { | |||
163 | .stream_name = "Playback", | 163 | .stream_name = "Playback", |
164 | .channels_min = 2, | 164 | .channels_min = 2, |
165 | .channels_max = 2, | 165 | .channels_max = 2, |
166 | .rates = SNDRV_PCM_RATE_8000_192000, | 166 | .rates = SNDRV_PCM_RATE_22050 | SNDRV_PCM_RATE_32000 | |
167 | SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000 | | ||
168 | SNDRV_PCM_RATE_88200 | SNDRV_PCM_RATE_96000 | | ||
169 | SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_192000, | ||
167 | .formats = SNDRV_PCM_FMTBIT_S16_LE | | 170 | .formats = SNDRV_PCM_FMTBIT_S16_LE | |
168 | SNDRV_PCM_FMTBIT_S24_3LE | | 171 | SNDRV_PCM_FMTBIT_S24_3LE | |
169 | SNDRV_PCM_FMTBIT_S24_LE | 172 | SNDRV_PCM_FMTBIT_S24_LE |
@@ -245,10 +248,12 @@ static struct snd_soc_codec_driver soc_codec_device_ak4104 = { | |||
245 | .suspend = ak4104_soc_suspend, | 248 | .suspend = ak4104_soc_suspend, |
246 | .resume = ak4104_soc_resume, | 249 | .resume = ak4104_soc_resume, |
247 | 250 | ||
248 | .dapm_widgets = ak4104_dapm_widgets, | 251 | .component_driver = { |
249 | .num_dapm_widgets = ARRAY_SIZE(ak4104_dapm_widgets), | 252 | .dapm_widgets = ak4104_dapm_widgets, |
250 | .dapm_routes = ak4104_dapm_routes, | 253 | .num_dapm_widgets = ARRAY_SIZE(ak4104_dapm_widgets), |
251 | .num_dapm_routes = ARRAY_SIZE(ak4104_dapm_routes), | 254 | .dapm_routes = ak4104_dapm_routes, |
255 | .num_dapm_routes = ARRAY_SIZE(ak4104_dapm_routes), | ||
256 | } | ||
252 | }; | 257 | }; |
253 | 258 | ||
254 | static const struct regmap_config ak4104_regmap = { | 259 | static const struct regmap_config ak4104_regmap = { |
diff --git a/sound/soc/codecs/ak4535.c b/sound/soc/codecs/ak4535.c index 54428c64387b..66cfffde9a12 100644 --- a/sound/soc/codecs/ak4535.c +++ b/sound/soc/codecs/ak4535.c | |||
@@ -395,12 +395,14 @@ static struct snd_soc_codec_driver soc_codec_dev_ak4535 = { | |||
395 | .set_bias_level = ak4535_set_bias_level, | 395 | .set_bias_level = ak4535_set_bias_level, |
396 | .suspend_bias_off = true, | 396 | .suspend_bias_off = true, |
397 | 397 | ||
398 | .controls = ak4535_snd_controls, | 398 | .component_driver = { |
399 | .num_controls = ARRAY_SIZE(ak4535_snd_controls), | 399 | .controls = ak4535_snd_controls, |
400 | .dapm_widgets = ak4535_dapm_widgets, | 400 | .num_controls = ARRAY_SIZE(ak4535_snd_controls), |
401 | .num_dapm_widgets = ARRAY_SIZE(ak4535_dapm_widgets), | 401 | .dapm_widgets = ak4535_dapm_widgets, |
402 | .dapm_routes = ak4535_audio_map, | 402 | .num_dapm_widgets = ARRAY_SIZE(ak4535_dapm_widgets), |
403 | .num_dapm_routes = ARRAY_SIZE(ak4535_audio_map), | 403 | .dapm_routes = ak4535_audio_map, |
404 | .num_dapm_routes = ARRAY_SIZE(ak4535_audio_map), | ||
405 | }, | ||
404 | }; | 406 | }; |
405 | 407 | ||
406 | static int ak4535_i2c_probe(struct i2c_client *i2c, | 408 | static int ak4535_i2c_probe(struct i2c_client *i2c, |
diff --git a/sound/soc/codecs/ak4554.c b/sound/soc/codecs/ak4554.c index 298dedc05140..b92c548b9d29 100644 --- a/sound/soc/codecs/ak4554.c +++ b/sound/soc/codecs/ak4554.c | |||
@@ -65,10 +65,12 @@ static struct snd_soc_dai_driver ak4554_dai = { | |||
65 | }; | 65 | }; |
66 | 66 | ||
67 | static struct snd_soc_codec_driver soc_codec_dev_ak4554 = { | 67 | static struct snd_soc_codec_driver soc_codec_dev_ak4554 = { |
68 | .dapm_widgets = ak4554_dapm_widgets, | 68 | .component_driver = { |
69 | .num_dapm_widgets = ARRAY_SIZE(ak4554_dapm_widgets), | 69 | .dapm_widgets = ak4554_dapm_widgets, |
70 | .dapm_routes = ak4554_dapm_routes, | 70 | .num_dapm_widgets = ARRAY_SIZE(ak4554_dapm_widgets), |
71 | .num_dapm_routes = ARRAY_SIZE(ak4554_dapm_routes), | 71 | .dapm_routes = ak4554_dapm_routes, |
72 | .num_dapm_routes = ARRAY_SIZE(ak4554_dapm_routes), | ||
73 | }, | ||
72 | }; | 74 | }; |
73 | 75 | ||
74 | static int ak4554_soc_probe(struct platform_device *pdev) | 76 | static int ak4554_soc_probe(struct platform_device *pdev) |
diff --git a/sound/soc/codecs/ak4613.c b/sound/soc/codecs/ak4613.c index 97798d250f08..e819dd8c82fd 100644 --- a/sound/soc/codecs/ak4613.c +++ b/sound/soc/codecs/ak4613.c | |||
@@ -458,12 +458,14 @@ static struct snd_soc_codec_driver soc_codec_dev_ak4613 = { | |||
458 | .suspend = ak4613_suspend, | 458 | .suspend = ak4613_suspend, |
459 | .resume = ak4613_resume, | 459 | .resume = ak4613_resume, |
460 | .set_bias_level = ak4613_set_bias_level, | 460 | .set_bias_level = ak4613_set_bias_level, |
461 | .controls = ak4613_snd_controls, | 461 | .component_driver = { |
462 | .num_controls = ARRAY_SIZE(ak4613_snd_controls), | 462 | .controls = ak4613_snd_controls, |
463 | .dapm_widgets = ak4613_dapm_widgets, | 463 | .num_controls = ARRAY_SIZE(ak4613_snd_controls), |
464 | .num_dapm_widgets = ARRAY_SIZE(ak4613_dapm_widgets), | 464 | .dapm_widgets = ak4613_dapm_widgets, |
465 | .dapm_routes = ak4613_intercon, | 465 | .num_dapm_widgets = ARRAY_SIZE(ak4613_dapm_widgets), |
466 | .num_dapm_routes = ARRAY_SIZE(ak4613_intercon), | 466 | .dapm_routes = ak4613_intercon, |
467 | .num_dapm_routes = ARRAY_SIZE(ak4613_intercon), | ||
468 | }, | ||
467 | }; | 469 | }; |
468 | 470 | ||
469 | static void ak4613_parse_of(struct ak4613_priv *priv, | 471 | static void ak4613_parse_of(struct ak4613_priv *priv, |
diff --git a/sound/soc/codecs/ak4641.c b/sound/soc/codecs/ak4641.c index b14176f8d884..c91717d08513 100644 --- a/sound/soc/codecs/ak4641.c +++ b/sound/soc/codecs/ak4641.c | |||
@@ -505,12 +505,14 @@ static struct snd_soc_dai_driver ak4641_dai[] = { | |||
505 | }; | 505 | }; |
506 | 506 | ||
507 | static struct snd_soc_codec_driver soc_codec_dev_ak4641 = { | 507 | static struct snd_soc_codec_driver soc_codec_dev_ak4641 = { |
508 | .controls = ak4641_snd_controls, | 508 | .component_driver = { |
509 | .num_controls = ARRAY_SIZE(ak4641_snd_controls), | 509 | .controls = ak4641_snd_controls, |
510 | .dapm_widgets = ak4641_dapm_widgets, | 510 | .num_controls = ARRAY_SIZE(ak4641_snd_controls), |
511 | .num_dapm_widgets = ARRAY_SIZE(ak4641_dapm_widgets), | 511 | .dapm_widgets = ak4641_dapm_widgets, |
512 | .dapm_routes = ak4641_audio_map, | 512 | .num_dapm_widgets = ARRAY_SIZE(ak4641_dapm_widgets), |
513 | .num_dapm_routes = ARRAY_SIZE(ak4641_audio_map), | 513 | .dapm_routes = ak4641_audio_map, |
514 | .num_dapm_routes = ARRAY_SIZE(ak4641_audio_map), | ||
515 | }, | ||
514 | .set_bias_level = ak4641_set_bias_level, | 516 | .set_bias_level = ak4641_set_bias_level, |
515 | .suspend_bias_off = true, | 517 | .suspend_bias_off = true, |
516 | }; | 518 | }; |
diff --git a/sound/soc/codecs/ak4642.c b/sound/soc/codecs/ak4642.c index cc941d66ec3d..2609f95b7d19 100644 --- a/sound/soc/codecs/ak4642.c +++ b/sound/soc/codecs/ak4642.c | |||
@@ -555,12 +555,14 @@ static struct snd_soc_codec_driver soc_codec_dev_ak4642 = { | |||
555 | .suspend = ak4642_suspend, | 555 | .suspend = ak4642_suspend, |
556 | .resume = ak4642_resume, | 556 | .resume = ak4642_resume, |
557 | .set_bias_level = ak4642_set_bias_level, | 557 | .set_bias_level = ak4642_set_bias_level, |
558 | .controls = ak4642_snd_controls, | 558 | .component_driver = { |
559 | .num_controls = ARRAY_SIZE(ak4642_snd_controls), | 559 | .controls = ak4642_snd_controls, |
560 | .dapm_widgets = ak4642_dapm_widgets, | 560 | .num_controls = ARRAY_SIZE(ak4642_snd_controls), |
561 | .num_dapm_widgets = ARRAY_SIZE(ak4642_dapm_widgets), | 561 | .dapm_widgets = ak4642_dapm_widgets, |
562 | .dapm_routes = ak4642_intercon, | 562 | .num_dapm_widgets = ARRAY_SIZE(ak4642_dapm_widgets), |
563 | .num_dapm_routes = ARRAY_SIZE(ak4642_intercon), | 563 | .dapm_routes = ak4642_intercon, |
564 | .num_dapm_routes = ARRAY_SIZE(ak4642_intercon), | ||
565 | }, | ||
564 | }; | 566 | }; |
565 | 567 | ||
566 | static const struct regmap_config ak4642_regmap = { | 568 | static const struct regmap_config ak4642_regmap = { |
diff --git a/sound/soc/codecs/ak4671.c b/sound/soc/codecs/ak4671.c index c73a9f6914b6..6088afaabf62 100644 --- a/sound/soc/codecs/ak4671.c +++ b/sound/soc/codecs/ak4671.c | |||
@@ -612,12 +612,14 @@ static struct snd_soc_dai_driver ak4671_dai = { | |||
612 | 612 | ||
613 | static struct snd_soc_codec_driver soc_codec_dev_ak4671 = { | 613 | static struct snd_soc_codec_driver soc_codec_dev_ak4671 = { |
614 | .set_bias_level = ak4671_set_bias_level, | 614 | .set_bias_level = ak4671_set_bias_level, |
615 | .controls = ak4671_snd_controls, | 615 | .component_driver = { |
616 | .num_controls = ARRAY_SIZE(ak4671_snd_controls), | 616 | .controls = ak4671_snd_controls, |
617 | .dapm_widgets = ak4671_dapm_widgets, | 617 | .num_controls = ARRAY_SIZE(ak4671_snd_controls), |
618 | .num_dapm_widgets = ARRAY_SIZE(ak4671_dapm_widgets), | 618 | .dapm_widgets = ak4671_dapm_widgets, |
619 | .dapm_routes = ak4671_intercon, | 619 | .num_dapm_widgets = ARRAY_SIZE(ak4671_dapm_widgets), |
620 | .num_dapm_routes = ARRAY_SIZE(ak4671_intercon), | 620 | .dapm_routes = ak4671_intercon, |
621 | .num_dapm_routes = ARRAY_SIZE(ak4671_intercon), | ||
622 | }, | ||
621 | }; | 623 | }; |
622 | 624 | ||
623 | static const struct regmap_config ak4671_regmap = { | 625 | static const struct regmap_config ak4671_regmap = { |
diff --git a/sound/soc/codecs/ak5386.c b/sound/soc/codecs/ak5386.c index afa95360826d..0ef2df223336 100644 --- a/sound/soc/codecs/ak5386.c +++ b/sound/soc/codecs/ak5386.c | |||
@@ -74,10 +74,12 @@ static struct snd_soc_codec_driver soc_codec_ak5386 = { | |||
74 | .remove = ak5386_soc_remove, | 74 | .remove = ak5386_soc_remove, |
75 | .suspend = ak5386_soc_suspend, | 75 | .suspend = ak5386_soc_suspend, |
76 | .resume = ak5386_soc_resume, | 76 | .resume = ak5386_soc_resume, |
77 | .dapm_widgets = ak5386_dapm_widgets, | 77 | .component_driver = { |
78 | .num_dapm_widgets = ARRAY_SIZE(ak5386_dapm_widgets), | 78 | .dapm_widgets = ak5386_dapm_widgets, |
79 | .dapm_routes = ak5386_dapm_routes, | 79 | .num_dapm_widgets = ARRAY_SIZE(ak5386_dapm_widgets), |
80 | .num_dapm_routes = ARRAY_SIZE(ak5386_dapm_routes), | 80 | .dapm_routes = ak5386_dapm_routes, |
81 | .num_dapm_routes = ARRAY_SIZE(ak5386_dapm_routes), | ||
82 | }, | ||
81 | }; | 83 | }; |
82 | 84 | ||
83 | static int ak5386_set_dai_fmt(struct snd_soc_dai *codec_dai, | 85 | static int ak5386_set_dai_fmt(struct snd_soc_dai *codec_dai, |
diff --git a/sound/soc/codecs/alc5632.c b/sound/soc/codecs/alc5632.c index 4d3ba33eb6f9..adb80d8719bd 100644 --- a/sound/soc/codecs/alc5632.c +++ b/sound/soc/codecs/alc5632.c | |||
@@ -1072,12 +1072,14 @@ static const struct snd_soc_codec_driver soc_codec_device_alc5632 = { | |||
1072 | .set_bias_level = alc5632_set_bias_level, | 1072 | .set_bias_level = alc5632_set_bias_level, |
1073 | .suspend_bias_off = true, | 1073 | .suspend_bias_off = true, |
1074 | 1074 | ||
1075 | .controls = alc5632_snd_controls, | 1075 | .component_driver = { |
1076 | .num_controls = ARRAY_SIZE(alc5632_snd_controls), | 1076 | .controls = alc5632_snd_controls, |
1077 | .dapm_widgets = alc5632_dapm_widgets, | 1077 | .num_controls = ARRAY_SIZE(alc5632_snd_controls), |
1078 | .num_dapm_widgets = ARRAY_SIZE(alc5632_dapm_widgets), | 1078 | .dapm_widgets = alc5632_dapm_widgets, |
1079 | .dapm_routes = alc5632_dapm_routes, | 1079 | .num_dapm_widgets = ARRAY_SIZE(alc5632_dapm_widgets), |
1080 | .num_dapm_routes = ARRAY_SIZE(alc5632_dapm_routes), | 1080 | .dapm_routes = alc5632_dapm_routes, |
1081 | .num_dapm_routes = ARRAY_SIZE(alc5632_dapm_routes), | ||
1082 | }, | ||
1081 | }; | 1083 | }; |
1082 | 1084 | ||
1083 | static const struct regmap_config alc5632_regmap = { | 1085 | static const struct regmap_config alc5632_regmap = { |
diff --git a/sound/soc/codecs/arizona.c b/sound/soc/codecs/arizona.c index ecfdbfcae366..846ca079845f 100644 --- a/sound/soc/codecs/arizona.c +++ b/sound/soc/codecs/arizona.c | |||
@@ -109,7 +109,7 @@ static int arizona_spk_ev(struct snd_soc_dapm_widget *w, | |||
109 | break; | 109 | break; |
110 | } | 110 | } |
111 | 111 | ||
112 | return 0; | 112 | return arizona_out_ev(w, kcontrol, event); |
113 | } | 113 | } |
114 | 114 | ||
115 | static irqreturn_t arizona_thermal_warn(int irq, void *data) | 115 | static irqreturn_t arizona_thermal_warn(int irq, void *data) |
@@ -159,12 +159,14 @@ static irqreturn_t arizona_thermal_shutdown(int irq, void *data) | |||
159 | static const struct snd_soc_dapm_widget arizona_spkl = | 159 | static const struct snd_soc_dapm_widget arizona_spkl = |
160 | SND_SOC_DAPM_PGA_E("OUT4L", SND_SOC_NOPM, | 160 | SND_SOC_DAPM_PGA_E("OUT4L", SND_SOC_NOPM, |
161 | ARIZONA_OUT4L_ENA_SHIFT, 0, NULL, 0, arizona_spk_ev, | 161 | ARIZONA_OUT4L_ENA_SHIFT, 0, NULL, 0, arizona_spk_ev, |
162 | SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU); | 162 | SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | |
163 | SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD); | ||
163 | 164 | ||
164 | static const struct snd_soc_dapm_widget arizona_spkr = | 165 | static const struct snd_soc_dapm_widget arizona_spkr = |
165 | SND_SOC_DAPM_PGA_E("OUT4R", SND_SOC_NOPM, | 166 | SND_SOC_DAPM_PGA_E("OUT4R", SND_SOC_NOPM, |
166 | ARIZONA_OUT4R_ENA_SHIFT, 0, NULL, 0, arizona_spk_ev, | 167 | ARIZONA_OUT4R_ENA_SHIFT, 0, NULL, 0, arizona_spk_ev, |
167 | SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU); | 168 | SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | |
169 | SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD); | ||
168 | 170 | ||
169 | int arizona_init_spk(struct snd_soc_codec *codec) | 171 | int arizona_init_spk(struct snd_soc_codec *codec) |
170 | { | 172 | { |
@@ -864,6 +866,7 @@ int arizona_out_ev(struct snd_soc_dapm_widget *w, | |||
864 | { | 866 | { |
865 | struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); | 867 | struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); |
866 | struct arizona_priv *priv = snd_soc_codec_get_drvdata(codec); | 868 | struct arizona_priv *priv = snd_soc_codec_get_drvdata(codec); |
869 | struct arizona *arizona = priv->arizona; | ||
867 | 870 | ||
868 | switch (event) { | 871 | switch (event) { |
869 | case SND_SOC_DAPM_PRE_PMU: | 872 | case SND_SOC_DAPM_PRE_PMU: |
@@ -877,6 +880,18 @@ int arizona_out_ev(struct snd_soc_dapm_widget *w, | |||
877 | priv->out_up_pending++; | 880 | priv->out_up_pending++; |
878 | priv->out_up_delay += 17; | 881 | priv->out_up_delay += 17; |
879 | break; | 882 | break; |
883 | case ARIZONA_OUT4L_ENA_SHIFT: | ||
884 | case ARIZONA_OUT4R_ENA_SHIFT: | ||
885 | priv->out_up_pending++; | ||
886 | switch (arizona->type) { | ||
887 | case WM5102: | ||
888 | case WM8997: | ||
889 | break; | ||
890 | default: | ||
891 | priv->out_up_delay += 10; | ||
892 | break; | ||
893 | } | ||
894 | break; | ||
880 | default: | 895 | default: |
881 | break; | 896 | break; |
882 | } | 897 | } |
@@ -889,8 +904,12 @@ int arizona_out_ev(struct snd_soc_dapm_widget *w, | |||
889 | case ARIZONA_OUT2R_ENA_SHIFT: | 904 | case ARIZONA_OUT2R_ENA_SHIFT: |
890 | case ARIZONA_OUT3L_ENA_SHIFT: | 905 | case ARIZONA_OUT3L_ENA_SHIFT: |
891 | case ARIZONA_OUT3R_ENA_SHIFT: | 906 | case ARIZONA_OUT3R_ENA_SHIFT: |
907 | case ARIZONA_OUT4L_ENA_SHIFT: | ||
908 | case ARIZONA_OUT4R_ENA_SHIFT: | ||
892 | priv->out_up_pending--; | 909 | priv->out_up_pending--; |
893 | if (!priv->out_up_pending) { | 910 | if (!priv->out_up_pending && priv->out_up_delay) { |
911 | dev_dbg(codec->dev, "Power up delay: %d\n", | ||
912 | priv->out_up_delay); | ||
894 | msleep(priv->out_up_delay); | 913 | msleep(priv->out_up_delay); |
895 | priv->out_up_delay = 0; | 914 | priv->out_up_delay = 0; |
896 | } | 915 | } |
@@ -911,6 +930,21 @@ int arizona_out_ev(struct snd_soc_dapm_widget *w, | |||
911 | priv->out_down_pending++; | 930 | priv->out_down_pending++; |
912 | priv->out_down_delay++; | 931 | priv->out_down_delay++; |
913 | break; | 932 | break; |
933 | case ARIZONA_OUT4L_ENA_SHIFT: | ||
934 | case ARIZONA_OUT4R_ENA_SHIFT: | ||
935 | priv->out_down_pending++; | ||
936 | switch (arizona->type) { | ||
937 | case WM5102: | ||
938 | case WM8997: | ||
939 | break; | ||
940 | case WM8998: | ||
941 | case WM1814: | ||
942 | priv->out_down_delay += 5; | ||
943 | break; | ||
944 | default: | ||
945 | priv->out_down_delay++; | ||
946 | break; | ||
947 | } | ||
914 | default: | 948 | default: |
915 | break; | 949 | break; |
916 | } | 950 | } |
@@ -923,8 +957,12 @@ int arizona_out_ev(struct snd_soc_dapm_widget *w, | |||
923 | case ARIZONA_OUT2R_ENA_SHIFT: | 957 | case ARIZONA_OUT2R_ENA_SHIFT: |
924 | case ARIZONA_OUT3L_ENA_SHIFT: | 958 | case ARIZONA_OUT3L_ENA_SHIFT: |
925 | case ARIZONA_OUT3R_ENA_SHIFT: | 959 | case ARIZONA_OUT3R_ENA_SHIFT: |
960 | case ARIZONA_OUT4L_ENA_SHIFT: | ||
961 | case ARIZONA_OUT4R_ENA_SHIFT: | ||
926 | priv->out_down_pending--; | 962 | priv->out_down_pending--; |
927 | if (!priv->out_down_pending) { | 963 | if (!priv->out_down_pending && priv->out_down_delay) { |
964 | dev_dbg(codec->dev, "Power down delay: %d\n", | ||
965 | priv->out_down_delay); | ||
928 | msleep(priv->out_down_delay); | 966 | msleep(priv->out_down_delay); |
929 | priv->out_down_delay = 0; | 967 | priv->out_down_delay = 0; |
930 | } | 968 | } |
@@ -1920,8 +1958,8 @@ static struct { | |||
1920 | 1958 | ||
1921 | struct arizona_fll_cfg { | 1959 | struct arizona_fll_cfg { |
1922 | int n; | 1960 | int n; |
1923 | int theta; | 1961 | unsigned int theta; |
1924 | int lambda; | 1962 | unsigned int lambda; |
1925 | int refdiv; | 1963 | int refdiv; |
1926 | int outdiv; | 1964 | int outdiv; |
1927 | int fratio; | 1965 | int fratio; |
@@ -2188,13 +2226,13 @@ static void arizona_apply_fll(struct arizona *arizona, unsigned int base, | |||
2188 | ARIZONA_FLL1_CTRL_UPD | cfg->n); | 2226 | ARIZONA_FLL1_CTRL_UPD | cfg->n); |
2189 | } | 2227 | } |
2190 | 2228 | ||
2191 | static int arizona_is_enabled_fll(struct arizona_fll *fll) | 2229 | static int arizona_is_enabled_fll(struct arizona_fll *fll, int base) |
2192 | { | 2230 | { |
2193 | struct arizona *arizona = fll->arizona; | 2231 | struct arizona *arizona = fll->arizona; |
2194 | unsigned int reg; | 2232 | unsigned int reg; |
2195 | int ret; | 2233 | int ret; |
2196 | 2234 | ||
2197 | ret = regmap_read(arizona->regmap, fll->base + 1, ®); | 2235 | ret = regmap_read(arizona->regmap, base + 1, ®); |
2198 | if (ret != 0) { | 2236 | if (ret != 0) { |
2199 | arizona_fll_err(fll, "Failed to read current state: %d\n", | 2237 | arizona_fll_err(fll, "Failed to read current state: %d\n", |
2200 | ret); | 2238 | ret); |
@@ -2208,21 +2246,24 @@ static int arizona_enable_fll(struct arizona_fll *fll) | |||
2208 | { | 2246 | { |
2209 | struct arizona *arizona = fll->arizona; | 2247 | struct arizona *arizona = fll->arizona; |
2210 | bool use_sync = false; | 2248 | bool use_sync = false; |
2211 | int already_enabled = arizona_is_enabled_fll(fll); | 2249 | int already_enabled = arizona_is_enabled_fll(fll, fll->base); |
2250 | int sync_enabled = arizona_is_enabled_fll(fll, fll->base + 0x10); | ||
2212 | struct arizona_fll_cfg cfg; | 2251 | struct arizona_fll_cfg cfg; |
2213 | int i; | 2252 | int i; |
2214 | unsigned int val; | 2253 | unsigned int val; |
2215 | 2254 | ||
2216 | if (already_enabled < 0) | 2255 | if (already_enabled < 0) |
2217 | return already_enabled; | 2256 | return already_enabled; |
2257 | if (sync_enabled < 0) | ||
2258 | return sync_enabled; | ||
2218 | 2259 | ||
2219 | if (already_enabled) { | 2260 | if (already_enabled) { |
2220 | /* Facilitate smooth refclk across the transition */ | 2261 | /* Facilitate smooth refclk across the transition */ |
2221 | regmap_update_bits_async(fll->arizona->regmap, fll->base + 0x9, | ||
2222 | ARIZONA_FLL1_GAIN_MASK, 0); | ||
2223 | regmap_update_bits(fll->arizona->regmap, fll->base + 1, | 2262 | regmap_update_bits(fll->arizona->regmap, fll->base + 1, |
2224 | ARIZONA_FLL1_FREERUN, ARIZONA_FLL1_FREERUN); | 2263 | ARIZONA_FLL1_FREERUN, ARIZONA_FLL1_FREERUN); |
2225 | udelay(32); | 2264 | udelay(32); |
2265 | regmap_update_bits_async(fll->arizona->regmap, fll->base + 0x9, | ||
2266 | ARIZONA_FLL1_GAIN_MASK, 0); | ||
2226 | } | 2267 | } |
2227 | 2268 | ||
2228 | /* | 2269 | /* |
@@ -2233,6 +2274,10 @@ static int arizona_enable_fll(struct arizona_fll *fll) | |||
2233 | fll->ref_src != fll->sync_src) { | 2274 | fll->ref_src != fll->sync_src) { |
2234 | arizona_calc_fll(fll, &cfg, fll->ref_freq, false); | 2275 | arizona_calc_fll(fll, &cfg, fll->ref_freq, false); |
2235 | 2276 | ||
2277 | /* Ref path hardcodes lambda to 65536 when sync is on */ | ||
2278 | if (fll->sync_src >= 0 && cfg.lambda) | ||
2279 | cfg.theta = (cfg.theta * (1 << 16)) / cfg.lambda; | ||
2280 | |||
2236 | arizona_apply_fll(arizona, fll->base, &cfg, fll->ref_src, | 2281 | arizona_apply_fll(arizona, fll->base, &cfg, fll->ref_src, |
2237 | false); | 2282 | false); |
2238 | if (fll->sync_src >= 0) { | 2283 | if (fll->sync_src >= 0) { |
@@ -2255,6 +2300,9 @@ static int arizona_enable_fll(struct arizona_fll *fll) | |||
2255 | return -EINVAL; | 2300 | return -EINVAL; |
2256 | } | 2301 | } |
2257 | 2302 | ||
2303 | if (already_enabled && !!sync_enabled != use_sync) | ||
2304 | arizona_fll_warn(fll, "Synchroniser changed on active FLL\n"); | ||
2305 | |||
2258 | /* | 2306 | /* |
2259 | * Increase the bandwidth if we're not using a low frequency | 2307 | * Increase the bandwidth if we're not using a low frequency |
2260 | * sync source. | 2308 | * sync source. |
@@ -2268,14 +2316,14 @@ static int arizona_enable_fll(struct arizona_fll *fll) | |||
2268 | ARIZONA_FLL1_SYNC_BW); | 2316 | ARIZONA_FLL1_SYNC_BW); |
2269 | 2317 | ||
2270 | if (!already_enabled) | 2318 | if (!already_enabled) |
2271 | pm_runtime_get(arizona->dev); | 2319 | pm_runtime_get_sync(arizona->dev); |
2272 | 2320 | ||
2273 | regmap_update_bits_async(arizona->regmap, fll->base + 1, | ||
2274 | ARIZONA_FLL1_ENA, ARIZONA_FLL1_ENA); | ||
2275 | if (use_sync) | 2321 | if (use_sync) |
2276 | regmap_update_bits_async(arizona->regmap, fll->base + 0x11, | 2322 | regmap_update_bits_async(arizona->regmap, fll->base + 0x11, |
2277 | ARIZONA_FLL1_SYNC_ENA, | 2323 | ARIZONA_FLL1_SYNC_ENA, |
2278 | ARIZONA_FLL1_SYNC_ENA); | 2324 | ARIZONA_FLL1_SYNC_ENA); |
2325 | regmap_update_bits_async(arizona->regmap, fll->base + 1, | ||
2326 | ARIZONA_FLL1_ENA, ARIZONA_FLL1_ENA); | ||
2279 | 2327 | ||
2280 | if (already_enabled) | 2328 | if (already_enabled) |
2281 | regmap_update_bits_async(arizona->regmap, fll->base + 1, | 2329 | regmap_update_bits_async(arizona->regmap, fll->base + 1, |
diff --git a/sound/soc/codecs/arizona.h b/sound/soc/codecs/arizona.h index 69da1ef3a17c..850aa338ba29 100644 --- a/sound/soc/codecs/arizona.h +++ b/sound/soc/codecs/arizona.h | |||
@@ -190,20 +190,21 @@ extern unsigned int arizona_mixer_values[ARIZONA_NUM_MIXER_INPUTS]; | |||
190 | 190 | ||
191 | #define ARIZONA_DSP_ROUTES(name) \ | 191 | #define ARIZONA_DSP_ROUTES(name) \ |
192 | { name, NULL, name " Preloader"}, \ | 192 | { name, NULL, name " Preloader"}, \ |
193 | { name " Preloader", NULL, name " Aux 1" }, \ | 193 | { name " Preloader", NULL, "SYSCLK" }, \ |
194 | { name " Preloader", NULL, name " Aux 2" }, \ | 194 | { name, NULL, name " Aux 1" }, \ |
195 | { name " Preloader", NULL, name " Aux 3" }, \ | 195 | { name, NULL, name " Aux 2" }, \ |
196 | { name " Preloader", NULL, name " Aux 4" }, \ | 196 | { name, NULL, name " Aux 3" }, \ |
197 | { name " Preloader", NULL, name " Aux 5" }, \ | 197 | { name, NULL, name " Aux 4" }, \ |
198 | { name " Preloader", NULL, name " Aux 6" }, \ | 198 | { name, NULL, name " Aux 5" }, \ |
199 | { name, NULL, name " Aux 6" }, \ | ||
199 | ARIZONA_MIXER_INPUT_ROUTES(name " Aux 1"), \ | 200 | ARIZONA_MIXER_INPUT_ROUTES(name " Aux 1"), \ |
200 | ARIZONA_MIXER_INPUT_ROUTES(name " Aux 2"), \ | 201 | ARIZONA_MIXER_INPUT_ROUTES(name " Aux 2"), \ |
201 | ARIZONA_MIXER_INPUT_ROUTES(name " Aux 3"), \ | 202 | ARIZONA_MIXER_INPUT_ROUTES(name " Aux 3"), \ |
202 | ARIZONA_MIXER_INPUT_ROUTES(name " Aux 4"), \ | 203 | ARIZONA_MIXER_INPUT_ROUTES(name " Aux 4"), \ |
203 | ARIZONA_MIXER_INPUT_ROUTES(name " Aux 5"), \ | 204 | ARIZONA_MIXER_INPUT_ROUTES(name " Aux 5"), \ |
204 | ARIZONA_MIXER_INPUT_ROUTES(name " Aux 6"), \ | 205 | ARIZONA_MIXER_INPUT_ROUTES(name " Aux 6"), \ |
205 | ARIZONA_MIXER_ROUTES(name " Preloader", name "L"), \ | 206 | ARIZONA_MIXER_ROUTES(name, name "L"), \ |
206 | ARIZONA_MIXER_ROUTES(name " Preloader", name "R") | 207 | ARIZONA_MIXER_ROUTES(name, name "R") |
207 | 208 | ||
208 | #define ARIZONA_EQ_CONTROL(xname, xbase) \ | 209 | #define ARIZONA_EQ_CONTROL(xname, xbase) \ |
209 | { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \ | 210 | { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \ |
diff --git a/sound/soc/codecs/bt-sco.c b/sound/soc/codecs/bt-sco.c index 2a8d0ee141d4..8014e697d540 100644 --- a/sound/soc/codecs/bt-sco.c +++ b/sound/soc/codecs/bt-sco.c | |||
@@ -63,10 +63,12 @@ static struct snd_soc_dai_driver bt_sco_dai[] = { | |||
63 | }; | 63 | }; |
64 | 64 | ||
65 | static struct snd_soc_codec_driver soc_codec_dev_bt_sco = { | 65 | static struct snd_soc_codec_driver soc_codec_dev_bt_sco = { |
66 | .dapm_widgets = bt_sco_widgets, | 66 | .component_driver = { |
67 | .num_dapm_widgets = ARRAY_SIZE(bt_sco_widgets), | 67 | .dapm_widgets = bt_sco_widgets, |
68 | .dapm_routes = bt_sco_routes, | 68 | .num_dapm_widgets = ARRAY_SIZE(bt_sco_widgets), |
69 | .num_dapm_routes = ARRAY_SIZE(bt_sco_routes), | 69 | .dapm_routes = bt_sco_routes, |
70 | .num_dapm_routes = ARRAY_SIZE(bt_sco_routes), | ||
71 | }, | ||
70 | }; | 72 | }; |
71 | 73 | ||
72 | static int bt_sco_probe(struct platform_device *pdev) | 74 | static int bt_sco_probe(struct platform_device *pdev) |
diff --git a/sound/soc/codecs/cq93vc.c b/sound/soc/codecs/cq93vc.c index 1c895a53001d..7a2d9a2ee427 100644 --- a/sound/soc/codecs/cq93vc.c +++ b/sound/soc/codecs/cq93vc.c | |||
@@ -131,8 +131,10 @@ static struct regmap *cq93vc_get_regmap(struct device *dev) | |||
131 | static struct snd_soc_codec_driver soc_codec_dev_cq93vc = { | 131 | static struct snd_soc_codec_driver soc_codec_dev_cq93vc = { |
132 | .set_bias_level = cq93vc_set_bias_level, | 132 | .set_bias_level = cq93vc_set_bias_level, |
133 | .get_regmap = cq93vc_get_regmap, | 133 | .get_regmap = cq93vc_get_regmap, |
134 | .controls = cq93vc_snd_controls, | 134 | .component_driver = { |
135 | .num_controls = ARRAY_SIZE(cq93vc_snd_controls), | 135 | .controls = cq93vc_snd_controls, |
136 | .num_controls = ARRAY_SIZE(cq93vc_snd_controls), | ||
137 | }, | ||
136 | }; | 138 | }; |
137 | 139 | ||
138 | static int cq93vc_platform_probe(struct platform_device *pdev) | 140 | static int cq93vc_platform_probe(struct platform_device *pdev) |
diff --git a/sound/soc/codecs/cs35l32.c b/sound/soc/codecs/cs35l32.c index 287d13740be4..7e9806206648 100644 --- a/sound/soc/codecs/cs35l32.c +++ b/sound/soc/codecs/cs35l32.c | |||
@@ -231,13 +231,14 @@ static int cs35l32_codec_set_sysclk(struct snd_soc_codec *codec, | |||
231 | static const struct snd_soc_codec_driver soc_codec_dev_cs35l32 = { | 231 | static const struct snd_soc_codec_driver soc_codec_dev_cs35l32 = { |
232 | .set_sysclk = cs35l32_codec_set_sysclk, | 232 | .set_sysclk = cs35l32_codec_set_sysclk, |
233 | 233 | ||
234 | .dapm_widgets = cs35l32_dapm_widgets, | 234 | .component_driver = { |
235 | .num_dapm_widgets = ARRAY_SIZE(cs35l32_dapm_widgets), | 235 | .controls = cs35l32_snd_controls, |
236 | .dapm_routes = cs35l32_audio_map, | 236 | .num_controls = ARRAY_SIZE(cs35l32_snd_controls), |
237 | .num_dapm_routes = ARRAY_SIZE(cs35l32_audio_map), | 237 | .dapm_widgets = cs35l32_dapm_widgets, |
238 | 238 | .num_dapm_widgets = ARRAY_SIZE(cs35l32_dapm_widgets), | |
239 | .controls = cs35l32_snd_controls, | 239 | .dapm_routes = cs35l32_audio_map, |
240 | .num_controls = ARRAY_SIZE(cs35l32_snd_controls), | 240 | .num_dapm_routes = ARRAY_SIZE(cs35l32_audio_map), |
241 | }, | ||
241 | }; | 242 | }; |
242 | 243 | ||
243 | /* Current and threshold powerup sequence Pg37 in datasheet */ | 244 | /* Current and threshold powerup sequence Pg37 in datasheet */ |
diff --git a/sound/soc/codecs/cs35l33.c b/sound/soc/codecs/cs35l33.c index 6f9c1addcd7f..6df29fa30fb9 100644 --- a/sound/soc/codecs/cs35l33.c +++ b/sound/soc/codecs/cs35l33.c | |||
@@ -837,13 +837,14 @@ static struct snd_soc_codec_driver soc_codec_dev_cs35l33 = { | |||
837 | .set_bias_level = cs35l33_set_bias_level, | 837 | .set_bias_level = cs35l33_set_bias_level, |
838 | .set_sysclk = cs35l33_codec_set_sysclk, | 838 | .set_sysclk = cs35l33_codec_set_sysclk, |
839 | 839 | ||
840 | .dapm_widgets = cs35l33_dapm_widgets, | 840 | .component_driver = { |
841 | .num_dapm_widgets = ARRAY_SIZE(cs35l33_dapm_widgets), | 841 | .controls = cs35l33_snd_controls, |
842 | .dapm_routes = cs35l33_audio_map, | 842 | .num_controls = ARRAY_SIZE(cs35l33_snd_controls), |
843 | .num_dapm_routes = ARRAY_SIZE(cs35l33_audio_map), | 843 | .dapm_widgets = cs35l33_dapm_widgets, |
844 | .controls = cs35l33_snd_controls, | 844 | .num_dapm_widgets = ARRAY_SIZE(cs35l33_dapm_widgets), |
845 | .num_controls = ARRAY_SIZE(cs35l33_snd_controls), | 845 | .dapm_routes = cs35l33_audio_map, |
846 | 846 | .num_dapm_routes = ARRAY_SIZE(cs35l33_audio_map), | |
847 | }, | ||
847 | .idle_bias_off = true, | 848 | .idle_bias_off = true, |
848 | }; | 849 | }; |
849 | 850 | ||
diff --git a/sound/soc/codecs/cs4265.c b/sound/soc/codecs/cs4265.c index 55db19ddc5ff..fd966bb851cb 100644 --- a/sound/soc/codecs/cs4265.c +++ b/sound/soc/codecs/cs4265.c | |||
@@ -547,13 +547,14 @@ static struct snd_soc_dai_driver cs4265_dai[] = { | |||
547 | static const struct snd_soc_codec_driver soc_codec_cs4265 = { | 547 | static const struct snd_soc_codec_driver soc_codec_cs4265 = { |
548 | .set_bias_level = cs4265_set_bias_level, | 548 | .set_bias_level = cs4265_set_bias_level, |
549 | 549 | ||
550 | .dapm_widgets = cs4265_dapm_widgets, | 550 | .component_driver = { |
551 | .num_dapm_widgets = ARRAY_SIZE(cs4265_dapm_widgets), | 551 | .controls = cs4265_snd_controls, |
552 | .dapm_routes = cs4265_audio_map, | 552 | .num_controls = ARRAY_SIZE(cs4265_snd_controls), |
553 | .num_dapm_routes = ARRAY_SIZE(cs4265_audio_map), | 553 | .dapm_widgets = cs4265_dapm_widgets, |
554 | 554 | .num_dapm_widgets = ARRAY_SIZE(cs4265_dapm_widgets), | |
555 | .controls = cs4265_snd_controls, | 555 | .dapm_routes = cs4265_audio_map, |
556 | .num_controls = ARRAY_SIZE(cs4265_snd_controls), | 556 | .num_dapm_routes = ARRAY_SIZE(cs4265_audio_map), |
557 | }, | ||
557 | }; | 558 | }; |
558 | 559 | ||
559 | static const struct regmap_config cs4265_regmap = { | 560 | static const struct regmap_config cs4265_regmap = { |
diff --git a/sound/soc/codecs/cs4270.c b/sound/soc/codecs/cs4270.c index e07807d96b68..18baea2f7d65 100644 --- a/sound/soc/codecs/cs4270.c +++ b/sound/soc/codecs/cs4270.c | |||
@@ -617,12 +617,14 @@ static const struct snd_soc_codec_driver soc_codec_device_cs4270 = { | |||
617 | .suspend = cs4270_soc_suspend, | 617 | .suspend = cs4270_soc_suspend, |
618 | .resume = cs4270_soc_resume, | 618 | .resume = cs4270_soc_resume, |
619 | 619 | ||
620 | .controls = cs4270_snd_controls, | 620 | .component_driver = { |
621 | .num_controls = ARRAY_SIZE(cs4270_snd_controls), | 621 | .controls = cs4270_snd_controls, |
622 | .dapm_widgets = cs4270_dapm_widgets, | 622 | .num_controls = ARRAY_SIZE(cs4270_snd_controls), |
623 | .num_dapm_widgets = ARRAY_SIZE(cs4270_dapm_widgets), | 623 | .dapm_widgets = cs4270_dapm_widgets, |
624 | .dapm_routes = cs4270_dapm_routes, | 624 | .num_dapm_widgets = ARRAY_SIZE(cs4270_dapm_widgets), |
625 | .num_dapm_routes = ARRAY_SIZE(cs4270_dapm_routes), | 625 | .dapm_routes = cs4270_dapm_routes, |
626 | .num_dapm_routes = ARRAY_SIZE(cs4270_dapm_routes), | ||
627 | }, | ||
626 | }; | 628 | }; |
627 | 629 | ||
628 | /* | 630 | /* |
diff --git a/sound/soc/codecs/cs4271.c b/sound/soc/codecs/cs4271.c index 0c0010b25421..8c0f3b89b5bc 100644 --- a/sound/soc/codecs/cs4271.c +++ b/sound/soc/codecs/cs4271.c | |||
@@ -645,12 +645,14 @@ static struct snd_soc_codec_driver soc_codec_dev_cs4271 = { | |||
645 | .suspend = cs4271_soc_suspend, | 645 | .suspend = cs4271_soc_suspend, |
646 | .resume = cs4271_soc_resume, | 646 | .resume = cs4271_soc_resume, |
647 | 647 | ||
648 | .controls = cs4271_snd_controls, | 648 | .component_driver = { |
649 | .num_controls = ARRAY_SIZE(cs4271_snd_controls), | 649 | .controls = cs4271_snd_controls, |
650 | .dapm_widgets = cs4271_dapm_widgets, | 650 | .num_controls = ARRAY_SIZE(cs4271_snd_controls), |
651 | .num_dapm_widgets = ARRAY_SIZE(cs4271_dapm_widgets), | 651 | .dapm_widgets = cs4271_dapm_widgets, |
652 | .dapm_routes = cs4271_dapm_routes, | 652 | .num_dapm_widgets = ARRAY_SIZE(cs4271_dapm_widgets), |
653 | .num_dapm_routes = ARRAY_SIZE(cs4271_dapm_routes), | 653 | .dapm_routes = cs4271_dapm_routes, |
654 | .num_dapm_routes = ARRAY_SIZE(cs4271_dapm_routes), | ||
655 | }, | ||
654 | }; | 656 | }; |
655 | 657 | ||
656 | static int cs4271_common_probe(struct device *dev, | 658 | static int cs4271_common_probe(struct device *dev, |
diff --git a/sound/soc/codecs/cs42l51.c b/sound/soc/codecs/cs42l51.c index 35488f14e237..96cfe38943cd 100644 --- a/sound/soc/codecs/cs42l51.c +++ b/sound/soc/codecs/cs42l51.c | |||
@@ -507,12 +507,14 @@ static int cs42l51_codec_probe(struct snd_soc_codec *codec) | |||
507 | static struct snd_soc_codec_driver soc_codec_device_cs42l51 = { | 507 | static struct snd_soc_codec_driver soc_codec_device_cs42l51 = { |
508 | .probe = cs42l51_codec_probe, | 508 | .probe = cs42l51_codec_probe, |
509 | 509 | ||
510 | .controls = cs42l51_snd_controls, | 510 | .component_driver = { |
511 | .num_controls = ARRAY_SIZE(cs42l51_snd_controls), | 511 | .controls = cs42l51_snd_controls, |
512 | .dapm_widgets = cs42l51_dapm_widgets, | 512 | .num_controls = ARRAY_SIZE(cs42l51_snd_controls), |
513 | .num_dapm_widgets = ARRAY_SIZE(cs42l51_dapm_widgets), | 513 | .dapm_widgets = cs42l51_dapm_widgets, |
514 | .dapm_routes = cs42l51_routes, | 514 | .num_dapm_widgets = ARRAY_SIZE(cs42l51_dapm_widgets), |
515 | .num_dapm_routes = ARRAY_SIZE(cs42l51_routes), | 515 | .dapm_routes = cs42l51_routes, |
516 | .num_dapm_routes = ARRAY_SIZE(cs42l51_routes), | ||
517 | }, | ||
516 | }; | 518 | }; |
517 | 519 | ||
518 | const struct regmap_config cs42l51_regmap = { | 520 | const struct regmap_config cs42l51_regmap = { |
diff --git a/sound/soc/codecs/cs42l52.c b/sound/soc/codecs/cs42l52.c index 47b97fcefb0b..0d9c4a57301b 100644 --- a/sound/soc/codecs/cs42l52.c +++ b/sound/soc/codecs/cs42l52.c | |||
@@ -1056,13 +1056,14 @@ static const struct snd_soc_codec_driver soc_codec_dev_cs42l52 = { | |||
1056 | .set_bias_level = cs42l52_set_bias_level, | 1056 | .set_bias_level = cs42l52_set_bias_level, |
1057 | .suspend_bias_off = true, | 1057 | .suspend_bias_off = true, |
1058 | 1058 | ||
1059 | .dapm_widgets = cs42l52_dapm_widgets, | 1059 | .component_driver = { |
1060 | .num_dapm_widgets = ARRAY_SIZE(cs42l52_dapm_widgets), | 1060 | .controls = cs42l52_snd_controls, |
1061 | .dapm_routes = cs42l52_audio_map, | 1061 | .num_controls = ARRAY_SIZE(cs42l52_snd_controls), |
1062 | .num_dapm_routes = ARRAY_SIZE(cs42l52_audio_map), | 1062 | .dapm_widgets = cs42l52_dapm_widgets, |
1063 | 1063 | .num_dapm_widgets = ARRAY_SIZE(cs42l52_dapm_widgets), | |
1064 | .controls = cs42l52_snd_controls, | 1064 | .dapm_routes = cs42l52_audio_map, |
1065 | .num_controls = ARRAY_SIZE(cs42l52_snd_controls), | 1065 | .num_dapm_routes = ARRAY_SIZE(cs42l52_audio_map), |
1066 | }, | ||
1066 | }; | 1067 | }; |
1067 | 1068 | ||
1068 | /* Current and threshold powerup sequence Pg37 */ | 1069 | /* Current and threshold powerup sequence Pg37 */ |
diff --git a/sound/soc/codecs/cs42l56.c b/sound/soc/codecs/cs42l56.c index eec1ff853b98..54c1768bc818 100644 --- a/sound/soc/codecs/cs42l56.c +++ b/sound/soc/codecs/cs42l56.c | |||
@@ -1121,13 +1121,14 @@ static const struct snd_soc_codec_driver soc_codec_dev_cs42l56 = { | |||
1121 | .set_bias_level = cs42l56_set_bias_level, | 1121 | .set_bias_level = cs42l56_set_bias_level, |
1122 | .suspend_bias_off = true, | 1122 | .suspend_bias_off = true, |
1123 | 1123 | ||
1124 | .dapm_widgets = cs42l56_dapm_widgets, | 1124 | .component_driver = { |
1125 | .num_dapm_widgets = ARRAY_SIZE(cs42l56_dapm_widgets), | 1125 | .controls = cs42l56_snd_controls, |
1126 | .dapm_routes = cs42l56_audio_map, | 1126 | .num_controls = ARRAY_SIZE(cs42l56_snd_controls), |
1127 | .num_dapm_routes = ARRAY_SIZE(cs42l56_audio_map), | 1127 | .dapm_widgets = cs42l56_dapm_widgets, |
1128 | 1128 | .num_dapm_widgets = ARRAY_SIZE(cs42l56_dapm_widgets), | |
1129 | .controls = cs42l56_snd_controls, | 1129 | .dapm_routes = cs42l56_audio_map, |
1130 | .num_controls = ARRAY_SIZE(cs42l56_snd_controls), | 1130 | .num_dapm_routes = ARRAY_SIZE(cs42l56_audio_map), |
1131 | }, | ||
1131 | }; | 1132 | }; |
1132 | 1133 | ||
1133 | static const struct regmap_config cs42l56_regmap = { | 1134 | static const struct regmap_config cs42l56_regmap = { |
diff --git a/sound/soc/codecs/cs42l73.c b/sound/soc/codecs/cs42l73.c index 42a8fd4e1f9b..71ba5605495f 100644 --- a/sound/soc/codecs/cs42l73.c +++ b/sound/soc/codecs/cs42l73.c | |||
@@ -794,7 +794,7 @@ struct cs42l73_mclk_div { | |||
794 | u8 mmcc; | 794 | u8 mmcc; |
795 | }; | 795 | }; |
796 | 796 | ||
797 | static struct cs42l73_mclk_div cs42l73_mclk_coeffs[] = { | 797 | static const struct cs42l73_mclk_div cs42l73_mclk_coeffs[] = { |
798 | /* MCLK, Sample Rate, xMMCC[5:0] */ | 798 | /* MCLK, Sample Rate, xMMCC[5:0] */ |
799 | {5644800, 11025, 0x30}, | 799 | {5644800, 11025, 0x30}, |
800 | {5644800, 22050, 0x20}, | 800 | {5644800, 22050, 0x20}, |
@@ -844,7 +844,7 @@ struct cs42l73_mclkx_div { | |||
844 | u8 mclkdiv; | 844 | u8 mclkdiv; |
845 | }; | 845 | }; |
846 | 846 | ||
847 | static struct cs42l73_mclkx_div cs42l73_mclkx_coeffs[] = { | 847 | static const struct cs42l73_mclkx_div cs42l73_mclkx_coeffs[] = { |
848 | {5644800, 1, 0}, /* 5644800 */ | 848 | {5644800, 1, 0}, /* 5644800 */ |
849 | {6000000, 1, 0}, /* 6000000 */ | 849 | {6000000, 1, 0}, /* 6000000 */ |
850 | {6144000, 1, 0}, /* 6144000 */ | 850 | {6144000, 1, 0}, /* 6144000 */ |
@@ -1257,13 +1257,14 @@ static const struct snd_soc_codec_driver soc_codec_dev_cs42l73 = { | |||
1257 | .set_bias_level = cs42l73_set_bias_level, | 1257 | .set_bias_level = cs42l73_set_bias_level, |
1258 | .suspend_bias_off = true, | 1258 | .suspend_bias_off = true, |
1259 | 1259 | ||
1260 | .dapm_widgets = cs42l73_dapm_widgets, | 1260 | .component_driver = { |
1261 | .num_dapm_widgets = ARRAY_SIZE(cs42l73_dapm_widgets), | 1261 | .controls = cs42l73_snd_controls, |
1262 | .dapm_routes = cs42l73_audio_map, | 1262 | .num_controls = ARRAY_SIZE(cs42l73_snd_controls), |
1263 | .num_dapm_routes = ARRAY_SIZE(cs42l73_audio_map), | 1263 | .dapm_widgets = cs42l73_dapm_widgets, |
1264 | 1264 | .num_dapm_widgets = ARRAY_SIZE(cs42l73_dapm_widgets), | |
1265 | .controls = cs42l73_snd_controls, | 1265 | .dapm_routes = cs42l73_audio_map, |
1266 | .num_controls = ARRAY_SIZE(cs42l73_snd_controls), | 1266 | .num_dapm_routes = ARRAY_SIZE(cs42l73_audio_map), |
1267 | }, | ||
1267 | }; | 1268 | }; |
1268 | 1269 | ||
1269 | static const struct regmap_config cs42l73_regmap = { | 1270 | static const struct regmap_config cs42l73_regmap = { |
diff --git a/sound/soc/codecs/cs42xx8.c b/sound/soc/codecs/cs42xx8.c index 1179101b2b05..b4d87379d2bc 100644 --- a/sound/soc/codecs/cs42xx8.c +++ b/sound/soc/codecs/cs42xx8.c | |||
@@ -411,12 +411,14 @@ static const struct snd_soc_codec_driver cs42xx8_driver = { | |||
411 | .probe = cs42xx8_codec_probe, | 411 | .probe = cs42xx8_codec_probe, |
412 | .idle_bias_off = true, | 412 | .idle_bias_off = true, |
413 | 413 | ||
414 | .controls = cs42xx8_snd_controls, | 414 | .component_driver = { |
415 | .num_controls = ARRAY_SIZE(cs42xx8_snd_controls), | 415 | .controls = cs42xx8_snd_controls, |
416 | .dapm_widgets = cs42xx8_dapm_widgets, | 416 | .num_controls = ARRAY_SIZE(cs42xx8_snd_controls), |
417 | .num_dapm_widgets = ARRAY_SIZE(cs42xx8_dapm_widgets), | 417 | .dapm_widgets = cs42xx8_dapm_widgets, |
418 | .dapm_routes = cs42xx8_dapm_routes, | 418 | .num_dapm_widgets = ARRAY_SIZE(cs42xx8_dapm_widgets), |
419 | .num_dapm_routes = ARRAY_SIZE(cs42xx8_dapm_routes), | 419 | .dapm_routes = cs42xx8_dapm_routes, |
420 | .num_dapm_routes = ARRAY_SIZE(cs42xx8_dapm_routes), | ||
421 | }, | ||
420 | }; | 422 | }; |
421 | 423 | ||
422 | const struct cs42xx8_driver_data cs42448_data = { | 424 | const struct cs42xx8_driver_data cs42448_data = { |
diff --git a/sound/soc/codecs/cs4349.c b/sound/soc/codecs/cs4349.c index 0ac8fc5ed4ae..231ca935cdf3 100644 --- a/sound/soc/codecs/cs4349.c +++ b/sound/soc/codecs/cs4349.c | |||
@@ -256,13 +256,14 @@ static struct snd_soc_dai_driver cs4349_dai = { | |||
256 | }; | 256 | }; |
257 | 257 | ||
258 | static struct snd_soc_codec_driver soc_codec_dev_cs4349 = { | 258 | static struct snd_soc_codec_driver soc_codec_dev_cs4349 = { |
259 | .controls = cs4349_snd_controls, | 259 | .component_driver = { |
260 | .num_controls = ARRAY_SIZE(cs4349_snd_controls), | 260 | .controls = cs4349_snd_controls, |
261 | 261 | .num_controls = ARRAY_SIZE(cs4349_snd_controls), | |
262 | .dapm_widgets = cs4349_dapm_widgets, | 262 | .dapm_widgets = cs4349_dapm_widgets, |
263 | .num_dapm_widgets = ARRAY_SIZE(cs4349_dapm_widgets), | 263 | .num_dapm_widgets = ARRAY_SIZE(cs4349_dapm_widgets), |
264 | .dapm_routes = cs4349_routes, | 264 | .dapm_routes = cs4349_routes, |
265 | .num_dapm_routes = ARRAY_SIZE(cs4349_routes), | 265 | .num_dapm_routes = ARRAY_SIZE(cs4349_routes), |
266 | }, | ||
266 | }; | 267 | }; |
267 | 268 | ||
268 | static const struct regmap_config cs4349_regmap = { | 269 | static const struct regmap_config cs4349_regmap = { |
diff --git a/sound/soc/codecs/cs47l24.c b/sound/soc/codecs/cs47l24.c index 954a4f5d3338..5b22564f037c 100644 --- a/sound/soc/codecs/cs47l24.c +++ b/sound/soc/codecs/cs47l24.c | |||
@@ -746,6 +746,16 @@ static const struct snd_soc_dapm_route cs47l24_dapm_routes[] = { | |||
746 | { "IN2L", NULL, "SYSCLK" }, | 746 | { "IN2L", NULL, "SYSCLK" }, |
747 | { "IN2R", NULL, "SYSCLK" }, | 747 | { "IN2R", NULL, "SYSCLK" }, |
748 | 748 | ||
749 | { "ASRC1L", NULL, "SYSCLK" }, | ||
750 | { "ASRC1R", NULL, "SYSCLK" }, | ||
751 | { "ASRC2L", NULL, "SYSCLK" }, | ||
752 | { "ASRC2R", NULL, "SYSCLK" }, | ||
753 | |||
754 | { "ASRC1L", NULL, "ASYNCCLK" }, | ||
755 | { "ASRC1R", NULL, "ASYNCCLK" }, | ||
756 | { "ASRC2L", NULL, "ASYNCCLK" }, | ||
757 | { "ASRC2R", NULL, "ASYNCCLK" }, | ||
758 | |||
749 | { "MICBIAS1", NULL, "MICVDD" }, | 759 | { "MICBIAS1", NULL, "MICVDD" }, |
750 | { "MICBIAS2", NULL, "MICVDD" }, | 760 | { "MICBIAS2", NULL, "MICVDD" }, |
751 | 761 | ||
@@ -804,7 +814,6 @@ static const struct snd_soc_dapm_route cs47l24_dapm_routes[] = { | |||
804 | { "AIF3 Capture", NULL, "SYSCLK" }, | 814 | { "AIF3 Capture", NULL, "SYSCLK" }, |
805 | 815 | ||
806 | { "Voice Control DSP", NULL, "DSP3" }, | 816 | { "Voice Control DSP", NULL, "DSP3" }, |
807 | { "Voice Control DSP", NULL, "SYSCLK" }, | ||
808 | 817 | ||
809 | { "IN1L PGA", NULL, "IN1L" }, | 818 | { "IN1L PGA", NULL, "IN1L" }, |
810 | { "IN1R PGA", NULL, "IN1R" }, | 819 | { "IN1R PGA", NULL, "IN1R" }, |
@@ -813,7 +822,6 @@ static const struct snd_soc_dapm_route cs47l24_dapm_routes[] = { | |||
813 | { "IN2R PGA", NULL, "IN2R" }, | 822 | { "IN2R PGA", NULL, "IN2R" }, |
814 | 823 | ||
815 | { "Audio Trace DSP", NULL, "DSP2" }, | 824 | { "Audio Trace DSP", NULL, "DSP2" }, |
816 | { "Audio Trace DSP", NULL, "SYSCLK" }, | ||
817 | 825 | ||
818 | ARIZONA_MIXER_ROUTES("OUT1L", "HPOUT1L"), | 826 | ARIZONA_MIXER_ROUTES("OUT1L", "HPOUT1L"), |
819 | ARIZONA_MIXER_ROUTES("OUT1R", "HPOUT1R"), | 827 | ARIZONA_MIXER_ROUTES("OUT1R", "HPOUT1R"), |
@@ -1190,12 +1198,14 @@ static struct snd_soc_codec_driver soc_codec_dev_cs47l24 = { | |||
1190 | .set_sysclk = arizona_set_sysclk, | 1198 | .set_sysclk = arizona_set_sysclk, |
1191 | .set_pll = cs47l24_set_fll, | 1199 | .set_pll = cs47l24_set_fll, |
1192 | 1200 | ||
1193 | .controls = cs47l24_snd_controls, | 1201 | .component_driver = { |
1194 | .num_controls = ARRAY_SIZE(cs47l24_snd_controls), | 1202 | .controls = cs47l24_snd_controls, |
1195 | .dapm_widgets = cs47l24_dapm_widgets, | 1203 | .num_controls = ARRAY_SIZE(cs47l24_snd_controls), |
1196 | .num_dapm_widgets = ARRAY_SIZE(cs47l24_dapm_widgets), | 1204 | .dapm_widgets = cs47l24_dapm_widgets, |
1197 | .dapm_routes = cs47l24_dapm_routes, | 1205 | .num_dapm_widgets = ARRAY_SIZE(cs47l24_dapm_widgets), |
1198 | .num_dapm_routes = ARRAY_SIZE(cs47l24_dapm_routes), | 1206 | .dapm_routes = cs47l24_dapm_routes, |
1207 | .num_dapm_routes = ARRAY_SIZE(cs47l24_dapm_routes), | ||
1208 | }, | ||
1199 | }; | 1209 | }; |
1200 | 1210 | ||
1201 | static struct snd_compr_ops cs47l24_compr_ops = { | 1211 | static struct snd_compr_ops cs47l24_compr_ops = { |
diff --git a/sound/soc/codecs/cs53l30.c b/sound/soc/codecs/cs53l30.c index 2c0d9c430a8c..cb47fb595ff4 100644 --- a/sound/soc/codecs/cs53l30.c +++ b/sound/soc/codecs/cs53l30.c | |||
@@ -466,7 +466,7 @@ struct cs53l30_mclk_div { | |||
466 | u8 mclk_int_scale; | 466 | u8 mclk_int_scale; |
467 | }; | 467 | }; |
468 | 468 | ||
469 | static struct cs53l30_mclk_div cs53l30_mclk_coeffs[] = { | 469 | static const struct cs53l30_mclk_div cs53l30_mclk_coeffs[] = { |
470 | /* NOTE: Enable MCLK_INT_SCALE to save power. */ | 470 | /* NOTE: Enable MCLK_INT_SCALE to save power. */ |
471 | 471 | ||
472 | /* MCLK, Sample Rate, asp_rate, internal_fs_ratio, mclk_int_scale */ | 472 | /* MCLK, Sample Rate, asp_rate, internal_fs_ratio, mclk_int_scale */ |
@@ -511,7 +511,7 @@ struct cs53l30_mclkx_div { | |||
511 | u8 mclkdiv; | 511 | u8 mclkdiv; |
512 | }; | 512 | }; |
513 | 513 | ||
514 | static struct cs53l30_mclkx_div cs53l30_mclkx_coeffs[] = { | 514 | static const struct cs53l30_mclkx_div cs53l30_mclkx_coeffs[] = { |
515 | {5644800, 1, CS53L30_MCLK_DIV_BY_1}, | 515 | {5644800, 1, CS53L30_MCLK_DIV_BY_1}, |
516 | {6000000, 1, CS53L30_MCLK_DIV_BY_1}, | 516 | {6000000, 1, CS53L30_MCLK_DIV_BY_1}, |
517 | {6144000, 1, CS53L30_MCLK_DIV_BY_1}, | 517 | {6144000, 1, CS53L30_MCLK_DIV_BY_1}, |
@@ -897,13 +897,14 @@ static struct snd_soc_codec_driver cs53l30_driver = { | |||
897 | .set_bias_level = cs53l30_set_bias_level, | 897 | .set_bias_level = cs53l30_set_bias_level, |
898 | .idle_bias_off = true, | 898 | .idle_bias_off = true, |
899 | 899 | ||
900 | .dapm_widgets = cs53l30_dapm_widgets, | 900 | .component_driver = { |
901 | .num_dapm_widgets = ARRAY_SIZE(cs53l30_dapm_widgets), | 901 | .controls = cs53l30_snd_controls, |
902 | .dapm_routes = cs53l30_dapm_routes, | 902 | .num_controls = ARRAY_SIZE(cs53l30_snd_controls), |
903 | .num_dapm_routes = ARRAY_SIZE(cs53l30_dapm_routes), | 903 | .dapm_widgets = cs53l30_dapm_widgets, |
904 | 904 | .num_dapm_widgets = ARRAY_SIZE(cs53l30_dapm_widgets), | |
905 | .controls = cs53l30_snd_controls, | 905 | .dapm_routes = cs53l30_dapm_routes, |
906 | .num_controls = ARRAY_SIZE(cs53l30_snd_controls), | 906 | .num_dapm_routes = ARRAY_SIZE(cs53l30_dapm_routes), |
907 | }, | ||
907 | }; | 908 | }; |
908 | 909 | ||
909 | static struct regmap_config cs53l30_regmap = { | 910 | static struct regmap_config cs53l30_regmap = { |
@@ -999,8 +1000,8 @@ static int cs53l30_i2c_probe(struct i2c_client *client, | |||
999 | /* Check if MCLK provided */ | 1000 | /* Check if MCLK provided */ |
1000 | cs53l30->mclk = devm_clk_get(dev, "mclk"); | 1001 | cs53l30->mclk = devm_clk_get(dev, "mclk"); |
1001 | if (IS_ERR(cs53l30->mclk)) { | 1002 | if (IS_ERR(cs53l30->mclk)) { |
1002 | if (PTR_ERR(cs53l30->mclk) == -EPROBE_DEFER) { | 1003 | if (PTR_ERR(cs53l30->mclk) != -ENOENT) { |
1003 | ret = -EPROBE_DEFER; | 1004 | ret = PTR_ERR(cs53l30->mclk); |
1004 | goto error; | 1005 | goto error; |
1005 | } | 1006 | } |
1006 | /* Otherwise mark the mclk pointer to NULL */ | 1007 | /* Otherwise mark the mclk pointer to NULL */ |
diff --git a/sound/soc/codecs/cx20442.c b/sound/soc/codecs/cx20442.c index fb3885fe0afb..2c12471e42a6 100644 --- a/sound/soc/codecs/cx20442.c +++ b/sound/soc/codecs/cx20442.c | |||
@@ -407,10 +407,12 @@ static struct snd_soc_codec_driver cx20442_codec_dev = { | |||
407 | .reg_word_size = sizeof(u8), | 407 | .reg_word_size = sizeof(u8), |
408 | .read = cx20442_read_reg_cache, | 408 | .read = cx20442_read_reg_cache, |
409 | .write = cx20442_write, | 409 | .write = cx20442_write, |
410 | .dapm_widgets = cx20442_dapm_widgets, | 410 | .component_driver = { |
411 | .num_dapm_widgets = ARRAY_SIZE(cx20442_dapm_widgets), | 411 | .dapm_widgets = cx20442_dapm_widgets, |
412 | .dapm_routes = cx20442_audio_map, | 412 | .num_dapm_widgets = ARRAY_SIZE(cx20442_dapm_widgets), |
413 | .num_dapm_routes = ARRAY_SIZE(cx20442_audio_map), | 413 | .dapm_routes = cx20442_audio_map, |
414 | .num_dapm_routes = ARRAY_SIZE(cx20442_audio_map), | ||
415 | }, | ||
414 | }; | 416 | }; |
415 | 417 | ||
416 | static int cx20442_platform_probe(struct platform_device *pdev) | 418 | static int cx20442_platform_probe(struct platform_device *pdev) |
diff --git a/sound/soc/codecs/da7210.c b/sound/soc/codecs/da7210.c index af23a61b7b28..17053dfc94cf 100644 --- a/sound/soc/codecs/da7210.c +++ b/sound/soc/codecs/da7210.c | |||
@@ -1167,13 +1167,14 @@ static int da7210_probe(struct snd_soc_codec *codec) | |||
1167 | static struct snd_soc_codec_driver soc_codec_dev_da7210 = { | 1167 | static struct snd_soc_codec_driver soc_codec_dev_da7210 = { |
1168 | .probe = da7210_probe, | 1168 | .probe = da7210_probe, |
1169 | 1169 | ||
1170 | .controls = da7210_snd_controls, | 1170 | .component_driver = { |
1171 | .num_controls = ARRAY_SIZE(da7210_snd_controls), | 1171 | .controls = da7210_snd_controls, |
1172 | 1172 | .num_controls = ARRAY_SIZE(da7210_snd_controls), | |
1173 | .dapm_widgets = da7210_dapm_widgets, | 1173 | .dapm_widgets = da7210_dapm_widgets, |
1174 | .num_dapm_widgets = ARRAY_SIZE(da7210_dapm_widgets), | 1174 | .num_dapm_widgets = ARRAY_SIZE(da7210_dapm_widgets), |
1175 | .dapm_routes = da7210_audio_map, | 1175 | .dapm_routes = da7210_audio_map, |
1176 | .num_dapm_routes = ARRAY_SIZE(da7210_audio_map), | 1176 | .num_dapm_routes = ARRAY_SIZE(da7210_audio_map), |
1177 | }, | ||
1177 | }; | 1178 | }; |
1178 | 1179 | ||
1179 | #if IS_ENABLED(CONFIG_I2C) | 1180 | #if IS_ENABLED(CONFIG_I2C) |
diff --git a/sound/soc/codecs/da7213.c b/sound/soc/codecs/da7213.c index bcf1834c5648..12da55882c06 100644 --- a/sound/soc/codecs/da7213.c +++ b/sound/soc/codecs/da7213.c | |||
@@ -750,11 +750,18 @@ static int da7213_dai_event(struct snd_soc_dapm_widget *w, | |||
750 | snd_soc_update_bits(codec, DA7213_PC_COUNT, | 750 | snd_soc_update_bits(codec, DA7213_PC_COUNT, |
751 | DA7213_PC_FREERUN_MASK, 0); | 751 | DA7213_PC_FREERUN_MASK, 0); |
752 | 752 | ||
753 | /* Slave mode, if SRM not enabled no need for status checks */ | 753 | /* If SRM not enabled then nothing more to do */ |
754 | pll_ctrl = snd_soc_read(codec, DA7213_PLL_CTRL); | 754 | pll_ctrl = snd_soc_read(codec, DA7213_PLL_CTRL); |
755 | if (!(pll_ctrl & DA7213_PLL_SRM_EN)) | 755 | if (!(pll_ctrl & DA7213_PLL_SRM_EN)) |
756 | return 0; | 756 | return 0; |
757 | 757 | ||
758 | /* Assist 32KHz mode PLL lock */ | ||
759 | if (pll_ctrl & DA7213_PLL_32K_MODE) { | ||
760 | snd_soc_write(codec, 0xF0, 0x8B); | ||
761 | snd_soc_write(codec, 0xF2, 0x03); | ||
762 | snd_soc_write(codec, 0xF0, 0x00); | ||
763 | } | ||
764 | |||
758 | /* Check SRM has locked */ | 765 | /* Check SRM has locked */ |
759 | do { | 766 | do { |
760 | pll_status = snd_soc_read(codec, DA7213_PLL_STATUS); | 767 | pll_status = snd_soc_read(codec, DA7213_PLL_STATUS); |
@@ -771,6 +778,14 @@ static int da7213_dai_event(struct snd_soc_dapm_widget *w, | |||
771 | 778 | ||
772 | return 0; | 779 | return 0; |
773 | case SND_SOC_DAPM_POST_PMD: | 780 | case SND_SOC_DAPM_POST_PMD: |
781 | /* Revert 32KHz PLL lock udpates if applied previously */ | ||
782 | pll_ctrl = snd_soc_read(codec, DA7213_PLL_CTRL); | ||
783 | if (pll_ctrl & DA7213_PLL_32K_MODE) { | ||
784 | snd_soc_write(codec, 0xF0, 0x8B); | ||
785 | snd_soc_write(codec, 0xF2, 0x01); | ||
786 | snd_soc_write(codec, 0xF0, 0x00); | ||
787 | } | ||
788 | |||
774 | /* PC free-running */ | 789 | /* PC free-running */ |
775 | snd_soc_update_bits(codec, DA7213_PC_COUNT, | 790 | snd_soc_update_bits(codec, DA7213_PC_COUNT, |
776 | DA7213_PC_FREERUN_MASK, | 791 | DA7213_PC_FREERUN_MASK, |
@@ -1297,10 +1312,13 @@ static int da7213_set_dai_sysclk(struct snd_soc_dai *codec_dai, | |||
1297 | 1312 | ||
1298 | switch (clk_id) { | 1313 | switch (clk_id) { |
1299 | case DA7213_CLKSRC_MCLK: | 1314 | case DA7213_CLKSRC_MCLK: |
1300 | da7213->mclk_squarer_en = false; | 1315 | snd_soc_update_bits(codec, DA7213_PLL_CTRL, |
1316 | DA7213_PLL_MCLK_SQR_EN, 0); | ||
1301 | break; | 1317 | break; |
1302 | case DA7213_CLKSRC_MCLK_SQR: | 1318 | case DA7213_CLKSRC_MCLK_SQR: |
1303 | da7213->mclk_squarer_en = true; | 1319 | snd_soc_update_bits(codec, DA7213_PLL_CTRL, |
1320 | DA7213_PLL_MCLK_SQR_EN, | ||
1321 | DA7213_PLL_MCLK_SQR_EN); | ||
1304 | break; | 1322 | break; |
1305 | default: | 1323 | default: |
1306 | dev_err(codec_dai->dev, "Unknown clock source %d\n", clk_id); | 1324 | dev_err(codec_dai->dev, "Unknown clock source %d\n", clk_id); |
@@ -1324,7 +1342,7 @@ static int da7213_set_dai_sysclk(struct snd_soc_dai *codec_dai, | |||
1324 | return 0; | 1342 | return 0; |
1325 | } | 1343 | } |
1326 | 1344 | ||
1327 | /* Supported PLL input frequencies are 5MHz - 54MHz. */ | 1345 | /* Supported PLL input frequencies are 32KHz, 5MHz - 54MHz. */ |
1328 | static int da7213_set_dai_pll(struct snd_soc_dai *codec_dai, int pll_id, | 1346 | static int da7213_set_dai_pll(struct snd_soc_dai *codec_dai, int pll_id, |
1329 | int source, unsigned int fref, unsigned int fout) | 1347 | int source, unsigned int fref, unsigned int fout) |
1330 | { | 1348 | { |
@@ -1336,22 +1354,26 @@ static int da7213_set_dai_pll(struct snd_soc_dai *codec_dai, int pll_id, | |||
1336 | u32 freq_ref; | 1354 | u32 freq_ref; |
1337 | u64 frac_div; | 1355 | u64 frac_div; |
1338 | 1356 | ||
1339 | /* Reset PLL configuration */ | ||
1340 | snd_soc_write(codec, DA7213_PLL_CTRL, 0); | ||
1341 | |||
1342 | pll_ctrl = 0; | ||
1343 | |||
1344 | /* Workout input divider based on MCLK rate */ | 1357 | /* Workout input divider based on MCLK rate */ |
1345 | if (da7213->mclk_rate == 32768) { | 1358 | if (da7213->mclk_rate == 32768) { |
1359 | if (!da7213->master) { | ||
1360 | dev_err(codec->dev, | ||
1361 | "32KHz only valid if codec is clock master\n"); | ||
1362 | return -EINVAL; | ||
1363 | } | ||
1364 | |||
1346 | /* 32KHz PLL Mode */ | 1365 | /* 32KHz PLL Mode */ |
1347 | indiv_bits = DA7213_PLL_INDIV_9_TO_18_MHZ; | 1366 | indiv_bits = DA7213_PLL_INDIV_9_TO_18_MHZ; |
1348 | indiv = DA7213_PLL_INDIV_9_TO_18_MHZ_VAL; | 1367 | indiv = DA7213_PLL_INDIV_9_TO_18_MHZ_VAL; |
1368 | source = DA7213_SYSCLK_PLL_32KHZ; | ||
1349 | freq_ref = 3750000; | 1369 | freq_ref = 3750000; |
1350 | pll_ctrl |= DA7213_PLL_32K_MODE; | 1370 | |
1351 | } else { | 1371 | } else { |
1352 | /* 5 - 54MHz MCLK */ | ||
1353 | if (da7213->mclk_rate < 5000000) { | 1372 | if (da7213->mclk_rate < 5000000) { |
1354 | goto pll_err; | 1373 | dev_err(codec->dev, |
1374 | "PLL input clock %d below valid range\n", | ||
1375 | da7213->mclk_rate); | ||
1376 | return -EINVAL; | ||
1355 | } else if (da7213->mclk_rate <= 9000000) { | 1377 | } else if (da7213->mclk_rate <= 9000000) { |
1356 | indiv_bits = DA7213_PLL_INDIV_5_TO_9_MHZ; | 1378 | indiv_bits = DA7213_PLL_INDIV_5_TO_9_MHZ; |
1357 | indiv = DA7213_PLL_INDIV_5_TO_9_MHZ_VAL; | 1379 | indiv = DA7213_PLL_INDIV_5_TO_9_MHZ_VAL; |
@@ -1365,32 +1387,44 @@ static int da7213_set_dai_pll(struct snd_soc_dai *codec_dai, int pll_id, | |||
1365 | indiv_bits = DA7213_PLL_INDIV_36_TO_54_MHZ; | 1387 | indiv_bits = DA7213_PLL_INDIV_36_TO_54_MHZ; |
1366 | indiv = DA7213_PLL_INDIV_36_TO_54_MHZ_VAL; | 1388 | indiv = DA7213_PLL_INDIV_36_TO_54_MHZ_VAL; |
1367 | } else { | 1389 | } else { |
1368 | goto pll_err; | 1390 | dev_err(codec->dev, |
1391 | "PLL input clock %d above valid range\n", | ||
1392 | da7213->mclk_rate); | ||
1393 | return -EINVAL; | ||
1369 | } | 1394 | } |
1370 | freq_ref = (da7213->mclk_rate / indiv); | 1395 | freq_ref = (da7213->mclk_rate / indiv); |
1371 | } | 1396 | } |
1372 | 1397 | ||
1373 | pll_ctrl |= indiv_bits; | 1398 | pll_ctrl = indiv_bits; |
1374 | 1399 | ||
1375 | /* PLL Bypass mode */ | 1400 | /* Configure PLL */ |
1376 | if (source == DA7213_SYSCLK_MCLK) { | 1401 | switch (source) { |
1377 | snd_soc_write(codec, DA7213_PLL_CTRL, pll_ctrl); | 1402 | case DA7213_SYSCLK_MCLK: |
1403 | snd_soc_update_bits(codec, DA7213_PLL_CTRL, | ||
1404 | DA7213_PLL_INDIV_MASK | | ||
1405 | DA7213_PLL_MODE_MASK, pll_ctrl); | ||
1378 | return 0; | 1406 | return 0; |
1379 | } | 1407 | case DA7213_SYSCLK_PLL: |
1408 | break; | ||
1409 | case DA7213_SYSCLK_PLL_SRM: | ||
1410 | pll_ctrl |= DA7213_PLL_SRM_EN; | ||
1411 | fout = DA7213_PLL_FREQ_OUT_94310400; | ||
1412 | break; | ||
1413 | case DA7213_SYSCLK_PLL_32KHZ: | ||
1414 | if (da7213->mclk_rate != 32768) { | ||
1415 | dev_err(codec->dev, | ||
1416 | "32KHz mode only valid with 32KHz MCLK\n"); | ||
1417 | return -EINVAL; | ||
1418 | } | ||
1380 | 1419 | ||
1381 | /* | 1420 | pll_ctrl |= DA7213_PLL_32K_MODE | DA7213_PLL_SRM_EN; |
1382 | * If Codec is slave and SRM enabled, | ||
1383 | * freq_out is (98304000 + 90316800)/2 = 94310400 | ||
1384 | */ | ||
1385 | if (!da7213->master && da7213->srm_en) { | ||
1386 | fout = DA7213_PLL_FREQ_OUT_94310400; | 1421 | fout = DA7213_PLL_FREQ_OUT_94310400; |
1387 | pll_ctrl |= DA7213_PLL_SRM_EN; | 1422 | break; |
1423 | default: | ||
1424 | dev_err(codec->dev, "Invalid PLL config\n"); | ||
1425 | return -EINVAL; | ||
1388 | } | 1426 | } |
1389 | 1427 | ||
1390 | /* Enable MCLK squarer if required */ | ||
1391 | if (da7213->mclk_squarer_en) | ||
1392 | pll_ctrl |= DA7213_PLL_MCLK_SQR_EN; | ||
1393 | |||
1394 | /* Calculate dividers for PLL */ | 1428 | /* Calculate dividers for PLL */ |
1395 | pll_integer = fout / freq_ref; | 1429 | pll_integer = fout / freq_ref; |
1396 | frac_div = (u64)(fout % freq_ref) * 8192ULL; | 1430 | frac_div = (u64)(fout % freq_ref) * 8192ULL; |
@@ -1405,14 +1439,19 @@ static int da7213_set_dai_pll(struct snd_soc_dai *codec_dai, int pll_id, | |||
1405 | 1439 | ||
1406 | /* Enable PLL */ | 1440 | /* Enable PLL */ |
1407 | pll_ctrl |= DA7213_PLL_EN; | 1441 | pll_ctrl |= DA7213_PLL_EN; |
1408 | snd_soc_write(codec, DA7213_PLL_CTRL, pll_ctrl); | 1442 | snd_soc_update_bits(codec, DA7213_PLL_CTRL, |
1443 | DA7213_PLL_INDIV_MASK | DA7213_PLL_MODE_MASK, | ||
1444 | pll_ctrl); | ||
1445 | |||
1446 | /* Assist 32KHz mode PLL lock */ | ||
1447 | if (source == DA7213_SYSCLK_PLL_32KHZ) { | ||
1448 | snd_soc_write(codec, 0xF0, 0x8B); | ||
1449 | snd_soc_write(codec, 0xF1, 0x03); | ||
1450 | snd_soc_write(codec, 0xF1, 0x01); | ||
1451 | snd_soc_write(codec, 0xF0, 0x00); | ||
1452 | } | ||
1409 | 1453 | ||
1410 | return 0; | 1454 | return 0; |
1411 | |||
1412 | pll_err: | ||
1413 | dev_err(codec_dai->dev, "Unsupported PLL input frequency %d\n", | ||
1414 | da7213->mclk_rate); | ||
1415 | return -EINVAL; | ||
1416 | } | 1455 | } |
1417 | 1456 | ||
1418 | /* DAI operations */ | 1457 | /* DAI operations */ |
@@ -1454,11 +1493,10 @@ static int da7213_set_bias_level(struct snd_soc_codec *codec, | |||
1454 | 1493 | ||
1455 | switch (level) { | 1494 | switch (level) { |
1456 | case SND_SOC_BIAS_ON: | 1495 | case SND_SOC_BIAS_ON: |
1457 | case SND_SOC_BIAS_PREPARE: | ||
1458 | break; | 1496 | break; |
1459 | case SND_SOC_BIAS_STANDBY: | 1497 | case SND_SOC_BIAS_PREPARE: |
1460 | if (snd_soc_codec_get_bias_level(codec) == SND_SOC_BIAS_OFF) { | 1498 | /* Enable MCLK for transition to ON state */ |
1461 | /* MCLK */ | 1499 | if (snd_soc_codec_get_bias_level(codec) == SND_SOC_BIAS_STANDBY) { |
1462 | if (da7213->mclk) { | 1500 | if (da7213->mclk) { |
1463 | ret = clk_prepare_enable(da7213->mclk); | 1501 | ret = clk_prepare_enable(da7213->mclk); |
1464 | if (ret) { | 1502 | if (ret) { |
@@ -1467,21 +1505,24 @@ static int da7213_set_bias_level(struct snd_soc_codec *codec, | |||
1467 | return ret; | 1505 | return ret; |
1468 | } | 1506 | } |
1469 | } | 1507 | } |
1470 | 1508 | } | |
1509 | break; | ||
1510 | case SND_SOC_BIAS_STANDBY: | ||
1511 | if (snd_soc_codec_get_bias_level(codec) == SND_SOC_BIAS_OFF) { | ||
1471 | /* Enable VMID reference & master bias */ | 1512 | /* Enable VMID reference & master bias */ |
1472 | snd_soc_update_bits(codec, DA7213_REFERENCES, | 1513 | snd_soc_update_bits(codec, DA7213_REFERENCES, |
1473 | DA7213_VMID_EN | DA7213_BIAS_EN, | 1514 | DA7213_VMID_EN | DA7213_BIAS_EN, |
1474 | DA7213_VMID_EN | DA7213_BIAS_EN); | 1515 | DA7213_VMID_EN | DA7213_BIAS_EN); |
1516 | } else { | ||
1517 | /* Remove MCLK */ | ||
1518 | if (da7213->mclk) | ||
1519 | clk_disable_unprepare(da7213->mclk); | ||
1475 | } | 1520 | } |
1476 | break; | 1521 | break; |
1477 | case SND_SOC_BIAS_OFF: | 1522 | case SND_SOC_BIAS_OFF: |
1478 | /* Disable VMID reference & master bias */ | 1523 | /* Disable VMID reference & master bias */ |
1479 | snd_soc_update_bits(codec, DA7213_REFERENCES, | 1524 | snd_soc_update_bits(codec, DA7213_REFERENCES, |
1480 | DA7213_VMID_EN | DA7213_BIAS_EN, 0); | 1525 | DA7213_VMID_EN | DA7213_BIAS_EN, 0); |
1481 | |||
1482 | /* MCLK */ | ||
1483 | if (da7213->mclk) | ||
1484 | clk_disable_unprepare(da7213->mclk); | ||
1485 | break; | 1526 | break; |
1486 | } | 1527 | } |
1487 | return 0; | 1528 | return 0; |
@@ -1605,9 +1646,6 @@ static int da7213_probe(struct snd_soc_codec *codec) | |||
1605 | DA7213_ALC_CALIB_MODE_MAN, 0); | 1646 | DA7213_ALC_CALIB_MODE_MAN, 0); |
1606 | da7213->alc_calib_auto = true; | 1647 | da7213->alc_calib_auto = true; |
1607 | 1648 | ||
1608 | /* Default to using SRM for slave mode */ | ||
1609 | da7213->srm_en = true; | ||
1610 | |||
1611 | /* Default PC counter to free-running */ | 1649 | /* Default PC counter to free-running */ |
1612 | snd_soc_update_bits(codec, DA7213_PC_COUNT, DA7213_PC_FREERUN_MASK, | 1650 | snd_soc_update_bits(codec, DA7213_PC_COUNT, DA7213_PC_FREERUN_MASK, |
1613 | DA7213_PC_FREERUN_MASK); | 1651 | DA7213_PC_FREERUN_MASK); |
@@ -1740,13 +1778,14 @@ static struct snd_soc_codec_driver soc_codec_dev_da7213 = { | |||
1740 | .probe = da7213_probe, | 1778 | .probe = da7213_probe, |
1741 | .set_bias_level = da7213_set_bias_level, | 1779 | .set_bias_level = da7213_set_bias_level, |
1742 | 1780 | ||
1743 | .controls = da7213_snd_controls, | 1781 | .component_driver = { |
1744 | .num_controls = ARRAY_SIZE(da7213_snd_controls), | 1782 | .controls = da7213_snd_controls, |
1745 | 1783 | .num_controls = ARRAY_SIZE(da7213_snd_controls), | |
1746 | .dapm_widgets = da7213_dapm_widgets, | 1784 | .dapm_widgets = da7213_dapm_widgets, |
1747 | .num_dapm_widgets = ARRAY_SIZE(da7213_dapm_widgets), | 1785 | .num_dapm_widgets = ARRAY_SIZE(da7213_dapm_widgets), |
1748 | .dapm_routes = da7213_audio_map, | 1786 | .dapm_routes = da7213_audio_map, |
1749 | .num_dapm_routes = ARRAY_SIZE(da7213_audio_map), | 1787 | .num_dapm_routes = ARRAY_SIZE(da7213_audio_map), |
1788 | }, | ||
1750 | }; | 1789 | }; |
1751 | 1790 | ||
1752 | static const struct regmap_config da7213_regmap_config = { | 1791 | static const struct regmap_config da7213_regmap_config = { |
diff --git a/sound/soc/codecs/da7213.h b/sound/soc/codecs/da7213.h index fbb7a356a501..16ef56f77cd4 100644 --- a/sound/soc/codecs/da7213.h +++ b/sound/soc/codecs/da7213.h | |||
@@ -172,6 +172,7 @@ | |||
172 | #define DA7213_PLL_32K_MODE (0x1 << 5) | 172 | #define DA7213_PLL_32K_MODE (0x1 << 5) |
173 | #define DA7213_PLL_SRM_EN (0x1 << 6) | 173 | #define DA7213_PLL_SRM_EN (0x1 << 6) |
174 | #define DA7213_PLL_EN (0x1 << 7) | 174 | #define DA7213_PLL_EN (0x1 << 7) |
175 | #define DA7213_PLL_MODE_MASK (0x7 << 5) | ||
175 | 176 | ||
176 | /* DA7213_DAI_CLK_MODE = 0x28 */ | 177 | /* DA7213_DAI_CLK_MODE = 0x28 */ |
177 | #define DA7213_DAI_BCLKS_PER_WCLK_32 (0x0 << 0) | 178 | #define DA7213_DAI_BCLKS_PER_WCLK_32 (0x0 << 0) |
@@ -499,8 +500,6 @@ | |||
499 | #define DA7213_ALC_AVG_ITERATIONS 5 | 500 | #define DA7213_ALC_AVG_ITERATIONS 5 |
500 | 501 | ||
501 | /* PLL related */ | 502 | /* PLL related */ |
502 | #define DA7213_SYSCLK_MCLK 0 | ||
503 | #define DA7213_SYSCLK_PLL 1 | ||
504 | #define DA7213_PLL_FREQ_OUT_90316800 90316800 | 503 | #define DA7213_PLL_FREQ_OUT_90316800 90316800 |
505 | #define DA7213_PLL_FREQ_OUT_98304000 98304000 | 504 | #define DA7213_PLL_FREQ_OUT_98304000 98304000 |
506 | #define DA7213_PLL_FREQ_OUT_94310400 94310400 | 505 | #define DA7213_PLL_FREQ_OUT_94310400 94310400 |
@@ -515,6 +514,13 @@ enum da7213_clk_src { | |||
515 | DA7213_CLKSRC_MCLK_SQR, | 514 | DA7213_CLKSRC_MCLK_SQR, |
516 | }; | 515 | }; |
517 | 516 | ||
517 | enum da7213_sys_clk { | ||
518 | DA7213_SYSCLK_MCLK = 0, | ||
519 | DA7213_SYSCLK_PLL, | ||
520 | DA7213_SYSCLK_PLL_SRM, | ||
521 | DA7213_SYSCLK_PLL_32KHZ | ||
522 | }; | ||
523 | |||
518 | /* Codec private data */ | 524 | /* Codec private data */ |
519 | struct da7213_priv { | 525 | struct da7213_priv { |
520 | struct regmap *regmap; | 526 | struct regmap *regmap; |
@@ -522,8 +528,6 @@ struct da7213_priv { | |||
522 | unsigned int mclk_rate; | 528 | unsigned int mclk_rate; |
523 | int clk_src; | 529 | int clk_src; |
524 | bool master; | 530 | bool master; |
525 | bool mclk_squarer_en; | ||
526 | bool srm_en; | ||
527 | bool alc_calib_auto; | 531 | bool alc_calib_auto; |
528 | bool alc_en; | 532 | bool alc_en; |
529 | struct da7213_platform_data *pdata; | 533 | struct da7213_platform_data *pdata; |
diff --git a/sound/soc/codecs/da7218.c b/sound/soc/codecs/da7218.c index 99ce23e113bf..c69e97654fc6 100644 --- a/sound/soc/codecs/da7218.c +++ b/sound/soc/codecs/da7218.c | |||
@@ -1819,7 +1819,7 @@ static int da7218_set_dai_sysclk(struct snd_soc_dai *codec_dai, | |||
1819 | if (da7218->mclk_rate == freq) | 1819 | if (da7218->mclk_rate == freq) |
1820 | return 0; | 1820 | return 0; |
1821 | 1821 | ||
1822 | if (((freq < 2000000) && (freq != 32768)) || (freq > 54000000)) { | 1822 | if ((freq < 2000000) || (freq > 54000000)) { |
1823 | dev_err(codec_dai->dev, "Unsupported MCLK value %d\n", | 1823 | dev_err(codec_dai->dev, "Unsupported MCLK value %d\n", |
1824 | freq); | 1824 | freq); |
1825 | return -EINVAL; | 1825 | return -EINVAL; |
@@ -1866,11 +1866,8 @@ static int da7218_set_dai_pll(struct snd_soc_dai *codec_dai, int pll_id, | |||
1866 | u32 freq_ref; | 1866 | u32 freq_ref; |
1867 | u64 frac_div; | 1867 | u64 frac_div; |
1868 | 1868 | ||
1869 | /* Verify 32KHz, 2MHz - 54MHz MCLK provided, and set input divider */ | 1869 | /* Verify 2MHz - 54MHz MCLK provided, and set input divider */ |
1870 | if (da7218->mclk_rate == 32768) { | 1870 | if (da7218->mclk_rate < 2000000) { |
1871 | indiv_bits = DA7218_PLL_INDIV_9_TO_18_MHZ; | ||
1872 | indiv = DA7218_PLL_INDIV_9_TO_18_MHZ_VAL; | ||
1873 | } else if (da7218->mclk_rate < 2000000) { | ||
1874 | dev_err(codec->dev, "PLL input clock %d below valid range\n", | 1871 | dev_err(codec->dev, "PLL input clock %d below valid range\n", |
1875 | da7218->mclk_rate); | 1872 | da7218->mclk_rate); |
1876 | return -EINVAL; | 1873 | return -EINVAL; |
@@ -1911,9 +1908,6 @@ static int da7218_set_dai_pll(struct snd_soc_dai *codec_dai, int pll_id, | |||
1911 | case DA7218_SYSCLK_PLL_SRM: | 1908 | case DA7218_SYSCLK_PLL_SRM: |
1912 | pll_ctrl |= DA7218_PLL_MODE_SRM; | 1909 | pll_ctrl |= DA7218_PLL_MODE_SRM; |
1913 | break; | 1910 | break; |
1914 | case DA7218_SYSCLK_PLL_32KHZ: | ||
1915 | pll_ctrl |= DA7218_PLL_MODE_32KHZ; | ||
1916 | break; | ||
1917 | default: | 1911 | default: |
1918 | dev_err(codec->dev, "Invalid PLL config\n"); | 1912 | dev_err(codec->dev, "Invalid PLL config\n"); |
1919 | return -EINVAL; | 1913 | return -EINVAL; |
@@ -2589,20 +2583,22 @@ static int da7218_set_bias_level(struct snd_soc_codec *codec, | |||
2589 | 2583 | ||
2590 | switch (level) { | 2584 | switch (level) { |
2591 | case SND_SOC_BIAS_ON: | 2585 | case SND_SOC_BIAS_ON: |
2592 | case SND_SOC_BIAS_PREPARE: | ||
2593 | break; | 2586 | break; |
2594 | case SND_SOC_BIAS_STANDBY: | 2587 | case SND_SOC_BIAS_PREPARE: |
2595 | if (snd_soc_codec_get_bias_level(codec) == SND_SOC_BIAS_OFF) { | 2588 | /* Enable MCLK for transition to ON state */ |
2596 | /* MCLK */ | 2589 | if (snd_soc_codec_get_bias_level(codec) == SND_SOC_BIAS_STANDBY) { |
2597 | if (da7218->mclk) { | 2590 | if (da7218->mclk) { |
2598 | ret = clk_prepare_enable(da7218->mclk); | 2591 | ret = clk_prepare_enable(da7218->mclk); |
2599 | if (ret) { | 2592 | if (ret) { |
2600 | dev_err(codec->dev, | 2593 | dev_err(codec->dev, "Failed to enable mclk\n"); |
2601 | "Failed to enable mclk\n"); | ||
2602 | return ret; | 2594 | return ret; |
2603 | } | 2595 | } |
2604 | } | 2596 | } |
2597 | } | ||
2605 | 2598 | ||
2599 | break; | ||
2600 | case SND_SOC_BIAS_STANDBY: | ||
2601 | if (snd_soc_codec_get_bias_level(codec) == SND_SOC_BIAS_OFF) { | ||
2606 | /* Master bias */ | 2602 | /* Master bias */ |
2607 | snd_soc_update_bits(codec, DA7218_REFERENCES, | 2603 | snd_soc_update_bits(codec, DA7218_REFERENCES, |
2608 | DA7218_BIAS_EN_MASK, | 2604 | DA7218_BIAS_EN_MASK, |
@@ -2612,6 +2608,10 @@ static int da7218_set_bias_level(struct snd_soc_codec *codec, | |||
2612 | snd_soc_update_bits(codec, DA7218_LDO_CTRL, | 2608 | snd_soc_update_bits(codec, DA7218_LDO_CTRL, |
2613 | DA7218_LDO_EN_MASK, | 2609 | DA7218_LDO_EN_MASK, |
2614 | DA7218_LDO_EN_MASK); | 2610 | DA7218_LDO_EN_MASK); |
2611 | } else { | ||
2612 | /* Remove MCLK */ | ||
2613 | if (da7218->mclk) | ||
2614 | clk_disable_unprepare(da7218->mclk); | ||
2615 | } | 2615 | } |
2616 | break; | 2616 | break; |
2617 | case SND_SOC_BIAS_OFF: | 2617 | case SND_SOC_BIAS_OFF: |
@@ -2625,10 +2625,6 @@ static int da7218_set_bias_level(struct snd_soc_codec *codec, | |||
2625 | snd_soc_update_bits(codec, DA7218_REFERENCES, | 2625 | snd_soc_update_bits(codec, DA7218_REFERENCES, |
2626 | DA7218_BIAS_EN_MASK, 0); | 2626 | DA7218_BIAS_EN_MASK, 0); |
2627 | } | 2627 | } |
2628 | |||
2629 | /* MCLK */ | ||
2630 | if (da7218->mclk) | ||
2631 | clk_disable_unprepare(da7218->mclk); | ||
2632 | break; | 2628 | break; |
2633 | } | 2629 | } |
2634 | 2630 | ||
@@ -3045,13 +3041,14 @@ static struct snd_soc_codec_driver soc_codec_dev_da7218 = { | |||
3045 | .resume = da7218_resume, | 3041 | .resume = da7218_resume, |
3046 | .set_bias_level = da7218_set_bias_level, | 3042 | .set_bias_level = da7218_set_bias_level, |
3047 | 3043 | ||
3048 | .controls = da7218_snd_controls, | 3044 | .component_driver = { |
3049 | .num_controls = ARRAY_SIZE(da7218_snd_controls), | 3045 | .controls = da7218_snd_controls, |
3050 | 3046 | .num_controls = ARRAY_SIZE(da7218_snd_controls), | |
3051 | .dapm_widgets = da7218_dapm_widgets, | 3047 | .dapm_widgets = da7218_dapm_widgets, |
3052 | .num_dapm_widgets = ARRAY_SIZE(da7218_dapm_widgets), | 3048 | .num_dapm_widgets = ARRAY_SIZE(da7218_dapm_widgets), |
3053 | .dapm_routes = da7218_audio_map, | 3049 | .dapm_routes = da7218_audio_map, |
3054 | .num_dapm_routes = ARRAY_SIZE(da7218_audio_map), | 3050 | .num_dapm_routes = ARRAY_SIZE(da7218_audio_map), |
3051 | }, | ||
3055 | }; | 3052 | }; |
3056 | 3053 | ||
3057 | 3054 | ||
diff --git a/sound/soc/codecs/da7218.h b/sound/soc/codecs/da7218.h index 477cd37723cf..4f7ec21069a4 100644 --- a/sound/soc/codecs/da7218.h +++ b/sound/soc/codecs/da7218.h | |||
@@ -888,7 +888,6 @@ | |||
888 | #define DA7218_PLL_MODE_BYPASS (0x0 << 6) | 888 | #define DA7218_PLL_MODE_BYPASS (0x0 << 6) |
889 | #define DA7218_PLL_MODE_NORMAL (0x1 << 6) | 889 | #define DA7218_PLL_MODE_NORMAL (0x1 << 6) |
890 | #define DA7218_PLL_MODE_SRM (0x2 << 6) | 890 | #define DA7218_PLL_MODE_SRM (0x2 << 6) |
891 | #define DA7218_PLL_MODE_32KHZ (0x3 << 6) | ||
892 | 891 | ||
893 | /* DA7218_PLL_FRAC_TOP = 0x92 */ | 892 | /* DA7218_PLL_FRAC_TOP = 0x92 */ |
894 | #define DA7218_PLL_FBDIV_FRAC_TOP_SHIFT 0 | 893 | #define DA7218_PLL_FBDIV_FRAC_TOP_SHIFT 0 |
@@ -1371,7 +1370,6 @@ enum da7218_sys_clk { | |||
1371 | DA7218_SYSCLK_MCLK = 0, | 1370 | DA7218_SYSCLK_MCLK = 0, |
1372 | DA7218_SYSCLK_PLL, | 1371 | DA7218_SYSCLK_PLL, |
1373 | DA7218_SYSCLK_PLL_SRM, | 1372 | DA7218_SYSCLK_PLL_SRM, |
1374 | DA7218_SYSCLK_PLL_32KHZ | ||
1375 | }; | 1373 | }; |
1376 | 1374 | ||
1377 | enum da7218_dev_id { | 1375 | enum da7218_dev_id { |
diff --git a/sound/soc/codecs/da7219-aad.c b/sound/soc/codecs/da7219-aad.c index f0057cd223a4..2b8914dd5990 100644 --- a/sound/soc/codecs/da7219-aad.c +++ b/sound/soc/codecs/da7219-aad.c | |||
@@ -13,6 +13,7 @@ | |||
13 | 13 | ||
14 | #include <linux/module.h> | 14 | #include <linux/module.h> |
15 | #include <linux/platform_device.h> | 15 | #include <linux/platform_device.h> |
16 | #include <linux/clk.h> | ||
16 | #include <linux/i2c.h> | 17 | #include <linux/i2c.h> |
17 | #include <linux/property.h> | 18 | #include <linux/property.h> |
18 | #include <linux/pm_wakeirq.h> | 19 | #include <linux/pm_wakeirq.h> |
@@ -114,13 +115,38 @@ static void da7219_aad_hptest_work(struct work_struct *work) | |||
114 | struct da7219_priv *da7219 = snd_soc_codec_get_drvdata(codec); | 115 | struct da7219_priv *da7219 = snd_soc_codec_get_drvdata(codec); |
115 | 116 | ||
116 | u16 tonegen_freq_hptest; | 117 | u16 tonegen_freq_hptest; |
117 | u8 accdet_cfg8; | 118 | u8 pll_srm_sts, gain_ramp_ctrl, accdet_cfg8; |
118 | int report = 0; | 119 | int report = 0, ret = 0; |
119 | 120 | ||
120 | /* Lock DAPM and any Kcontrols that are affected by this test */ | 121 | /* Lock DAPM and any Kcontrols that are affected by this test */ |
121 | snd_soc_dapm_mutex_lock(dapm); | 122 | snd_soc_dapm_mutex_lock(dapm); |
122 | mutex_lock(&da7219->lock); | 123 | mutex_lock(&da7219->lock); |
123 | 124 | ||
125 | /* Ensure MCLK is available for HP test procedure */ | ||
126 | if (da7219->mclk) { | ||
127 | ret = clk_prepare_enable(da7219->mclk); | ||
128 | if (ret) { | ||
129 | dev_err(codec->dev, "Failed to enable mclk - %d\n", ret); | ||
130 | mutex_unlock(&da7219->lock); | ||
131 | snd_soc_dapm_mutex_unlock(dapm); | ||
132 | return; | ||
133 | } | ||
134 | } | ||
135 | |||
136 | /* | ||
137 | * If MCLK not present, then we're using the internal oscillator and | ||
138 | * require different frequency settings to achieve the same result. | ||
139 | */ | ||
140 | pll_srm_sts = snd_soc_read(codec, DA7219_PLL_SRM_STS); | ||
141 | if (pll_srm_sts & DA7219_PLL_SRM_STS_MCLK) | ||
142 | tonegen_freq_hptest = cpu_to_le16(DA7219_AAD_HPTEST_RAMP_FREQ); | ||
143 | else | ||
144 | tonegen_freq_hptest = cpu_to_le16(DA7219_AAD_HPTEST_RAMP_FREQ_INT_OSC); | ||
145 | |||
146 | /* Ensure gain ramping at fastest rate */ | ||
147 | gain_ramp_ctrl = snd_soc_read(codec, DA7219_GAIN_RAMP_CTRL); | ||
148 | snd_soc_write(codec, DA7219_GAIN_RAMP_CTRL, DA7219_GAIN_RAMP_RATE_X8); | ||
149 | |||
124 | /* Bypass cache so it saves current settings */ | 150 | /* Bypass cache so it saves current settings */ |
125 | regcache_cache_bypass(da7219->regmap, true); | 151 | regcache_cache_bypass(da7219->regmap, true); |
126 | 152 | ||
@@ -183,9 +209,15 @@ static void da7219_aad_hptest_work(struct work_struct *work) | |||
183 | snd_soc_write(codec, DA7219_HP_R_CTRL, | 209 | snd_soc_write(codec, DA7219_HP_R_CTRL, |
184 | DA7219_HP_R_AMP_OE_MASK | DA7219_HP_R_AMP_EN_MASK); | 210 | DA7219_HP_R_AMP_OE_MASK | DA7219_HP_R_AMP_EN_MASK); |
185 | 211 | ||
212 | /* | ||
213 | * If we're running from the internal oscillator then give audio paths | ||
214 | * time to settle before running test. | ||
215 | */ | ||
216 | if (!(pll_srm_sts & DA7219_PLL_SRM_STS_MCLK)) | ||
217 | msleep(DA7219_AAD_HPTEST_INT_OSC_PATH_DELAY); | ||
218 | |||
186 | /* Configure & start Tone Generator */ | 219 | /* Configure & start Tone Generator */ |
187 | snd_soc_write(codec, DA7219_TONE_GEN_ON_PER, DA7219_BEEP_ON_PER_MASK); | 220 | snd_soc_write(codec, DA7219_TONE_GEN_ON_PER, DA7219_BEEP_ON_PER_MASK); |
188 | tonegen_freq_hptest = cpu_to_le16(DA7219_AAD_HPTEST_RAMP_FREQ); | ||
189 | regmap_raw_write(da7219->regmap, DA7219_TONE_GEN_FREQ1_L, | 221 | regmap_raw_write(da7219->regmap, DA7219_TONE_GEN_FREQ1_L, |
190 | &tonegen_freq_hptest, sizeof(tonegen_freq_hptest)); | 222 | &tonegen_freq_hptest, sizeof(tonegen_freq_hptest)); |
191 | snd_soc_update_bits(codec, DA7219_TONE_GEN_CFG2, | 223 | snd_soc_update_bits(codec, DA7219_TONE_GEN_CFG2, |
@@ -244,12 +276,26 @@ static void da7219_aad_hptest_work(struct work_struct *work) | |||
244 | snd_soc_update_bits(codec, DA7219_ACCDET_CONFIG_8, | 276 | snd_soc_update_bits(codec, DA7219_ACCDET_CONFIG_8, |
245 | DA7219_HPTEST_EN_MASK, 0); | 277 | DA7219_HPTEST_EN_MASK, 0); |
246 | 278 | ||
279 | /* | ||
280 | * If we're running from the internal oscillator then give audio paths | ||
281 | * time to settle before allowing headphones to be driven as required. | ||
282 | */ | ||
283 | if (!(pll_srm_sts & DA7219_PLL_SRM_STS_MCLK)) | ||
284 | msleep(DA7219_AAD_HPTEST_INT_OSC_PATH_DELAY); | ||
285 | |||
286 | /* Restore gain ramping rate */ | ||
287 | snd_soc_write(codec, DA7219_GAIN_RAMP_CTRL, gain_ramp_ctrl); | ||
288 | |||
247 | /* Drive Headphones/lineout */ | 289 | /* Drive Headphones/lineout */ |
248 | snd_soc_update_bits(codec, DA7219_HP_L_CTRL, DA7219_HP_L_AMP_OE_MASK, | 290 | snd_soc_update_bits(codec, DA7219_HP_L_CTRL, DA7219_HP_L_AMP_OE_MASK, |
249 | DA7219_HP_L_AMP_OE_MASK); | 291 | DA7219_HP_L_AMP_OE_MASK); |
250 | snd_soc_update_bits(codec, DA7219_HP_R_CTRL, DA7219_HP_R_AMP_OE_MASK, | 292 | snd_soc_update_bits(codec, DA7219_HP_R_CTRL, DA7219_HP_R_AMP_OE_MASK, |
251 | DA7219_HP_R_AMP_OE_MASK); | 293 | DA7219_HP_R_AMP_OE_MASK); |
252 | 294 | ||
295 | /* Remove MCLK, if previously enabled */ | ||
296 | if (da7219->mclk) | ||
297 | clk_disable_unprepare(da7219->mclk); | ||
298 | |||
253 | mutex_unlock(&da7219->lock); | 299 | mutex_unlock(&da7219->lock); |
254 | snd_soc_dapm_mutex_unlock(dapm); | 300 | snd_soc_dapm_mutex_unlock(dapm); |
255 | 301 | ||
@@ -751,6 +797,62 @@ static void da7219_aad_handle_pdata(struct snd_soc_codec *codec) | |||
751 | 797 | ||
752 | 798 | ||
753 | /* | 799 | /* |
800 | * Suspend/Resume | ||
801 | */ | ||
802 | |||
803 | void da7219_aad_suspend(struct snd_soc_codec *codec) | ||
804 | { | ||
805 | struct da7219_priv *da7219 = snd_soc_codec_get_drvdata(codec); | ||
806 | struct da7219_aad_priv *da7219_aad = da7219->aad; | ||
807 | struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec); | ||
808 | u8 micbias_ctrl; | ||
809 | |||
810 | if (da7219_aad->jack) { | ||
811 | /* Disable jack detection during suspend */ | ||
812 | snd_soc_update_bits(codec, DA7219_ACCDET_CONFIG_1, | ||
813 | DA7219_ACCDET_EN_MASK, 0); | ||
814 | |||
815 | /* | ||
816 | * If we have a 4-pole jack inserted, then micbias will be | ||
817 | * enabled. We can disable micbias here, and keep a note to | ||
818 | * re-enable it on resume. If jack removal occurred during | ||
819 | * suspend then this will be dealt with through the IRQ handler. | ||
820 | */ | ||
821 | if (da7219_aad->jack_inserted) { | ||
822 | micbias_ctrl = snd_soc_read(codec, DA7219_MICBIAS_CTRL); | ||
823 | if (micbias_ctrl & DA7219_MICBIAS1_EN_MASK) { | ||
824 | snd_soc_dapm_disable_pin(dapm, "Mic Bias"); | ||
825 | snd_soc_dapm_sync(dapm); | ||
826 | da7219_aad->micbias_resume_enable = true; | ||
827 | } | ||
828 | } | ||
829 | } | ||
830 | } | ||
831 | |||
832 | void da7219_aad_resume(struct snd_soc_codec *codec) | ||
833 | { | ||
834 | struct da7219_priv *da7219 = snd_soc_codec_get_drvdata(codec); | ||
835 | struct da7219_aad_priv *da7219_aad = da7219->aad; | ||
836 | struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec); | ||
837 | |||
838 | if (da7219_aad->jack) { | ||
839 | /* Re-enable micbias if previously enabled for 4-pole jack */ | ||
840 | if (da7219_aad->jack_inserted && | ||
841 | da7219_aad->micbias_resume_enable) { | ||
842 | snd_soc_dapm_force_enable_pin(dapm, "Mic Bias"); | ||
843 | snd_soc_dapm_sync(dapm); | ||
844 | da7219_aad->micbias_resume_enable = false; | ||
845 | } | ||
846 | |||
847 | /* Re-enable jack detection */ | ||
848 | snd_soc_update_bits(codec, DA7219_ACCDET_CONFIG_1, | ||
849 | DA7219_ACCDET_EN_MASK, | ||
850 | DA7219_ACCDET_EN_MASK); | ||
851 | } | ||
852 | } | ||
853 | |||
854 | |||
855 | /* | ||
754 | * Init/Exit | 856 | * Init/Exit |
755 | */ | 857 | */ |
756 | 858 | ||
diff --git a/sound/soc/codecs/da7219-aad.h b/sound/soc/codecs/da7219-aad.h index 4fccf677cd06..117a3d7ccd31 100644 --- a/sound/soc/codecs/da7219-aad.h +++ b/sound/soc/codecs/da7219-aad.h | |||
@@ -176,8 +176,10 @@ | |||
176 | #define DA7219_AAD_MICBIAS_CHK_DELAY 10 | 176 | #define DA7219_AAD_MICBIAS_CHK_DELAY 10 |
177 | #define DA7219_AAD_MICBIAS_CHK_RETRIES 5 | 177 | #define DA7219_AAD_MICBIAS_CHK_RETRIES 5 |
178 | 178 | ||
179 | #define DA7219_AAD_HPTEST_RAMP_FREQ 0x28 | 179 | #define DA7219_AAD_HPTEST_RAMP_FREQ 0x28 |
180 | #define DA7219_AAD_HPTEST_PERIOD 65 | 180 | #define DA7219_AAD_HPTEST_RAMP_FREQ_INT_OSC 0x4D |
181 | #define DA7219_AAD_HPTEST_PERIOD 65 | ||
182 | #define DA7219_AAD_HPTEST_INT_OSC_PATH_DELAY 20 | ||
181 | 183 | ||
182 | enum da7219_aad_event_regs { | 184 | enum da7219_aad_event_regs { |
183 | DA7219_AAD_IRQ_REG_A = 0, | 185 | DA7219_AAD_IRQ_REG_A = 0, |
@@ -199,12 +201,17 @@ struct da7219_aad_priv { | |||
199 | struct work_struct hptest_work; | 201 | struct work_struct hptest_work; |
200 | 202 | ||
201 | struct snd_soc_jack *jack; | 203 | struct snd_soc_jack *jack; |
204 | bool micbias_resume_enable; | ||
202 | bool jack_inserted; | 205 | bool jack_inserted; |
203 | }; | 206 | }; |
204 | 207 | ||
205 | /* AAD control */ | 208 | /* AAD control */ |
206 | void da7219_aad_jack_det(struct snd_soc_codec *codec, struct snd_soc_jack *jack); | 209 | void da7219_aad_jack_det(struct snd_soc_codec *codec, struct snd_soc_jack *jack); |
207 | 210 | ||
211 | /* Suspend/Resume */ | ||
212 | void da7219_aad_suspend(struct snd_soc_codec *codec); | ||
213 | void da7219_aad_resume(struct snd_soc_codec *codec); | ||
214 | |||
208 | /* Init/Exit */ | 215 | /* Init/Exit */ |
209 | int da7219_aad_init(struct snd_soc_codec *codec); | 216 | int da7219_aad_init(struct snd_soc_codec *codec); |
210 | void da7219_aad_exit(struct snd_soc_codec *codec); | 217 | void da7219_aad_exit(struct snd_soc_codec *codec); |
diff --git a/sound/soc/codecs/da7219.c b/sound/soc/codecs/da7219.c index 50ea94317cb3..1152aa5e7c39 100644 --- a/sound/soc/codecs/da7219.c +++ b/sound/soc/codecs/da7219.c | |||
@@ -801,7 +801,7 @@ static int da7219_dai_event(struct snd_soc_dapm_widget *w, | |||
801 | ++i; | 801 | ++i; |
802 | msleep(50); | 802 | msleep(50); |
803 | } | 803 | } |
804 | } while ((i < DA7219_SRM_CHECK_RETRIES) & (!srm_lock)); | 804 | } while ((i < DA7219_SRM_CHECK_RETRIES) && (!srm_lock)); |
805 | 805 | ||
806 | if (!srm_lock) | 806 | if (!srm_lock) |
807 | dev_warn(codec->dev, "SRM failed to lock\n"); | 807 | dev_warn(codec->dev, "SRM failed to lock\n"); |
@@ -1482,6 +1482,8 @@ static struct da7219_pdata *da7219_fw_to_pdata(struct snd_soc_codec *codec) | |||
1482 | if (!pdata) | 1482 | if (!pdata) |
1483 | return NULL; | 1483 | return NULL; |
1484 | 1484 | ||
1485 | pdata->wakeup_source = device_property_read_bool(dev, "wakeup-source"); | ||
1486 | |||
1485 | if (device_property_read_u32(dev, "dlg,micbias-lvl", &of_val32) >= 0) | 1487 | if (device_property_read_u32(dev, "dlg,micbias-lvl", &of_val32) >= 0) |
1486 | pdata->micbias_lvl = da7219_fw_micbias_lvl(dev, of_val32); | 1488 | pdata->micbias_lvl = da7219_fw_micbias_lvl(dev, of_val32); |
1487 | else | 1489 | else |
@@ -1508,11 +1510,10 @@ static int da7219_set_bias_level(struct snd_soc_codec *codec, | |||
1508 | 1510 | ||
1509 | switch (level) { | 1511 | switch (level) { |
1510 | case SND_SOC_BIAS_ON: | 1512 | case SND_SOC_BIAS_ON: |
1511 | case SND_SOC_BIAS_PREPARE: | ||
1512 | break; | 1513 | break; |
1513 | case SND_SOC_BIAS_STANDBY: | 1514 | case SND_SOC_BIAS_PREPARE: |
1514 | if (snd_soc_codec_get_bias_level(codec) == SND_SOC_BIAS_OFF) { | 1515 | /* Enable MCLK for transition to ON state */ |
1515 | /* MCLK */ | 1516 | if (snd_soc_codec_get_bias_level(codec) == SND_SOC_BIAS_STANDBY) { |
1516 | if (da7219->mclk) { | 1517 | if (da7219->mclk) { |
1517 | ret = clk_prepare_enable(da7219->mclk); | 1518 | ret = clk_prepare_enable(da7219->mclk); |
1518 | if (ret) { | 1519 | if (ret) { |
@@ -1521,22 +1522,28 @@ static int da7219_set_bias_level(struct snd_soc_codec *codec, | |||
1521 | return ret; | 1522 | return ret; |
1522 | } | 1523 | } |
1523 | } | 1524 | } |
1525 | } | ||
1524 | 1526 | ||
1527 | break; | ||
1528 | case SND_SOC_BIAS_STANDBY: | ||
1529 | if (snd_soc_codec_get_bias_level(codec) == SND_SOC_BIAS_OFF) | ||
1525 | /* Master bias */ | 1530 | /* Master bias */ |
1526 | snd_soc_update_bits(codec, DA7219_REFERENCES, | 1531 | snd_soc_update_bits(codec, DA7219_REFERENCES, |
1527 | DA7219_BIAS_EN_MASK, | 1532 | DA7219_BIAS_EN_MASK, |
1528 | DA7219_BIAS_EN_MASK); | 1533 | DA7219_BIAS_EN_MASK); |
1534 | |||
1535 | if (snd_soc_codec_get_bias_level(codec) == SND_SOC_BIAS_PREPARE) { | ||
1536 | /* Remove MCLK */ | ||
1537 | if (da7219->mclk) | ||
1538 | clk_disable_unprepare(da7219->mclk); | ||
1529 | } | 1539 | } |
1530 | break; | 1540 | break; |
1531 | case SND_SOC_BIAS_OFF: | 1541 | case SND_SOC_BIAS_OFF: |
1532 | /* Only disable master bias if jack detection not active */ | 1542 | /* Only disable master bias if we're not a wake-up source */ |
1533 | if (!da7219->aad->jack) | 1543 | if (!da7219->wakeup_source) |
1534 | snd_soc_update_bits(codec, DA7219_REFERENCES, | 1544 | snd_soc_update_bits(codec, DA7219_REFERENCES, |
1535 | DA7219_BIAS_EN_MASK, 0); | 1545 | DA7219_BIAS_EN_MASK, 0); |
1536 | 1546 | ||
1537 | /* MCLK */ | ||
1538 | if (da7219->mclk) | ||
1539 | clk_disable_unprepare(da7219->mclk); | ||
1540 | break; | 1547 | break; |
1541 | } | 1548 | } |
1542 | 1549 | ||
@@ -1599,6 +1606,8 @@ static void da7219_handle_pdata(struct snd_soc_codec *codec) | |||
1599 | if (pdata) { | 1606 | if (pdata) { |
1600 | u8 micbias_lvl = 0; | 1607 | u8 micbias_lvl = 0; |
1601 | 1608 | ||
1609 | da7219->wakeup_source = pdata->wakeup_source; | ||
1610 | |||
1602 | /* Mic Bias voltages */ | 1611 | /* Mic Bias voltages */ |
1603 | switch (pdata->micbias_lvl) { | 1612 | switch (pdata->micbias_lvl) { |
1604 | case DA7219_MICBIAS_1_6V: | 1613 | case DA7219_MICBIAS_1_6V: |
@@ -1733,11 +1742,11 @@ static int da7219_suspend(struct snd_soc_codec *codec) | |||
1733 | { | 1742 | { |
1734 | struct da7219_priv *da7219 = snd_soc_codec_get_drvdata(codec); | 1743 | struct da7219_priv *da7219 = snd_soc_codec_get_drvdata(codec); |
1735 | 1744 | ||
1736 | snd_soc_codec_force_bias_level(codec, SND_SOC_BIAS_OFF); | 1745 | /* Suspend AAD if we're not a wake-up source */ |
1746 | if (!da7219->wakeup_source) | ||
1747 | da7219_aad_suspend(codec); | ||
1737 | 1748 | ||
1738 | /* Put device into standby mode if jack detection disabled */ | 1749 | snd_soc_codec_force_bias_level(codec, SND_SOC_BIAS_OFF); |
1739 | if (!da7219->aad->jack) | ||
1740 | snd_soc_write(codec, DA7219_SYSTEM_ACTIVE, 0); | ||
1741 | 1750 | ||
1742 | return 0; | 1751 | return 0; |
1743 | } | 1752 | } |
@@ -1746,13 +1755,12 @@ static int da7219_resume(struct snd_soc_codec *codec) | |||
1746 | { | 1755 | { |
1747 | struct da7219_priv *da7219 = snd_soc_codec_get_drvdata(codec); | 1756 | struct da7219_priv *da7219 = snd_soc_codec_get_drvdata(codec); |
1748 | 1757 | ||
1749 | /* Put device into active mode if previously pushed to standby */ | ||
1750 | if (!da7219->aad->jack) | ||
1751 | snd_soc_write(codec, DA7219_SYSTEM_ACTIVE, | ||
1752 | DA7219_SYSTEM_ACTIVE_MASK); | ||
1753 | |||
1754 | snd_soc_codec_force_bias_level(codec, SND_SOC_BIAS_STANDBY); | 1758 | snd_soc_codec_force_bias_level(codec, SND_SOC_BIAS_STANDBY); |
1755 | 1759 | ||
1760 | /* Resume AAD if previously suspended */ | ||
1761 | if (!da7219->wakeup_source) | ||
1762 | da7219_aad_resume(codec); | ||
1763 | |||
1756 | return 0; | 1764 | return 0; |
1757 | } | 1765 | } |
1758 | #else | 1766 | #else |
@@ -1767,13 +1775,14 @@ static struct snd_soc_codec_driver soc_codec_dev_da7219 = { | |||
1767 | .resume = da7219_resume, | 1775 | .resume = da7219_resume, |
1768 | .set_bias_level = da7219_set_bias_level, | 1776 | .set_bias_level = da7219_set_bias_level, |
1769 | 1777 | ||
1770 | .controls = da7219_snd_controls, | 1778 | .component_driver = { |
1771 | .num_controls = ARRAY_SIZE(da7219_snd_controls), | 1779 | .controls = da7219_snd_controls, |
1772 | 1780 | .num_controls = ARRAY_SIZE(da7219_snd_controls), | |
1773 | .dapm_widgets = da7219_dapm_widgets, | 1781 | .dapm_widgets = da7219_dapm_widgets, |
1774 | .num_dapm_widgets = ARRAY_SIZE(da7219_dapm_widgets), | 1782 | .num_dapm_widgets = ARRAY_SIZE(da7219_dapm_widgets), |
1775 | .dapm_routes = da7219_audio_map, | 1783 | .dapm_routes = da7219_audio_map, |
1776 | .num_dapm_routes = ARRAY_SIZE(da7219_audio_map), | 1784 | .num_dapm_routes = ARRAY_SIZE(da7219_audio_map), |
1785 | }, | ||
1777 | }; | 1786 | }; |
1778 | 1787 | ||
1779 | 1788 | ||
@@ -1921,7 +1930,8 @@ static int da7219_i2c_probe(struct i2c_client *i2c, | |||
1921 | const struct i2c_device_id *id) | 1930 | const struct i2c_device_id *id) |
1922 | { | 1931 | { |
1923 | struct da7219_priv *da7219; | 1932 | struct da7219_priv *da7219; |
1924 | int ret; | 1933 | unsigned int system_active, system_status; |
1934 | int i, ret; | ||
1925 | 1935 | ||
1926 | da7219 = devm_kzalloc(&i2c->dev, sizeof(struct da7219_priv), | 1936 | da7219 = devm_kzalloc(&i2c->dev, sizeof(struct da7219_priv), |
1927 | GFP_KERNEL); | 1937 | GFP_KERNEL); |
@@ -1937,6 +1947,37 @@ static int da7219_i2c_probe(struct i2c_client *i2c, | |||
1937 | return ret; | 1947 | return ret; |
1938 | } | 1948 | } |
1939 | 1949 | ||
1950 | regcache_cache_bypass(da7219->regmap, true); | ||
1951 | |||
1952 | /* Disable audio paths if still active from previous start */ | ||
1953 | regmap_read(da7219->regmap, DA7219_SYSTEM_ACTIVE, &system_active); | ||
1954 | if (system_active) { | ||
1955 | regmap_write(da7219->regmap, DA7219_GAIN_RAMP_CTRL, | ||
1956 | DA7219_GAIN_RAMP_RATE_NOMINAL); | ||
1957 | regmap_write(da7219->regmap, DA7219_SYSTEM_MODES_INPUT, 0x00); | ||
1958 | regmap_write(da7219->regmap, DA7219_SYSTEM_MODES_OUTPUT, 0x01); | ||
1959 | |||
1960 | for (i = 0; i < DA7219_SYS_STAT_CHECK_RETRIES; ++i) { | ||
1961 | regmap_read(da7219->regmap, DA7219_SYSTEM_STATUS, | ||
1962 | &system_status); | ||
1963 | if (!system_status) | ||
1964 | break; | ||
1965 | |||
1966 | msleep(DA7219_SYS_STAT_CHECK_DELAY); | ||
1967 | } | ||
1968 | } | ||
1969 | |||
1970 | /* Soft reset codec */ | ||
1971 | regmap_write_bits(da7219->regmap, DA7219_ACCDET_CONFIG_1, | ||
1972 | DA7219_ACCDET_EN_MASK, 0); | ||
1973 | regmap_write_bits(da7219->regmap, DA7219_CIF_CTRL, | ||
1974 | DA7219_CIF_REG_SOFT_RESET_MASK, | ||
1975 | DA7219_CIF_REG_SOFT_RESET_MASK); | ||
1976 | regmap_write_bits(da7219->regmap, DA7219_SYSTEM_ACTIVE, | ||
1977 | DA7219_SYSTEM_ACTIVE_MASK, 0); | ||
1978 | |||
1979 | regcache_cache_bypass(da7219->regmap, false); | ||
1980 | |||
1940 | ret = snd_soc_register_codec(&i2c->dev, &soc_codec_dev_da7219, | 1981 | ret = snd_soc_register_codec(&i2c->dev, &soc_codec_dev_da7219, |
1941 | &da7219_dai, 1); | 1982 | &da7219_dai, 1); |
1942 | if (ret < 0) { | 1983 | if (ret < 0) { |
diff --git a/sound/soc/codecs/da7219.h b/sound/soc/codecs/da7219.h index ff2a2f02ce40..66d3bad86739 100644 --- a/sound/soc/codecs/da7219.h +++ b/sound/soc/codecs/da7219.h | |||
@@ -224,6 +224,7 @@ | |||
224 | #define DA7219_PLL_SRM_STATE_MASK (0xF << 0) | 224 | #define DA7219_PLL_SRM_STATE_MASK (0xF << 0) |
225 | #define DA7219_PLL_SRM_STATUS_SHIFT 4 | 225 | #define DA7219_PLL_SRM_STATUS_SHIFT 4 |
226 | #define DA7219_PLL_SRM_STATUS_MASK (0xF << 4) | 226 | #define DA7219_PLL_SRM_STATUS_MASK (0xF << 4) |
227 | #define DA7219_PLL_SRM_STS_MCLK (0x1 << 4) | ||
227 | #define DA7219_PLL_SRM_STS_SRM_LOCK (0x1 << 7) | 228 | #define DA7219_PLL_SRM_STS_SRM_LOCK (0x1 << 7) |
228 | 229 | ||
229 | /* DA7219_DIG_ROUTING_DAI = 0x2A */ | 230 | /* DA7219_DIG_ROUTING_DAI = 0x2A */ |
@@ -576,6 +577,8 @@ | |||
576 | /* DA7219_GAIN_RAMP_CTRL = 0x92 */ | 577 | /* DA7219_GAIN_RAMP_CTRL = 0x92 */ |
577 | #define DA7219_GAIN_RAMP_RATE_SHIFT 0 | 578 | #define DA7219_GAIN_RAMP_RATE_SHIFT 0 |
578 | #define DA7219_GAIN_RAMP_RATE_MASK (0x3 << 0) | 579 | #define DA7219_GAIN_RAMP_RATE_MASK (0x3 << 0) |
580 | #define DA7219_GAIN_RAMP_RATE_X8 (0x0 << 0) | ||
581 | #define DA7219_GAIN_RAMP_RATE_NOMINAL (0x1 << 0) | ||
579 | #define DA7219_GAIN_RAMP_RATE_MAX 4 | 582 | #define DA7219_GAIN_RAMP_RATE_MAX 4 |
580 | 583 | ||
581 | /* DA7219_PC_COUNT = 0x94 */ | 584 | /* DA7219_PC_COUNT = 0x94 */ |
@@ -770,6 +773,10 @@ | |||
770 | /* SRM */ | 773 | /* SRM */ |
771 | #define DA7219_SRM_CHECK_RETRIES 8 | 774 | #define DA7219_SRM_CHECK_RETRIES 8 |
772 | 775 | ||
776 | /* System Controller */ | ||
777 | #define DA7219_SYS_STAT_CHECK_RETRIES 6 | ||
778 | #define DA7219_SYS_STAT_CHECK_DELAY 50 | ||
779 | |||
773 | enum da7219_clk_src { | 780 | enum da7219_clk_src { |
774 | DA7219_CLKSRC_MCLK = 0, | 781 | DA7219_CLKSRC_MCLK = 0, |
775 | DA7219_CLKSRC_MCLK_SQR, | 782 | DA7219_CLKSRC_MCLK_SQR, |
@@ -796,6 +803,7 @@ struct da7219_priv { | |||
796 | struct da7219_aad_priv *aad; | 803 | struct da7219_aad_priv *aad; |
797 | struct da7219_pdata *pdata; | 804 | struct da7219_pdata *pdata; |
798 | 805 | ||
806 | bool wakeup_source; | ||
799 | struct regulator_bulk_data supplies[DA7219_NUM_SUPPLIES]; | 807 | struct regulator_bulk_data supplies[DA7219_NUM_SUPPLIES]; |
800 | struct regmap *regmap; | 808 | struct regmap *regmap; |
801 | struct mutex lock; | 809 | struct mutex lock; |
diff --git a/sound/soc/codecs/da732x.c b/sound/soc/codecs/da732x.c index 461506a4ca6a..c1cc1c1c28f2 100644 --- a/sound/soc/codecs/da732x.c +++ b/sound/soc/codecs/da732x.c | |||
@@ -1501,12 +1501,14 @@ static int da732x_set_bias_level(struct snd_soc_codec *codec, | |||
1501 | 1501 | ||
1502 | static struct snd_soc_codec_driver soc_codec_dev_da732x = { | 1502 | static struct snd_soc_codec_driver soc_codec_dev_da732x = { |
1503 | .set_bias_level = da732x_set_bias_level, | 1503 | .set_bias_level = da732x_set_bias_level, |
1504 | .controls = da732x_snd_controls, | 1504 | .component_driver = { |
1505 | .num_controls = ARRAY_SIZE(da732x_snd_controls), | 1505 | .controls = da732x_snd_controls, |
1506 | .dapm_widgets = da732x_dapm_widgets, | 1506 | .num_controls = ARRAY_SIZE(da732x_snd_controls), |
1507 | .num_dapm_widgets = ARRAY_SIZE(da732x_dapm_widgets), | 1507 | .dapm_widgets = da732x_dapm_widgets, |
1508 | .dapm_routes = da732x_dapm_routes, | 1508 | .num_dapm_widgets = ARRAY_SIZE(da732x_dapm_widgets), |
1509 | .num_dapm_routes = ARRAY_SIZE(da732x_dapm_routes), | 1509 | .dapm_routes = da732x_dapm_routes, |
1510 | .num_dapm_routes = ARRAY_SIZE(da732x_dapm_routes), | ||
1511 | }, | ||
1510 | .set_pll = da732x_set_dai_pll, | 1512 | .set_pll = da732x_set_dai_pll, |
1511 | }; | 1513 | }; |
1512 | 1514 | ||
diff --git a/sound/soc/codecs/da9055.c b/sound/soc/codecs/da9055.c index 0b2ede8db978..4efb5f897a0c 100644 --- a/sound/soc/codecs/da9055.c +++ b/sound/soc/codecs/da9055.c | |||
@@ -1455,13 +1455,14 @@ static struct snd_soc_codec_driver soc_codec_dev_da9055 = { | |||
1455 | .probe = da9055_probe, | 1455 | .probe = da9055_probe, |
1456 | .set_bias_level = da9055_set_bias_level, | 1456 | .set_bias_level = da9055_set_bias_level, |
1457 | 1457 | ||
1458 | .controls = da9055_snd_controls, | 1458 | .component_driver = { |
1459 | .num_controls = ARRAY_SIZE(da9055_snd_controls), | 1459 | .controls = da9055_snd_controls, |
1460 | 1460 | .num_controls = ARRAY_SIZE(da9055_snd_controls), | |
1461 | .dapm_widgets = da9055_dapm_widgets, | 1461 | .dapm_widgets = da9055_dapm_widgets, |
1462 | .num_dapm_widgets = ARRAY_SIZE(da9055_dapm_widgets), | 1462 | .num_dapm_widgets = ARRAY_SIZE(da9055_dapm_widgets), |
1463 | .dapm_routes = da9055_audio_map, | 1463 | .dapm_routes = da9055_audio_map, |
1464 | .num_dapm_routes = ARRAY_SIZE(da9055_audio_map), | 1464 | .num_dapm_routes = ARRAY_SIZE(da9055_audio_map), |
1465 | }, | ||
1465 | }; | 1466 | }; |
1466 | 1467 | ||
1467 | static const struct regmap_config da9055_regmap_config = { | 1468 | static const struct regmap_config da9055_regmap_config = { |
diff --git a/sound/soc/codecs/dmic.c b/sound/soc/codecs/dmic.c index fde53251c047..c82b9dc41e9a 100644 --- a/sound/soc/codecs/dmic.c +++ b/sound/soc/codecs/dmic.c | |||
@@ -51,10 +51,12 @@ static const struct snd_soc_dapm_route intercon[] = { | |||
51 | }; | 51 | }; |
52 | 52 | ||
53 | static struct snd_soc_codec_driver soc_dmic = { | 53 | static struct snd_soc_codec_driver soc_dmic = { |
54 | .dapm_widgets = dmic_dapm_widgets, | 54 | .component_driver = { |
55 | .num_dapm_widgets = ARRAY_SIZE(dmic_dapm_widgets), | 55 | .dapm_widgets = dmic_dapm_widgets, |
56 | .dapm_routes = intercon, | 56 | .num_dapm_widgets = ARRAY_SIZE(dmic_dapm_widgets), |
57 | .num_dapm_routes = ARRAY_SIZE(intercon), | 57 | .dapm_routes = intercon, |
58 | .num_dapm_routes = ARRAY_SIZE(intercon), | ||
59 | }, | ||
58 | }; | 60 | }; |
59 | 61 | ||
60 | static int dmic_dev_probe(struct platform_device *pdev) | 62 | static int dmic_dev_probe(struct platform_device *pdev) |
diff --git a/sound/soc/codecs/es8328.c b/sound/soc/codecs/es8328.c index 2086d7107622..37722194b107 100644 --- a/sound/soc/codecs/es8328.c +++ b/sound/soc/codecs/es8328.c | |||
@@ -823,12 +823,14 @@ static struct snd_soc_codec_driver es8328_codec_driver = { | |||
823 | .set_bias_level = es8328_set_bias_level, | 823 | .set_bias_level = es8328_set_bias_level, |
824 | .suspend_bias_off = true, | 824 | .suspend_bias_off = true, |
825 | 825 | ||
826 | .controls = es8328_snd_controls, | 826 | .component_driver = { |
827 | .num_controls = ARRAY_SIZE(es8328_snd_controls), | 827 | .controls = es8328_snd_controls, |
828 | .dapm_widgets = es8328_dapm_widgets, | 828 | .num_controls = ARRAY_SIZE(es8328_snd_controls), |
829 | .num_dapm_widgets = ARRAY_SIZE(es8328_dapm_widgets), | 829 | .dapm_widgets = es8328_dapm_widgets, |
830 | .dapm_routes = es8328_dapm_routes, | 830 | .num_dapm_widgets = ARRAY_SIZE(es8328_dapm_widgets), |
831 | .num_dapm_routes = ARRAY_SIZE(es8328_dapm_routes), | 831 | .dapm_routes = es8328_dapm_routes, |
832 | .num_dapm_routes = ARRAY_SIZE(es8328_dapm_routes), | ||
833 | }, | ||
832 | }; | 834 | }; |
833 | 835 | ||
834 | int es8328_probe(struct device *dev, struct regmap *regmap) | 836 | int es8328_probe(struct device *dev, struct regmap *regmap) |
diff --git a/sound/soc/codecs/gtm601.c b/sound/soc/codecs/gtm601.c index 0b80052996d3..926b1a4e37d4 100644 --- a/sound/soc/codecs/gtm601.c +++ b/sound/soc/codecs/gtm601.c | |||
@@ -52,10 +52,12 @@ static struct snd_soc_dai_driver gtm601_dai = { | |||
52 | }; | 52 | }; |
53 | 53 | ||
54 | static const struct snd_soc_codec_driver soc_codec_dev_gtm601 = { | 54 | static const struct snd_soc_codec_driver soc_codec_dev_gtm601 = { |
55 | .dapm_widgets = gtm601_dapm_widgets, | 55 | .component_driver = { |
56 | .num_dapm_widgets = ARRAY_SIZE(gtm601_dapm_widgets), | 56 | .dapm_widgets = gtm601_dapm_widgets, |
57 | .dapm_routes = gtm601_dapm_routes, | 57 | .num_dapm_widgets = ARRAY_SIZE(gtm601_dapm_widgets), |
58 | .num_dapm_routes = ARRAY_SIZE(gtm601_dapm_routes), | 58 | .dapm_routes = gtm601_dapm_routes, |
59 | .num_dapm_routes = ARRAY_SIZE(gtm601_dapm_routes), | ||
60 | }, | ||
59 | }; | 61 | }; |
60 | 62 | ||
61 | static int gtm601_platform_probe(struct platform_device *pdev) | 63 | static int gtm601_platform_probe(struct platform_device *pdev) |
diff --git a/sound/soc/codecs/hdac_hdmi.c b/sound/soc/codecs/hdac_hdmi.c index 4e181b270d95..c602c4960924 100644 --- a/sound/soc/codecs/hdac_hdmi.c +++ b/sound/soc/codecs/hdac_hdmi.c | |||
@@ -614,7 +614,7 @@ static int hdac_hdmi_pcm_open(struct snd_pcm_substream *substream, | |||
614 | (!pin->eld.eld_valid)) { | 614 | (!pin->eld.eld_valid)) { |
615 | 615 | ||
616 | dev_warn(&hdac->hdac.dev, | 616 | dev_warn(&hdac->hdac.dev, |
617 | "Failed: montior present? %d ELD valid?: %d for pin: %d\n", | 617 | "Failed: monitor present? %d ELD valid?: %d for pin: %d\n", |
618 | pin->eld.monitor_present, pin->eld.eld_valid, pin->nid); | 618 | pin->eld.monitor_present, pin->eld.eld_valid, pin->nid); |
619 | 619 | ||
620 | return 0; | 620 | return 0; |
diff --git a/sound/soc/codecs/hdmi-codec.c b/sound/soc/codecs/hdmi-codec.c index f27d115626db..b904492d7744 100644 --- a/sound/soc/codecs/hdmi-codec.c +++ b/sound/soc/codecs/hdmi-codec.c | |||
@@ -24,6 +24,15 @@ | |||
24 | 24 | ||
25 | #include <drm/drm_crtc.h> /* This is only to get MAX_ELD_BYTES */ | 25 | #include <drm/drm_crtc.h> /* This is only to get MAX_ELD_BYTES */ |
26 | 26 | ||
27 | struct hdmi_device { | ||
28 | struct device *dev; | ||
29 | struct list_head list; | ||
30 | int cnt; | ||
31 | }; | ||
32 | #define pos_to_hdmi_device(pos) container_of((pos), struct hdmi_device, list) | ||
33 | LIST_HEAD(hdmi_device_list); | ||
34 | |||
35 | #define DAI_NAME_SIZE 16 | ||
27 | struct hdmi_codec_priv { | 36 | struct hdmi_codec_priv { |
28 | struct hdmi_codec_pdata hcd; | 37 | struct hdmi_codec_pdata hcd; |
29 | struct snd_soc_dai_driver *daidrv; | 38 | struct snd_soc_dai_driver *daidrv; |
@@ -320,7 +329,6 @@ static const struct snd_soc_dai_ops hdmi_dai_ops = { | |||
320 | SNDRV_PCM_FMTBIT_S32_LE | SNDRV_PCM_FMTBIT_S32_BE) | 329 | SNDRV_PCM_FMTBIT_S32_LE | SNDRV_PCM_FMTBIT_S32_BE) |
321 | 330 | ||
322 | static struct snd_soc_dai_driver hdmi_i2s_dai = { | 331 | static struct snd_soc_dai_driver hdmi_i2s_dai = { |
323 | .name = "i2s-hifi", | ||
324 | .id = DAI_ID_I2S, | 332 | .id = DAI_ID_I2S, |
325 | .playback = { | 333 | .playback = { |
326 | .stream_name = "Playback", | 334 | .stream_name = "Playback", |
@@ -334,7 +342,6 @@ static struct snd_soc_dai_driver hdmi_i2s_dai = { | |||
334 | }; | 342 | }; |
335 | 343 | ||
336 | static const struct snd_soc_dai_driver hdmi_spdif_dai = { | 344 | static const struct snd_soc_dai_driver hdmi_spdif_dai = { |
337 | .name = "spdif-hifi", | ||
338 | .id = DAI_ID_SPDIF, | 345 | .id = DAI_ID_SPDIF, |
339 | .playback = { | 346 | .playback = { |
340 | .stream_name = "Playback", | 347 | .stream_name = "Playback", |
@@ -346,13 +353,37 @@ static const struct snd_soc_dai_driver hdmi_spdif_dai = { | |||
346 | .ops = &hdmi_dai_ops, | 353 | .ops = &hdmi_dai_ops, |
347 | }; | 354 | }; |
348 | 355 | ||
356 | static char hdmi_dai_name[][DAI_NAME_SIZE] = { | ||
357 | "hdmi-hifi.0", | ||
358 | "hdmi-hifi.1", | ||
359 | "hdmi-hifi.2", | ||
360 | "hdmi-hifi.3", | ||
361 | }; | ||
362 | |||
363 | static int hdmi_of_xlate_dai_name(struct snd_soc_component *component, | ||
364 | struct of_phandle_args *args, | ||
365 | const char **dai_name) | ||
366 | { | ||
367 | int id = args->args[0]; | ||
368 | |||
369 | if (id < ARRAY_SIZE(hdmi_dai_name)) { | ||
370 | *dai_name = hdmi_dai_name[id]; | ||
371 | return 0; | ||
372 | } | ||
373 | |||
374 | return -EAGAIN; | ||
375 | } | ||
376 | |||
349 | static struct snd_soc_codec_driver hdmi_codec = { | 377 | static struct snd_soc_codec_driver hdmi_codec = { |
350 | .controls = hdmi_controls, | 378 | .component_driver = { |
351 | .num_controls = ARRAY_SIZE(hdmi_controls), | 379 | .controls = hdmi_controls, |
352 | .dapm_widgets = hdmi_widgets, | 380 | .num_controls = ARRAY_SIZE(hdmi_controls), |
353 | .num_dapm_widgets = ARRAY_SIZE(hdmi_widgets), | 381 | .dapm_widgets = hdmi_widgets, |
354 | .dapm_routes = hdmi_routes, | 382 | .num_dapm_widgets = ARRAY_SIZE(hdmi_widgets), |
355 | .num_dapm_routes = ARRAY_SIZE(hdmi_routes), | 383 | .dapm_routes = hdmi_routes, |
384 | .num_dapm_routes = ARRAY_SIZE(hdmi_routes), | ||
385 | .of_xlate_dai_name = hdmi_of_xlate_dai_name, | ||
386 | }, | ||
356 | }; | 387 | }; |
357 | 388 | ||
358 | static int hdmi_codec_probe(struct platform_device *pdev) | 389 | static int hdmi_codec_probe(struct platform_device *pdev) |
@@ -360,6 +391,8 @@ static int hdmi_codec_probe(struct platform_device *pdev) | |||
360 | struct hdmi_codec_pdata *hcd = pdev->dev.platform_data; | 391 | struct hdmi_codec_pdata *hcd = pdev->dev.platform_data; |
361 | struct device *dev = &pdev->dev; | 392 | struct device *dev = &pdev->dev; |
362 | struct hdmi_codec_priv *hcp; | 393 | struct hdmi_codec_priv *hcp; |
394 | struct hdmi_device *hd; | ||
395 | struct list_head *pos; | ||
363 | int dai_count, i = 0; | 396 | int dai_count, i = 0; |
364 | int ret; | 397 | int ret; |
365 | 398 | ||
@@ -381,6 +414,31 @@ static int hdmi_codec_probe(struct platform_device *pdev) | |||
381 | if (!hcp) | 414 | if (!hcp) |
382 | return -ENOMEM; | 415 | return -ENOMEM; |
383 | 416 | ||
417 | hd = NULL; | ||
418 | list_for_each(pos, &hdmi_device_list) { | ||
419 | struct hdmi_device *tmp = pos_to_hdmi_device(pos); | ||
420 | |||
421 | if (tmp->dev == dev->parent) { | ||
422 | hd = tmp; | ||
423 | break; | ||
424 | } | ||
425 | } | ||
426 | |||
427 | if (!hd) { | ||
428 | hd = devm_kzalloc(dev, sizeof(*hd), GFP_KERNEL); | ||
429 | if (!hd) | ||
430 | return -ENOMEM; | ||
431 | |||
432 | hd->dev = dev->parent; | ||
433 | |||
434 | list_add_tail(&hd->list, &hdmi_device_list); | ||
435 | } | ||
436 | |||
437 | if (hd->cnt >= ARRAY_SIZE(hdmi_dai_name)) { | ||
438 | dev_err(dev, "too many hdmi codec are deteced\n"); | ||
439 | return -EINVAL; | ||
440 | } | ||
441 | |||
384 | hcp->hcd = *hcd; | 442 | hcp->hcd = *hcd; |
385 | mutex_init(&hcp->current_stream_lock); | 443 | mutex_init(&hcp->current_stream_lock); |
386 | 444 | ||
@@ -393,11 +451,14 @@ static int hdmi_codec_probe(struct platform_device *pdev) | |||
393 | hcp->daidrv[i] = hdmi_i2s_dai; | 451 | hcp->daidrv[i] = hdmi_i2s_dai; |
394 | hcp->daidrv[i].playback.channels_max = | 452 | hcp->daidrv[i].playback.channels_max = |
395 | hcd->max_i2s_channels; | 453 | hcd->max_i2s_channels; |
454 | hcp->daidrv[i].name = hdmi_dai_name[hd->cnt++]; | ||
396 | i++; | 455 | i++; |
397 | } | 456 | } |
398 | 457 | ||
399 | if (hcd->spdif) | 458 | if (hcd->spdif) { |
400 | hcp->daidrv[i] = hdmi_spdif_dai; | 459 | hcp->daidrv[i] = hdmi_spdif_dai; |
460 | hcp->daidrv[i].name = hdmi_dai_name[hd->cnt++]; | ||
461 | } | ||
401 | 462 | ||
402 | ret = snd_soc_register_codec(dev, &hdmi_codec, hcp->daidrv, | 463 | ret = snd_soc_register_codec(dev, &hdmi_codec, hcp->daidrv, |
403 | dai_count); | 464 | dai_count); |
diff --git a/sound/soc/codecs/inno_rk3036.c b/sound/soc/codecs/inno_rk3036.c index 9b6e8840a1b5..b918ba5c8ce5 100644 --- a/sound/soc/codecs/inno_rk3036.c +++ b/sound/soc/codecs/inno_rk3036.c | |||
@@ -380,12 +380,14 @@ static struct snd_soc_codec_driver rk3036_codec_driver = { | |||
380 | .probe = rk3036_codec_probe, | 380 | .probe = rk3036_codec_probe, |
381 | .remove = rk3036_codec_remove, | 381 | .remove = rk3036_codec_remove, |
382 | .set_bias_level = rk3036_codec_set_bias_level, | 382 | .set_bias_level = rk3036_codec_set_bias_level, |
383 | .controls = rk3036_codec_dapm_controls, | 383 | .component_driver = { |
384 | .num_controls = ARRAY_SIZE(rk3036_codec_dapm_controls), | 384 | .controls = rk3036_codec_dapm_controls, |
385 | .dapm_routes = rk3036_codec_dapm_routes, | 385 | .num_controls = ARRAY_SIZE(rk3036_codec_dapm_controls), |
386 | .num_dapm_routes = ARRAY_SIZE(rk3036_codec_dapm_routes), | 386 | .dapm_routes = rk3036_codec_dapm_routes, |
387 | .dapm_widgets = rk3036_codec_dapm_widgets, | 387 | .num_dapm_routes = ARRAY_SIZE(rk3036_codec_dapm_routes), |
388 | .num_dapm_widgets = ARRAY_SIZE(rk3036_codec_dapm_widgets), | 388 | .dapm_widgets = rk3036_codec_dapm_widgets, |
389 | .num_dapm_widgets = ARRAY_SIZE(rk3036_codec_dapm_widgets), | ||
390 | }, | ||
389 | }; | 391 | }; |
390 | 392 | ||
391 | static const struct regmap_config rk3036_codec_regmap_config = { | 393 | static const struct regmap_config rk3036_codec_regmap_config = { |
diff --git a/sound/soc/codecs/isabelle.c b/sound/soc/codecs/isabelle.c index be448373d39a..a4b0eded984a 100644 --- a/sound/soc/codecs/isabelle.c +++ b/sound/soc/codecs/isabelle.c | |||
@@ -1089,12 +1089,14 @@ static struct snd_soc_dai_driver isabelle_dai[] = { | |||
1089 | 1089 | ||
1090 | static struct snd_soc_codec_driver soc_codec_dev_isabelle = { | 1090 | static struct snd_soc_codec_driver soc_codec_dev_isabelle = { |
1091 | .set_bias_level = isabelle_set_bias_level, | 1091 | .set_bias_level = isabelle_set_bias_level, |
1092 | .controls = isabelle_snd_controls, | 1092 | .component_driver = { |
1093 | .num_controls = ARRAY_SIZE(isabelle_snd_controls), | 1093 | .controls = isabelle_snd_controls, |
1094 | .dapm_widgets = isabelle_dapm_widgets, | 1094 | .num_controls = ARRAY_SIZE(isabelle_snd_controls), |
1095 | .num_dapm_widgets = ARRAY_SIZE(isabelle_dapm_widgets), | 1095 | .dapm_widgets = isabelle_dapm_widgets, |
1096 | .dapm_routes = isabelle_intercon, | 1096 | .num_dapm_widgets = ARRAY_SIZE(isabelle_dapm_widgets), |
1097 | .num_dapm_routes = ARRAY_SIZE(isabelle_intercon), | 1097 | .dapm_routes = isabelle_intercon, |
1098 | .num_dapm_routes = ARRAY_SIZE(isabelle_intercon), | ||
1099 | }, | ||
1098 | .idle_bias_off = true, | 1100 | .idle_bias_off = true, |
1099 | }; | 1101 | }; |
1100 | 1102 | ||
diff --git a/sound/soc/codecs/jz4740.c b/sound/soc/codecs/jz4740.c index 1f5ab99956ed..0290fab383da 100644 --- a/sound/soc/codecs/jz4740.c +++ b/sound/soc/codecs/jz4740.c | |||
@@ -298,12 +298,14 @@ static struct snd_soc_codec_driver soc_codec_dev_jz4740_codec = { | |||
298 | .set_bias_level = jz4740_codec_set_bias_level, | 298 | .set_bias_level = jz4740_codec_set_bias_level, |
299 | .suspend_bias_off = true, | 299 | .suspend_bias_off = true, |
300 | 300 | ||
301 | .controls = jz4740_codec_controls, | 301 | .component_driver = { |
302 | .num_controls = ARRAY_SIZE(jz4740_codec_controls), | 302 | .controls = jz4740_codec_controls, |
303 | .dapm_widgets = jz4740_codec_dapm_widgets, | 303 | .num_controls = ARRAY_SIZE(jz4740_codec_controls), |
304 | .num_dapm_widgets = ARRAY_SIZE(jz4740_codec_dapm_widgets), | 304 | .dapm_widgets = jz4740_codec_dapm_widgets, |
305 | .dapm_routes = jz4740_codec_dapm_routes, | 305 | .num_dapm_widgets = ARRAY_SIZE(jz4740_codec_dapm_widgets), |
306 | .num_dapm_routes = ARRAY_SIZE(jz4740_codec_dapm_routes), | 306 | .dapm_routes = jz4740_codec_dapm_routes, |
307 | .num_dapm_routes = ARRAY_SIZE(jz4740_codec_dapm_routes), | ||
308 | }, | ||
307 | }; | 309 | }; |
308 | 310 | ||
309 | static const struct regmap_config jz4740_codec_regmap_config = { | 311 | static const struct regmap_config jz4740_codec_regmap_config = { |
diff --git a/sound/soc/codecs/l3.c b/sound/soc/codecs/l3.c index 5353af58862c..a10ea3c716c6 100644 --- a/sound/soc/codecs/l3.c +++ b/sound/soc/codecs/l3.c | |||
@@ -20,6 +20,8 @@ | |||
20 | #include <linux/module.h> | 20 | #include <linux/module.h> |
21 | #include <linux/kernel.h> | 21 | #include <linux/kernel.h> |
22 | #include <linux/delay.h> | 22 | #include <linux/delay.h> |
23 | #include <linux/device.h> | ||
24 | #include <linux/gpio.h> | ||
23 | 25 | ||
24 | #include <sound/l3.h> | 26 | #include <sound/l3.h> |
25 | 27 | ||
@@ -32,11 +34,11 @@ static void sendbyte(struct l3_pins *adap, unsigned int byte) | |||
32 | int i; | 34 | int i; |
33 | 35 | ||
34 | for (i = 0; i < 8; i++) { | 36 | for (i = 0; i < 8; i++) { |
35 | adap->setclk(0); | 37 | adap->setclk(adap, 0); |
36 | udelay(adap->data_hold); | 38 | udelay(adap->data_hold); |
37 | adap->setdat(byte & 1); | 39 | adap->setdat(adap, byte & 1); |
38 | udelay(adap->data_setup); | 40 | udelay(adap->data_setup); |
39 | adap->setclk(1); | 41 | adap->setclk(adap, 1); |
40 | udelay(adap->clock_high); | 42 | udelay(adap->clock_high); |
41 | byte >>= 1; | 43 | byte >>= 1; |
42 | } | 44 | } |
@@ -55,10 +57,10 @@ static void sendbytes(struct l3_pins *adap, const u8 *buf, | |||
55 | for (i = 0; i < len; i++) { | 57 | for (i = 0; i < len; i++) { |
56 | if (i) { | 58 | if (i) { |
57 | udelay(adap->mode_hold); | 59 | udelay(adap->mode_hold); |
58 | adap->setmode(0); | 60 | adap->setmode(adap, 0); |
59 | udelay(adap->mode); | 61 | udelay(adap->mode); |
60 | } | 62 | } |
61 | adap->setmode(1); | 63 | adap->setmode(adap, 1); |
62 | udelay(adap->mode_setup); | 64 | udelay(adap->mode_setup); |
63 | sendbyte(adap, buf[i]); | 65 | sendbyte(adap, buf[i]); |
64 | } | 66 | } |
@@ -66,26 +68,71 @@ static void sendbytes(struct l3_pins *adap, const u8 *buf, | |||
66 | 68 | ||
67 | int l3_write(struct l3_pins *adap, u8 addr, u8 *data, int len) | 69 | int l3_write(struct l3_pins *adap, u8 addr, u8 *data, int len) |
68 | { | 70 | { |
69 | adap->setclk(1); | 71 | adap->setclk(adap, 1); |
70 | adap->setdat(1); | 72 | adap->setdat(adap, 1); |
71 | adap->setmode(1); | 73 | adap->setmode(adap, 1); |
72 | udelay(adap->mode); | 74 | udelay(adap->mode); |
73 | 75 | ||
74 | adap->setmode(0); | 76 | adap->setmode(adap, 0); |
75 | udelay(adap->mode_setup); | 77 | udelay(adap->mode_setup); |
76 | sendbyte(adap, addr); | 78 | sendbyte(adap, addr); |
77 | udelay(adap->mode_hold); | 79 | udelay(adap->mode_hold); |
78 | 80 | ||
79 | sendbytes(adap, data, len); | 81 | sendbytes(adap, data, len); |
80 | 82 | ||
81 | adap->setclk(1); | 83 | adap->setclk(adap, 1); |
82 | adap->setdat(1); | 84 | adap->setdat(adap, 1); |
83 | adap->setmode(0); | 85 | adap->setmode(adap, 0); |
84 | 86 | ||
85 | return len; | 87 | return len; |
86 | } | 88 | } |
87 | EXPORT_SYMBOL_GPL(l3_write); | 89 | EXPORT_SYMBOL_GPL(l3_write); |
88 | 90 | ||
91 | |||
92 | static void l3_set_clk(struct l3_pins *adap, int val) | ||
93 | { | ||
94 | gpio_set_value(adap->gpio_clk, val); | ||
95 | } | ||
96 | |||
97 | static void l3_set_data(struct l3_pins *adap, int val) | ||
98 | { | ||
99 | gpio_set_value(adap->gpio_data, val); | ||
100 | } | ||
101 | |||
102 | static void l3_set_mode(struct l3_pins *adap, int val) | ||
103 | { | ||
104 | gpio_set_value(adap->gpio_mode, val); | ||
105 | } | ||
106 | |||
107 | int l3_set_gpio_ops(struct device *dev, struct l3_pins *adap) | ||
108 | { | ||
109 | int ret; | ||
110 | |||
111 | if (!adap->use_gpios) | ||
112 | return -EINVAL; | ||
113 | |||
114 | ret = devm_gpio_request_one(dev, adap->gpio_data, | ||
115 | GPIOF_OUT_INIT_LOW, "l3_data"); | ||
116 | if (ret < 0) | ||
117 | return ret; | ||
118 | adap->setdat = l3_set_data; | ||
119 | |||
120 | ret = devm_gpio_request_one(dev, adap->gpio_clk, | ||
121 | GPIOF_OUT_INIT_LOW, "l3_clk"); | ||
122 | if (ret < 0) | ||
123 | return ret; | ||
124 | adap->setclk = l3_set_clk; | ||
125 | |||
126 | ret = devm_gpio_request_one(dev, adap->gpio_mode, | ||
127 | GPIOF_OUT_INIT_LOW, "l3_mode"); | ||
128 | if (ret < 0) | ||
129 | return ret; | ||
130 | adap->setmode = l3_set_mode; | ||
131 | |||
132 | return 0; | ||
133 | } | ||
134 | EXPORT_SYMBOL_GPL(l3_set_gpio_ops); | ||
135 | |||
89 | MODULE_DESCRIPTION("L3 bit-banging driver"); | 136 | MODULE_DESCRIPTION("L3 bit-banging driver"); |
90 | MODULE_AUTHOR("Christian Pellegrin <chripell@evolware.org>"); | 137 | MODULE_AUTHOR("Christian Pellegrin <chripell@evolware.org>"); |
91 | MODULE_LICENSE("GPL"); | 138 | MODULE_LICENSE("GPL"); |
diff --git a/sound/soc/codecs/lm49453.c b/sound/soc/codecs/lm49453.c index 9af5640e3446..8d413c2677cc 100644 --- a/sound/soc/codecs/lm49453.c +++ b/sound/soc/codecs/lm49453.c | |||
@@ -1391,12 +1391,14 @@ static struct snd_soc_dai_driver lm49453_dai[] = { | |||
1391 | 1391 | ||
1392 | static struct snd_soc_codec_driver soc_codec_dev_lm49453 = { | 1392 | static struct snd_soc_codec_driver soc_codec_dev_lm49453 = { |
1393 | .set_bias_level = lm49453_set_bias_level, | 1393 | .set_bias_level = lm49453_set_bias_level, |
1394 | .controls = lm49453_snd_controls, | 1394 | .component_driver = { |
1395 | .num_controls = ARRAY_SIZE(lm49453_snd_controls), | 1395 | .controls = lm49453_snd_controls, |
1396 | .dapm_widgets = lm49453_dapm_widgets, | 1396 | .num_controls = ARRAY_SIZE(lm49453_snd_controls), |
1397 | .num_dapm_widgets = ARRAY_SIZE(lm49453_dapm_widgets), | 1397 | .dapm_widgets = lm49453_dapm_widgets, |
1398 | .dapm_routes = lm49453_audio_map, | 1398 | .num_dapm_widgets = ARRAY_SIZE(lm49453_dapm_widgets), |
1399 | .num_dapm_routes = ARRAY_SIZE(lm49453_audio_map), | 1399 | .dapm_routes = lm49453_audio_map, |
1400 | .num_dapm_routes = ARRAY_SIZE(lm49453_audio_map), | ||
1401 | }, | ||
1400 | .idle_bias_off = true, | 1402 | .idle_bias_off = true, |
1401 | }; | 1403 | }; |
1402 | 1404 | ||
diff --git a/sound/soc/codecs/max98088.c b/sound/soc/codecs/max98088.c index fc22804cabc5..72f77455582e 100644 --- a/sound/soc/codecs/max98088.c +++ b/sound/soc/codecs/max98088.c | |||
@@ -1704,12 +1704,14 @@ static struct snd_soc_codec_driver soc_codec_dev_max98088 = { | |||
1704 | .set_bias_level = max98088_set_bias_level, | 1704 | .set_bias_level = max98088_set_bias_level, |
1705 | .suspend_bias_off = true, | 1705 | .suspend_bias_off = true, |
1706 | 1706 | ||
1707 | .controls = max98088_snd_controls, | 1707 | .component_driver = { |
1708 | .num_controls = ARRAY_SIZE(max98088_snd_controls), | 1708 | .controls = max98088_snd_controls, |
1709 | .dapm_widgets = max98088_dapm_widgets, | 1709 | .num_controls = ARRAY_SIZE(max98088_snd_controls), |
1710 | .num_dapm_widgets = ARRAY_SIZE(max98088_dapm_widgets), | 1710 | .dapm_widgets = max98088_dapm_widgets, |
1711 | .dapm_routes = max98088_audio_map, | 1711 | .num_dapm_widgets = ARRAY_SIZE(max98088_dapm_widgets), |
1712 | .num_dapm_routes = ARRAY_SIZE(max98088_audio_map), | 1712 | .dapm_routes = max98088_audio_map, |
1713 | .num_dapm_routes = ARRAY_SIZE(max98088_audio_map), | ||
1714 | }, | ||
1713 | }; | 1715 | }; |
1714 | 1716 | ||
1715 | static int max98088_i2c_probe(struct i2c_client *i2c, | 1717 | static int max98088_i2c_probe(struct i2c_client *i2c, |
diff --git a/sound/soc/codecs/max98095.c b/sound/soc/codecs/max98095.c index 3577003f39cf..6f8a757876ed 100644 --- a/sound/soc/codecs/max98095.c +++ b/sound/soc/codecs/max98095.c | |||
@@ -2108,12 +2108,14 @@ static struct snd_soc_codec_driver soc_codec_dev_max98095 = { | |||
2108 | .suspend = max98095_suspend, | 2108 | .suspend = max98095_suspend, |
2109 | .resume = max98095_resume, | 2109 | .resume = max98095_resume, |
2110 | .set_bias_level = max98095_set_bias_level, | 2110 | .set_bias_level = max98095_set_bias_level, |
2111 | .controls = max98095_snd_controls, | 2111 | .component_driver = { |
2112 | .num_controls = ARRAY_SIZE(max98095_snd_controls), | 2112 | .controls = max98095_snd_controls, |
2113 | .dapm_widgets = max98095_dapm_widgets, | 2113 | .num_controls = ARRAY_SIZE(max98095_snd_controls), |
2114 | .num_dapm_widgets = ARRAY_SIZE(max98095_dapm_widgets), | 2114 | .dapm_widgets = max98095_dapm_widgets, |
2115 | .dapm_routes = max98095_audio_map, | 2115 | .num_dapm_widgets = ARRAY_SIZE(max98095_dapm_widgets), |
2116 | .num_dapm_routes = ARRAY_SIZE(max98095_audio_map), | 2116 | .dapm_routes = max98095_audio_map, |
2117 | .num_dapm_routes = ARRAY_SIZE(max98095_audio_map), | ||
2118 | }, | ||
2117 | }; | 2119 | }; |
2118 | 2120 | ||
2119 | static int max98095_i2c_probe(struct i2c_client *i2c, | 2121 | static int max98095_i2c_probe(struct i2c_client *i2c, |
diff --git a/sound/soc/codecs/max98357a.c b/sound/soc/codecs/max98357a.c index 5b1dfb1518fb..6a6b68a4cb52 100644 --- a/sound/soc/codecs/max98357a.c +++ b/sound/soc/codecs/max98357a.c | |||
@@ -74,10 +74,12 @@ static int max98357a_codec_probe(struct snd_soc_codec *codec) | |||
74 | 74 | ||
75 | static struct snd_soc_codec_driver max98357a_codec_driver = { | 75 | static struct snd_soc_codec_driver max98357a_codec_driver = { |
76 | .probe = max98357a_codec_probe, | 76 | .probe = max98357a_codec_probe, |
77 | .dapm_widgets = max98357a_dapm_widgets, | 77 | .component_driver = { |
78 | .num_dapm_widgets = ARRAY_SIZE(max98357a_dapm_widgets), | 78 | .dapm_widgets = max98357a_dapm_widgets, |
79 | .dapm_routes = max98357a_dapm_routes, | 79 | .num_dapm_widgets = ARRAY_SIZE(max98357a_dapm_widgets), |
80 | .num_dapm_routes = ARRAY_SIZE(max98357a_dapm_routes), | 80 | .dapm_routes = max98357a_dapm_routes, |
81 | .num_dapm_routes = ARRAY_SIZE(max98357a_dapm_routes), | ||
82 | }, | ||
81 | }; | 83 | }; |
82 | 84 | ||
83 | static const struct snd_soc_dai_ops max98357a_dai_ops = { | 85 | static const struct snd_soc_dai_ops max98357a_dai_ops = { |
diff --git a/sound/soc/codecs/max98371.c b/sound/soc/codecs/max98371.c index 02352ed8961c..781be9ba8dba 100644 --- a/sound/soc/codecs/max98371.c +++ b/sound/soc/codecs/max98371.c | |||
@@ -426,7 +426,6 @@ MODULE_DEVICE_TABLE(of, max98371_of_match); | |||
426 | static struct i2c_driver max98371_i2c_driver = { | 426 | static struct i2c_driver max98371_i2c_driver = { |
427 | .driver = { | 427 | .driver = { |
428 | .name = "max98371", | 428 | .name = "max98371", |
429 | .owner = THIS_MODULE, | ||
430 | .pm = NULL, | 429 | .pm = NULL, |
431 | .of_match_table = of_match_ptr(max98371_of_match), | 430 | .of_match_table = of_match_ptr(max98371_of_match), |
432 | }, | 431 | }, |
diff --git a/sound/soc/codecs/max9850.c b/sound/soc/codecs/max9850.c index c14a79d026a1..0610840733d1 100644 --- a/sound/soc/codecs/max9850.c +++ b/sound/soc/codecs/max9850.c | |||
@@ -306,12 +306,14 @@ static struct snd_soc_codec_driver soc_codec_dev_max9850 = { | |||
306 | .set_bias_level = max9850_set_bias_level, | 306 | .set_bias_level = max9850_set_bias_level, |
307 | .suspend_bias_off = true, | 307 | .suspend_bias_off = true, |
308 | 308 | ||
309 | .controls = max9850_controls, | 309 | .component_driver = { |
310 | .num_controls = ARRAY_SIZE(max9850_controls), | 310 | .controls = max9850_controls, |
311 | .dapm_widgets = max9850_dapm_widgets, | 311 | .num_controls = ARRAY_SIZE(max9850_controls), |
312 | .num_dapm_widgets = ARRAY_SIZE(max9850_dapm_widgets), | 312 | .dapm_widgets = max9850_dapm_widgets, |
313 | .dapm_routes = max9850_dapm_routes, | 313 | .num_dapm_widgets = ARRAY_SIZE(max9850_dapm_widgets), |
314 | .num_dapm_routes = ARRAY_SIZE(max9850_dapm_routes), | 314 | .dapm_routes = max9850_dapm_routes, |
315 | .num_dapm_routes = ARRAY_SIZE(max9850_dapm_routes), | ||
316 | }, | ||
315 | }; | 317 | }; |
316 | 318 | ||
317 | static int max9850_i2c_probe(struct i2c_client *i2c, | 319 | static int max9850_i2c_probe(struct i2c_client *i2c, |
diff --git a/sound/soc/codecs/max9860.c b/sound/soc/codecs/max9860.c index 68074c92a7c0..499bdbfd0a2d 100644 --- a/sound/soc/codecs/max9860.c +++ b/sound/soc/codecs/max9860.c | |||
@@ -538,12 +538,14 @@ static struct snd_soc_codec_driver max9860_codec_driver = { | |||
538 | .set_bias_level = max9860_set_bias_level, | 538 | .set_bias_level = max9860_set_bias_level, |
539 | .idle_bias_off = true, | 539 | .idle_bias_off = true, |
540 | 540 | ||
541 | .controls = max9860_controls, | 541 | .component_driver = { |
542 | .num_controls = ARRAY_SIZE(max9860_controls), | 542 | .controls = max9860_controls, |
543 | .dapm_widgets = max9860_dapm_widgets, | 543 | .num_controls = ARRAY_SIZE(max9860_controls), |
544 | .num_dapm_widgets = ARRAY_SIZE(max9860_dapm_widgets), | 544 | .dapm_widgets = max9860_dapm_widgets, |
545 | .dapm_routes = max9860_dapm_routes, | 545 | .num_dapm_widgets = ARRAY_SIZE(max9860_dapm_widgets), |
546 | .num_dapm_routes = ARRAY_SIZE(max9860_dapm_routes), | 546 | .dapm_routes = max9860_dapm_routes, |
547 | .num_dapm_routes = ARRAY_SIZE(max9860_dapm_routes), | ||
548 | }, | ||
547 | }; | 549 | }; |
548 | 550 | ||
549 | #ifdef CONFIG_PM | 551 | #ifdef CONFIG_PM |
diff --git a/sound/soc/codecs/max9867.c b/sound/soc/codecs/max9867.c index 2a22fddeb6af..42e2e407e287 100644 --- a/sound/soc/codecs/max9867.c +++ b/sound/soc/codecs/max9867.c | |||
@@ -38,11 +38,10 @@ static DECLARE_TLV_DB_SCALE(max9860_capture_tlv, -600, 200, 0); | |||
38 | static DECLARE_TLV_DB_SCALE(max9860_mic_tlv, 2000, 100, 1); | 38 | static DECLARE_TLV_DB_SCALE(max9860_mic_tlv, 2000, 100, 1); |
39 | static DECLARE_TLV_DB_SCALE(max9860_adc_left_tlv, -1200, 100, 1); | 39 | static DECLARE_TLV_DB_SCALE(max9860_adc_left_tlv, -1200, 100, 1); |
40 | static DECLARE_TLV_DB_SCALE(max9860_adc_right_tlv, -1200, 100, 1); | 40 | static DECLARE_TLV_DB_SCALE(max9860_adc_right_tlv, -1200, 100, 1); |
41 | static const unsigned int max98088_micboost_tlv[] = { | 41 | static const SNDRV_CTL_TLVD_DECLARE_DB_RANGE(max98088_micboost_tlv, |
42 | TLV_DB_RANGE_HEAD(2), | ||
43 | 0, 1, TLV_DB_SCALE_ITEM(0, 2000, 0), | 42 | 0, 1, TLV_DB_SCALE_ITEM(0, 2000, 0), |
44 | 2, 2, TLV_DB_SCALE_ITEM(3000, 0, 0), | 43 | 2, 2, TLV_DB_SCALE_ITEM(3000, 0, 0), |
45 | }; | 44 | ); |
46 | 45 | ||
47 | static const struct snd_kcontrol_new max9867_snd_controls[] = { | 46 | static const struct snd_kcontrol_new max9867_snd_controls[] = { |
48 | SOC_DOUBLE_R("Master Playback Volume", MAX9867_LEFTVOL, | 47 | SOC_DOUBLE_R("Master Playback Volume", MAX9867_LEFTVOL, |
@@ -417,12 +416,14 @@ static int max9867_probe(struct snd_soc_codec *codec) | |||
417 | 416 | ||
418 | static struct snd_soc_codec_driver max9867_codec = { | 417 | static struct snd_soc_codec_driver max9867_codec = { |
419 | .probe = max9867_probe, | 418 | .probe = max9867_probe, |
420 | .controls = max9867_snd_controls, | 419 | .component_driver = { |
421 | .num_controls = ARRAY_SIZE(max9867_snd_controls), | 420 | .controls = max9867_snd_controls, |
422 | .dapm_routes = max9867_audio_map, | 421 | .num_controls = ARRAY_SIZE(max9867_snd_controls), |
423 | .num_dapm_routes = ARRAY_SIZE(max9867_audio_map), | 422 | .dapm_routes = max9867_audio_map, |
424 | .dapm_widgets = max9867_dapm_widgets, | 423 | .num_dapm_routes = ARRAY_SIZE(max9867_audio_map), |
425 | .num_dapm_widgets = ARRAY_SIZE(max9867_dapm_widgets), | 424 | .dapm_widgets = max9867_dapm_widgets, |
425 | .num_dapm_widgets = ARRAY_SIZE(max9867_dapm_widgets), | ||
426 | }, | ||
426 | }; | 427 | }; |
427 | 428 | ||
428 | static bool max9867_volatile_register(struct device *dev, unsigned int reg) | 429 | static bool max9867_volatile_register(struct device *dev, unsigned int reg) |
diff --git a/sound/soc/codecs/max98925.c b/sound/soc/codecs/max98925.c index 5990de317999..327eaa25c9bd 100644 --- a/sound/soc/codecs/max98925.c +++ b/sound/soc/codecs/max98925.c | |||
@@ -540,12 +540,14 @@ static int max98925_probe(struct snd_soc_codec *codec) | |||
540 | 540 | ||
541 | static const struct snd_soc_codec_driver soc_codec_dev_max98925 = { | 541 | static const struct snd_soc_codec_driver soc_codec_dev_max98925 = { |
542 | .probe = max98925_probe, | 542 | .probe = max98925_probe, |
543 | .controls = max98925_snd_controls, | 543 | .component_driver = { |
544 | .num_controls = ARRAY_SIZE(max98925_snd_controls), | 544 | .controls = max98925_snd_controls, |
545 | .dapm_routes = max98925_audio_map, | 545 | .num_controls = ARRAY_SIZE(max98925_snd_controls), |
546 | .num_dapm_routes = ARRAY_SIZE(max98925_audio_map), | 546 | .dapm_routes = max98925_audio_map, |
547 | .dapm_widgets = max98925_dapm_widgets, | 547 | .num_dapm_routes = ARRAY_SIZE(max98925_audio_map), |
548 | .num_dapm_widgets = ARRAY_SIZE(max98925_dapm_widgets), | 548 | .dapm_widgets = max98925_dapm_widgets, |
549 | .num_dapm_widgets = ARRAY_SIZE(max98925_dapm_widgets), | ||
550 | }, | ||
549 | }; | 551 | }; |
550 | 552 | ||
551 | static const struct regmap_config max98925_regmap = { | 553 | static const struct regmap_config max98925_regmap = { |
diff --git a/sound/soc/codecs/max98926.c b/sound/soc/codecs/max98926.c index 8d14adae5cc5..1eff7e0b092e 100644 --- a/sound/soc/codecs/max98926.c +++ b/sound/soc/codecs/max98926.c | |||
@@ -347,7 +347,7 @@ static int max98926_dai_set_fmt(struct snd_soc_dai *codec_dai, | |||
347 | max98926_set_sense_data(max98926); | 347 | max98926_set_sense_data(max98926); |
348 | break; | 348 | break; |
349 | default: | 349 | default: |
350 | dev_err(codec->dev, "DAI clock mode unsupported"); | 350 | dev_err(codec->dev, "DAI clock mode unsupported\n"); |
351 | return -EINVAL; | 351 | return -EINVAL; |
352 | } | 352 | } |
353 | 353 | ||
@@ -364,7 +364,7 @@ static int max98926_dai_set_fmt(struct snd_soc_dai *codec_dai, | |||
364 | invert = MAX98926_DAI_BCI_MASK | MAX98926_DAI_WCI_MASK; | 364 | invert = MAX98926_DAI_BCI_MASK | MAX98926_DAI_WCI_MASK; |
365 | break; | 365 | break; |
366 | default: | 366 | default: |
367 | dev_err(codec->dev, "DAI invert mode unsupported"); | 367 | dev_err(codec->dev, "DAI invert mode unsupported\n"); |
368 | return -EINVAL; | 368 | return -EINVAL; |
369 | } | 369 | } |
370 | 370 | ||
@@ -408,7 +408,7 @@ static int max98926_dai_hw_params(struct snd_pcm_substream *substream, | |||
408 | max98926->ch_size = 32; | 408 | max98926->ch_size = 32; |
409 | break; | 409 | break; |
410 | default: | 410 | default: |
411 | dev_dbg(codec->dev, "format unsupported %d", | 411 | dev_dbg(codec->dev, "format unsupported %d\n", |
412 | params_format(params)); | 412 | params_format(params)); |
413 | return -EINVAL; | 413 | return -EINVAL; |
414 | } | 414 | } |
@@ -498,12 +498,14 @@ static int max98926_probe(struct snd_soc_codec *codec) | |||
498 | 498 | ||
499 | static struct snd_soc_codec_driver soc_codec_dev_max98926 = { | 499 | static struct snd_soc_codec_driver soc_codec_dev_max98926 = { |
500 | .probe = max98926_probe, | 500 | .probe = max98926_probe, |
501 | .controls = max98926_snd_controls, | 501 | .component_driver = { |
502 | .num_controls = ARRAY_SIZE(max98926_snd_controls), | 502 | .controls = max98926_snd_controls, |
503 | .dapm_routes = max98926_audio_map, | 503 | .num_controls = ARRAY_SIZE(max98926_snd_controls), |
504 | .num_dapm_routes = ARRAY_SIZE(max98926_audio_map), | 504 | .dapm_routes = max98926_audio_map, |
505 | .dapm_widgets = max98926_dapm_widgets, | 505 | .num_dapm_routes = ARRAY_SIZE(max98926_audio_map), |
506 | .num_dapm_widgets = ARRAY_SIZE(max98926_dapm_widgets), | 506 | .dapm_widgets = max98926_dapm_widgets, |
507 | .num_dapm_widgets = ARRAY_SIZE(max98926_dapm_widgets), | ||
508 | }, | ||
507 | }; | 509 | }; |
508 | 510 | ||
509 | static const struct regmap_config max98926_regmap = { | 511 | static const struct regmap_config max98926_regmap = { |
diff --git a/sound/soc/codecs/mc13783.c b/sound/soc/codecs/mc13783.c index 3e770cbe7f0f..90562703dcfd 100644 --- a/sound/soc/codecs/mc13783.c +++ b/sound/soc/codecs/mc13783.c | |||
@@ -737,12 +737,14 @@ static struct snd_soc_codec_driver soc_codec_dev_mc13783 = { | |||
737 | .probe = mc13783_probe, | 737 | .probe = mc13783_probe, |
738 | .remove = mc13783_remove, | 738 | .remove = mc13783_remove, |
739 | .get_regmap = mc13783_get_regmap, | 739 | .get_regmap = mc13783_get_regmap, |
740 | .controls = mc13783_control_list, | 740 | .component_driver = { |
741 | .num_controls = ARRAY_SIZE(mc13783_control_list), | 741 | .controls = mc13783_control_list, |
742 | .dapm_widgets = mc13783_dapm_widgets, | 742 | .num_controls = ARRAY_SIZE(mc13783_control_list), |
743 | .num_dapm_widgets = ARRAY_SIZE(mc13783_dapm_widgets), | 743 | .dapm_widgets = mc13783_dapm_widgets, |
744 | .dapm_routes = mc13783_routes, | 744 | .num_dapm_widgets = ARRAY_SIZE(mc13783_dapm_widgets), |
745 | .num_dapm_routes = ARRAY_SIZE(mc13783_routes), | 745 | .dapm_routes = mc13783_routes, |
746 | .num_dapm_routes = ARRAY_SIZE(mc13783_routes), | ||
747 | }, | ||
746 | }; | 748 | }; |
747 | 749 | ||
748 | static int __init mc13783_codec_probe(struct platform_device *pdev) | 750 | static int __init mc13783_codec_probe(struct platform_device *pdev) |
diff --git a/sound/soc/codecs/ml26124.c b/sound/soc/codecs/ml26124.c index f561c78b9e0e..69e5e18880c5 100644 --- a/sound/soc/codecs/ml26124.c +++ b/sound/soc/codecs/ml26124.c | |||
@@ -541,12 +541,14 @@ static struct snd_soc_codec_driver soc_codec_dev_ml26124 = { | |||
541 | .probe = ml26124_probe, | 541 | .probe = ml26124_probe, |
542 | .set_bias_level = ml26124_set_bias_level, | 542 | .set_bias_level = ml26124_set_bias_level, |
543 | .suspend_bias_off = true, | 543 | .suspend_bias_off = true, |
544 | .dapm_widgets = ml26124_dapm_widgets, | 544 | .component_driver = { |
545 | .num_dapm_widgets = ARRAY_SIZE(ml26124_dapm_widgets), | 545 | .controls = ml26124_snd_controls, |
546 | .dapm_routes = ml26124_intercon, | 546 | .num_controls = ARRAY_SIZE(ml26124_snd_controls), |
547 | .num_dapm_routes = ARRAY_SIZE(ml26124_intercon), | 547 | .dapm_widgets = ml26124_dapm_widgets, |
548 | .controls = ml26124_snd_controls, | 548 | .num_dapm_widgets = ARRAY_SIZE(ml26124_dapm_widgets), |
549 | .num_controls = ARRAY_SIZE(ml26124_snd_controls), | 549 | .dapm_routes = ml26124_intercon, |
550 | .num_dapm_routes = ARRAY_SIZE(ml26124_intercon), | ||
551 | }, | ||
550 | }; | 552 | }; |
551 | 553 | ||
552 | static const struct regmap_config ml26124_i2c_regmap = { | 554 | static const struct regmap_config ml26124_i2c_regmap = { |
diff --git a/sound/soc/codecs/nau8810.c b/sound/soc/codecs/nau8810.c new file mode 100644 index 000000000000..e45518629968 --- /dev/null +++ b/sound/soc/codecs/nau8810.c | |||
@@ -0,0 +1,884 @@ | |||
1 | /* | ||
2 | * nau8810.c -- NAU8810 ALSA Soc Audio driver | ||
3 | * | ||
4 | * Copyright 2016 Nuvoton Technology Corp. | ||
5 | * | ||
6 | * Author: David Lin <ctlin0@nuvoton.com> | ||
7 | * | ||
8 | * Based on WM8974.c | ||
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 version 2 as | ||
12 | * published by the Free Software Foundation. | ||
13 | */ | ||
14 | |||
15 | #include <linux/module.h> | ||
16 | #include <linux/moduleparam.h> | ||
17 | #include <linux/kernel.h> | ||
18 | #include <linux/init.h> | ||
19 | #include <linux/delay.h> | ||
20 | #include <linux/pm.h> | ||
21 | #include <linux/i2c.h> | ||
22 | #include <linux/regmap.h> | ||
23 | #include <linux/slab.h> | ||
24 | #include <sound/core.h> | ||
25 | #include <sound/pcm.h> | ||
26 | #include <sound/pcm_params.h> | ||
27 | #include <sound/soc.h> | ||
28 | #include <sound/initval.h> | ||
29 | #include <sound/tlv.h> | ||
30 | |||
31 | #include "nau8810.h" | ||
32 | |||
33 | #define NAU_PLL_FREQ_MAX 100000000 | ||
34 | #define NAU_PLL_FREQ_MIN 90000000 | ||
35 | #define NAU_PLL_REF_MAX 33000000 | ||
36 | #define NAU_PLL_REF_MIN 8000000 | ||
37 | #define NAU_PLL_OPTOP_MIN 6 | ||
38 | |||
39 | |||
40 | static const int nau8810_mclk_scaler[] = { 10, 15, 20, 30, 40, 60, 80, 120 }; | ||
41 | |||
42 | static const struct reg_default nau8810_reg_defaults[] = { | ||
43 | { NAU8810_REG_POWER1, 0x0000 }, | ||
44 | { NAU8810_REG_POWER2, 0x0000 }, | ||
45 | { NAU8810_REG_POWER3, 0x0000 }, | ||
46 | { NAU8810_REG_IFACE, 0x0050 }, | ||
47 | { NAU8810_REG_COMP, 0x0000 }, | ||
48 | { NAU8810_REG_CLOCK, 0x0140 }, | ||
49 | { NAU8810_REG_SMPLR, 0x0000 }, | ||
50 | { NAU8810_REG_DAC, 0x0000 }, | ||
51 | { NAU8810_REG_DACGAIN, 0x00FF }, | ||
52 | { NAU8810_REG_ADC, 0x0100 }, | ||
53 | { NAU8810_REG_ADCGAIN, 0x00FF }, | ||
54 | { NAU8810_REG_EQ1, 0x012C }, | ||
55 | { NAU8810_REG_EQ2, 0x002C }, | ||
56 | { NAU8810_REG_EQ3, 0x002C }, | ||
57 | { NAU8810_REG_EQ4, 0x002C }, | ||
58 | { NAU8810_REG_EQ5, 0x002C }, | ||
59 | { NAU8810_REG_DACLIM1, 0x0032 }, | ||
60 | { NAU8810_REG_DACLIM2, 0x0000 }, | ||
61 | { NAU8810_REG_NOTCH1, 0x0000 }, | ||
62 | { NAU8810_REG_NOTCH2, 0x0000 }, | ||
63 | { NAU8810_REG_NOTCH3, 0x0000 }, | ||
64 | { NAU8810_REG_NOTCH4, 0x0000 }, | ||
65 | { NAU8810_REG_ALC1, 0x0038 }, | ||
66 | { NAU8810_REG_ALC2, 0x000B }, | ||
67 | { NAU8810_REG_ALC3, 0x0032 }, | ||
68 | { NAU8810_REG_NOISEGATE, 0x0000 }, | ||
69 | { NAU8810_REG_PLLN, 0x0008 }, | ||
70 | { NAU8810_REG_PLLK1, 0x000C }, | ||
71 | { NAU8810_REG_PLLK2, 0x0093 }, | ||
72 | { NAU8810_REG_PLLK3, 0x00E9 }, | ||
73 | { NAU8810_REG_ATTEN, 0x0000 }, | ||
74 | { NAU8810_REG_INPUT_SIGNAL, 0x0003 }, | ||
75 | { NAU8810_REG_PGAGAIN, 0x0010 }, | ||
76 | { NAU8810_REG_ADCBOOST, 0x0100 }, | ||
77 | { NAU8810_REG_OUTPUT, 0x0002 }, | ||
78 | { NAU8810_REG_SPKMIX, 0x0001 }, | ||
79 | { NAU8810_REG_SPKGAIN, 0x0039 }, | ||
80 | { NAU8810_REG_MONOMIX, 0x0001 }, | ||
81 | { NAU8810_REG_POWER4, 0x0000 }, | ||
82 | { NAU8810_REG_TSLOTCTL1, 0x0000 }, | ||
83 | { NAU8810_REG_TSLOTCTL2, 0x0020 }, | ||
84 | { NAU8810_REG_DEVICE_REVID, 0x0000 }, | ||
85 | { NAU8810_REG_I2C_DEVICEID, 0x001A }, | ||
86 | { NAU8810_REG_ADDITIONID, 0x00CA }, | ||
87 | { NAU8810_REG_RESERVE, 0x0124 }, | ||
88 | { NAU8810_REG_OUTCTL, 0x0001 }, | ||
89 | { NAU8810_REG_ALC1ENHAN1, 0x0010 }, | ||
90 | { NAU8810_REG_ALC1ENHAN2, 0x0000 }, | ||
91 | { NAU8810_REG_MISCCTL, 0x0000 }, | ||
92 | { NAU8810_REG_OUTTIEOFF, 0x0000 }, | ||
93 | { NAU8810_REG_AGCP2POUT, 0x0000 }, | ||
94 | { NAU8810_REG_AGCPOUT, 0x0000 }, | ||
95 | { NAU8810_REG_AMTCTL, 0x0000 }, | ||
96 | { NAU8810_REG_OUTTIEOFFMAN, 0x0000 }, | ||
97 | }; | ||
98 | |||
99 | static bool nau8810_readable_reg(struct device *dev, unsigned int reg) | ||
100 | { | ||
101 | switch (reg) { | ||
102 | case NAU8810_REG_RESET ... NAU8810_REG_SMPLR: | ||
103 | case NAU8810_REG_DAC ... NAU8810_REG_DACGAIN: | ||
104 | case NAU8810_REG_ADC ... NAU8810_REG_ADCGAIN: | ||
105 | case NAU8810_REG_EQ1 ... NAU8810_REG_EQ5: | ||
106 | case NAU8810_REG_DACLIM1 ... NAU8810_REG_DACLIM2: | ||
107 | case NAU8810_REG_NOTCH1 ... NAU8810_REG_NOTCH4: | ||
108 | case NAU8810_REG_ALC1 ... NAU8810_REG_ATTEN: | ||
109 | case NAU8810_REG_INPUT_SIGNAL ... NAU8810_REG_PGAGAIN: | ||
110 | case NAU8810_REG_ADCBOOST: | ||
111 | case NAU8810_REG_OUTPUT ... NAU8810_REG_SPKMIX: | ||
112 | case NAU8810_REG_SPKGAIN: | ||
113 | case NAU8810_REG_MONOMIX: | ||
114 | case NAU8810_REG_POWER4 ... NAU8810_REG_TSLOTCTL2: | ||
115 | case NAU8810_REG_DEVICE_REVID ... NAU8810_REG_RESERVE: | ||
116 | case NAU8810_REG_OUTCTL ... NAU8810_REG_ALC1ENHAN2: | ||
117 | case NAU8810_REG_MISCCTL: | ||
118 | case NAU8810_REG_OUTTIEOFF ... NAU8810_REG_OUTTIEOFFMAN: | ||
119 | return true; | ||
120 | default: | ||
121 | return false; | ||
122 | } | ||
123 | } | ||
124 | |||
125 | static bool nau8810_writeable_reg(struct device *dev, unsigned int reg) | ||
126 | { | ||
127 | switch (reg) { | ||
128 | case NAU8810_REG_RESET ... NAU8810_REG_SMPLR: | ||
129 | case NAU8810_REG_DAC ... NAU8810_REG_DACGAIN: | ||
130 | case NAU8810_REG_ADC ... NAU8810_REG_ADCGAIN: | ||
131 | case NAU8810_REG_EQ1 ... NAU8810_REG_EQ5: | ||
132 | case NAU8810_REG_DACLIM1 ... NAU8810_REG_DACLIM2: | ||
133 | case NAU8810_REG_NOTCH1 ... NAU8810_REG_NOTCH4: | ||
134 | case NAU8810_REG_ALC1 ... NAU8810_REG_ATTEN: | ||
135 | case NAU8810_REG_INPUT_SIGNAL ... NAU8810_REG_PGAGAIN: | ||
136 | case NAU8810_REG_ADCBOOST: | ||
137 | case NAU8810_REG_OUTPUT ... NAU8810_REG_SPKMIX: | ||
138 | case NAU8810_REG_SPKGAIN: | ||
139 | case NAU8810_REG_MONOMIX: | ||
140 | case NAU8810_REG_POWER4 ... NAU8810_REG_TSLOTCTL2: | ||
141 | case NAU8810_REG_OUTCTL ... NAU8810_REG_ALC1ENHAN2: | ||
142 | case NAU8810_REG_MISCCTL: | ||
143 | case NAU8810_REG_OUTTIEOFF ... NAU8810_REG_OUTTIEOFFMAN: | ||
144 | return true; | ||
145 | default: | ||
146 | return false; | ||
147 | } | ||
148 | } | ||
149 | |||
150 | static bool nau8810_volatile_reg(struct device *dev, unsigned int reg) | ||
151 | { | ||
152 | switch (reg) { | ||
153 | case NAU8810_REG_RESET: | ||
154 | case NAU8810_REG_DEVICE_REVID ... NAU8810_REG_RESERVE: | ||
155 | return true; | ||
156 | default: | ||
157 | return false; | ||
158 | } | ||
159 | } | ||
160 | |||
161 | /* The EQ parameters get function is to get the 5 band equalizer control. | ||
162 | * The regmap raw read can't work here because regmap doesn't provide | ||
163 | * value format for value width of 9 bits. Therefore, the driver reads data | ||
164 | * from cache and makes value format according to the endianness of | ||
165 | * bytes type control element. | ||
166 | */ | ||
167 | static int nau8810_eq_get(struct snd_kcontrol *kcontrol, | ||
168 | struct snd_ctl_elem_value *ucontrol) | ||
169 | { | ||
170 | struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); | ||
171 | struct nau8810 *nau8810 = snd_soc_codec_get_drvdata(codec); | ||
172 | struct soc_bytes_ext *params = (void *)kcontrol->private_value; | ||
173 | int i, reg, reg_val; | ||
174 | u16 *val; | ||
175 | |||
176 | val = (u16 *)ucontrol->value.bytes.data; | ||
177 | reg = NAU8810_REG_EQ1; | ||
178 | for (i = 0; i < params->max / sizeof(u16); i++) { | ||
179 | regmap_read(nau8810->regmap, reg + i, ®_val); | ||
180 | /* conversion of 16-bit integers between native CPU format | ||
181 | * and big endian format | ||
182 | */ | ||
183 | reg_val = cpu_to_be16(reg_val); | ||
184 | memcpy(val + i, ®_val, sizeof(reg_val)); | ||
185 | } | ||
186 | |||
187 | return 0; | ||
188 | } | ||
189 | |||
190 | /* The EQ parameters put function is to make configuration of 5 band equalizer | ||
191 | * control. These configuration includes central frequency, equalizer gain, | ||
192 | * cut-off frequency, bandwidth control, and equalizer path. | ||
193 | * The regmap raw write can't work here because regmap doesn't provide | ||
194 | * register and value format for register with address 7 bits and value 9 bits. | ||
195 | * Therefore, the driver makes value format according to the endianness of | ||
196 | * bytes type control element and writes data to codec. | ||
197 | */ | ||
198 | static int nau8810_eq_put(struct snd_kcontrol *kcontrol, | ||
199 | struct snd_ctl_elem_value *ucontrol) | ||
200 | { | ||
201 | struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); | ||
202 | struct nau8810 *nau8810 = snd_soc_codec_get_drvdata(codec); | ||
203 | struct soc_bytes_ext *params = (void *)kcontrol->private_value; | ||
204 | void *data; | ||
205 | u16 *val, value; | ||
206 | int i, reg, ret; | ||
207 | |||
208 | data = kmemdup(ucontrol->value.bytes.data, | ||
209 | params->max, GFP_KERNEL | GFP_DMA); | ||
210 | if (!data) | ||
211 | return -ENOMEM; | ||
212 | |||
213 | val = (u16 *)data; | ||
214 | reg = NAU8810_REG_EQ1; | ||
215 | for (i = 0; i < params->max / sizeof(u16); i++) { | ||
216 | /* conversion of 16-bit integers between native CPU format | ||
217 | * and big endian format | ||
218 | */ | ||
219 | value = be16_to_cpu(*(val + i)); | ||
220 | ret = regmap_write(nau8810->regmap, reg + i, value); | ||
221 | if (ret) { | ||
222 | dev_err(codec->dev, "EQ configuration fail, register: %x ret: %d\n", | ||
223 | reg + i, ret); | ||
224 | kfree(data); | ||
225 | return ret; | ||
226 | } | ||
227 | } | ||
228 | kfree(data); | ||
229 | |||
230 | return 0; | ||
231 | } | ||
232 | |||
233 | static const char * const nau8810_companding[] = { | ||
234 | "Off", "NC", "u-law", "A-law" }; | ||
235 | |||
236 | static const struct soc_enum nau8810_companding_adc_enum = | ||
237 | SOC_ENUM_SINGLE(NAU8810_REG_COMP, NAU8810_ADCCM_SFT, | ||
238 | ARRAY_SIZE(nau8810_companding), nau8810_companding); | ||
239 | |||
240 | static const struct soc_enum nau8810_companding_dac_enum = | ||
241 | SOC_ENUM_SINGLE(NAU8810_REG_COMP, NAU8810_DACCM_SFT, | ||
242 | ARRAY_SIZE(nau8810_companding), nau8810_companding); | ||
243 | |||
244 | static const char * const nau8810_deemp[] = { | ||
245 | "None", "32kHz", "44.1kHz", "48kHz" }; | ||
246 | |||
247 | static const struct soc_enum nau8810_deemp_enum = | ||
248 | SOC_ENUM_SINGLE(NAU8810_REG_DAC, NAU8810_DEEMP_SFT, | ||
249 | ARRAY_SIZE(nau8810_deemp), nau8810_deemp); | ||
250 | |||
251 | static const char * const nau8810_eqmode[] = {"Capture", "Playback" }; | ||
252 | |||
253 | static const struct soc_enum nau8810_eqmode_enum = | ||
254 | SOC_ENUM_SINGLE(NAU8810_REG_EQ1, NAU8810_EQM_SFT, | ||
255 | ARRAY_SIZE(nau8810_eqmode), nau8810_eqmode); | ||
256 | |||
257 | static const char * const nau8810_alc[] = {"Normal", "Limiter" }; | ||
258 | |||
259 | static const struct soc_enum nau8810_alc_enum = | ||
260 | SOC_ENUM_SINGLE(NAU8810_REG_ALC3, NAU8810_ALCM_SFT, | ||
261 | ARRAY_SIZE(nau8810_alc), nau8810_alc); | ||
262 | |||
263 | static const DECLARE_TLV_DB_SCALE(digital_tlv, -12750, 50, 1); | ||
264 | static const DECLARE_TLV_DB_SCALE(eq_tlv, -1200, 100, 0); | ||
265 | static const DECLARE_TLV_DB_SCALE(inpga_tlv, -1200, 75, 0); | ||
266 | static const DECLARE_TLV_DB_SCALE(spk_tlv, -5700, 100, 0); | ||
267 | |||
268 | static const struct snd_kcontrol_new nau8810_snd_controls[] = { | ||
269 | SOC_ENUM("ADC Companding", nau8810_companding_adc_enum), | ||
270 | SOC_ENUM("DAC Companding", nau8810_companding_dac_enum), | ||
271 | SOC_ENUM("DAC De-emphasis", nau8810_deemp_enum), | ||
272 | |||
273 | SOC_ENUM("EQ Function", nau8810_eqmode_enum), | ||
274 | SND_SOC_BYTES_EXT("EQ Parameters", 10, | ||
275 | nau8810_eq_get, nau8810_eq_put), | ||
276 | |||
277 | SOC_SINGLE("DAC Inversion Switch", NAU8810_REG_DAC, | ||
278 | NAU8810_DACPL_SFT, 1, 0), | ||
279 | SOC_SINGLE_TLV("Playback Volume", NAU8810_REG_DACGAIN, | ||
280 | NAU8810_DACGAIN_SFT, 0xff, 0, digital_tlv), | ||
281 | |||
282 | SOC_SINGLE("High Pass Filter Switch", NAU8810_REG_ADC, | ||
283 | NAU8810_HPFEN_SFT, 1, 0), | ||
284 | SOC_SINGLE("High Pass Cut Off", NAU8810_REG_ADC, | ||
285 | NAU8810_HPF_SFT, 0x7, 0), | ||
286 | |||
287 | SOC_SINGLE("ADC Inversion Switch", NAU8810_REG_ADC, | ||
288 | NAU8810_ADCPL_SFT, 1, 0), | ||
289 | SOC_SINGLE_TLV("Capture Volume", NAU8810_REG_ADCGAIN, | ||
290 | NAU8810_ADCGAIN_SFT, 0xff, 0, digital_tlv), | ||
291 | |||
292 | SOC_SINGLE_TLV("EQ1 Volume", NAU8810_REG_EQ1, | ||
293 | NAU8810_EQ1GC_SFT, 0x18, 1, eq_tlv), | ||
294 | SOC_SINGLE_TLV("EQ2 Volume", NAU8810_REG_EQ2, | ||
295 | NAU8810_EQ2GC_SFT, 0x18, 1, eq_tlv), | ||
296 | SOC_SINGLE_TLV("EQ3 Volume", NAU8810_REG_EQ3, | ||
297 | NAU8810_EQ3GC_SFT, 0x18, 1, eq_tlv), | ||
298 | SOC_SINGLE_TLV("EQ4 Volume", NAU8810_REG_EQ4, | ||
299 | NAU8810_EQ4GC_SFT, 0x18, 1, eq_tlv), | ||
300 | SOC_SINGLE_TLV("EQ5 Volume", NAU8810_REG_EQ5, | ||
301 | NAU8810_EQ5GC_SFT, 0x18, 1, eq_tlv), | ||
302 | |||
303 | SOC_SINGLE("DAC Limiter Switch", NAU8810_REG_DACLIM1, | ||
304 | NAU8810_DACLIMEN_SFT, 1, 0), | ||
305 | SOC_SINGLE("DAC Limiter Decay", NAU8810_REG_DACLIM1, | ||
306 | NAU8810_DACLIMDCY_SFT, 0xf, 0), | ||
307 | SOC_SINGLE("DAC Limiter Attack", NAU8810_REG_DACLIM1, | ||
308 | NAU8810_DACLIMATK_SFT, 0xf, 0), | ||
309 | SOC_SINGLE("DAC Limiter Threshold", NAU8810_REG_DACLIM2, | ||
310 | NAU8810_DACLIMTHL_SFT, 0x7, 0), | ||
311 | SOC_SINGLE("DAC Limiter Boost", NAU8810_REG_DACLIM2, | ||
312 | NAU8810_DACLIMBST_SFT, 0xf, 0), | ||
313 | |||
314 | SOC_ENUM("ALC Mode", nau8810_alc_enum), | ||
315 | SOC_SINGLE("ALC Enable Switch", NAU8810_REG_ALC1, | ||
316 | NAU8810_ALCEN_SFT, 1, 0), | ||
317 | SOC_SINGLE("ALC Max Volume", NAU8810_REG_ALC1, | ||
318 | NAU8810_ALCMXGAIN_SFT, 0x7, 0), | ||
319 | SOC_SINGLE("ALC Min Volume", NAU8810_REG_ALC1, | ||
320 | NAU8810_ALCMINGAIN_SFT, 0x7, 0), | ||
321 | SOC_SINGLE("ALC ZC Switch", NAU8810_REG_ALC2, | ||
322 | NAU8810_ALCZC_SFT, 1, 0), | ||
323 | SOC_SINGLE("ALC Hold", NAU8810_REG_ALC2, | ||
324 | NAU8810_ALCHT_SFT, 0xf, 0), | ||
325 | SOC_SINGLE("ALC Target", NAU8810_REG_ALC2, | ||
326 | NAU8810_ALCSL_SFT, 0xf, 0), | ||
327 | SOC_SINGLE("ALC Decay", NAU8810_REG_ALC3, | ||
328 | NAU8810_ALCDCY_SFT, 0xf, 0), | ||
329 | SOC_SINGLE("ALC Attack", NAU8810_REG_ALC3, | ||
330 | NAU8810_ALCATK_SFT, 0xf, 0), | ||
331 | SOC_SINGLE("ALC Noise Gate Switch", NAU8810_REG_NOISEGATE, | ||
332 | NAU8810_ALCNEN_SFT, 1, 0), | ||
333 | SOC_SINGLE("ALC Noise Gate Threshold", NAU8810_REG_NOISEGATE, | ||
334 | NAU8810_ALCNTH_SFT, 0x7, 0), | ||
335 | |||
336 | SOC_SINGLE("PGA ZC Switch", NAU8810_REG_PGAGAIN, | ||
337 | NAU8810_PGAZC_SFT, 1, 0), | ||
338 | SOC_SINGLE_TLV("PGA Volume", NAU8810_REG_PGAGAIN, | ||
339 | NAU8810_PGAGAIN_SFT, 0x3f, 0, inpga_tlv), | ||
340 | |||
341 | SOC_SINGLE("Speaker ZC Switch", NAU8810_REG_SPKGAIN, | ||
342 | NAU8810_SPKZC_SFT, 1, 0), | ||
343 | SOC_SINGLE("Speaker Mute Switch", NAU8810_REG_SPKGAIN, | ||
344 | NAU8810_SPKMT_SFT, 1, 0), | ||
345 | SOC_SINGLE_TLV("Speaker Volume", NAU8810_REG_SPKGAIN, | ||
346 | NAU8810_SPKGAIN_SFT, 0x3f, 0, spk_tlv), | ||
347 | |||
348 | SOC_SINGLE("Capture Boost(+20dB)", NAU8810_REG_ADCBOOST, | ||
349 | NAU8810_PGABST_SFT, 1, 0), | ||
350 | SOC_SINGLE("Mono Mute Switch", NAU8810_REG_MONOMIX, | ||
351 | NAU8810_MOUTMXMT_SFT, 1, 0), | ||
352 | |||
353 | SOC_SINGLE("DAC Oversampling Rate(128x) Switch", NAU8810_REG_DAC, | ||
354 | NAU8810_DACOS_SFT, 1, 0), | ||
355 | SOC_SINGLE("ADC Oversampling Rate(128x) Switch", NAU8810_REG_ADC, | ||
356 | NAU8810_ADCOS_SFT, 1, 0), | ||
357 | }; | ||
358 | |||
359 | /* Speaker Output Mixer */ | ||
360 | static const struct snd_kcontrol_new nau8810_speaker_mixer_controls[] = { | ||
361 | SOC_DAPM_SINGLE("Line Bypass Switch", NAU8810_REG_SPKMIX, | ||
362 | NAU8810_BYPSPK_SFT, 1, 0), | ||
363 | SOC_DAPM_SINGLE("PCM Playback Switch", NAU8810_REG_SPKMIX, | ||
364 | NAU8810_DACSPK_SFT, 1, 0), | ||
365 | }; | ||
366 | |||
367 | /* Mono Output Mixer */ | ||
368 | static const struct snd_kcontrol_new nau8810_mono_mixer_controls[] = { | ||
369 | SOC_DAPM_SINGLE("Line Bypass Switch", NAU8810_REG_MONOMIX, | ||
370 | NAU8810_BYPMOUT_SFT, 1, 0), | ||
371 | SOC_DAPM_SINGLE("PCM Playback Switch", NAU8810_REG_MONOMIX, | ||
372 | NAU8810_DACMOUT_SFT, 1, 0), | ||
373 | }; | ||
374 | |||
375 | /* PGA Mute */ | ||
376 | static const struct snd_kcontrol_new nau8810_inpga_mute[] = { | ||
377 | SOC_DAPM_SINGLE("PGA Mute Switch", NAU8810_REG_PGAGAIN, | ||
378 | NAU8810_PGAMT_SFT, 1, 0), | ||
379 | }; | ||
380 | |||
381 | /* Input PGA */ | ||
382 | static const struct snd_kcontrol_new nau8810_inpga[] = { | ||
383 | SOC_DAPM_SINGLE("MicN Switch", NAU8810_REG_INPUT_SIGNAL, | ||
384 | NAU8810_NMICPGA_SFT, 1, 0), | ||
385 | SOC_DAPM_SINGLE("MicP Switch", NAU8810_REG_INPUT_SIGNAL, | ||
386 | NAU8810_PMICPGA_SFT, 1, 0), | ||
387 | }; | ||
388 | |||
389 | /* Mic Input boost vol */ | ||
390 | static const struct snd_kcontrol_new nau8810_mic_boost_controls = | ||
391 | SOC_DAPM_SINGLE("Mic Volume", NAU8810_REG_ADCBOOST, | ||
392 | NAU8810_PMICBSTGAIN_SFT, 0x7, 0); | ||
393 | |||
394 | /* Loopback Switch */ | ||
395 | static const struct snd_kcontrol_new nau8810_loopback = | ||
396 | SOC_DAPM_SINGLE("Switch", NAU8810_REG_COMP, | ||
397 | NAU8810_ADDAP_SFT, 1, 0); | ||
398 | |||
399 | static int check_mclk_select_pll(struct snd_soc_dapm_widget *source, | ||
400 | struct snd_soc_dapm_widget *sink) | ||
401 | { | ||
402 | struct snd_soc_codec *codec = snd_soc_dapm_to_codec(source->dapm); | ||
403 | struct nau8810 *nau8810 = snd_soc_codec_get_drvdata(codec); | ||
404 | unsigned int value; | ||
405 | |||
406 | regmap_read(nau8810->regmap, NAU8810_REG_CLOCK, &value); | ||
407 | return (value & NAU8810_CLKM_MASK); | ||
408 | } | ||
409 | |||
410 | static const struct snd_soc_dapm_widget nau8810_dapm_widgets[] = { | ||
411 | SND_SOC_DAPM_MIXER("Speaker Mixer", NAU8810_REG_POWER3, | ||
412 | NAU8810_SPKMX_EN_SFT, 0, &nau8810_speaker_mixer_controls[0], | ||
413 | ARRAY_SIZE(nau8810_speaker_mixer_controls)), | ||
414 | SND_SOC_DAPM_MIXER("Mono Mixer", NAU8810_REG_POWER3, | ||
415 | NAU8810_MOUTMX_EN_SFT, 0, &nau8810_mono_mixer_controls[0], | ||
416 | ARRAY_SIZE(nau8810_mono_mixer_controls)), | ||
417 | SND_SOC_DAPM_DAC("DAC", "HiFi Playback", NAU8810_REG_POWER3, | ||
418 | NAU8810_DAC_EN_SFT, 0), | ||
419 | SND_SOC_DAPM_ADC("ADC", "HiFi Capture", NAU8810_REG_POWER2, | ||
420 | NAU8810_ADC_EN_SFT, 0), | ||
421 | SND_SOC_DAPM_PGA("SpkN Out", NAU8810_REG_POWER3, | ||
422 | NAU8810_NSPK_EN_SFT, 0, NULL, 0), | ||
423 | SND_SOC_DAPM_PGA("SpkP Out", NAU8810_REG_POWER3, | ||
424 | NAU8810_PSPK_EN_SFT, 0, NULL, 0), | ||
425 | SND_SOC_DAPM_PGA("Mono Out", NAU8810_REG_POWER3, | ||
426 | NAU8810_MOUT_EN_SFT, 0, NULL, 0), | ||
427 | |||
428 | SND_SOC_DAPM_MIXER("Input PGA", NAU8810_REG_POWER2, | ||
429 | NAU8810_PGA_EN_SFT, 0, nau8810_inpga, | ||
430 | ARRAY_SIZE(nau8810_inpga)), | ||
431 | SND_SOC_DAPM_MIXER("Input Boost Stage", NAU8810_REG_POWER2, | ||
432 | NAU8810_BST_EN_SFT, 0, nau8810_inpga_mute, | ||
433 | ARRAY_SIZE(nau8810_inpga_mute)), | ||
434 | |||
435 | SND_SOC_DAPM_SUPPLY("Mic Bias", NAU8810_REG_POWER1, | ||
436 | NAU8810_MICBIAS_EN_SFT, 0, NULL, 0), | ||
437 | SND_SOC_DAPM_SUPPLY("PLL", NAU8810_REG_POWER1, | ||
438 | NAU8810_PLL_EN_SFT, 0, NULL, 0), | ||
439 | |||
440 | SND_SOC_DAPM_SWITCH("Digital Loopback", SND_SOC_NOPM, 0, 0, | ||
441 | &nau8810_loopback), | ||
442 | |||
443 | SND_SOC_DAPM_INPUT("MICN"), | ||
444 | SND_SOC_DAPM_INPUT("MICP"), | ||
445 | SND_SOC_DAPM_OUTPUT("MONOOUT"), | ||
446 | SND_SOC_DAPM_OUTPUT("SPKOUTP"), | ||
447 | SND_SOC_DAPM_OUTPUT("SPKOUTN"), | ||
448 | }; | ||
449 | |||
450 | static const struct snd_soc_dapm_route nau8810_dapm_routes[] = { | ||
451 | {"DAC", NULL, "PLL", check_mclk_select_pll}, | ||
452 | |||
453 | /* Mono output mixer */ | ||
454 | {"Mono Mixer", "PCM Playback Switch", "DAC"}, | ||
455 | {"Mono Mixer", "Line Bypass Switch", "Input Boost Stage"}, | ||
456 | |||
457 | /* Speaker output mixer */ | ||
458 | {"Speaker Mixer", "PCM Playback Switch", "DAC"}, | ||
459 | {"Speaker Mixer", "Line Bypass Switch", "Input Boost Stage"}, | ||
460 | |||
461 | /* Outputs */ | ||
462 | {"Mono Out", NULL, "Mono Mixer"}, | ||
463 | {"MONOOUT", NULL, "Mono Out"}, | ||
464 | {"SpkN Out", NULL, "Speaker Mixer"}, | ||
465 | {"SpkP Out", NULL, "Speaker Mixer"}, | ||
466 | {"SPKOUTN", NULL, "SpkN Out"}, | ||
467 | {"SPKOUTP", NULL, "SpkP Out"}, | ||
468 | |||
469 | /* Input Boost Stage */ | ||
470 | {"ADC", NULL, "Input Boost Stage"}, | ||
471 | {"ADC", NULL, "PLL", check_mclk_select_pll}, | ||
472 | {"Input Boost Stage", NULL, "Input PGA"}, | ||
473 | {"Input Boost Stage", NULL, "MICP"}, | ||
474 | |||
475 | /* Input PGA */ | ||
476 | {"Input PGA", NULL, "Mic Bias"}, | ||
477 | {"Input PGA", "MicN Switch", "MICN"}, | ||
478 | {"Input PGA", "MicP Switch", "MICP"}, | ||
479 | |||
480 | /* Digital Looptack */ | ||
481 | {"Digital Loopback", "Switch", "ADC"}, | ||
482 | {"DAC", NULL, "Digital Loopback"}, | ||
483 | }; | ||
484 | |||
485 | static int nau8810_set_sysclk(struct snd_soc_dai *dai, | ||
486 | int clk_id, unsigned int freq, int dir) | ||
487 | { | ||
488 | struct snd_soc_codec *codec = dai->codec; | ||
489 | struct nau8810 *nau8810 = snd_soc_codec_get_drvdata(codec); | ||
490 | |||
491 | nau8810->clk_id = clk_id; | ||
492 | nau8810->sysclk = freq; | ||
493 | dev_dbg(nau8810->dev, "master sysclk %dHz, source %s\n", | ||
494 | freq, clk_id == NAU8810_SCLK_PLL ? "PLL" : "MCLK"); | ||
495 | |||
496 | return 0; | ||
497 | } | ||
498 | |||
499 | static int nau88l0_calc_pll(unsigned int pll_in, | ||
500 | unsigned int fs, struct nau8810_pll *pll_param) | ||
501 | { | ||
502 | u64 f2, f2_max, pll_ratio; | ||
503 | int i, scal_sel; | ||
504 | |||
505 | if (pll_in > NAU_PLL_REF_MAX || pll_in < NAU_PLL_REF_MIN) | ||
506 | return -EINVAL; | ||
507 | |||
508 | f2_max = 0; | ||
509 | scal_sel = ARRAY_SIZE(nau8810_mclk_scaler); | ||
510 | for (i = 0; i < ARRAY_SIZE(nau8810_mclk_scaler); i++) { | ||
511 | f2 = 256 * fs * 4 * nau8810_mclk_scaler[i] / 10; | ||
512 | if (f2 > NAU_PLL_FREQ_MIN && f2 < NAU_PLL_FREQ_MAX && | ||
513 | f2_max < f2) { | ||
514 | f2_max = f2; | ||
515 | scal_sel = i; | ||
516 | } | ||
517 | } | ||
518 | if (ARRAY_SIZE(nau8810_mclk_scaler) == scal_sel) | ||
519 | return -EINVAL; | ||
520 | pll_param->mclk_scaler = scal_sel; | ||
521 | f2 = f2_max; | ||
522 | |||
523 | /* Calculate the PLL 4-bit integer input and the PLL 24-bit fractional | ||
524 | * input; round up the 24+4bit. | ||
525 | */ | ||
526 | pll_ratio = div_u64(f2 << 28, pll_in); | ||
527 | pll_param->pre_factor = 0; | ||
528 | if (((pll_ratio >> 28) & 0xF) < NAU_PLL_OPTOP_MIN) { | ||
529 | pll_ratio <<= 1; | ||
530 | pll_param->pre_factor = 1; | ||
531 | } | ||
532 | pll_param->pll_int = (pll_ratio >> 28) & 0xF; | ||
533 | pll_param->pll_frac = ((pll_ratio & 0xFFFFFFF) >> 4); | ||
534 | |||
535 | return 0; | ||
536 | } | ||
537 | |||
538 | static int nau8810_set_pll(struct snd_soc_dai *codec_dai, int pll_id, | ||
539 | int source, unsigned int freq_in, unsigned int freq_out) | ||
540 | { | ||
541 | struct snd_soc_codec *codec = codec_dai->codec; | ||
542 | struct nau8810 *nau8810 = snd_soc_codec_get_drvdata(codec); | ||
543 | struct regmap *map = nau8810->regmap; | ||
544 | struct nau8810_pll *pll_param = &nau8810->pll; | ||
545 | int ret, fs; | ||
546 | |||
547 | fs = freq_out / 256; | ||
548 | ret = nau88l0_calc_pll(freq_in, fs, pll_param); | ||
549 | if (ret < 0) { | ||
550 | dev_err(nau8810->dev, "Unsupported input clock %d\n", freq_in); | ||
551 | return ret; | ||
552 | } | ||
553 | dev_info(nau8810->dev, "pll_int=%x pll_frac=%x mclk_scaler=%x pre_factor=%x\n", | ||
554 | pll_param->pll_int, pll_param->pll_frac, pll_param->mclk_scaler, | ||
555 | pll_param->pre_factor); | ||
556 | |||
557 | regmap_update_bits(map, NAU8810_REG_PLLN, | ||
558 | NAU8810_PLLMCLK_DIV2 | NAU8810_PLLN_MASK, | ||
559 | (pll_param->pre_factor ? NAU8810_PLLMCLK_DIV2 : 0) | | ||
560 | pll_param->pll_int); | ||
561 | regmap_write(map, NAU8810_REG_PLLK1, | ||
562 | (pll_param->pll_frac >> NAU8810_PLLK1_SFT) & | ||
563 | NAU8810_PLLK1_MASK); | ||
564 | regmap_write(map, NAU8810_REG_PLLK2, | ||
565 | (pll_param->pll_frac >> NAU8810_PLLK2_SFT) & | ||
566 | NAU8810_PLLK2_MASK); | ||
567 | regmap_write(map, NAU8810_REG_PLLK3, | ||
568 | pll_param->pll_frac & NAU8810_PLLK3_MASK); | ||
569 | regmap_update_bits(map, NAU8810_REG_CLOCK, NAU8810_MCLKSEL_MASK, | ||
570 | pll_param->mclk_scaler << NAU8810_MCLKSEL_SFT); | ||
571 | regmap_update_bits(map, NAU8810_REG_CLOCK, | ||
572 | NAU8810_CLKM_MASK, NAU8810_CLKM_PLL); | ||
573 | |||
574 | return 0; | ||
575 | } | ||
576 | |||
577 | static int nau8810_set_dai_fmt(struct snd_soc_dai *codec_dai, | ||
578 | unsigned int fmt) | ||
579 | { | ||
580 | struct snd_soc_codec *codec = codec_dai->codec; | ||
581 | struct nau8810 *nau8810 = snd_soc_codec_get_drvdata(codec); | ||
582 | u16 ctrl1_val = 0, ctrl2_val = 0; | ||
583 | |||
584 | switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { | ||
585 | case SND_SOC_DAIFMT_CBM_CFM: | ||
586 | ctrl2_val |= NAU8810_CLKIO_MASTER; | ||
587 | break; | ||
588 | case SND_SOC_DAIFMT_CBS_CFS: | ||
589 | break; | ||
590 | default: | ||
591 | return -EINVAL; | ||
592 | } | ||
593 | |||
594 | switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { | ||
595 | case SND_SOC_DAIFMT_I2S: | ||
596 | ctrl1_val |= NAU8810_AIFMT_I2S; | ||
597 | break; | ||
598 | case SND_SOC_DAIFMT_RIGHT_J: | ||
599 | break; | ||
600 | case SND_SOC_DAIFMT_LEFT_J: | ||
601 | ctrl1_val |= NAU8810_AIFMT_LEFT; | ||
602 | break; | ||
603 | case SND_SOC_DAIFMT_DSP_A: | ||
604 | ctrl1_val |= NAU8810_AIFMT_PCM_A; | ||
605 | break; | ||
606 | default: | ||
607 | return -EINVAL; | ||
608 | } | ||
609 | |||
610 | switch (fmt & SND_SOC_DAIFMT_INV_MASK) { | ||
611 | case SND_SOC_DAIFMT_NB_NF: | ||
612 | break; | ||
613 | case SND_SOC_DAIFMT_IB_IF: | ||
614 | ctrl1_val |= NAU8810_BCLKP_IB | NAU8810_FSP_IF; | ||
615 | break; | ||
616 | case SND_SOC_DAIFMT_IB_NF: | ||
617 | ctrl1_val |= NAU8810_BCLKP_IB; | ||
618 | break; | ||
619 | case SND_SOC_DAIFMT_NB_IF: | ||
620 | ctrl1_val |= NAU8810_FSP_IF; | ||
621 | break; | ||
622 | default: | ||
623 | return -EINVAL; | ||
624 | } | ||
625 | |||
626 | regmap_update_bits(nau8810->regmap, NAU8810_REG_IFACE, | ||
627 | NAU8810_AIFMT_MASK | NAU8810_FSP_IF | | ||
628 | NAU8810_BCLKP_IB, ctrl1_val); | ||
629 | regmap_update_bits(nau8810->regmap, NAU8810_REG_CLOCK, | ||
630 | NAU8810_CLKIO_MASK, ctrl2_val); | ||
631 | |||
632 | return 0; | ||
633 | } | ||
634 | |||
635 | static int nau8810_mclk_clkdiv(struct nau8810 *nau8810, int rate) | ||
636 | { | ||
637 | int i, sclk, imclk = rate * 256, div = 0; | ||
638 | |||
639 | if (!nau8810->sysclk) { | ||
640 | dev_err(nau8810->dev, "Make mclk div configuration fail because of invalid system clock\n"); | ||
641 | return -EINVAL; | ||
642 | } | ||
643 | |||
644 | /* Configure the master clock prescaler div to make system | ||
645 | * clock to approximate the internal master clock (IMCLK); | ||
646 | * and large or equal to IMCLK. | ||
647 | */ | ||
648 | for (i = 1; i < ARRAY_SIZE(nau8810_mclk_scaler); i++) { | ||
649 | sclk = (nau8810->sysclk * 10) / | ||
650 | nau8810_mclk_scaler[i]; | ||
651 | if (sclk < imclk) | ||
652 | break; | ||
653 | div = i; | ||
654 | } | ||
655 | dev_dbg(nau8810->dev, | ||
656 | "master clock prescaler %x for fs %d\n", div, rate); | ||
657 | |||
658 | /* master clock from MCLK and disable PLL */ | ||
659 | regmap_update_bits(nau8810->regmap, NAU8810_REG_CLOCK, | ||
660 | NAU8810_MCLKSEL_MASK, (div << NAU8810_MCLKSEL_SFT)); | ||
661 | regmap_update_bits(nau8810->regmap, NAU8810_REG_CLOCK, | ||
662 | NAU8810_CLKM_MASK, NAU8810_CLKM_MCLK); | ||
663 | |||
664 | return 0; | ||
665 | } | ||
666 | |||
667 | static int nau8810_pcm_hw_params(struct snd_pcm_substream *substream, | ||
668 | struct snd_pcm_hw_params *params, struct snd_soc_dai *dai) | ||
669 | { | ||
670 | struct snd_soc_codec *codec = dai->codec; | ||
671 | struct nau8810 *nau8810 = snd_soc_codec_get_drvdata(codec); | ||
672 | int val_len = 0, val_rate = 0, ret = 0; | ||
673 | |||
674 | switch (params_width(params)) { | ||
675 | case 16: | ||
676 | break; | ||
677 | case 20: | ||
678 | val_len |= NAU8810_WLEN_20; | ||
679 | break; | ||
680 | case 24: | ||
681 | val_len |= NAU8810_WLEN_24; | ||
682 | break; | ||
683 | case 32: | ||
684 | val_len |= NAU8810_WLEN_32; | ||
685 | break; | ||
686 | } | ||
687 | |||
688 | switch (params_rate(params)) { | ||
689 | case 8000: | ||
690 | val_rate |= NAU8810_SMPLR_8K; | ||
691 | break; | ||
692 | case 11025: | ||
693 | val_rate |= NAU8810_SMPLR_12K; | ||
694 | break; | ||
695 | case 16000: | ||
696 | val_rate |= NAU8810_SMPLR_16K; | ||
697 | break; | ||
698 | case 22050: | ||
699 | val_rate |= NAU8810_SMPLR_24K; | ||
700 | break; | ||
701 | case 32000: | ||
702 | val_rate |= NAU8810_SMPLR_32K; | ||
703 | break; | ||
704 | case 44100: | ||
705 | case 48000: | ||
706 | break; | ||
707 | } | ||
708 | |||
709 | regmap_update_bits(nau8810->regmap, NAU8810_REG_IFACE, | ||
710 | NAU8810_WLEN_MASK, val_len); | ||
711 | regmap_update_bits(nau8810->regmap, NAU8810_REG_SMPLR, | ||
712 | NAU8810_SMPLR_MASK, val_rate); | ||
713 | |||
714 | /* If the master clock is from MCLK, provide the runtime FS for driver | ||
715 | * to get the master clock prescaler configuration. | ||
716 | */ | ||
717 | if (nau8810->clk_id == NAU8810_SCLK_MCLK) { | ||
718 | ret = nau8810_mclk_clkdiv(nau8810, params_rate(params)); | ||
719 | if (ret < 0) | ||
720 | dev_err(nau8810->dev, "MCLK div configuration fail\n"); | ||
721 | } | ||
722 | |||
723 | return ret; | ||
724 | } | ||
725 | |||
726 | static int nau8810_set_bias_level(struct snd_soc_codec *codec, | ||
727 | enum snd_soc_bias_level level) | ||
728 | { | ||
729 | struct nau8810 *nau8810 = snd_soc_codec_get_drvdata(codec); | ||
730 | struct regmap *map = nau8810->regmap; | ||
731 | |||
732 | switch (level) { | ||
733 | case SND_SOC_BIAS_ON: | ||
734 | case SND_SOC_BIAS_PREPARE: | ||
735 | regmap_update_bits(map, NAU8810_REG_POWER1, | ||
736 | NAU8810_REFIMP_MASK, NAU8810_REFIMP_80K); | ||
737 | break; | ||
738 | |||
739 | case SND_SOC_BIAS_STANDBY: | ||
740 | regmap_update_bits(map, NAU8810_REG_POWER1, | ||
741 | NAU8810_IOBUF_EN | NAU8810_ABIAS_EN, | ||
742 | NAU8810_IOBUF_EN | NAU8810_ABIAS_EN); | ||
743 | |||
744 | if (snd_soc_codec_get_bias_level(codec) == SND_SOC_BIAS_OFF) { | ||
745 | regcache_sync(map); | ||
746 | regmap_update_bits(map, NAU8810_REG_POWER1, | ||
747 | NAU8810_REFIMP_MASK, NAU8810_REFIMP_3K); | ||
748 | mdelay(100); | ||
749 | } | ||
750 | regmap_update_bits(map, NAU8810_REG_POWER1, | ||
751 | NAU8810_REFIMP_MASK, NAU8810_REFIMP_300K); | ||
752 | break; | ||
753 | |||
754 | case SND_SOC_BIAS_OFF: | ||
755 | regmap_write(map, NAU8810_REG_POWER1, 0); | ||
756 | regmap_write(map, NAU8810_REG_POWER2, 0); | ||
757 | regmap_write(map, NAU8810_REG_POWER3, 0); | ||
758 | break; | ||
759 | } | ||
760 | |||
761 | return 0; | ||
762 | } | ||
763 | |||
764 | |||
765 | #define NAU8810_RATES (SNDRV_PCM_RATE_8000_48000) | ||
766 | |||
767 | #define NAU8810_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE | \ | ||
768 | SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE) | ||
769 | |||
770 | static const struct snd_soc_dai_ops nau8810_ops = { | ||
771 | .hw_params = nau8810_pcm_hw_params, | ||
772 | .set_fmt = nau8810_set_dai_fmt, | ||
773 | .set_sysclk = nau8810_set_sysclk, | ||
774 | .set_pll = nau8810_set_pll, | ||
775 | }; | ||
776 | |||
777 | static struct snd_soc_dai_driver nau8810_dai = { | ||
778 | .name = "nau8810-hifi", | ||
779 | .playback = { | ||
780 | .stream_name = "Playback", | ||
781 | .channels_min = 1, | ||
782 | .channels_max = 2, /* Only 1 channel of data */ | ||
783 | .rates = NAU8810_RATES, | ||
784 | .formats = NAU8810_FORMATS, | ||
785 | }, | ||
786 | .capture = { | ||
787 | .stream_name = "Capture", | ||
788 | .channels_min = 1, | ||
789 | .channels_max = 2, /* Only 1 channel of data */ | ||
790 | .rates = NAU8810_RATES, | ||
791 | .formats = NAU8810_FORMATS, | ||
792 | }, | ||
793 | .ops = &nau8810_ops, | ||
794 | .symmetric_rates = 1, | ||
795 | }; | ||
796 | |||
797 | static const struct regmap_config nau8810_regmap_config = { | ||
798 | .reg_bits = 7, | ||
799 | .val_bits = 9, | ||
800 | |||
801 | .max_register = NAU8810_REG_MAX, | ||
802 | .readable_reg = nau8810_readable_reg, | ||
803 | .writeable_reg = nau8810_writeable_reg, | ||
804 | .volatile_reg = nau8810_volatile_reg, | ||
805 | |||
806 | .cache_type = REGCACHE_RBTREE, | ||
807 | .reg_defaults = nau8810_reg_defaults, | ||
808 | .num_reg_defaults = ARRAY_SIZE(nau8810_reg_defaults), | ||
809 | }; | ||
810 | |||
811 | static struct snd_soc_codec_driver nau8810_codec_driver = { | ||
812 | .set_bias_level = nau8810_set_bias_level, | ||
813 | .suspend_bias_off = true, | ||
814 | |||
815 | .component_driver = { | ||
816 | .controls = nau8810_snd_controls, | ||
817 | .num_controls = ARRAY_SIZE(nau8810_snd_controls), | ||
818 | .dapm_widgets = nau8810_dapm_widgets, | ||
819 | .num_dapm_widgets = ARRAY_SIZE(nau8810_dapm_widgets), | ||
820 | .dapm_routes = nau8810_dapm_routes, | ||
821 | .num_dapm_routes = ARRAY_SIZE(nau8810_dapm_routes), | ||
822 | }, | ||
823 | }; | ||
824 | |||
825 | static int nau8810_i2c_probe(struct i2c_client *i2c, | ||
826 | const struct i2c_device_id *id) | ||
827 | { | ||
828 | struct device *dev = &i2c->dev; | ||
829 | struct nau8810 *nau8810 = dev_get_platdata(dev); | ||
830 | |||
831 | if (!nau8810) { | ||
832 | nau8810 = devm_kzalloc(dev, sizeof(*nau8810), GFP_KERNEL); | ||
833 | if (!nau8810) | ||
834 | return -ENOMEM; | ||
835 | } | ||
836 | i2c_set_clientdata(i2c, nau8810); | ||
837 | |||
838 | nau8810->regmap = devm_regmap_init_i2c(i2c, &nau8810_regmap_config); | ||
839 | if (IS_ERR(nau8810->regmap)) | ||
840 | return PTR_ERR(nau8810->regmap); | ||
841 | nau8810->dev = dev; | ||
842 | |||
843 | regmap_write(nau8810->regmap, NAU8810_REG_RESET, 0x00); | ||
844 | |||
845 | return snd_soc_register_codec(dev, | ||
846 | &nau8810_codec_driver, &nau8810_dai, 1); | ||
847 | } | ||
848 | |||
849 | static int nau8810_i2c_remove(struct i2c_client *client) | ||
850 | { | ||
851 | snd_soc_unregister_codec(&client->dev); | ||
852 | |||
853 | return 0; | ||
854 | } | ||
855 | |||
856 | static const struct i2c_device_id nau8810_i2c_id[] = { | ||
857 | { "nau8810", 0 }, | ||
858 | { } | ||
859 | }; | ||
860 | MODULE_DEVICE_TABLE(i2c, nau8810_i2c_id); | ||
861 | |||
862 | #ifdef CONFIG_OF | ||
863 | static const struct of_device_id nau8810_of_match[] = { | ||
864 | { .compatible = "nuvoton,nau8810", }, | ||
865 | { } | ||
866 | }; | ||
867 | MODULE_DEVICE_TABLE(of, nau8810_of_match); | ||
868 | #endif | ||
869 | |||
870 | static struct i2c_driver nau8810_i2c_driver = { | ||
871 | .driver = { | ||
872 | .name = "nau8810", | ||
873 | .of_match_table = of_match_ptr(nau8810_of_match), | ||
874 | }, | ||
875 | .probe = nau8810_i2c_probe, | ||
876 | .remove = nau8810_i2c_remove, | ||
877 | .id_table = nau8810_i2c_id, | ||
878 | }; | ||
879 | |||
880 | module_i2c_driver(nau8810_i2c_driver); | ||
881 | |||
882 | MODULE_DESCRIPTION("ASoC NAU8810 driver"); | ||
883 | MODULE_AUTHOR("David Lin <ctlin0@nuvoton.com>"); | ||
884 | MODULE_LICENSE("GPL v2"); | ||
diff --git a/sound/soc/codecs/nau8810.h b/sound/soc/codecs/nau8810.h new file mode 100644 index 000000000000..df882658ca91 --- /dev/null +++ b/sound/soc/codecs/nau8810.h | |||
@@ -0,0 +1,281 @@ | |||
1 | /* | ||
2 | * NAU8810 ALSA SoC audio driver | ||
3 | * | ||
4 | * Copyright 2016 Nuvoton Technology Corp. | ||
5 | * Author: David Lin <ctlin0@nuvoton.com> | ||
6 | * | ||
7 | * This program is free software; you can redistribute it and/or modify | ||
8 | * it under the terms of the GNU General Public License version 2 as | ||
9 | * published by the Free Software Foundation. | ||
10 | */ | ||
11 | |||
12 | #ifndef __NAU8810_H__ | ||
13 | #define __NAU8810_H__ | ||
14 | |||
15 | #define NAU8810_REG_RESET 0x00 | ||
16 | #define NAU8810_REG_POWER1 0x01 | ||
17 | #define NAU8810_REG_POWER2 0x02 | ||
18 | #define NAU8810_REG_POWER3 0x03 | ||
19 | #define NAU8810_REG_IFACE 0x04 | ||
20 | #define NAU8810_REG_COMP 0x05 | ||
21 | #define NAU8810_REG_CLOCK 0x06 | ||
22 | #define NAU8810_REG_SMPLR 0x07 | ||
23 | #define NAU8810_REG_DAC 0x0A | ||
24 | #define NAU8810_REG_DACGAIN 0x0B | ||
25 | #define NAU8810_REG_ADC 0x0E | ||
26 | #define NAU8810_REG_ADCGAIN 0x0F | ||
27 | #define NAU8810_REG_EQ1 0x12 | ||
28 | #define NAU8810_REG_EQ2 0x13 | ||
29 | #define NAU8810_REG_EQ3 0x14 | ||
30 | #define NAU8810_REG_EQ4 0x15 | ||
31 | #define NAU8810_REG_EQ5 0x16 | ||
32 | #define NAU8810_REG_DACLIM1 0x18 | ||
33 | #define NAU8810_REG_DACLIM2 0x19 | ||
34 | #define NAU8810_REG_NOTCH1 0x1B | ||
35 | #define NAU8810_REG_NOTCH2 0x1C | ||
36 | #define NAU8810_REG_NOTCH3 0x1D | ||
37 | #define NAU8810_REG_NOTCH4 0x1E | ||
38 | #define NAU8810_REG_ALC1 0x20 | ||
39 | #define NAU8810_REG_ALC2 0x21 | ||
40 | #define NAU8810_REG_ALC3 0x22 | ||
41 | #define NAU8810_REG_NOISEGATE 0x23 | ||
42 | #define NAU8810_REG_PLLN 0x24 | ||
43 | #define NAU8810_REG_PLLK1 0x25 | ||
44 | #define NAU8810_REG_PLLK2 0x26 | ||
45 | #define NAU8810_REG_PLLK3 0x27 | ||
46 | #define NAU8810_REG_ATTEN 0x28 | ||
47 | #define NAU8810_REG_INPUT_SIGNAL 0x2C | ||
48 | #define NAU8810_REG_PGAGAIN 0x2D | ||
49 | #define NAU8810_REG_ADCBOOST 0x2F | ||
50 | #define NAU8810_REG_OUTPUT 0x31 | ||
51 | #define NAU8810_REG_SPKMIX 0x32 | ||
52 | #define NAU8810_REG_SPKGAIN 0x36 | ||
53 | #define NAU8810_REG_MONOMIX 0x38 | ||
54 | #define NAU8810_REG_POWER4 0x3A | ||
55 | #define NAU8810_REG_TSLOTCTL1 0x3B | ||
56 | #define NAU8810_REG_TSLOTCTL2 0x3C | ||
57 | #define NAU8810_REG_DEVICE_REVID 0x3E | ||
58 | #define NAU8810_REG_I2C_DEVICEID 0x3F | ||
59 | #define NAU8810_REG_ADDITIONID 0x40 | ||
60 | #define NAU8810_REG_RESERVE 0x41 | ||
61 | #define NAU8810_REG_OUTCTL 0x45 | ||
62 | #define NAU8810_REG_ALC1ENHAN1 0x46 | ||
63 | #define NAU8810_REG_ALC1ENHAN2 0x47 | ||
64 | #define NAU8810_REG_MISCCTL 0x49 | ||
65 | #define NAU8810_REG_OUTTIEOFF 0x4B | ||
66 | #define NAU8810_REG_AGCP2POUT 0x4C | ||
67 | #define NAU8810_REG_AGCPOUT 0x4D | ||
68 | #define NAU8810_REG_AMTCTL 0x4E | ||
69 | #define NAU8810_REG_OUTTIEOFFMAN 0x4F | ||
70 | #define NAU8810_REG_MAX NAU8810_REG_OUTTIEOFFMAN | ||
71 | |||
72 | |||
73 | /* NAU8810_REG_POWER1 (0x1) */ | ||
74 | #define NAU8810_DCBUF_EN (0x1 << 8) | ||
75 | #define NAU8810_PLL_EN_SFT 5 | ||
76 | #define NAU8810_MICBIAS_EN_SFT 4 | ||
77 | #define NAU8810_ABIAS_EN (0x1 << 3) | ||
78 | #define NAU8810_IOBUF_EN (0x1 << 2) | ||
79 | #define NAU8810_REFIMP_MASK 0x3 | ||
80 | #define NAU8810_REFIMP_DIS 0x0 | ||
81 | #define NAU8810_REFIMP_80K 0x1 | ||
82 | #define NAU8810_REFIMP_300K 0x2 | ||
83 | #define NAU8810_REFIMP_3K 0x3 | ||
84 | |||
85 | /* NAU8810_REG_POWER2 (0x2) */ | ||
86 | #define NAU8810_BST_EN_SFT 4 | ||
87 | #define NAU8810_PGA_EN_SFT 2 | ||
88 | #define NAU8810_ADC_EN_SFT 0 | ||
89 | |||
90 | /* NAU8810_REG_POWER3 (0x3) */ | ||
91 | #define NAU8810_DAC_EN_SFT 0 | ||
92 | #define NAU8810_SPKMX_EN_SFT 2 | ||
93 | #define NAU8810_MOUTMX_EN_SFT 3 | ||
94 | #define NAU8810_PSPK_EN_SFT 5 | ||
95 | #define NAU8810_NSPK_EN_SFT 6 | ||
96 | #define NAU8810_MOUT_EN_SFT 7 | ||
97 | |||
98 | /* NAU8810_REG_IFACE (0x4) */ | ||
99 | #define NAU8810_AIFMT_SFT 3 | ||
100 | #define NAU8810_AIFMT_MASK (0x3 << NAU8810_AIFMT_SFT) | ||
101 | #define NAU8810_AIFMT_RIGHT (0x0 << NAU8810_AIFMT_SFT) | ||
102 | #define NAU8810_AIFMT_LEFT (0x1 << NAU8810_AIFMT_SFT) | ||
103 | #define NAU8810_AIFMT_I2S (0x2 << NAU8810_AIFMT_SFT) | ||
104 | #define NAU8810_AIFMT_PCM_A (0x3 << NAU8810_AIFMT_SFT) | ||
105 | #define NAU8810_WLEN_SFT 5 | ||
106 | #define NAU8810_WLEN_MASK (0x3 << NAU8810_WLEN_SFT) | ||
107 | #define NAU8810_WLEN_16 (0x0 << NAU8810_WLEN_SFT) | ||
108 | #define NAU8810_WLEN_20 (0x1 << NAU8810_WLEN_SFT) | ||
109 | #define NAU8810_WLEN_24 (0x2 << NAU8810_WLEN_SFT) | ||
110 | #define NAU8810_WLEN_32 (0x3 << NAU8810_WLEN_SFT) | ||
111 | #define NAU8810_FSP_IF (0x1 << 7) | ||
112 | #define NAU8810_BCLKP_IB (0x1 << 8) | ||
113 | |||
114 | /* NAU8810_REG_COMP (0x5) */ | ||
115 | #define NAU8810_ADDAP_SFT 0 | ||
116 | #define NAU8810_ADCCM_SFT 1 | ||
117 | #define NAU8810_DACCM_SFT 3 | ||
118 | |||
119 | /* NAU8810_REG_CLOCK (0x6) */ | ||
120 | #define NAU8810_CLKIO_MASK 0x1 | ||
121 | #define NAU8810_CLKIO_SLAVE 0x0 | ||
122 | #define NAU8810_CLKIO_MASTER 0x1 | ||
123 | #define NAU8810_BCLKSEL_SFT 2 | ||
124 | #define NAU8810_BCLKSEL_MASK (0x7 << NAU8810_BCLKSEL_SFT) | ||
125 | #define NAU8810_BCLKDIV_1 (0x0 << NAU8810_BCLKSEL_SFT) | ||
126 | #define NAU8810_BCLKDIV_2 (0x1 << NAU8810_BCLKSEL_SFT) | ||
127 | #define NAU8810_BCLKDIV_4 (0x2 << NAU8810_BCLKSEL_SFT) | ||
128 | #define NAU8810_BCLKDIV_8 (0x3 << NAU8810_BCLKSEL_SFT) | ||
129 | #define NAU8810_BCLKDIV_16 (0x4 << NAU8810_BCLKSEL_SFT) | ||
130 | #define NAU8810_BCLKDIV_32 (0x5 << NAU8810_BCLKSEL_SFT) | ||
131 | #define NAU8810_MCLKSEL_SFT 5 | ||
132 | #define NAU8810_MCLKSEL_MASK (0x7 << NAU8810_MCLKSEL_SFT) | ||
133 | #define NAU8810_CLKM_SFT 8 | ||
134 | #define NAU8810_CLKM_MASK (0x1 << NAU8810_CLKM_SFT) | ||
135 | #define NAU8810_CLKM_MCLK (0x0 << NAU8810_CLKM_SFT) | ||
136 | #define NAU8810_CLKM_PLL (0x1 << NAU8810_CLKM_SFT) | ||
137 | |||
138 | /* NAU8810_REG_SMPLR (0x7) */ | ||
139 | #define NAU8810_SMPLR_SFT 1 | ||
140 | #define NAU8810_SMPLR_MASK (0x7 << NAU8810_SMPLR_SFT) | ||
141 | #define NAU8810_SMPLR_48K (0x0 << NAU8810_SMPLR_SFT) | ||
142 | #define NAU8810_SMPLR_32K (0x1 << NAU8810_SMPLR_SFT) | ||
143 | #define NAU8810_SMPLR_24K (0x2 << NAU8810_SMPLR_SFT) | ||
144 | #define NAU8810_SMPLR_16K (0x3 << NAU8810_SMPLR_SFT) | ||
145 | #define NAU8810_SMPLR_12K (0x4 << NAU8810_SMPLR_SFT) | ||
146 | #define NAU8810_SMPLR_8K (0x5 << NAU8810_SMPLR_SFT) | ||
147 | |||
148 | /* NAU8810_REG_DAC (0xA) */ | ||
149 | #define NAU8810_DACPL_SFT 0 | ||
150 | #define NAU8810_DACOS_SFT 3 | ||
151 | #define NAU8810_DEEMP_SFT 4 | ||
152 | |||
153 | /* NAU8810_REG_DACGAIN (0xB) */ | ||
154 | #define NAU8810_DACGAIN_SFT 0 | ||
155 | |||
156 | /* NAU8810_REG_ADC (0xE) */ | ||
157 | #define NAU8810_ADCPL_SFT 0 | ||
158 | #define NAU8810_ADCOS_SFT 3 | ||
159 | #define NAU8810_HPF_SFT 4 | ||
160 | #define NAU8810_HPFEN_SFT 8 | ||
161 | |||
162 | /* NAU8810_REG_ADCGAIN (0xF) */ | ||
163 | #define NAU8810_ADCGAIN_SFT 0 | ||
164 | |||
165 | /* NAU8810_REG_EQ1 (0x12) */ | ||
166 | #define NAU8810_EQ1GC_SFT 0 | ||
167 | #define NAU8810_EQ1CF_SFT 5 | ||
168 | #define NAU8810_EQM_SFT 8 | ||
169 | |||
170 | /* NAU8810_REG_EQ2 (0x13) */ | ||
171 | #define NAU8810_EQ2GC_SFT 0 | ||
172 | #define NAU8810_EQ2CF_SFT 5 | ||
173 | #define NAU8810_EQ2BW_SFT 8 | ||
174 | |||
175 | /* NAU8810_REG_EQ3 (0x14) */ | ||
176 | #define NAU8810_EQ3GC_SFT 0 | ||
177 | #define NAU8810_EQ3CF_SFT 5 | ||
178 | #define NAU8810_EQ3BW_SFT 8 | ||
179 | |||
180 | /* NAU8810_REG_EQ4 (0x15) */ | ||
181 | #define NAU8810_EQ4GC_SFT 0 | ||
182 | #define NAU8810_EQ4CF_SFT 5 | ||
183 | #define NAU8810_EQ4BW_SFT 8 | ||
184 | |||
185 | /* NAU8810_REG_EQ5 (0x16) */ | ||
186 | #define NAU8810_EQ5GC_SFT 0 | ||
187 | #define NAU8810_EQ5CF_SFT 5 | ||
188 | |||
189 | /* NAU8810_REG_DACLIM1 (0x18) */ | ||
190 | #define NAU8810_DACLIMATK_SFT 0 | ||
191 | #define NAU8810_DACLIMDCY_SFT 4 | ||
192 | #define NAU8810_DACLIMEN_SFT 8 | ||
193 | |||
194 | /* NAU8810_REG_DACLIM2 (0x19) */ | ||
195 | #define NAU8810_DACLIMBST_SFT 0 | ||
196 | #define NAU8810_DACLIMTHL_SFT 4 | ||
197 | |||
198 | /* NAU8810_REG_ALC1 (0x20) */ | ||
199 | #define NAU8810_ALCMINGAIN_SFT 0 | ||
200 | #define NAU8810_ALCMXGAIN_SFT 3 | ||
201 | #define NAU8810_ALCEN_SFT 8 | ||
202 | |||
203 | /* NAU8810_REG_ALC2 (0x21) */ | ||
204 | #define NAU8810_ALCSL_SFT 0 | ||
205 | #define NAU8810_ALCHT_SFT 4 | ||
206 | #define NAU8810_ALCZC_SFT 8 | ||
207 | |||
208 | /* NAU8810_REG_ALC3 (0x22) */ | ||
209 | #define NAU8810_ALCATK_SFT 0 | ||
210 | #define NAU8810_ALCDCY_SFT 4 | ||
211 | #define NAU8810_ALCM_SFT 8 | ||
212 | |||
213 | /* NAU8810_REG_NOISEGATE (0x23) */ | ||
214 | #define NAU8810_ALCNTH_SFT 0 | ||
215 | #define NAU8810_ALCNEN_SFT 3 | ||
216 | |||
217 | /* NAU8810_REG_PLLN (0x24) */ | ||
218 | #define NAU8810_PLLN_MASK 0xF | ||
219 | #define NAU8810_PLLMCLK_DIV2 (0x1 << 4) | ||
220 | |||
221 | /* NAU8810_REG_PLLK1 (0x25) */ | ||
222 | #define NAU8810_PLLK1_SFT 18 | ||
223 | #define NAU8810_PLLK1_MASK 0x3F | ||
224 | |||
225 | /* NAU8810_REG_PLLK2 (0x26) */ | ||
226 | #define NAU8810_PLLK2_SFT 9 | ||
227 | #define NAU8810_PLLK2_MASK 0x1FF | ||
228 | |||
229 | /* NAU8810_REG_PLLK3 (0x27) */ | ||
230 | #define NAU8810_PLLK3_MASK 0x1FF | ||
231 | |||
232 | /* NAU8810_REG_INPUT_SIGNAL (0x2C) */ | ||
233 | #define NAU8810_PMICPGA_SFT 0 | ||
234 | #define NAU8810_NMICPGA_SFT 1 | ||
235 | |||
236 | /* NAU8810_REG_PGAGAIN (0x2D) */ | ||
237 | #define NAU8810_PGAGAIN_SFT 0 | ||
238 | #define NAU8810_PGAMT_SFT 6 | ||
239 | #define NAU8810_PGAZC_SFT 7 | ||
240 | |||
241 | /* NAU8810_REG_ADCBOOST (0x2F) */ | ||
242 | #define NAU8810_PMICBSTGAIN_SFT 4 | ||
243 | #define NAU8810_PGABST_SFT 8 | ||
244 | |||
245 | /* NAU8810_REG_SPKMIX (0x32) */ | ||
246 | #define NAU8810_DACSPK_SFT 0 | ||
247 | #define NAU8810_BYPSPK_SFT 1 | ||
248 | |||
249 | /* NAU8810_REG_SPKGAIN (0x36) */ | ||
250 | #define NAU8810_SPKGAIN_SFT 0 | ||
251 | #define NAU8810_SPKMT_SFT 6 | ||
252 | #define NAU8810_SPKZC_SFT 7 | ||
253 | |||
254 | /* NAU8810_REG_MONOMIX (0x38) */ | ||
255 | #define NAU8810_DACMOUT_SFT 0 | ||
256 | #define NAU8810_BYPMOUT_SFT 1 | ||
257 | #define NAU8810_MOUTMXMT_SFT 6 | ||
258 | |||
259 | |||
260 | /* System Clock Source */ | ||
261 | enum { | ||
262 | NAU8810_SCLK_MCLK, | ||
263 | NAU8810_SCLK_PLL, | ||
264 | }; | ||
265 | |||
266 | struct nau8810_pll { | ||
267 | int pre_factor; | ||
268 | int mclk_scaler; | ||
269 | int pll_frac; | ||
270 | int pll_int; | ||
271 | }; | ||
272 | |||
273 | struct nau8810 { | ||
274 | struct device *dev; | ||
275 | struct regmap *regmap; | ||
276 | struct nau8810_pll pll; | ||
277 | int sysclk; | ||
278 | int clk_id; | ||
279 | }; | ||
280 | |||
281 | #endif | ||
diff --git a/sound/soc/codecs/nau8825.c b/sound/soc/codecs/nau8825.c index 2e59a85e360b..e643be91d762 100644 --- a/sound/soc/codecs/nau8825.c +++ b/sound/soc/codecs/nau8825.c | |||
@@ -1907,7 +1907,7 @@ static int nau8825_calc_fll_param(unsigned int fll_in, unsigned int fs, | |||
1907 | /* Calculate the FLL 10-bit integer input and the FLL 16-bit fractional | 1907 | /* Calculate the FLL 10-bit integer input and the FLL 16-bit fractional |
1908 | * input based on FDCO, FREF and FLL ratio. | 1908 | * input based on FDCO, FREF and FLL ratio. |
1909 | */ | 1909 | */ |
1910 | fvco = div_u64(fvco << 16, fref * fll_param->ratio); | 1910 | fvco = div_u64(fvco_max << 16, fref * fll_param->ratio); |
1911 | fll_param->fll_int = (fvco >> 16) & 0x3FF; | 1911 | fll_param->fll_int = (fvco >> 16) & 0x3FF; |
1912 | fll_param->fll_frac = fvco & 0xFFFF; | 1912 | fll_param->fll_frac = fvco & 0xFFFF; |
1913 | return 0; | 1913 | return 0; |
@@ -2256,12 +2256,14 @@ static struct snd_soc_codec_driver nau8825_codec_driver = { | |||
2256 | .suspend = nau8825_suspend, | 2256 | .suspend = nau8825_suspend, |
2257 | .resume = nau8825_resume, | 2257 | .resume = nau8825_resume, |
2258 | 2258 | ||
2259 | .controls = nau8825_controls, | 2259 | .component_driver = { |
2260 | .num_controls = ARRAY_SIZE(nau8825_controls), | 2260 | .controls = nau8825_controls, |
2261 | .dapm_widgets = nau8825_dapm_widgets, | 2261 | .num_controls = ARRAY_SIZE(nau8825_controls), |
2262 | .num_dapm_widgets = ARRAY_SIZE(nau8825_dapm_widgets), | 2262 | .dapm_widgets = nau8825_dapm_widgets, |
2263 | .dapm_routes = nau8825_dapm_routes, | 2263 | .num_dapm_widgets = ARRAY_SIZE(nau8825_dapm_widgets), |
2264 | .num_dapm_routes = ARRAY_SIZE(nau8825_dapm_routes), | 2264 | .dapm_routes = nau8825_dapm_routes, |
2265 | .num_dapm_routes = ARRAY_SIZE(nau8825_dapm_routes), | ||
2266 | }, | ||
2265 | }; | 2267 | }; |
2266 | 2268 | ||
2267 | static void nau8825_reset_chip(struct regmap *regmap) | 2269 | static void nau8825_reset_chip(struct regmap *regmap) |
diff --git a/sound/soc/codecs/pcm1681.c b/sound/soc/codecs/pcm1681.c index 33e1fc2d1598..0b14efab6280 100644 --- a/sound/soc/codecs/pcm1681.c +++ b/sound/soc/codecs/pcm1681.c | |||
@@ -289,12 +289,14 @@ static const struct regmap_config pcm1681_regmap = { | |||
289 | }; | 289 | }; |
290 | 290 | ||
291 | static struct snd_soc_codec_driver soc_codec_dev_pcm1681 = { | 291 | static struct snd_soc_codec_driver soc_codec_dev_pcm1681 = { |
292 | .controls = pcm1681_controls, | 292 | .component_driver = { |
293 | .num_controls = ARRAY_SIZE(pcm1681_controls), | 293 | .controls = pcm1681_controls, |
294 | .dapm_widgets = pcm1681_dapm_widgets, | 294 | .num_controls = ARRAY_SIZE(pcm1681_controls), |
295 | .num_dapm_widgets = ARRAY_SIZE(pcm1681_dapm_widgets), | 295 | .dapm_widgets = pcm1681_dapm_widgets, |
296 | .dapm_routes = pcm1681_dapm_routes, | 296 | .num_dapm_widgets = ARRAY_SIZE(pcm1681_dapm_widgets), |
297 | .num_dapm_routes = ARRAY_SIZE(pcm1681_dapm_routes), | 297 | .dapm_routes = pcm1681_dapm_routes, |
298 | .num_dapm_routes = ARRAY_SIZE(pcm1681_dapm_routes), | ||
299 | }, | ||
298 | }; | 300 | }; |
299 | 301 | ||
300 | static const struct i2c_device_id pcm1681_i2c_id[] = { | 302 | static const struct i2c_device_id pcm1681_i2c_id[] = { |
diff --git a/sound/soc/codecs/pcm179x.c b/sound/soc/codecs/pcm179x.c index 88fbdd184aa0..b813a154ddd9 100644 --- a/sound/soc/codecs/pcm179x.c +++ b/sound/soc/codecs/pcm179x.c | |||
@@ -206,12 +206,14 @@ const struct regmap_config pcm179x_regmap_config = { | |||
206 | EXPORT_SYMBOL_GPL(pcm179x_regmap_config); | 206 | EXPORT_SYMBOL_GPL(pcm179x_regmap_config); |
207 | 207 | ||
208 | static struct snd_soc_codec_driver soc_codec_dev_pcm179x = { | 208 | static struct snd_soc_codec_driver soc_codec_dev_pcm179x = { |
209 | .controls = pcm179x_controls, | 209 | .component_driver = { |
210 | .num_controls = ARRAY_SIZE(pcm179x_controls), | 210 | .controls = pcm179x_controls, |
211 | .dapm_widgets = pcm179x_dapm_widgets, | 211 | .num_controls = ARRAY_SIZE(pcm179x_controls), |
212 | .num_dapm_widgets = ARRAY_SIZE(pcm179x_dapm_widgets), | 212 | .dapm_widgets = pcm179x_dapm_widgets, |
213 | .dapm_routes = pcm179x_dapm_routes, | 213 | .num_dapm_widgets = ARRAY_SIZE(pcm179x_dapm_widgets), |
214 | .num_dapm_routes = ARRAY_SIZE(pcm179x_dapm_routes), | 214 | .dapm_routes = pcm179x_dapm_routes, |
215 | .num_dapm_routes = ARRAY_SIZE(pcm179x_dapm_routes), | ||
216 | }, | ||
215 | }; | 217 | }; |
216 | 218 | ||
217 | int pcm179x_common_init(struct device *dev, struct regmap *regmap) | 219 | int pcm179x_common_init(struct device *dev, struct regmap *regmap) |
diff --git a/sound/soc/codecs/pcm3008.c b/sound/soc/codecs/pcm3008.c index 8fb445f33f6f..708af05486f6 100644 --- a/sound/soc/codecs/pcm3008.c +++ b/sound/soc/codecs/pcm3008.c | |||
@@ -99,10 +99,12 @@ static struct snd_soc_dai_driver pcm3008_dai = { | |||
99 | }; | 99 | }; |
100 | 100 | ||
101 | static struct snd_soc_codec_driver soc_codec_dev_pcm3008 = { | 101 | static struct snd_soc_codec_driver soc_codec_dev_pcm3008 = { |
102 | .dapm_widgets = pcm3008_dapm_widgets, | 102 | .component_driver = { |
103 | .num_dapm_widgets = ARRAY_SIZE(pcm3008_dapm_widgets), | 103 | .dapm_widgets = pcm3008_dapm_widgets, |
104 | .dapm_routes = pcm3008_dapm_routes, | 104 | .num_dapm_widgets = ARRAY_SIZE(pcm3008_dapm_widgets), |
105 | .num_dapm_routes = ARRAY_SIZE(pcm3008_dapm_routes), | 105 | .dapm_routes = pcm3008_dapm_routes, |
106 | .num_dapm_routes = ARRAY_SIZE(pcm3008_dapm_routes), | ||
107 | }, | ||
106 | }; | 108 | }; |
107 | 109 | ||
108 | static int pcm3008_codec_probe(struct platform_device *pdev) | 110 | static int pcm3008_codec_probe(struct platform_device *pdev) |
diff --git a/sound/soc/codecs/pcm3168a.c b/sound/soc/codecs/pcm3168a.c index 992a77edcd5d..39bc02d5bc5d 100644 --- a/sound/soc/codecs/pcm3168a.c +++ b/sound/soc/codecs/pcm3168a.c | |||
@@ -599,12 +599,14 @@ EXPORT_SYMBOL_GPL(pcm3168a_regmap); | |||
599 | 599 | ||
600 | static const struct snd_soc_codec_driver pcm3168a_driver = { | 600 | static const struct snd_soc_codec_driver pcm3168a_driver = { |
601 | .idle_bias_off = true, | 601 | .idle_bias_off = true, |
602 | .controls = pcm3168a_snd_controls, | 602 | .component_driver = { |
603 | .num_controls = ARRAY_SIZE(pcm3168a_snd_controls), | 603 | .controls = pcm3168a_snd_controls, |
604 | .dapm_widgets = pcm3168a_dapm_widgets, | 604 | .num_controls = ARRAY_SIZE(pcm3168a_snd_controls), |
605 | .num_dapm_widgets = ARRAY_SIZE(pcm3168a_dapm_widgets), | 605 | .dapm_widgets = pcm3168a_dapm_widgets, |
606 | .dapm_routes = pcm3168a_dapm_routes, | 606 | .num_dapm_widgets = ARRAY_SIZE(pcm3168a_dapm_widgets), |
607 | .num_dapm_routes = ARRAY_SIZE(pcm3168a_dapm_routes) | 607 | .dapm_routes = pcm3168a_dapm_routes, |
608 | .num_dapm_routes = ARRAY_SIZE(pcm3168a_dapm_routes) | ||
609 | }, | ||
608 | }; | 610 | }; |
609 | 611 | ||
610 | int pcm3168a_probe(struct device *dev, struct regmap *regmap) | 612 | int pcm3168a_probe(struct device *dev, struct regmap *regmap) |
diff --git a/sound/soc/codecs/pcm512x.c b/sound/soc/codecs/pcm512x.c index 047c48953a20..72b19e62f626 100644 --- a/sound/soc/codecs/pcm512x.c +++ b/sound/soc/codecs/pcm512x.c | |||
@@ -1348,12 +1348,14 @@ static struct snd_soc_codec_driver pcm512x_codec_driver = { | |||
1348 | .set_bias_level = pcm512x_set_bias_level, | 1348 | .set_bias_level = pcm512x_set_bias_level, |
1349 | .idle_bias_off = true, | 1349 | .idle_bias_off = true, |
1350 | 1350 | ||
1351 | .controls = pcm512x_controls, | 1351 | .component_driver = { |
1352 | .num_controls = ARRAY_SIZE(pcm512x_controls), | 1352 | .controls = pcm512x_controls, |
1353 | .dapm_widgets = pcm512x_dapm_widgets, | 1353 | .num_controls = ARRAY_SIZE(pcm512x_controls), |
1354 | .num_dapm_widgets = ARRAY_SIZE(pcm512x_dapm_widgets), | 1354 | .dapm_widgets = pcm512x_dapm_widgets, |
1355 | .dapm_routes = pcm512x_dapm_routes, | 1355 | .num_dapm_widgets = ARRAY_SIZE(pcm512x_dapm_widgets), |
1356 | .num_dapm_routes = ARRAY_SIZE(pcm512x_dapm_routes), | 1356 | .dapm_routes = pcm512x_dapm_routes, |
1357 | .num_dapm_routes = ARRAY_SIZE(pcm512x_dapm_routes), | ||
1358 | }, | ||
1357 | }; | 1359 | }; |
1358 | 1360 | ||
1359 | static const struct regmap_range_cfg pcm512x_range = { | 1361 | static const struct regmap_range_cfg pcm512x_range = { |
diff --git a/sound/soc/codecs/rt286.c b/sound/soc/codecs/rt286.c index 74c0e4eb3788..9c365a7f758d 100644 --- a/sound/soc/codecs/rt286.c +++ b/sound/soc/codecs/rt286.c | |||
@@ -1053,12 +1053,14 @@ static struct snd_soc_codec_driver soc_codec_dev_rt286 = { | |||
1053 | .resume = rt286_resume, | 1053 | .resume = rt286_resume, |
1054 | .set_bias_level = rt286_set_bias_level, | 1054 | .set_bias_level = rt286_set_bias_level, |
1055 | .idle_bias_off = true, | 1055 | .idle_bias_off = true, |
1056 | .controls = rt286_snd_controls, | 1056 | .component_driver = { |
1057 | .num_controls = ARRAY_SIZE(rt286_snd_controls), | 1057 | .controls = rt286_snd_controls, |
1058 | .dapm_widgets = rt286_dapm_widgets, | 1058 | .num_controls = ARRAY_SIZE(rt286_snd_controls), |
1059 | .num_dapm_widgets = ARRAY_SIZE(rt286_dapm_widgets), | 1059 | .dapm_widgets = rt286_dapm_widgets, |
1060 | .dapm_routes = rt286_dapm_routes, | 1060 | .num_dapm_widgets = ARRAY_SIZE(rt286_dapm_widgets), |
1061 | .num_dapm_routes = ARRAY_SIZE(rt286_dapm_routes), | 1061 | .dapm_routes = rt286_dapm_routes, |
1062 | .num_dapm_routes = ARRAY_SIZE(rt286_dapm_routes), | ||
1063 | }, | ||
1062 | }; | 1064 | }; |
1063 | 1065 | ||
1064 | static const struct regmap_config rt286_regmap = { | 1066 | static const struct regmap_config rt286_regmap = { |
diff --git a/sound/soc/codecs/rt298.c b/sound/soc/codecs/rt298.c index f80cfe4d2ef2..55558643166f 100644 --- a/sound/soc/codecs/rt298.c +++ b/sound/soc/codecs/rt298.c | |||
@@ -1095,12 +1095,14 @@ static struct snd_soc_codec_driver soc_codec_dev_rt298 = { | |||
1095 | .resume = rt298_resume, | 1095 | .resume = rt298_resume, |
1096 | .set_bias_level = rt298_set_bias_level, | 1096 | .set_bias_level = rt298_set_bias_level, |
1097 | .idle_bias_off = true, | 1097 | .idle_bias_off = true, |
1098 | .controls = rt298_snd_controls, | 1098 | .component_driver = { |
1099 | .num_controls = ARRAY_SIZE(rt298_snd_controls), | 1099 | .controls = rt298_snd_controls, |
1100 | .dapm_widgets = rt298_dapm_widgets, | 1100 | .num_controls = ARRAY_SIZE(rt298_snd_controls), |
1101 | .num_dapm_widgets = ARRAY_SIZE(rt298_dapm_widgets), | 1101 | .dapm_widgets = rt298_dapm_widgets, |
1102 | .dapm_routes = rt298_dapm_routes, | 1102 | .num_dapm_widgets = ARRAY_SIZE(rt298_dapm_widgets), |
1103 | .num_dapm_routes = ARRAY_SIZE(rt298_dapm_routes), | 1103 | .dapm_routes = rt298_dapm_routes, |
1104 | .num_dapm_routes = ARRAY_SIZE(rt298_dapm_routes), | ||
1105 | }, | ||
1104 | }; | 1106 | }; |
1105 | 1107 | ||
1106 | static const struct regmap_config rt298_regmap = { | 1108 | static const struct regmap_config rt298_regmap = { |
diff --git a/sound/soc/codecs/rt5514-spi.c b/sound/soc/codecs/rt5514-spi.c index 77ff8ebe6dfb..09103aab0cb2 100644 --- a/sound/soc/codecs/rt5514-spi.c +++ b/sound/soc/codecs/rt5514-spi.c | |||
@@ -236,7 +236,7 @@ static snd_pcm_uframes_t rt5514_spi_pcm_pointer( | |||
236 | return bytes_to_frames(runtime, rt5514_dsp->dma_offset); | 236 | return bytes_to_frames(runtime, rt5514_dsp->dma_offset); |
237 | } | 237 | } |
238 | 238 | ||
239 | static struct snd_pcm_ops rt5514_spi_pcm_ops = { | 239 | static const struct snd_pcm_ops rt5514_spi_pcm_ops = { |
240 | .open = rt5514_spi_pcm_open, | 240 | .open = rt5514_spi_pcm_open, |
241 | .hw_params = rt5514_spi_hw_params, | 241 | .hw_params = rt5514_spi_hw_params, |
242 | .hw_free = rt5514_spi_hw_free, | 242 | .hw_free = rt5514_spi_hw_free, |
diff --git a/sound/soc/codecs/rt5514.c b/sound/soc/codecs/rt5514.c index 7162f05101d9..f24b7cfd3a89 100644 --- a/sound/soc/codecs/rt5514.c +++ b/sound/soc/codecs/rt5514.c | |||
@@ -278,7 +278,7 @@ static const DECLARE_TLV_DB_RANGE(bst_tlv, | |||
278 | 8, 8, TLV_DB_SCALE_ITEM(1700, 0, 0) | 278 | 8, 8, TLV_DB_SCALE_ITEM(1700, 0, 0) |
279 | ); | 279 | ); |
280 | 280 | ||
281 | static const DECLARE_TLV_DB_SCALE(adc_vol_tlv, -17625, 375, 0); | 281 | static const DECLARE_TLV_DB_SCALE(adc_vol_tlv, -1725, 75, 0); |
282 | 282 | ||
283 | static int rt5514_dsp_voice_wake_up_get(struct snd_kcontrol *kcontrol, | 283 | static int rt5514_dsp_voice_wake_up_get(struct snd_kcontrol *kcontrol, |
284 | struct snd_ctl_elem_value *ucontrol) | 284 | struct snd_ctl_elem_value *ucontrol) |
@@ -352,10 +352,10 @@ static const struct snd_kcontrol_new rt5514_snd_controls[] = { | |||
352 | SOC_DOUBLE_TLV("MIC Boost Volume", RT5514_ANA_CTRL_MICBST, | 352 | SOC_DOUBLE_TLV("MIC Boost Volume", RT5514_ANA_CTRL_MICBST, |
353 | RT5514_SEL_BSTL_SFT, RT5514_SEL_BSTR_SFT, 8, 0, bst_tlv), | 353 | RT5514_SEL_BSTL_SFT, RT5514_SEL_BSTR_SFT, 8, 0, bst_tlv), |
354 | SOC_DOUBLE_R_TLV("ADC1 Capture Volume", RT5514_DOWNFILTER0_CTRL1, | 354 | SOC_DOUBLE_R_TLV("ADC1 Capture Volume", RT5514_DOWNFILTER0_CTRL1, |
355 | RT5514_DOWNFILTER0_CTRL2, RT5514_AD_GAIN_SFT, 127, 0, | 355 | RT5514_DOWNFILTER0_CTRL2, RT5514_AD_GAIN_SFT, 63, 0, |
356 | adc_vol_tlv), | 356 | adc_vol_tlv), |
357 | SOC_DOUBLE_R_TLV("ADC2 Capture Volume", RT5514_DOWNFILTER1_CTRL1, | 357 | SOC_DOUBLE_R_TLV("ADC2 Capture Volume", RT5514_DOWNFILTER1_CTRL1, |
358 | RT5514_DOWNFILTER1_CTRL2, RT5514_AD_GAIN_SFT, 127, 0, | 358 | RT5514_DOWNFILTER1_CTRL2, RT5514_AD_GAIN_SFT, 63, 0, |
359 | adc_vol_tlv), | 359 | adc_vol_tlv), |
360 | SOC_SINGLE_EXT("DSP Voice Wake Up", SND_SOC_NOPM, 0, 1, 0, | 360 | SOC_SINGLE_EXT("DSP Voice Wake Up", SND_SOC_NOPM, 0, 1, 0, |
361 | rt5514_dsp_voice_wake_up_get, rt5514_dsp_voice_wake_up_put), | 361 | rt5514_dsp_voice_wake_up_get, rt5514_dsp_voice_wake_up_put), |
@@ -1023,12 +1023,14 @@ static struct snd_soc_codec_driver soc_codec_dev_rt5514 = { | |||
1023 | .probe = rt5514_probe, | 1023 | .probe = rt5514_probe, |
1024 | .idle_bias_off = true, | 1024 | .idle_bias_off = true, |
1025 | .set_bias_level = rt5514_set_bias_level, | 1025 | .set_bias_level = rt5514_set_bias_level, |
1026 | .controls = rt5514_snd_controls, | 1026 | .component_driver = { |
1027 | .num_controls = ARRAY_SIZE(rt5514_snd_controls), | 1027 | .controls = rt5514_snd_controls, |
1028 | .dapm_widgets = rt5514_dapm_widgets, | 1028 | .num_controls = ARRAY_SIZE(rt5514_snd_controls), |
1029 | .num_dapm_widgets = ARRAY_SIZE(rt5514_dapm_widgets), | 1029 | .dapm_widgets = rt5514_dapm_widgets, |
1030 | .dapm_routes = rt5514_dapm_routes, | 1030 | .num_dapm_widgets = ARRAY_SIZE(rt5514_dapm_widgets), |
1031 | .num_dapm_routes = ARRAY_SIZE(rt5514_dapm_routes), | 1031 | .dapm_routes = rt5514_dapm_routes, |
1032 | .num_dapm_routes = ARRAY_SIZE(rt5514_dapm_routes), | ||
1033 | }, | ||
1032 | }; | 1034 | }; |
1033 | 1035 | ||
1034 | static const struct regmap_config rt5514_i2c_regmap = { | 1036 | static const struct regmap_config rt5514_i2c_regmap = { |
diff --git a/sound/soc/codecs/rt5514.h b/sound/soc/codecs/rt5514.h index 68883c68e999..229de0e2c88c 100644 --- a/sound/soc/codecs/rt5514.h +++ b/sound/soc/codecs/rt5514.h | |||
@@ -196,8 +196,8 @@ | |||
196 | #define RT5514_AD_AD_MIX_BIT 10 | 196 | #define RT5514_AD_AD_MIX_BIT 10 |
197 | #define RT5514_AD_AD_MUTE (0x1 << 7) | 197 | #define RT5514_AD_AD_MUTE (0x1 << 7) |
198 | #define RT5514_AD_AD_MUTE_BIT 7 | 198 | #define RT5514_AD_AD_MUTE_BIT 7 |
199 | #define RT5514_AD_GAIN_MASK (0x7f << 0) | 199 | #define RT5514_AD_GAIN_MASK (0x3f << 1) |
200 | #define RT5514_AD_GAIN_SFT 0 | 200 | #define RT5514_AD_GAIN_SFT 1 |
201 | 201 | ||
202 | /* RT5514_ANA_CTRL_MICBST (0x2220) */ | 202 | /* RT5514_ANA_CTRL_MICBST (0x2220) */ |
203 | #define RT5514_SEL_BSTL_MASK (0xf << 4) | 203 | #define RT5514_SEL_BSTL_MASK (0xf << 4) |
diff --git a/sound/soc/codecs/rt5616.c b/sound/soc/codecs/rt5616.c index f527b5b2817b..d1f273b24991 100644 --- a/sound/soc/codecs/rt5616.c +++ b/sound/soc/codecs/rt5616.c | |||
@@ -294,8 +294,7 @@ static const DECLARE_TLV_DB_SCALE(adc_vol_tlv, -17625, 375, 0); | |||
294 | static const DECLARE_TLV_DB_SCALE(adc_bst_tlv, 0, 1200, 0); | 294 | static const DECLARE_TLV_DB_SCALE(adc_bst_tlv, 0, 1200, 0); |
295 | 295 | ||
296 | /* {0, +20, +24, +30, +35, +40, +44, +50, +52} dB */ | 296 | /* {0, +20, +24, +30, +35, +40, +44, +50, +52} dB */ |
297 | static unsigned int bst_tlv[] = { | 297 | static const SNDRV_CTL_TLVD_DECLARE_DB_RANGE(bst_tlv, |
298 | TLV_DB_RANGE_HEAD(7), | ||
299 | 0, 0, TLV_DB_SCALE_ITEM(0, 0, 0), | 298 | 0, 0, TLV_DB_SCALE_ITEM(0, 0, 0), |
300 | 1, 1, TLV_DB_SCALE_ITEM(2000, 0, 0), | 299 | 1, 1, TLV_DB_SCALE_ITEM(2000, 0, 0), |
301 | 2, 2, TLV_DB_SCALE_ITEM(2400, 0, 0), | 300 | 2, 2, TLV_DB_SCALE_ITEM(2400, 0, 0), |
@@ -303,7 +302,7 @@ static unsigned int bst_tlv[] = { | |||
303 | 6, 6, TLV_DB_SCALE_ITEM(4400, 0, 0), | 302 | 6, 6, TLV_DB_SCALE_ITEM(4400, 0, 0), |
304 | 7, 7, TLV_DB_SCALE_ITEM(5000, 0, 0), | 303 | 7, 7, TLV_DB_SCALE_ITEM(5000, 0, 0), |
305 | 8, 8, TLV_DB_SCALE_ITEM(5200, 0, 0), | 304 | 8, 8, TLV_DB_SCALE_ITEM(5200, 0, 0), |
306 | }; | 305 | ); |
307 | 306 | ||
308 | static const struct snd_kcontrol_new rt5616_snd_controls[] = { | 307 | static const struct snd_kcontrol_new rt5616_snd_controls[] = { |
309 | /* Headphone Output Volume */ | 308 | /* Headphone Output Volume */ |
@@ -1267,14 +1266,14 @@ static int rt5616_resume(struct snd_soc_codec *codec) | |||
1267 | #define RT5616_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE | \ | 1266 | #define RT5616_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE | \ |
1268 | SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S8) | 1267 | SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S8) |
1269 | 1268 | ||
1270 | struct snd_soc_dai_ops rt5616_aif_dai_ops = { | 1269 | static struct snd_soc_dai_ops rt5616_aif_dai_ops = { |
1271 | .hw_params = rt5616_hw_params, | 1270 | .hw_params = rt5616_hw_params, |
1272 | .set_fmt = rt5616_set_dai_fmt, | 1271 | .set_fmt = rt5616_set_dai_fmt, |
1273 | .set_sysclk = rt5616_set_dai_sysclk, | 1272 | .set_sysclk = rt5616_set_dai_sysclk, |
1274 | .set_pll = rt5616_set_dai_pll, | 1273 | .set_pll = rt5616_set_dai_pll, |
1275 | }; | 1274 | }; |
1276 | 1275 | ||
1277 | struct snd_soc_dai_driver rt5616_dai[] = { | 1276 | static struct snd_soc_dai_driver rt5616_dai[] = { |
1278 | { | 1277 | { |
1279 | .name = "rt5616-aif1", | 1278 | .name = "rt5616-aif1", |
1280 | .id = RT5616_AIF1, | 1279 | .id = RT5616_AIF1, |
@@ -1302,12 +1301,14 @@ static struct snd_soc_codec_driver soc_codec_dev_rt5616 = { | |||
1302 | .resume = rt5616_resume, | 1301 | .resume = rt5616_resume, |
1303 | .set_bias_level = rt5616_set_bias_level, | 1302 | .set_bias_level = rt5616_set_bias_level, |
1304 | .idle_bias_off = true, | 1303 | .idle_bias_off = true, |
1305 | .controls = rt5616_snd_controls, | 1304 | .component_driver = { |
1306 | .num_controls = ARRAY_SIZE(rt5616_snd_controls), | 1305 | .controls = rt5616_snd_controls, |
1307 | .dapm_widgets = rt5616_dapm_widgets, | 1306 | .num_controls = ARRAY_SIZE(rt5616_snd_controls), |
1308 | .num_dapm_widgets = ARRAY_SIZE(rt5616_dapm_widgets), | 1307 | .dapm_widgets = rt5616_dapm_widgets, |
1309 | .dapm_routes = rt5616_dapm_routes, | 1308 | .num_dapm_widgets = ARRAY_SIZE(rt5616_dapm_widgets), |
1310 | .num_dapm_routes = ARRAY_SIZE(rt5616_dapm_routes), | 1309 | .dapm_routes = rt5616_dapm_routes, |
1310 | .num_dapm_routes = ARRAY_SIZE(rt5616_dapm_routes), | ||
1311 | }, | ||
1311 | }; | 1312 | }; |
1312 | 1313 | ||
1313 | static const struct regmap_config rt5616_regmap = { | 1314 | static const struct regmap_config rt5616_regmap = { |
diff --git a/sound/soc/codecs/rt5631.c b/sound/soc/codecs/rt5631.c index 1be2bab7dee3..0e418089c053 100644 --- a/sound/soc/codecs/rt5631.c +++ b/sound/soc/codecs/rt5631.c | |||
@@ -1657,12 +1657,14 @@ static struct snd_soc_codec_driver soc_codec_dev_rt5631 = { | |||
1657 | .probe = rt5631_probe, | 1657 | .probe = rt5631_probe, |
1658 | .set_bias_level = rt5631_set_bias_level, | 1658 | .set_bias_level = rt5631_set_bias_level, |
1659 | .suspend_bias_off = true, | 1659 | .suspend_bias_off = true, |
1660 | .controls = rt5631_snd_controls, | 1660 | .component_driver = { |
1661 | .num_controls = ARRAY_SIZE(rt5631_snd_controls), | 1661 | .controls = rt5631_snd_controls, |
1662 | .dapm_widgets = rt5631_dapm_widgets, | 1662 | .num_controls = ARRAY_SIZE(rt5631_snd_controls), |
1663 | .num_dapm_widgets = ARRAY_SIZE(rt5631_dapm_widgets), | 1663 | .dapm_widgets = rt5631_dapm_widgets, |
1664 | .dapm_routes = rt5631_dapm_routes, | 1664 | .num_dapm_widgets = ARRAY_SIZE(rt5631_dapm_widgets), |
1665 | .num_dapm_routes = ARRAY_SIZE(rt5631_dapm_routes), | 1665 | .dapm_routes = rt5631_dapm_routes, |
1666 | .num_dapm_routes = ARRAY_SIZE(rt5631_dapm_routes), | ||
1667 | }, | ||
1666 | }; | 1668 | }; |
1667 | 1669 | ||
1668 | static const struct i2c_device_id rt5631_i2c_id[] = { | 1670 | static const struct i2c_device_id rt5631_i2c_id[] = { |
diff --git a/sound/soc/codecs/rt5640.c b/sound/soc/codecs/rt5640.c index 09e8988bbb2d..3cc1135fc2cd 100644 --- a/sound/soc/codecs/rt5640.c +++ b/sound/soc/codecs/rt5640.c | |||
@@ -1870,6 +1870,9 @@ static int rt5640_set_dai_sysclk(struct snd_soc_dai *dai, | |||
1870 | case RT5640_SCLK_S_PLL1: | 1870 | case RT5640_SCLK_S_PLL1: |
1871 | reg_val |= RT5640_SCLK_SRC_PLL1; | 1871 | reg_val |= RT5640_SCLK_SRC_PLL1; |
1872 | break; | 1872 | break; |
1873 | case RT5640_SCLK_S_RCCLK: | ||
1874 | reg_val |= RT5640_SCLK_SRC_RCCLK; | ||
1875 | break; | ||
1873 | default: | 1876 | default: |
1874 | dev_err(codec->dev, "Invalid clock id (%d)\n", clk_id); | 1877 | dev_err(codec->dev, "Invalid clock id (%d)\n", clk_id); |
1875 | return -EINVAL; | 1878 | return -EINVAL; |
@@ -2261,12 +2264,14 @@ static struct snd_soc_codec_driver soc_codec_dev_rt5640 = { | |||
2261 | .resume = rt5640_resume, | 2264 | .resume = rt5640_resume, |
2262 | .set_bias_level = rt5640_set_bias_level, | 2265 | .set_bias_level = rt5640_set_bias_level, |
2263 | .idle_bias_off = true, | 2266 | .idle_bias_off = true, |
2264 | .controls = rt5640_snd_controls, | 2267 | .component_driver = { |
2265 | .num_controls = ARRAY_SIZE(rt5640_snd_controls), | 2268 | .controls = rt5640_snd_controls, |
2266 | .dapm_widgets = rt5640_dapm_widgets, | 2269 | .num_controls = ARRAY_SIZE(rt5640_snd_controls), |
2267 | .num_dapm_widgets = ARRAY_SIZE(rt5640_dapm_widgets), | 2270 | .dapm_widgets = rt5640_dapm_widgets, |
2268 | .dapm_routes = rt5640_dapm_routes, | 2271 | .num_dapm_widgets = ARRAY_SIZE(rt5640_dapm_widgets), |
2269 | .num_dapm_routes = ARRAY_SIZE(rt5640_dapm_routes), | 2272 | .dapm_routes = rt5640_dapm_routes, |
2273 | .num_dapm_routes = ARRAY_SIZE(rt5640_dapm_routes), | ||
2274 | }, | ||
2270 | }; | 2275 | }; |
2271 | 2276 | ||
2272 | static const struct regmap_config rt5640_regmap = { | 2277 | static const struct regmap_config rt5640_regmap = { |
diff --git a/sound/soc/codecs/rt5640.h b/sound/soc/codecs/rt5640.h index 58b664b06c16..90c88711c72a 100644 --- a/sound/soc/codecs/rt5640.h +++ b/sound/soc/codecs/rt5640.h | |||
@@ -984,6 +984,7 @@ | |||
984 | #define RT5640_SCLK_SRC_SFT 14 | 984 | #define RT5640_SCLK_SRC_SFT 14 |
985 | #define RT5640_SCLK_SRC_MCLK (0x0 << 14) | 985 | #define RT5640_SCLK_SRC_MCLK (0x0 << 14) |
986 | #define RT5640_SCLK_SRC_PLL1 (0x1 << 14) | 986 | #define RT5640_SCLK_SRC_PLL1 (0x1 << 14) |
987 | #define RT5640_SCLK_SRC_RCCLK (0x2 << 14) | ||
987 | #define RT5640_PLL1_SRC_MASK (0x3 << 12) | 988 | #define RT5640_PLL1_SRC_MASK (0x3 << 12) |
988 | #define RT5640_PLL1_SRC_SFT 12 | 989 | #define RT5640_PLL1_SRC_SFT 12 |
989 | #define RT5640_PLL1_SRC_MCLK (0x0 << 12) | 990 | #define RT5640_PLL1_SRC_MCLK (0x0 << 12) |
diff --git a/sound/soc/codecs/rt5645.c b/sound/soc/codecs/rt5645.c index 490bfe661346..10c2a564a715 100644 --- a/sound/soc/codecs/rt5645.c +++ b/sound/soc/codecs/rt5645.c | |||
@@ -3484,12 +3484,14 @@ static struct snd_soc_codec_driver soc_codec_dev_rt5645 = { | |||
3484 | .resume = rt5645_resume, | 3484 | .resume = rt5645_resume, |
3485 | .set_bias_level = rt5645_set_bias_level, | 3485 | .set_bias_level = rt5645_set_bias_level, |
3486 | .idle_bias_off = true, | 3486 | .idle_bias_off = true, |
3487 | .controls = rt5645_snd_controls, | 3487 | .component_driver = { |
3488 | .num_controls = ARRAY_SIZE(rt5645_snd_controls), | 3488 | .controls = rt5645_snd_controls, |
3489 | .dapm_widgets = rt5645_dapm_widgets, | 3489 | .num_controls = ARRAY_SIZE(rt5645_snd_controls), |
3490 | .num_dapm_widgets = ARRAY_SIZE(rt5645_dapm_widgets), | 3490 | .dapm_widgets = rt5645_dapm_widgets, |
3491 | .dapm_routes = rt5645_dapm_routes, | 3491 | .num_dapm_widgets = ARRAY_SIZE(rt5645_dapm_widgets), |
3492 | .num_dapm_routes = ARRAY_SIZE(rt5645_dapm_routes), | 3492 | .dapm_routes = rt5645_dapm_routes, |
3493 | .num_dapm_routes = ARRAY_SIZE(rt5645_dapm_routes), | ||
3494 | }, | ||
3493 | }; | 3495 | }; |
3494 | 3496 | ||
3495 | static const struct regmap_config rt5645_regmap = { | 3497 | static const struct regmap_config rt5645_regmap = { |
diff --git a/sound/soc/codecs/rt5651.c b/sound/soc/codecs/rt5651.c index 7a6197042423..f5d34153e21f 100644 --- a/sound/soc/codecs/rt5651.c +++ b/sound/soc/codecs/rt5651.c | |||
@@ -1712,12 +1712,14 @@ static struct snd_soc_codec_driver soc_codec_dev_rt5651 = { | |||
1712 | .resume = rt5651_resume, | 1712 | .resume = rt5651_resume, |
1713 | .set_bias_level = rt5651_set_bias_level, | 1713 | .set_bias_level = rt5651_set_bias_level, |
1714 | .idle_bias_off = true, | 1714 | .idle_bias_off = true, |
1715 | .controls = rt5651_snd_controls, | 1715 | .component_driver = { |
1716 | .num_controls = ARRAY_SIZE(rt5651_snd_controls), | 1716 | .controls = rt5651_snd_controls, |
1717 | .dapm_widgets = rt5651_dapm_widgets, | 1717 | .num_controls = ARRAY_SIZE(rt5651_snd_controls), |
1718 | .num_dapm_widgets = ARRAY_SIZE(rt5651_dapm_widgets), | 1718 | .dapm_widgets = rt5651_dapm_widgets, |
1719 | .dapm_routes = rt5651_dapm_routes, | 1719 | .num_dapm_widgets = ARRAY_SIZE(rt5651_dapm_widgets), |
1720 | .num_dapm_routes = ARRAY_SIZE(rt5651_dapm_routes), | 1720 | .dapm_routes = rt5651_dapm_routes, |
1721 | .num_dapm_routes = ARRAY_SIZE(rt5651_dapm_routes), | ||
1722 | }, | ||
1721 | }; | 1723 | }; |
1722 | 1724 | ||
1723 | static const struct regmap_config rt5651_regmap = { | 1725 | static const struct regmap_config rt5651_regmap = { |
diff --git a/sound/soc/codecs/rt5659.c b/sound/soc/codecs/rt5659.c index 1b30914c2d91..db54550aed60 100644 --- a/sound/soc/codecs/rt5659.c +++ b/sound/soc/codecs/rt5659.c | |||
@@ -9,6 +9,7 @@ | |||
9 | * published by the Free Software Foundation. | 9 | * published by the Free Software Foundation. |
10 | */ | 10 | */ |
11 | 11 | ||
12 | #include <linux/clk.h> | ||
12 | #include <linux/module.h> | 13 | #include <linux/module.h> |
13 | #include <linux/moduleparam.h> | 14 | #include <linux/moduleparam.h> |
14 | #include <linux/init.h> | 15 | #include <linux/init.h> |
@@ -3565,7 +3566,9 @@ static int rt5659_set_bclk_ratio(struct snd_soc_dai *dai, unsigned int ratio) | |||
3565 | static int rt5659_set_bias_level(struct snd_soc_codec *codec, | 3566 | static int rt5659_set_bias_level(struct snd_soc_codec *codec, |
3566 | enum snd_soc_bias_level level) | 3567 | enum snd_soc_bias_level level) |
3567 | { | 3568 | { |
3569 | struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec); | ||
3568 | struct rt5659_priv *rt5659 = snd_soc_codec_get_drvdata(codec); | 3570 | struct rt5659_priv *rt5659 = snd_soc_codec_get_drvdata(codec); |
3571 | int ret; | ||
3569 | 3572 | ||
3570 | switch (level) { | 3573 | switch (level) { |
3571 | case SND_SOC_BIAS_PREPARE: | 3574 | case SND_SOC_BIAS_PREPARE: |
@@ -3582,6 +3585,17 @@ static int rt5659_set_bias_level(struct snd_soc_codec *codec, | |||
3582 | RT5659_PWR_FV1 | RT5659_PWR_FV2); | 3585 | RT5659_PWR_FV1 | RT5659_PWR_FV2); |
3583 | break; | 3586 | break; |
3584 | 3587 | ||
3588 | case SND_SOC_BIAS_STANDBY: | ||
3589 | if (dapm->bias_level == SND_SOC_BIAS_OFF) { | ||
3590 | ret = clk_prepare_enable(rt5659->mclk); | ||
3591 | if (ret) { | ||
3592 | dev_err(codec->dev, | ||
3593 | "failed to enable MCLK: %d\n", ret); | ||
3594 | return ret; | ||
3595 | } | ||
3596 | } | ||
3597 | break; | ||
3598 | |||
3585 | case SND_SOC_BIAS_OFF: | 3599 | case SND_SOC_BIAS_OFF: |
3586 | regmap_update_bits(rt5659->regmap, RT5659_PWR_DIG_1, | 3600 | regmap_update_bits(rt5659->regmap, RT5659_PWR_DIG_1, |
3587 | RT5659_PWR_LDO, 0); | 3601 | RT5659_PWR_LDO, 0); |
@@ -3591,6 +3605,7 @@ static int rt5659_set_bias_level(struct snd_soc_codec *codec, | |||
3591 | RT5659_PWR_MB | RT5659_PWR_VREF2); | 3605 | RT5659_PWR_MB | RT5659_PWR_VREF2); |
3592 | regmap_update_bits(rt5659->regmap, RT5659_DIG_MISC, | 3606 | regmap_update_bits(rt5659->regmap, RT5659_DIG_MISC, |
3593 | RT5659_DIG_GATE_CTRL, 0); | 3607 | RT5659_DIG_GATE_CTRL, 0); |
3608 | clk_disable_unprepare(rt5659->mclk); | ||
3594 | break; | 3609 | break; |
3595 | 3610 | ||
3596 | default: | 3611 | default: |
@@ -3722,12 +3737,14 @@ static struct snd_soc_codec_driver soc_codec_dev_rt5659 = { | |||
3722 | .resume = rt5659_resume, | 3737 | .resume = rt5659_resume, |
3723 | .set_bias_level = rt5659_set_bias_level, | 3738 | .set_bias_level = rt5659_set_bias_level, |
3724 | .idle_bias_off = true, | 3739 | .idle_bias_off = true, |
3725 | .controls = rt5659_snd_controls, | 3740 | .component_driver = { |
3726 | .num_controls = ARRAY_SIZE(rt5659_snd_controls), | 3741 | .controls = rt5659_snd_controls, |
3727 | .dapm_widgets = rt5659_dapm_widgets, | 3742 | .num_controls = ARRAY_SIZE(rt5659_snd_controls), |
3728 | .num_dapm_widgets = ARRAY_SIZE(rt5659_dapm_widgets), | 3743 | .dapm_widgets = rt5659_dapm_widgets, |
3729 | .dapm_routes = rt5659_dapm_routes, | 3744 | .num_dapm_widgets = ARRAY_SIZE(rt5659_dapm_widgets), |
3730 | .num_dapm_routes = ARRAY_SIZE(rt5659_dapm_routes), | 3745 | .dapm_routes = rt5659_dapm_routes, |
3746 | .num_dapm_routes = ARRAY_SIZE(rt5659_dapm_routes), | ||
3747 | }, | ||
3731 | }; | 3748 | }; |
3732 | 3749 | ||
3733 | 3750 | ||
@@ -4020,6 +4037,15 @@ static int rt5659_i2c_probe(struct i2c_client *i2c, | |||
4020 | 4037 | ||
4021 | regmap_write(rt5659->regmap, RT5659_RESET, 0); | 4038 | regmap_write(rt5659->regmap, RT5659_RESET, 0); |
4022 | 4039 | ||
4040 | /* Check if MCLK provided */ | ||
4041 | rt5659->mclk = devm_clk_get(&i2c->dev, "mclk"); | ||
4042 | if (IS_ERR(rt5659->mclk)) { | ||
4043 | if (PTR_ERR(rt5659->mclk) != -ENOENT) | ||
4044 | return PTR_ERR(rt5659->mclk); | ||
4045 | /* Otherwise mark the mclk pointer to NULL */ | ||
4046 | rt5659->mclk = NULL; | ||
4047 | } | ||
4048 | |||
4023 | rt5659_calibrate(rt5659); | 4049 | rt5659_calibrate(rt5659); |
4024 | 4050 | ||
4025 | /* line in diff mode*/ | 4051 | /* line in diff mode*/ |
@@ -4163,6 +4189,9 @@ static int rt5659_i2c_probe(struct i2c_client *i2c, | |||
4163 | if (ret) | 4189 | if (ret) |
4164 | dev_err(&i2c->dev, "Failed to reguest IRQ: %d\n", ret); | 4190 | dev_err(&i2c->dev, "Failed to reguest IRQ: %d\n", ret); |
4165 | 4191 | ||
4192 | /* Enable IRQ output for GPIO1 pin any way */ | ||
4193 | regmap_update_bits(rt5659->regmap, RT5659_GPIO_CTRL_1, | ||
4194 | RT5659_GP1_PIN_MASK, RT5659_GP1_PIN_IRQ); | ||
4166 | } | 4195 | } |
4167 | 4196 | ||
4168 | return snd_soc_register_codec(&i2c->dev, &soc_codec_dev_rt5659, | 4197 | return snd_soc_register_codec(&i2c->dev, &soc_codec_dev_rt5659, |
diff --git a/sound/soc/codecs/rt5659.h b/sound/soc/codecs/rt5659.h index d31c9e5bcec8..8f1aeef08489 100644 --- a/sound/soc/codecs/rt5659.h +++ b/sound/soc/codecs/rt5659.h | |||
@@ -180,9 +180,9 @@ | |||
180 | #define RT5659_IRQ_CTRL_1 0x00b6 | 180 | #define RT5659_IRQ_CTRL_1 0x00b6 |
181 | #define RT5659_IRQ_CTRL_2 0x00b7 | 181 | #define RT5659_IRQ_CTRL_2 0x00b7 |
182 | #define RT5659_IRQ_CTRL_3 0x00b8 | 182 | #define RT5659_IRQ_CTRL_3 0x00b8 |
183 | #define RT5659_IRQ_CTRL_4 0x00b9 | 183 | #define RT5659_IRQ_CTRL_4 0x00ba |
184 | #define RT5659_IRQ_CTRL_5 0x00ba | 184 | #define RT5659_IRQ_CTRL_5 0x00bb |
185 | #define RT5659_IRQ_CTRL_6 0x00bb | 185 | #define RT5659_IRQ_CTRL_6 0x00bc |
186 | #define RT5659_INT_ST_1 0x00be | 186 | #define RT5659_INT_ST_1 0x00be |
187 | #define RT5659_INT_ST_2 0x00bf | 187 | #define RT5659_INT_ST_2 0x00bf |
188 | #define RT5659_GPIO_CTRL_1 0x00c0 | 188 | #define RT5659_GPIO_CTRL_1 0x00c0 |
@@ -1796,6 +1796,7 @@ struct rt5659_priv { | |||
1796 | struct gpio_desc *gpiod_reset; | 1796 | struct gpio_desc *gpiod_reset; |
1797 | struct snd_soc_jack *hs_jack; | 1797 | struct snd_soc_jack *hs_jack; |
1798 | struct delayed_work jack_detect_work; | 1798 | struct delayed_work jack_detect_work; |
1799 | struct clk *mclk; | ||
1799 | 1800 | ||
1800 | int sysclk; | 1801 | int sysclk; |
1801 | int sysclk_src; | 1802 | int sysclk_src; |
diff --git a/sound/soc/codecs/rt5660.c b/sound/soc/codecs/rt5660.c new file mode 100644 index 000000000000..9f0933ced804 --- /dev/null +++ b/sound/soc/codecs/rt5660.c | |||
@@ -0,0 +1,1353 @@ | |||
1 | /* | ||
2 | * rt5660.c -- RT5660 ALSA SoC audio codec driver | ||
3 | * | ||
4 | * Copyright 2016 Realtek Semiconductor Corp. | ||
5 | * Author: Oder Chiou <oder_chiou@realtek.com> | ||
6 | * | ||
7 | * This program is free software; you can redistribute it and/or modify | ||
8 | * it under the terms of the GNU General Public License version 2 as | ||
9 | * published by the Free Software Foundation. | ||
10 | */ | ||
11 | |||
12 | #include <linux/module.h> | ||
13 | #include <linux/moduleparam.h> | ||
14 | #include <linux/init.h> | ||
15 | #include <linux/delay.h> | ||
16 | #include <linux/pm.h> | ||
17 | #include <linux/gpio.h> | ||
18 | #include <linux/i2c.h> | ||
19 | #include <linux/regmap.h> | ||
20 | #include <linux/of.h> | ||
21 | #include <linux/of_gpio.h> | ||
22 | #include <linux/platform_device.h> | ||
23 | #include <linux/spi/spi.h> | ||
24 | #include <linux/acpi.h> | ||
25 | #include <sound/core.h> | ||
26 | #include <sound/pcm.h> | ||
27 | #include <sound/pcm_params.h> | ||
28 | #include <sound/soc.h> | ||
29 | #include <sound/soc-dapm.h> | ||
30 | #include <sound/initval.h> | ||
31 | #include <sound/tlv.h> | ||
32 | |||
33 | #include "rl6231.h" | ||
34 | #include "rt5660.h" | ||
35 | |||
36 | #define RT5660_DEVICE_ID 0x6338 | ||
37 | |||
38 | #define RT5660_PR_RANGE_BASE (0xff + 1) | ||
39 | #define RT5660_PR_SPACING 0x100 | ||
40 | |||
41 | #define RT5660_PR_BASE (RT5660_PR_RANGE_BASE + (0 * RT5660_PR_SPACING)) | ||
42 | |||
43 | static const struct regmap_range_cfg rt5660_ranges[] = { | ||
44 | { .name = "PR", .range_min = RT5660_PR_BASE, | ||
45 | .range_max = RT5660_PR_BASE + 0xf3, | ||
46 | .selector_reg = RT5660_PRIV_INDEX, | ||
47 | .selector_mask = 0xff, | ||
48 | .selector_shift = 0x0, | ||
49 | .window_start = RT5660_PRIV_DATA, | ||
50 | .window_len = 0x1, }, | ||
51 | }; | ||
52 | |||
53 | static const struct reg_sequence rt5660_patch[] = { | ||
54 | { RT5660_ALC_PGA_CTRL2, 0x44c3 }, | ||
55 | { RT5660_PR_BASE + 0x3d, 0x2600 }, | ||
56 | }; | ||
57 | |||
58 | static const struct reg_default rt5660_reg[] = { | ||
59 | { 0x00, 0x0000 }, | ||
60 | { 0x01, 0xc800 }, | ||
61 | { 0x02, 0xc8c8 }, | ||
62 | { 0x0d, 0x1010 }, | ||
63 | { 0x0e, 0x1010 }, | ||
64 | { 0x19, 0xafaf }, | ||
65 | { 0x1c, 0x2f2f }, | ||
66 | { 0x1e, 0x0000 }, | ||
67 | { 0x27, 0x6060 }, | ||
68 | { 0x29, 0x8080 }, | ||
69 | { 0x2a, 0x4242 }, | ||
70 | { 0x2f, 0x0000 }, | ||
71 | { 0x3b, 0x0000 }, | ||
72 | { 0x3c, 0x007f }, | ||
73 | { 0x3d, 0x0000 }, | ||
74 | { 0x3e, 0x007f }, | ||
75 | { 0x45, 0xe000 }, | ||
76 | { 0x46, 0x003e }, | ||
77 | { 0x48, 0xf800 }, | ||
78 | { 0x4a, 0x0004 }, | ||
79 | { 0x4d, 0x0000 }, | ||
80 | { 0x4e, 0x0000 }, | ||
81 | { 0x4f, 0x01ff }, | ||
82 | { 0x50, 0x0000 }, | ||
83 | { 0x51, 0x0000 }, | ||
84 | { 0x52, 0x01ff }, | ||
85 | { 0x61, 0x0000 }, | ||
86 | { 0x62, 0x0000 }, | ||
87 | { 0x63, 0x00c0 }, | ||
88 | { 0x64, 0x0000 }, | ||
89 | { 0x65, 0x0000 }, | ||
90 | { 0x66, 0x0000 }, | ||
91 | { 0x70, 0x8000 }, | ||
92 | { 0x73, 0x7000 }, | ||
93 | { 0x74, 0x3c00 }, | ||
94 | { 0x75, 0x2800 }, | ||
95 | { 0x80, 0x0000 }, | ||
96 | { 0x81, 0x0000 }, | ||
97 | { 0x82, 0x0000 }, | ||
98 | { 0x8c, 0x0228 }, | ||
99 | { 0x8d, 0xa000 }, | ||
100 | { 0x8e, 0x0000 }, | ||
101 | { 0x92, 0x0000 }, | ||
102 | { 0x93, 0x3000 }, | ||
103 | { 0xa1, 0x0059 }, | ||
104 | { 0xa2, 0x0001 }, | ||
105 | { 0xa3, 0x5c80 }, | ||
106 | { 0xa4, 0x0146 }, | ||
107 | { 0xa5, 0x1f1f }, | ||
108 | { 0xa6, 0x78c6 }, | ||
109 | { 0xa7, 0xe5ec }, | ||
110 | { 0xa8, 0xba61 }, | ||
111 | { 0xa9, 0x3c78 }, | ||
112 | { 0xaa, 0x8ae2 }, | ||
113 | { 0xab, 0xe5ec }, | ||
114 | { 0xac, 0xc600 }, | ||
115 | { 0xad, 0xba61 }, | ||
116 | { 0xae, 0x17ed }, | ||
117 | { 0xb0, 0x2080 }, | ||
118 | { 0xb1, 0x0000 }, | ||
119 | { 0xb3, 0x001f }, | ||
120 | { 0xb4, 0x020c }, | ||
121 | { 0xb5, 0x1f00 }, | ||
122 | { 0xb6, 0x0000 }, | ||
123 | { 0xb7, 0x4000 }, | ||
124 | { 0xbb, 0x0000 }, | ||
125 | { 0xbd, 0x0000 }, | ||
126 | { 0xbe, 0x0000 }, | ||
127 | { 0xbf, 0x0100 }, | ||
128 | { 0xc0, 0x0000 }, | ||
129 | { 0xc2, 0x0000 }, | ||
130 | { 0xd3, 0xa220 }, | ||
131 | { 0xd9, 0x0809 }, | ||
132 | { 0xda, 0x0000 }, | ||
133 | { 0xe0, 0x8000 }, | ||
134 | { 0xe1, 0x0200 }, | ||
135 | { 0xe2, 0x8000 }, | ||
136 | { 0xe3, 0x0200 }, | ||
137 | { 0xe4, 0x0f20 }, | ||
138 | { 0xe5, 0x001f }, | ||
139 | { 0xe6, 0x020c }, | ||
140 | { 0xe7, 0x1f00 }, | ||
141 | { 0xe8, 0x0000 }, | ||
142 | { 0xe9, 0x4000 }, | ||
143 | { 0xea, 0x00a6 }, | ||
144 | { 0xeb, 0x04c3 }, | ||
145 | { 0xec, 0x27c8 }, | ||
146 | { 0xed, 0x7418 }, | ||
147 | { 0xee, 0xbf50 }, | ||
148 | { 0xef, 0x0045 }, | ||
149 | { 0xf0, 0x0007 }, | ||
150 | { 0xfa, 0x0000 }, | ||
151 | { 0xfd, 0x0000 }, | ||
152 | { 0xfe, 0x10ec }, | ||
153 | { 0xff, 0x6338 }, | ||
154 | }; | ||
155 | |||
156 | static bool rt5660_volatile_register(struct device *dev, unsigned int reg) | ||
157 | { | ||
158 | int i; | ||
159 | |||
160 | for (i = 0; i < ARRAY_SIZE(rt5660_ranges); i++) | ||
161 | if ((reg >= rt5660_ranges[i].window_start && | ||
162 | reg <= rt5660_ranges[i].window_start + | ||
163 | rt5660_ranges[i].window_len) || | ||
164 | (reg >= rt5660_ranges[i].range_min && | ||
165 | reg <= rt5660_ranges[i].range_max)) | ||
166 | return true; | ||
167 | |||
168 | switch (reg) { | ||
169 | case RT5660_RESET: | ||
170 | case RT5660_PRIV_DATA: | ||
171 | case RT5660_EQ_CTRL1: | ||
172 | case RT5660_IRQ_CTRL2: | ||
173 | case RT5660_INT_IRQ_ST: | ||
174 | case RT5660_VENDOR_ID: | ||
175 | case RT5660_VENDOR_ID1: | ||
176 | case RT5660_VENDOR_ID2: | ||
177 | return true; | ||
178 | default: | ||
179 | return false; | ||
180 | } | ||
181 | } | ||
182 | |||
183 | static bool rt5660_readable_register(struct device *dev, unsigned int reg) | ||
184 | { | ||
185 | int i; | ||
186 | |||
187 | for (i = 0; i < ARRAY_SIZE(rt5660_ranges); i++) | ||
188 | if ((reg >= rt5660_ranges[i].window_start && | ||
189 | reg <= rt5660_ranges[i].window_start + | ||
190 | rt5660_ranges[i].window_len) || | ||
191 | (reg >= rt5660_ranges[i].range_min && | ||
192 | reg <= rt5660_ranges[i].range_max)) | ||
193 | return true; | ||
194 | |||
195 | switch (reg) { | ||
196 | case RT5660_RESET: | ||
197 | case RT5660_SPK_VOL: | ||
198 | case RT5660_LOUT_VOL: | ||
199 | case RT5660_IN1_IN2: | ||
200 | case RT5660_IN3_IN4: | ||
201 | case RT5660_DAC1_DIG_VOL: | ||
202 | case RT5660_STO1_ADC_DIG_VOL: | ||
203 | case RT5660_ADC_BST_VOL1: | ||
204 | case RT5660_STO1_ADC_MIXER: | ||
205 | case RT5660_AD_DA_MIXER: | ||
206 | case RT5660_STO_DAC_MIXER: | ||
207 | case RT5660_DIG_INF1_DATA: | ||
208 | case RT5660_REC_L1_MIXER: | ||
209 | case RT5660_REC_L2_MIXER: | ||
210 | case RT5660_REC_R1_MIXER: | ||
211 | case RT5660_REC_R2_MIXER: | ||
212 | case RT5660_LOUT_MIXER: | ||
213 | case RT5660_SPK_MIXER: | ||
214 | case RT5660_SPO_MIXER: | ||
215 | case RT5660_SPO_CLSD_RATIO: | ||
216 | case RT5660_OUT_L_GAIN1: | ||
217 | case RT5660_OUT_L_GAIN2: | ||
218 | case RT5660_OUT_L1_MIXER: | ||
219 | case RT5660_OUT_R_GAIN1: | ||
220 | case RT5660_OUT_R_GAIN2: | ||
221 | case RT5660_OUT_R1_MIXER: | ||
222 | case RT5660_PWR_DIG1: | ||
223 | case RT5660_PWR_DIG2: | ||
224 | case RT5660_PWR_ANLG1: | ||
225 | case RT5660_PWR_ANLG2: | ||
226 | case RT5660_PWR_MIXER: | ||
227 | case RT5660_PWR_VOL: | ||
228 | case RT5660_PRIV_INDEX: | ||
229 | case RT5660_PRIV_DATA: | ||
230 | case RT5660_I2S1_SDP: | ||
231 | case RT5660_ADDA_CLK1: | ||
232 | case RT5660_ADDA_CLK2: | ||
233 | case RT5660_DMIC_CTRL1: | ||
234 | case RT5660_GLB_CLK: | ||
235 | case RT5660_PLL_CTRL1: | ||
236 | case RT5660_PLL_CTRL2: | ||
237 | case RT5660_CLSD_AMP_OC_CTRL: | ||
238 | case RT5660_CLSD_AMP_CTRL: | ||
239 | case RT5660_LOUT_AMP_CTRL: | ||
240 | case RT5660_SPK_AMP_SPKVDD: | ||
241 | case RT5660_MICBIAS: | ||
242 | case RT5660_CLSD_OUT_CTRL1: | ||
243 | case RT5660_CLSD_OUT_CTRL2: | ||
244 | case RT5660_DIPOLE_MIC_CTRL1: | ||
245 | case RT5660_DIPOLE_MIC_CTRL2: | ||
246 | case RT5660_DIPOLE_MIC_CTRL3: | ||
247 | case RT5660_DIPOLE_MIC_CTRL4: | ||
248 | case RT5660_DIPOLE_MIC_CTRL5: | ||
249 | case RT5660_DIPOLE_MIC_CTRL6: | ||
250 | case RT5660_DIPOLE_MIC_CTRL7: | ||
251 | case RT5660_DIPOLE_MIC_CTRL8: | ||
252 | case RT5660_DIPOLE_MIC_CTRL9: | ||
253 | case RT5660_DIPOLE_MIC_CTRL10: | ||
254 | case RT5660_DIPOLE_MIC_CTRL11: | ||
255 | case RT5660_DIPOLE_MIC_CTRL12: | ||
256 | case RT5660_EQ_CTRL1: | ||
257 | case RT5660_EQ_CTRL2: | ||
258 | case RT5660_DRC_AGC_CTRL1: | ||
259 | case RT5660_DRC_AGC_CTRL2: | ||
260 | case RT5660_DRC_AGC_CTRL3: | ||
261 | case RT5660_DRC_AGC_CTRL4: | ||
262 | case RT5660_DRC_AGC_CTRL5: | ||
263 | case RT5660_JD_CTRL: | ||
264 | case RT5660_IRQ_CTRL1: | ||
265 | case RT5660_IRQ_CTRL2: | ||
266 | case RT5660_INT_IRQ_ST: | ||
267 | case RT5660_GPIO_CTRL1: | ||
268 | case RT5660_GPIO_CTRL2: | ||
269 | case RT5660_WIND_FILTER_CTRL1: | ||
270 | case RT5660_SV_ZCD1: | ||
271 | case RT5660_SV_ZCD2: | ||
272 | case RT5660_DRC1_LM_CTRL1: | ||
273 | case RT5660_DRC1_LM_CTRL2: | ||
274 | case RT5660_DRC2_LM_CTRL1: | ||
275 | case RT5660_DRC2_LM_CTRL2: | ||
276 | case RT5660_MULTI_DRC_CTRL: | ||
277 | case RT5660_DRC2_CTRL1: | ||
278 | case RT5660_DRC2_CTRL2: | ||
279 | case RT5660_DRC2_CTRL3: | ||
280 | case RT5660_DRC2_CTRL4: | ||
281 | case RT5660_DRC2_CTRL5: | ||
282 | case RT5660_ALC_PGA_CTRL1: | ||
283 | case RT5660_ALC_PGA_CTRL2: | ||
284 | case RT5660_ALC_PGA_CTRL3: | ||
285 | case RT5660_ALC_PGA_CTRL4: | ||
286 | case RT5660_ALC_PGA_CTRL5: | ||
287 | case RT5660_ALC_PGA_CTRL6: | ||
288 | case RT5660_ALC_PGA_CTRL7: | ||
289 | case RT5660_GEN_CTRL1: | ||
290 | case RT5660_GEN_CTRL2: | ||
291 | case RT5660_GEN_CTRL3: | ||
292 | case RT5660_VENDOR_ID: | ||
293 | case RT5660_VENDOR_ID1: | ||
294 | case RT5660_VENDOR_ID2: | ||
295 | return true; | ||
296 | default: | ||
297 | return false; | ||
298 | } | ||
299 | } | ||
300 | |||
301 | static const DECLARE_TLV_DB_SCALE(rt5660_out_vol_tlv, -4650, 150, 0); | ||
302 | static const DECLARE_TLV_DB_SCALE(rt5660_dac_vol_tlv, -6525, 75, 0); | ||
303 | static const DECLARE_TLV_DB_SCALE(rt5660_adc_vol_tlv, -1725, 75, 0); | ||
304 | static const DECLARE_TLV_DB_SCALE(rt5660_adc_bst_tlv, 0, 1200, 0); | ||
305 | static const DECLARE_TLV_DB_SCALE(rt5660_bst_tlv, -1200, 75, 0); | ||
306 | |||
307 | static const struct snd_kcontrol_new rt5660_snd_controls[] = { | ||
308 | /* Speaker Output Volume */ | ||
309 | SOC_SINGLE("Speaker Playback Switch", RT5660_SPK_VOL, RT5660_L_MUTE_SFT, | ||
310 | 1, 1), | ||
311 | SOC_SINGLE_TLV("Speaker Playback Volume", RT5660_SPK_VOL, | ||
312 | RT5660_L_VOL_SFT, 39, 1, rt5660_out_vol_tlv), | ||
313 | |||
314 | /* OUTPUT Control */ | ||
315 | SOC_DOUBLE("OUT Playback Switch", RT5660_LOUT_VOL, RT5660_L_MUTE_SFT, | ||
316 | RT5660_R_MUTE_SFT, 1, 1), | ||
317 | SOC_DOUBLE_TLV("OUT Playback Volume", RT5660_LOUT_VOL, RT5660_L_VOL_SFT, | ||
318 | RT5660_R_VOL_SFT, 39, 1, rt5660_out_vol_tlv), | ||
319 | |||
320 | /* DAC Digital Volume */ | ||
321 | SOC_DOUBLE_TLV("DAC1 Playback Volume", RT5660_DAC1_DIG_VOL, | ||
322 | RT5660_DAC_L1_VOL_SFT, RT5660_DAC_R1_VOL_SFT, 87, 0, | ||
323 | rt5660_dac_vol_tlv), | ||
324 | |||
325 | /* IN1/IN2/IN3 Control */ | ||
326 | SOC_SINGLE_TLV("IN1 Boost Volume", RT5660_IN1_IN2, RT5660_BST_SFT1, 69, | ||
327 | 0, rt5660_bst_tlv), | ||
328 | SOC_SINGLE_TLV("IN2 Boost Volume", RT5660_IN1_IN2, RT5660_BST_SFT2, 69, | ||
329 | 0, rt5660_bst_tlv), | ||
330 | SOC_SINGLE_TLV("IN3 Boost Volume", RT5660_IN3_IN4, RT5660_BST_SFT3, 69, | ||
331 | 0, rt5660_bst_tlv), | ||
332 | |||
333 | /* ADC Digital Volume Control */ | ||
334 | SOC_DOUBLE("ADC Capture Switch", RT5660_STO1_ADC_DIG_VOL, | ||
335 | RT5660_L_MUTE_SFT, RT5660_R_MUTE_SFT, 1, 1), | ||
336 | SOC_DOUBLE_TLV("ADC Capture Volume", RT5660_STO1_ADC_DIG_VOL, | ||
337 | RT5660_ADC_L_VOL_SFT, RT5660_ADC_R_VOL_SFT, 63, 0, | ||
338 | rt5660_adc_vol_tlv), | ||
339 | |||
340 | /* ADC Boost Volume Control */ | ||
341 | SOC_DOUBLE_TLV("STO1 ADC Boost Gain Volume", RT5660_ADC_BST_VOL1, | ||
342 | RT5660_STO1_ADC_L_BST_SFT, RT5660_STO1_ADC_R_BST_SFT, 3, 0, | ||
343 | rt5660_adc_bst_tlv), | ||
344 | }; | ||
345 | |||
346 | /** | ||
347 | * rt5660_set_dmic_clk - Set parameter of dmic. | ||
348 | * | ||
349 | * @w: DAPM widget. | ||
350 | * @kcontrol: The kcontrol of this widget. | ||
351 | * @event: Event id. | ||
352 | * | ||
353 | */ | ||
354 | static int rt5660_set_dmic_clk(struct snd_soc_dapm_widget *w, | ||
355 | struct snd_kcontrol *kcontrol, int event) | ||
356 | { | ||
357 | struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); | ||
358 | struct rt5660_priv *rt5660 = snd_soc_codec_get_drvdata(codec); | ||
359 | int idx, rate; | ||
360 | |||
361 | rate = rt5660->sysclk / rl6231_get_pre_div(rt5660->regmap, | ||
362 | RT5660_ADDA_CLK1, RT5660_I2S_PD1_SFT); | ||
363 | idx = rl6231_calc_dmic_clk(rate); | ||
364 | if (idx < 0) | ||
365 | dev_err(codec->dev, "Failed to set DMIC clock\n"); | ||
366 | else | ||
367 | snd_soc_update_bits(codec, RT5660_DMIC_CTRL1, | ||
368 | RT5660_DMIC_CLK_MASK, idx << RT5660_DMIC_CLK_SFT); | ||
369 | |||
370 | return idx; | ||
371 | } | ||
372 | |||
373 | static int rt5660_is_sys_clk_from_pll(struct snd_soc_dapm_widget *source, | ||
374 | struct snd_soc_dapm_widget *sink) | ||
375 | { | ||
376 | struct snd_soc_codec *codec = snd_soc_dapm_to_codec(source->dapm); | ||
377 | unsigned int val; | ||
378 | |||
379 | val = snd_soc_read(codec, RT5660_GLB_CLK); | ||
380 | val &= RT5660_SCLK_SRC_MASK; | ||
381 | if (val == RT5660_SCLK_SRC_PLL1) | ||
382 | return 1; | ||
383 | else | ||
384 | return 0; | ||
385 | } | ||
386 | |||
387 | /* Digital Mixer */ | ||
388 | static const struct snd_kcontrol_new rt5660_sto1_adc_l_mix[] = { | ||
389 | SOC_DAPM_SINGLE("ADC1 Switch", RT5660_STO1_ADC_MIXER, | ||
390 | RT5660_M_ADC_L1_SFT, 1, 1), | ||
391 | SOC_DAPM_SINGLE("ADC2 Switch", RT5660_STO1_ADC_MIXER, | ||
392 | RT5660_M_ADC_L2_SFT, 1, 1), | ||
393 | }; | ||
394 | |||
395 | static const struct snd_kcontrol_new rt5660_sto1_adc_r_mix[] = { | ||
396 | SOC_DAPM_SINGLE("ADC1 Switch", RT5660_STO1_ADC_MIXER, | ||
397 | RT5660_M_ADC_R1_SFT, 1, 1), | ||
398 | SOC_DAPM_SINGLE("ADC2 Switch", RT5660_STO1_ADC_MIXER, | ||
399 | RT5660_M_ADC_R2_SFT, 1, 1), | ||
400 | }; | ||
401 | |||
402 | static const struct snd_kcontrol_new rt5660_dac_l_mix[] = { | ||
403 | SOC_DAPM_SINGLE("Stereo ADC Switch", RT5660_AD_DA_MIXER, | ||
404 | RT5660_M_ADCMIX_L_SFT, 1, 1), | ||
405 | SOC_DAPM_SINGLE("DAC1 Switch", RT5660_AD_DA_MIXER, | ||
406 | RT5660_M_DAC1_L_SFT, 1, 1), | ||
407 | }; | ||
408 | |||
409 | static const struct snd_kcontrol_new rt5660_dac_r_mix[] = { | ||
410 | SOC_DAPM_SINGLE("Stereo ADC Switch", RT5660_AD_DA_MIXER, | ||
411 | RT5660_M_ADCMIX_R_SFT, 1, 1), | ||
412 | SOC_DAPM_SINGLE("DAC1 Switch", RT5660_AD_DA_MIXER, | ||
413 | RT5660_M_DAC1_R_SFT, 1, 1), | ||
414 | }; | ||
415 | |||
416 | static const struct snd_kcontrol_new rt5660_sto_dac_l_mix[] = { | ||
417 | SOC_DAPM_SINGLE("DAC L1 Switch", RT5660_STO_DAC_MIXER, | ||
418 | RT5660_M_DAC_L1_SFT, 1, 1), | ||
419 | SOC_DAPM_SINGLE("DAC R1 Switch", RT5660_STO_DAC_MIXER, | ||
420 | RT5660_M_DAC_R1_STO_L_SFT, 1, 1), | ||
421 | }; | ||
422 | |||
423 | static const struct snd_kcontrol_new rt5660_sto_dac_r_mix[] = { | ||
424 | SOC_DAPM_SINGLE("DAC R1 Switch", RT5660_STO_DAC_MIXER, | ||
425 | RT5660_M_DAC_R1_SFT, 1, 1), | ||
426 | SOC_DAPM_SINGLE("DAC L1 Switch", RT5660_STO_DAC_MIXER, | ||
427 | RT5660_M_DAC_L1_STO_R_SFT, 1, 1), | ||
428 | }; | ||
429 | |||
430 | /* Analog Input Mixer */ | ||
431 | static const struct snd_kcontrol_new rt5660_rec_l_mix[] = { | ||
432 | SOC_DAPM_SINGLE("BST3 Switch", RT5660_REC_L2_MIXER, | ||
433 | RT5660_M_BST3_RM_L_SFT, 1, 1), | ||
434 | SOC_DAPM_SINGLE("BST2 Switch", RT5660_REC_L2_MIXER, | ||
435 | RT5660_M_BST2_RM_L_SFT, 1, 1), | ||
436 | SOC_DAPM_SINGLE("BST1 Switch", RT5660_REC_L2_MIXER, | ||
437 | RT5660_M_BST1_RM_L_SFT, 1, 1), | ||
438 | SOC_DAPM_SINGLE("OUT MIXL Switch", RT5660_REC_L2_MIXER, | ||
439 | RT5660_M_OM_L_RM_L_SFT, 1, 1), | ||
440 | }; | ||
441 | |||
442 | static const struct snd_kcontrol_new rt5660_rec_r_mix[] = { | ||
443 | SOC_DAPM_SINGLE("BST3 Switch", RT5660_REC_R2_MIXER, | ||
444 | RT5660_M_BST3_RM_R_SFT, 1, 1), | ||
445 | SOC_DAPM_SINGLE("BST2 Switch", RT5660_REC_R2_MIXER, | ||
446 | RT5660_M_BST2_RM_R_SFT, 1, 1), | ||
447 | SOC_DAPM_SINGLE("BST1 Switch", RT5660_REC_R2_MIXER, | ||
448 | RT5660_M_BST1_RM_R_SFT, 1, 1), | ||
449 | SOC_DAPM_SINGLE("OUT MIXR Switch", RT5660_REC_R2_MIXER, | ||
450 | RT5660_M_OM_R_RM_R_SFT, 1, 1), | ||
451 | }; | ||
452 | |||
453 | static const struct snd_kcontrol_new rt5660_spk_mix[] = { | ||
454 | SOC_DAPM_SINGLE("BST3 Switch", RT5660_SPK_MIXER, | ||
455 | RT5660_M_BST3_SM_SFT, 1, 1), | ||
456 | SOC_DAPM_SINGLE("BST1 Switch", RT5660_SPK_MIXER, | ||
457 | RT5660_M_BST1_SM_SFT, 1, 1), | ||
458 | SOC_DAPM_SINGLE("DACL Switch", RT5660_SPK_MIXER, | ||
459 | RT5660_M_DACL_SM_SFT, 1, 1), | ||
460 | SOC_DAPM_SINGLE("DACR Switch", RT5660_SPK_MIXER, | ||
461 | RT5660_M_DACR_SM_SFT, 1, 1), | ||
462 | SOC_DAPM_SINGLE("OUTMIXL Switch", RT5660_SPK_MIXER, | ||
463 | RT5660_M_OM_L_SM_SFT, 1, 1), | ||
464 | }; | ||
465 | |||
466 | static const struct snd_kcontrol_new rt5660_out_l_mix[] = { | ||
467 | SOC_DAPM_SINGLE("BST3 Switch", RT5660_OUT_L1_MIXER, | ||
468 | RT5660_M_BST3_OM_L_SFT, 1, 1), | ||
469 | SOC_DAPM_SINGLE("BST2 Switch", RT5660_OUT_L1_MIXER, | ||
470 | RT5660_M_BST2_OM_L_SFT, 1, 1), | ||
471 | SOC_DAPM_SINGLE("BST1 Switch", RT5660_OUT_L1_MIXER, | ||
472 | RT5660_M_BST1_OM_L_SFT, 1, 1), | ||
473 | SOC_DAPM_SINGLE("RECMIXL Switch", RT5660_OUT_L1_MIXER, | ||
474 | RT5660_M_RM_L_OM_L_SFT, 1, 1), | ||
475 | SOC_DAPM_SINGLE("DACR Switch", RT5660_OUT_L1_MIXER, | ||
476 | RT5660_M_DAC_R_OM_L_SFT, 1, 1), | ||
477 | SOC_DAPM_SINGLE("DACL Switch", RT5660_OUT_L1_MIXER, | ||
478 | RT5660_M_DAC_L_OM_L_SFT, 1, 1), | ||
479 | }; | ||
480 | |||
481 | static const struct snd_kcontrol_new rt5660_out_r_mix[] = { | ||
482 | SOC_DAPM_SINGLE("BST2 Switch", RT5660_OUT_R1_MIXER, | ||
483 | RT5660_M_BST2_OM_R_SFT, 1, 1), | ||
484 | SOC_DAPM_SINGLE("BST1 Switch", RT5660_OUT_R1_MIXER, | ||
485 | RT5660_M_BST1_OM_R_SFT, 1, 1), | ||
486 | SOC_DAPM_SINGLE("RECMIXR Switch", RT5660_OUT_R1_MIXER, | ||
487 | RT5660_M_RM_R_OM_R_SFT, 1, 1), | ||
488 | SOC_DAPM_SINGLE("DACR Switch", RT5660_OUT_R1_MIXER, | ||
489 | RT5660_M_DAC_R_OM_R_SFT, 1, 1), | ||
490 | SOC_DAPM_SINGLE("DACL Switch", RT5660_OUT_R1_MIXER, | ||
491 | RT5660_M_DAC_L_OM_R_SFT, 1, 1), | ||
492 | }; | ||
493 | |||
494 | static const struct snd_kcontrol_new rt5660_spo_mix[] = { | ||
495 | SOC_DAPM_SINGLE("DACR Switch", RT5660_SPO_MIXER, | ||
496 | RT5660_M_DAC_R_SPM_SFT, 1, 1), | ||
497 | SOC_DAPM_SINGLE("DACL Switch", RT5660_SPO_MIXER, | ||
498 | RT5660_M_DAC_L_SPM_SFT, 1, 1), | ||
499 | SOC_DAPM_SINGLE("SPKVOL Switch", RT5660_SPO_MIXER, | ||
500 | RT5660_M_SV_SPM_SFT, 1, 1), | ||
501 | SOC_DAPM_SINGLE("BST1 Switch", RT5660_SPO_MIXER, | ||
502 | RT5660_M_BST1_SPM_SFT, 1, 1), | ||
503 | }; | ||
504 | |||
505 | static const struct snd_kcontrol_new rt5660_lout_mix[] = { | ||
506 | SOC_DAPM_SINGLE("DAC Switch", RT5660_LOUT_MIXER, | ||
507 | RT5660_M_DAC1_LM_SFT, 1, 1), | ||
508 | SOC_DAPM_SINGLE("OUTMIX Switch", RT5660_LOUT_MIXER, | ||
509 | RT5660_M_LOVOL_LM_SFT, 1, 1), | ||
510 | }; | ||
511 | |||
512 | static const struct snd_kcontrol_new spk_vol_control = | ||
513 | SOC_DAPM_SINGLE("Switch", RT5660_SPK_VOL, | ||
514 | RT5660_VOL_L_SFT, 1, 1); | ||
515 | |||
516 | static const struct snd_kcontrol_new lout_l_vol_control = | ||
517 | SOC_DAPM_SINGLE("Switch", RT5660_LOUT_VOL, | ||
518 | RT5660_VOL_L_SFT, 1, 1); | ||
519 | |||
520 | static const struct snd_kcontrol_new lout_r_vol_control = | ||
521 | SOC_DAPM_SINGLE("Switch", RT5660_LOUT_VOL, | ||
522 | RT5660_VOL_R_SFT, 1, 1); | ||
523 | |||
524 | /* Interface data select */ | ||
525 | static const char * const rt5660_data_select[] = { | ||
526 | "L/R", "R/L", "L/L", "R/R" | ||
527 | }; | ||
528 | |||
529 | static const SOC_ENUM_SINGLE_DECL(rt5660_if1_dac_enum, | ||
530 | RT5660_DIG_INF1_DATA, RT5660_IF1_DAC_IN_SFT, rt5660_data_select); | ||
531 | |||
532 | static const SOC_ENUM_SINGLE_DECL(rt5660_if1_adc_enum, | ||
533 | RT5660_DIG_INF1_DATA, RT5660_IF1_ADC_IN_SFT, rt5660_data_select); | ||
534 | |||
535 | static const struct snd_kcontrol_new rt5660_if1_dac_swap_mux = | ||
536 | SOC_DAPM_ENUM("IF1 DAC Swap Source", rt5660_if1_dac_enum); | ||
537 | |||
538 | static const struct snd_kcontrol_new rt5660_if1_adc_swap_mux = | ||
539 | SOC_DAPM_ENUM("IF1 ADC Swap Source", rt5660_if1_adc_enum); | ||
540 | |||
541 | static int rt5660_lout_event(struct snd_soc_dapm_widget *w, | ||
542 | struct snd_kcontrol *kcontrol, int event) | ||
543 | { | ||
544 | struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); | ||
545 | |||
546 | switch (event) { | ||
547 | case SND_SOC_DAPM_POST_PMU: | ||
548 | snd_soc_update_bits(codec, RT5660_LOUT_AMP_CTRL, | ||
549 | RT5660_LOUT_CO_MASK | RT5660_LOUT_CB_MASK, | ||
550 | RT5660_LOUT_CO_EN | RT5660_LOUT_CB_PU); | ||
551 | break; | ||
552 | |||
553 | case SND_SOC_DAPM_PRE_PMD: | ||
554 | snd_soc_update_bits(codec, RT5660_LOUT_AMP_CTRL, | ||
555 | RT5660_LOUT_CO_MASK | RT5660_LOUT_CB_MASK, | ||
556 | RT5660_LOUT_CO_DIS | RT5660_LOUT_CB_PD); | ||
557 | break; | ||
558 | |||
559 | default: | ||
560 | return 0; | ||
561 | } | ||
562 | |||
563 | return 0; | ||
564 | } | ||
565 | |||
566 | static const struct snd_soc_dapm_widget rt5660_dapm_widgets[] = { | ||
567 | SND_SOC_DAPM_SUPPLY("LDO2", RT5660_PWR_ANLG1, | ||
568 | RT5660_PWR_LDO2_BIT, 0, NULL, 0), | ||
569 | SND_SOC_DAPM_SUPPLY("PLL1", RT5660_PWR_ANLG2, | ||
570 | RT5660_PWR_PLL_BIT, 0, NULL, 0), | ||
571 | |||
572 | /* MICBIAS */ | ||
573 | SND_SOC_DAPM_SUPPLY("MICBIAS1", RT5660_PWR_ANLG2, | ||
574 | RT5660_PWR_MB1_BIT, 0, NULL, 0), | ||
575 | SND_SOC_DAPM_SUPPLY("MICBIAS2", RT5660_PWR_ANLG2, | ||
576 | RT5660_PWR_MB2_BIT, 0, NULL, 0), | ||
577 | |||
578 | /* Input Side */ | ||
579 | /* Input Lines */ | ||
580 | SND_SOC_DAPM_INPUT("DMIC L1"), | ||
581 | SND_SOC_DAPM_INPUT("DMIC R1"), | ||
582 | |||
583 | SND_SOC_DAPM_INPUT("IN1P"), | ||
584 | SND_SOC_DAPM_INPUT("IN1N"), | ||
585 | SND_SOC_DAPM_INPUT("IN2P"), | ||
586 | SND_SOC_DAPM_INPUT("IN3P"), | ||
587 | SND_SOC_DAPM_INPUT("IN3N"), | ||
588 | |||
589 | SND_SOC_DAPM_SUPPLY("DMIC CLK", SND_SOC_NOPM, 0, 0, | ||
590 | rt5660_set_dmic_clk, SND_SOC_DAPM_PRE_PMU), | ||
591 | SND_SOC_DAPM_SUPPLY("DMIC Power", RT5660_DMIC_CTRL1, | ||
592 | RT5660_DMIC_1_EN_SFT, 0, NULL, 0), | ||
593 | |||
594 | /* Boost */ | ||
595 | SND_SOC_DAPM_PGA("BST1", RT5660_PWR_ANLG2, RT5660_PWR_BST1_BIT, 0, | ||
596 | NULL, 0), | ||
597 | SND_SOC_DAPM_PGA("BST2", RT5660_PWR_ANLG2, RT5660_PWR_BST2_BIT, 0, | ||
598 | NULL, 0), | ||
599 | SND_SOC_DAPM_PGA("BST3", RT5660_PWR_ANLG2, RT5660_PWR_BST3_BIT, 0, | ||
600 | NULL, 0), | ||
601 | |||
602 | /* REC Mixer */ | ||
603 | SND_SOC_DAPM_MIXER("RECMIXL", RT5660_PWR_MIXER, RT5660_PWR_RM_L_BIT, | ||
604 | 0, rt5660_rec_l_mix, ARRAY_SIZE(rt5660_rec_l_mix)), | ||
605 | SND_SOC_DAPM_MIXER("RECMIXR", RT5660_PWR_MIXER, RT5660_PWR_RM_R_BIT, | ||
606 | 0, rt5660_rec_r_mix, ARRAY_SIZE(rt5660_rec_r_mix)), | ||
607 | |||
608 | /* ADCs */ | ||
609 | SND_SOC_DAPM_ADC("ADC L", NULL, SND_SOC_NOPM, 0, 0), | ||
610 | SND_SOC_DAPM_ADC("ADC R", NULL, SND_SOC_NOPM, 0, 0), | ||
611 | |||
612 | SND_SOC_DAPM_SUPPLY("ADC L power", RT5660_PWR_DIG1, | ||
613 | RT5660_PWR_ADC_L_BIT, 0, NULL, 0), | ||
614 | SND_SOC_DAPM_SUPPLY("ADC R power", RT5660_PWR_DIG1, | ||
615 | RT5660_PWR_ADC_R_BIT, 0, NULL, 0), | ||
616 | SND_SOC_DAPM_SUPPLY("ADC clock", RT5660_PR_BASE + RT5660_CHOP_DAC_ADC, | ||
617 | 12, 0, NULL, 0), | ||
618 | |||
619 | /* ADC Mixer */ | ||
620 | SND_SOC_DAPM_SUPPLY("adc stereo1 filter", RT5660_PWR_DIG2, | ||
621 | RT5660_PWR_ADC_S1F_BIT, 0, NULL, 0), | ||
622 | SND_SOC_DAPM_MIXER("Sto1 ADC MIXL", SND_SOC_NOPM, 0, 0, | ||
623 | rt5660_sto1_adc_l_mix, ARRAY_SIZE(rt5660_sto1_adc_l_mix)), | ||
624 | SND_SOC_DAPM_MIXER("Sto1 ADC MIXR", SND_SOC_NOPM, 0, 0, | ||
625 | rt5660_sto1_adc_r_mix, ARRAY_SIZE(rt5660_sto1_adc_r_mix)), | ||
626 | |||
627 | /* ADC */ | ||
628 | SND_SOC_DAPM_ADC("Stereo1 ADC MIXL", NULL, RT5660_STO1_ADC_DIG_VOL, | ||
629 | RT5660_L_MUTE_SFT, 1), | ||
630 | SND_SOC_DAPM_ADC("Stereo1 ADC MIXR", NULL, RT5660_STO1_ADC_DIG_VOL, | ||
631 | RT5660_R_MUTE_SFT, 1), | ||
632 | |||
633 | /* Digital Interface */ | ||
634 | SND_SOC_DAPM_SUPPLY("I2S1", RT5660_PWR_DIG1, RT5660_PWR_I2S1_BIT, 0, | ||
635 | NULL, 0), | ||
636 | SND_SOC_DAPM_PGA("IF1 DAC", SND_SOC_NOPM, 0, 0, NULL, 0), | ||
637 | SND_SOC_DAPM_PGA("IF1 DAC L", SND_SOC_NOPM, 0, 0, NULL, 0), | ||
638 | SND_SOC_DAPM_PGA("IF1 DAC R", SND_SOC_NOPM, 0, 0, NULL, 0), | ||
639 | SND_SOC_DAPM_MUX("IF1 DAC Swap Mux", SND_SOC_NOPM, 0, 0, | ||
640 | &rt5660_if1_dac_swap_mux), | ||
641 | SND_SOC_DAPM_PGA("IF1 ADC", SND_SOC_NOPM, 0, 0, NULL, 0), | ||
642 | SND_SOC_DAPM_MUX("IF1 ADC Swap Mux", SND_SOC_NOPM, 0, 0, | ||
643 | &rt5660_if1_adc_swap_mux), | ||
644 | |||
645 | /* Audio Interface */ | ||
646 | SND_SOC_DAPM_AIF_IN("AIF1RX", "AIF1 Playback", 0, SND_SOC_NOPM, 0, 0), | ||
647 | SND_SOC_DAPM_AIF_OUT("AIF1TX", "AIF1 Capture", 0, SND_SOC_NOPM, 0, 0), | ||
648 | |||
649 | /* Output Side */ | ||
650 | /* DAC mixer before sound effect */ | ||
651 | SND_SOC_DAPM_MIXER("DAC1 MIXL", SND_SOC_NOPM, 0, 0, rt5660_dac_l_mix, | ||
652 | ARRAY_SIZE(rt5660_dac_l_mix)), | ||
653 | SND_SOC_DAPM_MIXER("DAC1 MIXR", SND_SOC_NOPM, 0, 0, rt5660_dac_r_mix, | ||
654 | ARRAY_SIZE(rt5660_dac_r_mix)), | ||
655 | |||
656 | /* DAC Mixer */ | ||
657 | SND_SOC_DAPM_SUPPLY("dac stereo1 filter", RT5660_PWR_DIG2, | ||
658 | RT5660_PWR_DAC_S1F_BIT, 0, NULL, 0), | ||
659 | SND_SOC_DAPM_MIXER("Stereo DAC MIXL", SND_SOC_NOPM, 0, 0, | ||
660 | rt5660_sto_dac_l_mix, ARRAY_SIZE(rt5660_sto_dac_l_mix)), | ||
661 | SND_SOC_DAPM_MIXER("Stereo DAC MIXR", SND_SOC_NOPM, 0, 0, | ||
662 | rt5660_sto_dac_r_mix, ARRAY_SIZE(rt5660_sto_dac_r_mix)), | ||
663 | |||
664 | /* DACs */ | ||
665 | SND_SOC_DAPM_DAC("DAC L1", NULL, RT5660_PWR_DIG1, | ||
666 | RT5660_PWR_DAC_L1_BIT, 0), | ||
667 | SND_SOC_DAPM_DAC("DAC R1", NULL, RT5660_PWR_DIG1, | ||
668 | RT5660_PWR_DAC_R1_BIT, 0), | ||
669 | |||
670 | /* OUT Mixer */ | ||
671 | SND_SOC_DAPM_MIXER("SPK MIX", RT5660_PWR_MIXER, RT5660_PWR_SM_BIT, | ||
672 | 0, rt5660_spk_mix, ARRAY_SIZE(rt5660_spk_mix)), | ||
673 | SND_SOC_DAPM_MIXER("OUT MIXL", RT5660_PWR_MIXER, RT5660_PWR_OM_L_BIT, | ||
674 | 0, rt5660_out_l_mix, ARRAY_SIZE(rt5660_out_l_mix)), | ||
675 | SND_SOC_DAPM_MIXER("OUT MIXR", RT5660_PWR_MIXER, RT5660_PWR_OM_R_BIT, | ||
676 | 0, rt5660_out_r_mix, ARRAY_SIZE(rt5660_out_r_mix)), | ||
677 | |||
678 | /* Output Volume */ | ||
679 | SND_SOC_DAPM_SWITCH("SPKVOL", RT5660_PWR_VOL, | ||
680 | RT5660_PWR_SV_BIT, 0, &spk_vol_control), | ||
681 | SND_SOC_DAPM_PGA("DAC 1", SND_SOC_NOPM, | ||
682 | 0, 0, NULL, 0), | ||
683 | SND_SOC_DAPM_PGA("LOUTVOL", SND_SOC_NOPM, | ||
684 | 0, 0, NULL, 0), | ||
685 | SND_SOC_DAPM_SWITCH("LOUTVOL L", SND_SOC_NOPM, | ||
686 | RT5660_PWR_LV_L_BIT, 0, &lout_l_vol_control), | ||
687 | SND_SOC_DAPM_SWITCH("LOUTVOL R", SND_SOC_NOPM, | ||
688 | RT5660_PWR_LV_R_BIT, 0, &lout_r_vol_control), | ||
689 | |||
690 | /* HPO/LOUT/Mono Mixer */ | ||
691 | SND_SOC_DAPM_MIXER("SPO MIX", SND_SOC_NOPM, 0, | ||
692 | 0, rt5660_spo_mix, ARRAY_SIZE(rt5660_spo_mix)), | ||
693 | SND_SOC_DAPM_MIXER("LOUT MIX", SND_SOC_NOPM, 0, 0, | ||
694 | rt5660_lout_mix, ARRAY_SIZE(rt5660_lout_mix)), | ||
695 | SND_SOC_DAPM_SUPPLY("VREF HP", RT5660_GEN_CTRL1, | ||
696 | RT5660_PWR_VREF_HP_SFT, 0, NULL, 0), | ||
697 | SND_SOC_DAPM_PGA_S("LOUT amp", 1, RT5660_PWR_ANLG1, | ||
698 | RT5660_PWR_HA_BIT, 0, rt5660_lout_event, | ||
699 | SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU), | ||
700 | SND_SOC_DAPM_PGA_S("SPK amp", 1, RT5660_PWR_DIG1, | ||
701 | RT5660_PWR_CLS_D_BIT, 0, NULL, 0), | ||
702 | |||
703 | /* Output Lines */ | ||
704 | SND_SOC_DAPM_OUTPUT("LOUTL"), | ||
705 | SND_SOC_DAPM_OUTPUT("LOUTR"), | ||
706 | SND_SOC_DAPM_OUTPUT("SPO"), | ||
707 | }; | ||
708 | |||
709 | static const struct snd_soc_dapm_route rt5660_dapm_routes[] = { | ||
710 | { "MICBIAS1", NULL, "LDO2" }, | ||
711 | { "MICBIAS2", NULL, "LDO2" }, | ||
712 | |||
713 | { "BST1", NULL, "IN1P" }, | ||
714 | { "BST1", NULL, "IN1N" }, | ||
715 | { "BST2", NULL, "IN2P" }, | ||
716 | { "BST3", NULL, "IN3P" }, | ||
717 | { "BST3", NULL, "IN3N" }, | ||
718 | |||
719 | { "RECMIXL", "BST3 Switch", "BST3" }, | ||
720 | { "RECMIXL", "BST2 Switch", "BST2" }, | ||
721 | { "RECMIXL", "BST1 Switch", "BST1" }, | ||
722 | { "RECMIXL", "OUT MIXL Switch", "OUT MIXL" }, | ||
723 | |||
724 | { "RECMIXR", "BST3 Switch", "BST3" }, | ||
725 | { "RECMIXR", "BST2 Switch", "BST2" }, | ||
726 | { "RECMIXR", "BST1 Switch", "BST1" }, | ||
727 | { "RECMIXR", "OUT MIXR Switch", "OUT MIXR" }, | ||
728 | |||
729 | { "ADC L", NULL, "RECMIXL" }, | ||
730 | { "ADC L", NULL, "ADC L power" }, | ||
731 | { "ADC L", NULL, "ADC clock" }, | ||
732 | { "ADC R", NULL, "RECMIXR" }, | ||
733 | { "ADC R", NULL, "ADC R power" }, | ||
734 | { "ADC R", NULL, "ADC clock" }, | ||
735 | |||
736 | {"DMIC L1", NULL, "DMIC CLK"}, | ||
737 | {"DMIC L1", NULL, "DMIC Power"}, | ||
738 | {"DMIC R1", NULL, "DMIC CLK"}, | ||
739 | {"DMIC R1", NULL, "DMIC Power"}, | ||
740 | |||
741 | { "Sto1 ADC MIXL", "ADC1 Switch", "ADC L" }, | ||
742 | { "Sto1 ADC MIXL", "ADC2 Switch", "DMIC L1" }, | ||
743 | { "Sto1 ADC MIXR", "ADC1 Switch", "ADC R" }, | ||
744 | { "Sto1 ADC MIXR", "ADC2 Switch", "DMIC R1" }, | ||
745 | |||
746 | { "Stereo1 ADC MIXL", NULL, "Sto1 ADC MIXL" }, | ||
747 | { "Stereo1 ADC MIXL", NULL, "adc stereo1 filter" }, | ||
748 | { "adc stereo1 filter", NULL, "PLL1", rt5660_is_sys_clk_from_pll }, | ||
749 | |||
750 | { "Stereo1 ADC MIXR", NULL, "Sto1 ADC MIXR" }, | ||
751 | { "Stereo1 ADC MIXR", NULL, "adc stereo1 filter" }, | ||
752 | { "adc stereo1 filter", NULL, "PLL1", rt5660_is_sys_clk_from_pll }, | ||
753 | |||
754 | { "IF1 ADC", NULL, "Stereo1 ADC MIXL" }, | ||
755 | { "IF1 ADC", NULL, "Stereo1 ADC MIXR" }, | ||
756 | { "IF1 ADC", NULL, "I2S1" }, | ||
757 | |||
758 | { "IF1 ADC Swap Mux", "L/R", "IF1 ADC" }, | ||
759 | { "IF1 ADC Swap Mux", "R/L", "IF1 ADC" }, | ||
760 | { "IF1 ADC Swap Mux", "L/L", "IF1 ADC" }, | ||
761 | { "IF1 ADC Swap Mux", "R/R", "IF1 ADC" }, | ||
762 | { "AIF1TX", NULL, "IF1 ADC Swap Mux" }, | ||
763 | |||
764 | { "IF1 DAC", NULL, "AIF1RX" }, | ||
765 | { "IF1 DAC", NULL, "I2S1" }, | ||
766 | |||
767 | { "IF1 DAC Swap Mux", "L/R", "IF1 DAC" }, | ||
768 | { "IF1 DAC Swap Mux", "R/L", "IF1 DAC" }, | ||
769 | { "IF1 DAC Swap Mux", "L/L", "IF1 DAC" }, | ||
770 | { "IF1 DAC Swap Mux", "R/R", "IF1 DAC" }, | ||
771 | |||
772 | { "IF1 DAC L", NULL, "IF1 DAC Swap Mux" }, | ||
773 | { "IF1 DAC R", NULL, "IF1 DAC Swap Mux" }, | ||
774 | |||
775 | { "DAC1 MIXL", "Stereo ADC Switch", "Stereo1 ADC MIXL" }, | ||
776 | { "DAC1 MIXL", "DAC1 Switch", "IF1 DAC L" }, | ||
777 | { "DAC1 MIXR", "Stereo ADC Switch", "Stereo1 ADC MIXR" }, | ||
778 | { "DAC1 MIXR", "DAC1 Switch", "IF1 DAC R" }, | ||
779 | |||
780 | { "Stereo DAC MIXL", "DAC L1 Switch", "DAC1 MIXL" }, | ||
781 | { "Stereo DAC MIXL", "DAC R1 Switch", "DAC1 MIXR" }, | ||
782 | { "Stereo DAC MIXL", NULL, "dac stereo1 filter" }, | ||
783 | { "dac stereo1 filter", NULL, "PLL1", rt5660_is_sys_clk_from_pll }, | ||
784 | { "Stereo DAC MIXR", "DAC R1 Switch", "DAC1 MIXR" }, | ||
785 | { "Stereo DAC MIXR", "DAC L1 Switch", "DAC1 MIXL" }, | ||
786 | { "Stereo DAC MIXR", NULL, "dac stereo1 filter" }, | ||
787 | { "dac stereo1 filter", NULL, "PLL1", rt5660_is_sys_clk_from_pll }, | ||
788 | |||
789 | { "DAC L1", NULL, "Stereo DAC MIXL" }, | ||
790 | { "DAC R1", NULL, "Stereo DAC MIXR" }, | ||
791 | |||
792 | { "SPK MIX", "BST3 Switch", "BST3" }, | ||
793 | { "SPK MIX", "BST1 Switch", "BST1" }, | ||
794 | { "SPK MIX", "DACL Switch", "DAC L1" }, | ||
795 | { "SPK MIX", "DACR Switch", "DAC R1" }, | ||
796 | { "SPK MIX", "OUTMIXL Switch", "OUT MIXL" }, | ||
797 | |||
798 | { "OUT MIXL", "BST3 Switch", "BST3" }, | ||
799 | { "OUT MIXL", "BST2 Switch", "BST2" }, | ||
800 | { "OUT MIXL", "BST1 Switch", "BST1" }, | ||
801 | { "OUT MIXL", "RECMIXL Switch", "RECMIXL" }, | ||
802 | { "OUT MIXL", "DACR Switch", "DAC R1" }, | ||
803 | { "OUT MIXL", "DACL Switch", "DAC L1" }, | ||
804 | |||
805 | { "OUT MIXR", "BST2 Switch", "BST2" }, | ||
806 | { "OUT MIXR", "BST1 Switch", "BST1" }, | ||
807 | { "OUT MIXR", "RECMIXR Switch", "RECMIXR" }, | ||
808 | { "OUT MIXR", "DACR Switch", "DAC R1" }, | ||
809 | { "OUT MIXR", "DACL Switch", "DAC L1" }, | ||
810 | |||
811 | { "SPO MIX", "DACR Switch", "DAC R1" }, | ||
812 | { "SPO MIX", "DACL Switch", "DAC L1" }, | ||
813 | { "SPO MIX", "SPKVOL Switch", "SPKVOL" }, | ||
814 | { "SPO MIX", "BST1 Switch", "BST1" }, | ||
815 | |||
816 | { "SPKVOL", "Switch", "SPK MIX" }, | ||
817 | { "LOUTVOL L", "Switch", "OUT MIXL" }, | ||
818 | { "LOUTVOL R", "Switch", "OUT MIXR" }, | ||
819 | |||
820 | { "LOUTVOL", NULL, "LOUTVOL L" }, | ||
821 | { "LOUTVOL", NULL, "LOUTVOL R" }, | ||
822 | |||
823 | { "DAC 1", NULL, "DAC L1" }, | ||
824 | { "DAC 1", NULL, "DAC R1" }, | ||
825 | |||
826 | { "LOUT MIX", "DAC Switch", "DAC 1" }, | ||
827 | { "LOUT MIX", "OUTMIX Switch", "LOUTVOL" }, | ||
828 | |||
829 | { "LOUT amp", NULL, "LOUT MIX" }, | ||
830 | { "LOUT amp", NULL, "VREF HP" }, | ||
831 | { "LOUTL", NULL, "LOUT amp" }, | ||
832 | { "LOUTR", NULL, "LOUT amp" }, | ||
833 | |||
834 | { "SPK amp", NULL, "SPO MIX" }, | ||
835 | { "SPO", NULL, "SPK amp" }, | ||
836 | }; | ||
837 | |||
838 | static int rt5660_hw_params(struct snd_pcm_substream *substream, | ||
839 | struct snd_pcm_hw_params *params, struct snd_soc_dai *dai) | ||
840 | { | ||
841 | struct snd_soc_codec *codec = dai->codec; | ||
842 | struct rt5660_priv *rt5660 = snd_soc_codec_get_drvdata(codec); | ||
843 | unsigned int val_len = 0, val_clk, mask_clk; | ||
844 | int pre_div, bclk_ms, frame_size; | ||
845 | |||
846 | rt5660->lrck[dai->id] = params_rate(params); | ||
847 | pre_div = rl6231_get_clk_info(rt5660->sysclk, rt5660->lrck[dai->id]); | ||
848 | if (pre_div < 0) { | ||
849 | dev_err(codec->dev, "Unsupported clock setting %d for DAI %d\n", | ||
850 | rt5660->lrck[dai->id], dai->id); | ||
851 | return -EINVAL; | ||
852 | } | ||
853 | |||
854 | frame_size = snd_soc_params_to_frame_size(params); | ||
855 | if (frame_size < 0) { | ||
856 | dev_err(codec->dev, "Unsupported frame size: %d\n", frame_size); | ||
857 | return frame_size; | ||
858 | } | ||
859 | |||
860 | if (frame_size > 32) | ||
861 | bclk_ms = 1; | ||
862 | else | ||
863 | bclk_ms = 0; | ||
864 | |||
865 | rt5660->bclk[dai->id] = rt5660->lrck[dai->id] * (32 << bclk_ms); | ||
866 | |||
867 | dev_dbg(dai->dev, "bclk is %dHz and lrck is %dHz\n", | ||
868 | rt5660->bclk[dai->id], rt5660->lrck[dai->id]); | ||
869 | dev_dbg(dai->dev, "bclk_ms is %d and pre_div is %d for iis %d\n", | ||
870 | bclk_ms, pre_div, dai->id); | ||
871 | |||
872 | switch (params_width(params)) { | ||
873 | case 16: | ||
874 | break; | ||
875 | case 20: | ||
876 | val_len |= RT5660_I2S_DL_20; | ||
877 | break; | ||
878 | case 24: | ||
879 | val_len |= RT5660_I2S_DL_24; | ||
880 | break; | ||
881 | case 8: | ||
882 | val_len |= RT5660_I2S_DL_8; | ||
883 | break; | ||
884 | default: | ||
885 | return -EINVAL; | ||
886 | } | ||
887 | |||
888 | switch (dai->id) { | ||
889 | case RT5660_AIF1: | ||
890 | mask_clk = RT5660_I2S_BCLK_MS1_MASK | RT5660_I2S_PD1_MASK; | ||
891 | val_clk = bclk_ms << RT5660_I2S_BCLK_MS1_SFT | | ||
892 | pre_div << RT5660_I2S_PD1_SFT; | ||
893 | snd_soc_update_bits(codec, RT5660_I2S1_SDP, RT5660_I2S_DL_MASK, | ||
894 | val_len); | ||
895 | snd_soc_update_bits(codec, RT5660_ADDA_CLK1, mask_clk, val_clk); | ||
896 | break; | ||
897 | |||
898 | default: | ||
899 | dev_err(codec->dev, "Invalid dai->id: %d\n", dai->id); | ||
900 | return -EINVAL; | ||
901 | } | ||
902 | |||
903 | return 0; | ||
904 | } | ||
905 | |||
906 | static int rt5660_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt) | ||
907 | { | ||
908 | struct snd_soc_codec *codec = dai->codec; | ||
909 | struct rt5660_priv *rt5660 = snd_soc_codec_get_drvdata(codec); | ||
910 | unsigned int reg_val = 0; | ||
911 | |||
912 | switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { | ||
913 | case SND_SOC_DAIFMT_CBM_CFM: | ||
914 | rt5660->master[dai->id] = 1; | ||
915 | break; | ||
916 | |||
917 | case SND_SOC_DAIFMT_CBS_CFS: | ||
918 | reg_val |= RT5660_I2S_MS_S; | ||
919 | rt5660->master[dai->id] = 0; | ||
920 | break; | ||
921 | |||
922 | default: | ||
923 | return -EINVAL; | ||
924 | } | ||
925 | |||
926 | switch (fmt & SND_SOC_DAIFMT_INV_MASK) { | ||
927 | case SND_SOC_DAIFMT_NB_NF: | ||
928 | break; | ||
929 | |||
930 | case SND_SOC_DAIFMT_IB_NF: | ||
931 | reg_val |= RT5660_I2S_BP_INV; | ||
932 | break; | ||
933 | |||
934 | default: | ||
935 | return -EINVAL; | ||
936 | } | ||
937 | |||
938 | switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { | ||
939 | case SND_SOC_DAIFMT_I2S: | ||
940 | break; | ||
941 | |||
942 | case SND_SOC_DAIFMT_LEFT_J: | ||
943 | reg_val |= RT5660_I2S_DF_LEFT; | ||
944 | break; | ||
945 | |||
946 | case SND_SOC_DAIFMT_DSP_A: | ||
947 | reg_val |= RT5660_I2S_DF_PCM_A; | ||
948 | break; | ||
949 | |||
950 | case SND_SOC_DAIFMT_DSP_B: | ||
951 | reg_val |= RT5660_I2S_DF_PCM_B; | ||
952 | break; | ||
953 | |||
954 | default: | ||
955 | return -EINVAL; | ||
956 | } | ||
957 | |||
958 | switch (dai->id) { | ||
959 | case RT5660_AIF1: | ||
960 | snd_soc_update_bits(codec, RT5660_I2S1_SDP, | ||
961 | RT5660_I2S_MS_MASK | RT5660_I2S_BP_MASK | | ||
962 | RT5660_I2S_DF_MASK, reg_val); | ||
963 | break; | ||
964 | |||
965 | default: | ||
966 | dev_err(codec->dev, "Invalid dai->id: %d\n", dai->id); | ||
967 | return -EINVAL; | ||
968 | } | ||
969 | |||
970 | return 0; | ||
971 | } | ||
972 | |||
973 | static int rt5660_set_dai_sysclk(struct snd_soc_dai *dai, | ||
974 | int clk_id, unsigned int freq, int dir) | ||
975 | { | ||
976 | struct snd_soc_codec *codec = dai->codec; | ||
977 | struct rt5660_priv *rt5660 = snd_soc_codec_get_drvdata(codec); | ||
978 | unsigned int reg_val = 0; | ||
979 | |||
980 | if (freq == rt5660->sysclk && clk_id == rt5660->sysclk_src) | ||
981 | return 0; | ||
982 | |||
983 | switch (clk_id) { | ||
984 | case RT5660_SCLK_S_MCLK: | ||
985 | reg_val |= RT5660_SCLK_SRC_MCLK; | ||
986 | break; | ||
987 | |||
988 | case RT5660_SCLK_S_PLL1: | ||
989 | reg_val |= RT5660_SCLK_SRC_PLL1; | ||
990 | break; | ||
991 | |||
992 | case RT5660_SCLK_S_RCCLK: | ||
993 | reg_val |= RT5660_SCLK_SRC_RCCLK; | ||
994 | break; | ||
995 | |||
996 | default: | ||
997 | dev_err(codec->dev, "Invalid clock id (%d)\n", clk_id); | ||
998 | return -EINVAL; | ||
999 | } | ||
1000 | |||
1001 | snd_soc_update_bits(codec, RT5660_GLB_CLK, RT5660_SCLK_SRC_MASK, | ||
1002 | reg_val); | ||
1003 | |||
1004 | rt5660->sysclk = freq; | ||
1005 | rt5660->sysclk_src = clk_id; | ||
1006 | |||
1007 | dev_dbg(dai->dev, "Sysclk is %dHz and clock id is %d\n", freq, clk_id); | ||
1008 | |||
1009 | return 0; | ||
1010 | } | ||
1011 | |||
1012 | static int rt5660_set_dai_pll(struct snd_soc_dai *dai, int pll_id, int source, | ||
1013 | unsigned int freq_in, unsigned int freq_out) | ||
1014 | { | ||
1015 | struct snd_soc_codec *codec = dai->codec; | ||
1016 | struct rt5660_priv *rt5660 = snd_soc_codec_get_drvdata(codec); | ||
1017 | struct rl6231_pll_code pll_code; | ||
1018 | int ret; | ||
1019 | |||
1020 | if (source == rt5660->pll_src && freq_in == rt5660->pll_in && | ||
1021 | freq_out == rt5660->pll_out) | ||
1022 | return 0; | ||
1023 | |||
1024 | if (!freq_in || !freq_out) { | ||
1025 | dev_dbg(codec->dev, "PLL disabled\n"); | ||
1026 | |||
1027 | rt5660->pll_in = 0; | ||
1028 | rt5660->pll_out = 0; | ||
1029 | snd_soc_update_bits(codec, RT5660_GLB_CLK, | ||
1030 | RT5660_SCLK_SRC_MASK, RT5660_SCLK_SRC_MCLK); | ||
1031 | return 0; | ||
1032 | } | ||
1033 | |||
1034 | switch (source) { | ||
1035 | case RT5660_PLL1_S_MCLK: | ||
1036 | snd_soc_update_bits(codec, RT5660_GLB_CLK, | ||
1037 | RT5660_PLL1_SRC_MASK, RT5660_PLL1_SRC_MCLK); | ||
1038 | break; | ||
1039 | |||
1040 | case RT5660_PLL1_S_BCLK: | ||
1041 | snd_soc_update_bits(codec, RT5660_GLB_CLK, | ||
1042 | RT5660_PLL1_SRC_MASK, RT5660_PLL1_SRC_BCLK1); | ||
1043 | break; | ||
1044 | |||
1045 | default: | ||
1046 | dev_err(codec->dev, "Unknown PLL source %d\n", source); | ||
1047 | return -EINVAL; | ||
1048 | } | ||
1049 | |||
1050 | ret = rl6231_pll_calc(freq_in, freq_out, &pll_code); | ||
1051 | if (ret < 0) { | ||
1052 | dev_err(codec->dev, "Unsupport input clock %d\n", freq_in); | ||
1053 | return ret; | ||
1054 | } | ||
1055 | |||
1056 | dev_dbg(codec->dev, "bypass=%d m=%d n=%d k=%d\n", | ||
1057 | pll_code.m_bp, (pll_code.m_bp ? 0 : pll_code.m_code), | ||
1058 | pll_code.n_code, pll_code.k_code); | ||
1059 | |||
1060 | snd_soc_write(codec, RT5660_PLL_CTRL1, | ||
1061 | pll_code.n_code << RT5660_PLL_N_SFT | pll_code.k_code); | ||
1062 | snd_soc_write(codec, RT5660_PLL_CTRL2, | ||
1063 | (pll_code.m_bp ? 0 : pll_code.m_code) << RT5660_PLL_M_SFT | | ||
1064 | pll_code.m_bp << RT5660_PLL_M_BP_SFT); | ||
1065 | |||
1066 | rt5660->pll_in = freq_in; | ||
1067 | rt5660->pll_out = freq_out; | ||
1068 | rt5660->pll_src = source; | ||
1069 | |||
1070 | return 0; | ||
1071 | } | ||
1072 | |||
1073 | static int rt5660_set_bias_level(struct snd_soc_codec *codec, | ||
1074 | enum snd_soc_bias_level level) | ||
1075 | { | ||
1076 | struct rt5660_priv *rt5660 = snd_soc_codec_get_drvdata(codec); | ||
1077 | int ret; | ||
1078 | |||
1079 | switch (level) { | ||
1080 | case SND_SOC_BIAS_ON: | ||
1081 | break; | ||
1082 | |||
1083 | case SND_SOC_BIAS_PREPARE: | ||
1084 | snd_soc_update_bits(codec, RT5660_GEN_CTRL1, | ||
1085 | RT5660_DIG_GATE_CTRL, RT5660_DIG_GATE_CTRL); | ||
1086 | |||
1087 | if (IS_ERR(rt5660->mclk)) | ||
1088 | break; | ||
1089 | |||
1090 | if (snd_soc_codec_get_bias_level(codec) == SND_SOC_BIAS_ON) { | ||
1091 | clk_disable_unprepare(rt5660->mclk); | ||
1092 | } else { | ||
1093 | ret = clk_prepare_enable(rt5660->mclk); | ||
1094 | if (ret) | ||
1095 | return ret; | ||
1096 | } | ||
1097 | break; | ||
1098 | |||
1099 | case SND_SOC_BIAS_STANDBY: | ||
1100 | if (snd_soc_codec_get_bias_level(codec) == SND_SOC_BIAS_OFF) { | ||
1101 | snd_soc_update_bits(codec, RT5660_PWR_ANLG1, | ||
1102 | RT5660_PWR_VREF1 | RT5660_PWR_MB | | ||
1103 | RT5660_PWR_BG | RT5660_PWR_VREF2, | ||
1104 | RT5660_PWR_VREF1 | RT5660_PWR_MB | | ||
1105 | RT5660_PWR_BG | RT5660_PWR_VREF2); | ||
1106 | usleep_range(10000, 15000); | ||
1107 | snd_soc_update_bits(codec, RT5660_PWR_ANLG1, | ||
1108 | RT5660_PWR_FV1 | RT5660_PWR_FV2, | ||
1109 | RT5660_PWR_FV1 | RT5660_PWR_FV2); | ||
1110 | } | ||
1111 | break; | ||
1112 | |||
1113 | case SND_SOC_BIAS_OFF: | ||
1114 | snd_soc_update_bits(codec, RT5660_GEN_CTRL1, | ||
1115 | RT5660_DIG_GATE_CTRL, 0); | ||
1116 | break; | ||
1117 | |||
1118 | default: | ||
1119 | break; | ||
1120 | } | ||
1121 | |||
1122 | return 0; | ||
1123 | } | ||
1124 | |||
1125 | static int rt5660_probe(struct snd_soc_codec *codec) | ||
1126 | { | ||
1127 | struct rt5660_priv *rt5660 = snd_soc_codec_get_drvdata(codec); | ||
1128 | |||
1129 | rt5660->codec = codec; | ||
1130 | |||
1131 | return 0; | ||
1132 | } | ||
1133 | |||
1134 | static int rt5660_remove(struct snd_soc_codec *codec) | ||
1135 | { | ||
1136 | return snd_soc_write(codec, RT5660_RESET, 0); | ||
1137 | } | ||
1138 | |||
1139 | #ifdef CONFIG_PM | ||
1140 | static int rt5660_suspend(struct snd_soc_codec *codec) | ||
1141 | { | ||
1142 | struct rt5660_priv *rt5660 = snd_soc_codec_get_drvdata(codec); | ||
1143 | |||
1144 | regcache_cache_only(rt5660->regmap, true); | ||
1145 | regcache_mark_dirty(rt5660->regmap); | ||
1146 | |||
1147 | return 0; | ||
1148 | } | ||
1149 | |||
1150 | static int rt5660_resume(struct snd_soc_codec *codec) | ||
1151 | { | ||
1152 | struct rt5660_priv *rt5660 = snd_soc_codec_get_drvdata(codec); | ||
1153 | |||
1154 | if (rt5660->pdata.poweroff_codec_in_suspend) | ||
1155 | usleep_range(350000, 400000); | ||
1156 | |||
1157 | regcache_cache_only(rt5660->regmap, false); | ||
1158 | regcache_sync(rt5660->regmap); | ||
1159 | |||
1160 | return 0; | ||
1161 | } | ||
1162 | #else | ||
1163 | #define rt5660_suspend NULL | ||
1164 | #define rt5660_resume NULL | ||
1165 | #endif | ||
1166 | |||
1167 | #define RT5660_STEREO_RATES SNDRV_PCM_RATE_8000_192000 | ||
1168 | #define RT5660_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE | \ | ||
1169 | SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S8) | ||
1170 | |||
1171 | static const struct snd_soc_dai_ops rt5660_aif_dai_ops = { | ||
1172 | .hw_params = rt5660_hw_params, | ||
1173 | .set_fmt = rt5660_set_dai_fmt, | ||
1174 | .set_sysclk = rt5660_set_dai_sysclk, | ||
1175 | .set_pll = rt5660_set_dai_pll, | ||
1176 | }; | ||
1177 | |||
1178 | static struct snd_soc_dai_driver rt5660_dai[] = { | ||
1179 | { | ||
1180 | .name = "rt5660-aif1", | ||
1181 | .id = RT5660_AIF1, | ||
1182 | .playback = { | ||
1183 | .stream_name = "AIF1 Playback", | ||
1184 | .channels_min = 1, | ||
1185 | .channels_max = 2, | ||
1186 | .rates = RT5660_STEREO_RATES, | ||
1187 | .formats = RT5660_FORMATS, | ||
1188 | }, | ||
1189 | .capture = { | ||
1190 | .stream_name = "AIF1 Capture", | ||
1191 | .channels_min = 1, | ||
1192 | .channels_max = 2, | ||
1193 | .rates = RT5660_STEREO_RATES, | ||
1194 | .formats = RT5660_FORMATS, | ||
1195 | }, | ||
1196 | .ops = &rt5660_aif_dai_ops, | ||
1197 | }, | ||
1198 | }; | ||
1199 | |||
1200 | static struct snd_soc_codec_driver soc_codec_dev_rt5660 = { | ||
1201 | .probe = rt5660_probe, | ||
1202 | .remove = rt5660_remove, | ||
1203 | .suspend = rt5660_suspend, | ||
1204 | .resume = rt5660_resume, | ||
1205 | .set_bias_level = rt5660_set_bias_level, | ||
1206 | .idle_bias_off = true, | ||
1207 | .component_driver = { | ||
1208 | .controls = rt5660_snd_controls, | ||
1209 | .num_controls = ARRAY_SIZE(rt5660_snd_controls), | ||
1210 | .dapm_widgets = rt5660_dapm_widgets, | ||
1211 | .num_dapm_widgets = ARRAY_SIZE(rt5660_dapm_widgets), | ||
1212 | .dapm_routes = rt5660_dapm_routes, | ||
1213 | .num_dapm_routes = ARRAY_SIZE(rt5660_dapm_routes), | ||
1214 | }, | ||
1215 | }; | ||
1216 | |||
1217 | static const struct regmap_config rt5660_regmap = { | ||
1218 | .reg_bits = 8, | ||
1219 | .val_bits = 16, | ||
1220 | .use_single_rw = true, | ||
1221 | |||
1222 | .max_register = RT5660_VENDOR_ID2 + 1 + (ARRAY_SIZE(rt5660_ranges) * | ||
1223 | RT5660_PR_SPACING), | ||
1224 | .volatile_reg = rt5660_volatile_register, | ||
1225 | .readable_reg = rt5660_readable_register, | ||
1226 | |||
1227 | .cache_type = REGCACHE_RBTREE, | ||
1228 | .reg_defaults = rt5660_reg, | ||
1229 | .num_reg_defaults = ARRAY_SIZE(rt5660_reg), | ||
1230 | .ranges = rt5660_ranges, | ||
1231 | .num_ranges = ARRAY_SIZE(rt5660_ranges), | ||
1232 | }; | ||
1233 | |||
1234 | static const struct i2c_device_id rt5660_i2c_id[] = { | ||
1235 | { "rt5660", 0 }, | ||
1236 | { } | ||
1237 | }; | ||
1238 | MODULE_DEVICE_TABLE(i2c, rt5660_i2c_id); | ||
1239 | |||
1240 | static const struct of_device_id rt5660_of_match[] = { | ||
1241 | { .compatible = "realtek,rt5660", }, | ||
1242 | {}, | ||
1243 | }; | ||
1244 | MODULE_DEVICE_TABLE(of, rt5660_of_match); | ||
1245 | |||
1246 | static const struct acpi_device_id rt5660_acpi_match[] = { | ||
1247 | { "10EC5660", 0 }, | ||
1248 | { }, | ||
1249 | }; | ||
1250 | MODULE_DEVICE_TABLE(acpi, rt5660_acpi_match); | ||
1251 | |||
1252 | static int rt5660_parse_dt(struct rt5660_priv *rt5660, struct device *dev) | ||
1253 | { | ||
1254 | rt5660->pdata.in1_diff = device_property_read_bool(dev, | ||
1255 | "realtek,in1-differential"); | ||
1256 | rt5660->pdata.in3_diff = device_property_read_bool(dev, | ||
1257 | "realtek,in3-differential"); | ||
1258 | rt5660->pdata.poweroff_codec_in_suspend = device_property_read_bool(dev, | ||
1259 | "realtek,poweroff-in-suspend"); | ||
1260 | device_property_read_u32(dev, "realtek,dmic1-data-pin", | ||
1261 | &rt5660->pdata.dmic1_data_pin); | ||
1262 | |||
1263 | return 0; | ||
1264 | } | ||
1265 | |||
1266 | static int rt5660_i2c_probe(struct i2c_client *i2c, | ||
1267 | const struct i2c_device_id *id) | ||
1268 | { | ||
1269 | struct rt5660_platform_data *pdata = dev_get_platdata(&i2c->dev); | ||
1270 | struct rt5660_priv *rt5660; | ||
1271 | int ret; | ||
1272 | unsigned int val; | ||
1273 | |||
1274 | rt5660 = devm_kzalloc(&i2c->dev, sizeof(struct rt5660_priv), | ||
1275 | GFP_KERNEL); | ||
1276 | |||
1277 | if (rt5660 == NULL) | ||
1278 | return -ENOMEM; | ||
1279 | |||
1280 | /* Check if MCLK provided */ | ||
1281 | rt5660->mclk = devm_clk_get(&i2c->dev, "mclk"); | ||
1282 | if (PTR_ERR(rt5660->mclk) == -EPROBE_DEFER) | ||
1283 | return -EPROBE_DEFER; | ||
1284 | |||
1285 | i2c_set_clientdata(i2c, rt5660); | ||
1286 | |||
1287 | if (pdata) | ||
1288 | rt5660->pdata = *pdata; | ||
1289 | else if (i2c->dev.of_node) | ||
1290 | rt5660_parse_dt(rt5660, &i2c->dev); | ||
1291 | |||
1292 | rt5660->regmap = devm_regmap_init_i2c(i2c, &rt5660_regmap); | ||
1293 | if (IS_ERR(rt5660->regmap)) { | ||
1294 | ret = PTR_ERR(rt5660->regmap); | ||
1295 | dev_err(&i2c->dev, "Failed to allocate register map: %d\n", | ||
1296 | ret); | ||
1297 | return ret; | ||
1298 | } | ||
1299 | |||
1300 | regmap_read(rt5660->regmap, RT5660_VENDOR_ID2, &val); | ||
1301 | if (val != RT5660_DEVICE_ID) { | ||
1302 | dev_err(&i2c->dev, | ||
1303 | "Device with ID register %#x is not rt5660\n", val); | ||
1304 | return -ENODEV; | ||
1305 | } | ||
1306 | |||
1307 | regmap_write(rt5660->regmap, RT5660_RESET, 0); | ||
1308 | |||
1309 | ret = regmap_register_patch(rt5660->regmap, rt5660_patch, | ||
1310 | ARRAY_SIZE(rt5660_patch)); | ||
1311 | if (ret != 0) | ||
1312 | dev_warn(&i2c->dev, "Failed to apply regmap patch: %d\n", ret); | ||
1313 | |||
1314 | if (rt5660->pdata.dmic1_data_pin) { | ||
1315 | regmap_update_bits(rt5660->regmap, RT5660_GPIO_CTRL1, | ||
1316 | RT5660_GP1_PIN_MASK, RT5660_GP1_PIN_DMIC1_SCL); | ||
1317 | |||
1318 | if (rt5660->pdata.dmic1_data_pin == RT5660_DMIC1_DATA_GPIO2) | ||
1319 | regmap_update_bits(rt5660->regmap, RT5660_DMIC_CTRL1, | ||
1320 | RT5660_SEL_DMIC_DATA_MASK, | ||
1321 | RT5660_SEL_DMIC_DATA_GPIO2); | ||
1322 | else if (rt5660->pdata.dmic1_data_pin == RT5660_DMIC1_DATA_IN1P) | ||
1323 | regmap_update_bits(rt5660->regmap, RT5660_DMIC_CTRL1, | ||
1324 | RT5660_SEL_DMIC_DATA_MASK, | ||
1325 | RT5660_SEL_DMIC_DATA_IN1P); | ||
1326 | } | ||
1327 | |||
1328 | return snd_soc_register_codec(&i2c->dev, &soc_codec_dev_rt5660, | ||
1329 | rt5660_dai, ARRAY_SIZE(rt5660_dai)); | ||
1330 | } | ||
1331 | |||
1332 | static int rt5660_i2c_remove(struct i2c_client *i2c) | ||
1333 | { | ||
1334 | snd_soc_unregister_codec(&i2c->dev); | ||
1335 | |||
1336 | return 0; | ||
1337 | } | ||
1338 | |||
1339 | static struct i2c_driver rt5660_i2c_driver = { | ||
1340 | .driver = { | ||
1341 | .name = "rt5660", | ||
1342 | .acpi_match_table = ACPI_PTR(rt5660_acpi_match), | ||
1343 | .of_match_table = of_match_ptr(rt5660_of_match), | ||
1344 | }, | ||
1345 | .probe = rt5660_i2c_probe, | ||
1346 | .remove = rt5660_i2c_remove, | ||
1347 | .id_table = rt5660_i2c_id, | ||
1348 | }; | ||
1349 | module_i2c_driver(rt5660_i2c_driver); | ||
1350 | |||
1351 | MODULE_DESCRIPTION("ASoC RT5660 driver"); | ||
1352 | MODULE_AUTHOR("Oder Chiou <oder_chiou@realtek.com>"); | ||
1353 | MODULE_LICENSE("GPL v2"); | ||
diff --git a/sound/soc/codecs/rt5660.h b/sound/soc/codecs/rt5660.h new file mode 100644 index 000000000000..6cdb9269ec9e --- /dev/null +++ b/sound/soc/codecs/rt5660.h | |||
@@ -0,0 +1,847 @@ | |||
1 | /* | ||
2 | * rt5660.h -- RT5660 ALSA SoC audio driver | ||
3 | * | ||
4 | * Copyright 2016 Realtek Semiconductor Corp. | ||
5 | * Author: Oder Chiou <oder_chiou@realtek.com> | ||
6 | * | ||
7 | * This program is free software; you can redistribute it and/or modify | ||
8 | * it under the terms of the GNU General Public License version 2 as | ||
9 | * published by the Free Software Foundation. | ||
10 | */ | ||
11 | |||
12 | #ifndef _RT5660_H | ||
13 | #define _RT5660_H | ||
14 | |||
15 | #include <linux/clk.h> | ||
16 | #include <sound/rt5660.h> | ||
17 | |||
18 | /* Info */ | ||
19 | #define RT5660_RESET 0x00 | ||
20 | #define RT5660_VENDOR_ID 0xfd | ||
21 | #define RT5660_VENDOR_ID1 0xfe | ||
22 | #define RT5660_VENDOR_ID2 0xff | ||
23 | /* I/O - Output */ | ||
24 | #define RT5660_SPK_VOL 0x01 | ||
25 | #define RT5660_LOUT_VOL 0x02 | ||
26 | /* I/O - Input */ | ||
27 | #define RT5660_IN1_IN2 0x0d | ||
28 | #define RT5660_IN3_IN4 0x0e | ||
29 | /* I/O - ADC/DAC/DMIC */ | ||
30 | #define RT5660_DAC1_DIG_VOL 0x19 | ||
31 | #define RT5660_STO1_ADC_DIG_VOL 0x1c | ||
32 | #define RT5660_ADC_BST_VOL1 0x1e | ||
33 | /* Mixer - D-D */ | ||
34 | #define RT5660_STO1_ADC_MIXER 0x27 | ||
35 | #define RT5660_AD_DA_MIXER 0x29 | ||
36 | #define RT5660_STO_DAC_MIXER 0x2a | ||
37 | #define RT5660_DIG_INF1_DATA 0x2f | ||
38 | /* Mixer - ADC */ | ||
39 | #define RT5660_REC_L1_MIXER 0x3b | ||
40 | #define RT5660_REC_L2_MIXER 0x3c | ||
41 | #define RT5660_REC_R1_MIXER 0x3d | ||
42 | #define RT5660_REC_R2_MIXER 0x3e | ||
43 | /* Mixer - DAC */ | ||
44 | #define RT5660_LOUT_MIXER 0x45 | ||
45 | #define RT5660_SPK_MIXER 0x46 | ||
46 | #define RT5660_SPO_MIXER 0x48 | ||
47 | #define RT5660_SPO_CLSD_RATIO 0x4a | ||
48 | #define RT5660_OUT_L_GAIN1 0x4d | ||
49 | #define RT5660_OUT_L_GAIN2 0x4e | ||
50 | #define RT5660_OUT_L1_MIXER 0x4f | ||
51 | #define RT5660_OUT_R_GAIN1 0x50 | ||
52 | #define RT5660_OUT_R_GAIN2 0x51 | ||
53 | #define RT5660_OUT_R1_MIXER 0x52 | ||
54 | /* Power */ | ||
55 | #define RT5660_PWR_DIG1 0x61 | ||
56 | #define RT5660_PWR_DIG2 0x62 | ||
57 | #define RT5660_PWR_ANLG1 0x63 | ||
58 | #define RT5660_PWR_ANLG2 0x64 | ||
59 | #define RT5660_PWR_MIXER 0x65 | ||
60 | #define RT5660_PWR_VOL 0x66 | ||
61 | /* Private Register Control */ | ||
62 | #define RT5660_PRIV_INDEX 0x6a | ||
63 | #define RT5660_PRIV_DATA 0x6c | ||
64 | /* Format - ADC/DAC */ | ||
65 | #define RT5660_I2S1_SDP 0x70 | ||
66 | #define RT5660_ADDA_CLK1 0x73 | ||
67 | #define RT5660_ADDA_CLK2 0x74 | ||
68 | #define RT5660_DMIC_CTRL1 0x75 | ||
69 | /* Function - Analog */ | ||
70 | #define RT5660_GLB_CLK 0x80 | ||
71 | #define RT5660_PLL_CTRL1 0x81 | ||
72 | #define RT5660_PLL_CTRL2 0x82 | ||
73 | #define RT5660_CLSD_AMP_OC_CTRL 0x8c | ||
74 | #define RT5660_CLSD_AMP_CTRL 0x8d | ||
75 | #define RT5660_LOUT_AMP_CTRL 0x8e | ||
76 | #define RT5660_SPK_AMP_SPKVDD 0x92 | ||
77 | #define RT5660_MICBIAS 0x93 | ||
78 | #define RT5660_CLSD_OUT_CTRL1 0xa1 | ||
79 | #define RT5660_CLSD_OUT_CTRL2 0xa2 | ||
80 | #define RT5660_DIPOLE_MIC_CTRL1 0xa3 | ||
81 | #define RT5660_DIPOLE_MIC_CTRL2 0xa4 | ||
82 | #define RT5660_DIPOLE_MIC_CTRL3 0xa5 | ||
83 | #define RT5660_DIPOLE_MIC_CTRL4 0xa6 | ||
84 | #define RT5660_DIPOLE_MIC_CTRL5 0xa7 | ||
85 | #define RT5660_DIPOLE_MIC_CTRL6 0xa8 | ||
86 | #define RT5660_DIPOLE_MIC_CTRL7 0xa9 | ||
87 | #define RT5660_DIPOLE_MIC_CTRL8 0xaa | ||
88 | #define RT5660_DIPOLE_MIC_CTRL9 0xab | ||
89 | #define RT5660_DIPOLE_MIC_CTRL10 0xac | ||
90 | #define RT5660_DIPOLE_MIC_CTRL11 0xad | ||
91 | #define RT5660_DIPOLE_MIC_CTRL12 0xae | ||
92 | /* Function - Digital */ | ||
93 | #define RT5660_EQ_CTRL1 0xb0 | ||
94 | #define RT5660_EQ_CTRL2 0xb1 | ||
95 | #define RT5660_DRC_AGC_CTRL1 0xb3 | ||
96 | #define RT5660_DRC_AGC_CTRL2 0xb4 | ||
97 | #define RT5660_DRC_AGC_CTRL3 0xb5 | ||
98 | #define RT5660_DRC_AGC_CTRL4 0xb6 | ||
99 | #define RT5660_DRC_AGC_CTRL5 0xb7 | ||
100 | #define RT5660_JD_CTRL 0xbb | ||
101 | #define RT5660_IRQ_CTRL1 0xbd | ||
102 | #define RT5660_IRQ_CTRL2 0xbe | ||
103 | #define RT5660_INT_IRQ_ST 0xbf | ||
104 | #define RT5660_GPIO_CTRL1 0xc0 | ||
105 | #define RT5660_GPIO_CTRL2 0xc2 | ||
106 | #define RT5660_WIND_FILTER_CTRL1 0xd3 | ||
107 | #define RT5660_SV_ZCD1 0xd9 | ||
108 | #define RT5660_SV_ZCD2 0xda | ||
109 | #define RT5660_DRC1_LM_CTRL1 0xe0 | ||
110 | #define RT5660_DRC1_LM_CTRL2 0xe1 | ||
111 | #define RT5660_DRC2_LM_CTRL1 0xe2 | ||
112 | #define RT5660_DRC2_LM_CTRL2 0xe3 | ||
113 | #define RT5660_MULTI_DRC_CTRL 0xe4 | ||
114 | #define RT5660_DRC2_CTRL1 0xe5 | ||
115 | #define RT5660_DRC2_CTRL2 0xe6 | ||
116 | #define RT5660_DRC2_CTRL3 0xe7 | ||
117 | #define RT5660_DRC2_CTRL4 0xe8 | ||
118 | #define RT5660_DRC2_CTRL5 0xe9 | ||
119 | #define RT5660_ALC_PGA_CTRL1 0xea | ||
120 | #define RT5660_ALC_PGA_CTRL2 0xeb | ||
121 | #define RT5660_ALC_PGA_CTRL3 0xec | ||
122 | #define RT5660_ALC_PGA_CTRL4 0xed | ||
123 | #define RT5660_ALC_PGA_CTRL5 0xee | ||
124 | #define RT5660_ALC_PGA_CTRL6 0xef | ||
125 | #define RT5660_ALC_PGA_CTRL7 0xf0 | ||
126 | |||
127 | /* General Control */ | ||
128 | #define RT5660_GEN_CTRL1 0xfa | ||
129 | #define RT5660_GEN_CTRL2 0xfb | ||
130 | #define RT5660_GEN_CTRL3 0xfc | ||
131 | |||
132 | /* Index of Codec Private Register definition */ | ||
133 | #define RT5660_CHOP_DAC_ADC 0x3d | ||
134 | |||
135 | /* Global Definition */ | ||
136 | #define RT5660_L_MUTE (0x1 << 15) | ||
137 | #define RT5660_L_MUTE_SFT 15 | ||
138 | #define RT5660_VOL_L_MUTE (0x1 << 14) | ||
139 | #define RT5660_VOL_L_SFT 14 | ||
140 | #define RT5660_R_MUTE (0x1 << 7) | ||
141 | #define RT5660_R_MUTE_SFT 7 | ||
142 | #define RT5660_VOL_R_MUTE (0x1 << 6) | ||
143 | #define RT5660_VOL_R_SFT 6 | ||
144 | #define RT5660_L_VOL_MASK (0x3f << 8) | ||
145 | #define RT5660_L_VOL_SFT 8 | ||
146 | #define RT5660_R_VOL_MASK (0x3f) | ||
147 | #define RT5660_R_VOL_SFT 0 | ||
148 | |||
149 | /* IN1 and IN2 Control (0x0d) */ | ||
150 | #define RT5660_IN_DF1 (0x1 << 15) | ||
151 | #define RT5660_IN_SFT1 15 | ||
152 | #define RT5660_BST_MASK1 (0x7f << 8) | ||
153 | #define RT5660_BST_SFT1 8 | ||
154 | #define RT5660_IN_DF2 (0x1 << 7) | ||
155 | #define RT5660_IN_SFT2 7 | ||
156 | #define RT5660_BST_MASK2 (0x7f << 0) | ||
157 | #define RT5660_BST_SFT2 0 | ||
158 | |||
159 | /* IN3 and IN4 Control (0x0e) */ | ||
160 | #define RT5660_IN_DF3 (0x1 << 15) | ||
161 | #define RT5660_IN_SFT3 15 | ||
162 | #define RT5660_BST_MASK3 (0x7f << 8) | ||
163 | #define RT5660_BST_SFT3 8 | ||
164 | #define RT5660_IN_DF4 (0x1 << 7) | ||
165 | #define RT5660_IN_SFT4 7 | ||
166 | #define RT5660_BST_MASK4 (0x7f << 0) | ||
167 | #define RT5660_BST_SFT4 0 | ||
168 | |||
169 | /* DAC1 Digital Volume (0x19) */ | ||
170 | #define RT5660_DAC_L1_VOL_MASK (0x7f << 9) | ||
171 | #define RT5660_DAC_L1_VOL_SFT 9 | ||
172 | #define RT5660_DAC_R1_VOL_MASK (0x7f << 1) | ||
173 | #define RT5660_DAC_R1_VOL_SFT 1 | ||
174 | |||
175 | /* ADC Digital Volume Control (0x1c) */ | ||
176 | #define RT5660_ADC_L_VOL_MASK (0x3f << 9) | ||
177 | #define RT5660_ADC_L_VOL_SFT 9 | ||
178 | #define RT5660_ADC_R_VOL_MASK (0x3f << 1) | ||
179 | #define RT5660_ADC_R_VOL_SFT 1 | ||
180 | |||
181 | /* ADC Boost Volume Control (0x1e) */ | ||
182 | #define RT5660_STO1_ADC_L_BST_MASK (0x3 << 14) | ||
183 | #define RT5660_STO1_ADC_L_BST_SFT 14 | ||
184 | #define RT5660_STO1_ADC_R_BST_MASK (0x3 << 12) | ||
185 | #define RT5660_STO1_ADC_R_BST_SFT 12 | ||
186 | |||
187 | /* Stereo ADC Mixer Control (0x27) */ | ||
188 | #define RT5660_M_ADC_L1 (0x1 << 14) | ||
189 | #define RT5660_M_ADC_L1_SFT 14 | ||
190 | #define RT5660_M_ADC_L2 (0x1 << 13) | ||
191 | #define RT5660_M_ADC_L2_SFT 13 | ||
192 | #define RT5660_M_ADC_R1 (0x1 << 6) | ||
193 | #define RT5660_M_ADC_R1_SFT 6 | ||
194 | #define RT5660_M_ADC_R2 (0x1 << 5) | ||
195 | #define RT5660_M_ADC_R2_SFT 5 | ||
196 | |||
197 | /* ADC Mixer to DAC Mixer Control (0x29) */ | ||
198 | #define RT5660_M_ADCMIX_L (0x1 << 15) | ||
199 | #define RT5660_M_ADCMIX_L_SFT 15 | ||
200 | #define RT5660_M_DAC1_L (0x1 << 14) | ||
201 | #define RT5660_M_DAC1_L_SFT 14 | ||
202 | #define RT5660_M_ADCMIX_R (0x1 << 7) | ||
203 | #define RT5660_M_ADCMIX_R_SFT 7 | ||
204 | #define RT5660_M_DAC1_R (0x1 << 6) | ||
205 | #define RT5660_M_DAC1_R_SFT 6 | ||
206 | |||
207 | /* Stereo DAC Mixer Control (0x2a) */ | ||
208 | #define RT5660_M_DAC_L1 (0x1 << 14) | ||
209 | #define RT5660_M_DAC_L1_SFT 14 | ||
210 | #define RT5660_DAC_L1_STO_L_VOL_MASK (0x1 << 13) | ||
211 | #define RT5660_DAC_L1_STO_L_VOL_SFT 13 | ||
212 | #define RT5660_M_DAC_R1_STO_L (0x1 << 9) | ||
213 | #define RT5660_M_DAC_R1_STO_L_SFT 9 | ||
214 | #define RT5660_DAC_R1_STO_L_VOL_MASK (0x1 << 8) | ||
215 | #define RT5660_DAC_R1_STO_L_VOL_SFT 8 | ||
216 | #define RT5660_M_DAC_R1 (0x1 << 6) | ||
217 | #define RT5660_M_DAC_R1_SFT 6 | ||
218 | #define RT5660_DAC_R1_STO_R_VOL_MASK (0x1 << 5) | ||
219 | #define RT5660_DAC_R1_STO_R_VOL_SFT 5 | ||
220 | #define RT5660_M_DAC_L1_STO_R (0x1 << 1) | ||
221 | #define RT5660_M_DAC_L1_STO_R_SFT 1 | ||
222 | #define RT5660_DAC_L1_STO_R_VOL_MASK (0x1) | ||
223 | #define RT5660_DAC_L1_STO_R_VOL_SFT 0 | ||
224 | |||
225 | /* Digital Interface Data Control (0x2f) */ | ||
226 | #define RT5660_IF1_DAC_IN_SEL (0x3 << 14) | ||
227 | #define RT5660_IF1_DAC_IN_SFT 14 | ||
228 | #define RT5660_IF1_ADC_IN_SEL (0x3 << 12) | ||
229 | #define RT5660_IF1_ADC_IN_SFT 12 | ||
230 | |||
231 | /* REC Left Mixer Control 1 (0x3b) */ | ||
232 | #define RT5660_G_BST3_RM_L_MASK (0x7 << 4) | ||
233 | #define RT5660_G_BST3_RM_L_SFT 4 | ||
234 | #define RT5660_G_BST2_RM_L_MASK (0x7 << 1) | ||
235 | #define RT5660_G_BST2_RM_L_SFT 1 | ||
236 | |||
237 | /* REC Left Mixer Control 2 (0x3c) */ | ||
238 | #define RT5660_G_BST1_RM_L_MASK (0x7 << 13) | ||
239 | #define RT5660_G_BST1_RM_L_SFT 13 | ||
240 | #define RT5660_G_OM_L_RM_L_MASK (0x7 << 10) | ||
241 | #define RT5660_G_OM_L_RM_L_SFT 10 | ||
242 | #define RT5660_M_BST3_RM_L (0x1 << 3) | ||
243 | #define RT5660_M_BST3_RM_L_SFT 3 | ||
244 | #define RT5660_M_BST2_RM_L (0x1 << 2) | ||
245 | #define RT5660_M_BST2_RM_L_SFT 2 | ||
246 | #define RT5660_M_BST1_RM_L (0x1 << 1) | ||
247 | #define RT5660_M_BST1_RM_L_SFT 1 | ||
248 | #define RT5660_M_OM_L_RM_L (0x1) | ||
249 | #define RT5660_M_OM_L_RM_L_SFT 0 | ||
250 | |||
251 | /* REC Right Mixer Control 1 (0x3d) */ | ||
252 | #define RT5660_G_BST3_RM_R_MASK (0x7 << 4) | ||
253 | #define RT5660_G_BST3_RM_R_SFT 4 | ||
254 | #define RT5660_G_BST2_RM_R_MASK (0x7 << 1) | ||
255 | #define RT5660_G_BST2_RM_R_SFT 1 | ||
256 | |||
257 | /* REC Right Mixer Control 2 (0x3e) */ | ||
258 | #define RT5660_G_BST1_RM_R_MASK (0x7 << 13) | ||
259 | #define RT5660_G_BST1_RM_R_SFT 13 | ||
260 | #define RT5660_G_OM_R_RM_R_MASK (0x7 << 10) | ||
261 | #define RT5660_G_OM_R_RM_R_SFT 10 | ||
262 | #define RT5660_M_BST3_RM_R (0x1 << 3) | ||
263 | #define RT5660_M_BST3_RM_R_SFT 3 | ||
264 | #define RT5660_M_BST2_RM_R (0x1 << 2) | ||
265 | #define RT5660_M_BST2_RM_R_SFT 2 | ||
266 | #define RT5660_M_BST1_RM_R (0x1 << 1) | ||
267 | #define RT5660_M_BST1_RM_R_SFT 1 | ||
268 | #define RT5660_M_OM_R_RM_R (0x1) | ||
269 | #define RT5660_M_OM_R_RM_R_SFT 0 | ||
270 | |||
271 | /* LOUTMIX Control (0x45) */ | ||
272 | #define RT5660_M_DAC1_LM (0x1 << 14) | ||
273 | #define RT5660_M_DAC1_LM_SFT 14 | ||
274 | #define RT5660_M_LOVOL_M (0x1 << 13) | ||
275 | #define RT5660_M_LOVOL_LM_SFT 13 | ||
276 | |||
277 | /* SPK Mixer Control (0x46) */ | ||
278 | #define RT5660_G_BST3_SM_MASK (0x3 << 14) | ||
279 | #define RT5660_G_BST3_SM_SFT 14 | ||
280 | #define RT5660_G_BST1_SM_MASK (0x3 << 12) | ||
281 | #define RT5660_G_BST1_SM_SFT 12 | ||
282 | #define RT5660_G_DACl_SM_MASK (0x3 << 10) | ||
283 | #define RT5660_G_DACl_SM_SFT 10 | ||
284 | #define RT5660_G_DACR_SM_MASK (0x3 << 8) | ||
285 | #define RT5660_G_DACR_SM_SFT 8 | ||
286 | #define RT5660_G_OM_L_SM_MASK (0x3 << 6) | ||
287 | #define RT5660_G_OM_L_SM_SFT 6 | ||
288 | #define RT5660_M_DACR_SM (0x1 << 5) | ||
289 | #define RT5660_M_DACR_SM_SFT 5 | ||
290 | #define RT5660_M_BST1_SM (0x1 << 4) | ||
291 | #define RT5660_M_BST1_SM_SFT 4 | ||
292 | #define RT5660_M_BST3_SM (0x1 << 3) | ||
293 | #define RT5660_M_BST3_SM_SFT 3 | ||
294 | #define RT5660_M_DACL_SM (0x1 << 2) | ||
295 | #define RT5660_M_DACL_SM_SFT 2 | ||
296 | #define RT5660_M_OM_L_SM (0x1 << 1) | ||
297 | #define RT5660_M_OM_L_SM_SFT 1 | ||
298 | |||
299 | /* SPOMIX Control (0x48) */ | ||
300 | #define RT5660_M_DAC_R_SPM (0x1 << 14) | ||
301 | #define RT5660_M_DAC_R_SPM_SFT 14 | ||
302 | #define RT5660_M_DAC_L_SPM (0x1 << 13) | ||
303 | #define RT5660_M_DAC_L_SPM_SFT 13 | ||
304 | #define RT5660_M_SV_SPM (0x1 << 12) | ||
305 | #define RT5660_M_SV_SPM_SFT 12 | ||
306 | #define RT5660_M_BST1_SPM (0x1 << 11) | ||
307 | #define RT5660_M_BST1_SPM_SFT 11 | ||
308 | |||
309 | /* Output Left Mixer Control 1 (0x4d) */ | ||
310 | #define RT5660_G_BST3_OM_L_MASK (0x7 << 13) | ||
311 | #define RT5660_G_BST3_OM_L_SFT 13 | ||
312 | #define RT5660_G_BST2_OM_L_MASK (0x7 << 10) | ||
313 | #define RT5660_G_BST2_OM_L_SFT 10 | ||
314 | #define RT5660_G_BST1_OM_L_MASK (0x7 << 7) | ||
315 | #define RT5660_G_BST1_OM_L_SFT 7 | ||
316 | #define RT5660_G_RM_L_OM_L_MASK (0x7 << 1) | ||
317 | #define RT5660_G_RM_L_OM_L_SFT 1 | ||
318 | |||
319 | /* Output Left Mixer Control 2 (0x4e) */ | ||
320 | #define RT5660_G_DAC_R1_OM_L_MASK (0x7 << 10) | ||
321 | #define RT5660_G_DAC_R1_OM_L_SFT 10 | ||
322 | #define RT5660_G_DAC_L1_OM_L_MASK (0x7 << 7) | ||
323 | #define RT5660_G_DAC_L1_OM_L_SFT 7 | ||
324 | |||
325 | /* Output Left Mixer Control 3 (0x4f) */ | ||
326 | #define RT5660_M_BST3_OM_L (0x1 << 5) | ||
327 | #define RT5660_M_BST3_OM_L_SFT 5 | ||
328 | #define RT5660_M_BST2_OM_L (0x1 << 4) | ||
329 | #define RT5660_M_BST2_OM_L_SFT 4 | ||
330 | #define RT5660_M_BST1_OM_L (0x1 << 3) | ||
331 | #define RT5660_M_BST1_OM_L_SFT 3 | ||
332 | #define RT5660_M_RM_L_OM_L (0x1 << 2) | ||
333 | #define RT5660_M_RM_L_OM_L_SFT 2 | ||
334 | #define RT5660_M_DAC_R_OM_L (0x1 << 1) | ||
335 | #define RT5660_M_DAC_R_OM_L_SFT 1 | ||
336 | #define RT5660_M_DAC_L_OM_L (0x1) | ||
337 | #define RT5660_M_DAC_L_OM_L_SFT 0 | ||
338 | |||
339 | /* Output Right Mixer Control 1 (0x50) */ | ||
340 | #define RT5660_G_BST2_OM_R_MASK (0x7 << 10) | ||
341 | #define RT5660_G_BST2_OM_R_SFT 10 | ||
342 | #define RT5660_G_BST1_OM_R_MASK (0x7 << 7) | ||
343 | #define RT5660_G_BST1_OM_R_SFT 7 | ||
344 | #define RT5660_G_RM_R_OM_R_MASK (0x7 << 1) | ||
345 | #define RT5660_G_RM_R_OM_R_SFT 1 | ||
346 | |||
347 | /* Output Right Mixer Control 2 (0x51) */ | ||
348 | #define RT5660_G_DAC_L_OM_R_MASK (0x7 << 10) | ||
349 | #define RT5660_G_DAC_L_OM_R_SFT 10 | ||
350 | #define RT5660_G_DAC_R_OM_R_MASK (0x7 << 7) | ||
351 | #define RT5660_G_DAC_R_OM_R_SFT 7 | ||
352 | |||
353 | /* Output Right Mixer Control 3 (0x52) */ | ||
354 | #define RT5660_M_BST2_OM_R (0x1 << 4) | ||
355 | #define RT5660_M_BST2_OM_R_SFT 4 | ||
356 | #define RT5660_M_BST1_OM_R (0x1 << 3) | ||
357 | #define RT5660_M_BST1_OM_R_SFT 3 | ||
358 | #define RT5660_M_RM_R_OM_R (0x1 << 2) | ||
359 | #define RT5660_M_RM_R_OM_R_SFT 2 | ||
360 | #define RT5660_M_DAC_L_OM_R (0x1 << 1) | ||
361 | #define RT5660_M_DAC_L_OM_R_SFT 1 | ||
362 | #define RT5660_M_DAC_R_OM_R (0x1) | ||
363 | #define RT5660_M_DAC_R_OM_R_SFT 0 | ||
364 | |||
365 | /* Power Management for Digital 1 (0x61) */ | ||
366 | #define RT5660_PWR_I2S1 (0x1 << 15) | ||
367 | #define RT5660_PWR_I2S1_BIT 15 | ||
368 | #define RT5660_PWR_DAC_L1 (0x1 << 12) | ||
369 | #define RT5660_PWR_DAC_L1_BIT 12 | ||
370 | #define RT5660_PWR_DAC_R1 (0x1 << 11) | ||
371 | #define RT5660_PWR_DAC_R1_BIT 11 | ||
372 | #define RT5660_PWR_ADC_L (0x1 << 2) | ||
373 | #define RT5660_PWR_ADC_L_BIT 2 | ||
374 | #define RT5660_PWR_ADC_R (0x1 << 1) | ||
375 | #define RT5660_PWR_ADC_R_BIT 1 | ||
376 | #define RT5660_PWR_CLS_D (0x1) | ||
377 | #define RT5660_PWR_CLS_D_BIT 0 | ||
378 | |||
379 | /* Power Management for Digital 2 (0x62) */ | ||
380 | #define RT5660_PWR_ADC_S1F (0x1 << 15) | ||
381 | #define RT5660_PWR_ADC_S1F_BIT 15 | ||
382 | #define RT5660_PWR_DAC_S1F (0x1 << 11) | ||
383 | #define RT5660_PWR_DAC_S1F_BIT 11 | ||
384 | |||
385 | /* Power Management for Analog 1 (0x63) */ | ||
386 | #define RT5660_PWR_VREF1 (0x1 << 15) | ||
387 | #define RT5660_PWR_VREF1_BIT 15 | ||
388 | #define RT5660_PWR_FV1 (0x1 << 14) | ||
389 | #define RT5660_PWR_FV1_BIT 14 | ||
390 | #define RT5660_PWR_MB (0x1 << 13) | ||
391 | #define RT5660_PWR_MB_BIT 13 | ||
392 | #define RT5660_PWR_BG (0x1 << 11) | ||
393 | #define RT5660_PWR_BG_BIT 11 | ||
394 | #define RT5660_PWR_HP_L (0x1 << 7) | ||
395 | #define RT5660_PWR_HP_L_BIT 7 | ||
396 | #define RT5660_PWR_HP_R (0x1 << 6) | ||
397 | #define RT5660_PWR_HP_R_BIT 6 | ||
398 | #define RT5660_PWR_HA (0x1 << 5) | ||
399 | #define RT5660_PWR_HA_BIT 5 | ||
400 | #define RT5660_PWR_VREF2 (0x1 << 4) | ||
401 | #define RT5660_PWR_VREF2_BIT 4 | ||
402 | #define RT5660_PWR_FV2 (0x1 << 3) | ||
403 | #define RT5660_PWR_FV2_BIT 3 | ||
404 | #define RT5660_PWR_LDO2 (0x1 << 2) | ||
405 | #define RT5660_PWR_LDO2_BIT 2 | ||
406 | |||
407 | /* Power Management for Analog 2 (0x64) */ | ||
408 | #define RT5660_PWR_BST1 (0x1 << 15) | ||
409 | #define RT5660_PWR_BST1_BIT 15 | ||
410 | #define RT5660_PWR_BST2 (0x1 << 14) | ||
411 | #define RT5660_PWR_BST2_BIT 14 | ||
412 | #define RT5660_PWR_BST3 (0x1 << 13) | ||
413 | #define RT5660_PWR_BST3_BIT 13 | ||
414 | #define RT5660_PWR_MB1 (0x1 << 11) | ||
415 | #define RT5660_PWR_MB1_BIT 11 | ||
416 | #define RT5660_PWR_MB2 (0x1 << 10) | ||
417 | #define RT5660_PWR_MB2_BIT 10 | ||
418 | #define RT5660_PWR_PLL (0x1 << 9) | ||
419 | #define RT5660_PWR_PLL_BIT 9 | ||
420 | |||
421 | /* Power Management for Mixer (0x65) */ | ||
422 | #define RT5660_PWR_OM_L (0x1 << 15) | ||
423 | #define RT5660_PWR_OM_L_BIT 15 | ||
424 | #define RT5660_PWR_OM_R (0x1 << 14) | ||
425 | #define RT5660_PWR_OM_R_BIT 14 | ||
426 | #define RT5660_PWR_SM (0x1 << 13) | ||
427 | #define RT5660_PWR_SM_BIT 13 | ||
428 | #define RT5660_PWR_RM_L (0x1 << 11) | ||
429 | #define RT5660_PWR_RM_L_BIT 11 | ||
430 | #define RT5660_PWR_RM_R (0x1 << 10) | ||
431 | #define RT5660_PWR_RM_R_BIT 10 | ||
432 | |||
433 | /* Power Management for Volume (0x66) */ | ||
434 | #define RT5660_PWR_SV (0x1 << 15) | ||
435 | #define RT5660_PWR_SV_BIT 15 | ||
436 | #define RT5660_PWR_LV_L (0x1 << 11) | ||
437 | #define RT5660_PWR_LV_L_BIT 11 | ||
438 | #define RT5660_PWR_LV_R (0x1 << 10) | ||
439 | #define RT5660_PWR_LV_R_BIT 10 | ||
440 | |||
441 | /* I2S1 Audio Serial Data Port Control (0x70) */ | ||
442 | #define RT5660_I2S_MS_MASK (0x1 << 15) | ||
443 | #define RT5660_I2S_MS_SFT 15 | ||
444 | #define RT5660_I2S_MS_M (0x0 << 15) | ||
445 | #define RT5660_I2S_MS_S (0x1 << 15) | ||
446 | #define RT5660_I2S_O_CP_MASK (0x3 << 10) | ||
447 | #define RT5660_I2S_O_CP_SFT 10 | ||
448 | #define RT5660_I2S_O_CP_OFF (0x0 << 10) | ||
449 | #define RT5660_I2S_O_CP_U_LAW (0x1 << 10) | ||
450 | #define RT5660_I2S_O_CP_A_LAW (0x2 << 10) | ||
451 | #define RT5660_I2S_I_CP_MASK (0x3 << 8) | ||
452 | #define RT5660_I2S_I_CP_SFT 8 | ||
453 | #define RT5660_I2S_I_CP_OFF (0x0 << 8) | ||
454 | #define RT5660_I2S_I_CP_U_LAW (0x1 << 8) | ||
455 | #define RT5660_I2S_I_CP_A_LAW (0x2 << 8) | ||
456 | #define RT5660_I2S_BP_MASK (0x1 << 7) | ||
457 | #define RT5660_I2S_BP_SFT 7 | ||
458 | #define RT5660_I2S_BP_NOR (0x0 << 7) | ||
459 | #define RT5660_I2S_BP_INV (0x1 << 7) | ||
460 | #define RT5660_I2S_DL_MASK (0x3 << 2) | ||
461 | #define RT5660_I2S_DL_SFT 2 | ||
462 | #define RT5660_I2S_DL_16 (0x0 << 2) | ||
463 | #define RT5660_I2S_DL_20 (0x1 << 2) | ||
464 | #define RT5660_I2S_DL_24 (0x2 << 2) | ||
465 | #define RT5660_I2S_DL_8 (0x3 << 2) | ||
466 | #define RT5660_I2S_DF_MASK (0x3) | ||
467 | #define RT5660_I2S_DF_SFT 0 | ||
468 | #define RT5660_I2S_DF_I2S (0x0) | ||
469 | #define RT5660_I2S_DF_LEFT (0x1) | ||
470 | #define RT5660_I2S_DF_PCM_A (0x2) | ||
471 | #define RT5660_I2S_DF_PCM_B (0x3) | ||
472 | |||
473 | /* ADC/DAC Clock Control 1 (0x73) */ | ||
474 | #define RT5660_I2S_BCLK_MS1_MASK (0x1 << 15) | ||
475 | #define RT5660_I2S_BCLK_MS1_SFT 15 | ||
476 | #define RT5660_I2S_BCLK_MS1_32 (0x0 << 15) | ||
477 | #define RT5660_I2S_BCLK_MS1_64 (0x1 << 15) | ||
478 | #define RT5660_I2S_PD1_MASK (0x7 << 12) | ||
479 | #define RT5660_I2S_PD1_SFT 12 | ||
480 | #define RT5660_I2S_PD1_1 (0x0 << 12) | ||
481 | #define RT5660_I2S_PD1_2 (0x1 << 12) | ||
482 | #define RT5660_I2S_PD1_3 (0x2 << 12) | ||
483 | #define RT5660_I2S_PD1_4 (0x3 << 12) | ||
484 | #define RT5660_I2S_PD1_6 (0x4 << 12) | ||
485 | #define RT5660_I2S_PD1_8 (0x5 << 12) | ||
486 | #define RT5660_I2S_PD1_12 (0x6 << 12) | ||
487 | #define RT5660_I2S_PD1_16 (0x7 << 12) | ||
488 | #define RT5660_DAC_OSR_MASK (0x3 << 2) | ||
489 | #define RT5660_DAC_OSR_SFT 2 | ||
490 | #define RT5660_DAC_OSR_128 (0x0 << 2) | ||
491 | #define RT5660_DAC_OSR_64 (0x1 << 2) | ||
492 | #define RT5660_DAC_OSR_32 (0x2 << 2) | ||
493 | #define RT5660_DAC_OSR_16 (0x3 << 2) | ||
494 | #define RT5660_ADC_OSR_MASK (0x3) | ||
495 | #define RT5660_ADC_OSR_SFT 0 | ||
496 | #define RT5660_ADC_OSR_128 (0x0) | ||
497 | #define RT5660_ADC_OSR_64 (0x1) | ||
498 | #define RT5660_ADC_OSR_32 (0x2) | ||
499 | #define RT5660_ADC_OSR_16 (0x3) | ||
500 | |||
501 | /* ADC/DAC Clock Control 2 (0x74) */ | ||
502 | #define RT5660_RESET_ADF (0x1 << 13) | ||
503 | #define RT5660_RESET_ADF_SFT 13 | ||
504 | #define RT5660_RESET_DAF (0x1 << 12) | ||
505 | #define RT5660_RESET_DAF_SFT 12 | ||
506 | #define RT5660_DAHPF_EN (0x1 << 11) | ||
507 | #define RT5660_DAHPF_EN_SFT 11 | ||
508 | #define RT5660_ADHPF_EN (0x1 << 10) | ||
509 | #define RT5660_ADHPF_EN_SFT 10 | ||
510 | |||
511 | /* Digital Microphone Control (0x75) */ | ||
512 | #define RT5660_DMIC_1_EN_MASK (0x1 << 15) | ||
513 | #define RT5660_DMIC_1_EN_SFT 15 | ||
514 | #define RT5660_DMIC_1_DIS (0x0 << 15) | ||
515 | #define RT5660_DMIC_1_EN (0x1 << 15) | ||
516 | #define RT5660_DMIC_1L_LH_MASK (0x1 << 13) | ||
517 | #define RT5660_DMIC_1L_LH_SFT 13 | ||
518 | #define RT5660_DMIC_1L_LH_RISING (0x0 << 13) | ||
519 | #define RT5660_DMIC_1L_LH_FALLING (0x1 << 13) | ||
520 | #define RT5660_DMIC_1R_LH_MASK (0x1 << 12) | ||
521 | #define RT5660_DMIC_1R_LH_SFT 12 | ||
522 | #define RT5660_DMIC_1R_LH_RISING (0x0 << 12) | ||
523 | #define RT5660_DMIC_1R_LH_FALLING (0x1 << 12) | ||
524 | #define RT5660_SEL_DMIC_DATA_MASK (0x1 << 11) | ||
525 | #define RT5660_SEL_DMIC_DATA_SFT 11 | ||
526 | #define RT5660_SEL_DMIC_DATA_GPIO2 (0x0 << 11) | ||
527 | #define RT5660_SEL_DMIC_DATA_IN1P (0x1 << 11) | ||
528 | #define RT5660_DMIC_CLK_MASK (0x7 << 5) | ||
529 | #define RT5660_DMIC_CLK_SFT 5 | ||
530 | |||
531 | /* Global Clock Control (0x80) */ | ||
532 | #define RT5660_SCLK_SRC_MASK (0x3 << 14) | ||
533 | #define RT5660_SCLK_SRC_SFT 14 | ||
534 | #define RT5660_SCLK_SRC_MCLK (0x0 << 14) | ||
535 | #define RT5660_SCLK_SRC_PLL1 (0x1 << 14) | ||
536 | #define RT5660_SCLK_SRC_RCCLK (0x2 << 14) | ||
537 | #define RT5660_PLL1_SRC_MASK (0x3 << 12) | ||
538 | #define RT5660_PLL1_SRC_SFT 12 | ||
539 | #define RT5660_PLL1_SRC_MCLK (0x0 << 12) | ||
540 | #define RT5660_PLL1_SRC_BCLK1 (0x1 << 12) | ||
541 | #define RT5660_PLL1_SRC_RCCLK (0x2 << 12) | ||
542 | #define RT5660_PLL1_PD_MASK (0x1 << 3) | ||
543 | #define RT5660_PLL1_PD_SFT 3 | ||
544 | #define RT5660_PLL1_PD_1 (0x0 << 3) | ||
545 | #define RT5660_PLL1_PD_2 (0x1 << 3) | ||
546 | |||
547 | #define RT5660_PLL_INP_MAX 40000000 | ||
548 | #define RT5660_PLL_INP_MIN 256000 | ||
549 | /* PLL M/N/K Code Control 1 (0x81) */ | ||
550 | #define RT5660_PLL_N_MAX 0x1ff | ||
551 | #define RT5660_PLL_N_MASK (RT5660_PLL_N_MAX << 7) | ||
552 | #define RT5660_PLL_N_SFT 7 | ||
553 | #define RT5660_PLL_K_MAX 0x1f | ||
554 | #define RT5660_PLL_K_MASK (RT5660_PLL_K_MAX) | ||
555 | #define RT5660_PLL_K_SFT 0 | ||
556 | |||
557 | /* PLL M/N/K Code Control 2 (0x82) */ | ||
558 | #define RT5660_PLL_M_MAX 0xf | ||
559 | #define RT5660_PLL_M_MASK (RT5660_PLL_M_MAX << 12) | ||
560 | #define RT5660_PLL_M_SFT 12 | ||
561 | #define RT5660_PLL_M_BP (0x1 << 11) | ||
562 | #define RT5660_PLL_M_BP_SFT 11 | ||
563 | |||
564 | /* Class D Over Current Control (0x8c) */ | ||
565 | #define RT5660_CLSD_OC_MASK (0x1 << 9) | ||
566 | #define RT5660_CLSD_OC_SFT 9 | ||
567 | #define RT5660_CLSD_OC_PU (0x0 << 9) | ||
568 | #define RT5660_CLSD_OC_PD (0x1 << 9) | ||
569 | #define RT5660_AUTO_PD_MASK (0x1 << 8) | ||
570 | #define RT5660_AUTO_PD_SFT 8 | ||
571 | #define RT5660_AUTO_PD_DIS (0x0 << 8) | ||
572 | #define RT5660_AUTO_PD_EN (0x1 << 8) | ||
573 | #define RT5660_CLSD_OC_TH_MASK (0x3f) | ||
574 | #define RT5660_CLSD_OC_TH_SFT 0 | ||
575 | |||
576 | /* Class D Output Control (0x8d) */ | ||
577 | #define RT5660_CLSD_RATIO_MASK (0xf << 12) | ||
578 | #define RT5660_CLSD_RATIO_SFT 12 | ||
579 | |||
580 | /* Lout Amp Control 1 (0x8e) */ | ||
581 | #define RT5660_LOUT_CO_MASK (0x1 << 4) | ||
582 | #define RT5660_LOUT_CO_SFT 4 | ||
583 | #define RT5660_LOUT_CO_DIS (0x0 << 4) | ||
584 | #define RT5660_LOUT_CO_EN (0x1 << 4) | ||
585 | #define RT5660_LOUT_CB_MASK (0x1) | ||
586 | #define RT5660_LOUT_CB_SFT 0 | ||
587 | #define RT5660_LOUT_CB_PD (0x0) | ||
588 | #define RT5660_LOUT_CB_PU (0x1) | ||
589 | |||
590 | /* SPKVDD detection control (0x92) */ | ||
591 | #define RT5660_SPKVDD_DET_MASK (0x1 << 15) | ||
592 | #define RT5660_SPKVDD_DET_SFT 15 | ||
593 | #define RT5660_SPKVDD_DET_DIS (0x0 << 15) | ||
594 | #define RT5660_SPKVDD_DET_EN (0x1 << 15) | ||
595 | #define RT5660_SPK_AG_MASK (0x1 << 14) | ||
596 | #define RT5660_SPK_AG_SFT 14 | ||
597 | #define RT5660_SPK_AG_DIS (0x0 << 14) | ||
598 | #define RT5660_SPK_AG_EN (0x1 << 14) | ||
599 | |||
600 | /* Micbias Control (0x93) */ | ||
601 | #define RT5660_MIC1_BS_MASK (0x1 << 15) | ||
602 | #define RT5660_MIC1_BS_SFT 15 | ||
603 | #define RT5660_MIC1_BS_9AV (0x0 << 15) | ||
604 | #define RT5660_MIC1_BS_75AV (0x1 << 15) | ||
605 | #define RT5660_MIC2_BS_MASK (0x1 << 14) | ||
606 | #define RT5660_MIC2_BS_SFT 14 | ||
607 | #define RT5660_MIC2_BS_9AV (0x0 << 14) | ||
608 | #define RT5660_MIC2_BS_75AV (0x1 << 14) | ||
609 | #define RT5660_MIC1_OVCD_MASK (0x1 << 11) | ||
610 | #define RT5660_MIC1_OVCD_SFT 11 | ||
611 | #define RT5660_MIC1_OVCD_DIS (0x0 << 11) | ||
612 | #define RT5660_MIC1_OVCD_EN (0x1 << 11) | ||
613 | #define RT5660_MIC1_OVTH_MASK (0x3 << 9) | ||
614 | #define RT5660_MIC1_OVTH_SFT 9 | ||
615 | #define RT5660_MIC1_OVTH_600UA (0x0 << 9) | ||
616 | #define RT5660_MIC1_OVTH_1500UA (0x1 << 9) | ||
617 | #define RT5660_MIC1_OVTH_2000UA (0x2 << 9) | ||
618 | #define RT5660_MIC2_OVCD_MASK (0x1 << 8) | ||
619 | #define RT5660_MIC2_OVCD_SFT 8 | ||
620 | #define RT5660_MIC2_OVCD_DIS (0x0 << 8) | ||
621 | #define RT5660_MIC2_OVCD_EN (0x1 << 8) | ||
622 | #define RT5660_MIC2_OVTH_MASK (0x3 << 6) | ||
623 | #define RT5660_MIC2_OVTH_SFT 6 | ||
624 | #define RT5660_MIC2_OVTH_600UA (0x0 << 6) | ||
625 | #define RT5660_MIC2_OVTH_1500UA (0x1 << 6) | ||
626 | #define RT5660_MIC2_OVTH_2000UA (0x2 << 6) | ||
627 | #define RT5660_PWR_CLK25M_MASK (0x1 << 4) | ||
628 | #define RT5660_PWR_CLK25M_SFT 4 | ||
629 | #define RT5660_PWR_CLK25M_PD (0x0 << 4) | ||
630 | #define RT5660_PWR_CLK25M_PU (0x1 << 4) | ||
631 | |||
632 | /* EQ Control 1 (0xb0) */ | ||
633 | #define RT5660_EQ_SRC_MASK (0x1 << 15) | ||
634 | #define RT5660_EQ_SRC_SFT 15 | ||
635 | #define RT5660_EQ_SRC_DAC (0x0 << 15) | ||
636 | #define RT5660_EQ_SRC_ADC (0x1 << 15) | ||
637 | #define RT5660_EQ_UPD (0x1 << 14) | ||
638 | #define RT5660_EQ_UPD_BIT 14 | ||
639 | |||
640 | /* Jack Detect Control (0xbb) */ | ||
641 | #define RT5660_JD_MASK (0x3 << 14) | ||
642 | #define RT5660_JD_SFT 14 | ||
643 | #define RT5660_JD_DIS (0x0 << 14) | ||
644 | #define RT5660_JD_GPIO1 (0x1 << 14) | ||
645 | #define RT5660_JD_GPIO2 (0x2 << 14) | ||
646 | #define RT5660_JD_LOUT_MASK (0x1 << 11) | ||
647 | #define RT5660_JD_LOUT_SFT 11 | ||
648 | #define RT5660_JD_LOUT_DIS (0x0 << 11) | ||
649 | #define RT5660_JD_LOUT_EN (0x1 << 11) | ||
650 | #define RT5660_JD_LOUT_TRG_MASK (0x1 << 10) | ||
651 | #define RT5660_JD_LOUT_TRG_SFT 10 | ||
652 | #define RT5660_JD_LOUT_TRG_LO (0x0 << 10) | ||
653 | #define RT5660_JD_LOUT_TRG_HI (0x1 << 10) | ||
654 | #define RT5660_JD_SPO_MASK (0x1 << 9) | ||
655 | #define RT5660_JD_SPO_SFT 9 | ||
656 | #define RT5660_JD_SPO_DIS (0x0 << 9) | ||
657 | #define RT5660_JD_SPO_EN (0x1 << 9) | ||
658 | #define RT5660_JD_SPO_TRG_MASK (0x1 << 8) | ||
659 | #define RT5660_JD_SPO_TRG_SFT 8 | ||
660 | #define RT5660_JD_SPO_TRG_LO (0x0 << 8) | ||
661 | #define RT5660_JD_SPO_TRG_HI (0x1 << 8) | ||
662 | |||
663 | /* IRQ Control 1 (0xbd) */ | ||
664 | #define RT5660_IRQ_JD_MASK (0x1 << 15) | ||
665 | #define RT5660_IRQ_JD_SFT 15 | ||
666 | #define RT5660_IRQ_JD_BP (0x0 << 15) | ||
667 | #define RT5660_IRQ_JD_NOR (0x1 << 15) | ||
668 | #define RT5660_IRQ_OT_MASK (0x1 << 14) | ||
669 | #define RT5660_IRQ_OT_SFT 14 | ||
670 | #define RT5660_IRQ_OT_BP (0x0 << 14) | ||
671 | #define RT5660_IRQ_OT_NOR (0x1 << 14) | ||
672 | #define RT5660_JD_STKY_MASK (0x1 << 13) | ||
673 | #define RT5660_JD_STKY_SFT 13 | ||
674 | #define RT5660_JD_STKY_DIS (0x0 << 13) | ||
675 | #define RT5660_JD_STKY_EN (0x1 << 13) | ||
676 | #define RT5660_OT_STKY_MASK (0x1 << 12) | ||
677 | #define RT5660_OT_STKY_SFT 12 | ||
678 | #define RT5660_OT_STKY_DIS (0x0 << 12) | ||
679 | #define RT5660_OT_STKY_EN (0x1 << 12) | ||
680 | #define RT5660_JD_P_MASK (0x1 << 11) | ||
681 | #define RT5660_JD_P_SFT 11 | ||
682 | #define RT5660_JD_P_NOR (0x0 << 11) | ||
683 | #define RT5660_JD_P_INV (0x1 << 11) | ||
684 | #define RT5660_OT_P_MASK (0x1 << 10) | ||
685 | #define RT5660_OT_P_SFT 10 | ||
686 | #define RT5660_OT_P_NOR (0x0 << 10) | ||
687 | #define RT5660_OT_P_INV (0x1 << 10) | ||
688 | |||
689 | /* IRQ Control 2 (0xbe) */ | ||
690 | #define RT5660_IRQ_MB1_OC_MASK (0x1 << 15) | ||
691 | #define RT5660_IRQ_MB1_OC_SFT 15 | ||
692 | #define RT5660_IRQ_MB1_OC_BP (0x0 << 15) | ||
693 | #define RT5660_IRQ_MB1_OC_NOR (0x1 << 15) | ||
694 | #define RT5660_IRQ_MB2_OC_MASK (0x1 << 14) | ||
695 | #define RT5660_IRQ_MB2_OC_SFT 14 | ||
696 | #define RT5660_IRQ_MB2_OC_BP (0x0 << 14) | ||
697 | #define RT5660_IRQ_MB2_OC_NOR (0x1 << 14) | ||
698 | #define RT5660_MB1_OC_STKY_MASK (0x1 << 11) | ||
699 | #define RT5660_MB1_OC_STKY_SFT 11 | ||
700 | #define RT5660_MB1_OC_STKY_DIS (0x0 << 11) | ||
701 | #define RT5660_MB1_OC_STKY_EN (0x1 << 11) | ||
702 | #define RT5660_MB2_OC_STKY_MASK (0x1 << 10) | ||
703 | #define RT5660_MB2_OC_STKY_SFT 10 | ||
704 | #define RT5660_MB2_OC_STKY_DIS (0x0 << 10) | ||
705 | #define RT5660_MB2_OC_STKY_EN (0x1 << 10) | ||
706 | #define RT5660_MB1_OC_P_MASK (0x1 << 7) | ||
707 | #define RT5660_MB1_OC_P_SFT 7 | ||
708 | #define RT5660_MB1_OC_P_NOR (0x0 << 7) | ||
709 | #define RT5660_MB1_OC_P_INV (0x1 << 7) | ||
710 | #define RT5660_MB2_OC_P_MASK (0x1 << 6) | ||
711 | #define RT5660_MB2_OC_P_SFT 6 | ||
712 | #define RT5660_MB2_OC_P_NOR (0x0 << 6) | ||
713 | #define RT5660_MB2_OC_P_INV (0x1 << 6) | ||
714 | #define RT5660_MB1_OC_CLR (0x1 << 3) | ||
715 | #define RT5660_MB1_OC_CLR_SFT 3 | ||
716 | #define RT5660_MB2_OC_CLR (0x1 << 2) | ||
717 | #define RT5660_MB2_OC_CLR_SFT 2 | ||
718 | |||
719 | /* GPIO Control 1 (0xc0) */ | ||
720 | #define RT5660_GP2_PIN_MASK (0x1 << 14) | ||
721 | #define RT5660_GP2_PIN_SFT 14 | ||
722 | #define RT5660_GP2_PIN_GPIO2 (0x0 << 14) | ||
723 | #define RT5660_GP2_PIN_DMIC1_SDA (0x1 << 14) | ||
724 | #define RT5660_GP1_PIN_MASK (0x3 << 12) | ||
725 | #define RT5660_GP1_PIN_SFT 12 | ||
726 | #define RT5660_GP1_PIN_GPIO1 (0x0 << 12) | ||
727 | #define RT5660_GP1_PIN_DMIC1_SCL (0x1 << 12) | ||
728 | #define RT5660_GP1_PIN_IRQ (0x2 << 12) | ||
729 | #define RT5660_GPIO_M_MASK (0x1 << 9) | ||
730 | #define RT5660_GPIO_M_SFT 9 | ||
731 | #define RT5660_GPIO_M_FLT (0x0 << 9) | ||
732 | #define RT5660_GPIO_M_PH (0x1 << 9) | ||
733 | |||
734 | /* GPIO Control 3 (0xc2) */ | ||
735 | #define RT5660_GP2_PF_MASK (0x1 << 5) | ||
736 | #define RT5660_GP2_PF_SFT 5 | ||
737 | #define RT5660_GP2_PF_IN (0x0 << 5) | ||
738 | #define RT5660_GP2_PF_OUT (0x1 << 5) | ||
739 | #define RT5660_GP2_OUT_MASK (0x1 << 4) | ||
740 | #define RT5660_GP2_OUT_SFT 4 | ||
741 | #define RT5660_GP2_OUT_LO (0x0 << 4) | ||
742 | #define RT5660_GP2_OUT_HI (0x1 << 4) | ||
743 | #define RT5660_GP2_P_MASK (0x1 << 3) | ||
744 | #define RT5660_GP2_P_SFT 3 | ||
745 | #define RT5660_GP2_P_NOR (0x0 << 3) | ||
746 | #define RT5660_GP2_P_INV (0x1 << 3) | ||
747 | #define RT5660_GP1_PF_MASK (0x1 << 2) | ||
748 | #define RT5660_GP1_PF_SFT 2 | ||
749 | #define RT5660_GP1_PF_IN (0x0 << 2) | ||
750 | #define RT5660_GP1_PF_OUT (0x1 << 2) | ||
751 | #define RT5660_GP1_OUT_MASK (0x1 << 1) | ||
752 | #define RT5660_GP1_OUT_SFT 1 | ||
753 | #define RT5660_GP1_OUT_LO (0x0 << 1) | ||
754 | #define RT5660_GP1_OUT_HI (0x1 << 1) | ||
755 | #define RT5660_GP1_P_MASK (0x1) | ||
756 | #define RT5660_GP1_P_SFT 0 | ||
757 | #define RT5660_GP1_P_NOR (0x0) | ||
758 | #define RT5660_GP1_P_INV (0x1) | ||
759 | |||
760 | /* Soft volume and zero cross control 1 (0xd9) */ | ||
761 | #define RT5660_SV_MASK (0x1 << 15) | ||
762 | #define RT5660_SV_SFT 15 | ||
763 | #define RT5660_SV_DIS (0x0 << 15) | ||
764 | #define RT5660_SV_EN (0x1 << 15) | ||
765 | #define RT5660_SPO_SV_MASK (0x1 << 14) | ||
766 | #define RT5660_SPO_SV_SFT 14 | ||
767 | #define RT5660_SPO_SV_DIS (0x0 << 14) | ||
768 | #define RT5660_SPO_SV_EN (0x1 << 14) | ||
769 | #define RT5660_OUT_SV_MASK (0x1 << 12) | ||
770 | #define RT5660_OUT_SV_SFT 12 | ||
771 | #define RT5660_OUT_SV_DIS (0x0 << 12) | ||
772 | #define RT5660_OUT_SV_EN (0x1 << 12) | ||
773 | #define RT5660_ZCD_DIG_MASK (0x1 << 11) | ||
774 | #define RT5660_ZCD_DIG_SFT 11 | ||
775 | #define RT5660_ZCD_DIG_DIS (0x0 << 11) | ||
776 | #define RT5660_ZCD_DIG_EN (0x1 << 11) | ||
777 | #define RT5660_ZCD_MASK (0x1 << 10) | ||
778 | #define RT5660_ZCD_SFT 10 | ||
779 | #define RT5660_ZCD_PD (0x0 << 10) | ||
780 | #define RT5660_ZCD_PU (0x1 << 10) | ||
781 | #define RT5660_SV_DLY_MASK (0xf) | ||
782 | #define RT5660_SV_DLY_SFT 0 | ||
783 | |||
784 | /* Soft volume and zero cross control 2 (0xda) */ | ||
785 | #define RT5660_ZCD_SPO_MASK (0x1 << 15) | ||
786 | #define RT5660_ZCD_SPO_SFT 15 | ||
787 | #define RT5660_ZCD_SPO_DIS (0x0 << 15) | ||
788 | #define RT5660_ZCD_SPO_EN (0x1 << 15) | ||
789 | #define RT5660_ZCD_OMR_MASK (0x1 << 8) | ||
790 | #define RT5660_ZCD_OMR_SFT 8 | ||
791 | #define RT5660_ZCD_OMR_DIS (0x0 << 8) | ||
792 | #define RT5660_ZCD_OMR_EN (0x1 << 8) | ||
793 | #define RT5660_ZCD_OML_MASK (0x1 << 7) | ||
794 | #define RT5660_ZCD_OML_SFT 7 | ||
795 | #define RT5660_ZCD_OML_DIS (0x0 << 7) | ||
796 | #define RT5660_ZCD_OML_EN (0x1 << 7) | ||
797 | #define RT5660_ZCD_SPM_MASK (0x1 << 6) | ||
798 | #define RT5660_ZCD_SPM_SFT 6 | ||
799 | #define RT5660_ZCD_SPM_DIS (0x0 << 6) | ||
800 | #define RT5660_ZCD_SPM_EN (0x1 << 6) | ||
801 | #define RT5660_ZCD_RMR_MASK (0x1 << 5) | ||
802 | #define RT5660_ZCD_RMR_SFT 5 | ||
803 | #define RT5660_ZCD_RMR_DIS (0x0 << 5) | ||
804 | #define RT5660_ZCD_RMR_EN (0x1 << 5) | ||
805 | #define RT5660_ZCD_RML_MASK (0x1 << 4) | ||
806 | #define RT5660_ZCD_RML_SFT 4 | ||
807 | #define RT5660_ZCD_RML_DIS (0x0 << 4) | ||
808 | #define RT5660_ZCD_RML_EN (0x1 << 4) | ||
809 | |||
810 | /* General Control 1 (0xfa) */ | ||
811 | #define RT5660_PWR_VREF_HP (0x1 << 11) | ||
812 | #define RT5660_PWR_VREF_HP_SFT 11 | ||
813 | #define RT5660_DIG_GATE_CTRL (0x1) | ||
814 | #define RT5660_DIG_GATE_CTRL_SFT 0 | ||
815 | |||
816 | /* System Clock Source */ | ||
817 | #define RT5660_SCLK_S_MCLK 0 | ||
818 | #define RT5660_SCLK_S_PLL1 1 | ||
819 | #define RT5660_SCLK_S_RCCLK 2 | ||
820 | |||
821 | /* PLL1 Source */ | ||
822 | #define RT5660_PLL1_S_MCLK 0 | ||
823 | #define RT5660_PLL1_S_BCLK 1 | ||
824 | |||
825 | enum { | ||
826 | RT5660_AIF1, | ||
827 | RT5660_AIFS, | ||
828 | }; | ||
829 | |||
830 | struct rt5660_priv { | ||
831 | struct snd_soc_codec *codec; | ||
832 | struct rt5660_platform_data pdata; | ||
833 | struct regmap *regmap; | ||
834 | struct clk *mclk; | ||
835 | |||
836 | int sysclk; | ||
837 | int sysclk_src; | ||
838 | int lrck[RT5660_AIFS]; | ||
839 | int bclk[RT5660_AIFS]; | ||
840 | int master[RT5660_AIFS]; | ||
841 | |||
842 | int pll_src; | ||
843 | int pll_in; | ||
844 | int pll_out; | ||
845 | }; | ||
846 | |||
847 | #endif | ||
diff --git a/sound/soc/codecs/rt5663.c b/sound/soc/codecs/rt5663.c new file mode 100644 index 000000000000..01a18d88f1eb --- /dev/null +++ b/sound/soc/codecs/rt5663.c | |||
@@ -0,0 +1,3218 @@ | |||
1 | /* | ||
2 | * rt5663.c -- RT5668/RT5663 ALSA SoC audio codec driver | ||
3 | * | ||
4 | * Copyright 2016 Realtek Semiconductor Corp. | ||
5 | * Author: Jack Yu <jack.yu@realtek.com> | ||
6 | * | ||
7 | * This program is free software; you can redistribute it and/or modify | ||
8 | * it under the terms of the GNU General Public License version 2 as | ||
9 | * published by the Free Software Foundation. | ||
10 | */ | ||
11 | #include <linux/module.h> | ||
12 | #include <linux/moduleparam.h> | ||
13 | #include <linux/init.h> | ||
14 | #include <linux/delay.h> | ||
15 | #include <linux/pm.h> | ||
16 | #include <linux/i2c.h> | ||
17 | #include <linux/platform_device.h> | ||
18 | #include <linux/spi/spi.h> | ||
19 | #include <linux/acpi.h> | ||
20 | #include <linux/workqueue.h> | ||
21 | #include <sound/core.h> | ||
22 | #include <sound/pcm.h> | ||
23 | #include <sound/pcm_params.h> | ||
24 | #include <sound/jack.h> | ||
25 | #include <sound/soc.h> | ||
26 | #include <sound/soc-dapm.h> | ||
27 | #include <sound/initval.h> | ||
28 | #include <sound/tlv.h> | ||
29 | |||
30 | #include "rt5663.h" | ||
31 | #include "rl6231.h" | ||
32 | |||
33 | #define RT5668_DEVICE_ID 0x6451 | ||
34 | #define RT5663_DEVICE_ID 0x6406 | ||
35 | |||
36 | enum { | ||
37 | CODEC_TYPE_RT5668, | ||
38 | CODEC_TYPE_RT5663, | ||
39 | }; | ||
40 | |||
41 | struct rt5663_priv { | ||
42 | struct snd_soc_codec *codec; | ||
43 | struct regmap *regmap; | ||
44 | struct delayed_work jack_detect_work; | ||
45 | struct snd_soc_jack *hs_jack; | ||
46 | struct timer_list btn_check_timer; | ||
47 | |||
48 | int codec_type; | ||
49 | int sysclk; | ||
50 | int sysclk_src; | ||
51 | int lrck; | ||
52 | |||
53 | int pll_src; | ||
54 | int pll_in; | ||
55 | int pll_out; | ||
56 | |||
57 | int jack_type; | ||
58 | }; | ||
59 | |||
60 | static const struct reg_default rt5668_reg[] = { | ||
61 | { 0x0000, 0x0000 }, | ||
62 | { 0x0001, 0xc8c8 }, | ||
63 | { 0x0002, 0x8080 }, | ||
64 | { 0x0003, 0x8000 }, | ||
65 | { 0x0004, 0xc80a }, | ||
66 | { 0x0005, 0x0000 }, | ||
67 | { 0x0006, 0x0000 }, | ||
68 | { 0x0007, 0x0000 }, | ||
69 | { 0x000a, 0x0000 }, | ||
70 | { 0x000b, 0x0000 }, | ||
71 | { 0x000c, 0x0000 }, | ||
72 | { 0x000d, 0x0000 }, | ||
73 | { 0x000f, 0x0808 }, | ||
74 | { 0x0010, 0x4000 }, | ||
75 | { 0x0011, 0x0000 }, | ||
76 | { 0x0012, 0x1404 }, | ||
77 | { 0x0013, 0x1000 }, | ||
78 | { 0x0014, 0xa00a }, | ||
79 | { 0x0015, 0x0404 }, | ||
80 | { 0x0016, 0x0404 }, | ||
81 | { 0x0017, 0x0011 }, | ||
82 | { 0x0018, 0xafaf }, | ||
83 | { 0x0019, 0xafaf }, | ||
84 | { 0x001a, 0xafaf }, | ||
85 | { 0x001b, 0x0011 }, | ||
86 | { 0x001c, 0x2f2f }, | ||
87 | { 0x001d, 0x2f2f }, | ||
88 | { 0x001e, 0x2f2f }, | ||
89 | { 0x001f, 0x0000 }, | ||
90 | { 0x0020, 0x0000 }, | ||
91 | { 0x0021, 0x0000 }, | ||
92 | { 0x0022, 0x5757 }, | ||
93 | { 0x0023, 0x0039 }, | ||
94 | { 0x0024, 0x000b }, | ||
95 | { 0x0026, 0xc0c0 }, | ||
96 | { 0x0027, 0xc0c0 }, | ||
97 | { 0x0028, 0xc0c0 }, | ||
98 | { 0x0029, 0x8080 }, | ||
99 | { 0x002a, 0xaaaa }, | ||
100 | { 0x002b, 0xaaaa }, | ||
101 | { 0x002c, 0xaba8 }, | ||
102 | { 0x002d, 0x0000 }, | ||
103 | { 0x002e, 0x0000 }, | ||
104 | { 0x002f, 0x0000 }, | ||
105 | { 0x0030, 0x0000 }, | ||
106 | { 0x0031, 0x5000 }, | ||
107 | { 0x0032, 0x0000 }, | ||
108 | { 0x0033, 0x0000 }, | ||
109 | { 0x0034, 0x0000 }, | ||
110 | { 0x0035, 0x0000 }, | ||
111 | { 0x003a, 0x0000 }, | ||
112 | { 0x003b, 0x0000 }, | ||
113 | { 0x003c, 0x00ff }, | ||
114 | { 0x003d, 0x0000 }, | ||
115 | { 0x003e, 0x00ff }, | ||
116 | { 0x003f, 0x0000 }, | ||
117 | { 0x0040, 0x0000 }, | ||
118 | { 0x0041, 0x00ff }, | ||
119 | { 0x0042, 0x0000 }, | ||
120 | { 0x0043, 0x00ff }, | ||
121 | { 0x0044, 0x0c0c }, | ||
122 | { 0x0049, 0xc00b }, | ||
123 | { 0x004a, 0x0000 }, | ||
124 | { 0x004b, 0x031f }, | ||
125 | { 0x004d, 0x0000 }, | ||
126 | { 0x004e, 0x001f }, | ||
127 | { 0x004f, 0x0000 }, | ||
128 | { 0x0050, 0x001f }, | ||
129 | { 0x0052, 0xf000 }, | ||
130 | { 0x0061, 0x0000 }, | ||
131 | { 0x0062, 0x0000 }, | ||
132 | { 0x0063, 0x003e }, | ||
133 | { 0x0064, 0x0000 }, | ||
134 | { 0x0065, 0x0000 }, | ||
135 | { 0x0066, 0x003f }, | ||
136 | { 0x0067, 0x0000 }, | ||
137 | { 0x006b, 0x0000 }, | ||
138 | { 0x006d, 0xff00 }, | ||
139 | { 0x006e, 0x2808 }, | ||
140 | { 0x006f, 0x000a }, | ||
141 | { 0x0070, 0x8000 }, | ||
142 | { 0x0071, 0x8000 }, | ||
143 | { 0x0072, 0x8000 }, | ||
144 | { 0x0073, 0x7000 }, | ||
145 | { 0x0074, 0x7770 }, | ||
146 | { 0x0075, 0x0002 }, | ||
147 | { 0x0076, 0x0001 }, | ||
148 | { 0x0078, 0x00f0 }, | ||
149 | { 0x0079, 0x0000 }, | ||
150 | { 0x007a, 0x0000 }, | ||
151 | { 0x007b, 0x0000 }, | ||
152 | { 0x007c, 0x0000 }, | ||
153 | { 0x007d, 0x0123 }, | ||
154 | { 0x007e, 0x4500 }, | ||
155 | { 0x007f, 0x8003 }, | ||
156 | { 0x0080, 0x0000 }, | ||
157 | { 0x0081, 0x0000 }, | ||
158 | { 0x0082, 0x0000 }, | ||
159 | { 0x0083, 0x0000 }, | ||
160 | { 0x0084, 0x0000 }, | ||
161 | { 0x0085, 0x0000 }, | ||
162 | { 0x0086, 0x0008 }, | ||
163 | { 0x0087, 0x0000 }, | ||
164 | { 0x0088, 0x0000 }, | ||
165 | { 0x0089, 0x0000 }, | ||
166 | { 0x008a, 0x0000 }, | ||
167 | { 0x008b, 0x0000 }, | ||
168 | { 0x008c, 0x0003 }, | ||
169 | { 0x008e, 0x0060 }, | ||
170 | { 0x008f, 0x1000 }, | ||
171 | { 0x0091, 0x0c26 }, | ||
172 | { 0x0092, 0x0073 }, | ||
173 | { 0x0093, 0x0000 }, | ||
174 | { 0x0094, 0x0080 }, | ||
175 | { 0x0098, 0x0000 }, | ||
176 | { 0x0099, 0x0000 }, | ||
177 | { 0x009a, 0x0007 }, | ||
178 | { 0x009f, 0x0000 }, | ||
179 | { 0x00a0, 0x0000 }, | ||
180 | { 0x00a1, 0x0002 }, | ||
181 | { 0x00a2, 0x0001 }, | ||
182 | { 0x00a3, 0x0002 }, | ||
183 | { 0x00a4, 0x0001 }, | ||
184 | { 0x00ae, 0x2040 }, | ||
185 | { 0x00af, 0x0000 }, | ||
186 | { 0x00b6, 0x0000 }, | ||
187 | { 0x00b7, 0x0000 }, | ||
188 | { 0x00b8, 0x0000 }, | ||
189 | { 0x00b9, 0x0000 }, | ||
190 | { 0x00ba, 0x0002 }, | ||
191 | { 0x00bb, 0x0000 }, | ||
192 | { 0x00be, 0x0000 }, | ||
193 | { 0x00c0, 0x0000 }, | ||
194 | { 0x00c1, 0x0aaa }, | ||
195 | { 0x00c2, 0xaa80 }, | ||
196 | { 0x00c3, 0x0003 }, | ||
197 | { 0x00c4, 0x0000 }, | ||
198 | { 0x00d0, 0x0000 }, | ||
199 | { 0x00d1, 0x2244 }, | ||
200 | { 0x00d2, 0x0000 }, | ||
201 | { 0x00d3, 0x3300 }, | ||
202 | { 0x00d4, 0x2200 }, | ||
203 | { 0x00d9, 0x0809 }, | ||
204 | { 0x00da, 0x0000 }, | ||
205 | { 0x00db, 0x0008 }, | ||
206 | { 0x00dc, 0x00c0 }, | ||
207 | { 0x00dd, 0x6724 }, | ||
208 | { 0x00de, 0x3131 }, | ||
209 | { 0x00df, 0x0008 }, | ||
210 | { 0x00e0, 0x4000 }, | ||
211 | { 0x00e1, 0x3131 }, | ||
212 | { 0x00e2, 0x600c }, | ||
213 | { 0x00ea, 0xb320 }, | ||
214 | { 0x00eb, 0x0000 }, | ||
215 | { 0x00ec, 0xb300 }, | ||
216 | { 0x00ed, 0x0000 }, | ||
217 | { 0x00ee, 0xb320 }, | ||
218 | { 0x00ef, 0x0000 }, | ||
219 | { 0x00f0, 0x0201 }, | ||
220 | { 0x00f1, 0x0ddd }, | ||
221 | { 0x00f2, 0x0ddd }, | ||
222 | { 0x00f6, 0x0000 }, | ||
223 | { 0x00f7, 0x0000 }, | ||
224 | { 0x00f8, 0x0000 }, | ||
225 | { 0x00fa, 0x0000 }, | ||
226 | { 0x00fb, 0x0000 }, | ||
227 | { 0x00fc, 0x0000 }, | ||
228 | { 0x00fd, 0x0000 }, | ||
229 | { 0x00fe, 0x10ec }, | ||
230 | { 0x00ff, 0x6451 }, | ||
231 | { 0x0100, 0xaaaa }, | ||
232 | { 0x0101, 0x000a }, | ||
233 | { 0x010a, 0xaaaa }, | ||
234 | { 0x010b, 0xa0a0 }, | ||
235 | { 0x010c, 0xaeae }, | ||
236 | { 0x010d, 0xaaaa }, | ||
237 | { 0x010e, 0xaaaa }, | ||
238 | { 0x010f, 0xaaaa }, | ||
239 | { 0x0110, 0xe002 }, | ||
240 | { 0x0111, 0xa602 }, | ||
241 | { 0x0112, 0xaaaa }, | ||
242 | { 0x0113, 0x2000 }, | ||
243 | { 0x0117, 0x0f00 }, | ||
244 | { 0x0125, 0x0420 }, | ||
245 | { 0x0132, 0x0000 }, | ||
246 | { 0x0133, 0x0000 }, | ||
247 | { 0x0136, 0x5555 }, | ||
248 | { 0x0137, 0x5540 }, | ||
249 | { 0x0138, 0x3700 }, | ||
250 | { 0x0139, 0x79a1 }, | ||
251 | { 0x013a, 0x2020 }, | ||
252 | { 0x013b, 0x2020 }, | ||
253 | { 0x013c, 0x2005 }, | ||
254 | { 0x013f, 0x0000 }, | ||
255 | { 0x0145, 0x0002 }, | ||
256 | { 0x0146, 0x0000 }, | ||
257 | { 0x0147, 0x0000 }, | ||
258 | { 0x0148, 0x0000 }, | ||
259 | { 0x0160, 0x4ec0 }, | ||
260 | { 0x0161, 0x0080 }, | ||
261 | { 0x0162, 0x0200 }, | ||
262 | { 0x0163, 0x0800 }, | ||
263 | { 0x0164, 0x0000 }, | ||
264 | { 0x0165, 0x0000 }, | ||
265 | { 0x0166, 0x0000 }, | ||
266 | { 0x0167, 0x000f }, | ||
267 | { 0x0168, 0x000f }, | ||
268 | { 0x0170, 0x4e80 }, | ||
269 | { 0x0171, 0x0080 }, | ||
270 | { 0x0172, 0x0200 }, | ||
271 | { 0x0173, 0x0800 }, | ||
272 | { 0x0174, 0x00ff }, | ||
273 | { 0x0175, 0x0000 }, | ||
274 | { 0x0190, 0x4131 }, | ||
275 | { 0x0191, 0x4131 }, | ||
276 | { 0x0192, 0x4131 }, | ||
277 | { 0x0193, 0x4131 }, | ||
278 | { 0x0194, 0x0000 }, | ||
279 | { 0x0195, 0x0000 }, | ||
280 | { 0x0196, 0x0000 }, | ||
281 | { 0x0197, 0x0000 }, | ||
282 | { 0x0198, 0x0000 }, | ||
283 | { 0x0199, 0x0000 }, | ||
284 | { 0x01a0, 0x1e64 }, | ||
285 | { 0x01a1, 0x06a3 }, | ||
286 | { 0x01a2, 0x0000 }, | ||
287 | { 0x01a3, 0x0000 }, | ||
288 | { 0x01a4, 0x0000 }, | ||
289 | { 0x01a5, 0x0000 }, | ||
290 | { 0x01a6, 0x0000 }, | ||
291 | { 0x01a7, 0x0000 }, | ||
292 | { 0x01a8, 0x0000 }, | ||
293 | { 0x01a9, 0x0000 }, | ||
294 | { 0x01aa, 0x0000 }, | ||
295 | { 0x01ab, 0x0000 }, | ||
296 | { 0x01b5, 0x0000 }, | ||
297 | { 0x01b6, 0x01c3 }, | ||
298 | { 0x01b7, 0x02a0 }, | ||
299 | { 0x01b8, 0x03e9 }, | ||
300 | { 0x01b9, 0x1389 }, | ||
301 | { 0x01ba, 0xc351 }, | ||
302 | { 0x01bb, 0x0009 }, | ||
303 | { 0x01bc, 0x0018 }, | ||
304 | { 0x01bd, 0x002a }, | ||
305 | { 0x01be, 0x004c }, | ||
306 | { 0x01bf, 0x0097 }, | ||
307 | { 0x01c0, 0x433d }, | ||
308 | { 0x01c1, 0x0000 }, | ||
309 | { 0x01c2, 0x0000 }, | ||
310 | { 0x01c3, 0x0000 }, | ||
311 | { 0x01c4, 0x0000 }, | ||
312 | { 0x01c5, 0x0000 }, | ||
313 | { 0x01c6, 0x0000 }, | ||
314 | { 0x01c7, 0x0000 }, | ||
315 | { 0x01c8, 0x40af }, | ||
316 | { 0x01c9, 0x0702 }, | ||
317 | { 0x01ca, 0x0000 }, | ||
318 | { 0x01cb, 0x0000 }, | ||
319 | { 0x01cc, 0x5757 }, | ||
320 | { 0x01cd, 0x5757 }, | ||
321 | { 0x01ce, 0x5757 }, | ||
322 | { 0x01cf, 0x5757 }, | ||
323 | { 0x01d0, 0x5757 }, | ||
324 | { 0x01d1, 0x5757 }, | ||
325 | { 0x01d2, 0x5757 }, | ||
326 | { 0x01d3, 0x5757 }, | ||
327 | { 0x01d4, 0x5757 }, | ||
328 | { 0x01d5, 0x5757 }, | ||
329 | { 0x01d6, 0x003c }, | ||
330 | { 0x01da, 0x0000 }, | ||
331 | { 0x01db, 0x0000 }, | ||
332 | { 0x01dc, 0x0000 }, | ||
333 | { 0x01de, 0x7c00 }, | ||
334 | { 0x01df, 0x0320 }, | ||
335 | { 0x01e0, 0x06a1 }, | ||
336 | { 0x01e1, 0x0000 }, | ||
337 | { 0x01e2, 0x0000 }, | ||
338 | { 0x01e3, 0x0000 }, | ||
339 | { 0x01e4, 0x0000 }, | ||
340 | { 0x01e5, 0x0000 }, | ||
341 | { 0x01e6, 0x0001 }, | ||
342 | { 0x01e7, 0x0000 }, | ||
343 | { 0x01e8, 0x0000 }, | ||
344 | { 0x01ea, 0x0000 }, | ||
345 | { 0x01eb, 0x0000 }, | ||
346 | { 0x01ec, 0x0000 }, | ||
347 | { 0x01ed, 0x0000 }, | ||
348 | { 0x01ee, 0x0000 }, | ||
349 | { 0x01ef, 0x0000 }, | ||
350 | { 0x01f0, 0x0000 }, | ||
351 | { 0x01f1, 0x0000 }, | ||
352 | { 0x01f2, 0x0000 }, | ||
353 | { 0x01f3, 0x0000 }, | ||
354 | { 0x01f4, 0x0000 }, | ||
355 | { 0x0200, 0x0000 }, | ||
356 | { 0x0201, 0x0000 }, | ||
357 | { 0x0202, 0x0000 }, | ||
358 | { 0x0203, 0x0000 }, | ||
359 | { 0x0204, 0x0000 }, | ||
360 | { 0x0205, 0x0000 }, | ||
361 | { 0x0206, 0x0000 }, | ||
362 | { 0x0207, 0x0000 }, | ||
363 | { 0x0208, 0x0000 }, | ||
364 | { 0x0210, 0x60b1 }, | ||
365 | { 0x0211, 0xa000 }, | ||
366 | { 0x0212, 0x024c }, | ||
367 | { 0x0213, 0xf7ff }, | ||
368 | { 0x0214, 0x024c }, | ||
369 | { 0x0215, 0x0102 }, | ||
370 | { 0x0216, 0x00a3 }, | ||
371 | { 0x0217, 0x0048 }, | ||
372 | { 0x0218, 0x92c0 }, | ||
373 | { 0x0219, 0x0000 }, | ||
374 | { 0x021a, 0x00c8 }, | ||
375 | { 0x021b, 0x0020 }, | ||
376 | { 0x02fa, 0x0000 }, | ||
377 | { 0x02fb, 0x0000 }, | ||
378 | { 0x02fc, 0x0000 }, | ||
379 | { 0x02ff, 0x0110 }, | ||
380 | { 0x0300, 0x001f }, | ||
381 | { 0x0301, 0x032c }, | ||
382 | { 0x0302, 0x5f21 }, | ||
383 | { 0x0303, 0x4000 }, | ||
384 | { 0x0304, 0x4000 }, | ||
385 | { 0x0305, 0x06d5 }, | ||
386 | { 0x0306, 0x8000 }, | ||
387 | { 0x0307, 0x0700 }, | ||
388 | { 0x0310, 0x4560 }, | ||
389 | { 0x0311, 0xa4a8 }, | ||
390 | { 0x0312, 0x7418 }, | ||
391 | { 0x0313, 0x0000 }, | ||
392 | { 0x0314, 0x0006 }, | ||
393 | { 0x0315, 0xffff }, | ||
394 | { 0x0316, 0xc400 }, | ||
395 | { 0x0317, 0x0000 }, | ||
396 | { 0x0330, 0x00a6 }, | ||
397 | { 0x0331, 0x04c3 }, | ||
398 | { 0x0332, 0x27c8 }, | ||
399 | { 0x0333, 0xbf50 }, | ||
400 | { 0x0334, 0x0045 }, | ||
401 | { 0x0335, 0x0007 }, | ||
402 | { 0x0336, 0x7418 }, | ||
403 | { 0x0337, 0x0501 }, | ||
404 | { 0x0338, 0x0000 }, | ||
405 | { 0x0339, 0x0010 }, | ||
406 | { 0x033a, 0x1010 }, | ||
407 | { 0x03c0, 0x7e00 }, | ||
408 | { 0x03c1, 0x8000 }, | ||
409 | { 0x03c2, 0x8000 }, | ||
410 | { 0x03c3, 0x8000 }, | ||
411 | { 0x03c4, 0x8000 }, | ||
412 | { 0x03c5, 0x8000 }, | ||
413 | { 0x03c6, 0x8000 }, | ||
414 | { 0x03c7, 0x8000 }, | ||
415 | { 0x03c8, 0x8000 }, | ||
416 | { 0x03c9, 0x8000 }, | ||
417 | { 0x03ca, 0x8000 }, | ||
418 | { 0x03cb, 0x8000 }, | ||
419 | { 0x03cc, 0x8000 }, | ||
420 | { 0x03d0, 0x0000 }, | ||
421 | { 0x03d1, 0x0000 }, | ||
422 | { 0x03d2, 0x0000 }, | ||
423 | { 0x03d3, 0x0000 }, | ||
424 | { 0x03d4, 0x2000 }, | ||
425 | { 0x03d5, 0x2000 }, | ||
426 | { 0x03d6, 0x0000 }, | ||
427 | { 0x03d7, 0x0000 }, | ||
428 | { 0x03d8, 0x2000 }, | ||
429 | { 0x03d9, 0x2000 }, | ||
430 | { 0x03da, 0x2000 }, | ||
431 | { 0x03db, 0x2000 }, | ||
432 | { 0x03dc, 0x0000 }, | ||
433 | { 0x03dd, 0x0000 }, | ||
434 | { 0x03de, 0x0000 }, | ||
435 | { 0x03df, 0x2000 }, | ||
436 | { 0x03e0, 0x0000 }, | ||
437 | { 0x03e1, 0x0000 }, | ||
438 | { 0x03e2, 0x0000 }, | ||
439 | { 0x03e3, 0x0000 }, | ||
440 | { 0x03e4, 0x0000 }, | ||
441 | { 0x03e5, 0x0000 }, | ||
442 | { 0x03e6, 0x0000 }, | ||
443 | { 0x03e7, 0x0000 }, | ||
444 | { 0x03e8, 0x0000 }, | ||
445 | { 0x03e9, 0x0000 }, | ||
446 | { 0x03ea, 0x0000 }, | ||
447 | { 0x03eb, 0x0000 }, | ||
448 | { 0x03ec, 0x0000 }, | ||
449 | { 0x03ed, 0x0000 }, | ||
450 | { 0x03ee, 0x0000 }, | ||
451 | { 0x03ef, 0x0000 }, | ||
452 | { 0x03f0, 0x0800 }, | ||
453 | { 0x03f1, 0x0800 }, | ||
454 | { 0x03f2, 0x0800 }, | ||
455 | { 0x03f3, 0x0800 }, | ||
456 | { 0x03fe, 0x0000 }, | ||
457 | { 0x03ff, 0x0000 }, | ||
458 | { 0x07f0, 0x0000 }, | ||
459 | { 0x07fa, 0x0000 }, | ||
460 | }; | ||
461 | |||
462 | static const struct reg_default rt5663_reg[] = { | ||
463 | { 0x0000, 0x0000 }, | ||
464 | { 0x0002, 0x0008 }, | ||
465 | { 0x0005, 0x1000 }, | ||
466 | { 0x0006, 0x1000 }, | ||
467 | { 0x000a, 0x0000 }, | ||
468 | { 0x0010, 0x000f }, | ||
469 | { 0x0015, 0x42c1 }, | ||
470 | { 0x0016, 0x0000 }, | ||
471 | { 0x0018, 0x000b }, | ||
472 | { 0x0019, 0xafaf }, | ||
473 | { 0x001c, 0x2f2f }, | ||
474 | { 0x001f, 0x0000 }, | ||
475 | { 0x0022, 0x5757 }, | ||
476 | { 0x0023, 0x0039 }, | ||
477 | { 0x0026, 0xc0c0 }, | ||
478 | { 0x0029, 0x8080 }, | ||
479 | { 0x002a, 0xa0a0 }, | ||
480 | { 0x002c, 0x000c }, | ||
481 | { 0x002d, 0x0000 }, | ||
482 | { 0x0040, 0x0808 }, | ||
483 | { 0x0061, 0x0000 }, | ||
484 | { 0x0062, 0x0000 }, | ||
485 | { 0x0063, 0x003e }, | ||
486 | { 0x0064, 0x0000 }, | ||
487 | { 0x0065, 0x0000 }, | ||
488 | { 0x0066, 0x0000 }, | ||
489 | { 0x006b, 0x0000 }, | ||
490 | { 0x006e, 0x0000 }, | ||
491 | { 0x006f, 0x0000 }, | ||
492 | { 0x0070, 0x8020 }, | ||
493 | { 0x0073, 0x1000 }, | ||
494 | { 0x0074, 0xe400 }, | ||
495 | { 0x0075, 0x0002 }, | ||
496 | { 0x0076, 0x0001 }, | ||
497 | { 0x0077, 0x00f0 }, | ||
498 | { 0x0078, 0x0000 }, | ||
499 | { 0x0079, 0x0000 }, | ||
500 | { 0x007a, 0x0123 }, | ||
501 | { 0x007b, 0x8003 }, | ||
502 | { 0x0080, 0x0000 }, | ||
503 | { 0x0081, 0x0000 }, | ||
504 | { 0x0082, 0x0000 }, | ||
505 | { 0x0083, 0x0000 }, | ||
506 | { 0x0084, 0x0000 }, | ||
507 | { 0x0086, 0x0008 }, | ||
508 | { 0x0087, 0x0000 }, | ||
509 | { 0x008a, 0x0000 }, | ||
510 | { 0x008b, 0x0000 }, | ||
511 | { 0x008c, 0x0003 }, | ||
512 | { 0x008e, 0x0004 }, | ||
513 | { 0x008f, 0x1000 }, | ||
514 | { 0x0090, 0x0646 }, | ||
515 | { 0x0091, 0x0e3e }, | ||
516 | { 0x0092, 0x1071 }, | ||
517 | { 0x0093, 0x0000 }, | ||
518 | { 0x0094, 0x0080 }, | ||
519 | { 0x0097, 0x0000 }, | ||
520 | { 0x0098, 0x0000 }, | ||
521 | { 0x009a, 0x0000 }, | ||
522 | { 0x009f, 0x0000 }, | ||
523 | { 0x00ae, 0x2000 }, | ||
524 | { 0x00af, 0x0000 }, | ||
525 | { 0x00b6, 0x0000 }, | ||
526 | { 0x00b7, 0x0000 }, | ||
527 | { 0x00b8, 0x0000 }, | ||
528 | { 0x00ba, 0x0000 }, | ||
529 | { 0x00bb, 0x0000 }, | ||
530 | { 0x00be, 0x0000 }, | ||
531 | { 0x00bf, 0x0000 }, | ||
532 | { 0x00c0, 0x0000 }, | ||
533 | { 0x00c1, 0x0000 }, | ||
534 | { 0x00c5, 0x0000 }, | ||
535 | { 0x00cb, 0xa02f }, | ||
536 | { 0x00cc, 0x0000 }, | ||
537 | { 0x00cd, 0x0e02 }, | ||
538 | { 0x00d9, 0x08f9 }, | ||
539 | { 0x00db, 0x0008 }, | ||
540 | { 0x00dc, 0x00c0 }, | ||
541 | { 0x00dd, 0x6724 }, | ||
542 | { 0x00de, 0x3131 }, | ||
543 | { 0x00df, 0x0008 }, | ||
544 | { 0x00e0, 0x4000 }, | ||
545 | { 0x00e1, 0x3131 }, | ||
546 | { 0x00e2, 0x0043 }, | ||
547 | { 0x00e4, 0x400b }, | ||
548 | { 0x00e5, 0x8031 }, | ||
549 | { 0x00e6, 0x3080 }, | ||
550 | { 0x00e7, 0x4100 }, | ||
551 | { 0x00e8, 0x1400 }, | ||
552 | { 0x00e9, 0xe00a }, | ||
553 | { 0x00ea, 0x0404 }, | ||
554 | { 0x00eb, 0x0404 }, | ||
555 | { 0x00ec, 0xb320 }, | ||
556 | { 0x00ed, 0x0000 }, | ||
557 | { 0x00f4, 0x0000 }, | ||
558 | { 0x00f6, 0x0000 }, | ||
559 | { 0x00f8, 0x0000 }, | ||
560 | { 0x00fa, 0x8000 }, | ||
561 | { 0x00fd, 0x0001 }, | ||
562 | { 0x00fe, 0x10ec }, | ||
563 | { 0x00ff, 0x6406 }, | ||
564 | { 0x0100, 0xa0a0 }, | ||
565 | { 0x0108, 0x4444 }, | ||
566 | { 0x0109, 0x4444 }, | ||
567 | { 0x010a, 0xaaaa }, | ||
568 | { 0x010b, 0x00a0 }, | ||
569 | { 0x010c, 0x8aaa }, | ||
570 | { 0x010d, 0xaaaa }, | ||
571 | { 0x010e, 0x2aaa }, | ||
572 | { 0x010f, 0x002a }, | ||
573 | { 0x0110, 0xa0a4 }, | ||
574 | { 0x0111, 0x4602 }, | ||
575 | { 0x0112, 0x0101 }, | ||
576 | { 0x0113, 0x2000 }, | ||
577 | { 0x0114, 0x0000 }, | ||
578 | { 0x0116, 0x0000 }, | ||
579 | { 0x0117, 0x0f00 }, | ||
580 | { 0x0118, 0x0006 }, | ||
581 | { 0x0125, 0x2224 }, | ||
582 | { 0x0126, 0x5550 }, | ||
583 | { 0x0127, 0x0400 }, | ||
584 | { 0x0128, 0x7711 }, | ||
585 | { 0x0132, 0x0004 }, | ||
586 | { 0x0137, 0x5441 }, | ||
587 | { 0x0139, 0x79a1 }, | ||
588 | { 0x013a, 0x30c0 }, | ||
589 | { 0x013b, 0x2000 }, | ||
590 | { 0x013c, 0x2005 }, | ||
591 | { 0x013d, 0x30c0 }, | ||
592 | { 0x013e, 0x0000 }, | ||
593 | { 0x0140, 0x3700 }, | ||
594 | { 0x0141, 0x1f00 }, | ||
595 | { 0x0144, 0x0000 }, | ||
596 | { 0x0145, 0x0002 }, | ||
597 | { 0x0146, 0x0000 }, | ||
598 | { 0x0160, 0x0e80 }, | ||
599 | { 0x0161, 0x0020 }, | ||
600 | { 0x0162, 0x0080 }, | ||
601 | { 0x0163, 0x0800 }, | ||
602 | { 0x0164, 0x0000 }, | ||
603 | { 0x0165, 0x0000 }, | ||
604 | { 0x0166, 0x0000 }, | ||
605 | { 0x0167, 0x1417 }, | ||
606 | { 0x0168, 0x0017 }, | ||
607 | { 0x0169, 0x0017 }, | ||
608 | { 0x0180, 0x2000 }, | ||
609 | { 0x0181, 0x0000 }, | ||
610 | { 0x0182, 0x0000 }, | ||
611 | { 0x0183, 0x2000 }, | ||
612 | { 0x0184, 0x0000 }, | ||
613 | { 0x0185, 0x0000 }, | ||
614 | { 0x01b0, 0x4b30 }, | ||
615 | { 0x01b1, 0x0000 }, | ||
616 | { 0x01b2, 0xd870 }, | ||
617 | { 0x01b3, 0x0000 }, | ||
618 | { 0x01b4, 0x0030 }, | ||
619 | { 0x01b5, 0x5757 }, | ||
620 | { 0x01b6, 0x5757 }, | ||
621 | { 0x01b7, 0x5757 }, | ||
622 | { 0x01b8, 0x5757 }, | ||
623 | { 0x01c0, 0x433d }, | ||
624 | { 0x01c1, 0x0540 }, | ||
625 | { 0x01c2, 0x0000 }, | ||
626 | { 0x01c3, 0x0000 }, | ||
627 | { 0x01c4, 0x0000 }, | ||
628 | { 0x01c5, 0x0009 }, | ||
629 | { 0x01c6, 0x0018 }, | ||
630 | { 0x01c7, 0x002a }, | ||
631 | { 0x01c8, 0x004c }, | ||
632 | { 0x01c9, 0x0097 }, | ||
633 | { 0x01ca, 0x01c3 }, | ||
634 | { 0x01cb, 0x03e9 }, | ||
635 | { 0x01cc, 0x1389 }, | ||
636 | { 0x01cd, 0xc351 }, | ||
637 | { 0x01ce, 0x0000 }, | ||
638 | { 0x01cf, 0x0000 }, | ||
639 | { 0x01d0, 0x0000 }, | ||
640 | { 0x01d1, 0x0000 }, | ||
641 | { 0x01d2, 0x0000 }, | ||
642 | { 0x01d3, 0x003c }, | ||
643 | { 0x01d4, 0x5757 }, | ||
644 | { 0x01d5, 0x5757 }, | ||
645 | { 0x01d6, 0x5757 }, | ||
646 | { 0x01d7, 0x5757 }, | ||
647 | { 0x01d8, 0x5757 }, | ||
648 | { 0x01d9, 0x5757 }, | ||
649 | { 0x01da, 0x0000 }, | ||
650 | { 0x01db, 0x0000 }, | ||
651 | { 0x01dd, 0x0009 }, | ||
652 | { 0x01de, 0x7f00 }, | ||
653 | { 0x01df, 0x00c8 }, | ||
654 | { 0x01e0, 0x0691 }, | ||
655 | { 0x01e1, 0x0000 }, | ||
656 | { 0x01e2, 0x0000 }, | ||
657 | { 0x01e3, 0x0000 }, | ||
658 | { 0x01e4, 0x0000 }, | ||
659 | { 0x01e5, 0x0040 }, | ||
660 | { 0x01e6, 0x0000 }, | ||
661 | { 0x01e7, 0x0000 }, | ||
662 | { 0x01e8, 0x0000 }, | ||
663 | { 0x01ea, 0x0000 }, | ||
664 | { 0x01eb, 0x0000 }, | ||
665 | { 0x01ec, 0x0000 }, | ||
666 | { 0x01ed, 0x0000 }, | ||
667 | { 0x01ee, 0x0000 }, | ||
668 | { 0x01ef, 0x0000 }, | ||
669 | { 0x01f0, 0x0000 }, | ||
670 | { 0x01f1, 0x0000 }, | ||
671 | { 0x01f2, 0x0000 }, | ||
672 | { 0x0200, 0x0000 }, | ||
673 | { 0x0201, 0x2244 }, | ||
674 | { 0x0202, 0xaaaa }, | ||
675 | { 0x0250, 0x8010 }, | ||
676 | { 0x0251, 0x0000 }, | ||
677 | { 0x0252, 0x028a }, | ||
678 | { 0x02fa, 0x0000 }, | ||
679 | { 0x02fb, 0x0000 }, | ||
680 | { 0x02fc, 0x0000 }, | ||
681 | { 0x0300, 0x0000 }, | ||
682 | { 0x03d0, 0x0000 }, | ||
683 | { 0x03d1, 0x0000 }, | ||
684 | { 0x03d2, 0x0000 }, | ||
685 | { 0x03d3, 0x0000 }, | ||
686 | { 0x03d4, 0x2000 }, | ||
687 | { 0x03d5, 0x2000 }, | ||
688 | { 0x03d6, 0x0000 }, | ||
689 | { 0x03d7, 0x0000 }, | ||
690 | { 0x03d8, 0x2000 }, | ||
691 | { 0x03d9, 0x2000 }, | ||
692 | { 0x03da, 0x2000 }, | ||
693 | { 0x03db, 0x2000 }, | ||
694 | { 0x03dc, 0x0000 }, | ||
695 | { 0x03dd, 0x0000 }, | ||
696 | { 0x03de, 0x0000 }, | ||
697 | { 0x03df, 0x2000 }, | ||
698 | { 0x03e0, 0x0000 }, | ||
699 | { 0x03e1, 0x0000 }, | ||
700 | { 0x03e2, 0x0000 }, | ||
701 | { 0x03e3, 0x0000 }, | ||
702 | { 0x03e4, 0x0000 }, | ||
703 | { 0x03e5, 0x0000 }, | ||
704 | { 0x03e6, 0x0000 }, | ||
705 | { 0x03e7, 0x0000 }, | ||
706 | { 0x03e8, 0x0000 }, | ||
707 | { 0x03e9, 0x0000 }, | ||
708 | { 0x03ea, 0x0000 }, | ||
709 | { 0x03eb, 0x0000 }, | ||
710 | { 0x03ec, 0x0000 }, | ||
711 | { 0x03ed, 0x0000 }, | ||
712 | { 0x03ee, 0x0000 }, | ||
713 | { 0x03ef, 0x0000 }, | ||
714 | { 0x03f0, 0x0800 }, | ||
715 | { 0x03f1, 0x0800 }, | ||
716 | { 0x03f2, 0x0800 }, | ||
717 | { 0x03f3, 0x0800 }, | ||
718 | }; | ||
719 | |||
720 | static bool rt5663_volatile_register(struct device *dev, unsigned int reg) | ||
721 | { | ||
722 | switch (reg) { | ||
723 | case RT5663_RESET: | ||
724 | case RT5663_SIL_DET_CTL: | ||
725 | case RT5663_HP_IMP_GAIN_2: | ||
726 | case RT5663_AD_DA_MIXER: | ||
727 | case RT5663_FRAC_DIV_2: | ||
728 | case RT5663_MICBIAS_1: | ||
729 | case RT5663_ASRC_11_2: | ||
730 | case RT5663_ADC_EQ_1: | ||
731 | case RT5663_INT_ST_1: | ||
732 | case RT5663_INT_ST_2: | ||
733 | case RT5663_GPIO_STA: | ||
734 | case RT5663_SIN_GEN_1: | ||
735 | case RT5663_IL_CMD_1: | ||
736 | case RT5663_IL_CMD_5: | ||
737 | case RT5663_IL_CMD_PWRSAV1: | ||
738 | case RT5663_EM_JACK_TYPE_1: | ||
739 | case RT5663_EM_JACK_TYPE_2: | ||
740 | case RT5663_EM_JACK_TYPE_3: | ||
741 | case RT5663_JD_CTRL2: | ||
742 | case RT5663_VENDOR_ID: | ||
743 | case RT5663_VENDOR_ID_1: | ||
744 | case RT5663_VENDOR_ID_2: | ||
745 | case RT5663_PLL_INT_REG: | ||
746 | case RT5663_SOFT_RAMP: | ||
747 | case RT5663_STO_DRE_1: | ||
748 | case RT5663_STO_DRE_5: | ||
749 | case RT5663_STO_DRE_6: | ||
750 | case RT5663_STO_DRE_7: | ||
751 | case RT5663_MIC_DECRO_1: | ||
752 | case RT5663_MIC_DECRO_4: | ||
753 | case RT5663_HP_IMP_SEN_1: | ||
754 | case RT5663_HP_IMP_SEN_3: | ||
755 | case RT5663_HP_IMP_SEN_4: | ||
756 | case RT5663_HP_IMP_SEN_5: | ||
757 | case RT5663_HP_CALIB_1_1: | ||
758 | case RT5663_HP_CALIB_9: | ||
759 | case RT5663_HP_CALIB_ST1: | ||
760 | case RT5663_HP_CALIB_ST2: | ||
761 | case RT5663_HP_CALIB_ST3: | ||
762 | case RT5663_HP_CALIB_ST4: | ||
763 | case RT5663_HP_CALIB_ST5: | ||
764 | case RT5663_HP_CALIB_ST6: | ||
765 | case RT5663_HP_CALIB_ST7: | ||
766 | case RT5663_HP_CALIB_ST8: | ||
767 | case RT5663_HP_CALIB_ST9: | ||
768 | case RT5663_ANA_JD: | ||
769 | return true; | ||
770 | default: | ||
771 | return false; | ||
772 | } | ||
773 | } | ||
774 | |||
775 | static bool rt5663_readable_register(struct device *dev, unsigned int reg) | ||
776 | { | ||
777 | switch (reg) { | ||
778 | case RT5663_RESET: | ||
779 | case RT5663_HP_OUT_EN: | ||
780 | case RT5663_HP_LCH_DRE: | ||
781 | case RT5663_HP_RCH_DRE: | ||
782 | case RT5663_CALIB_BST: | ||
783 | case RT5663_RECMIX: | ||
784 | case RT5663_SIL_DET_CTL: | ||
785 | case RT5663_PWR_SAV_SILDET: | ||
786 | case RT5663_SIDETONE_CTL: | ||
787 | case RT5663_STO1_DAC_DIG_VOL: | ||
788 | case RT5663_STO1_ADC_DIG_VOL: | ||
789 | case RT5663_STO1_BOOST: | ||
790 | case RT5663_HP_IMP_GAIN_1: | ||
791 | case RT5663_HP_IMP_GAIN_2: | ||
792 | case RT5663_STO1_ADC_MIXER: | ||
793 | case RT5663_AD_DA_MIXER: | ||
794 | case RT5663_STO_DAC_MIXER: | ||
795 | case RT5663_DIG_SIDE_MIXER: | ||
796 | case RT5663_BYPASS_STO_DAC: | ||
797 | case RT5663_CALIB_REC_MIX: | ||
798 | case RT5663_PWR_DIG_1: | ||
799 | case RT5663_PWR_DIG_2: | ||
800 | case RT5663_PWR_ANLG_1: | ||
801 | case RT5663_PWR_ANLG_2: | ||
802 | case RT5663_PWR_ANLG_3: | ||
803 | case RT5663_PWR_MIXER: | ||
804 | case RT5663_SIG_CLK_DET: | ||
805 | case RT5663_PRE_DIV_GATING_1: | ||
806 | case RT5663_PRE_DIV_GATING_2: | ||
807 | case RT5663_I2S1_SDP: | ||
808 | case RT5663_ADDA_CLK_1: | ||
809 | case RT5663_ADDA_RST: | ||
810 | case RT5663_FRAC_DIV_1: | ||
811 | case RT5663_FRAC_DIV_2: | ||
812 | case RT5663_TDM_1: | ||
813 | case RT5663_TDM_2: | ||
814 | case RT5663_TDM_3: | ||
815 | case RT5663_TDM_4: | ||
816 | case RT5663_TDM_5: | ||
817 | case RT5663_GLB_CLK: | ||
818 | case RT5663_PLL_1: | ||
819 | case RT5663_PLL_2: | ||
820 | case RT5663_ASRC_1: | ||
821 | case RT5663_ASRC_2: | ||
822 | case RT5663_ASRC_4: | ||
823 | case RT5663_DUMMY_REG: | ||
824 | case RT5663_ASRC_8: | ||
825 | case RT5663_ASRC_9: | ||
826 | case RT5663_ASRC_11: | ||
827 | case RT5663_DEPOP_1: | ||
828 | case RT5663_DEPOP_2: | ||
829 | case RT5663_DEPOP_3: | ||
830 | case RT5663_HP_CHARGE_PUMP_1: | ||
831 | case RT5663_HP_CHARGE_PUMP_2: | ||
832 | case RT5663_MICBIAS_1: | ||
833 | case RT5663_RC_CLK: | ||
834 | case RT5663_ASRC_11_2: | ||
835 | case RT5663_DUMMY_REG_2: | ||
836 | case RT5663_REC_PATH_GAIN: | ||
837 | case RT5663_AUTO_1MRC_CLK: | ||
838 | case RT5663_ADC_EQ_1: | ||
839 | case RT5663_ADC_EQ_2: | ||
840 | case RT5663_IRQ_1: | ||
841 | case RT5663_IRQ_2: | ||
842 | case RT5663_IRQ_3: | ||
843 | case RT5663_IRQ_4: | ||
844 | case RT5663_IRQ_5: | ||
845 | case RT5663_INT_ST_1: | ||
846 | case RT5663_INT_ST_2: | ||
847 | case RT5663_GPIO_1: | ||
848 | case RT5663_GPIO_2: | ||
849 | case RT5663_GPIO_STA: | ||
850 | case RT5663_SIN_GEN_1: | ||
851 | case RT5663_SIN_GEN_2: | ||
852 | case RT5663_SIN_GEN_3: | ||
853 | case RT5663_SOF_VOL_ZC1: | ||
854 | case RT5663_IL_CMD_1: | ||
855 | case RT5663_IL_CMD_2: | ||
856 | case RT5663_IL_CMD_3: | ||
857 | case RT5663_IL_CMD_4: | ||
858 | case RT5663_IL_CMD_5: | ||
859 | case RT5663_IL_CMD_6: | ||
860 | case RT5663_IL_CMD_7: | ||
861 | case RT5663_IL_CMD_8: | ||
862 | case RT5663_IL_CMD_PWRSAV1: | ||
863 | case RT5663_IL_CMD_PWRSAV2: | ||
864 | case RT5663_EM_JACK_TYPE_1: | ||
865 | case RT5663_EM_JACK_TYPE_2: | ||
866 | case RT5663_EM_JACK_TYPE_3: | ||
867 | case RT5663_EM_JACK_TYPE_4: | ||
868 | case RT5663_EM_JACK_TYPE_5: | ||
869 | case RT5663_EM_JACK_TYPE_6: | ||
870 | case RT5663_STO1_HPF_ADJ1: | ||
871 | case RT5663_STO1_HPF_ADJ2: | ||
872 | case RT5663_FAST_OFF_MICBIAS: | ||
873 | case RT5663_JD_CTRL1: | ||
874 | case RT5663_JD_CTRL2: | ||
875 | case RT5663_DIG_MISC: | ||
876 | case RT5663_VENDOR_ID: | ||
877 | case RT5663_VENDOR_ID_1: | ||
878 | case RT5663_VENDOR_ID_2: | ||
879 | case RT5663_DIG_VOL_ZCD: | ||
880 | case RT5663_ANA_BIAS_CUR_1: | ||
881 | case RT5663_ANA_BIAS_CUR_2: | ||
882 | case RT5663_ANA_BIAS_CUR_3: | ||
883 | case RT5663_ANA_BIAS_CUR_4: | ||
884 | case RT5663_ANA_BIAS_CUR_5: | ||
885 | case RT5663_ANA_BIAS_CUR_6: | ||
886 | case RT5663_BIAS_CUR_5: | ||
887 | case RT5663_BIAS_CUR_6: | ||
888 | case RT5663_BIAS_CUR_7: | ||
889 | case RT5663_BIAS_CUR_8: | ||
890 | case RT5663_DACREF_LDO: | ||
891 | case RT5663_DUMMY_REG_3: | ||
892 | case RT5663_BIAS_CUR_9: | ||
893 | case RT5663_DUMMY_REG_4: | ||
894 | case RT5663_VREFADJ_OP: | ||
895 | case RT5663_VREF_RECMIX: | ||
896 | case RT5663_CHARGE_PUMP_1: | ||
897 | case RT5663_CHARGE_PUMP_1_2: | ||
898 | case RT5663_CHARGE_PUMP_1_3: | ||
899 | case RT5663_CHARGE_PUMP_2: | ||
900 | case RT5663_DIG_IN_PIN1: | ||
901 | case RT5663_PAD_DRV_CTL: | ||
902 | case RT5663_PLL_INT_REG: | ||
903 | case RT5663_CHOP_DAC_L: | ||
904 | case RT5663_CHOP_ADC: | ||
905 | case RT5663_CALIB_ADC: | ||
906 | case RT5663_CHOP_DAC_R: | ||
907 | case RT5663_DUMMY_CTL_DACLR: | ||
908 | case RT5663_DUMMY_REG_5: | ||
909 | case RT5663_SOFT_RAMP: | ||
910 | case RT5663_TEST_MODE_1: | ||
911 | case RT5663_TEST_MODE_2: | ||
912 | case RT5663_TEST_MODE_3: | ||
913 | case RT5663_STO_DRE_1: | ||
914 | case RT5663_STO_DRE_2: | ||
915 | case RT5663_STO_DRE_3: | ||
916 | case RT5663_STO_DRE_4: | ||
917 | case RT5663_STO_DRE_5: | ||
918 | case RT5663_STO_DRE_6: | ||
919 | case RT5663_STO_DRE_7: | ||
920 | case RT5663_STO_DRE_8: | ||
921 | case RT5663_STO_DRE_9: | ||
922 | case RT5663_STO_DRE_10: | ||
923 | case RT5663_MIC_DECRO_1: | ||
924 | case RT5663_MIC_DECRO_2: | ||
925 | case RT5663_MIC_DECRO_3: | ||
926 | case RT5663_MIC_DECRO_4: | ||
927 | case RT5663_MIC_DECRO_5: | ||
928 | case RT5663_MIC_DECRO_6: | ||
929 | case RT5663_HP_DECRO_1: | ||
930 | case RT5663_HP_DECRO_2: | ||
931 | case RT5663_HP_DECRO_3: | ||
932 | case RT5663_HP_DECRO_4: | ||
933 | case RT5663_HP_DECOUP: | ||
934 | case RT5663_HP_IMP_SEN_MAP8: | ||
935 | case RT5663_HP_IMP_SEN_MAP9: | ||
936 | case RT5663_HP_IMP_SEN_MAP10: | ||
937 | case RT5663_HP_IMP_SEN_MAP11: | ||
938 | case RT5663_HP_IMP_SEN_1: | ||
939 | case RT5663_HP_IMP_SEN_2: | ||
940 | case RT5663_HP_IMP_SEN_3: | ||
941 | case RT5663_HP_IMP_SEN_4: | ||
942 | case RT5663_HP_IMP_SEN_5: | ||
943 | case RT5663_HP_IMP_SEN_6: | ||
944 | case RT5663_HP_IMP_SEN_7: | ||
945 | case RT5663_HP_IMP_SEN_8: | ||
946 | case RT5663_HP_IMP_SEN_9: | ||
947 | case RT5663_HP_IMP_SEN_10: | ||
948 | case RT5663_HP_IMP_SEN_11: | ||
949 | case RT5663_HP_IMP_SEN_12: | ||
950 | case RT5663_HP_IMP_SEN_13: | ||
951 | case RT5663_HP_IMP_SEN_14: | ||
952 | case RT5663_HP_IMP_SEN_15: | ||
953 | case RT5663_HP_IMP_SEN_16: | ||
954 | case RT5663_HP_IMP_SEN_17: | ||
955 | case RT5663_HP_IMP_SEN_18: | ||
956 | case RT5663_HP_IMP_SEN_19: | ||
957 | case RT5663_HP_IMPSEN_DIG5: | ||
958 | case RT5663_HP_IMPSEN_MAP1: | ||
959 | case RT5663_HP_IMPSEN_MAP2: | ||
960 | case RT5663_HP_IMPSEN_MAP3: | ||
961 | case RT5663_HP_IMPSEN_MAP4: | ||
962 | case RT5663_HP_IMPSEN_MAP5: | ||
963 | case RT5663_HP_IMPSEN_MAP7: | ||
964 | case RT5663_HP_LOGIC_1: | ||
965 | case RT5663_HP_LOGIC_2: | ||
966 | case RT5663_HP_CALIB_1: | ||
967 | case RT5663_HP_CALIB_1_1: | ||
968 | case RT5663_HP_CALIB_2: | ||
969 | case RT5663_HP_CALIB_3: | ||
970 | case RT5663_HP_CALIB_4: | ||
971 | case RT5663_HP_CALIB_5: | ||
972 | case RT5663_HP_CALIB_5_1: | ||
973 | case RT5663_HP_CALIB_6: | ||
974 | case RT5663_HP_CALIB_7: | ||
975 | case RT5663_HP_CALIB_9: | ||
976 | case RT5663_HP_CALIB_10: | ||
977 | case RT5663_HP_CALIB_11: | ||
978 | case RT5663_HP_CALIB_ST1: | ||
979 | case RT5663_HP_CALIB_ST2: | ||
980 | case RT5663_HP_CALIB_ST3: | ||
981 | case RT5663_HP_CALIB_ST4: | ||
982 | case RT5663_HP_CALIB_ST5: | ||
983 | case RT5663_HP_CALIB_ST6: | ||
984 | case RT5663_HP_CALIB_ST7: | ||
985 | case RT5663_HP_CALIB_ST8: | ||
986 | case RT5663_HP_CALIB_ST9: | ||
987 | case RT5663_HP_AMP_DET: | ||
988 | case RT5663_DUMMY_REG_6: | ||
989 | case RT5663_HP_BIAS: | ||
990 | case RT5663_CBJ_1: | ||
991 | case RT5663_CBJ_2: | ||
992 | case RT5663_CBJ_3: | ||
993 | case RT5663_DUMMY_1: | ||
994 | case RT5663_DUMMY_2: | ||
995 | case RT5663_DUMMY_3: | ||
996 | case RT5663_ANA_JD: | ||
997 | case RT5663_ADC_LCH_LPF1_A1: | ||
998 | case RT5663_ADC_RCH_LPF1_A1: | ||
999 | case RT5663_ADC_LCH_LPF1_H0: | ||
1000 | case RT5663_ADC_RCH_LPF1_H0: | ||
1001 | case RT5663_ADC_LCH_BPF1_A1: | ||
1002 | case RT5663_ADC_RCH_BPF1_A1: | ||
1003 | case RT5663_ADC_LCH_BPF1_A2: | ||
1004 | case RT5663_ADC_RCH_BPF1_A2: | ||
1005 | case RT5663_ADC_LCH_BPF1_H0: | ||
1006 | case RT5663_ADC_RCH_BPF1_H0: | ||
1007 | case RT5663_ADC_LCH_BPF2_A1: | ||
1008 | case RT5663_ADC_RCH_BPF2_A1: | ||
1009 | case RT5663_ADC_LCH_BPF2_A2: | ||
1010 | case RT5663_ADC_RCH_BPF2_A2: | ||
1011 | case RT5663_ADC_LCH_BPF2_H0: | ||
1012 | case RT5663_ADC_RCH_BPF2_H0: | ||
1013 | case RT5663_ADC_LCH_BPF3_A1: | ||
1014 | case RT5663_ADC_RCH_BPF3_A1: | ||
1015 | case RT5663_ADC_LCH_BPF3_A2: | ||
1016 | case RT5663_ADC_RCH_BPF3_A2: | ||
1017 | case RT5663_ADC_LCH_BPF3_H0: | ||
1018 | case RT5663_ADC_RCH_BPF3_H0: | ||
1019 | case RT5663_ADC_LCH_BPF4_A1: | ||
1020 | case RT5663_ADC_RCH_BPF4_A1: | ||
1021 | case RT5663_ADC_LCH_BPF4_A2: | ||
1022 | case RT5663_ADC_RCH_BPF4_A2: | ||
1023 | case RT5663_ADC_LCH_BPF4_H0: | ||
1024 | case RT5663_ADC_RCH_BPF4_H0: | ||
1025 | case RT5663_ADC_LCH_HPF1_A1: | ||
1026 | case RT5663_ADC_RCH_HPF1_A1: | ||
1027 | case RT5663_ADC_LCH_HPF1_H0: | ||
1028 | case RT5663_ADC_RCH_HPF1_H0: | ||
1029 | case RT5663_ADC_EQ_PRE_VOL_L: | ||
1030 | case RT5663_ADC_EQ_PRE_VOL_R: | ||
1031 | case RT5663_ADC_EQ_POST_VOL_L: | ||
1032 | case RT5663_ADC_EQ_POST_VOL_R: | ||
1033 | return true; | ||
1034 | default: | ||
1035 | return false; | ||
1036 | } | ||
1037 | } | ||
1038 | |||
1039 | static bool rt5668_volatile_register(struct device *dev, unsigned int reg) | ||
1040 | { | ||
1041 | switch (reg) { | ||
1042 | case RT5663_RESET: | ||
1043 | case RT5668_CBJ_TYPE_2: | ||
1044 | case RT5668_PDM_OUT_CTL: | ||
1045 | case RT5668_PDM_I2C_DATA_CTL1: | ||
1046 | case RT5668_PDM_I2C_DATA_CTL4: | ||
1047 | case RT5668_ALC_BK_GAIN: | ||
1048 | case RT5663_PLL_2: | ||
1049 | case RT5663_MICBIAS_1: | ||
1050 | case RT5663_ADC_EQ_1: | ||
1051 | case RT5663_INT_ST_1: | ||
1052 | case RT5668_GPIO_STA: | ||
1053 | case RT5663_IL_CMD_1: | ||
1054 | case RT5663_IL_CMD_5: | ||
1055 | case RT5668_A_JD_CTRL: | ||
1056 | case RT5663_JD_CTRL2: | ||
1057 | case RT5663_VENDOR_ID: | ||
1058 | case RT5663_VENDOR_ID_1: | ||
1059 | case RT5663_VENDOR_ID_2: | ||
1060 | case RT5663_STO_DRE_1: | ||
1061 | case RT5663_STO_DRE_5: | ||
1062 | case RT5663_STO_DRE_6: | ||
1063 | case RT5663_STO_DRE_7: | ||
1064 | case RT5668_MONO_DYNA_6: | ||
1065 | case RT5668_STO1_SIL_DET: | ||
1066 | case RT5668_MONOL_SIL_DET: | ||
1067 | case RT5668_MONOR_SIL_DET: | ||
1068 | case RT5668_STO2_DAC_SIL: | ||
1069 | case RT5668_MONO_AMP_CAL_ST1: | ||
1070 | case RT5668_MONO_AMP_CAL_ST2: | ||
1071 | case RT5668_MONO_AMP_CAL_ST3: | ||
1072 | case RT5668_MONO_AMP_CAL_ST4: | ||
1073 | case RT5663_HP_IMP_SEN_2: | ||
1074 | case RT5663_HP_IMP_SEN_3: | ||
1075 | case RT5663_HP_IMP_SEN_4: | ||
1076 | case RT5663_HP_IMP_SEN_10: | ||
1077 | case RT5663_HP_CALIB_1: | ||
1078 | case RT5663_HP_CALIB_10: | ||
1079 | case RT5663_HP_CALIB_ST1: | ||
1080 | case RT5663_HP_CALIB_ST4: | ||
1081 | case RT5663_HP_CALIB_ST5: | ||
1082 | case RT5663_HP_CALIB_ST6: | ||
1083 | case RT5663_HP_CALIB_ST7: | ||
1084 | case RT5663_HP_CALIB_ST8: | ||
1085 | case RT5663_HP_CALIB_ST9: | ||
1086 | case RT5668_HP_CALIB_ST10: | ||
1087 | case RT5668_HP_CALIB_ST11: | ||
1088 | return true; | ||
1089 | default: | ||
1090 | return false; | ||
1091 | } | ||
1092 | } | ||
1093 | |||
1094 | static bool rt5668_readable_register(struct device *dev, unsigned int reg) | ||
1095 | { | ||
1096 | switch (reg) { | ||
1097 | case RT5668_LOUT_CTRL: | ||
1098 | case RT5668_HP_AMP_2: | ||
1099 | case RT5668_MONO_OUT: | ||
1100 | case RT5668_MONO_GAIN: | ||
1101 | case RT5668_AEC_BST: | ||
1102 | case RT5668_IN1_IN2: | ||
1103 | case RT5668_IN3_IN4: | ||
1104 | case RT5668_INL1_INR1: | ||
1105 | case RT5668_CBJ_TYPE_2: | ||
1106 | case RT5668_CBJ_TYPE_3: | ||
1107 | case RT5668_CBJ_TYPE_4: | ||
1108 | case RT5668_CBJ_TYPE_5: | ||
1109 | case RT5668_CBJ_TYPE_8: | ||
1110 | case RT5668_DAC3_DIG_VOL: | ||
1111 | case RT5668_DAC3_CTRL: | ||
1112 | case RT5668_MONO_ADC_DIG_VOL: | ||
1113 | case RT5668_STO2_ADC_DIG_VOL: | ||
1114 | case RT5668_MONO_ADC_BST_GAIN: | ||
1115 | case RT5668_STO2_ADC_BST_GAIN: | ||
1116 | case RT5668_SIDETONE_CTRL: | ||
1117 | case RT5668_MONO1_ADC_MIXER: | ||
1118 | case RT5668_STO2_ADC_MIXER: | ||
1119 | case RT5668_MONO_DAC_MIXER: | ||
1120 | case RT5668_DAC2_SRC_CTRL: | ||
1121 | case RT5668_IF_3_4_DATA_CTL: | ||
1122 | case RT5668_IF_5_DATA_CTL: | ||
1123 | case RT5668_PDM_OUT_CTL: | ||
1124 | case RT5668_PDM_I2C_DATA_CTL1: | ||
1125 | case RT5668_PDM_I2C_DATA_CTL2: | ||
1126 | case RT5668_PDM_I2C_DATA_CTL3: | ||
1127 | case RT5668_PDM_I2C_DATA_CTL4: | ||
1128 | case RT5668_RECMIX1_NEW: | ||
1129 | case RT5668_RECMIX1L_0: | ||
1130 | case RT5668_RECMIX1L: | ||
1131 | case RT5668_RECMIX1R_0: | ||
1132 | case RT5668_RECMIX1R: | ||
1133 | case RT5668_RECMIX2_NEW: | ||
1134 | case RT5668_RECMIX2_L_2: | ||
1135 | case RT5668_RECMIX2_R: | ||
1136 | case RT5668_RECMIX2_R_2: | ||
1137 | case RT5668_CALIB_REC_LR: | ||
1138 | case RT5668_ALC_BK_GAIN: | ||
1139 | case RT5668_MONOMIX_GAIN: | ||
1140 | case RT5668_MONOMIX_IN_GAIN: | ||
1141 | case RT5668_OUT_MIXL_GAIN: | ||
1142 | case RT5668_OUT_LMIX_IN_GAIN: | ||
1143 | case RT5668_OUT_RMIX_IN_GAIN: | ||
1144 | case RT5668_OUT_RMIX_IN_GAIN1: | ||
1145 | case RT5668_LOUT_MIXER_CTRL: | ||
1146 | case RT5668_PWR_VOL: | ||
1147 | case RT5668_ADCDAC_RST: | ||
1148 | case RT5668_I2S34_SDP: | ||
1149 | case RT5668_I2S5_SDP: | ||
1150 | case RT5668_TDM_5: | ||
1151 | case RT5668_TDM_6: | ||
1152 | case RT5668_TDM_7: | ||
1153 | case RT5668_TDM_8: | ||
1154 | case RT5668_ASRC_3: | ||
1155 | case RT5668_ASRC_6: | ||
1156 | case RT5668_ASRC_7: | ||
1157 | case RT5668_PLL_TRK_13: | ||
1158 | case RT5668_I2S_M_CLK_CTL: | ||
1159 | case RT5668_FDIV_I2S34_M_CLK: | ||
1160 | case RT5668_FDIV_I2S34_M_CLK2: | ||
1161 | case RT5668_FDIV_I2S5_M_CLK: | ||
1162 | case RT5668_FDIV_I2S5_M_CLK2: | ||
1163 | case RT5668_IRQ_4: | ||
1164 | case RT5668_GPIO_3: | ||
1165 | case RT5668_GPIO_4: | ||
1166 | case RT5668_GPIO_STA: | ||
1167 | case RT5668_HP_AMP_DET1: | ||
1168 | case RT5668_HP_AMP_DET2: | ||
1169 | case RT5668_HP_AMP_DET3: | ||
1170 | case RT5668_MID_BD_HP_AMP: | ||
1171 | case RT5668_LOW_BD_HP_AMP: | ||
1172 | case RT5668_SOF_VOL_ZC2: | ||
1173 | case RT5668_ADC_STO2_ADJ1: | ||
1174 | case RT5668_ADC_STO2_ADJ2: | ||
1175 | case RT5668_A_JD_CTRL: | ||
1176 | case RT5668_JD1_TRES_CTRL: | ||
1177 | case RT5668_JD2_TRES_CTRL: | ||
1178 | case RT5668_JD_CTRL2: | ||
1179 | case RT5668_DUM_REG_2: | ||
1180 | case RT5668_DUM_REG_3: | ||
1181 | case RT5663_VENDOR_ID: | ||
1182 | case RT5663_VENDOR_ID_1: | ||
1183 | case RT5663_VENDOR_ID_2: | ||
1184 | case RT5668_DACADC_DIG_VOL2: | ||
1185 | case RT5668_DIG_IN_PIN2: | ||
1186 | case RT5668_PAD_DRV_CTL1: | ||
1187 | case RT5668_SOF_RAM_DEPOP: | ||
1188 | case RT5668_VOL_TEST: | ||
1189 | case RT5668_TEST_MODE_3: | ||
1190 | case RT5668_TEST_MODE_4: | ||
1191 | case RT5663_STO_DRE_9: | ||
1192 | case RT5668_MONO_DYNA_1: | ||
1193 | case RT5668_MONO_DYNA_2: | ||
1194 | case RT5668_MONO_DYNA_3: | ||
1195 | case RT5668_MONO_DYNA_4: | ||
1196 | case RT5668_MONO_DYNA_5: | ||
1197 | case RT5668_MONO_DYNA_6: | ||
1198 | case RT5668_STO1_SIL_DET: | ||
1199 | case RT5668_MONOL_SIL_DET: | ||
1200 | case RT5668_MONOR_SIL_DET: | ||
1201 | case RT5668_STO2_DAC_SIL: | ||
1202 | case RT5668_PWR_SAV_CTL1: | ||
1203 | case RT5668_PWR_SAV_CTL2: | ||
1204 | case RT5668_PWR_SAV_CTL3: | ||
1205 | case RT5668_PWR_SAV_CTL4: | ||
1206 | case RT5668_PWR_SAV_CTL5: | ||
1207 | case RT5668_PWR_SAV_CTL6: | ||
1208 | case RT5668_MONO_AMP_CAL1: | ||
1209 | case RT5668_MONO_AMP_CAL2: | ||
1210 | case RT5668_MONO_AMP_CAL3: | ||
1211 | case RT5668_MONO_AMP_CAL4: | ||
1212 | case RT5668_MONO_AMP_CAL5: | ||
1213 | case RT5668_MONO_AMP_CAL6: | ||
1214 | case RT5668_MONO_AMP_CAL7: | ||
1215 | case RT5668_MONO_AMP_CAL_ST1: | ||
1216 | case RT5668_MONO_AMP_CAL_ST2: | ||
1217 | case RT5668_MONO_AMP_CAL_ST3: | ||
1218 | case RT5668_MONO_AMP_CAL_ST4: | ||
1219 | case RT5668_MONO_AMP_CAL_ST5: | ||
1220 | case RT5668_HP_IMP_SEN_13: | ||
1221 | case RT5668_HP_IMP_SEN_14: | ||
1222 | case RT5668_HP_IMP_SEN_6: | ||
1223 | case RT5668_HP_IMP_SEN_7: | ||
1224 | case RT5668_HP_IMP_SEN_8: | ||
1225 | case RT5668_HP_IMP_SEN_9: | ||
1226 | case RT5668_HP_IMP_SEN_10: | ||
1227 | case RT5668_HP_LOGIC_3: | ||
1228 | case RT5668_HP_CALIB_ST10: | ||
1229 | case RT5668_HP_CALIB_ST11: | ||
1230 | case RT5668_PRO_REG_TBL_4: | ||
1231 | case RT5668_PRO_REG_TBL_5: | ||
1232 | case RT5668_PRO_REG_TBL_6: | ||
1233 | case RT5668_PRO_REG_TBL_7: | ||
1234 | case RT5668_PRO_REG_TBL_8: | ||
1235 | case RT5668_PRO_REG_TBL_9: | ||
1236 | case RT5668_SAR_ADC_INL_1: | ||
1237 | case RT5668_SAR_ADC_INL_2: | ||
1238 | case RT5668_SAR_ADC_INL_3: | ||
1239 | case RT5668_SAR_ADC_INL_4: | ||
1240 | case RT5668_SAR_ADC_INL_5: | ||
1241 | case RT5668_SAR_ADC_INL_6: | ||
1242 | case RT5668_SAR_ADC_INL_7: | ||
1243 | case RT5668_SAR_ADC_INL_8: | ||
1244 | case RT5668_SAR_ADC_INL_9: | ||
1245 | case RT5668_SAR_ADC_INL_10: | ||
1246 | case RT5668_SAR_ADC_INL_11: | ||
1247 | case RT5668_SAR_ADC_INL_12: | ||
1248 | case RT5668_DRC_CTRL_1: | ||
1249 | case RT5668_DRC1_CTRL_2: | ||
1250 | case RT5668_DRC1_CTRL_3: | ||
1251 | case RT5668_DRC1_CTRL_4: | ||
1252 | case RT5668_DRC1_CTRL_5: | ||
1253 | case RT5668_DRC1_CTRL_6: | ||
1254 | case RT5668_DRC1_HD_CTRL_1: | ||
1255 | case RT5668_DRC1_HD_CTRL_2: | ||
1256 | case RT5668_DRC1_PRI_REG_1: | ||
1257 | case RT5668_DRC1_PRI_REG_2: | ||
1258 | case RT5668_DRC1_PRI_REG_3: | ||
1259 | case RT5668_DRC1_PRI_REG_4: | ||
1260 | case RT5668_DRC1_PRI_REG_5: | ||
1261 | case RT5668_DRC1_PRI_REG_6: | ||
1262 | case RT5668_DRC1_PRI_REG_7: | ||
1263 | case RT5668_DRC1_PRI_REG_8: | ||
1264 | case RT5668_ALC_PGA_CTL_1: | ||
1265 | case RT5668_ALC_PGA_CTL_2: | ||
1266 | case RT5668_ALC_PGA_CTL_3: | ||
1267 | case RT5668_ALC_PGA_CTL_4: | ||
1268 | case RT5668_ALC_PGA_CTL_5: | ||
1269 | case RT5668_ALC_PGA_CTL_6: | ||
1270 | case RT5668_ALC_PGA_CTL_7: | ||
1271 | case RT5668_ALC_PGA_CTL_8: | ||
1272 | case RT5668_ALC_PGA_REG_1: | ||
1273 | case RT5668_ALC_PGA_REG_2: | ||
1274 | case RT5668_ALC_PGA_REG_3: | ||
1275 | case RT5668_ADC_EQ_RECOV_1: | ||
1276 | case RT5668_ADC_EQ_RECOV_2: | ||
1277 | case RT5668_ADC_EQ_RECOV_3: | ||
1278 | case RT5668_ADC_EQ_RECOV_4: | ||
1279 | case RT5668_ADC_EQ_RECOV_5: | ||
1280 | case RT5668_ADC_EQ_RECOV_6: | ||
1281 | case RT5668_ADC_EQ_RECOV_7: | ||
1282 | case RT5668_ADC_EQ_RECOV_8: | ||
1283 | case RT5668_ADC_EQ_RECOV_9: | ||
1284 | case RT5668_ADC_EQ_RECOV_10: | ||
1285 | case RT5668_ADC_EQ_RECOV_11: | ||
1286 | case RT5668_ADC_EQ_RECOV_12: | ||
1287 | case RT5668_ADC_EQ_RECOV_13: | ||
1288 | case RT5668_VID_HIDDEN: | ||
1289 | case RT5668_VID_CUSTOMER: | ||
1290 | case RT5668_SCAN_MODE: | ||
1291 | case RT5668_I2C_BYPA: | ||
1292 | return true; | ||
1293 | case RT5663_TDM_1: | ||
1294 | case RT5663_DEPOP_3: | ||
1295 | case RT5663_ASRC_11_2: | ||
1296 | case RT5663_INT_ST_2: | ||
1297 | case RT5663_GPIO_STA: | ||
1298 | case RT5663_SIN_GEN_1: | ||
1299 | case RT5663_SIN_GEN_2: | ||
1300 | case RT5663_SIN_GEN_3: | ||
1301 | case RT5663_IL_CMD_PWRSAV1: | ||
1302 | case RT5663_IL_CMD_PWRSAV2: | ||
1303 | case RT5663_EM_JACK_TYPE_1: | ||
1304 | case RT5663_EM_JACK_TYPE_2: | ||
1305 | case RT5663_EM_JACK_TYPE_3: | ||
1306 | case RT5663_EM_JACK_TYPE_4: | ||
1307 | case RT5663_FAST_OFF_MICBIAS: | ||
1308 | case RT5663_ANA_BIAS_CUR_1: | ||
1309 | case RT5663_ANA_BIAS_CUR_2: | ||
1310 | case RT5663_BIAS_CUR_9: | ||
1311 | case RT5663_DUMMY_REG_4: | ||
1312 | case RT5663_VREF_RECMIX: | ||
1313 | case RT5663_CHARGE_PUMP_1_2: | ||
1314 | case RT5663_CHARGE_PUMP_1_3: | ||
1315 | case RT5663_CHARGE_PUMP_2: | ||
1316 | case RT5663_CHOP_DAC_R: | ||
1317 | case RT5663_DUMMY_CTL_DACLR: | ||
1318 | case RT5663_DUMMY_REG_5: | ||
1319 | case RT5663_SOFT_RAMP: | ||
1320 | case RT5663_TEST_MODE_1: | ||
1321 | case RT5663_STO_DRE_10: | ||
1322 | case RT5663_MIC_DECRO_1: | ||
1323 | case RT5663_MIC_DECRO_2: | ||
1324 | case RT5663_MIC_DECRO_3: | ||
1325 | case RT5663_MIC_DECRO_4: | ||
1326 | case RT5663_MIC_DECRO_5: | ||
1327 | case RT5663_MIC_DECRO_6: | ||
1328 | case RT5663_HP_DECRO_1: | ||
1329 | case RT5663_HP_DECRO_2: | ||
1330 | case RT5663_HP_DECRO_3: | ||
1331 | case RT5663_HP_DECRO_4: | ||
1332 | case RT5663_HP_DECOUP: | ||
1333 | case RT5663_HP_IMPSEN_MAP4: | ||
1334 | case RT5663_HP_IMPSEN_MAP5: | ||
1335 | case RT5663_HP_IMPSEN_MAP7: | ||
1336 | case RT5663_HP_CALIB_1: | ||
1337 | case RT5663_CBJ_1: | ||
1338 | case RT5663_CBJ_2: | ||
1339 | case RT5663_CBJ_3: | ||
1340 | return false; | ||
1341 | default: | ||
1342 | return rt5663_readable_register(dev, reg); | ||
1343 | } | ||
1344 | } | ||
1345 | |||
1346 | static const DECLARE_TLV_DB_SCALE(rt5663_hp_vol_tlv, -2400, 150, 0); | ||
1347 | static const DECLARE_TLV_DB_SCALE(rt5668_hp_vol_tlv, -2250, 150, 0); | ||
1348 | static const DECLARE_TLV_DB_SCALE(dac_vol_tlv, -6525, 75, 0); | ||
1349 | static const DECLARE_TLV_DB_SCALE(adc_vol_tlv, -1725, 75, 0); | ||
1350 | |||
1351 | /* {0, +20, +24, +30, +35, +40, +44, +50, +52} dB */ | ||
1352 | static const DECLARE_TLV_DB_RANGE(in_bst_tlv, | ||
1353 | 0, 0, TLV_DB_SCALE_ITEM(0, 0, 0), | ||
1354 | 1, 1, TLV_DB_SCALE_ITEM(2000, 0, 0), | ||
1355 | 2, 2, TLV_DB_SCALE_ITEM(2400, 0, 0), | ||
1356 | 3, 5, TLV_DB_SCALE_ITEM(3000, 500, 0), | ||
1357 | 6, 6, TLV_DB_SCALE_ITEM(4400, 0, 0), | ||
1358 | 7, 7, TLV_DB_SCALE_ITEM(5000, 0, 0), | ||
1359 | 8, 8, TLV_DB_SCALE_ITEM(5200, 0, 0) | ||
1360 | ); | ||
1361 | |||
1362 | /* Interface data select */ | ||
1363 | static const char * const rt5663_if1_adc_data_select[] = { | ||
1364 | "L/R", "R/L", "L/L", "R/R" | ||
1365 | }; | ||
1366 | |||
1367 | static SOC_ENUM_SINGLE_DECL(rt5663_if1_adc_enum, RT5663_TDM_2, | ||
1368 | RT5663_DATA_SWAP_ADCDAT1_SHIFT, rt5663_if1_adc_data_select); | ||
1369 | |||
1370 | static void rt5663_enable_push_button_irq(struct snd_soc_codec *codec, | ||
1371 | bool enable) | ||
1372 | { | ||
1373 | struct rt5663_priv *rt5663 = snd_soc_codec_get_drvdata(codec); | ||
1374 | |||
1375 | if (enable) { | ||
1376 | snd_soc_update_bits(codec, RT5663_IL_CMD_6, | ||
1377 | RT5668_EN_4BTN_INL_MASK, RT5668_EN_4BTN_INL_EN); | ||
1378 | /* reset in-line command */ | ||
1379 | snd_soc_update_bits(codec, RT5663_IL_CMD_6, | ||
1380 | RT5668_RESET_4BTN_INL_MASK, | ||
1381 | RT5668_RESET_4BTN_INL_RESET); | ||
1382 | snd_soc_update_bits(codec, RT5663_IL_CMD_6, | ||
1383 | RT5668_RESET_4BTN_INL_MASK, | ||
1384 | RT5668_RESET_4BTN_INL_NOR); | ||
1385 | switch (rt5663->codec_type) { | ||
1386 | case CODEC_TYPE_RT5668: | ||
1387 | snd_soc_update_bits(codec, RT5663_IRQ_3, | ||
1388 | RT5668_EN_IRQ_INLINE_MASK, | ||
1389 | RT5668_EN_IRQ_INLINE_NOR); | ||
1390 | break; | ||
1391 | case CODEC_TYPE_RT5663: | ||
1392 | snd_soc_update_bits(codec, RT5663_IRQ_2, | ||
1393 | RT5663_EN_IRQ_INLINE_MASK, | ||
1394 | RT5663_EN_IRQ_INLINE_NOR); | ||
1395 | break; | ||
1396 | default: | ||
1397 | dev_err(codec->dev, "Unknown CODEC_TYPE\n"); | ||
1398 | } | ||
1399 | } else { | ||
1400 | switch (rt5663->codec_type) { | ||
1401 | case CODEC_TYPE_RT5668: | ||
1402 | snd_soc_update_bits(codec, RT5663_IRQ_3, | ||
1403 | RT5668_EN_IRQ_INLINE_MASK, | ||
1404 | RT5668_EN_IRQ_INLINE_BYP); | ||
1405 | break; | ||
1406 | case CODEC_TYPE_RT5663: | ||
1407 | snd_soc_update_bits(codec, RT5663_IRQ_2, | ||
1408 | RT5663_EN_IRQ_INLINE_MASK, | ||
1409 | RT5663_EN_IRQ_INLINE_BYP); | ||
1410 | break; | ||
1411 | default: | ||
1412 | dev_err(codec->dev, "Unknown CODEC_TYPE\n"); | ||
1413 | } | ||
1414 | snd_soc_update_bits(codec, RT5663_IL_CMD_6, | ||
1415 | RT5668_EN_4BTN_INL_MASK, RT5668_EN_4BTN_INL_DIS); | ||
1416 | /* reset in-line command */ | ||
1417 | snd_soc_update_bits(codec, RT5663_IL_CMD_6, | ||
1418 | RT5668_RESET_4BTN_INL_MASK, | ||
1419 | RT5668_RESET_4BTN_INL_RESET); | ||
1420 | snd_soc_update_bits(codec, RT5663_IL_CMD_6, | ||
1421 | RT5668_RESET_4BTN_INL_MASK, | ||
1422 | RT5668_RESET_4BTN_INL_NOR); | ||
1423 | } | ||
1424 | } | ||
1425 | |||
1426 | /** | ||
1427 | * rt5668_jack_detect - Detect headset. | ||
1428 | * @codec: SoC audio codec device. | ||
1429 | * @jack_insert: Jack insert or not. | ||
1430 | * | ||
1431 | * Detect whether is headset or not when jack inserted. | ||
1432 | * | ||
1433 | * Returns detect status. | ||
1434 | */ | ||
1435 | |||
1436 | static int rt5668_jack_detect(struct snd_soc_codec *codec, int jack_insert) | ||
1437 | { | ||
1438 | struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec); | ||
1439 | struct rt5663_priv *rt5668 = snd_soc_codec_get_drvdata(codec); | ||
1440 | int val, i = 0, sleep_time[5] = {300, 150, 100, 50, 30}; | ||
1441 | |||
1442 | dev_dbg(codec->dev, "%s jack_insert:%d\n", __func__, jack_insert); | ||
1443 | if (jack_insert) { | ||
1444 | snd_soc_write(codec, RT5668_CBJ_TYPE_2, 0x8040); | ||
1445 | snd_soc_write(codec, RT5668_CBJ_TYPE_3, 0x1484); | ||
1446 | |||
1447 | snd_soc_dapm_force_enable_pin(dapm, "MICBIAS1"); | ||
1448 | snd_soc_dapm_force_enable_pin(dapm, "MICBIAS2"); | ||
1449 | snd_soc_dapm_force_enable_pin(dapm, "Mic Det Power"); | ||
1450 | snd_soc_dapm_force_enable_pin(dapm, "CBJ Power"); | ||
1451 | snd_soc_dapm_sync(dapm); | ||
1452 | snd_soc_update_bits(codec, RT5663_RC_CLK, | ||
1453 | RT5668_DIG_1M_CLK_MASK, RT5668_DIG_1M_CLK_EN); | ||
1454 | snd_soc_update_bits(codec, RT5663_RECMIX, 0x8, 0x8); | ||
1455 | |||
1456 | while (i < 5) { | ||
1457 | msleep(sleep_time[i]); | ||
1458 | val = snd_soc_read(codec, RT5668_CBJ_TYPE_2) & 0x0003; | ||
1459 | if (val == 0x1 || val == 0x2 || val == 0x3) | ||
1460 | break; | ||
1461 | dev_dbg(codec->dev, "%s: MX-0011 val=%x sleep %d\n", | ||
1462 | __func__, val, sleep_time[i]); | ||
1463 | i++; | ||
1464 | } | ||
1465 | dev_dbg(codec->dev, "%s val = %d\n", __func__, val); | ||
1466 | switch (val) { | ||
1467 | case 1: | ||
1468 | case 2: | ||
1469 | rt5668->jack_type = SND_JACK_HEADSET; | ||
1470 | rt5663_enable_push_button_irq(codec, true); | ||
1471 | break; | ||
1472 | default: | ||
1473 | snd_soc_dapm_disable_pin(dapm, "MICBIAS1"); | ||
1474 | snd_soc_dapm_disable_pin(dapm, "MICBIAS2"); | ||
1475 | snd_soc_dapm_disable_pin(dapm, "Mic Det Power"); | ||
1476 | snd_soc_dapm_disable_pin(dapm, "CBJ Power"); | ||
1477 | snd_soc_dapm_sync(dapm); | ||
1478 | rt5668->jack_type = SND_JACK_HEADPHONE; | ||
1479 | break; | ||
1480 | } | ||
1481 | } else { | ||
1482 | snd_soc_update_bits(codec, RT5663_RECMIX, 0x8, 0x0); | ||
1483 | |||
1484 | if (rt5668->jack_type == SND_JACK_HEADSET) { | ||
1485 | rt5663_enable_push_button_irq(codec, false); | ||
1486 | snd_soc_dapm_disable_pin(dapm, "MICBIAS1"); | ||
1487 | snd_soc_dapm_disable_pin(dapm, "MICBIAS2"); | ||
1488 | snd_soc_dapm_disable_pin(dapm, "Mic Det Power"); | ||
1489 | snd_soc_dapm_disable_pin(dapm, "CBJ Power"); | ||
1490 | snd_soc_dapm_sync(dapm); | ||
1491 | } | ||
1492 | rt5668->jack_type = 0; | ||
1493 | } | ||
1494 | |||
1495 | dev_dbg(codec->dev, "jack_type = %d\n", rt5668->jack_type); | ||
1496 | return rt5668->jack_type; | ||
1497 | } | ||
1498 | |||
1499 | /** | ||
1500 | * rt5663_jack_detect - Detect headset. | ||
1501 | * @codec: SoC audio codec device. | ||
1502 | * @jack_insert: Jack insert or not. | ||
1503 | * | ||
1504 | * Detect whether is headset or not when jack inserted. | ||
1505 | * | ||
1506 | * Returns detect status. | ||
1507 | */ | ||
1508 | static int rt5663_jack_detect(struct snd_soc_codec *codec, int jack_insert) | ||
1509 | { | ||
1510 | struct rt5663_priv *rt5663 = snd_soc_codec_get_drvdata(codec); | ||
1511 | int val, i = 0, sleep_time[5] = {300, 150, 100, 50, 30}; | ||
1512 | |||
1513 | dev_dbg(codec->dev, "%s jack_insert:%d\n", __func__, jack_insert); | ||
1514 | |||
1515 | if (jack_insert) { | ||
1516 | snd_soc_update_bits(codec, RT5663_DIG_MISC, | ||
1517 | RT5668_DIG_GATE_CTRL_MASK, RT5668_DIG_GATE_CTRL_EN); | ||
1518 | snd_soc_update_bits(codec, RT5663_HP_CHARGE_PUMP_1, | ||
1519 | RT5663_SI_HP_MASK | RT5668_OSW_HP_L_MASK | | ||
1520 | RT5668_OSW_HP_R_MASK, RT5663_SI_HP_EN | | ||
1521 | RT5668_OSW_HP_L_DIS | RT5668_OSW_HP_R_DIS); | ||
1522 | snd_soc_update_bits(codec, RT5663_DUMMY_1, | ||
1523 | RT5663_EMB_CLK_MASK | RT5663_HPA_CPL_BIAS_MASK | | ||
1524 | RT5663_HPA_CPR_BIAS_MASK, RT5663_EMB_CLK_EN | | ||
1525 | RT5663_HPA_CPL_BIAS_1 | RT5663_HPA_CPR_BIAS_1); | ||
1526 | snd_soc_update_bits(codec, RT5663_CBJ_1, | ||
1527 | RT5663_INBUF_CBJ_BST1_MASK | RT5663_CBJ_SENSE_BST1_MASK, | ||
1528 | RT5663_INBUF_CBJ_BST1_ON | RT5663_CBJ_SENSE_BST1_L); | ||
1529 | snd_soc_update_bits(codec, RT5663_IL_CMD_2, | ||
1530 | RT5663_PWR_MIC_DET_MASK, RT5663_PWR_MIC_DET_ON); | ||
1531 | /* BST1 power on for JD */ | ||
1532 | snd_soc_update_bits(codec, RT5663_PWR_ANLG_2, | ||
1533 | RT5668_PWR_BST1_MASK, RT5668_PWR_BST1_ON); | ||
1534 | snd_soc_update_bits(codec, RT5663_EM_JACK_TYPE_1, | ||
1535 | RT5663_CBJ_DET_MASK | RT5663_EXT_JD_MASK | | ||
1536 | RT5663_POL_EXT_JD_MASK, RT5663_CBJ_DET_EN | | ||
1537 | RT5663_EXT_JD_EN | RT5663_POL_EXT_JD_EN); | ||
1538 | snd_soc_update_bits(codec, RT5663_PWR_ANLG_1, | ||
1539 | RT5668_PWR_MB_MASK | RT5668_LDO1_DVO_MASK | | ||
1540 | RT5668_AMP_HP_MASK, RT5668_PWR_MB | | ||
1541 | RT5668_LDO1_DVO_0_9V | RT5668_AMP_HP_3X); | ||
1542 | snd_soc_update_bits(codec, RT5663_AUTO_1MRC_CLK, | ||
1543 | RT5668_IRQ_POW_SAV_MASK, RT5668_IRQ_POW_SAV_EN); | ||
1544 | snd_soc_update_bits(codec, RT5663_IRQ_1, | ||
1545 | RT5663_EN_IRQ_JD1_MASK, RT5663_EN_IRQ_JD1_EN); | ||
1546 | while (i < 5) { | ||
1547 | msleep(sleep_time[i]); | ||
1548 | val = snd_soc_read(codec, RT5663_EM_JACK_TYPE_2) & | ||
1549 | 0x0003; | ||
1550 | i++; | ||
1551 | if (val == 0x1 || val == 0x2 || val == 0x3) | ||
1552 | break; | ||
1553 | dev_dbg(codec->dev, "%s: MX-00e7 val=%x sleep %d\n", | ||
1554 | __func__, val, sleep_time[i]); | ||
1555 | } | ||
1556 | dev_dbg(codec->dev, "%s val = %d\n", __func__, val); | ||
1557 | switch (val) { | ||
1558 | case 1: | ||
1559 | case 2: | ||
1560 | rt5663->jack_type = SND_JACK_HEADSET; | ||
1561 | rt5663_enable_push_button_irq(codec, true); | ||
1562 | break; | ||
1563 | default: | ||
1564 | rt5663->jack_type = SND_JACK_HEADPHONE; | ||
1565 | break; | ||
1566 | } | ||
1567 | } else { | ||
1568 | if (rt5663->jack_type == SND_JACK_HEADSET) | ||
1569 | rt5663_enable_push_button_irq(codec, false); | ||
1570 | rt5663->jack_type = 0; | ||
1571 | } | ||
1572 | |||
1573 | dev_dbg(codec->dev, "jack_type = %d\n", rt5663->jack_type); | ||
1574 | return rt5663->jack_type; | ||
1575 | } | ||
1576 | |||
1577 | static int rt5663_button_detect(struct snd_soc_codec *codec) | ||
1578 | { | ||
1579 | int btn_type, val; | ||
1580 | |||
1581 | val = snd_soc_read(codec, RT5663_IL_CMD_5); | ||
1582 | dev_dbg(codec->dev, "%s: val=0x%x\n", __func__, val); | ||
1583 | btn_type = val & 0xfff0; | ||
1584 | snd_soc_write(codec, RT5663_IL_CMD_5, val); | ||
1585 | |||
1586 | return btn_type; | ||
1587 | } | ||
1588 | |||
1589 | static irqreturn_t rt5663_irq(int irq, void *data) | ||
1590 | { | ||
1591 | struct rt5663_priv *rt5663 = data; | ||
1592 | |||
1593 | dev_dbg(rt5663->codec->dev, "%s IRQ queue work\n", __func__); | ||
1594 | |||
1595 | queue_delayed_work(system_wq, &rt5663->jack_detect_work, | ||
1596 | msecs_to_jiffies(250)); | ||
1597 | |||
1598 | return IRQ_HANDLED; | ||
1599 | } | ||
1600 | |||
1601 | int rt5663_set_jack_detect(struct snd_soc_codec *codec, | ||
1602 | struct snd_soc_jack *hs_jack) | ||
1603 | { | ||
1604 | struct rt5663_priv *rt5663 = snd_soc_codec_get_drvdata(codec); | ||
1605 | |||
1606 | rt5663->hs_jack = hs_jack; | ||
1607 | |||
1608 | rt5663_irq(0, rt5663); | ||
1609 | |||
1610 | return 0; | ||
1611 | } | ||
1612 | EXPORT_SYMBOL_GPL(rt5663_set_jack_detect); | ||
1613 | |||
1614 | static bool rt5663_check_jd_status(struct snd_soc_codec *codec) | ||
1615 | { | ||
1616 | struct rt5663_priv *rt5663 = snd_soc_codec_get_drvdata(codec); | ||
1617 | int val = snd_soc_read(codec, RT5663_INT_ST_1); | ||
1618 | |||
1619 | dev_dbg(codec->dev, "%s val=%x\n", __func__, val); | ||
1620 | |||
1621 | /* JD1 */ | ||
1622 | switch (rt5663->codec_type) { | ||
1623 | case CODEC_TYPE_RT5668: | ||
1624 | return !(val & 0x2000); | ||
1625 | case CODEC_TYPE_RT5663: | ||
1626 | return !(val & 0x1000); | ||
1627 | default: | ||
1628 | dev_err(codec->dev, "Unknown CODEC_TYPE\n"); | ||
1629 | } | ||
1630 | |||
1631 | return false; | ||
1632 | } | ||
1633 | |||
1634 | static void rt5663_jack_detect_work(struct work_struct *work) | ||
1635 | { | ||
1636 | struct rt5663_priv *rt5663 = | ||
1637 | container_of(work, struct rt5663_priv, jack_detect_work.work); | ||
1638 | struct snd_soc_codec *codec = rt5663->codec; | ||
1639 | int btn_type, report = 0; | ||
1640 | |||
1641 | if (!codec) | ||
1642 | return; | ||
1643 | |||
1644 | if (rt5663_check_jd_status(codec)) { | ||
1645 | /* jack in */ | ||
1646 | if (rt5663->jack_type == 0) { | ||
1647 | /* jack was out, report jack type */ | ||
1648 | switch (rt5663->codec_type) { | ||
1649 | case CODEC_TYPE_RT5668: | ||
1650 | report = rt5668_jack_detect(rt5663->codec, 1); | ||
1651 | break; | ||
1652 | case CODEC_TYPE_RT5663: | ||
1653 | report = rt5663_jack_detect(rt5663->codec, 1); | ||
1654 | break; | ||
1655 | default: | ||
1656 | dev_err(codec->dev, "Unknown CODEC_TYPE\n"); | ||
1657 | } | ||
1658 | } else { | ||
1659 | /* jack is already in, report button event */ | ||
1660 | report = SND_JACK_HEADSET; | ||
1661 | btn_type = rt5663_button_detect(rt5663->codec); | ||
1662 | /** | ||
1663 | * rt5663 can report three kinds of button behavior, | ||
1664 | * one click, double click and hold. However, | ||
1665 | * currently we will report button pressed/released | ||
1666 | * event. So all the three button behaviors are | ||
1667 | * treated as button pressed. | ||
1668 | */ | ||
1669 | switch (btn_type) { | ||
1670 | case 0x8000: | ||
1671 | case 0x4000: | ||
1672 | case 0x2000: | ||
1673 | report |= SND_JACK_BTN_0; | ||
1674 | break; | ||
1675 | case 0x1000: | ||
1676 | case 0x0800: | ||
1677 | case 0x0400: | ||
1678 | report |= SND_JACK_BTN_1; | ||
1679 | break; | ||
1680 | case 0x0200: | ||
1681 | case 0x0100: | ||
1682 | case 0x0080: | ||
1683 | report |= SND_JACK_BTN_2; | ||
1684 | break; | ||
1685 | case 0x0040: | ||
1686 | case 0x0020: | ||
1687 | case 0x0010: | ||
1688 | report |= SND_JACK_BTN_3; | ||
1689 | break; | ||
1690 | case 0x0000: /* unpressed */ | ||
1691 | break; | ||
1692 | default: | ||
1693 | btn_type = 0; | ||
1694 | dev_err(rt5663->codec->dev, | ||
1695 | "Unexpected button code 0x%04x\n", | ||
1696 | btn_type); | ||
1697 | break; | ||
1698 | } | ||
1699 | /* button release or spurious interrput*/ | ||
1700 | if (btn_type == 0) | ||
1701 | report = rt5663->jack_type; | ||
1702 | } | ||
1703 | } else { | ||
1704 | /* jack out */ | ||
1705 | switch (rt5663->codec_type) { | ||
1706 | case CODEC_TYPE_RT5668: | ||
1707 | report = rt5668_jack_detect(rt5663->codec, 0); | ||
1708 | break; | ||
1709 | case CODEC_TYPE_RT5663: | ||
1710 | report = rt5663_jack_detect(rt5663->codec, 0); | ||
1711 | break; | ||
1712 | default: | ||
1713 | dev_err(codec->dev, "Unknown CODEC_TYPE\n"); | ||
1714 | } | ||
1715 | } | ||
1716 | dev_dbg(codec->dev, "%s jack report: 0x%04x\n", __func__, report); | ||
1717 | snd_soc_jack_report(rt5663->hs_jack, report, SND_JACK_HEADSET | | ||
1718 | SND_JACK_BTN_0 | SND_JACK_BTN_1 | | ||
1719 | SND_JACK_BTN_2 | SND_JACK_BTN_3); | ||
1720 | } | ||
1721 | |||
1722 | static const struct snd_kcontrol_new rt5663_snd_controls[] = { | ||
1723 | /* DAC Digital Volume */ | ||
1724 | SOC_DOUBLE_TLV("DAC Playback Volume", RT5663_STO1_DAC_DIG_VOL, | ||
1725 | RT5668_DAC_L1_VOL_SHIFT + 1, RT5668_DAC_R1_VOL_SHIFT + 1, | ||
1726 | 87, 0, dac_vol_tlv), | ||
1727 | /* ADC Digital Volume Control */ | ||
1728 | SOC_DOUBLE("ADC Capture Switch", RT5663_STO1_ADC_DIG_VOL, | ||
1729 | RT5668_ADC_L_MUTE_SHIFT, RT5668_ADC_R_MUTE_SHIFT, 1, 1), | ||
1730 | SOC_DOUBLE_TLV("ADC Capture Volume", RT5663_STO1_ADC_DIG_VOL, | ||
1731 | RT5668_ADC_L_VOL_SHIFT + 1, RT5668_ADC_R_VOL_SHIFT + 1, | ||
1732 | 63, 0, adc_vol_tlv), | ||
1733 | }; | ||
1734 | |||
1735 | static const struct snd_kcontrol_new rt5668_specific_controls[] = { | ||
1736 | /* Headphone Output Volume */ | ||
1737 | SOC_DOUBLE_R_TLV("Headphone Playback Volume", RT5663_HP_LCH_DRE, | ||
1738 | RT5663_HP_RCH_DRE, RT5668_GAIN_HP_SHIFT, 15, 1, | ||
1739 | rt5668_hp_vol_tlv), | ||
1740 | /* Mic Boost Volume */ | ||
1741 | SOC_SINGLE_TLV("IN1 Capture Volume", RT5668_AEC_BST, | ||
1742 | RT5668_GAIN_CBJ_SHIFT, 8, 0, in_bst_tlv), | ||
1743 | }; | ||
1744 | |||
1745 | static const struct snd_kcontrol_new rt5663_specific_controls[] = { | ||
1746 | /* Headphone Output Volume */ | ||
1747 | SOC_DOUBLE_R_TLV("Headphone Playback Volume", RT5663_STO_DRE_9, | ||
1748 | RT5663_STO_DRE_10, RT5663_DRE_GAIN_HP_SHIFT, 23, 1, | ||
1749 | rt5663_hp_vol_tlv), | ||
1750 | /* Mic Boost Volume*/ | ||
1751 | SOC_SINGLE_TLV("IN1 Capture Volume", RT5663_CBJ_2, | ||
1752 | RT5663_GAIN_BST1_SHIFT, 8, 0, in_bst_tlv), | ||
1753 | /* Data Swap for Slot0/1 in ADCDAT1 */ | ||
1754 | SOC_ENUM("IF1 ADC Data Swap", rt5663_if1_adc_enum), | ||
1755 | }; | ||
1756 | |||
1757 | static int rt5663_is_sys_clk_from_pll(struct snd_soc_dapm_widget *w, | ||
1758 | struct snd_soc_dapm_widget *sink) | ||
1759 | { | ||
1760 | unsigned int val; | ||
1761 | struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); | ||
1762 | |||
1763 | val = snd_soc_read(codec, RT5663_GLB_CLK); | ||
1764 | val &= RT5663_SCLK_SRC_MASK; | ||
1765 | if (val == RT5663_SCLK_SRC_PLL1) | ||
1766 | return 1; | ||
1767 | else | ||
1768 | return 0; | ||
1769 | } | ||
1770 | |||
1771 | static int rt5663_is_using_asrc(struct snd_soc_dapm_widget *w, | ||
1772 | struct snd_soc_dapm_widget *sink) | ||
1773 | { | ||
1774 | unsigned int reg, shift, val; | ||
1775 | struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); | ||
1776 | struct rt5663_priv *rt5663 = snd_soc_codec_get_drvdata(codec); | ||
1777 | |||
1778 | if (rt5663->codec_type == CODEC_TYPE_RT5668) { | ||
1779 | switch (w->shift) { | ||
1780 | case RT5668_ADC_STO1_ASRC_SHIFT: | ||
1781 | reg = RT5668_ASRC_3; | ||
1782 | shift = RT5668_AD_STO1_TRACK_SHIFT; | ||
1783 | break; | ||
1784 | case RT5668_DAC_STO1_ASRC_SHIFT: | ||
1785 | reg = RT5663_ASRC_2; | ||
1786 | shift = RT5668_DA_STO1_TRACK_SHIFT; | ||
1787 | break; | ||
1788 | default: | ||
1789 | return 0; | ||
1790 | } | ||
1791 | } else { | ||
1792 | switch (w->shift) { | ||
1793 | case RT5663_ADC_STO1_ASRC_SHIFT: | ||
1794 | reg = RT5663_ASRC_2; | ||
1795 | shift = RT5663_AD_STO1_TRACK_SHIFT; | ||
1796 | break; | ||
1797 | case RT5663_DAC_STO1_ASRC_SHIFT: | ||
1798 | reg = RT5663_ASRC_2; | ||
1799 | shift = RT5663_DA_STO1_TRACK_SHIFT; | ||
1800 | break; | ||
1801 | default: | ||
1802 | return 0; | ||
1803 | } | ||
1804 | } | ||
1805 | |||
1806 | val = (snd_soc_read(codec, reg) >> shift) & 0x7; | ||
1807 | |||
1808 | if (val) | ||
1809 | return 1; | ||
1810 | |||
1811 | return 0; | ||
1812 | } | ||
1813 | |||
1814 | static int rt5663_i2s_use_asrc(struct snd_soc_dapm_widget *source, | ||
1815 | struct snd_soc_dapm_widget *sink) | ||
1816 | { | ||
1817 | struct snd_soc_codec *codec = snd_soc_dapm_to_codec(source->dapm); | ||
1818 | struct rt5663_priv *rt5663 = snd_soc_codec_get_drvdata(codec); | ||
1819 | int da_asrc_en, ad_asrc_en; | ||
1820 | |||
1821 | da_asrc_en = (snd_soc_read(codec, RT5663_ASRC_2) & | ||
1822 | RT5663_DA_STO1_TRACK_MASK) ? 1 : 0; | ||
1823 | switch (rt5663->codec_type) { | ||
1824 | case CODEC_TYPE_RT5668: | ||
1825 | ad_asrc_en = (snd_soc_read(codec, RT5668_ASRC_3) & | ||
1826 | RT5668_AD_STO1_TRACK_MASK) ? 1 : 0; | ||
1827 | break; | ||
1828 | case CODEC_TYPE_RT5663: | ||
1829 | ad_asrc_en = (snd_soc_read(codec, RT5663_ASRC_2) & | ||
1830 | RT5663_AD_STO1_TRACK_MASK) ? 1 : 0; | ||
1831 | break; | ||
1832 | default: | ||
1833 | dev_err(codec->dev, "Unknown CODEC_TYPE\n"); | ||
1834 | return 1; | ||
1835 | } | ||
1836 | |||
1837 | if (da_asrc_en || ad_asrc_en) | ||
1838 | if (rt5663->sysclk > rt5663->lrck * 384) | ||
1839 | return 1; | ||
1840 | |||
1841 | dev_err(codec->dev, "sysclk < 384 x fs, disable i2s asrc\n"); | ||
1842 | |||
1843 | return 0; | ||
1844 | } | ||
1845 | |||
1846 | /** | ||
1847 | * rt5663_sel_asrc_clk_src - select ASRC clock source for a set of filters | ||
1848 | * @codec: SoC audio codec device. | ||
1849 | * @filter_mask: mask of filters. | ||
1850 | * @clk_src: clock source | ||
1851 | * | ||
1852 | * The ASRC function is for asynchronous MCLK and LRCK. Also, since RT5668 can | ||
1853 | * only support standard 32fs or 64fs i2s format, ASRC should be enabled to | ||
1854 | * support special i2s clock format such as Intel's 100fs(100 * sampling rate). | ||
1855 | * ASRC function will track i2s clock and generate a corresponding system clock | ||
1856 | * for codec. This function provides an API to select the clock source for a | ||
1857 | * set of filters specified by the mask. And the codec driver will turn on ASRC | ||
1858 | * for these filters if ASRC is selected as their clock source. | ||
1859 | */ | ||
1860 | int rt5663_sel_asrc_clk_src(struct snd_soc_codec *codec, | ||
1861 | unsigned int filter_mask, unsigned int clk_src) | ||
1862 | { | ||
1863 | struct rt5663_priv *rt5668 = snd_soc_codec_get_drvdata(codec); | ||
1864 | unsigned int asrc2_mask = 0; | ||
1865 | unsigned int asrc2_value = 0; | ||
1866 | unsigned int asrc3_mask = 0; | ||
1867 | unsigned int asrc3_value = 0; | ||
1868 | |||
1869 | switch (clk_src) { | ||
1870 | case RT5663_CLK_SEL_SYS: | ||
1871 | case RT5663_CLK_SEL_I2S1_ASRC: | ||
1872 | break; | ||
1873 | |||
1874 | default: | ||
1875 | return -EINVAL; | ||
1876 | } | ||
1877 | |||
1878 | if (filter_mask & RT5663_DA_STEREO_FILTER) { | ||
1879 | asrc2_mask |= RT5668_DA_STO1_TRACK_MASK; | ||
1880 | asrc2_value |= clk_src << RT5668_DA_STO1_TRACK_SHIFT; | ||
1881 | } | ||
1882 | |||
1883 | if (filter_mask & RT5663_AD_STEREO_FILTER) { | ||
1884 | switch (rt5668->codec_type) { | ||
1885 | case CODEC_TYPE_RT5668: | ||
1886 | asrc3_mask |= RT5668_AD_STO1_TRACK_MASK; | ||
1887 | asrc3_value |= clk_src << RT5668_AD_STO1_TRACK_SHIFT; | ||
1888 | break; | ||
1889 | case CODEC_TYPE_RT5663: | ||
1890 | asrc2_mask |= RT5663_AD_STO1_TRACK_MASK; | ||
1891 | asrc2_value |= clk_src << RT5663_AD_STO1_TRACK_SHIFT; | ||
1892 | break; | ||
1893 | default: | ||
1894 | dev_err(codec->dev, "Unknown CODEC_TYPE\n"); | ||
1895 | } | ||
1896 | } | ||
1897 | |||
1898 | if (asrc2_mask) | ||
1899 | snd_soc_update_bits(codec, RT5663_ASRC_2, asrc2_mask, | ||
1900 | asrc2_value); | ||
1901 | |||
1902 | if (asrc3_mask) | ||
1903 | snd_soc_update_bits(codec, RT5668_ASRC_3, asrc3_mask, | ||
1904 | asrc3_value); | ||
1905 | |||
1906 | return 0; | ||
1907 | } | ||
1908 | EXPORT_SYMBOL_GPL(rt5663_sel_asrc_clk_src); | ||
1909 | |||
1910 | /* Analog Mixer */ | ||
1911 | static const struct snd_kcontrol_new rt5668_recmix1l[] = { | ||
1912 | SOC_DAPM_SINGLE("BST2 Switch", RT5668_RECMIX1L, | ||
1913 | RT5668_RECMIX1L_BST2_SHIFT, 1, 1), | ||
1914 | SOC_DAPM_SINGLE("BST1 CBJ Switch", RT5668_RECMIX1L, | ||
1915 | RT5668_RECMIX1L_BST1_CBJ_SHIFT, 1, 1), | ||
1916 | }; | ||
1917 | |||
1918 | static const struct snd_kcontrol_new rt5668_recmix1r[] = { | ||
1919 | SOC_DAPM_SINGLE("BST2 Switch", RT5668_RECMIX1R, | ||
1920 | RT5668_RECMIX1R_BST2_SHIFT, 1, 1), | ||
1921 | }; | ||
1922 | |||
1923 | /* Digital Mixer */ | ||
1924 | static const struct snd_kcontrol_new rt5663_sto1_adc_l_mix[] = { | ||
1925 | SOC_DAPM_SINGLE("ADC1 Switch", RT5663_STO1_ADC_MIXER, | ||
1926 | RT5668_M_STO1_ADC_L1_SHIFT, 1, 1), | ||
1927 | SOC_DAPM_SINGLE("ADC2 Switch", RT5663_STO1_ADC_MIXER, | ||
1928 | RT5668_M_STO1_ADC_L2_SHIFT, 1, 1), | ||
1929 | }; | ||
1930 | |||
1931 | static const struct snd_kcontrol_new rt5668_sto1_adc_r_mix[] = { | ||
1932 | SOC_DAPM_SINGLE("ADC1 Switch", RT5663_STO1_ADC_MIXER, | ||
1933 | RT5668_M_STO1_ADC_R1_SHIFT, 1, 1), | ||
1934 | SOC_DAPM_SINGLE("ADC2 Switch", RT5663_STO1_ADC_MIXER, | ||
1935 | RT5668_M_STO1_ADC_R2_SHIFT, 1, 1), | ||
1936 | }; | ||
1937 | |||
1938 | static const struct snd_kcontrol_new rt5663_adda_l_mix[] = { | ||
1939 | SOC_DAPM_SINGLE("ADC L Switch", RT5663_AD_DA_MIXER, | ||
1940 | RT5668_M_ADCMIX_L_SHIFT, 1, 1), | ||
1941 | SOC_DAPM_SINGLE("DAC L Switch", RT5663_AD_DA_MIXER, | ||
1942 | RT5668_M_DAC1_L_SHIFT, 1, 1), | ||
1943 | }; | ||
1944 | |||
1945 | static const struct snd_kcontrol_new rt5663_adda_r_mix[] = { | ||
1946 | SOC_DAPM_SINGLE("ADC R Switch", RT5663_AD_DA_MIXER, | ||
1947 | RT5668_M_ADCMIX_R_SHIFT, 1, 1), | ||
1948 | SOC_DAPM_SINGLE("DAC R Switch", RT5663_AD_DA_MIXER, | ||
1949 | RT5668_M_DAC1_R_SHIFT, 1, 1), | ||
1950 | }; | ||
1951 | |||
1952 | static const struct snd_kcontrol_new rt5663_sto1_dac_l_mix[] = { | ||
1953 | SOC_DAPM_SINGLE("DAC L Switch", RT5663_STO_DAC_MIXER, | ||
1954 | RT5668_M_DAC_L1_STO_L_SHIFT, 1, 1), | ||
1955 | SOC_DAPM_SINGLE("DAC R Switch", RT5663_STO_DAC_MIXER, | ||
1956 | RT5668_M_DAC_R1_STO_L_SHIFT, 1, 1), | ||
1957 | }; | ||
1958 | |||
1959 | static const struct snd_kcontrol_new rt5663_sto1_dac_r_mix[] = { | ||
1960 | SOC_DAPM_SINGLE("DAC L Switch", RT5663_STO_DAC_MIXER, | ||
1961 | RT5668_M_DAC_L1_STO_R_SHIFT, 1, 1), | ||
1962 | SOC_DAPM_SINGLE("DAC R Switch", RT5663_STO_DAC_MIXER, | ||
1963 | RT5668_M_DAC_R1_STO_R_SHIFT, 1, 1), | ||
1964 | }; | ||
1965 | |||
1966 | /* Out Switch */ | ||
1967 | static const struct snd_kcontrol_new rt5668_hpo_switch = | ||
1968 | SOC_DAPM_SINGLE_AUTODISABLE("Switch", RT5668_HP_AMP_2, | ||
1969 | RT5668_EN_DAC_HPO_SHIFT, 1, 0); | ||
1970 | |||
1971 | /* Stereo ADC source */ | ||
1972 | static const char * const rt5668_sto1_adc_src[] = { | ||
1973 | "ADC L", "ADC R" | ||
1974 | }; | ||
1975 | |||
1976 | static SOC_ENUM_SINGLE_DECL(rt5668_sto1_adcl_enum, RT5663_STO1_ADC_MIXER, | ||
1977 | RT5668_STO1_ADC_L_SRC_SHIFT, rt5668_sto1_adc_src); | ||
1978 | |||
1979 | static const struct snd_kcontrol_new rt5668_sto1_adcl_mux = | ||
1980 | SOC_DAPM_ENUM("STO1 ADC L Mux", rt5668_sto1_adcl_enum); | ||
1981 | |||
1982 | static SOC_ENUM_SINGLE_DECL(rt5668_sto1_adcr_enum, RT5663_STO1_ADC_MIXER, | ||
1983 | RT5668_STO1_ADC_R_SRC_SHIFT, rt5668_sto1_adc_src); | ||
1984 | |||
1985 | static const struct snd_kcontrol_new rt5668_sto1_adcr_mux = | ||
1986 | SOC_DAPM_ENUM("STO1 ADC R Mux", rt5668_sto1_adcr_enum); | ||
1987 | |||
1988 | /* RT5663: Analog DACL1 input source */ | ||
1989 | static const char * const rt5663_alg_dacl_src[] = { | ||
1990 | "DAC L", "STO DAC MIXL" | ||
1991 | }; | ||
1992 | |||
1993 | static SOC_ENUM_SINGLE_DECL(rt5663_alg_dacl_enum, RT5663_BYPASS_STO_DAC, | ||
1994 | RT5663_DACL1_SRC_SHIFT, rt5663_alg_dacl_src); | ||
1995 | |||
1996 | static const struct snd_kcontrol_new rt5663_alg_dacl_mux = | ||
1997 | SOC_DAPM_ENUM("DAC L Mux", rt5663_alg_dacl_enum); | ||
1998 | |||
1999 | /* RT5663: Analog DACR1 input source */ | ||
2000 | static const char * const rt5663_alg_dacr_src[] = { | ||
2001 | "DAC R", "STO DAC MIXR" | ||
2002 | }; | ||
2003 | |||
2004 | static SOC_ENUM_SINGLE_DECL(rt5663_alg_dacr_enum, RT5663_BYPASS_STO_DAC, | ||
2005 | RT5663_DACR1_SRC_SHIFT, rt5663_alg_dacr_src); | ||
2006 | |||
2007 | static const struct snd_kcontrol_new rt5663_alg_dacr_mux = | ||
2008 | SOC_DAPM_ENUM("DAC R Mux", rt5663_alg_dacr_enum); | ||
2009 | |||
2010 | static int rt5663_hp_event(struct snd_soc_dapm_widget *w, | ||
2011 | struct snd_kcontrol *kcontrol, int event) | ||
2012 | { | ||
2013 | struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); | ||
2014 | struct rt5663_priv *rt5663 = snd_soc_codec_get_drvdata(codec); | ||
2015 | |||
2016 | switch (event) { | ||
2017 | case SND_SOC_DAPM_POST_PMU: | ||
2018 | if (rt5663->codec_type == CODEC_TYPE_RT5668) { | ||
2019 | snd_soc_update_bits(codec, RT5663_HP_CHARGE_PUMP_1, | ||
2020 | RT5668_SEL_PM_HP_SHIFT, RT5668_SEL_PM_HP_HIGH); | ||
2021 | snd_soc_update_bits(codec, RT5663_HP_LOGIC_2, | ||
2022 | RT5668_HP_SIG_SRC1_MASK, | ||
2023 | RT5668_HP_SIG_SRC1_SILENCE); | ||
2024 | } else { | ||
2025 | snd_soc_write(codec, RT5663_DEPOP_2, 0x3003); | ||
2026 | snd_soc_update_bits(codec, RT5663_DEPOP_1, 0x000b, | ||
2027 | 0x000b); | ||
2028 | snd_soc_update_bits(codec, RT5663_DEPOP_1, 0x0030, | ||
2029 | 0x0030); | ||
2030 | snd_soc_update_bits(codec, RT5663_HP_CHARGE_PUMP_1, | ||
2031 | RT5668_OVCD_HP_MASK, RT5668_OVCD_HP_DIS); | ||
2032 | snd_soc_write(codec, RT5663_HP_CHARGE_PUMP_2, 0x1371); | ||
2033 | snd_soc_write(codec, RT5663_HP_BIAS, 0xabba); | ||
2034 | snd_soc_write(codec, RT5663_CHARGE_PUMP_1, 0x2224); | ||
2035 | snd_soc_write(codec, RT5663_ANA_BIAS_CUR_1, 0x7766); | ||
2036 | snd_soc_write(codec, RT5663_HP_BIAS, 0xafaa); | ||
2037 | snd_soc_write(codec, RT5663_CHARGE_PUMP_2, 0x7777); | ||
2038 | snd_soc_update_bits(codec, RT5663_DEPOP_1, 0x3000, | ||
2039 | 0x3000); | ||
2040 | } | ||
2041 | break; | ||
2042 | |||
2043 | case SND_SOC_DAPM_PRE_PMD: | ||
2044 | if (rt5663->codec_type == CODEC_TYPE_RT5668) { | ||
2045 | snd_soc_update_bits(codec, RT5663_HP_LOGIC_2, | ||
2046 | RT5668_HP_SIG_SRC1_MASK, | ||
2047 | RT5668_HP_SIG_SRC1_REG); | ||
2048 | } else { | ||
2049 | snd_soc_update_bits(codec, RT5663_DEPOP_1, 0x3000, 0x0); | ||
2050 | snd_soc_update_bits(codec, RT5663_HP_CHARGE_PUMP_1, | ||
2051 | RT5668_OVCD_HP_MASK, RT5668_OVCD_HP_EN); | ||
2052 | snd_soc_update_bits(codec, RT5663_DEPOP_1, 0x0030, 0x0); | ||
2053 | snd_soc_update_bits(codec, RT5663_DEPOP_1, 0x000b, | ||
2054 | 0x000b); | ||
2055 | } | ||
2056 | break; | ||
2057 | |||
2058 | default: | ||
2059 | return 0; | ||
2060 | } | ||
2061 | |||
2062 | return 0; | ||
2063 | } | ||
2064 | |||
2065 | static int rt5668_bst2_power(struct snd_soc_dapm_widget *w, | ||
2066 | struct snd_kcontrol *kcontrol, int event) | ||
2067 | { | ||
2068 | struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); | ||
2069 | |||
2070 | switch (event) { | ||
2071 | case SND_SOC_DAPM_POST_PMU: | ||
2072 | snd_soc_update_bits(codec, RT5663_PWR_ANLG_2, | ||
2073 | RT5668_PWR_BST2_MASK | RT5668_PWR_BST2_OP_MASK, | ||
2074 | RT5668_PWR_BST2 | RT5668_PWR_BST2_OP); | ||
2075 | break; | ||
2076 | |||
2077 | case SND_SOC_DAPM_PRE_PMD: | ||
2078 | snd_soc_update_bits(codec, RT5663_PWR_ANLG_2, | ||
2079 | RT5668_PWR_BST2_MASK | RT5668_PWR_BST2_OP_MASK, 0); | ||
2080 | break; | ||
2081 | |||
2082 | default: | ||
2083 | return 0; | ||
2084 | } | ||
2085 | |||
2086 | return 0; | ||
2087 | } | ||
2088 | |||
2089 | static int rt5663_pre_div_power(struct snd_soc_dapm_widget *w, | ||
2090 | struct snd_kcontrol *kcontrol, int event) | ||
2091 | { | ||
2092 | struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); | ||
2093 | |||
2094 | switch (event) { | ||
2095 | case SND_SOC_DAPM_POST_PMU: | ||
2096 | snd_soc_write(codec, RT5663_PRE_DIV_GATING_1, 0xff00); | ||
2097 | snd_soc_write(codec, RT5663_PRE_DIV_GATING_2, 0xfffc); | ||
2098 | break; | ||
2099 | |||
2100 | case SND_SOC_DAPM_PRE_PMD: | ||
2101 | snd_soc_write(codec, RT5663_PRE_DIV_GATING_1, 0x0000); | ||
2102 | snd_soc_write(codec, RT5663_PRE_DIV_GATING_2, 0x0000); | ||
2103 | break; | ||
2104 | |||
2105 | default: | ||
2106 | return 0; | ||
2107 | } | ||
2108 | |||
2109 | return 0; | ||
2110 | } | ||
2111 | |||
2112 | static const struct snd_soc_dapm_widget rt5663_dapm_widgets[] = { | ||
2113 | SND_SOC_DAPM_SUPPLY("PLL", RT5663_PWR_ANLG_3, RT5668_PWR_PLL_SHIFT, 0, | ||
2114 | NULL, 0), | ||
2115 | |||
2116 | /* micbias */ | ||
2117 | SND_SOC_DAPM_MICBIAS("MICBIAS1", RT5663_PWR_ANLG_2, | ||
2118 | RT5668_PWR_MB1_SHIFT, 0), | ||
2119 | SND_SOC_DAPM_MICBIAS("MICBIAS2", RT5663_PWR_ANLG_2, | ||
2120 | RT5668_PWR_MB2_SHIFT, 0), | ||
2121 | |||
2122 | /* Input Lines */ | ||
2123 | SND_SOC_DAPM_INPUT("IN1P"), | ||
2124 | SND_SOC_DAPM_INPUT("IN1N"), | ||
2125 | |||
2126 | /* REC Mixer Power */ | ||
2127 | SND_SOC_DAPM_SUPPLY("RECMIX1L Power", RT5663_PWR_ANLG_2, | ||
2128 | RT5668_PWR_RECMIX1_SHIFT, 0, NULL, 0), | ||
2129 | |||
2130 | /* ADCs */ | ||
2131 | SND_SOC_DAPM_ADC("ADC L", NULL, SND_SOC_NOPM, 0, 0), | ||
2132 | SND_SOC_DAPM_SUPPLY("ADC L Power", RT5663_PWR_DIG_1, | ||
2133 | RT5668_PWR_ADC_L1_SHIFT, 0, NULL, 0), | ||
2134 | SND_SOC_DAPM_SUPPLY("ADC Clock", RT5663_CHOP_ADC, | ||
2135 | RT5668_CKGEN_ADCC_SHIFT, 0, NULL, 0), | ||
2136 | |||
2137 | /* ADC Mixer */ | ||
2138 | SND_SOC_DAPM_MIXER("STO1 ADC MIXL", SND_SOC_NOPM, | ||
2139 | 0, 0, rt5663_sto1_adc_l_mix, | ||
2140 | ARRAY_SIZE(rt5663_sto1_adc_l_mix)), | ||
2141 | |||
2142 | /* ADC Filter Power */ | ||
2143 | SND_SOC_DAPM_SUPPLY("STO1 ADC Filter", RT5663_PWR_DIG_2, | ||
2144 | RT5668_PWR_ADC_S1F_SHIFT, 0, NULL, 0), | ||
2145 | |||
2146 | /* Digital Interface */ | ||
2147 | SND_SOC_DAPM_SUPPLY("I2S", RT5663_PWR_DIG_1, RT5668_PWR_I2S1_SHIFT, 0, | ||
2148 | NULL, 0), | ||
2149 | SND_SOC_DAPM_PGA("IF DAC", SND_SOC_NOPM, 0, 0, NULL, 0), | ||
2150 | SND_SOC_DAPM_PGA("IF1 DAC1 L", SND_SOC_NOPM, 0, 0, NULL, 0), | ||
2151 | SND_SOC_DAPM_PGA("IF1 DAC1 R", SND_SOC_NOPM, 0, 0, NULL, 0), | ||
2152 | SND_SOC_DAPM_PGA("IF1 ADC1", SND_SOC_NOPM, 0, 0, NULL, 0), | ||
2153 | SND_SOC_DAPM_PGA("IF ADC", SND_SOC_NOPM, 0, 0, NULL, 0), | ||
2154 | |||
2155 | /* Audio Interface */ | ||
2156 | SND_SOC_DAPM_AIF_IN("AIFRX", "AIF Playback", 0, SND_SOC_NOPM, 0, 0), | ||
2157 | SND_SOC_DAPM_AIF_OUT("AIFTX", "AIF Capture", 0, SND_SOC_NOPM, 0, 0), | ||
2158 | |||
2159 | /* DAC mixer before sound effect */ | ||
2160 | SND_SOC_DAPM_MIXER("ADDA MIXL", SND_SOC_NOPM, 0, 0, rt5663_adda_l_mix, | ||
2161 | ARRAY_SIZE(rt5663_adda_l_mix)), | ||
2162 | SND_SOC_DAPM_MIXER("ADDA MIXR", SND_SOC_NOPM, 0, 0, rt5663_adda_r_mix, | ||
2163 | ARRAY_SIZE(rt5663_adda_r_mix)), | ||
2164 | SND_SOC_DAPM_PGA("DAC L1", SND_SOC_NOPM, 0, 0, NULL, 0), | ||
2165 | SND_SOC_DAPM_PGA("DAC R1", SND_SOC_NOPM, 0, 0, NULL, 0), | ||
2166 | |||
2167 | /* DAC Mixer */ | ||
2168 | SND_SOC_DAPM_SUPPLY("STO1 DAC Filter", RT5663_PWR_DIG_2, | ||
2169 | RT5668_PWR_DAC_S1F_SHIFT, 0, NULL, 0), | ||
2170 | SND_SOC_DAPM_MIXER("STO1 DAC MIXL", SND_SOC_NOPM, 0, 0, | ||
2171 | rt5663_sto1_dac_l_mix, ARRAY_SIZE(rt5663_sto1_dac_l_mix)), | ||
2172 | SND_SOC_DAPM_MIXER("STO1 DAC MIXR", SND_SOC_NOPM, 0, 0, | ||
2173 | rt5663_sto1_dac_r_mix, ARRAY_SIZE(rt5663_sto1_dac_r_mix)), | ||
2174 | |||
2175 | /* DACs */ | ||
2176 | SND_SOC_DAPM_SUPPLY("STO1 DAC L Power", RT5663_PWR_DIG_1, | ||
2177 | RT5668_PWR_DAC_L1_SHIFT, 0, NULL, 0), | ||
2178 | SND_SOC_DAPM_SUPPLY("STO1 DAC R Power", RT5663_PWR_DIG_1, | ||
2179 | RT5668_PWR_DAC_R1_SHIFT, 0, NULL, 0), | ||
2180 | SND_SOC_DAPM_DAC("DAC L", NULL, SND_SOC_NOPM, 0, 0), | ||
2181 | SND_SOC_DAPM_DAC("DAC R", NULL, SND_SOC_NOPM, 0, 0), | ||
2182 | |||
2183 | /* Headphone*/ | ||
2184 | SND_SOC_DAPM_PGA_S("HP Amp", 1, SND_SOC_NOPM, 0, 0, rt5663_hp_event, | ||
2185 | SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU), | ||
2186 | |||
2187 | /* Output Lines */ | ||
2188 | SND_SOC_DAPM_OUTPUT("HPOL"), | ||
2189 | SND_SOC_DAPM_OUTPUT("HPOR"), | ||
2190 | }; | ||
2191 | |||
2192 | static const struct snd_soc_dapm_widget rt5668_specific_dapm_widgets[] = { | ||
2193 | SND_SOC_DAPM_SUPPLY("LDO2", RT5663_PWR_ANLG_3, | ||
2194 | RT5668_PWR_LDO2_SHIFT, 0, NULL, 0), | ||
2195 | SND_SOC_DAPM_SUPPLY("Mic Det Power", RT5668_PWR_VOL, | ||
2196 | RT5668_PWR_MIC_DET_SHIFT, 0, NULL, 0), | ||
2197 | SND_SOC_DAPM_SUPPLY("LDO DAC", RT5663_PWR_DIG_1, | ||
2198 | RT5668_PWR_LDO_DACREF_SHIFT, 0, NULL, 0), | ||
2199 | |||
2200 | /* ASRC */ | ||
2201 | SND_SOC_DAPM_SUPPLY("I2S ASRC", RT5663_ASRC_1, | ||
2202 | RT5668_I2S1_ASRC_SHIFT, 0, NULL, 0), | ||
2203 | SND_SOC_DAPM_SUPPLY("DAC ASRC", RT5663_ASRC_1, | ||
2204 | RT5668_DAC_STO1_ASRC_SHIFT, 0, NULL, 0), | ||
2205 | SND_SOC_DAPM_SUPPLY("ADC ASRC", RT5663_ASRC_1, | ||
2206 | RT5668_ADC_STO1_ASRC_SHIFT, 0, NULL, 0), | ||
2207 | |||
2208 | /* Input Lines */ | ||
2209 | SND_SOC_DAPM_INPUT("IN2P"), | ||
2210 | SND_SOC_DAPM_INPUT("IN2N"), | ||
2211 | |||
2212 | /* Boost */ | ||
2213 | SND_SOC_DAPM_PGA("BST1 CBJ", SND_SOC_NOPM, 0, 0, NULL, 0), | ||
2214 | SND_SOC_DAPM_SUPPLY("CBJ Power", RT5663_PWR_ANLG_3, | ||
2215 | RT5668_PWR_CBJ_SHIFT, 0, NULL, 0), | ||
2216 | SND_SOC_DAPM_PGA("BST2", SND_SOC_NOPM, 0, 0, NULL, 0), | ||
2217 | SND_SOC_DAPM_SUPPLY("BST2 Power", SND_SOC_NOPM, 0, 0, | ||
2218 | rt5668_bst2_power, SND_SOC_DAPM_PRE_PMD | | ||
2219 | SND_SOC_DAPM_POST_PMU), | ||
2220 | |||
2221 | /* REC Mixer */ | ||
2222 | SND_SOC_DAPM_MIXER("RECMIX1L", SND_SOC_NOPM, 0, 0, rt5668_recmix1l, | ||
2223 | ARRAY_SIZE(rt5668_recmix1l)), | ||
2224 | SND_SOC_DAPM_MIXER("RECMIX1R", SND_SOC_NOPM, 0, 0, rt5668_recmix1r, | ||
2225 | ARRAY_SIZE(rt5668_recmix1r)), | ||
2226 | SND_SOC_DAPM_SUPPLY("RECMIX1R Power", RT5663_PWR_ANLG_2, | ||
2227 | RT5668_PWR_RECMIX2_SHIFT, 0, NULL, 0), | ||
2228 | |||
2229 | /* ADC */ | ||
2230 | SND_SOC_DAPM_ADC("ADC R", NULL, SND_SOC_NOPM, 0, 0), | ||
2231 | SND_SOC_DAPM_SUPPLY("ADC R Power", RT5663_PWR_DIG_1, | ||
2232 | RT5668_PWR_ADC_R1_SHIFT, 0, NULL, 0), | ||
2233 | |||
2234 | /* ADC Mux */ | ||
2235 | SND_SOC_DAPM_PGA("STO1 ADC L1", RT5663_STO1_ADC_MIXER, | ||
2236 | RT5668_STO1_ADC_L1_SRC_SHIFT, 0, NULL, 0), | ||
2237 | SND_SOC_DAPM_PGA("STO1 ADC R1", RT5663_STO1_ADC_MIXER, | ||
2238 | RT5668_STO1_ADC_R1_SRC_SHIFT, 0, NULL, 0), | ||
2239 | SND_SOC_DAPM_PGA("STO1 ADC L2", RT5663_STO1_ADC_MIXER, | ||
2240 | RT5668_STO1_ADC_L2_SRC_SHIFT, 1, NULL, 0), | ||
2241 | SND_SOC_DAPM_PGA("STO1 ADC R2", RT5663_STO1_ADC_MIXER, | ||
2242 | RT5668_STO1_ADC_R2_SRC_SHIFT, 1, NULL, 0), | ||
2243 | |||
2244 | SND_SOC_DAPM_MUX("STO1 ADC L Mux", SND_SOC_NOPM, 0, 0, | ||
2245 | &rt5668_sto1_adcl_mux), | ||
2246 | SND_SOC_DAPM_MUX("STO1 ADC R Mux", SND_SOC_NOPM, 0, 0, | ||
2247 | &rt5668_sto1_adcr_mux), | ||
2248 | |||
2249 | /* ADC Mix */ | ||
2250 | SND_SOC_DAPM_MIXER("STO1 ADC MIXR", SND_SOC_NOPM, 0, 0, | ||
2251 | rt5668_sto1_adc_r_mix, ARRAY_SIZE(rt5668_sto1_adc_r_mix)), | ||
2252 | |||
2253 | /* Analog DAC Clock */ | ||
2254 | SND_SOC_DAPM_SUPPLY("DAC Clock", RT5663_CHOP_DAC_L, | ||
2255 | RT5668_CKGEN_DAC1_SHIFT, 0, NULL, 0), | ||
2256 | |||
2257 | /* Headphone out */ | ||
2258 | SND_SOC_DAPM_SWITCH("HPO Playback", SND_SOC_NOPM, 0, 0, | ||
2259 | &rt5668_hpo_switch), | ||
2260 | }; | ||
2261 | |||
2262 | static const struct snd_soc_dapm_widget rt5663_specific_dapm_widgets[] = { | ||
2263 | /* System Clock Pre Divider Gating */ | ||
2264 | SND_SOC_DAPM_SUPPLY("Pre Div Power", SND_SOC_NOPM, 0, 0, | ||
2265 | rt5663_pre_div_power, SND_SOC_DAPM_POST_PMU | | ||
2266 | SND_SOC_DAPM_PRE_PMD), | ||
2267 | |||
2268 | /* LDO */ | ||
2269 | SND_SOC_DAPM_SUPPLY("LDO ADC", RT5663_PWR_DIG_1, | ||
2270 | RT5668_PWR_LDO_DACREF_SHIFT, 0, NULL, 0), | ||
2271 | |||
2272 | /* ASRC */ | ||
2273 | SND_SOC_DAPM_SUPPLY("I2S ASRC", RT5663_ASRC_1, | ||
2274 | RT5663_I2S1_ASRC_SHIFT, 0, NULL, 0), | ||
2275 | SND_SOC_DAPM_SUPPLY("DAC ASRC", RT5663_ASRC_1, | ||
2276 | RT5663_DAC_STO1_ASRC_SHIFT, 0, NULL, 0), | ||
2277 | SND_SOC_DAPM_SUPPLY("ADC ASRC", RT5663_ASRC_1, | ||
2278 | RT5663_ADC_STO1_ASRC_SHIFT, 0, NULL, 0), | ||
2279 | |||
2280 | /* Boost */ | ||
2281 | SND_SOC_DAPM_PGA("BST1", SND_SOC_NOPM, 0, 0, NULL, 0), | ||
2282 | |||
2283 | /* STO ADC */ | ||
2284 | SND_SOC_DAPM_PGA("STO1 ADC L1", SND_SOC_NOPM, 0, 0, NULL, 0), | ||
2285 | SND_SOC_DAPM_PGA("STO1 ADC L2", SND_SOC_NOPM, 0, 0, NULL, 0), | ||
2286 | |||
2287 | /* Analog DAC source */ | ||
2288 | SND_SOC_DAPM_MUX("DAC L Mux", SND_SOC_NOPM, 0, 0, &rt5663_alg_dacl_mux), | ||
2289 | SND_SOC_DAPM_MUX("DAC R Mux", SND_SOC_NOPM, 0, 0, &rt5663_alg_dacr_mux), | ||
2290 | }; | ||
2291 | |||
2292 | static const struct snd_soc_dapm_route rt5663_dapm_routes[] = { | ||
2293 | /* PLL */ | ||
2294 | { "I2S", NULL, "PLL", rt5663_is_sys_clk_from_pll }, | ||
2295 | |||
2296 | /* ASRC */ | ||
2297 | { "STO1 ADC Filter", NULL, "ADC ASRC", rt5663_is_using_asrc }, | ||
2298 | { "STO1 DAC Filter", NULL, "DAC ASRC", rt5663_is_using_asrc }, | ||
2299 | { "I2S", NULL, "I2S ASRC", rt5663_i2s_use_asrc }, | ||
2300 | |||
2301 | { "ADC L", NULL, "ADC L Power" }, | ||
2302 | { "ADC L", NULL, "ADC Clock" }, | ||
2303 | |||
2304 | { "STO1 ADC L2", NULL, "STO1 DAC MIXL" }, | ||
2305 | |||
2306 | { "STO1 ADC MIXL", "ADC1 Switch", "STO1 ADC L1" }, | ||
2307 | { "STO1 ADC MIXL", "ADC2 Switch", "STO1 ADC L2" }, | ||
2308 | { "STO1 ADC MIXL", NULL, "STO1 ADC Filter" }, | ||
2309 | |||
2310 | { "IF1 ADC1", NULL, "STO1 ADC MIXL" }, | ||
2311 | { "IF ADC", NULL, "IF1 ADC1" }, | ||
2312 | { "AIFTX", NULL, "IF ADC" }, | ||
2313 | { "AIFTX", NULL, "I2S" }, | ||
2314 | |||
2315 | { "AIFRX", NULL, "I2S" }, | ||
2316 | { "IF DAC", NULL, "AIFRX" }, | ||
2317 | { "IF1 DAC1 L", NULL, "IF DAC" }, | ||
2318 | { "IF1 DAC1 R", NULL, "IF DAC" }, | ||
2319 | |||
2320 | { "ADDA MIXL", "ADC L Switch", "STO1 ADC MIXL" }, | ||
2321 | { "ADDA MIXL", "DAC L Switch", "IF1 DAC1 L" }, | ||
2322 | { "ADDA MIXL", NULL, "STO1 DAC Filter" }, | ||
2323 | { "ADDA MIXL", NULL, "STO1 DAC L Power" }, | ||
2324 | { "ADDA MIXR", "DAC R Switch", "IF1 DAC1 R" }, | ||
2325 | { "ADDA MIXR", NULL, "STO1 DAC Filter" }, | ||
2326 | { "ADDA MIXR", NULL, "STO1 DAC R Power" }, | ||
2327 | |||
2328 | { "DAC L1", NULL, "ADDA MIXL" }, | ||
2329 | { "DAC R1", NULL, "ADDA MIXR" }, | ||
2330 | |||
2331 | { "STO1 DAC MIXL", "DAC L Switch", "DAC L1" }, | ||
2332 | { "STO1 DAC MIXL", "DAC R Switch", "DAC R1" }, | ||
2333 | { "STO1 DAC MIXL", NULL, "STO1 DAC L Power" }, | ||
2334 | { "STO1 DAC MIXL", NULL, "STO1 DAC Filter" }, | ||
2335 | { "STO1 DAC MIXR", "DAC R Switch", "DAC R1" }, | ||
2336 | { "STO1 DAC MIXR", "DAC L Switch", "DAC L1" }, | ||
2337 | { "STO1 DAC MIXR", NULL, "STO1 DAC R Power" }, | ||
2338 | { "STO1 DAC MIXR", NULL, "STO1 DAC Filter" }, | ||
2339 | |||
2340 | { "HP Amp", NULL, "DAC L" }, | ||
2341 | { "HP Amp", NULL, "DAC R" }, | ||
2342 | }; | ||
2343 | |||
2344 | static const struct snd_soc_dapm_route rt5668_specific_dapm_routes[] = { | ||
2345 | { "MICBIAS1", NULL, "LDO2" }, | ||
2346 | { "MICBIAS2", NULL, "LDO2" }, | ||
2347 | |||
2348 | { "BST1 CBJ", NULL, "IN1P" }, | ||
2349 | { "BST1 CBJ", NULL, "IN1N" }, | ||
2350 | { "BST1 CBJ", NULL, "CBJ Power" }, | ||
2351 | |||
2352 | { "BST2", NULL, "IN2P" }, | ||
2353 | { "BST2", NULL, "IN2N" }, | ||
2354 | { "BST2", NULL, "BST2 Power" }, | ||
2355 | |||
2356 | { "RECMIX1L", "BST2 Switch", "BST2" }, | ||
2357 | { "RECMIX1L", "BST1 CBJ Switch", "BST1 CBJ" }, | ||
2358 | { "RECMIX1L", NULL, "RECMIX1L Power" }, | ||
2359 | { "RECMIX1R", "BST2 Switch", "BST2" }, | ||
2360 | { "RECMIX1R", NULL, "RECMIX1R Power" }, | ||
2361 | |||
2362 | { "ADC L", NULL, "RECMIX1L" }, | ||
2363 | { "ADC R", NULL, "RECMIX1R" }, | ||
2364 | { "ADC R", NULL, "ADC R Power" }, | ||
2365 | { "ADC R", NULL, "ADC Clock" }, | ||
2366 | |||
2367 | { "STO1 ADC L Mux", "ADC L", "ADC L" }, | ||
2368 | { "STO1 ADC L Mux", "ADC R", "ADC R" }, | ||
2369 | { "STO1 ADC L1", NULL, "STO1 ADC L Mux" }, | ||
2370 | |||
2371 | { "STO1 ADC R Mux", "ADC L", "ADC L" }, | ||
2372 | { "STO1 ADC R Mux", "ADC R", "ADC R" }, | ||
2373 | { "STO1 ADC R1", NULL, "STO1 ADC R Mux" }, | ||
2374 | { "STO1 ADC R2", NULL, "STO1 DAC MIXR" }, | ||
2375 | |||
2376 | { "STO1 ADC MIXR", "ADC1 Switch", "STO1 ADC R1" }, | ||
2377 | { "STO1 ADC MIXR", "ADC2 Switch", "STO1 ADC R2" }, | ||
2378 | { "STO1 ADC MIXR", NULL, "STO1 ADC Filter" }, | ||
2379 | |||
2380 | { "IF1 ADC1", NULL, "STO1 ADC MIXR" }, | ||
2381 | |||
2382 | { "ADDA MIXR", "ADC R Switch", "STO1 ADC MIXR" }, | ||
2383 | |||
2384 | { "DAC L", NULL, "STO1 DAC MIXL" }, | ||
2385 | { "DAC L", NULL, "LDO DAC" }, | ||
2386 | { "DAC L", NULL, "DAC Clock" }, | ||
2387 | { "DAC R", NULL, "STO1 DAC MIXR" }, | ||
2388 | { "DAC R", NULL, "LDO DAC" }, | ||
2389 | { "DAC R", NULL, "DAC Clock" }, | ||
2390 | |||
2391 | { "HPO Playback", "Switch", "HP Amp" }, | ||
2392 | { "HPOL", NULL, "HPO Playback" }, | ||
2393 | { "HPOR", NULL, "HPO Playback" }, | ||
2394 | }; | ||
2395 | |||
2396 | static const struct snd_soc_dapm_route rt5663_specific_dapm_routes[] = { | ||
2397 | { "I2S", NULL, "Pre Div Power" }, | ||
2398 | |||
2399 | { "BST1", NULL, "IN1P" }, | ||
2400 | { "BST1", NULL, "IN1N" }, | ||
2401 | { "BST1", NULL, "RECMIX1L Power" }, | ||
2402 | |||
2403 | { "ADC L", NULL, "BST1" }, | ||
2404 | |||
2405 | { "STO1 ADC L1", NULL, "ADC L" }, | ||
2406 | |||
2407 | { "DAC L Mux", "DAC L", "DAC L1" }, | ||
2408 | { "DAC L Mux", "STO DAC MIXL", "STO1 DAC MIXL" }, | ||
2409 | { "DAC R Mux", "DAC R", "DAC R1"}, | ||
2410 | { "DAC R Mux", "STO DAC MIXR", "STO1 DAC MIXR" }, | ||
2411 | |||
2412 | { "DAC L", NULL, "DAC L Mux" }, | ||
2413 | { "DAC R", NULL, "DAC R Mux" }, | ||
2414 | |||
2415 | { "HPOL", NULL, "HP Amp" }, | ||
2416 | { "HPOR", NULL, "HP Amp" }, | ||
2417 | }; | ||
2418 | |||
2419 | static int rt5663_hw_params(struct snd_pcm_substream *substream, | ||
2420 | struct snd_pcm_hw_params *params, struct snd_soc_dai *dai) | ||
2421 | { | ||
2422 | struct snd_soc_codec *codec = dai->codec; | ||
2423 | struct rt5663_priv *rt5663 = snd_soc_codec_get_drvdata(codec); | ||
2424 | unsigned int val_len = 0; | ||
2425 | int pre_div; | ||
2426 | |||
2427 | rt5663->lrck = params_rate(params); | ||
2428 | |||
2429 | dev_dbg(dai->dev, "bclk is %dHz and sysclk is %dHz\n", | ||
2430 | rt5663->lrck, rt5663->sysclk); | ||
2431 | |||
2432 | pre_div = rl6231_get_clk_info(rt5663->sysclk, rt5663->lrck); | ||
2433 | if (pre_div < 0) { | ||
2434 | dev_err(codec->dev, "Unsupported clock setting %d for DAI %d\n", | ||
2435 | rt5663->lrck, dai->id); | ||
2436 | return -EINVAL; | ||
2437 | } | ||
2438 | |||
2439 | dev_dbg(dai->dev, "pre_div is %d for iis %d\n", pre_div, dai->id); | ||
2440 | |||
2441 | switch (params_width(params)) { | ||
2442 | case 8: | ||
2443 | val_len = RT5668_I2S_DL_8; | ||
2444 | break; | ||
2445 | case 16: | ||
2446 | val_len = RT5668_I2S_DL_16; | ||
2447 | break; | ||
2448 | case 20: | ||
2449 | val_len = RT5668_I2S_DL_20; | ||
2450 | break; | ||
2451 | case 24: | ||
2452 | val_len = RT5668_I2S_DL_24; | ||
2453 | break; | ||
2454 | default: | ||
2455 | return -EINVAL; | ||
2456 | } | ||
2457 | |||
2458 | snd_soc_update_bits(codec, RT5663_I2S1_SDP, | ||
2459 | RT5668_I2S_DL_MASK, val_len); | ||
2460 | |||
2461 | snd_soc_update_bits(codec, RT5663_ADDA_CLK_1, | ||
2462 | RT5668_I2S_PD1_MASK, pre_div << RT5668_I2S_PD1_SHIFT); | ||
2463 | |||
2464 | return 0; | ||
2465 | } | ||
2466 | |||
2467 | static int rt5663_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt) | ||
2468 | { | ||
2469 | struct snd_soc_codec *codec = dai->codec; | ||
2470 | unsigned int reg_val = 0; | ||
2471 | |||
2472 | switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { | ||
2473 | case SND_SOC_DAIFMT_CBM_CFM: | ||
2474 | break; | ||
2475 | case SND_SOC_DAIFMT_CBS_CFS: | ||
2476 | reg_val |= RT5668_I2S_MS_S; | ||
2477 | break; | ||
2478 | default: | ||
2479 | return -EINVAL; | ||
2480 | } | ||
2481 | |||
2482 | switch (fmt & SND_SOC_DAIFMT_INV_MASK) { | ||
2483 | case SND_SOC_DAIFMT_NB_NF: | ||
2484 | break; | ||
2485 | case SND_SOC_DAIFMT_IB_NF: | ||
2486 | reg_val |= RT5668_I2S_BP_INV; | ||
2487 | break; | ||
2488 | default: | ||
2489 | return -EINVAL; | ||
2490 | } | ||
2491 | |||
2492 | switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { | ||
2493 | case SND_SOC_DAIFMT_I2S: | ||
2494 | break; | ||
2495 | case SND_SOC_DAIFMT_LEFT_J: | ||
2496 | reg_val |= RT5668_I2S_DF_LEFT; | ||
2497 | break; | ||
2498 | case SND_SOC_DAIFMT_DSP_A: | ||
2499 | reg_val |= RT5668_I2S_DF_PCM_A; | ||
2500 | break; | ||
2501 | case SND_SOC_DAIFMT_DSP_B: | ||
2502 | reg_val |= RT5668_I2S_DF_PCM_B; | ||
2503 | break; | ||
2504 | default: | ||
2505 | return -EINVAL; | ||
2506 | } | ||
2507 | |||
2508 | snd_soc_update_bits(codec, RT5663_I2S1_SDP, RT5668_I2S_MS_MASK | | ||
2509 | RT5668_I2S_BP_MASK | RT5668_I2S_DF_MASK, reg_val); | ||
2510 | |||
2511 | return 0; | ||
2512 | } | ||
2513 | |||
2514 | static int rt5663_set_dai_sysclk(struct snd_soc_dai *dai, int clk_id, | ||
2515 | unsigned int freq, int dir) | ||
2516 | { | ||
2517 | struct snd_soc_codec *codec = dai->codec; | ||
2518 | struct rt5663_priv *rt5663 = snd_soc_codec_get_drvdata(codec); | ||
2519 | unsigned int reg_val = 0; | ||
2520 | |||
2521 | if (freq == rt5663->sysclk && clk_id == rt5663->sysclk_src) | ||
2522 | return 0; | ||
2523 | |||
2524 | switch (clk_id) { | ||
2525 | case RT5663_SCLK_S_MCLK: | ||
2526 | reg_val |= RT5663_SCLK_SRC_MCLK; | ||
2527 | break; | ||
2528 | case RT5663_SCLK_S_PLL1: | ||
2529 | reg_val |= RT5663_SCLK_SRC_PLL1; | ||
2530 | break; | ||
2531 | case RT5663_SCLK_S_RCCLK: | ||
2532 | reg_val |= RT5663_SCLK_SRC_RCCLK; | ||
2533 | break; | ||
2534 | default: | ||
2535 | dev_err(codec->dev, "Invalid clock id (%d)\n", clk_id); | ||
2536 | return -EINVAL; | ||
2537 | } | ||
2538 | snd_soc_update_bits(codec, RT5663_GLB_CLK, RT5668_SCLK_SRC_MASK, | ||
2539 | reg_val); | ||
2540 | rt5663->sysclk = freq; | ||
2541 | rt5663->sysclk_src = clk_id; | ||
2542 | |||
2543 | dev_dbg(codec->dev, "Sysclk is %dHz and clock id is %d\n", | ||
2544 | freq, clk_id); | ||
2545 | |||
2546 | return 0; | ||
2547 | } | ||
2548 | |||
2549 | static int rt5663_set_dai_pll(struct snd_soc_dai *dai, int pll_id, int source, | ||
2550 | unsigned int freq_in, unsigned int freq_out) | ||
2551 | { | ||
2552 | struct snd_soc_codec *codec = dai->codec; | ||
2553 | struct rt5663_priv *rt5663 = snd_soc_codec_get_drvdata(codec); | ||
2554 | struct rl6231_pll_code pll_code; | ||
2555 | int ret; | ||
2556 | int mask, shift, val; | ||
2557 | |||
2558 | if (source == rt5663->pll_src && freq_in == rt5663->pll_in && | ||
2559 | freq_out == rt5663->pll_out) | ||
2560 | return 0; | ||
2561 | |||
2562 | if (!freq_in || !freq_out) { | ||
2563 | dev_dbg(codec->dev, "PLL disabled\n"); | ||
2564 | |||
2565 | rt5663->pll_in = 0; | ||
2566 | rt5663->pll_out = 0; | ||
2567 | snd_soc_update_bits(codec, RT5663_GLB_CLK, | ||
2568 | RT5663_SCLK_SRC_MASK, RT5663_SCLK_SRC_MCLK); | ||
2569 | return 0; | ||
2570 | } | ||
2571 | |||
2572 | switch (rt5663->codec_type) { | ||
2573 | case CODEC_TYPE_RT5668: | ||
2574 | mask = RT5668_PLL1_SRC_MASK; | ||
2575 | shift = RT5668_PLL1_SRC_SHIFT; | ||
2576 | break; | ||
2577 | case CODEC_TYPE_RT5663: | ||
2578 | mask = RT5663_PLL1_SRC_MASK; | ||
2579 | shift = RT5663_PLL1_SRC_SHIFT; | ||
2580 | break; | ||
2581 | default: | ||
2582 | dev_err(codec->dev, "Unknown CODEC_TYPE\n"); | ||
2583 | return -EINVAL; | ||
2584 | } | ||
2585 | |||
2586 | switch (source) { | ||
2587 | case RT5663_PLL1_S_MCLK: | ||
2588 | val = 0x0; | ||
2589 | break; | ||
2590 | case RT5663_PLL1_S_BCLK1: | ||
2591 | val = 0x1; | ||
2592 | break; | ||
2593 | default: | ||
2594 | dev_err(codec->dev, "Unknown PLL source %d\n", source); | ||
2595 | return -EINVAL; | ||
2596 | } | ||
2597 | snd_soc_update_bits(codec, RT5663_GLB_CLK, mask, (val << shift)); | ||
2598 | |||
2599 | ret = rl6231_pll_calc(freq_in, freq_out, &pll_code); | ||
2600 | if (ret < 0) { | ||
2601 | dev_err(codec->dev, "Unsupport input clock %d\n", freq_in); | ||
2602 | return ret; | ||
2603 | } | ||
2604 | |||
2605 | dev_dbg(codec->dev, "bypass=%d m=%d n=%d k=%d\n", pll_code.m_bp, | ||
2606 | (pll_code.m_bp ? 0 : pll_code.m_code), pll_code.n_code, | ||
2607 | pll_code.k_code); | ||
2608 | |||
2609 | snd_soc_write(codec, RT5663_PLL_1, | ||
2610 | pll_code.n_code << RT5668_PLL_N_SHIFT | pll_code.k_code); | ||
2611 | snd_soc_write(codec, RT5663_PLL_2, | ||
2612 | (pll_code.m_bp ? 0 : pll_code.m_code) << RT5668_PLL_M_SHIFT | | ||
2613 | pll_code.m_bp << RT5668_PLL_M_BP_SHIFT); | ||
2614 | |||
2615 | rt5663->pll_in = freq_in; | ||
2616 | rt5663->pll_out = freq_out; | ||
2617 | rt5663->pll_src = source; | ||
2618 | |||
2619 | return 0; | ||
2620 | } | ||
2621 | |||
2622 | static int rt5663_set_tdm_slot(struct snd_soc_dai *dai, unsigned int tx_mask, | ||
2623 | unsigned int rx_mask, int slots, int slot_width) | ||
2624 | { | ||
2625 | struct snd_soc_codec *codec = dai->codec; | ||
2626 | struct rt5663_priv *rt5663 = snd_soc_codec_get_drvdata(codec); | ||
2627 | unsigned int val = 0, reg; | ||
2628 | |||
2629 | if (rx_mask || tx_mask) | ||
2630 | val |= RT5668_TDM_MODE_TDM; | ||
2631 | |||
2632 | switch (slots) { | ||
2633 | case 4: | ||
2634 | val |= RT5668_TDM_IN_CH_4; | ||
2635 | val |= RT5668_TDM_OUT_CH_4; | ||
2636 | break; | ||
2637 | case 6: | ||
2638 | val |= RT5668_TDM_IN_CH_6; | ||
2639 | val |= RT5668_TDM_OUT_CH_6; | ||
2640 | break; | ||
2641 | case 8: | ||
2642 | val |= RT5668_TDM_IN_CH_8; | ||
2643 | val |= RT5668_TDM_OUT_CH_8; | ||
2644 | break; | ||
2645 | case 2: | ||
2646 | break; | ||
2647 | default: | ||
2648 | return -EINVAL; | ||
2649 | } | ||
2650 | |||
2651 | switch (slot_width) { | ||
2652 | case 20: | ||
2653 | val |= RT5668_TDM_IN_LEN_20; | ||
2654 | val |= RT5668_TDM_OUT_LEN_20; | ||
2655 | break; | ||
2656 | case 24: | ||
2657 | val |= RT5668_TDM_IN_LEN_24; | ||
2658 | val |= RT5668_TDM_OUT_LEN_24; | ||
2659 | break; | ||
2660 | case 32: | ||
2661 | val |= RT5668_TDM_IN_LEN_32; | ||
2662 | val |= RT5668_TDM_OUT_LEN_32; | ||
2663 | break; | ||
2664 | case 16: | ||
2665 | break; | ||
2666 | default: | ||
2667 | return -EINVAL; | ||
2668 | } | ||
2669 | |||
2670 | switch (rt5663->codec_type) { | ||
2671 | case CODEC_TYPE_RT5668: | ||
2672 | reg = RT5663_TDM_2; | ||
2673 | break; | ||
2674 | case CODEC_TYPE_RT5663: | ||
2675 | reg = RT5663_TDM_1; | ||
2676 | break; | ||
2677 | default: | ||
2678 | dev_err(codec->dev, "Unknown CODEC_TYPE\n"); | ||
2679 | return -EINVAL; | ||
2680 | } | ||
2681 | |||
2682 | snd_soc_update_bits(codec, reg, RT5668_TDM_MODE_MASK | | ||
2683 | RT5668_TDM_IN_CH_MASK | RT5668_TDM_OUT_CH_MASK | | ||
2684 | RT5668_TDM_IN_LEN_MASK | RT5668_TDM_OUT_LEN_MASK, val); | ||
2685 | |||
2686 | return 0; | ||
2687 | } | ||
2688 | |||
2689 | static int rt5663_set_bclk_ratio(struct snd_soc_dai *dai, unsigned int ratio) | ||
2690 | { | ||
2691 | struct snd_soc_codec *codec = dai->codec; | ||
2692 | struct rt5663_priv *rt5663 = snd_soc_codec_get_drvdata(codec); | ||
2693 | unsigned int reg; | ||
2694 | |||
2695 | dev_dbg(codec->dev, "%s ratio = %d\n", __func__, ratio); | ||
2696 | |||
2697 | if (rt5663->codec_type == CODEC_TYPE_RT5668) | ||
2698 | reg = RT5668_TDM_8; | ||
2699 | else | ||
2700 | reg = RT5663_TDM_5; | ||
2701 | |||
2702 | switch (ratio) { | ||
2703 | case 32: | ||
2704 | snd_soc_update_bits(codec, reg, | ||
2705 | RT5663_TDM_LENGTN_MASK, | ||
2706 | RT5663_TDM_LENGTN_16); | ||
2707 | break; | ||
2708 | case 40: | ||
2709 | snd_soc_update_bits(codec, reg, | ||
2710 | RT5663_TDM_LENGTN_MASK, | ||
2711 | RT5663_TDM_LENGTN_20); | ||
2712 | break; | ||
2713 | case 48: | ||
2714 | snd_soc_update_bits(codec, reg, | ||
2715 | RT5663_TDM_LENGTN_MASK, | ||
2716 | RT5663_TDM_LENGTN_24); | ||
2717 | break; | ||
2718 | case 64: | ||
2719 | snd_soc_update_bits(codec, reg, | ||
2720 | RT5663_TDM_LENGTN_MASK, | ||
2721 | RT5663_TDM_LENGTN_32); | ||
2722 | break; | ||
2723 | default: | ||
2724 | dev_err(codec->dev, "Invalid ratio!\n"); | ||
2725 | return -EINVAL; | ||
2726 | } | ||
2727 | |||
2728 | return 0; | ||
2729 | } | ||
2730 | |||
2731 | static int rt5663_set_bias_level(struct snd_soc_codec *codec, | ||
2732 | enum snd_soc_bias_level level) | ||
2733 | { | ||
2734 | struct rt5663_priv *rt5663 = snd_soc_codec_get_drvdata(codec); | ||
2735 | |||
2736 | switch (level) { | ||
2737 | case SND_SOC_BIAS_ON: | ||
2738 | snd_soc_update_bits(codec, RT5663_PWR_ANLG_1, | ||
2739 | RT5668_PWR_FV1_MASK | RT5668_PWR_FV2_MASK, | ||
2740 | RT5668_PWR_FV1 | RT5668_PWR_FV2); | ||
2741 | break; | ||
2742 | |||
2743 | case SND_SOC_BIAS_PREPARE: | ||
2744 | if (rt5663->codec_type == CODEC_TYPE_RT5668) { | ||
2745 | snd_soc_update_bits(codec, RT5663_DIG_MISC, | ||
2746 | RT5668_DIG_GATE_CTRL_MASK, | ||
2747 | RT5668_DIG_GATE_CTRL_EN); | ||
2748 | snd_soc_update_bits(codec, RT5663_SIG_CLK_DET, | ||
2749 | RT5668_EN_ANA_CLK_DET_MASK | | ||
2750 | RT5668_PWR_CLK_DET_MASK, | ||
2751 | RT5668_EN_ANA_CLK_DET_AUTO | | ||
2752 | RT5668_PWR_CLK_DET_EN); | ||
2753 | } | ||
2754 | break; | ||
2755 | |||
2756 | case SND_SOC_BIAS_STANDBY: | ||
2757 | if (rt5663->codec_type == CODEC_TYPE_RT5668) | ||
2758 | snd_soc_update_bits(codec, RT5663_DIG_MISC, | ||
2759 | RT5668_DIG_GATE_CTRL_MASK, | ||
2760 | RT5668_DIG_GATE_CTRL_DIS); | ||
2761 | snd_soc_update_bits(codec, RT5663_PWR_ANLG_1, | ||
2762 | RT5668_PWR_VREF1_MASK | RT5668_PWR_VREF2_MASK | | ||
2763 | RT5668_PWR_FV1_MASK | RT5668_PWR_FV2_MASK | | ||
2764 | RT5668_PWR_MB_MASK, RT5668_PWR_VREF1 | | ||
2765 | RT5668_PWR_VREF2 | RT5668_PWR_MB); | ||
2766 | usleep_range(10000, 10005); | ||
2767 | if (rt5663->codec_type == CODEC_TYPE_RT5668) { | ||
2768 | snd_soc_update_bits(codec, RT5663_SIG_CLK_DET, | ||
2769 | RT5668_EN_ANA_CLK_DET_MASK | | ||
2770 | RT5668_PWR_CLK_DET_MASK, | ||
2771 | RT5668_EN_ANA_CLK_DET_DIS | | ||
2772 | RT5668_PWR_CLK_DET_DIS); | ||
2773 | } | ||
2774 | break; | ||
2775 | |||
2776 | case SND_SOC_BIAS_OFF: | ||
2777 | snd_soc_update_bits(codec, RT5663_PWR_ANLG_1, | ||
2778 | RT5668_PWR_VREF1_MASK | RT5668_PWR_VREF2_MASK | | ||
2779 | RT5668_PWR_FV1 | RT5668_PWR_FV2, 0x0); | ||
2780 | break; | ||
2781 | |||
2782 | default: | ||
2783 | break; | ||
2784 | } | ||
2785 | |||
2786 | return 0; | ||
2787 | } | ||
2788 | |||
2789 | static int rt5663_probe(struct snd_soc_codec *codec) | ||
2790 | { | ||
2791 | struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec); | ||
2792 | struct rt5663_priv *rt5663 = snd_soc_codec_get_drvdata(codec); | ||
2793 | |||
2794 | rt5663->codec = codec; | ||
2795 | |||
2796 | switch (rt5663->codec_type) { | ||
2797 | case CODEC_TYPE_RT5668: | ||
2798 | snd_soc_dapm_new_controls(dapm, | ||
2799 | rt5668_specific_dapm_widgets, | ||
2800 | ARRAY_SIZE(rt5668_specific_dapm_widgets)); | ||
2801 | snd_soc_dapm_add_routes(dapm, | ||
2802 | rt5668_specific_dapm_routes, | ||
2803 | ARRAY_SIZE(rt5668_specific_dapm_routes)); | ||
2804 | snd_soc_add_codec_controls(codec, rt5668_specific_controls, | ||
2805 | ARRAY_SIZE(rt5668_specific_controls)); | ||
2806 | break; | ||
2807 | case CODEC_TYPE_RT5663: | ||
2808 | snd_soc_dapm_new_controls(dapm, | ||
2809 | rt5663_specific_dapm_widgets, | ||
2810 | ARRAY_SIZE(rt5663_specific_dapm_widgets)); | ||
2811 | snd_soc_dapm_add_routes(dapm, | ||
2812 | rt5663_specific_dapm_routes, | ||
2813 | ARRAY_SIZE(rt5663_specific_dapm_routes)); | ||
2814 | snd_soc_add_codec_controls(codec, rt5663_specific_controls, | ||
2815 | ARRAY_SIZE(rt5663_specific_controls)); | ||
2816 | break; | ||
2817 | } | ||
2818 | |||
2819 | return 0; | ||
2820 | } | ||
2821 | |||
2822 | static int rt5663_remove(struct snd_soc_codec *codec) | ||
2823 | { | ||
2824 | struct rt5663_priv *rt5663 = snd_soc_codec_get_drvdata(codec); | ||
2825 | |||
2826 | regmap_write(rt5663->regmap, RT5663_RESET, 0); | ||
2827 | |||
2828 | return 0; | ||
2829 | } | ||
2830 | |||
2831 | #ifdef CONFIG_PM | ||
2832 | static int rt5663_suspend(struct snd_soc_codec *codec) | ||
2833 | { | ||
2834 | struct rt5663_priv *rt5663 = snd_soc_codec_get_drvdata(codec); | ||
2835 | |||
2836 | regcache_cache_only(rt5663->regmap, true); | ||
2837 | regcache_mark_dirty(rt5663->regmap); | ||
2838 | |||
2839 | return 0; | ||
2840 | } | ||
2841 | |||
2842 | static int rt5663_resume(struct snd_soc_codec *codec) | ||
2843 | { | ||
2844 | struct rt5663_priv *rt5663 = snd_soc_codec_get_drvdata(codec); | ||
2845 | |||
2846 | regcache_cache_only(rt5663->regmap, false); | ||
2847 | regcache_sync(rt5663->regmap); | ||
2848 | |||
2849 | return 0; | ||
2850 | } | ||
2851 | #else | ||
2852 | #define rt5663_suspend NULL | ||
2853 | #define rt5663_resume NULL | ||
2854 | #endif | ||
2855 | |||
2856 | #define RT5663_STEREO_RATES SNDRV_PCM_RATE_8000_192000 | ||
2857 | #define RT5663_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE | \ | ||
2858 | SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S8) | ||
2859 | |||
2860 | static struct snd_soc_dai_ops rt5663_aif_dai_ops = { | ||
2861 | .hw_params = rt5663_hw_params, | ||
2862 | .set_fmt = rt5663_set_dai_fmt, | ||
2863 | .set_sysclk = rt5663_set_dai_sysclk, | ||
2864 | .set_pll = rt5663_set_dai_pll, | ||
2865 | .set_tdm_slot = rt5663_set_tdm_slot, | ||
2866 | .set_bclk_ratio = rt5663_set_bclk_ratio, | ||
2867 | }; | ||
2868 | |||
2869 | static struct snd_soc_dai_driver rt5663_dai[] = { | ||
2870 | { | ||
2871 | .name = "rt5663-aif", | ||
2872 | .id = RT5663_AIF, | ||
2873 | .playback = { | ||
2874 | .stream_name = "AIF Playback", | ||
2875 | .channels_min = 1, | ||
2876 | .channels_max = 2, | ||
2877 | .rates = RT5663_STEREO_RATES, | ||
2878 | .formats = RT5663_FORMATS, | ||
2879 | }, | ||
2880 | .capture = { | ||
2881 | .stream_name = "AIF Capture", | ||
2882 | .channels_min = 1, | ||
2883 | .channels_max = 2, | ||
2884 | .rates = RT5663_STEREO_RATES, | ||
2885 | .formats = RT5663_FORMATS, | ||
2886 | }, | ||
2887 | .ops = &rt5663_aif_dai_ops, | ||
2888 | }, | ||
2889 | }; | ||
2890 | |||
2891 | static struct snd_soc_codec_driver soc_codec_dev_rt5663 = { | ||
2892 | .probe = rt5663_probe, | ||
2893 | .remove = rt5663_remove, | ||
2894 | .suspend = rt5663_suspend, | ||
2895 | .resume = rt5663_resume, | ||
2896 | .set_bias_level = rt5663_set_bias_level, | ||
2897 | .idle_bias_off = true, | ||
2898 | .component_driver = { | ||
2899 | .controls = rt5663_snd_controls, | ||
2900 | .num_controls = ARRAY_SIZE(rt5663_snd_controls), | ||
2901 | .dapm_widgets = rt5663_dapm_widgets, | ||
2902 | .num_dapm_widgets = ARRAY_SIZE(rt5663_dapm_widgets), | ||
2903 | .dapm_routes = rt5663_dapm_routes, | ||
2904 | .num_dapm_routes = ARRAY_SIZE(rt5663_dapm_routes), | ||
2905 | } | ||
2906 | }; | ||
2907 | |||
2908 | static const struct regmap_config rt5668_regmap = { | ||
2909 | .reg_bits = 16, | ||
2910 | .val_bits = 16, | ||
2911 | .use_single_rw = true, | ||
2912 | .max_register = 0x07fa, | ||
2913 | .volatile_reg = rt5668_volatile_register, | ||
2914 | .readable_reg = rt5668_readable_register, | ||
2915 | .cache_type = REGCACHE_RBTREE, | ||
2916 | .reg_defaults = rt5668_reg, | ||
2917 | .num_reg_defaults = ARRAY_SIZE(rt5668_reg), | ||
2918 | }; | ||
2919 | |||
2920 | static const struct regmap_config rt5663_regmap = { | ||
2921 | .reg_bits = 16, | ||
2922 | .val_bits = 16, | ||
2923 | .use_single_rw = true, | ||
2924 | .max_register = 0x03f3, | ||
2925 | .volatile_reg = rt5663_volatile_register, | ||
2926 | .readable_reg = rt5663_readable_register, | ||
2927 | .cache_type = REGCACHE_RBTREE, | ||
2928 | .reg_defaults = rt5663_reg, | ||
2929 | .num_reg_defaults = ARRAY_SIZE(rt5663_reg), | ||
2930 | }; | ||
2931 | |||
2932 | static const struct regmap_config temp_regmap = { | ||
2933 | .name = "nocache", | ||
2934 | .reg_bits = 16, | ||
2935 | .val_bits = 16, | ||
2936 | .use_single_rw = true, | ||
2937 | .max_register = 0x03f3, | ||
2938 | .cache_type = REGCACHE_NONE, | ||
2939 | }; | ||
2940 | |||
2941 | static const struct i2c_device_id rt5663_i2c_id[] = { | ||
2942 | { "rt5668", 0 }, | ||
2943 | { "rt5663", 0 }, | ||
2944 | {} | ||
2945 | }; | ||
2946 | MODULE_DEVICE_TABLE(i2c, rt5663_i2c_id); | ||
2947 | |||
2948 | #if defined(CONFIG_OF) | ||
2949 | static const struct of_device_id rt5663_of_match[] = { | ||
2950 | { .compatible = "realtek,rt5668", }, | ||
2951 | { .compatible = "realtek,rt5663", }, | ||
2952 | {}, | ||
2953 | }; | ||
2954 | MODULE_DEVICE_TABLE(of, rt5663_of_match); | ||
2955 | #endif | ||
2956 | |||
2957 | #ifdef CONFIG_ACPI | ||
2958 | static struct acpi_device_id rt5663_acpi_match[] = { | ||
2959 | { "10EC5668", 0}, | ||
2960 | { "10EC5663", 0}, | ||
2961 | {}, | ||
2962 | }; | ||
2963 | MODULE_DEVICE_TABLE(acpi, rt5663_acpi_match); | ||
2964 | #endif | ||
2965 | |||
2966 | static void rt5668_calibrate(struct rt5663_priv *rt5668) | ||
2967 | { | ||
2968 | regmap_write(rt5668->regmap, RT5663_BIAS_CUR_8, 0xa402); | ||
2969 | regmap_write(rt5668->regmap, RT5663_PWR_DIG_1, 0x0100); | ||
2970 | regmap_write(rt5668->regmap, RT5663_RECMIX, 0x4040); | ||
2971 | regmap_write(rt5668->regmap, RT5663_DIG_MISC, 0x0001); | ||
2972 | regmap_write(rt5668->regmap, RT5663_RC_CLK, 0x0380); | ||
2973 | regmap_write(rt5668->regmap, RT5663_GLB_CLK, 0x8000); | ||
2974 | regmap_write(rt5668->regmap, RT5663_ADDA_CLK_1, 0x1000); | ||
2975 | regmap_write(rt5668->regmap, RT5663_CHOP_DAC_L, 0x3030); | ||
2976 | regmap_write(rt5668->regmap, RT5663_CALIB_ADC, 0x3c05); | ||
2977 | regmap_write(rt5668->regmap, RT5663_PWR_ANLG_1, 0xa23e); | ||
2978 | msleep(40); | ||
2979 | regmap_write(rt5668->regmap, RT5663_PWR_ANLG_1, 0xf23e); | ||
2980 | regmap_write(rt5668->regmap, RT5663_HP_CALIB_2, 0x0321); | ||
2981 | regmap_write(rt5668->regmap, RT5663_HP_CALIB_1, 0xfc00); | ||
2982 | msleep(500); | ||
2983 | } | ||
2984 | |||
2985 | static void rt5663_calibrate(struct rt5663_priv *rt5668) | ||
2986 | { | ||
2987 | int value, count; | ||
2988 | |||
2989 | regmap_write(rt5668->regmap, RT5663_RC_CLK, 0x0280); | ||
2990 | regmap_write(rt5668->regmap, RT5663_GLB_CLK, 0x8000); | ||
2991 | regmap_write(rt5668->regmap, RT5663_DIG_MISC, 0x8001); | ||
2992 | regmap_write(rt5668->regmap, RT5663_VREF_RECMIX, 0x0032); | ||
2993 | regmap_write(rt5668->regmap, RT5663_PWR_ANLG_1, 0xa2be); | ||
2994 | msleep(20); | ||
2995 | regmap_write(rt5668->regmap, RT5663_PWR_ANLG_1, 0xf2be); | ||
2996 | regmap_write(rt5668->regmap, RT5663_PWR_DIG_2, 0x8400); | ||
2997 | regmap_write(rt5668->regmap, RT5663_CHOP_ADC, 0x3000); | ||
2998 | regmap_write(rt5668->regmap, RT5663_DEPOP_1, 0x003b); | ||
2999 | regmap_write(rt5668->regmap, RT5663_PWR_DIG_1, 0x8df8); | ||
3000 | regmap_write(rt5668->regmap, RT5663_PWR_ANLG_2, 0x0003); | ||
3001 | regmap_write(rt5668->regmap, RT5663_PWR_ANLG_3, 0x018c); | ||
3002 | regmap_write(rt5668->regmap, RT5663_ADDA_CLK_1, 0x1111); | ||
3003 | regmap_write(rt5668->regmap, RT5663_PRE_DIV_GATING_1, 0xffff); | ||
3004 | regmap_write(rt5668->regmap, RT5663_PRE_DIV_GATING_2, 0xffff); | ||
3005 | regmap_write(rt5668->regmap, RT5663_DEPOP_2, 0x3003); | ||
3006 | regmap_write(rt5668->regmap, RT5663_DEPOP_1, 0x003b); | ||
3007 | regmap_write(rt5668->regmap, RT5663_HP_CHARGE_PUMP_1, 0x1e32); | ||
3008 | regmap_write(rt5668->regmap, RT5663_HP_CHARGE_PUMP_2, 0x1371); | ||
3009 | regmap_write(rt5668->regmap, RT5663_DACREF_LDO, 0x3b0b); | ||
3010 | regmap_write(rt5668->regmap, RT5663_STO_DAC_MIXER, 0x2080); | ||
3011 | regmap_write(rt5668->regmap, RT5663_BYPASS_STO_DAC, 0x000c); | ||
3012 | regmap_write(rt5668->regmap, RT5663_HP_BIAS, 0xabba); | ||
3013 | regmap_write(rt5668->regmap, RT5663_CHARGE_PUMP_1, 0x2224); | ||
3014 | regmap_write(rt5668->regmap, RT5663_HP_OUT_EN, 0x8088); | ||
3015 | regmap_write(rt5668->regmap, RT5663_STO_DRE_9, 0x0017); | ||
3016 | regmap_write(rt5668->regmap, RT5663_STO_DRE_10, 0x0017); | ||
3017 | regmap_write(rt5668->regmap, RT5663_STO1_ADC_MIXER, 0x4040); | ||
3018 | regmap_write(rt5668->regmap, RT5663_RECMIX, 0x0005); | ||
3019 | regmap_write(rt5668->regmap, RT5663_ADDA_RST, 0xc000); | ||
3020 | regmap_write(rt5668->regmap, RT5663_STO1_HPF_ADJ1, 0x3320); | ||
3021 | regmap_write(rt5668->regmap, RT5663_HP_CALIB_2, 0x00c9); | ||
3022 | regmap_write(rt5668->regmap, RT5663_DUMMY_1, 0x004c); | ||
3023 | regmap_write(rt5668->regmap, RT5663_ANA_BIAS_CUR_1, 0x7766); | ||
3024 | regmap_write(rt5668->regmap, RT5663_BIAS_CUR_8, 0x4702); | ||
3025 | msleep(200); | ||
3026 | regmap_write(rt5668->regmap, RT5663_HP_CALIB_1, 0x0069); | ||
3027 | regmap_write(rt5668->regmap, RT5663_HP_CALIB_3, 0x06c2); | ||
3028 | regmap_write(rt5668->regmap, RT5663_HP_CALIB_1_1, 0x7b00); | ||
3029 | regmap_write(rt5668->regmap, RT5663_HP_CALIB_1_1, 0xfb00); | ||
3030 | count = 0; | ||
3031 | while (true) { | ||
3032 | regmap_read(rt5668->regmap, RT5663_HP_CALIB_1_1, &value); | ||
3033 | if (value & 0x8000) | ||
3034 | usleep_range(10000, 10005); | ||
3035 | else | ||
3036 | break; | ||
3037 | |||
3038 | if (count > 200) | ||
3039 | return; | ||
3040 | count++; | ||
3041 | } | ||
3042 | } | ||
3043 | |||
3044 | static int rt5663_i2c_probe(struct i2c_client *i2c, | ||
3045 | const struct i2c_device_id *id) | ||
3046 | { | ||
3047 | struct rt5663_priv *rt5663; | ||
3048 | int ret; | ||
3049 | unsigned int val; | ||
3050 | struct regmap *regmap; | ||
3051 | |||
3052 | rt5663 = devm_kzalloc(&i2c->dev, sizeof(struct rt5663_priv), | ||
3053 | GFP_KERNEL); | ||
3054 | |||
3055 | if (rt5663 == NULL) | ||
3056 | return -ENOMEM; | ||
3057 | |||
3058 | i2c_set_clientdata(i2c, rt5663); | ||
3059 | |||
3060 | regmap = devm_regmap_init_i2c(i2c, &temp_regmap); | ||
3061 | if (IS_ERR(regmap)) { | ||
3062 | ret = PTR_ERR(regmap); | ||
3063 | dev_err(&i2c->dev, "Failed to allocate temp register map: %d\n", | ||
3064 | ret); | ||
3065 | return ret; | ||
3066 | } | ||
3067 | regmap_read(regmap, RT5663_VENDOR_ID_2, &val); | ||
3068 | switch (val) { | ||
3069 | case RT5668_DEVICE_ID: | ||
3070 | rt5663->regmap = devm_regmap_init_i2c(i2c, &rt5668_regmap); | ||
3071 | rt5663->codec_type = CODEC_TYPE_RT5668; | ||
3072 | break; | ||
3073 | case RT5663_DEVICE_ID: | ||
3074 | rt5663->regmap = devm_regmap_init_i2c(i2c, &rt5663_regmap); | ||
3075 | rt5663->codec_type = CODEC_TYPE_RT5663; | ||
3076 | break; | ||
3077 | default: | ||
3078 | dev_err(&i2c->dev, | ||
3079 | "Device with ID register %#x is not rt5663 or rt5668\n", | ||
3080 | val); | ||
3081 | return -ENODEV; | ||
3082 | } | ||
3083 | |||
3084 | if (IS_ERR(rt5663->regmap)) { | ||
3085 | ret = PTR_ERR(rt5663->regmap); | ||
3086 | dev_err(&i2c->dev, "Failed to allocate register map: %d\n", | ||
3087 | ret); | ||
3088 | return ret; | ||
3089 | } | ||
3090 | |||
3091 | /* reset and calibrate */ | ||
3092 | regmap_write(rt5663->regmap, RT5663_RESET, 0); | ||
3093 | regcache_cache_bypass(rt5663->regmap, true); | ||
3094 | switch (rt5663->codec_type) { | ||
3095 | case CODEC_TYPE_RT5668: | ||
3096 | rt5668_calibrate(rt5663); | ||
3097 | break; | ||
3098 | case CODEC_TYPE_RT5663: | ||
3099 | rt5663_calibrate(rt5663); | ||
3100 | break; | ||
3101 | default: | ||
3102 | dev_err(&i2c->dev, "%s:Unknown codec type\n", __func__); | ||
3103 | } | ||
3104 | regcache_cache_bypass(rt5663->regmap, false); | ||
3105 | regmap_write(rt5663->regmap, RT5663_RESET, 0); | ||
3106 | dev_dbg(&i2c->dev, "calibrate done\n"); | ||
3107 | |||
3108 | /* GPIO1 as IRQ */ | ||
3109 | regmap_update_bits(rt5663->regmap, RT5663_GPIO_1, RT5668_GP1_PIN_MASK, | ||
3110 | RT5668_GP1_PIN_IRQ); | ||
3111 | /* 4btn inline command debounce */ | ||
3112 | regmap_update_bits(rt5663->regmap, RT5663_IL_CMD_5, | ||
3113 | RT5668_4BTN_CLK_DEB_MASK, RT5668_4BTN_CLK_DEB_65MS); | ||
3114 | |||
3115 | switch (rt5663->codec_type) { | ||
3116 | case CODEC_TYPE_RT5668: | ||
3117 | regmap_write(rt5663->regmap, RT5663_BIAS_CUR_8, 0xa402); | ||
3118 | /* JD1 */ | ||
3119 | regmap_update_bits(rt5663->regmap, RT5663_AUTO_1MRC_CLK, | ||
3120 | RT5668_IRQ_POW_SAV_MASK | RT5668_IRQ_POW_SAV_JD1_MASK, | ||
3121 | RT5668_IRQ_POW_SAV_EN | RT5668_IRQ_POW_SAV_JD1_EN); | ||
3122 | regmap_update_bits(rt5663->regmap, RT5663_PWR_ANLG_2, | ||
3123 | RT5668_PWR_JD1_MASK, RT5668_PWR_JD1); | ||
3124 | regmap_update_bits(rt5663->regmap, RT5663_IRQ_1, | ||
3125 | RT5668_EN_CB_JD_MASK, RT5668_EN_CB_JD_EN); | ||
3126 | |||
3127 | regmap_update_bits(rt5663->regmap, RT5663_HP_LOGIC_2, | ||
3128 | RT5668_HP_SIG_SRC1_MASK, RT5668_HP_SIG_SRC1_REG); | ||
3129 | regmap_update_bits(rt5663->regmap, RT5663_RECMIX, | ||
3130 | RT5668_VREF_BIAS_MASK | RT5668_CBJ_DET_MASK | | ||
3131 | RT5668_DET_TYPE_MASK, RT5668_VREF_BIAS_REG | | ||
3132 | RT5668_CBJ_DET_EN | RT5668_DET_TYPE_QFN); | ||
3133 | /* Set GPIO4 and GPIO8 as input for combo jack */ | ||
3134 | regmap_update_bits(rt5663->regmap, RT5663_GPIO_2, | ||
3135 | RT5668_GP4_PIN_CONF_MASK, RT5668_GP4_PIN_CONF_INPUT); | ||
3136 | regmap_update_bits(rt5663->regmap, RT5668_GPIO_3, | ||
3137 | RT5668_GP8_PIN_CONF_MASK, RT5668_GP8_PIN_CONF_INPUT); | ||
3138 | regmap_update_bits(rt5663->regmap, RT5663_PWR_ANLG_1, | ||
3139 | RT5668_LDO1_DVO_MASK | RT5668_AMP_HP_MASK, | ||
3140 | RT5668_LDO1_DVO_0_9V | RT5668_AMP_HP_3X); | ||
3141 | break; | ||
3142 | case CODEC_TYPE_RT5663: | ||
3143 | regmap_write(rt5663->regmap, RT5663_VREF_RECMIX, 0x0032); | ||
3144 | regmap_write(rt5663->regmap, RT5663_PWR_ANLG_1, 0xa2be); | ||
3145 | msleep(20); | ||
3146 | regmap_write(rt5663->regmap, RT5663_PWR_ANLG_1, 0xf2be); | ||
3147 | regmap_update_bits(rt5663->regmap, RT5663_GPIO_2, | ||
3148 | RT5663_GP1_PIN_CONF_MASK, RT5663_GP1_PIN_CONF_OUTPUT); | ||
3149 | /* DACREF LDO control */ | ||
3150 | regmap_update_bits(rt5663->regmap, RT5663_DACREF_LDO, 0x3e0e, | ||
3151 | 0x3a0a); | ||
3152 | regmap_update_bits(rt5663->regmap, RT5663_RECMIX, | ||
3153 | RT5663_RECMIX1_BST1_MASK, RT5663_RECMIX1_BST1_ON); | ||
3154 | regmap_update_bits(rt5663->regmap, RT5663_TDM_2, | ||
3155 | RT5663_DATA_SWAP_ADCDAT1_MASK, | ||
3156 | RT5663_DATA_SWAP_ADCDAT1_LL); | ||
3157 | break; | ||
3158 | default: | ||
3159 | dev_err(&i2c->dev, "%s:Unknown codec type\n", __func__); | ||
3160 | } | ||
3161 | |||
3162 | INIT_DELAYED_WORK(&rt5663->jack_detect_work, rt5663_jack_detect_work); | ||
3163 | |||
3164 | if (i2c->irq) { | ||
3165 | ret = request_irq(i2c->irq, rt5663_irq, | ||
3166 | IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING | ||
3167 | | IRQF_ONESHOT, "rt5663", rt5663); | ||
3168 | if (ret) | ||
3169 | dev_err(&i2c->dev, "%s Failed to reguest IRQ: %d\n", | ||
3170 | __func__, ret); | ||
3171 | } | ||
3172 | |||
3173 | ret = snd_soc_register_codec(&i2c->dev, &soc_codec_dev_rt5663, | ||
3174 | rt5663_dai, ARRAY_SIZE(rt5663_dai)); | ||
3175 | |||
3176 | if (ret) { | ||
3177 | if (i2c->irq) | ||
3178 | free_irq(i2c->irq, rt5663); | ||
3179 | } | ||
3180 | |||
3181 | return ret; | ||
3182 | } | ||
3183 | |||
3184 | static int rt5663_i2c_remove(struct i2c_client *i2c) | ||
3185 | { | ||
3186 | struct rt5663_priv *rt5663 = i2c_get_clientdata(i2c); | ||
3187 | |||
3188 | if (i2c->irq) | ||
3189 | free_irq(i2c->irq, rt5663); | ||
3190 | |||
3191 | snd_soc_unregister_codec(&i2c->dev); | ||
3192 | |||
3193 | return 0; | ||
3194 | } | ||
3195 | |||
3196 | static void rt5663_i2c_shutdown(struct i2c_client *client) | ||
3197 | { | ||
3198 | struct rt5663_priv *rt5663 = i2c_get_clientdata(client); | ||
3199 | |||
3200 | regmap_write(rt5663->regmap, RT5663_RESET, 0); | ||
3201 | } | ||
3202 | |||
3203 | static struct i2c_driver rt5663_i2c_driver = { | ||
3204 | .driver = { | ||
3205 | .name = "rt5663", | ||
3206 | .acpi_match_table = ACPI_PTR(rt5663_acpi_match), | ||
3207 | .of_match_table = of_match_ptr(rt5663_of_match), | ||
3208 | }, | ||
3209 | .probe = rt5663_i2c_probe, | ||
3210 | .remove = rt5663_i2c_remove, | ||
3211 | .shutdown = rt5663_i2c_shutdown, | ||
3212 | .id_table = rt5663_i2c_id, | ||
3213 | }; | ||
3214 | module_i2c_driver(rt5663_i2c_driver); | ||
3215 | |||
3216 | MODULE_DESCRIPTION("ASoC RT5663 driver"); | ||
3217 | MODULE_AUTHOR("Jack Yu <jack.yu@realtek.com>"); | ||
3218 | MODULE_LICENSE("GPL v2"); | ||
diff --git a/sound/soc/codecs/rt5663.h b/sound/soc/codecs/rt5663.h new file mode 100644 index 000000000000..2cc8f28080f6 --- /dev/null +++ b/sound/soc/codecs/rt5663.h | |||
@@ -0,0 +1,1121 @@ | |||
1 | /* | ||
2 | * rt5663.h -- RT5663 ALSA SoC audio driver | ||
3 | * | ||
4 | * Copyright 2016 Realtek Microelectronics | ||
5 | * Author: Jack Yu <jack.yu@realtek.com> | ||
6 | * | ||
7 | * This program is free software; you can redistribute it and/or modify | ||
8 | * it under the terms of the GNU General Public License version 2 as | ||
9 | * published by the Free Software Foundation. | ||
10 | */ | ||
11 | |||
12 | #ifndef __RT5663_H__ | ||
13 | #define __RT5663_H__ | ||
14 | |||
15 | /* Info */ | ||
16 | #define RT5663_RESET 0x0000 | ||
17 | #define RT5663_VENDOR_ID 0x00fd | ||
18 | #define RT5663_VENDOR_ID_1 0x00fe | ||
19 | #define RT5663_VENDOR_ID_2 0x00ff | ||
20 | |||
21 | #define RT5668_LOUT_CTRL 0x0001 | ||
22 | #define RT5668_HP_AMP_2 0x0003 | ||
23 | #define RT5668_MONO_OUT 0x0004 | ||
24 | #define RT5668_MONO_GAIN 0x0007 | ||
25 | |||
26 | #define RT5668_AEC_BST 0x000b | ||
27 | #define RT5668_IN1_IN2 0x000c | ||
28 | #define RT5668_IN3_IN4 0x000d | ||
29 | #define RT5668_INL1_INR1 0x000f | ||
30 | #define RT5668_CBJ_TYPE_2 0x0011 | ||
31 | #define RT5668_CBJ_TYPE_3 0x0012 | ||
32 | #define RT5668_CBJ_TYPE_4 0x0013 | ||
33 | #define RT5668_CBJ_TYPE_5 0x0014 | ||
34 | #define RT5668_CBJ_TYPE_8 0x0017 | ||
35 | |||
36 | /* I/O - ADC/DAC/DMIC */ | ||
37 | #define RT5668_DAC3_DIG_VOL 0x001a | ||
38 | #define RT5668_DAC3_CTRL 0x001b | ||
39 | #define RT5668_MONO_ADC_DIG_VOL 0x001d | ||
40 | #define RT5668_STO2_ADC_DIG_VOL 0x001e | ||
41 | #define RT5668_MONO_ADC_BST_GAIN 0x0020 | ||
42 | #define RT5668_STO2_ADC_BST_GAIN 0x0021 | ||
43 | #define RT5668_SIDETONE_CTRL 0x0024 | ||
44 | /* Mixer - D-D */ | ||
45 | #define RT5668_MONO1_ADC_MIXER 0x0027 | ||
46 | #define RT5668_STO2_ADC_MIXER 0x0028 | ||
47 | #define RT5668_MONO_DAC_MIXER 0x002b | ||
48 | #define RT5668_DAC2_SRC_CTRL 0x002e | ||
49 | #define RT5668_IF_3_4_DATA_CTL 0x002f | ||
50 | #define RT5668_IF_5_DATA_CTL 0x0030 | ||
51 | #define RT5668_PDM_OUT_CTL 0x0031 | ||
52 | #define RT5668_PDM_I2C_DATA_CTL1 0x0032 | ||
53 | #define RT5668_PDM_I2C_DATA_CTL2 0x0033 | ||
54 | #define RT5668_PDM_I2C_DATA_CTL3 0x0034 | ||
55 | #define RT5668_PDM_I2C_DATA_CTL4 0x0035 | ||
56 | |||
57 | /*Mixer - Analog*/ | ||
58 | #define RT5668_RECMIX1_NEW 0x003a | ||
59 | #define RT5668_RECMIX1L_0 0x003b | ||
60 | #define RT5668_RECMIX1L 0x003c | ||
61 | #define RT5668_RECMIX1R_0 0x003d | ||
62 | #define RT5668_RECMIX1R 0x003e | ||
63 | #define RT5668_RECMIX2_NEW 0x003f | ||
64 | #define RT5668_RECMIX2_L_2 0x0041 | ||
65 | #define RT5668_RECMIX2_R 0x0042 | ||
66 | #define RT5668_RECMIX2_R_2 0x0043 | ||
67 | #define RT5668_CALIB_REC_LR 0x0044 | ||
68 | #define RT5668_ALC_BK_GAIN 0x0049 | ||
69 | #define RT5668_MONOMIX_GAIN 0x004a | ||
70 | #define RT5668_MONOMIX_IN_GAIN 0x004b | ||
71 | #define RT5668_OUT_MIXL_GAIN 0x004d | ||
72 | #define RT5668_OUT_LMIX_IN_GAIN 0x004e | ||
73 | #define RT5668_OUT_RMIX_IN_GAIN 0x004f | ||
74 | #define RT5668_OUT_RMIX_IN_GAIN1 0x0050 | ||
75 | #define RT5668_LOUT_MIXER_CTRL 0x0052 | ||
76 | /* Power */ | ||
77 | #define RT5668_PWR_VOL 0x0067 | ||
78 | |||
79 | #define RT5668_ADCDAC_RST 0x006d | ||
80 | /* Format - ADC/DAC */ | ||
81 | #define RT5668_I2S34_SDP 0x0071 | ||
82 | #define RT5668_I2S5_SDP 0x0072 | ||
83 | /* Format - TDM Control */ | ||
84 | #define RT5668_TDM_5 0x007c | ||
85 | #define RT5668_TDM_6 0x007d | ||
86 | #define RT5668_TDM_7 0x007e | ||
87 | #define RT5668_TDM_8 0x007f | ||
88 | |||
89 | /* Function - Analog */ | ||
90 | #define RT5668_ASRC_3 0x0085 | ||
91 | #define RT5668_ASRC_6 0x0088 | ||
92 | #define RT5668_ASRC_7 0x0089 | ||
93 | #define RT5668_PLL_TRK_13 0x0099 | ||
94 | #define RT5668_I2S_M_CLK_CTL 0x00a0 | ||
95 | #define RT5668_FDIV_I2S34_M_CLK 0x00a1 | ||
96 | #define RT5668_FDIV_I2S34_M_CLK2 0x00a2 | ||
97 | #define RT5668_FDIV_I2S5_M_CLK 0x00a3 | ||
98 | #define RT5668_FDIV_I2S5_M_CLK2 0x00a4 | ||
99 | |||
100 | /* Function - Digital */ | ||
101 | #define RT5668_IRQ_4 0x00b9 | ||
102 | #define RT5668_GPIO_3 0x00c2 | ||
103 | #define RT5668_GPIO_4 0x00c3 | ||
104 | #define RT5668_GPIO_STA 0x00c4 | ||
105 | #define RT5668_HP_AMP_DET1 0x00d0 | ||
106 | #define RT5668_HP_AMP_DET2 0x00d1 | ||
107 | #define RT5668_HP_AMP_DET3 0x00d2 | ||
108 | #define RT5668_MID_BD_HP_AMP 0x00d3 | ||
109 | #define RT5668_LOW_BD_HP_AMP 0x00d4 | ||
110 | #define RT5668_SOF_VOL_ZC2 0x00da | ||
111 | #define RT5668_ADC_STO2_ADJ1 0x00ee | ||
112 | #define RT5668_ADC_STO2_ADJ2 0x00ef | ||
113 | /* General Control */ | ||
114 | #define RT5668_A_JD_CTRL 0x00f0 | ||
115 | #define RT5668_JD1_TRES_CTRL 0x00f1 | ||
116 | #define RT5668_JD2_TRES_CTRL 0x00f2 | ||
117 | #define RT5668_JD_CTRL2 0x00f7 | ||
118 | #define RT5668_DUM_REG_2 0x00fb | ||
119 | #define RT5668_DUM_REG_3 0x00fc | ||
120 | |||
121 | |||
122 | #define RT5668_DACADC_DIG_VOL2 0x0101 | ||
123 | #define RT5668_DIG_IN_PIN2 0x0133 | ||
124 | #define RT5668_PAD_DRV_CTL1 0x0136 | ||
125 | #define RT5668_SOF_RAM_DEPOP 0x0138 | ||
126 | #define RT5668_VOL_TEST 0x013f | ||
127 | #define RT5668_TEST_MODE_3 0x0147 | ||
128 | #define RT5668_TEST_MODE_4 0x0148 | ||
129 | #define RT5668_MONO_DYNA_1 0x0170 | ||
130 | #define RT5668_MONO_DYNA_2 0x0171 | ||
131 | #define RT5668_MONO_DYNA_3 0x0172 | ||
132 | #define RT5668_MONO_DYNA_4 0x0173 | ||
133 | #define RT5668_MONO_DYNA_5 0x0174 | ||
134 | #define RT5668_MONO_DYNA_6 0x0175 | ||
135 | #define RT5668_STO1_SIL_DET 0x0190 | ||
136 | #define RT5668_MONOL_SIL_DET 0x0191 | ||
137 | #define RT5668_MONOR_SIL_DET 0x0192 | ||
138 | #define RT5668_STO2_DAC_SIL 0x0193 | ||
139 | #define RT5668_PWR_SAV_CTL1 0x0194 | ||
140 | #define RT5668_PWR_SAV_CTL2 0x0195 | ||
141 | #define RT5668_PWR_SAV_CTL3 0x0196 | ||
142 | #define RT5668_PWR_SAV_CTL4 0x0197 | ||
143 | #define RT5668_PWR_SAV_CTL5 0x0198 | ||
144 | #define RT5668_PWR_SAV_CTL6 0x0199 | ||
145 | #define RT5668_MONO_AMP_CAL1 0x01a0 | ||
146 | #define RT5668_MONO_AMP_CAL2 0x01a1 | ||
147 | #define RT5668_MONO_AMP_CAL3 0x01a2 | ||
148 | #define RT5668_MONO_AMP_CAL4 0x01a3 | ||
149 | #define RT5668_MONO_AMP_CAL5 0x01a4 | ||
150 | #define RT5668_MONO_AMP_CAL6 0x01a5 | ||
151 | #define RT5668_MONO_AMP_CAL7 0x01a6 | ||
152 | #define RT5668_MONO_AMP_CAL_ST1 0x01a7 | ||
153 | #define RT5668_MONO_AMP_CAL_ST2 0x01a8 | ||
154 | #define RT5668_MONO_AMP_CAL_ST3 0x01a9 | ||
155 | #define RT5668_MONO_AMP_CAL_ST4 0x01aa | ||
156 | #define RT5668_MONO_AMP_CAL_ST5 0x01ab | ||
157 | #define RT5668_HP_IMP_SEN_13 0x01b9 | ||
158 | #define RT5668_HP_IMP_SEN_14 0x01ba | ||
159 | #define RT5668_HP_IMP_SEN_6 0x01bb | ||
160 | #define RT5668_HP_IMP_SEN_7 0x01bc | ||
161 | #define RT5668_HP_IMP_SEN_8 0x01bd | ||
162 | #define RT5668_HP_IMP_SEN_9 0x01be | ||
163 | #define RT5668_HP_IMP_SEN_10 0x01bf | ||
164 | #define RT5668_HP_LOGIC_3 0x01dc | ||
165 | #define RT5668_HP_CALIB_ST10 0x01f3 | ||
166 | #define RT5668_HP_CALIB_ST11 0x01f4 | ||
167 | #define RT5668_PRO_REG_TBL_4 0x0203 | ||
168 | #define RT5668_PRO_REG_TBL_5 0x0204 | ||
169 | #define RT5668_PRO_REG_TBL_6 0x0205 | ||
170 | #define RT5668_PRO_REG_TBL_7 0x0206 | ||
171 | #define RT5668_PRO_REG_TBL_8 0x0207 | ||
172 | #define RT5668_PRO_REG_TBL_9 0x0208 | ||
173 | #define RT5668_SAR_ADC_INL_1 0x0210 | ||
174 | #define RT5668_SAR_ADC_INL_2 0x0211 | ||
175 | #define RT5668_SAR_ADC_INL_3 0x0212 | ||
176 | #define RT5668_SAR_ADC_INL_4 0x0213 | ||
177 | #define RT5668_SAR_ADC_INL_5 0x0214 | ||
178 | #define RT5668_SAR_ADC_INL_6 0x0215 | ||
179 | #define RT5668_SAR_ADC_INL_7 0x0216 | ||
180 | #define RT5668_SAR_ADC_INL_8 0x0217 | ||
181 | #define RT5668_SAR_ADC_INL_9 0x0218 | ||
182 | #define RT5668_SAR_ADC_INL_10 0x0219 | ||
183 | #define RT5668_SAR_ADC_INL_11 0x021a | ||
184 | #define RT5668_SAR_ADC_INL_12 0x021b | ||
185 | #define RT5668_DRC_CTRL_1 0x02ff | ||
186 | #define RT5668_DRC1_CTRL_2 0x0301 | ||
187 | #define RT5668_DRC1_CTRL_3 0x0302 | ||
188 | #define RT5668_DRC1_CTRL_4 0x0303 | ||
189 | #define RT5668_DRC1_CTRL_5 0x0304 | ||
190 | #define RT5668_DRC1_CTRL_6 0x0305 | ||
191 | #define RT5668_DRC1_HD_CTRL_1 0x0306 | ||
192 | #define RT5668_DRC1_HD_CTRL_2 0x0307 | ||
193 | #define RT5668_DRC1_PRI_REG_1 0x0310 | ||
194 | #define RT5668_DRC1_PRI_REG_2 0x0311 | ||
195 | #define RT5668_DRC1_PRI_REG_3 0x0312 | ||
196 | #define RT5668_DRC1_PRI_REG_4 0x0313 | ||
197 | #define RT5668_DRC1_PRI_REG_5 0x0314 | ||
198 | #define RT5668_DRC1_PRI_REG_6 0x0315 | ||
199 | #define RT5668_DRC1_PRI_REG_7 0x0316 | ||
200 | #define RT5668_DRC1_PRI_REG_8 0x0317 | ||
201 | #define RT5668_ALC_PGA_CTL_1 0x0330 | ||
202 | #define RT5668_ALC_PGA_CTL_2 0x0331 | ||
203 | #define RT5668_ALC_PGA_CTL_3 0x0332 | ||
204 | #define RT5668_ALC_PGA_CTL_4 0x0333 | ||
205 | #define RT5668_ALC_PGA_CTL_5 0x0334 | ||
206 | #define RT5668_ALC_PGA_CTL_6 0x0335 | ||
207 | #define RT5668_ALC_PGA_CTL_7 0x0336 | ||
208 | #define RT5668_ALC_PGA_CTL_8 0x0337 | ||
209 | #define RT5668_ALC_PGA_REG_1 0x0338 | ||
210 | #define RT5668_ALC_PGA_REG_2 0x0339 | ||
211 | #define RT5668_ALC_PGA_REG_3 0x033a | ||
212 | #define RT5668_ADC_EQ_RECOV_1 0x03c0 | ||
213 | #define RT5668_ADC_EQ_RECOV_2 0x03c1 | ||
214 | #define RT5668_ADC_EQ_RECOV_3 0x03c2 | ||
215 | #define RT5668_ADC_EQ_RECOV_4 0x03c3 | ||
216 | #define RT5668_ADC_EQ_RECOV_5 0x03c4 | ||
217 | #define RT5668_ADC_EQ_RECOV_6 0x03c5 | ||
218 | #define RT5668_ADC_EQ_RECOV_7 0x03c6 | ||
219 | #define RT5668_ADC_EQ_RECOV_8 0x03c7 | ||
220 | #define RT5668_ADC_EQ_RECOV_9 0x03c8 | ||
221 | #define RT5668_ADC_EQ_RECOV_10 0x03c9 | ||
222 | #define RT5668_ADC_EQ_RECOV_11 0x03ca | ||
223 | #define RT5668_ADC_EQ_RECOV_12 0x03cb | ||
224 | #define RT5668_ADC_EQ_RECOV_13 0x03cc | ||
225 | #define RT5668_VID_HIDDEN 0x03fe | ||
226 | #define RT5668_VID_CUSTOMER 0x03ff | ||
227 | #define RT5668_SCAN_MODE 0x07f0 | ||
228 | #define RT5668_I2C_BYPA 0x07fa | ||
229 | |||
230 | /* Headphone Amp Control 2 (0x0003) */ | ||
231 | #define RT5668_EN_DAC_HPO_MASK (0x1 << 14) | ||
232 | #define RT5668_EN_DAC_HPO_SHIFT 14 | ||
233 | #define RT5668_EN_DAC_HPO_DIS (0x0 << 14) | ||
234 | #define RT5668_EN_DAC_HPO_EN (0x1 << 14) | ||
235 | |||
236 | /*Headphone Amp L/R Analog Gain and Digital NG2 Gain Control (0x0005 0x0006)*/ | ||
237 | #define RT5668_GAIN_HP (0x1f << 8) | ||
238 | #define RT5668_GAIN_HP_SHIFT 8 | ||
239 | |||
240 | /* AEC BST Control (0x000b) */ | ||
241 | #define RT5668_GAIN_CBJ_MASK (0xf << 8) | ||
242 | #define RT5668_GAIN_CBJ_SHIFT 8 | ||
243 | |||
244 | /* IN1 Control / MIC GND REF (0x000c) */ | ||
245 | #define RT5668_IN1_DF_MASK (0x1 << 15) | ||
246 | #define RT5668_IN1_DF_SHIFT 15 | ||
247 | |||
248 | /* Combo Jack and Type Detection Control 1 (0x0010) */ | ||
249 | #define RT5668_CBJ_DET_MASK (0x1 << 15) | ||
250 | #define RT5668_CBJ_DET_SHIFT 15 | ||
251 | #define RT5668_CBJ_DET_DIS (0x0 << 15) | ||
252 | #define RT5668_CBJ_DET_EN (0x1 << 15) | ||
253 | #define RT5668_DET_TYPE_MASK (0x1 << 12) | ||
254 | #define RT5668_DET_TYPE_SHIFT 12 | ||
255 | #define RT5668_DET_TYPE_WLCSP (0x0 << 12) | ||
256 | #define RT5668_DET_TYPE_QFN (0x1 << 12) | ||
257 | #define RT5668_VREF_BIAS_MASK (0x1 << 6) | ||
258 | #define RT5668_VREF_BIAS_SHIFT 6 | ||
259 | #define RT5668_VREF_BIAS_FSM (0x0 << 6) | ||
260 | #define RT5668_VREF_BIAS_REG (0x1 << 6) | ||
261 | |||
262 | /* REC Left Mixer Control 2 (0x003c) */ | ||
263 | #define RT5668_RECMIX1L_BST1_CBJ (0x1 << 7) | ||
264 | #define RT5668_RECMIX1L_BST1_CBJ_SHIFT 7 | ||
265 | #define RT5668_RECMIX1L_BST2 (0x1 << 4) | ||
266 | #define RT5668_RECMIX1L_BST2_SHIFT 4 | ||
267 | |||
268 | /* REC Right Mixer Control 2 (0x003e) */ | ||
269 | #define RT5668_RECMIX1R_BST2 (0x1 << 4) | ||
270 | #define RT5668_RECMIX1R_BST2_SHIFT 4 | ||
271 | |||
272 | /* DAC1 Digital Volume (0x0019) */ | ||
273 | #define RT5668_DAC_L1_VOL_MASK (0xff << 8) | ||
274 | #define RT5668_DAC_L1_VOL_SHIFT 8 | ||
275 | #define RT5668_DAC_R1_VOL_MASK (0xff) | ||
276 | #define RT5668_DAC_R1_VOL_SHIFT 0 | ||
277 | |||
278 | /* ADC Digital Volume Control (0x001c) */ | ||
279 | #define RT5668_ADC_L_MUTE_MASK (0x1 << 15) | ||
280 | #define RT5668_ADC_L_MUTE_SHIFT 15 | ||
281 | #define RT5668_ADC_L_VOL_MASK (0x7f << 8) | ||
282 | #define RT5668_ADC_L_VOL_SHIFT 8 | ||
283 | #define RT5668_ADC_R_MUTE_MASK (0x1 << 7) | ||
284 | #define RT5668_ADC_R_MUTE_SHIFT 7 | ||
285 | #define RT5668_ADC_R_VOL_MASK (0x7f) | ||
286 | #define RT5668_ADC_R_VOL_SHIFT 0 | ||
287 | |||
288 | /* Stereo ADC Mixer Control (0x0026) */ | ||
289 | #define RT5668_M_STO1_ADC_L1 (0x1 << 15) | ||
290 | #define RT5668_M_STO1_ADC_L1_SHIFT 15 | ||
291 | #define RT5668_M_STO1_ADC_L2 (0x1 << 14) | ||
292 | #define RT5668_M_STO1_ADC_L2_SHIFT 14 | ||
293 | #define RT5668_STO1_ADC_L1_SRC (0x1 << 13) | ||
294 | #define RT5668_STO1_ADC_L1_SRC_SHIFT 13 | ||
295 | #define RT5668_STO1_ADC_L2_SRC (0x1 << 12) | ||
296 | #define RT5668_STO1_ADC_L2_SRC_SHIFT 12 | ||
297 | #define RT5668_STO1_ADC_L_SRC (0x3 << 10) | ||
298 | #define RT5668_STO1_ADC_L_SRC_SHIFT 10 | ||
299 | #define RT5668_M_STO1_ADC_R1 (0x1 << 7) | ||
300 | #define RT5668_M_STO1_ADC_R1_SHIFT 7 | ||
301 | #define RT5668_M_STO1_ADC_R2 (0x1 << 6) | ||
302 | #define RT5668_M_STO1_ADC_R2_SHIFT 6 | ||
303 | #define RT5668_STO1_ADC_R1_SRC (0x1 << 5) | ||
304 | #define RT5668_STO1_ADC_R1_SRC_SHIFT 5 | ||
305 | #define RT5668_STO1_ADC_R2_SRC (0x1 << 4) | ||
306 | #define RT5668_STO1_ADC_R2_SRC_SHIFT 4 | ||
307 | #define RT5668_STO1_ADC_R_SRC (0x3 << 2) | ||
308 | #define RT5668_STO1_ADC_R_SRC_SHIFT 2 | ||
309 | |||
310 | /* ADC Mixer to DAC Mixer Control (0x0029) */ | ||
311 | #define RT5668_M_ADCMIX_L (0x1 << 15) | ||
312 | #define RT5668_M_ADCMIX_L_SHIFT 15 | ||
313 | #define RT5668_M_DAC1_L (0x1 << 14) | ||
314 | #define RT5668_M_DAC1_L_SHIFT 14 | ||
315 | #define RT5668_M_ADCMIX_R (0x1 << 7) | ||
316 | #define RT5668_M_ADCMIX_R_SHIFT 7 | ||
317 | #define RT5668_M_DAC1_R (0x1 << 6) | ||
318 | #define RT5668_M_DAC1_R_SHIFT 6 | ||
319 | |||
320 | /* Stereo DAC Mixer Control (0x002a) */ | ||
321 | #define RT5668_M_DAC_L1_STO_L (0x1 << 15) | ||
322 | #define RT5668_M_DAC_L1_STO_L_SHIFT 15 | ||
323 | #define RT5668_M_DAC_R1_STO_L (0x1 << 13) | ||
324 | #define RT5668_M_DAC_R1_STO_L_SHIFT 13 | ||
325 | #define RT5668_M_DAC_L1_STO_R (0x1 << 7) | ||
326 | #define RT5668_M_DAC_L1_STO_R_SHIFT 7 | ||
327 | #define RT5668_M_DAC_R1_STO_R (0x1 << 5) | ||
328 | #define RT5668_M_DAC_R1_STO_R_SHIFT 5 | ||
329 | |||
330 | /* Power Management for Digital 1 (0x0061) */ | ||
331 | #define RT5668_PWR_I2S1 (0x1 << 15) | ||
332 | #define RT5668_PWR_I2S1_SHIFT 15 | ||
333 | #define RT5668_PWR_DAC_L1 (0x1 << 11) | ||
334 | #define RT5668_PWR_DAC_L1_SHIFT 11 | ||
335 | #define RT5668_PWR_DAC_R1 (0x1 << 10) | ||
336 | #define RT5668_PWR_DAC_R1_SHIFT 10 | ||
337 | #define RT5668_PWR_LDO_DACREF_MASK (0x1 << 8) | ||
338 | #define RT5668_PWR_LDO_DACREF_SHIFT 8 | ||
339 | #define RT5668_PWR_LDO_DACREF_ON (0x1 << 8) | ||
340 | #define RT5668_PWR_LDO_DACREF_DOWN (0x0 << 8) | ||
341 | #define RT5668_PWR_LDO_SHIFT 8 | ||
342 | #define RT5668_PWR_ADC_L1 (0x1 << 4) | ||
343 | #define RT5668_PWR_ADC_L1_SHIFT 4 | ||
344 | #define RT5668_PWR_ADC_R1 (0x1 << 3) | ||
345 | #define RT5668_PWR_ADC_R1_SHIFT 3 | ||
346 | |||
347 | /* Power Management for Digital 2 (0x0062) */ | ||
348 | #define RT5668_PWR_ADC_S1F (0x1 << 15) | ||
349 | #define RT5668_PWR_ADC_S1F_SHIFT 15 | ||
350 | #define RT5668_PWR_DAC_S1F (0x1 << 10) | ||
351 | #define RT5668_PWR_DAC_S1F_SHIFT 10 | ||
352 | |||
353 | /* Power Management for Analog 1 (0x0063) */ | ||
354 | #define RT5668_PWR_VREF1 (0x1 << 15) | ||
355 | #define RT5668_PWR_VREF1_MASK (0x1 << 15) | ||
356 | #define RT5668_PWR_VREF1_SHIFT 15 | ||
357 | #define RT5668_PWR_FV1 (0x1 << 14) | ||
358 | #define RT5668_PWR_FV1_MASK (0x1 << 14) | ||
359 | #define RT5668_PWR_FV1_SHIFT 14 | ||
360 | #define RT5668_PWR_VREF2 (0x1 << 13) | ||
361 | #define RT5668_PWR_VREF2_MASK (0x1 << 13) | ||
362 | #define RT5668_PWR_VREF2_SHIFT 13 | ||
363 | #define RT5668_PWR_FV2 (0x1 << 12) | ||
364 | #define RT5668_PWR_FV2_MASK (0x1 << 12) | ||
365 | #define RT5668_PWR_FV2_SHIFT 12 | ||
366 | #define RT5668_PWR_MB (0x1 << 9) | ||
367 | #define RT5668_PWR_MB_MASK (0x1 << 9) | ||
368 | #define RT5668_PWR_MB_SHIFT 9 | ||
369 | #define RT5668_AMP_HP_MASK (0x3 << 2) | ||
370 | #define RT5668_AMP_HP_SHIFT 2 | ||
371 | #define RT5668_AMP_HP_1X (0x0 << 2) | ||
372 | #define RT5668_AMP_HP_3X (0x1 << 2) | ||
373 | #define RT5668_AMP_HP_5X (0x3 << 2) | ||
374 | #define RT5668_LDO1_DVO_MASK (0x3) | ||
375 | #define RT5668_LDO1_DVO_SHIFT 0 | ||
376 | #define RT5668_LDO1_DVO_0_9V (0x0) | ||
377 | #define RT5668_LDO1_DVO_1_0V (0x1) | ||
378 | #define RT5668_LDO1_DVO_1_2V (0x2) | ||
379 | #define RT5668_LDO1_DVO_1_4V (0x3) | ||
380 | |||
381 | /* Power Management for Analog 2 (0x0064) */ | ||
382 | #define RT5668_PWR_BST1 (0x1 << 15) | ||
383 | #define RT5668_PWR_BST1_MASK (0x1 << 15) | ||
384 | #define RT5668_PWR_BST1_SHIFT 15 | ||
385 | #define RT5668_PWR_BST1_OFF (0x0 << 15) | ||
386 | #define RT5668_PWR_BST1_ON (0x1 << 15) | ||
387 | #define RT5668_PWR_BST2 (0x1 << 14) | ||
388 | #define RT5668_PWR_BST2_MASK (0x1 << 14) | ||
389 | #define RT5668_PWR_BST2_SHIFT 14 | ||
390 | #define RT5668_PWR_MB1 (0x1 << 11) | ||
391 | #define RT5668_PWR_MB1_SHIFT 11 | ||
392 | #define RT5668_PWR_MB2 (0x1 << 10) | ||
393 | #define RT5668_PWR_MB2_SHIFT 10 | ||
394 | #define RT5668_PWR_BST2_OP (0x1 << 6) | ||
395 | #define RT5668_PWR_BST2_OP_MASK (0x1 << 6) | ||
396 | #define RT5668_PWR_BST2_OP_SHIFT 6 | ||
397 | #define RT5668_PWR_JD1 (0x1 << 3) | ||
398 | #define RT5668_PWR_JD1_MASK (0x1 << 3) | ||
399 | #define RT5668_PWR_JD1_SHIFT 3 | ||
400 | #define RT5668_PWR_JD2 (0x1 << 2) | ||
401 | #define RT5668_PWR_JD2_MASK (0x1 << 2) | ||
402 | #define RT5668_PWR_JD2_SHIFT 2 | ||
403 | #define RT5668_PWR_RECMIX1 (0x1 << 1) | ||
404 | #define RT5668_PWR_RECMIX1_SHIFT 1 | ||
405 | #define RT5668_PWR_RECMIX2 (0x1) | ||
406 | #define RT5668_PWR_RECMIX2_SHIFT 0 | ||
407 | |||
408 | /* Power Management for Analog 3 (0x0065) */ | ||
409 | #define RT5668_PWR_CBJ_MASK (0x1 << 9) | ||
410 | #define RT5668_PWR_CBJ_SHIFT 9 | ||
411 | #define RT5668_PWR_CBJ_OFF (0x0 << 9) | ||
412 | #define RT5668_PWR_CBJ_ON (0x1 << 9) | ||
413 | #define RT5668_PWR_PLL (0x1 << 6) | ||
414 | #define RT5668_PWR_PLL_SHIFT 6 | ||
415 | #define RT5668_PWR_LDO2 (0x1 << 2) | ||
416 | #define RT5668_PWR_LDO2_SHIFT 2 | ||
417 | |||
418 | /* Power Management for Volume (0x0067) */ | ||
419 | #define RT5668_PWR_MIC_DET (0x1 << 5) | ||
420 | #define RT5668_PWR_MIC_DET_SHIFT 5 | ||
421 | |||
422 | /* MCLK and System Clock Detection Control (0x006b) */ | ||
423 | #define RT5668_EN_ANA_CLK_DET_MASK (0x1 << 15) | ||
424 | #define RT5668_EN_ANA_CLK_DET_SHIFT 15 | ||
425 | #define RT5668_EN_ANA_CLK_DET_DIS (0x0 << 15) | ||
426 | #define RT5668_EN_ANA_CLK_DET_AUTO (0x1 << 15) | ||
427 | #define RT5668_PWR_CLK_DET_MASK (0x1) | ||
428 | #define RT5668_PWR_CLK_DET_SHIFT 0 | ||
429 | #define RT5668_PWR_CLK_DET_DIS (0x0) | ||
430 | #define RT5668_PWR_CLK_DET_EN (0x1) | ||
431 | |||
432 | /* I2S1 Audio Serial Data Port Control (0x0070) */ | ||
433 | #define RT5668_I2S_MS_MASK (0x1 << 15) | ||
434 | #define RT5668_I2S_MS_SHIFT 15 | ||
435 | #define RT5668_I2S_MS_M (0x0 << 15) | ||
436 | #define RT5668_I2S_MS_S (0x1 << 15) | ||
437 | #define RT5668_I2S_BP_MASK (0x1 << 8) | ||
438 | #define RT5668_I2S_BP_SHIFT 8 | ||
439 | #define RT5668_I2S_BP_NOR (0x0 << 8) | ||
440 | #define RT5668_I2S_BP_INV (0x1 << 8) | ||
441 | #define RT5668_I2S_DL_MASK (0x3 << 4) | ||
442 | #define RT5668_I2S_DL_SHIFT 4 | ||
443 | #define RT5668_I2S_DL_16 (0x0 << 4) | ||
444 | #define RT5668_I2S_DL_20 (0x1 << 4) | ||
445 | #define RT5668_I2S_DL_24 (0x2 << 4) | ||
446 | #define RT5668_I2S_DL_8 (0x3 << 4) | ||
447 | #define RT5668_I2S_DF_MASK (0x7) | ||
448 | #define RT5668_I2S_DF_SHIFT 0 | ||
449 | #define RT5668_I2S_DF_I2S (0x0) | ||
450 | #define RT5668_I2S_DF_LEFT (0x1) | ||
451 | #define RT5668_I2S_DF_PCM_A (0x2) | ||
452 | #define RT5668_I2S_DF_PCM_B (0x3) | ||
453 | #define RT5668_I2S_DF_PCM_A_N (0x6) | ||
454 | #define RT5668_I2S_DF_PCM_B_N (0x7) | ||
455 | |||
456 | /* ADC/DAC Clock Control 1 (0x0073) */ | ||
457 | #define RT5668_I2S_PD1_MASK (0x7 << 12) | ||
458 | #define RT5668_I2S_PD1_SHIFT 12 | ||
459 | #define RT5668_M_I2S_DIV_MASK (0x7 << 8) | ||
460 | #define RT5668_M_I2S_DIV_SHIFT 8 | ||
461 | #define RT5668_CLK_SRC_MASK (0x3 << 4) | ||
462 | #define RT5668_CLK_SRC_MCLK (0x0 << 4) | ||
463 | #define RT5668_CLK_SRC_PLL_OUT (0x1 << 4) | ||
464 | #define RT5668_CLK_SRC_DIV (0x2 << 4) | ||
465 | #define RT5668_CLK_SRC_RC (0x3 << 4) | ||
466 | #define RT5668_DAC_OSR_MASK (0x3 << 2) | ||
467 | #define RT5668_DAC_OSR_SHIFT 2 | ||
468 | #define RT5668_DAC_OSR_128 (0x0 << 2) | ||
469 | #define RT5668_DAC_OSR_64 (0x1 << 2) | ||
470 | #define RT5668_DAC_OSR_32 (0x2 << 2) | ||
471 | #define RT5668_ADC_OSR_MASK (0x3) | ||
472 | #define RT5668_ADC_OSR_SHIFT 0 | ||
473 | #define RT5668_ADC_OSR_128 (0x0) | ||
474 | #define RT5668_ADC_OSR_64 (0x1) | ||
475 | #define RT5668_ADC_OSR_32 (0x2) | ||
476 | |||
477 | /* TDM1 control 1 (0x0078) */ | ||
478 | #define RT5668_TDM_MODE_MASK (0x1 << 15) | ||
479 | #define RT5668_TDM_MODE_SHIFT 15 | ||
480 | #define RT5668_TDM_MODE_I2S (0x0 << 15) | ||
481 | #define RT5668_TDM_MODE_TDM (0x1 << 15) | ||
482 | #define RT5668_TDM_IN_CH_MASK (0x3 << 10) | ||
483 | #define RT5668_TDM_IN_CH_SHIFT 10 | ||
484 | #define RT5668_TDM_IN_CH_2 (0x0 << 10) | ||
485 | #define RT5668_TDM_IN_CH_4 (0x1 << 10) | ||
486 | #define RT5668_TDM_IN_CH_6 (0x2 << 10) | ||
487 | #define RT5668_TDM_IN_CH_8 (0x3 << 10) | ||
488 | #define RT5668_TDM_OUT_CH_MASK (0x3 << 8) | ||
489 | #define RT5668_TDM_OUT_CH_SHIFT 8 | ||
490 | #define RT5668_TDM_OUT_CH_2 (0x0 << 8) | ||
491 | #define RT5668_TDM_OUT_CH_4 (0x1 << 8) | ||
492 | #define RT5668_TDM_OUT_CH_6 (0x2 << 8) | ||
493 | #define RT5668_TDM_OUT_CH_8 (0x3 << 8) | ||
494 | #define RT5668_TDM_IN_LEN_MASK (0x3 << 6) | ||
495 | #define RT5668_TDM_IN_LEN_SHIFT 6 | ||
496 | #define RT5668_TDM_IN_LEN_16 (0x0 << 6) | ||
497 | #define RT5668_TDM_IN_LEN_20 (0x1 << 6) | ||
498 | #define RT5668_TDM_IN_LEN_24 (0x2 << 6) | ||
499 | #define RT5668_TDM_IN_LEN_32 (0x3 << 6) | ||
500 | #define RT5668_TDM_OUT_LEN_MASK (0x3 << 4) | ||
501 | #define RT5668_TDM_OUT_LEN_SHIFT 4 | ||
502 | #define RT5668_TDM_OUT_LEN_16 (0x0 << 4) | ||
503 | #define RT5668_TDM_OUT_LEN_20 (0x1 << 4) | ||
504 | #define RT5668_TDM_OUT_LEN_24 (0x2 << 4) | ||
505 | #define RT5668_TDM_OUT_LEN_32 (0x3 << 4) | ||
506 | |||
507 | /* Global Clock Control (0x0080) */ | ||
508 | #define RT5668_SCLK_SRC_MASK (0x3 << 14) | ||
509 | #define RT5668_SCLK_SRC_SHIFT 14 | ||
510 | #define RT5668_SCLK_SRC_MCLK (0x0 << 14) | ||
511 | #define RT5668_SCLK_SRC_PLL1 (0x1 << 14) | ||
512 | #define RT5668_SCLK_SRC_RCCLK (0x2 << 14) | ||
513 | #define RT5668_PLL1_SRC_MASK (0x7 << 8) | ||
514 | #define RT5668_PLL1_SRC_SHIFT 8 | ||
515 | #define RT5668_PLL1_SRC_MCLK (0x0 << 8) | ||
516 | #define RT5668_PLL1_SRC_BCLK1 (0x1 << 8) | ||
517 | #define RT5668_PLL1_PD_MASK (0x1 << 4) | ||
518 | #define RT5668_PLL1_PD_SHIFT 4 | ||
519 | |||
520 | #define RT5668_PLL_INP_MAX 40000000 | ||
521 | #define RT5668_PLL_INP_MIN 256000 | ||
522 | /* PLL M/N/K Code Control 1 (0x0081) */ | ||
523 | #define RT5668_PLL_N_MAX 0x001ff | ||
524 | #define RT5668_PLL_N_MASK (RT5668_PLL_N_MAX << 7) | ||
525 | #define RT5668_PLL_N_SHIFT 7 | ||
526 | #define RT5668_PLL_K_MAX 0x001f | ||
527 | #define RT5668_PLL_K_MASK (RT5668_PLL_K_MAX) | ||
528 | #define RT5668_PLL_K_SHIFT 0 | ||
529 | |||
530 | /* PLL M/N/K Code Control 2 (0x0082) */ | ||
531 | #define RT5668_PLL_M_MAX 0x00f | ||
532 | #define RT5668_PLL_M_MASK (RT5668_PLL_M_MAX << 12) | ||
533 | #define RT5668_PLL_M_SHIFT 12 | ||
534 | #define RT5668_PLL_M_BP (0x1 << 11) | ||
535 | #define RT5668_PLL_M_BP_SHIFT 11 | ||
536 | |||
537 | /* PLL tracking mode 1 (0x0083) */ | ||
538 | #define RT5668_I2S1_ASRC_MASK (0x1 << 13) | ||
539 | #define RT5668_I2S1_ASRC_SHIFT 13 | ||
540 | #define RT5668_DAC_STO1_ASRC_MASK (0x1 << 12) | ||
541 | #define RT5668_DAC_STO1_ASRC_SHIFT 12 | ||
542 | #define RT5668_ADC_STO1_ASRC_MASK (0x1 << 4) | ||
543 | #define RT5668_ADC_STO1_ASRC_SHIFT 4 | ||
544 | |||
545 | /* PLL tracking mode 2 (0x0084)*/ | ||
546 | #define RT5668_DA_STO1_TRACK_MASK (0x7 << 12) | ||
547 | #define RT5668_DA_STO1_TRACK_SHIFT 12 | ||
548 | #define RT5668_DA_STO1_TRACK_SYSCLK (0x0 << 12) | ||
549 | #define RT5668_DA_STO1_TRACK_I2S1 (0x1 << 12) | ||
550 | |||
551 | /* PLL tracking mode 3 (0x0085)*/ | ||
552 | #define RT5668_AD_STO1_TRACK_MASK (0x7 << 12) | ||
553 | #define RT5668_AD_STO1_TRACK_SHIFT 12 | ||
554 | #define RT5668_AD_STO1_TRACK_SYSCLK (0x0 << 12) | ||
555 | #define RT5668_AD_STO1_TRACK_I2S1 (0x1 << 12) | ||
556 | |||
557 | /* HPOUT Charge pump control 1 (0x0091) */ | ||
558 | #define RT5668_OSW_HP_L_MASK (0x1 << 11) | ||
559 | #define RT5668_OSW_HP_L_SHIFT 11 | ||
560 | #define RT5668_OSW_HP_L_EN (0x1 << 11) | ||
561 | #define RT5668_OSW_HP_L_DIS (0x0 << 11) | ||
562 | #define RT5668_OSW_HP_R_MASK (0x1 << 10) | ||
563 | #define RT5668_OSW_HP_R_SHIFT 10 | ||
564 | #define RT5668_OSW_HP_R_EN (0x1 << 10) | ||
565 | #define RT5668_OSW_HP_R_DIS (0x0 << 10) | ||
566 | #define RT5668_SEL_PM_HP_MASK (0x3 << 8) | ||
567 | #define RT5668_SEL_PM_HP_SHIFT 8 | ||
568 | #define RT5668_SEL_PM_HP_0_6 (0x0 << 8) | ||
569 | #define RT5668_SEL_PM_HP_0_9 (0x1 << 8) | ||
570 | #define RT5668_SEL_PM_HP_1_8 (0x2 << 8) | ||
571 | #define RT5668_SEL_PM_HP_HIGH (0x3 << 8) | ||
572 | #define RT5668_OVCD_HP_MASK (0x1 << 2) | ||
573 | #define RT5668_OVCD_HP_SHIFT 2 | ||
574 | #define RT5668_OVCD_HP_EN (0x1 << 2) | ||
575 | #define RT5668_OVCD_HP_DIS (0x0 << 2) | ||
576 | |||
577 | /* RC Clock Control (0x0094) */ | ||
578 | #define RT5668_DIG_25M_CLK_MASK (0x1 << 9) | ||
579 | #define RT5668_DIG_25M_CLK_SHIFT 9 | ||
580 | #define RT5668_DIG_25M_CLK_DIS (0x0 << 9) | ||
581 | #define RT5668_DIG_25M_CLK_EN (0x1 << 9) | ||
582 | #define RT5668_DIG_1M_CLK_MASK (0x1 << 8) | ||
583 | #define RT5668_DIG_1M_CLK_SHIFT 8 | ||
584 | #define RT5668_DIG_1M_CLK_DIS (0x0 << 8) | ||
585 | #define RT5668_DIG_1M_CLK_EN (0x1 << 8) | ||
586 | |||
587 | /* Auto Turn On 1M RC CLK (0x009f) */ | ||
588 | #define RT5668_IRQ_POW_SAV_MASK (0x1 << 15) | ||
589 | #define RT5668_IRQ_POW_SAV_SHIFT 15 | ||
590 | #define RT5668_IRQ_POW_SAV_DIS (0x0 << 15) | ||
591 | #define RT5668_IRQ_POW_SAV_EN (0x1 << 15) | ||
592 | #define RT5668_IRQ_POW_SAV_JD1_MASK (0x1 << 14) | ||
593 | #define RT5668_IRQ_POW_SAV_JD1_SHIFT 14 | ||
594 | #define RT5668_IRQ_POW_SAV_JD1_DIS (0x0 << 14) | ||
595 | #define RT5668_IRQ_POW_SAV_JD1_EN (0x1 << 14) | ||
596 | |||
597 | /* IRQ Control 1 (0x00b6) */ | ||
598 | #define RT5668_EN_CB_JD_MASK (0x1 << 3) | ||
599 | #define RT5668_EN_CB_JD_SHIFT 3 | ||
600 | #define RT5668_EN_CB_JD_EN (0x1 << 3) | ||
601 | #define RT5668_EN_CB_JD_DIS (0x0 << 3) | ||
602 | |||
603 | /* IRQ Control 3 (0x00b8) */ | ||
604 | #define RT5668_EN_IRQ_INLINE_MASK (0x1 << 6) | ||
605 | #define RT5668_EN_IRQ_INLINE_SHIFT 6 | ||
606 | #define RT5668_EN_IRQ_INLINE_BYP (0x0 << 6) | ||
607 | #define RT5668_EN_IRQ_INLINE_NOR (0x1 << 6) | ||
608 | |||
609 | /* GPIO Control 1 (0x00c0) */ | ||
610 | #define RT5668_GP1_PIN_MASK (0x1 << 15) | ||
611 | #define RT5668_GP1_PIN_SHIFT 15 | ||
612 | #define RT5668_GP1_PIN_GPIO1 (0x0 << 15) | ||
613 | #define RT5668_GP1_PIN_IRQ (0x1 << 15) | ||
614 | |||
615 | /* GPIO Control 2 (0x00c1) */ | ||
616 | #define RT5668_GP4_PIN_CONF_MASK (0x1 << 5) | ||
617 | #define RT5668_GP4_PIN_CONF_SHIFT 5 | ||
618 | #define RT5668_GP4_PIN_CONF_INPUT (0x0 << 5) | ||
619 | #define RT5668_GP4_PIN_CONF_OUTPUT (0x1 << 5) | ||
620 | |||
621 | /* GPIO Control 2 (0x00c2) */ | ||
622 | #define RT5668_GP8_PIN_CONF_MASK (0x1 << 13) | ||
623 | #define RT5668_GP8_PIN_CONF_SHIFT 13 | ||
624 | #define RT5668_GP8_PIN_CONF_INPUT (0x0 << 13) | ||
625 | #define RT5668_GP8_PIN_CONF_OUTPUT (0x1 << 13) | ||
626 | |||
627 | /* 4 Buttons Inline Command Function 1 (0x00df) */ | ||
628 | #define RT5668_4BTN_CLK_DEB_MASK (0x3 << 2) | ||
629 | #define RT5668_4BTN_CLK_DEB_SHIFT 2 | ||
630 | #define RT5668_4BTN_CLK_DEB_8MS (0x0 << 2) | ||
631 | #define RT5668_4BTN_CLK_DEB_16MS (0x1 << 2) | ||
632 | #define RT5668_4BTN_CLK_DEB_32MS (0x2 << 2) | ||
633 | #define RT5668_4BTN_CLK_DEB_65MS (0x3 << 2) | ||
634 | |||
635 | /* Inline Command Function 6 (0x00e0) */ | ||
636 | #define RT5668_EN_4BTN_INL_MASK (0x1 << 15) | ||
637 | #define RT5668_EN_4BTN_INL_SHIFT 15 | ||
638 | #define RT5668_EN_4BTN_INL_DIS (0x0 << 15) | ||
639 | #define RT5668_EN_4BTN_INL_EN (0x1 << 15) | ||
640 | #define RT5668_RESET_4BTN_INL_MASK (0x1 << 14) | ||
641 | #define RT5668_RESET_4BTN_INL_SHIFT 14 | ||
642 | #define RT5668_RESET_4BTN_INL_RESET (0x0 << 14) | ||
643 | #define RT5668_RESET_4BTN_INL_NOR (0x1 << 14) | ||
644 | |||
645 | /* Digital Misc Control (0x00fa) */ | ||
646 | #define RT5668_DIG_GATE_CTRL_MASK 0x1 | ||
647 | #define RT5668_DIG_GATE_CTRL_SHIFT (0) | ||
648 | #define RT5668_DIG_GATE_CTRL_DIS 0x0 | ||
649 | #define RT5668_DIG_GATE_CTRL_EN 0x1 | ||
650 | |||
651 | /* Chopper and Clock control for DAC L (0x013a)*/ | ||
652 | #define RT5668_CKXEN_DAC1_MASK (0x1 << 13) | ||
653 | #define RT5668_CKXEN_DAC1_SHIFT 13 | ||
654 | #define RT5668_CKGEN_DAC1_MASK (0x1 << 12) | ||
655 | #define RT5668_CKGEN_DAC1_SHIFT 12 | ||
656 | |||
657 | /* Chopper and Clock control for ADC (0x013b)*/ | ||
658 | #define RT5668_CKXEN_ADCC_MASK (0x1 << 13) | ||
659 | #define RT5668_CKXEN_ADCC_SHIFT 13 | ||
660 | #define RT5668_CKGEN_ADCC_MASK (0x1 << 12) | ||
661 | #define RT5668_CKGEN_ADCC_SHIFT 12 | ||
662 | |||
663 | /* HP Behavior Logic Control 2 (0x01db) */ | ||
664 | #define RT5668_HP_SIG_SRC1_MASK (0x3) | ||
665 | #define RT5668_HP_SIG_SRC1_SHIFT 0 | ||
666 | #define RT5668_HP_SIG_SRC1_HP_DC (0x0) | ||
667 | #define RT5668_HP_SIG_SRC1_HP_CALIB (0x1) | ||
668 | #define RT5668_HP_SIG_SRC1_REG (0x2) | ||
669 | #define RT5668_HP_SIG_SRC1_SILENCE (0x3) | ||
670 | |||
671 | /* RT5663 specific register */ | ||
672 | #define RT5663_HP_OUT_EN 0x0002 | ||
673 | #define RT5663_HP_LCH_DRE 0x0005 | ||
674 | #define RT5663_HP_RCH_DRE 0x0006 | ||
675 | #define RT5663_CALIB_BST 0x000a | ||
676 | #define RT5663_RECMIX 0x0010 | ||
677 | #define RT5663_SIL_DET_CTL 0x0015 | ||
678 | #define RT5663_PWR_SAV_SILDET 0x0016 | ||
679 | #define RT5663_SIDETONE_CTL 0x0018 | ||
680 | #define RT5663_STO1_DAC_DIG_VOL 0x0019 | ||
681 | #define RT5663_STO1_ADC_DIG_VOL 0x001c | ||
682 | #define RT5663_STO1_BOOST 0x001f | ||
683 | #define RT5663_HP_IMP_GAIN_1 0x0022 | ||
684 | #define RT5663_HP_IMP_GAIN_2 0x0023 | ||
685 | #define RT5663_STO1_ADC_MIXER 0x0026 | ||
686 | #define RT5663_AD_DA_MIXER 0x0029 | ||
687 | #define RT5663_STO_DAC_MIXER 0x002a | ||
688 | #define RT5663_DIG_SIDE_MIXER 0x002c | ||
689 | #define RT5663_BYPASS_STO_DAC 0x002d | ||
690 | #define RT5663_CALIB_REC_MIX 0x0040 | ||
691 | #define RT5663_PWR_DIG_1 0x0061 | ||
692 | #define RT5663_PWR_DIG_2 0x0062 | ||
693 | #define RT5663_PWR_ANLG_1 0x0063 | ||
694 | #define RT5663_PWR_ANLG_2 0x0064 | ||
695 | #define RT5663_PWR_ANLG_3 0x0065 | ||
696 | #define RT5663_PWR_MIXER 0x0066 | ||
697 | #define RT5663_SIG_CLK_DET 0x006b | ||
698 | #define RT5663_PRE_DIV_GATING_1 0x006e | ||
699 | #define RT5663_PRE_DIV_GATING_2 0x006f | ||
700 | #define RT5663_I2S1_SDP 0x0070 | ||
701 | #define RT5663_ADDA_CLK_1 0x0073 | ||
702 | #define RT5663_ADDA_RST 0x0074 | ||
703 | #define RT5663_FRAC_DIV_1 0x0075 | ||
704 | #define RT5663_FRAC_DIV_2 0x0076 | ||
705 | #define RT5663_TDM_1 0x0077 | ||
706 | #define RT5663_TDM_2 0x0078 | ||
707 | #define RT5663_TDM_3 0x0079 | ||
708 | #define RT5663_TDM_4 0x007a | ||
709 | #define RT5663_TDM_5 0x007b | ||
710 | #define RT5663_GLB_CLK 0x0080 | ||
711 | #define RT5663_PLL_1 0x0081 | ||
712 | #define RT5663_PLL_2 0x0082 | ||
713 | #define RT5663_ASRC_1 0x0083 | ||
714 | #define RT5663_ASRC_2 0x0084 | ||
715 | #define RT5663_ASRC_4 0x0086 | ||
716 | #define RT5663_DUMMY_REG 0x0087 | ||
717 | #define RT5663_ASRC_8 0x008a | ||
718 | #define RT5663_ASRC_9 0x008b | ||
719 | #define RT5663_ASRC_11 0x008c | ||
720 | #define RT5663_DEPOP_1 0x008e | ||
721 | #define RT5663_DEPOP_2 0x008f | ||
722 | #define RT5663_DEPOP_3 0x0090 | ||
723 | #define RT5663_HP_CHARGE_PUMP_1 0x0091 | ||
724 | #define RT5663_HP_CHARGE_PUMP_2 0x0092 | ||
725 | #define RT5663_MICBIAS_1 0x0093 | ||
726 | #define RT5663_RC_CLK 0x0094 | ||
727 | #define RT5663_ASRC_11_2 0x0097 | ||
728 | #define RT5663_DUMMY_REG_2 0x0098 | ||
729 | #define RT5663_REC_PATH_GAIN 0x009a | ||
730 | #define RT5663_AUTO_1MRC_CLK 0x009f | ||
731 | #define RT5663_ADC_EQ_1 0x00ae | ||
732 | #define RT5663_ADC_EQ_2 0x00af | ||
733 | #define RT5663_IRQ_1 0x00b6 | ||
734 | #define RT5663_IRQ_2 0x00b7 | ||
735 | #define RT5663_IRQ_3 0x00b8 | ||
736 | #define RT5663_IRQ_4 0x00ba | ||
737 | #define RT5663_IRQ_5 0x00bb | ||
738 | #define RT5663_INT_ST_1 0x00be | ||
739 | #define RT5663_INT_ST_2 0x00bf | ||
740 | #define RT5663_GPIO_1 0x00c0 | ||
741 | #define RT5663_GPIO_2 0x00c1 | ||
742 | #define RT5663_GPIO_STA 0x00c5 | ||
743 | #define RT5663_SIN_GEN_1 0x00cb | ||
744 | #define RT5663_SIN_GEN_2 0x00cc | ||
745 | #define RT5663_SIN_GEN_3 0x00cd | ||
746 | #define RT5663_SOF_VOL_ZC1 0x00d9 | ||
747 | #define RT5663_IL_CMD_1 0x00db | ||
748 | #define RT5663_IL_CMD_2 0x00dc | ||
749 | #define RT5663_IL_CMD_3 0x00dd | ||
750 | #define RT5663_IL_CMD_4 0x00de | ||
751 | #define RT5663_IL_CMD_5 0x00df | ||
752 | #define RT5663_IL_CMD_6 0x00e0 | ||
753 | #define RT5663_IL_CMD_7 0x00e1 | ||
754 | #define RT5663_IL_CMD_8 0x00e2 | ||
755 | #define RT5663_IL_CMD_PWRSAV1 0x00e4 | ||
756 | #define RT5663_IL_CMD_PWRSAV2 0x00e5 | ||
757 | #define RT5663_EM_JACK_TYPE_1 0x00e6 | ||
758 | #define RT5663_EM_JACK_TYPE_2 0x00e7 | ||
759 | #define RT5663_EM_JACK_TYPE_3 0x00e8 | ||
760 | #define RT5663_EM_JACK_TYPE_4 0x00e9 | ||
761 | #define RT5663_EM_JACK_TYPE_5 0x00ea | ||
762 | #define RT5663_EM_JACK_TYPE_6 0x00eb | ||
763 | #define RT5663_STO1_HPF_ADJ1 0x00ec | ||
764 | #define RT5663_STO1_HPF_ADJ2 0x00ed | ||
765 | #define RT5663_FAST_OFF_MICBIAS 0x00f4 | ||
766 | #define RT5663_JD_CTRL1 0x00f6 | ||
767 | #define RT5663_JD_CTRL2 0x00f8 | ||
768 | #define RT5663_DIG_MISC 0x00fa | ||
769 | #define RT5663_DIG_VOL_ZCD 0x0100 | ||
770 | #define RT5663_ANA_BIAS_CUR_1 0x0108 | ||
771 | #define RT5663_ANA_BIAS_CUR_2 0x0109 | ||
772 | #define RT5663_ANA_BIAS_CUR_3 0x010a | ||
773 | #define RT5663_ANA_BIAS_CUR_4 0x010b | ||
774 | #define RT5663_ANA_BIAS_CUR_5 0x010c | ||
775 | #define RT5663_ANA_BIAS_CUR_6 0x010d | ||
776 | #define RT5663_BIAS_CUR_5 0x010e | ||
777 | #define RT5663_BIAS_CUR_6 0x010f | ||
778 | #define RT5663_BIAS_CUR_7 0x0110 | ||
779 | #define RT5663_BIAS_CUR_8 0x0111 | ||
780 | #define RT5663_DACREF_LDO 0x0112 | ||
781 | #define RT5663_DUMMY_REG_3 0x0113 | ||
782 | #define RT5663_BIAS_CUR_9 0x0114 | ||
783 | #define RT5663_DUMMY_REG_4 0x0116 | ||
784 | #define RT5663_VREFADJ_OP 0x0117 | ||
785 | #define RT5663_VREF_RECMIX 0x0118 | ||
786 | #define RT5663_CHARGE_PUMP_1 0x0125 | ||
787 | #define RT5663_CHARGE_PUMP_1_2 0x0126 | ||
788 | #define RT5663_CHARGE_PUMP_1_3 0x0127 | ||
789 | #define RT5663_CHARGE_PUMP_2 0x0128 | ||
790 | #define RT5663_DIG_IN_PIN1 0x0132 | ||
791 | #define RT5663_PAD_DRV_CTL 0x0137 | ||
792 | #define RT5663_PLL_INT_REG 0x0139 | ||
793 | #define RT5663_CHOP_DAC_L 0x013a | ||
794 | #define RT5663_CHOP_ADC 0x013b | ||
795 | #define RT5663_CALIB_ADC 0x013c | ||
796 | #define RT5663_CHOP_DAC_R 0x013d | ||
797 | #define RT5663_DUMMY_CTL_DACLR 0x013e | ||
798 | #define RT5663_DUMMY_REG_5 0x0140 | ||
799 | #define RT5663_SOFT_RAMP 0x0141 | ||
800 | #define RT5663_TEST_MODE_1 0x0144 | ||
801 | #define RT5663_TEST_MODE_2 0x0145 | ||
802 | #define RT5663_TEST_MODE_3 0x0146 | ||
803 | #define RT5663_STO_DRE_1 0x0160 | ||
804 | #define RT5663_STO_DRE_2 0x0161 | ||
805 | #define RT5663_STO_DRE_3 0x0162 | ||
806 | #define RT5663_STO_DRE_4 0x0163 | ||
807 | #define RT5663_STO_DRE_5 0x0164 | ||
808 | #define RT5663_STO_DRE_6 0x0165 | ||
809 | #define RT5663_STO_DRE_7 0x0166 | ||
810 | #define RT5663_STO_DRE_8 0x0167 | ||
811 | #define RT5663_STO_DRE_9 0x0168 | ||
812 | #define RT5663_STO_DRE_10 0x0169 | ||
813 | #define RT5663_MIC_DECRO_1 0x0180 | ||
814 | #define RT5663_MIC_DECRO_2 0x0181 | ||
815 | #define RT5663_MIC_DECRO_3 0x0182 | ||
816 | #define RT5663_MIC_DECRO_4 0x0183 | ||
817 | #define RT5663_MIC_DECRO_5 0x0184 | ||
818 | #define RT5663_MIC_DECRO_6 0x0185 | ||
819 | #define RT5663_HP_DECRO_1 0x01b0 | ||
820 | #define RT5663_HP_DECRO_2 0x01b1 | ||
821 | #define RT5663_HP_DECRO_3 0x01b2 | ||
822 | #define RT5663_HP_DECRO_4 0x01b3 | ||
823 | #define RT5663_HP_DECOUP 0x01b4 | ||
824 | #define RT5663_HP_IMP_SEN_MAP8 0x01b5 | ||
825 | #define RT5663_HP_IMP_SEN_MAP9 0x01b6 | ||
826 | #define RT5663_HP_IMP_SEN_MAP10 0x01b7 | ||
827 | #define RT5663_HP_IMP_SEN_MAP11 0x01b8 | ||
828 | #define RT5663_HP_IMP_SEN_1 0x01c0 | ||
829 | #define RT5663_HP_IMP_SEN_2 0x01c1 | ||
830 | #define RT5663_HP_IMP_SEN_3 0x01c2 | ||
831 | #define RT5663_HP_IMP_SEN_4 0x01c3 | ||
832 | #define RT5663_HP_IMP_SEN_5 0x01c4 | ||
833 | #define RT5663_HP_IMP_SEN_6 0x01c5 | ||
834 | #define RT5663_HP_IMP_SEN_7 0x01c6 | ||
835 | #define RT5663_HP_IMP_SEN_8 0x01c7 | ||
836 | #define RT5663_HP_IMP_SEN_9 0x01c8 | ||
837 | #define RT5663_HP_IMP_SEN_10 0x01c9 | ||
838 | #define RT5663_HP_IMP_SEN_11 0x01ca | ||
839 | #define RT5663_HP_IMP_SEN_12 0x01cb | ||
840 | #define RT5663_HP_IMP_SEN_13 0x01cc | ||
841 | #define RT5663_HP_IMP_SEN_14 0x01cd | ||
842 | #define RT5663_HP_IMP_SEN_15 0x01ce | ||
843 | #define RT5663_HP_IMP_SEN_16 0x01cf | ||
844 | #define RT5663_HP_IMP_SEN_17 0x01d0 | ||
845 | #define RT5663_HP_IMP_SEN_18 0x01d1 | ||
846 | #define RT5663_HP_IMP_SEN_19 0x01d2 | ||
847 | #define RT5663_HP_IMPSEN_DIG5 0x01d3 | ||
848 | #define RT5663_HP_IMPSEN_MAP1 0x01d4 | ||
849 | #define RT5663_HP_IMPSEN_MAP2 0x01d5 | ||
850 | #define RT5663_HP_IMPSEN_MAP3 0x01d6 | ||
851 | #define RT5663_HP_IMPSEN_MAP4 0x01d7 | ||
852 | #define RT5663_HP_IMPSEN_MAP5 0x01d8 | ||
853 | #define RT5663_HP_IMPSEN_MAP7 0x01d9 | ||
854 | #define RT5663_HP_LOGIC_1 0x01da | ||
855 | #define RT5663_HP_LOGIC_2 0x01db | ||
856 | #define RT5663_HP_CALIB_1 0x01dd | ||
857 | #define RT5663_HP_CALIB_1_1 0x01de | ||
858 | #define RT5663_HP_CALIB_2 0x01df | ||
859 | #define RT5663_HP_CALIB_3 0x01e0 | ||
860 | #define RT5663_HP_CALIB_4 0x01e1 | ||
861 | #define RT5663_HP_CALIB_5 0x01e2 | ||
862 | #define RT5663_HP_CALIB_5_1 0x01e3 | ||
863 | #define RT5663_HP_CALIB_6 0x01e4 | ||
864 | #define RT5663_HP_CALIB_7 0x01e5 | ||
865 | #define RT5663_HP_CALIB_9 0x01e6 | ||
866 | #define RT5663_HP_CALIB_10 0x01e7 | ||
867 | #define RT5663_HP_CALIB_11 0x01e8 | ||
868 | #define RT5663_HP_CALIB_ST1 0x01ea | ||
869 | #define RT5663_HP_CALIB_ST2 0x01eb | ||
870 | #define RT5663_HP_CALIB_ST3 0x01ec | ||
871 | #define RT5663_HP_CALIB_ST4 0x01ed | ||
872 | #define RT5663_HP_CALIB_ST5 0x01ee | ||
873 | #define RT5663_HP_CALIB_ST6 0x01ef | ||
874 | #define RT5663_HP_CALIB_ST7 0x01f0 | ||
875 | #define RT5663_HP_CALIB_ST8 0x01f1 | ||
876 | #define RT5663_HP_CALIB_ST9 0x01f2 | ||
877 | #define RT5663_HP_AMP_DET 0x0200 | ||
878 | #define RT5663_DUMMY_REG_6 0x0201 | ||
879 | #define RT5663_HP_BIAS 0x0202 | ||
880 | #define RT5663_CBJ_1 0x0250 | ||
881 | #define RT5663_CBJ_2 0x0251 | ||
882 | #define RT5663_CBJ_3 0x0252 | ||
883 | #define RT5663_DUMMY_1 0x02fa | ||
884 | #define RT5663_DUMMY_2 0x02fb | ||
885 | #define RT5663_DUMMY_3 0x02fc | ||
886 | #define RT5663_ANA_JD 0x0300 | ||
887 | #define RT5663_ADC_LCH_LPF1_A1 0x03d0 | ||
888 | #define RT5663_ADC_RCH_LPF1_A1 0x03d1 | ||
889 | #define RT5663_ADC_LCH_LPF1_H0 0x03d2 | ||
890 | #define RT5663_ADC_RCH_LPF1_H0 0x03d3 | ||
891 | #define RT5663_ADC_LCH_BPF1_A1 0x03d4 | ||
892 | #define RT5663_ADC_RCH_BPF1_A1 0x03d5 | ||
893 | #define RT5663_ADC_LCH_BPF1_A2 0x03d6 | ||
894 | #define RT5663_ADC_RCH_BPF1_A2 0x03d7 | ||
895 | #define RT5663_ADC_LCH_BPF1_H0 0x03d8 | ||
896 | #define RT5663_ADC_RCH_BPF1_H0 0x03d9 | ||
897 | #define RT5663_ADC_LCH_BPF2_A1 0x03da | ||
898 | #define RT5663_ADC_RCH_BPF2_A1 0x03db | ||
899 | #define RT5663_ADC_LCH_BPF2_A2 0x03dc | ||
900 | #define RT5663_ADC_RCH_BPF2_A2 0x03dd | ||
901 | #define RT5663_ADC_LCH_BPF2_H0 0x03de | ||
902 | #define RT5663_ADC_RCH_BPF2_H0 0x03df | ||
903 | #define RT5663_ADC_LCH_BPF3_A1 0x03e0 | ||
904 | #define RT5663_ADC_RCH_BPF3_A1 0x03e1 | ||
905 | #define RT5663_ADC_LCH_BPF3_A2 0x03e2 | ||
906 | #define RT5663_ADC_RCH_BPF3_A2 0x03e3 | ||
907 | #define RT5663_ADC_LCH_BPF3_H0 0x03e4 | ||
908 | #define RT5663_ADC_RCH_BPF3_H0 0x03e5 | ||
909 | #define RT5663_ADC_LCH_BPF4_A1 0x03e6 | ||
910 | #define RT5663_ADC_RCH_BPF4_A1 0x03e7 | ||
911 | #define RT5663_ADC_LCH_BPF4_A2 0x03e8 | ||
912 | #define RT5663_ADC_RCH_BPF4_A2 0x03e9 | ||
913 | #define RT5663_ADC_LCH_BPF4_H0 0x03ea | ||
914 | #define RT5663_ADC_RCH_BPF4_H0 0x03eb | ||
915 | #define RT5663_ADC_LCH_HPF1_A1 0x03ec | ||
916 | #define RT5663_ADC_RCH_HPF1_A1 0x03ed | ||
917 | #define RT5663_ADC_LCH_HPF1_H0 0x03ee | ||
918 | #define RT5663_ADC_RCH_HPF1_H0 0x03ef | ||
919 | #define RT5663_ADC_EQ_PRE_VOL_L 0x03f0 | ||
920 | #define RT5663_ADC_EQ_PRE_VOL_R 0x03f1 | ||
921 | #define RT5663_ADC_EQ_POST_VOL_L 0x03f2 | ||
922 | #define RT5663_ADC_EQ_POST_VOL_R 0x03f3 | ||
923 | |||
924 | /* RT5663: RECMIX Control (0x0010) */ | ||
925 | #define RT5663_RECMIX1_BST1_MASK (0x1) | ||
926 | #define RT5663_RECMIX1_BST1_SHIFT 0 | ||
927 | #define RT5663_RECMIX1_BST1_ON (0x0) | ||
928 | #define RT5663_RECMIX1_BST1_OFF (0x1) | ||
929 | |||
930 | /* RT5663: Bypass Stereo1 DAC Mixer Control (0x002d) */ | ||
931 | #define RT5663_DACL1_SRC_MASK (0x1 << 3) | ||
932 | #define RT5663_DACL1_SRC_SHIFT 3 | ||
933 | #define RT5663_DACR1_SRC_MASK (0x1 << 2) | ||
934 | #define RT5663_DACR1_SRC_SHIFT 2 | ||
935 | |||
936 | /* RT5663: TDM control 2 (0x0078) */ | ||
937 | #define RT5663_DATA_SWAP_ADCDAT1_MASK (0x3 << 14) | ||
938 | #define RT5663_DATA_SWAP_ADCDAT1_SHIFT 14 | ||
939 | #define RT5663_DATA_SWAP_ADCDAT1_LR (0x0 << 14) | ||
940 | #define RT5663_DATA_SWAP_ADCDAT1_RL (0x1 << 14) | ||
941 | #define RT5663_DATA_SWAP_ADCDAT1_LL (0x2 << 14) | ||
942 | #define RT5663_DATA_SWAP_ADCDAT1_RR (0x3 << 14) | ||
943 | |||
944 | /* RT5663: TDM control 5 (0x007b) */ | ||
945 | #define RT5663_TDM_LENGTN_MASK (0x3) | ||
946 | #define RT5663_TDM_LENGTN_SHIFT 0 | ||
947 | #define RT5663_TDM_LENGTN_16 (0x0) | ||
948 | #define RT5663_TDM_LENGTN_20 (0x1) | ||
949 | #define RT5663_TDM_LENGTN_24 (0x2) | ||
950 | #define RT5663_TDM_LENGTN_32 (0x3) | ||
951 | |||
952 | /* RT5663: Global Clock Control (0x0080) */ | ||
953 | #define RT5663_SCLK_SRC_MASK (0x3 << 14) | ||
954 | #define RT5663_SCLK_SRC_SHIFT 14 | ||
955 | #define RT5663_SCLK_SRC_MCLK (0x0 << 14) | ||
956 | #define RT5663_SCLK_SRC_PLL1 (0x1 << 14) | ||
957 | #define RT5663_SCLK_SRC_RCCLK (0x2 << 14) | ||
958 | #define RT5663_PLL1_SRC_MASK (0x7 << 11) | ||
959 | #define RT5663_PLL1_SRC_SHIFT 11 | ||
960 | #define RT5663_PLL1_SRC_MCLK (0x0 << 11) | ||
961 | #define RT5663_PLL1_SRC_BCLK1 (0x1 << 11) | ||
962 | |||
963 | /* PLL tracking mode 1 (0x0083) */ | ||
964 | #define RT5663_I2S1_ASRC_MASK (0x1 << 11) | ||
965 | #define RT5663_I2S1_ASRC_SHIFT 11 | ||
966 | #define RT5663_DAC_STO1_ASRC_MASK (0x1 << 10) | ||
967 | #define RT5663_DAC_STO1_ASRC_SHIFT 10 | ||
968 | #define RT5663_ADC_STO1_ASRC_MASK (0x1 << 3) | ||
969 | #define RT5663_ADC_STO1_ASRC_SHIFT 3 | ||
970 | |||
971 | /* PLL tracking mode 2 (0x0084)*/ | ||
972 | #define RT5663_DA_STO1_TRACK_MASK (0x7 << 12) | ||
973 | #define RT5663_DA_STO1_TRACK_SHIFT 12 | ||
974 | #define RT5663_DA_STO1_TRACK_SYSCLK (0x0 << 12) | ||
975 | #define RT5663_DA_STO1_TRACK_I2S1 (0x1 << 12) | ||
976 | #define RT5663_AD_STO1_TRACK_MASK (0x7) | ||
977 | #define RT5663_AD_STO1_TRACK_SHIFT 0 | ||
978 | #define RT5663_AD_STO1_TRACK_SYSCLK (0x0) | ||
979 | #define RT5663_AD_STO1_TRACK_I2S1 (0x1) | ||
980 | |||
981 | /* RT5663: HPOUT Charge pump control 1 (0x0091) */ | ||
982 | #define RT5663_SI_HP_MASK (0x1 << 12) | ||
983 | #define RT5663_SI_HP_SHIFT 12 | ||
984 | #define RT5663_SI_HP_EN (0x1 << 12) | ||
985 | #define RT5663_SI_HP_DIS (0x0 << 12) | ||
986 | |||
987 | /* RT5663: GPIO Control 2 (0x00b6) */ | ||
988 | #define RT5663_GP1_PIN_CONF_MASK (0x1 << 2) | ||
989 | #define RT5663_GP1_PIN_CONF_SHIFT 2 | ||
990 | #define RT5663_GP1_PIN_CONF_OUTPUT (0x1 << 2) | ||
991 | #define RT5663_GP1_PIN_CONF_INPUT (0x0 << 2) | ||
992 | |||
993 | /* RT5663: GPIO Control 2 (0x00b7) */ | ||
994 | #define RT5663_EN_IRQ_INLINE_MASK (0x1 << 3) | ||
995 | #define RT5663_EN_IRQ_INLINE_SHIFT 3 | ||
996 | #define RT5663_EN_IRQ_INLINE_NOR (0x1 << 3) | ||
997 | #define RT5663_EN_IRQ_INLINE_BYP (0x0 << 3) | ||
998 | |||
999 | /* RT5663: IRQ Control 1 (0x00c1) */ | ||
1000 | #define RT5663_EN_IRQ_JD1_MASK (0x1 << 6) | ||
1001 | #define RT5663_EN_IRQ_JD1_SHIFT 6 | ||
1002 | #define RT5663_EN_IRQ_JD1_EN (0x1 << 6) | ||
1003 | #define RT5663_EN_IRQ_JD1_DIS (0x0 << 6) | ||
1004 | |||
1005 | /* RT5663: Inline Command Function 2 (0x00dc) */ | ||
1006 | #define RT5663_PWR_MIC_DET_MASK (0x1) | ||
1007 | #define RT5663_PWR_MIC_DET_SHIFT 0 | ||
1008 | #define RT5663_PWR_MIC_DET_ON (0x1) | ||
1009 | #define RT5663_PWR_MIC_DET_OFF (0x0) | ||
1010 | |||
1011 | /* RT5663: Embeeded Jack and Type Detection Control 1 (0x00e6)*/ | ||
1012 | #define RT5663_CBJ_DET_MASK (0x1 << 15) | ||
1013 | #define RT5663_CBJ_DET_SHIFT 15 | ||
1014 | #define RT5663_CBJ_DET_DIS (0x0 << 15) | ||
1015 | #define RT5663_CBJ_DET_EN (0x1 << 15) | ||
1016 | #define RT5663_EXT_JD_MASK (0x1 << 11) | ||
1017 | #define RT5663_EXT_JD_SHIFT 11 | ||
1018 | #define RT5663_EXT_JD_EN (0x1 << 11) | ||
1019 | #define RT5663_EXT_JD_DIS (0x0 << 11) | ||
1020 | #define RT5663_POL_EXT_JD_MASK (0x1 << 10) | ||
1021 | #define RT5663_POL_EXT_JD_SHIFT 10 | ||
1022 | #define RT5663_POL_EXT_JD_EN (0x1 << 10) | ||
1023 | #define RT5663_POL_EXT_JD_DIS (0x0 << 10) | ||
1024 | |||
1025 | /* RT5663: DACREF LDO Control (0x0112)*/ | ||
1026 | #define RT5663_PWR_LDO_DACREFL_MASK (0x1 << 9) | ||
1027 | #define RT5663_PWR_LDO_DACREFL_SHIFT 9 | ||
1028 | #define RT5663_PWR_LDO_DACREFR_MASK (0x1 << 1) | ||
1029 | #define RT5663_PWR_LDO_DACREFR_SHIFT 1 | ||
1030 | |||
1031 | /* RT5663: Stereo Dynamic Range Enhancement Control 9 (0x0168, 0x0169)*/ | ||
1032 | #define RT5663_DRE_GAIN_HP_MASK (0x1f) | ||
1033 | #define RT5663_DRE_GAIN_HP_SHIFT 0 | ||
1034 | |||
1035 | /* RT5663: Combo Jack Control (0x0250) */ | ||
1036 | #define RT5663_INBUF_CBJ_BST1_MASK (0x1 << 11) | ||
1037 | #define RT5663_INBUF_CBJ_BST1_SHIFT 11 | ||
1038 | #define RT5663_INBUF_CBJ_BST1_ON (0x1 << 11) | ||
1039 | #define RT5663_INBUF_CBJ_BST1_OFF (0x0 << 11) | ||
1040 | #define RT5663_CBJ_SENSE_BST1_MASK (0x1 << 10) | ||
1041 | #define RT5663_CBJ_SENSE_BST1_SHIFT 10 | ||
1042 | #define RT5663_CBJ_SENSE_BST1_L (0x1 << 10) | ||
1043 | #define RT5663_CBJ_SENSE_BST1_R (0x0 << 10) | ||
1044 | |||
1045 | /* RT5663: Combo Jack Control (0x0251) */ | ||
1046 | #define RT5663_GAIN_BST1_MASK (0xf) | ||
1047 | #define RT5663_GAIN_BST1_SHIFT 0 | ||
1048 | |||
1049 | /* RT5663: Dummy register 1 (0x02fa) */ | ||
1050 | #define RT5663_EMB_CLK_MASK (0x1 << 9) | ||
1051 | #define RT5663_EMB_CLK_SHIFT 9 | ||
1052 | #define RT5663_EMB_CLK_EN (0x1 << 9) | ||
1053 | #define RT5663_EMB_CLK_DIS (0x0 << 9) | ||
1054 | #define RT5663_HPA_CPL_BIAS_MASK (0x7 << 6) | ||
1055 | #define RT5663_HPA_CPL_BIAS_SHIFT 6 | ||
1056 | #define RT5663_HPA_CPL_BIAS_0_5 (0x0 << 6) | ||
1057 | #define RT5663_HPA_CPL_BIAS_1 (0x1 << 6) | ||
1058 | #define RT5663_HPA_CPL_BIAS_2 (0x2 << 6) | ||
1059 | #define RT5663_HPA_CPL_BIAS_3 (0x3 << 6) | ||
1060 | #define RT5663_HPA_CPL_BIAS_4_1 (0x4 << 6) | ||
1061 | #define RT5663_HPA_CPL_BIAS_4_2 (0x5 << 6) | ||
1062 | #define RT5663_HPA_CPL_BIAS_6 (0x6 << 6) | ||
1063 | #define RT5663_HPA_CPL_BIAS_8 (0x7 << 6) | ||
1064 | #define RT5663_HPA_CPR_BIAS_MASK (0x7 << 3) | ||
1065 | #define RT5663_HPA_CPR_BIAS_SHIFT 3 | ||
1066 | #define RT5663_HPA_CPR_BIAS_0_5 (0x0 << 3) | ||
1067 | #define RT5663_HPA_CPR_BIAS_1 (0x1 << 3) | ||
1068 | #define RT5663_HPA_CPR_BIAS_2 (0x2 << 3) | ||
1069 | #define RT5663_HPA_CPR_BIAS_3 (0x3 << 3) | ||
1070 | #define RT5663_HPA_CPR_BIAS_4_1 (0x4 << 3) | ||
1071 | #define RT5663_HPA_CPR_BIAS_4_2 (0x5 << 3) | ||
1072 | #define RT5663_HPA_CPR_BIAS_6 (0x6 << 3) | ||
1073 | #define RT5663_HPA_CPR_BIAS_8 (0x7 << 3) | ||
1074 | #define RT5663_DUMMY_BIAS_MASK (0x7) | ||
1075 | #define RT5663_DUMMY_BIAS_SHIFT 0 | ||
1076 | #define RT5663_DUMMY_BIAS_0_5 (0x0) | ||
1077 | #define RT5663_DUMMY_BIAS_1 (0x1) | ||
1078 | #define RT5663_DUMMY_BIAS_2 (0x2) | ||
1079 | #define RT5663_DUMMY_BIAS_3 (0x3) | ||
1080 | #define RT5663_DUMMY_BIAS_4_1 (0x4) | ||
1081 | #define RT5663_DUMMY_BIAS_4_2 (0x5) | ||
1082 | #define RT5663_DUMMY_BIAS_6 (0x6) | ||
1083 | #define RT5663_DUMMY_BIAS_8 (0x7) | ||
1084 | |||
1085 | |||
1086 | /* System Clock Source */ | ||
1087 | enum { | ||
1088 | RT5663_SCLK_S_MCLK, | ||
1089 | RT5663_SCLK_S_PLL1, | ||
1090 | RT5663_SCLK_S_RCCLK, | ||
1091 | }; | ||
1092 | |||
1093 | /* PLL1 Source */ | ||
1094 | enum { | ||
1095 | RT5663_PLL1_S_MCLK, | ||
1096 | RT5663_PLL1_S_BCLK1, | ||
1097 | }; | ||
1098 | |||
1099 | enum { | ||
1100 | RT5663_AIF, | ||
1101 | RT5663_AIFS, | ||
1102 | }; | ||
1103 | |||
1104 | /* asrc clock source */ | ||
1105 | enum { | ||
1106 | RT5663_CLK_SEL_SYS = 0x0, | ||
1107 | RT5663_CLK_SEL_I2S1_ASRC = 0x1, | ||
1108 | }; | ||
1109 | |||
1110 | /* filter mask */ | ||
1111 | enum { | ||
1112 | RT5663_DA_STEREO_FILTER = 0x1, | ||
1113 | RT5663_AD_STEREO_FILTER = 0x2, | ||
1114 | }; | ||
1115 | |||
1116 | int rt5663_set_jack_detect(struct snd_soc_codec *codec, | ||
1117 | struct snd_soc_jack *hs_jack); | ||
1118 | int rt5663_sel_asrc_clk_src(struct snd_soc_codec *codec, | ||
1119 | unsigned int filter_mask, unsigned int clk_src); | ||
1120 | |||
1121 | #endif /* __RT5663_H__ */ | ||
diff --git a/sound/soc/codecs/rt5670.c b/sound/soc/codecs/rt5670.c index 8ef467f64f03..49caf1393aeb 100644 --- a/sound/soc/codecs/rt5670.c +++ b/sound/soc/codecs/rt5670.c | |||
@@ -2777,12 +2777,14 @@ static struct snd_soc_codec_driver soc_codec_dev_rt5670 = { | |||
2777 | .resume = rt5670_resume, | 2777 | .resume = rt5670_resume, |
2778 | .set_bias_level = rt5670_set_bias_level, | 2778 | .set_bias_level = rt5670_set_bias_level, |
2779 | .idle_bias_off = true, | 2779 | .idle_bias_off = true, |
2780 | .controls = rt5670_snd_controls, | 2780 | .component_driver = { |
2781 | .num_controls = ARRAY_SIZE(rt5670_snd_controls), | 2781 | .controls = rt5670_snd_controls, |
2782 | .dapm_widgets = rt5670_dapm_widgets, | 2782 | .num_controls = ARRAY_SIZE(rt5670_snd_controls), |
2783 | .num_dapm_widgets = ARRAY_SIZE(rt5670_dapm_widgets), | 2783 | .dapm_widgets = rt5670_dapm_widgets, |
2784 | .dapm_routes = rt5670_dapm_routes, | 2784 | .num_dapm_widgets = ARRAY_SIZE(rt5670_dapm_widgets), |
2785 | .num_dapm_routes = ARRAY_SIZE(rt5670_dapm_routes), | 2785 | .dapm_routes = rt5670_dapm_routes, |
2786 | .num_dapm_routes = ARRAY_SIZE(rt5670_dapm_routes), | ||
2787 | }, | ||
2786 | }; | 2788 | }; |
2787 | 2789 | ||
2788 | static const struct regmap_config rt5670_regmap = { | 2790 | static const struct regmap_config rt5670_regmap = { |
diff --git a/sound/soc/codecs/rt5677.c b/sound/soc/codecs/rt5677.c index da9483c1c6fb..abc802a5a479 100644 --- a/sound/soc/codecs/rt5677.c +++ b/sound/soc/codecs/rt5677.c | |||
@@ -9,6 +9,7 @@ | |||
9 | * published by the Free Software Foundation. | 9 | * published by the Free Software Foundation. |
10 | */ | 10 | */ |
11 | 11 | ||
12 | #include <linux/acpi.h> | ||
12 | #include <linux/fs.h> | 13 | #include <linux/fs.h> |
13 | #include <linux/module.h> | 14 | #include <linux/module.h> |
14 | #include <linux/moduleparam.h> | 15 | #include <linux/moduleparam.h> |
@@ -40,6 +41,15 @@ | |||
40 | 41 | ||
41 | #define RT5677_PR_BASE (RT5677_PR_RANGE_BASE + (0 * RT5677_PR_SPACING)) | 42 | #define RT5677_PR_BASE (RT5677_PR_RANGE_BASE + (0 * RT5677_PR_SPACING)) |
42 | 43 | ||
44 | /* GPIO indexes defined by ACPI */ | ||
45 | enum { | ||
46 | RT5677_GPIO_PLUG_DET = 0, | ||
47 | RT5677_GPIO_MIC_PRESENT_L = 1, | ||
48 | RT5677_GPIO_HOTWORD_DET_L = 2, | ||
49 | RT5677_GPIO_DSP_INT = 3, | ||
50 | RT5677_GPIO_HP_AMP_SHDN_L = 4, | ||
51 | }; | ||
52 | |||
43 | static const struct regmap_range_cfg rt5677_ranges[] = { | 53 | static const struct regmap_range_cfg rt5677_ranges[] = { |
44 | { | 54 | { |
45 | .name = "PR", | 55 | .name = "PR", |
@@ -4657,7 +4667,7 @@ static int rt5677_to_irq(struct gpio_chip *chip, unsigned offset) | |||
4657 | return regmap_irq_get_virq(data, irq); | 4667 | return regmap_irq_get_virq(data, irq); |
4658 | } | 4668 | } |
4659 | 4669 | ||
4660 | static struct gpio_chip rt5677_template_chip = { | 4670 | static const struct gpio_chip rt5677_template_chip = { |
4661 | .label = "rt5677", | 4671 | .label = "rt5677", |
4662 | .owner = THIS_MODULE, | 4672 | .owner = THIS_MODULE, |
4663 | .direction_output = rt5677_gpio_direction_out, | 4673 | .direction_output = rt5677_gpio_direction_out, |
@@ -4974,12 +4984,14 @@ static struct snd_soc_codec_driver soc_codec_dev_rt5677 = { | |||
4974 | .resume = rt5677_resume, | 4984 | .resume = rt5677_resume, |
4975 | .set_bias_level = rt5677_set_bias_level, | 4985 | .set_bias_level = rt5677_set_bias_level, |
4976 | .idle_bias_off = true, | 4986 | .idle_bias_off = true, |
4977 | .controls = rt5677_snd_controls, | 4987 | .component_driver = { |
4978 | .num_controls = ARRAY_SIZE(rt5677_snd_controls), | 4988 | .controls = rt5677_snd_controls, |
4979 | .dapm_widgets = rt5677_dapm_widgets, | 4989 | .num_controls = ARRAY_SIZE(rt5677_snd_controls), |
4980 | .num_dapm_widgets = ARRAY_SIZE(rt5677_dapm_widgets), | 4990 | .dapm_widgets = rt5677_dapm_widgets, |
4981 | .dapm_routes = rt5677_dapm_routes, | 4991 | .num_dapm_widgets = ARRAY_SIZE(rt5677_dapm_widgets), |
4982 | .num_dapm_routes = ARRAY_SIZE(rt5677_dapm_routes), | 4992 | .dapm_routes = rt5677_dapm_routes, |
4993 | .num_dapm_routes = ARRAY_SIZE(rt5677_dapm_routes), | ||
4994 | }, | ||
4983 | }; | 4995 | }; |
4984 | 4996 | ||
4985 | static const struct regmap_config rt5677_regmap_physical = { | 4997 | static const struct regmap_config rt5677_regmap_physical = { |
@@ -5018,10 +5030,47 @@ static const struct regmap_config rt5677_regmap = { | |||
5018 | static const struct i2c_device_id rt5677_i2c_id[] = { | 5030 | static const struct i2c_device_id rt5677_i2c_id[] = { |
5019 | { "rt5677", RT5677 }, | 5031 | { "rt5677", RT5677 }, |
5020 | { "rt5676", RT5676 }, | 5032 | { "rt5676", RT5676 }, |
5033 | { "RT5677CE:00", RT5677 }, | ||
5021 | { } | 5034 | { } |
5022 | }; | 5035 | }; |
5023 | MODULE_DEVICE_TABLE(i2c, rt5677_i2c_id); | 5036 | MODULE_DEVICE_TABLE(i2c, rt5677_i2c_id); |
5024 | 5037 | ||
5038 | static const struct acpi_gpio_params plug_det_gpio = { RT5677_GPIO_PLUG_DET, 0, false }; | ||
5039 | static const struct acpi_gpio_params mic_present_gpio = { RT5677_GPIO_MIC_PRESENT_L, 0, false }; | ||
5040 | static const struct acpi_gpio_params headphone_enable_gpio = { RT5677_GPIO_HP_AMP_SHDN_L, 0, false }; | ||
5041 | |||
5042 | static const struct acpi_gpio_mapping bdw_rt5677_gpios[] = { | ||
5043 | { "plug-det-gpios", &plug_det_gpio, 1 }, | ||
5044 | { "mic-present-gpios", &mic_present_gpio, 1 }, | ||
5045 | { "headphone-enable-gpios", &headphone_enable_gpio, 1 }, | ||
5046 | { NULL }, | ||
5047 | }; | ||
5048 | |||
5049 | static void rt5677_read_acpi_properties(struct rt5677_priv *rt5677, | ||
5050 | struct device *dev) | ||
5051 | { | ||
5052 | int ret; | ||
5053 | u32 val; | ||
5054 | |||
5055 | ret = acpi_dev_add_driver_gpios(ACPI_COMPANION(dev), | ||
5056 | bdw_rt5677_gpios); | ||
5057 | if (ret) | ||
5058 | dev_warn(dev, "Failed to add driver gpios\n"); | ||
5059 | |||
5060 | if (!device_property_read_u32(dev, "DCLK", &val)) | ||
5061 | rt5677->pdata.dmic2_clk_pin = val; | ||
5062 | |||
5063 | rt5677->pdata.in1_diff = device_property_read_bool(dev, "IN1"); | ||
5064 | rt5677->pdata.in2_diff = device_property_read_bool(dev, "IN2"); | ||
5065 | rt5677->pdata.lout1_diff = device_property_read_bool(dev, "OUT1"); | ||
5066 | rt5677->pdata.lout2_diff = device_property_read_bool(dev, "OUT2"); | ||
5067 | rt5677->pdata.lout3_diff = device_property_read_bool(dev, "OUT3"); | ||
5068 | |||
5069 | device_property_read_u32(dev, "JD1", &rt5677->pdata.jd1_gpio); | ||
5070 | device_property_read_u32(dev, "JD2", &rt5677->pdata.jd2_gpio); | ||
5071 | device_property_read_u32(dev, "JD3", &rt5677->pdata.jd3_gpio); | ||
5072 | } | ||
5073 | |||
5025 | static void rt5677_read_device_properties(struct rt5677_priv *rt5677, | 5074 | static void rt5677_read_device_properties(struct rt5677_priv *rt5677, |
5026 | struct device *dev) | 5075 | struct device *dev) |
5027 | { | 5076 | { |
@@ -5127,8 +5176,12 @@ static int rt5677_i2c_probe(struct i2c_client *i2c, | |||
5127 | 5176 | ||
5128 | if (pdata) | 5177 | if (pdata) |
5129 | rt5677->pdata = *pdata; | 5178 | rt5677->pdata = *pdata; |
5130 | else | 5179 | else if (i2c->dev.of_node) |
5131 | rt5677_read_device_properties(rt5677, &i2c->dev); | 5180 | rt5677_read_device_properties(rt5677, &i2c->dev); |
5181 | else if (ACPI_HANDLE(&i2c->dev)) | ||
5182 | rt5677_read_acpi_properties(rt5677, &i2c->dev); | ||
5183 | else | ||
5184 | return -EINVAL; | ||
5132 | 5185 | ||
5133 | /* pow-ldo2 and reset are optional. The codec pins may be statically | 5186 | /* pow-ldo2 and reset are optional. The codec pins may be statically |
5134 | * connected on the board without gpios. If the gpio device property | 5187 | * connected on the board without gpios. If the gpio device property |
diff --git a/sound/soc/codecs/sgtl5000.c b/sound/soc/codecs/sgtl5000.c index 527b759c1562..1589325855bc 100644 --- a/sound/soc/codecs/sgtl5000.c +++ b/sound/soc/codecs/sgtl5000.c | |||
@@ -411,6 +411,8 @@ static const struct snd_kcontrol_new sgtl5000_snd_controls[] = { | |||
411 | 0, 8, | 411 | 0, 8, |
412 | 0x7f, 1, | 412 | 0x7f, 1, |
413 | headphone_volume), | 413 | headphone_volume), |
414 | SOC_SINGLE("Headphone Playback Switch", SGTL5000_CHIP_ANA_CTRL, | ||
415 | 4, 1, 1), | ||
414 | SOC_SINGLE("Headphone Playback ZC Switch", SGTL5000_CHIP_ANA_CTRL, | 416 | SOC_SINGLE("Headphone Playback ZC Switch", SGTL5000_CHIP_ANA_CTRL, |
415 | 5, 1, 0), | 417 | 5, 1, 0), |
416 | 418 | ||
@@ -423,6 +425,7 @@ static const struct snd_kcontrol_new sgtl5000_snd_controls[] = { | |||
423 | SGTL5000_LINE_OUT_VOL_RIGHT_SHIFT, | 425 | SGTL5000_LINE_OUT_VOL_RIGHT_SHIFT, |
424 | 0x1f, 1, | 426 | 0x1f, 1, |
425 | lineout_volume), | 427 | lineout_volume), |
428 | SOC_SINGLE("Lineout Playback Switch", SGTL5000_CHIP_ANA_CTRL, 8, 1, 1), | ||
426 | }; | 429 | }; |
427 | 430 | ||
428 | /* mute the codec used by alsa core */ | 431 | /* mute the codec used by alsa core */ |
@@ -1151,12 +1154,14 @@ static struct snd_soc_codec_driver sgtl5000_driver = { | |||
1151 | .remove = sgtl5000_remove, | 1154 | .remove = sgtl5000_remove, |
1152 | .set_bias_level = sgtl5000_set_bias_level, | 1155 | .set_bias_level = sgtl5000_set_bias_level, |
1153 | .suspend_bias_off = true, | 1156 | .suspend_bias_off = true, |
1154 | .controls = sgtl5000_snd_controls, | 1157 | .component_driver = { |
1155 | .num_controls = ARRAY_SIZE(sgtl5000_snd_controls), | 1158 | .controls = sgtl5000_snd_controls, |
1156 | .dapm_widgets = sgtl5000_dapm_widgets, | 1159 | .num_controls = ARRAY_SIZE(sgtl5000_snd_controls), |
1157 | .num_dapm_widgets = ARRAY_SIZE(sgtl5000_dapm_widgets), | 1160 | .dapm_widgets = sgtl5000_dapm_widgets, |
1158 | .dapm_routes = sgtl5000_dapm_routes, | 1161 | .num_dapm_widgets = ARRAY_SIZE(sgtl5000_dapm_widgets), |
1159 | .num_dapm_routes = ARRAY_SIZE(sgtl5000_dapm_routes), | 1162 | .dapm_routes = sgtl5000_dapm_routes, |
1163 | .num_dapm_routes = ARRAY_SIZE(sgtl5000_dapm_routes), | ||
1164 | }, | ||
1160 | }; | 1165 | }; |
1161 | 1166 | ||
1162 | static const struct regmap_config sgtl5000_regmap = { | 1167 | static const struct regmap_config sgtl5000_regmap = { |
diff --git a/sound/soc/codecs/si476x.c b/sound/soc/codecs/si476x.c index a8402d0af0ea..5344f4aa8fde 100644 --- a/sound/soc/codecs/si476x.c +++ b/sound/soc/codecs/si476x.c | |||
@@ -238,10 +238,12 @@ static struct regmap *si476x_get_regmap(struct device *dev) | |||
238 | 238 | ||
239 | static struct snd_soc_codec_driver soc_codec_dev_si476x = { | 239 | static struct snd_soc_codec_driver soc_codec_dev_si476x = { |
240 | .get_regmap = si476x_get_regmap, | 240 | .get_regmap = si476x_get_regmap, |
241 | .dapm_widgets = si476x_dapm_widgets, | 241 | .component_driver = { |
242 | .num_dapm_widgets = ARRAY_SIZE(si476x_dapm_widgets), | 242 | .dapm_widgets = si476x_dapm_widgets, |
243 | .dapm_routes = si476x_dapm_routes, | 243 | .num_dapm_widgets = ARRAY_SIZE(si476x_dapm_widgets), |
244 | .num_dapm_routes = ARRAY_SIZE(si476x_dapm_routes), | 244 | .dapm_routes = si476x_dapm_routes, |
245 | .num_dapm_routes = ARRAY_SIZE(si476x_dapm_routes), | ||
246 | }, | ||
245 | }; | 247 | }; |
246 | 248 | ||
247 | static int si476x_platform_probe(struct platform_device *pdev) | 249 | static int si476x_platform_probe(struct platform_device *pdev) |
diff --git a/sound/soc/codecs/sn95031.c b/sound/soc/codecs/sn95031.c index 3a7de0159f24..eae54c37cff9 100644 --- a/sound/soc/codecs/sn95031.c +++ b/sound/soc/codecs/sn95031.c | |||
@@ -888,12 +888,14 @@ static struct snd_soc_codec_driver sn95031_codec = { | |||
888 | .set_bias_level = sn95031_set_vaud_bias, | 888 | .set_bias_level = sn95031_set_vaud_bias, |
889 | .idle_bias_off = true, | 889 | .idle_bias_off = true, |
890 | 890 | ||
891 | .controls = sn95031_snd_controls, | 891 | .component_driver = { |
892 | .num_controls = ARRAY_SIZE(sn95031_snd_controls), | 892 | .controls = sn95031_snd_controls, |
893 | .dapm_widgets = sn95031_dapm_widgets, | 893 | .num_controls = ARRAY_SIZE(sn95031_snd_controls), |
894 | .num_dapm_widgets = ARRAY_SIZE(sn95031_dapm_widgets), | 894 | .dapm_widgets = sn95031_dapm_widgets, |
895 | .dapm_routes = sn95031_audio_map, | 895 | .num_dapm_widgets = ARRAY_SIZE(sn95031_dapm_widgets), |
896 | .num_dapm_routes = ARRAY_SIZE(sn95031_audio_map), | 896 | .dapm_routes = sn95031_audio_map, |
897 | .num_dapm_routes = ARRAY_SIZE(sn95031_audio_map), | ||
898 | }, | ||
897 | }; | 899 | }; |
898 | 900 | ||
899 | static int sn95031_device_probe(struct platform_device *pdev) | 901 | static int sn95031_device_probe(struct platform_device *pdev) |
diff --git a/sound/soc/codecs/spdif_receiver.c b/sound/soc/codecs/spdif_receiver.c index 3ec41ccbf4e2..234f87b54838 100644 --- a/sound/soc/codecs/spdif_receiver.c +++ b/sound/soc/codecs/spdif_receiver.c | |||
@@ -38,10 +38,12 @@ static const struct snd_soc_dapm_route dir_routes[] = { | |||
38 | SNDRV_PCM_FMTBIT_IEC958_SUBFRAME_LE) | 38 | SNDRV_PCM_FMTBIT_IEC958_SUBFRAME_LE) |
39 | 39 | ||
40 | static struct snd_soc_codec_driver soc_codec_spdif_dir = { | 40 | static struct snd_soc_codec_driver soc_codec_spdif_dir = { |
41 | .dapm_widgets = dir_widgets, | 41 | .component_driver = { |
42 | .num_dapm_widgets = ARRAY_SIZE(dir_widgets), | 42 | .dapm_widgets = dir_widgets, |
43 | .dapm_routes = dir_routes, | 43 | .num_dapm_widgets = ARRAY_SIZE(dir_widgets), |
44 | .num_dapm_routes = ARRAY_SIZE(dir_routes), | 44 | .dapm_routes = dir_routes, |
45 | .num_dapm_routes = ARRAY_SIZE(dir_routes), | ||
46 | }, | ||
45 | }; | 47 | }; |
46 | 48 | ||
47 | static struct snd_soc_dai_driver dir_stub_dai = { | 49 | static struct snd_soc_dai_driver dir_stub_dai = { |
diff --git a/sound/soc/codecs/spdif_transmitter.c b/sound/soc/codecs/spdif_transmitter.c index ef634a9ad673..ee367536a498 100644 --- a/sound/soc/codecs/spdif_transmitter.c +++ b/sound/soc/codecs/spdif_transmitter.c | |||
@@ -38,10 +38,12 @@ static const struct snd_soc_dapm_route dit_routes[] = { | |||
38 | }; | 38 | }; |
39 | 39 | ||
40 | static struct snd_soc_codec_driver soc_codec_spdif_dit = { | 40 | static struct snd_soc_codec_driver soc_codec_spdif_dit = { |
41 | .dapm_widgets = dit_widgets, | 41 | .component_driver = { |
42 | .num_dapm_widgets = ARRAY_SIZE(dit_widgets), | 42 | .dapm_widgets = dit_widgets, |
43 | .dapm_routes = dit_routes, | 43 | .num_dapm_widgets = ARRAY_SIZE(dit_widgets), |
44 | .num_dapm_routes = ARRAY_SIZE(dit_routes), | 44 | .dapm_routes = dit_routes, |
45 | .num_dapm_routes = ARRAY_SIZE(dit_routes), | ||
46 | }, | ||
45 | }; | 47 | }; |
46 | 48 | ||
47 | static struct snd_soc_dai_driver dit_stub_dai = { | 49 | static struct snd_soc_dai_driver dit_stub_dai = { |
diff --git a/sound/soc/codecs/ssm2518.c b/sound/soc/codecs/ssm2518.c index e2e0bfa7ec20..38a85f3adc80 100644 --- a/sound/soc/codecs/ssm2518.c +++ b/sound/soc/codecs/ssm2518.c | |||
@@ -715,12 +715,14 @@ static struct snd_soc_codec_driver ssm2518_codec_driver = { | |||
715 | .set_sysclk = ssm2518_set_sysclk, | 715 | .set_sysclk = ssm2518_set_sysclk, |
716 | .idle_bias_off = true, | 716 | .idle_bias_off = true, |
717 | 717 | ||
718 | .controls = ssm2518_snd_controls, | 718 | .component_driver = { |
719 | .num_controls = ARRAY_SIZE(ssm2518_snd_controls), | 719 | .controls = ssm2518_snd_controls, |
720 | .dapm_widgets = ssm2518_dapm_widgets, | 720 | .num_controls = ARRAY_SIZE(ssm2518_snd_controls), |
721 | .num_dapm_widgets = ARRAY_SIZE(ssm2518_dapm_widgets), | 721 | .dapm_widgets = ssm2518_dapm_widgets, |
722 | .dapm_routes = ssm2518_routes, | 722 | .num_dapm_widgets = ARRAY_SIZE(ssm2518_dapm_widgets), |
723 | .num_dapm_routes = ARRAY_SIZE(ssm2518_routes), | 723 | .dapm_routes = ssm2518_routes, |
724 | .num_dapm_routes = ARRAY_SIZE(ssm2518_routes), | ||
725 | }, | ||
724 | }; | 726 | }; |
725 | 727 | ||
726 | static const struct regmap_config ssm2518_regmap_config = { | 728 | static const struct regmap_config ssm2518_regmap_config = { |
diff --git a/sound/soc/codecs/ssm2602.c b/sound/soc/codecs/ssm2602.c index 4452fea0b118..993bde29ca1b 100644 --- a/sound/soc/codecs/ssm2602.c +++ b/sound/soc/codecs/ssm2602.c | |||
@@ -597,12 +597,14 @@ static struct snd_soc_codec_driver soc_codec_dev_ssm2602 = { | |||
597 | .set_bias_level = ssm2602_set_bias_level, | 597 | .set_bias_level = ssm2602_set_bias_level, |
598 | .suspend_bias_off = true, | 598 | .suspend_bias_off = true, |
599 | 599 | ||
600 | .controls = ssm260x_snd_controls, | 600 | .component_driver = { |
601 | .num_controls = ARRAY_SIZE(ssm260x_snd_controls), | 601 | .controls = ssm260x_snd_controls, |
602 | .dapm_widgets = ssm260x_dapm_widgets, | 602 | .num_controls = ARRAY_SIZE(ssm260x_snd_controls), |
603 | .num_dapm_widgets = ARRAY_SIZE(ssm260x_dapm_widgets), | 603 | .dapm_widgets = ssm260x_dapm_widgets, |
604 | .dapm_routes = ssm260x_routes, | 604 | .num_dapm_widgets = ARRAY_SIZE(ssm260x_dapm_widgets), |
605 | .num_dapm_routes = ARRAY_SIZE(ssm260x_routes), | 605 | .dapm_routes = ssm260x_routes, |
606 | .num_dapm_routes = ARRAY_SIZE(ssm260x_routes), | ||
607 | }, | ||
606 | }; | 608 | }; |
607 | 609 | ||
608 | static bool ssm2602_register_volatile(struct device *dev, unsigned int reg) | 610 | static bool ssm2602_register_volatile(struct device *dev, unsigned int reg) |
diff --git a/sound/soc/codecs/ssm4567.c b/sound/soc/codecs/ssm4567.c index 080c78e88e10..2bb5a11c9ba1 100644 --- a/sound/soc/codecs/ssm4567.c +++ b/sound/soc/codecs/ssm4567.c | |||
@@ -421,12 +421,14 @@ static struct snd_soc_codec_driver ssm4567_codec_driver = { | |||
421 | .set_bias_level = ssm4567_set_bias_level, | 421 | .set_bias_level = ssm4567_set_bias_level, |
422 | .idle_bias_off = true, | 422 | .idle_bias_off = true, |
423 | 423 | ||
424 | .controls = ssm4567_snd_controls, | 424 | .component_driver = { |
425 | .num_controls = ARRAY_SIZE(ssm4567_snd_controls), | 425 | .controls = ssm4567_snd_controls, |
426 | .dapm_widgets = ssm4567_dapm_widgets, | 426 | .num_controls = ARRAY_SIZE(ssm4567_snd_controls), |
427 | .num_dapm_widgets = ARRAY_SIZE(ssm4567_dapm_widgets), | 427 | .dapm_widgets = ssm4567_dapm_widgets, |
428 | .dapm_routes = ssm4567_routes, | 428 | .num_dapm_widgets = ARRAY_SIZE(ssm4567_dapm_widgets), |
429 | .num_dapm_routes = ARRAY_SIZE(ssm4567_routes), | 429 | .dapm_routes = ssm4567_routes, |
430 | .num_dapm_routes = ARRAY_SIZE(ssm4567_routes), | ||
431 | }, | ||
430 | }; | 432 | }; |
431 | 433 | ||
432 | static const struct regmap_config ssm4567_regmap_config = { | 434 | static const struct regmap_config ssm4567_regmap_config = { |
diff --git a/sound/soc/codecs/sta32x.c b/sound/soc/codecs/sta32x.c index a9844b2ac829..0790ae8530d9 100644 --- a/sound/soc/codecs/sta32x.c +++ b/sound/soc/codecs/sta32x.c | |||
@@ -991,12 +991,14 @@ static const struct snd_soc_codec_driver sta32x_codec = { | |||
991 | .remove = sta32x_remove, | 991 | .remove = sta32x_remove, |
992 | .set_bias_level = sta32x_set_bias_level, | 992 | .set_bias_level = sta32x_set_bias_level, |
993 | .suspend_bias_off = true, | 993 | .suspend_bias_off = true, |
994 | .controls = sta32x_snd_controls, | 994 | .component_driver = { |
995 | .num_controls = ARRAY_SIZE(sta32x_snd_controls), | 995 | .controls = sta32x_snd_controls, |
996 | .dapm_widgets = sta32x_dapm_widgets, | 996 | .num_controls = ARRAY_SIZE(sta32x_snd_controls), |
997 | .num_dapm_widgets = ARRAY_SIZE(sta32x_dapm_widgets), | 997 | .dapm_widgets = sta32x_dapm_widgets, |
998 | .dapm_routes = sta32x_dapm_routes, | 998 | .num_dapm_widgets = ARRAY_SIZE(sta32x_dapm_widgets), |
999 | .num_dapm_routes = ARRAY_SIZE(sta32x_dapm_routes), | 999 | .dapm_routes = sta32x_dapm_routes, |
1000 | .num_dapm_routes = ARRAY_SIZE(sta32x_dapm_routes), | ||
1001 | }, | ||
1000 | }; | 1002 | }; |
1001 | 1003 | ||
1002 | static const struct regmap_config sta32x_regmap = { | 1004 | static const struct regmap_config sta32x_regmap = { |
diff --git a/sound/soc/codecs/sta350.c b/sound/soc/codecs/sta350.c index 33a4612f0a07..9644c20f44e3 100644 --- a/sound/soc/codecs/sta350.c +++ b/sound/soc/codecs/sta350.c | |||
@@ -1057,12 +1057,14 @@ static const struct snd_soc_codec_driver sta350_codec = { | |||
1057 | .remove = sta350_remove, | 1057 | .remove = sta350_remove, |
1058 | .set_bias_level = sta350_set_bias_level, | 1058 | .set_bias_level = sta350_set_bias_level, |
1059 | .suspend_bias_off = true, | 1059 | .suspend_bias_off = true, |
1060 | .controls = sta350_snd_controls, | 1060 | .component_driver = { |
1061 | .num_controls = ARRAY_SIZE(sta350_snd_controls), | 1061 | .controls = sta350_snd_controls, |
1062 | .dapm_widgets = sta350_dapm_widgets, | 1062 | .num_controls = ARRAY_SIZE(sta350_snd_controls), |
1063 | .num_dapm_widgets = ARRAY_SIZE(sta350_dapm_widgets), | 1063 | .dapm_widgets = sta350_dapm_widgets, |
1064 | .dapm_routes = sta350_dapm_routes, | 1064 | .num_dapm_widgets = ARRAY_SIZE(sta350_dapm_widgets), |
1065 | .num_dapm_routes = ARRAY_SIZE(sta350_dapm_routes), | 1065 | .dapm_routes = sta350_dapm_routes, |
1066 | .num_dapm_routes = ARRAY_SIZE(sta350_dapm_routes), | ||
1067 | }, | ||
1066 | }; | 1068 | }; |
1067 | 1069 | ||
1068 | static const struct regmap_config sta350_regmap = { | 1070 | static const struct regmap_config sta350_regmap = { |
diff --git a/sound/soc/codecs/sta529.c b/sound/soc/codecs/sta529.c index 2cdaca943a8c..d4b384e4b266 100644 --- a/sound/soc/codecs/sta529.c +++ b/sound/soc/codecs/sta529.c | |||
@@ -317,8 +317,10 @@ static const struct snd_soc_codec_driver sta529_codec_driver = { | |||
317 | .set_bias_level = sta529_set_bias_level, | 317 | .set_bias_level = sta529_set_bias_level, |
318 | .suspend_bias_off = true, | 318 | .suspend_bias_off = true, |
319 | 319 | ||
320 | .controls = sta529_snd_controls, | 320 | .component_driver = { |
321 | .num_controls = ARRAY_SIZE(sta529_snd_controls), | 321 | .controls = sta529_snd_controls, |
322 | .num_controls = ARRAY_SIZE(sta529_snd_controls), | ||
323 | }, | ||
322 | }; | 324 | }; |
323 | 325 | ||
324 | static const struct regmap_config sta529_regmap = { | 326 | static const struct regmap_config sta529_regmap = { |
diff --git a/sound/soc/codecs/stac9766.c b/sound/soc/codecs/stac9766.c index 0945c51df003..27f30d352867 100644 --- a/sound/soc/codecs/stac9766.c +++ b/sound/soc/codecs/stac9766.c | |||
@@ -85,10 +85,10 @@ static SOC_ENUM_SINGLE_DECL(stac9766_boost2_enum, | |||
85 | static SOC_ENUM_SINGLE_DECL(stac9766_stereo_mic_enum, | 85 | static SOC_ENUM_SINGLE_DECL(stac9766_stereo_mic_enum, |
86 | AC97_STAC_STEREO_MIC, 2, stac9766_stereo_mic); | 86 | AC97_STAC_STEREO_MIC, 2, stac9766_stereo_mic); |
87 | 87 | ||
88 | static const DECLARE_TLV_DB_LINEAR(master_tlv, -4600, 0); | 88 | static const SNDRV_CTL_TLVD_DECLARE_DB_SCALE(master_tlv, -4650, 150, 0); |
89 | static const DECLARE_TLV_DB_LINEAR(record_tlv, 0, 2250); | 89 | static const SNDRV_CTL_TLVD_DECLARE_DB_SCALE(record_tlv, 0, 150, 0); |
90 | static const DECLARE_TLV_DB_LINEAR(beep_tlv, -4500, 0); | 90 | static const SNDRV_CTL_TLVD_DECLARE_DB_SCALE(beep_tlv, -4500, 300, 0); |
91 | static const DECLARE_TLV_DB_LINEAR(mix_tlv, -3450, 1200); | 91 | static const SNDRV_CTL_TLVD_DECLARE_DB_SCALE(mix_tlv, -3450, 150, 0); |
92 | 92 | ||
93 | static const struct snd_kcontrol_new stac9766_snd_ac97_controls[] = { | 93 | static const struct snd_kcontrol_new stac9766_snd_ac97_controls[] = { |
94 | SOC_DOUBLE_TLV("Speaker Volume", AC97_MASTER, 8, 0, 31, 1, master_tlv), | 94 | SOC_DOUBLE_TLV("Speaker Volume", AC97_MASTER, 8, 0, 31, 1, master_tlv), |
@@ -320,8 +320,10 @@ static int stac9766_codec_remove(struct snd_soc_codec *codec) | |||
320 | } | 320 | } |
321 | 321 | ||
322 | static struct snd_soc_codec_driver soc_codec_dev_stac9766 = { | 322 | static struct snd_soc_codec_driver soc_codec_dev_stac9766 = { |
323 | .controls = stac9766_snd_ac97_controls, | 323 | .component_driver = { |
324 | .num_controls = ARRAY_SIZE(stac9766_snd_ac97_controls), | 324 | .controls = stac9766_snd_ac97_controls, |
325 | .num_controls = ARRAY_SIZE(stac9766_snd_ac97_controls), | ||
326 | }, | ||
325 | .write = stac9766_ac97_write, | 327 | .write = stac9766_ac97_write, |
326 | .read = stac9766_ac97_read, | 328 | .read = stac9766_ac97_read, |
327 | .set_bias_level = stac9766_set_bias_level, | 329 | .set_bias_level = stac9766_set_bias_level, |
diff --git a/sound/soc/codecs/sti-sas.c b/sound/soc/codecs/sti-sas.c index 160d61a66204..7b31ee9b82bc 100644 --- a/sound/soc/codecs/sti-sas.c +++ b/sound/soc/codecs/sti-sas.c | |||
@@ -591,11 +591,11 @@ static int sti_sas_driver_probe(struct platform_device *pdev) | |||
591 | sti_sas_dai[STI_SAS_DAI_ANALOG_OUT].ops = drvdata->dev_data->dac_ops; | 591 | sti_sas_dai[STI_SAS_DAI_ANALOG_OUT].ops = drvdata->dev_data->dac_ops; |
592 | 592 | ||
593 | /* Set dapms*/ | 593 | /* Set dapms*/ |
594 | sti_sas_driver.dapm_widgets = drvdata->dev_data->dapm_widgets; | 594 | sti_sas_driver.component_driver.dapm_widgets = drvdata->dev_data->dapm_widgets; |
595 | sti_sas_driver.num_dapm_widgets = drvdata->dev_data->num_dapm_widgets; | 595 | sti_sas_driver.component_driver.num_dapm_widgets = drvdata->dev_data->num_dapm_widgets; |
596 | 596 | ||
597 | sti_sas_driver.dapm_routes = drvdata->dev_data->dapm_routes; | 597 | sti_sas_driver.component_driver.dapm_routes = drvdata->dev_data->dapm_routes; |
598 | sti_sas_driver.num_dapm_routes = drvdata->dev_data->num_dapm_routes; | 598 | sti_sas_driver.component_driver.num_dapm_routes = drvdata->dev_data->num_dapm_routes; |
599 | 599 | ||
600 | /* Store context */ | 600 | /* Store context */ |
601 | dev_set_drvdata(&pdev->dev, drvdata); | 601 | dev_set_drvdata(&pdev->dev, drvdata); |
diff --git a/sound/soc/codecs/tas2552.c b/sound/soc/codecs/tas2552.c index cc1d3981fa4b..baf455e8c2f7 100644 --- a/sound/soc/codecs/tas2552.c +++ b/sound/soc/codecs/tas2552.c | |||
@@ -667,12 +667,14 @@ static struct snd_soc_codec_driver soc_codec_dev_tas2552 = { | |||
667 | .resume = tas2552_resume, | 667 | .resume = tas2552_resume, |
668 | .ignore_pmdown_time = true, | 668 | .ignore_pmdown_time = true, |
669 | 669 | ||
670 | .controls = tas2552_snd_controls, | 670 | .component_driver = { |
671 | .num_controls = ARRAY_SIZE(tas2552_snd_controls), | 671 | .controls = tas2552_snd_controls, |
672 | .dapm_widgets = tas2552_dapm_widgets, | 672 | .num_controls = ARRAY_SIZE(tas2552_snd_controls), |
673 | .num_dapm_widgets = ARRAY_SIZE(tas2552_dapm_widgets), | 673 | .dapm_widgets = tas2552_dapm_widgets, |
674 | .dapm_routes = tas2552_audio_map, | 674 | .num_dapm_widgets = ARRAY_SIZE(tas2552_dapm_widgets), |
675 | .num_dapm_routes = ARRAY_SIZE(tas2552_audio_map), | 675 | .dapm_routes = tas2552_audio_map, |
676 | .num_dapm_routes = ARRAY_SIZE(tas2552_audio_map), | ||
677 | }, | ||
676 | }; | 678 | }; |
677 | 679 | ||
678 | static const struct regmap_config tas2552_regmap_config = { | 680 | static const struct regmap_config tas2552_regmap_config = { |
diff --git a/sound/soc/codecs/tas5086.c b/sound/soc/codecs/tas5086.c index d49d25d51957..b7de857abb16 100644 --- a/sound/soc/codecs/tas5086.c +++ b/sound/soc/codecs/tas5086.c | |||
@@ -387,7 +387,7 @@ static int tas5086_hw_params(struct snd_pcm_substream *substream, | |||
387 | val = index_in_array(tas5086_ratios, ARRAY_SIZE(tas5086_ratios), | 387 | val = index_in_array(tas5086_ratios, ARRAY_SIZE(tas5086_ratios), |
388 | priv->mclk / priv->rate); | 388 | priv->mclk / priv->rate); |
389 | if (val < 0) { | 389 | if (val < 0) { |
390 | dev_err(codec->dev, "Inavlid MCLK / Fs ratio\n"); | 390 | dev_err(codec->dev, "Invalid MCLK / Fs ratio\n"); |
391 | return -EINVAL; | 391 | return -EINVAL; |
392 | } | 392 | } |
393 | 393 | ||
@@ -890,12 +890,14 @@ static struct snd_soc_codec_driver soc_codec_dev_tas5086 = { | |||
890 | .remove = tas5086_remove, | 890 | .remove = tas5086_remove, |
891 | .suspend = tas5086_soc_suspend, | 891 | .suspend = tas5086_soc_suspend, |
892 | .resume = tas5086_soc_resume, | 892 | .resume = tas5086_soc_resume, |
893 | .controls = tas5086_controls, | 893 | .component_driver = { |
894 | .num_controls = ARRAY_SIZE(tas5086_controls), | 894 | .controls = tas5086_controls, |
895 | .dapm_widgets = tas5086_dapm_widgets, | 895 | .num_controls = ARRAY_SIZE(tas5086_controls), |
896 | .num_dapm_widgets = ARRAY_SIZE(tas5086_dapm_widgets), | 896 | .dapm_widgets = tas5086_dapm_widgets, |
897 | .dapm_routes = tas5086_dapm_routes, | 897 | .num_dapm_widgets = ARRAY_SIZE(tas5086_dapm_widgets), |
898 | .num_dapm_routes = ARRAY_SIZE(tas5086_dapm_routes), | 898 | .dapm_routes = tas5086_dapm_routes, |
899 | .num_dapm_routes = ARRAY_SIZE(tas5086_dapm_routes), | ||
900 | }, | ||
899 | }; | 901 | }; |
900 | 902 | ||
901 | static const struct i2c_device_id tas5086_i2c_id[] = { | 903 | static const struct i2c_device_id tas5086_i2c_id[] = { |
diff --git a/sound/soc/codecs/tas571x.c b/sound/soc/codecs/tas571x.c index d8baca3f8413..df5e5cb33baa 100644 --- a/sound/soc/codecs/tas571x.c +++ b/sound/soc/codecs/tas571x.c | |||
@@ -658,10 +658,12 @@ static const struct snd_soc_codec_driver tas571x_codec = { | |||
658 | .set_bias_level = tas571x_set_bias_level, | 658 | .set_bias_level = tas571x_set_bias_level, |
659 | .idle_bias_off = true, | 659 | .idle_bias_off = true, |
660 | 660 | ||
661 | .dapm_widgets = tas571x_dapm_widgets, | 661 | .component_driver = { |
662 | .num_dapm_widgets = ARRAY_SIZE(tas571x_dapm_widgets), | 662 | .dapm_widgets = tas571x_dapm_widgets, |
663 | .dapm_routes = tas571x_dapm_routes, | 663 | .num_dapm_widgets = ARRAY_SIZE(tas571x_dapm_widgets), |
664 | .num_dapm_routes = ARRAY_SIZE(tas571x_dapm_routes), | 664 | .dapm_routes = tas571x_dapm_routes, |
665 | .num_dapm_routes = ARRAY_SIZE(tas571x_dapm_routes), | ||
666 | }, | ||
665 | }; | 667 | }; |
666 | 668 | ||
667 | static struct snd_soc_dai_driver tas571x_dai = { | 669 | static struct snd_soc_dai_driver tas571x_dai = { |
@@ -754,8 +756,8 @@ static int tas571x_i2c_probe(struct i2c_client *client, | |||
754 | 756 | ||
755 | 757 | ||
756 | memcpy(&priv->codec_driver, &tas571x_codec, sizeof(priv->codec_driver)); | 758 | memcpy(&priv->codec_driver, &tas571x_codec, sizeof(priv->codec_driver)); |
757 | priv->codec_driver.controls = priv->chip->controls; | 759 | priv->codec_driver.component_driver.controls = priv->chip->controls; |
758 | priv->codec_driver.num_controls = priv->chip->num_controls; | 760 | priv->codec_driver.component_driver.num_controls = priv->chip->num_controls; |
759 | 761 | ||
760 | if (priv->chip->vol_reg_size == 2) { | 762 | if (priv->chip->vol_reg_size == 2) { |
761 | /* | 763 | /* |
diff --git a/sound/soc/codecs/tas5720.c b/sound/soc/codecs/tas5720.c index f54fb46b77c2..c65b917598d2 100644 --- a/sound/soc/codecs/tas5720.c +++ b/sound/soc/codecs/tas5720.c | |||
@@ -489,12 +489,14 @@ static struct snd_soc_codec_driver soc_codec_dev_tas5720 = { | |||
489 | .suspend = tas5720_suspend, | 489 | .suspend = tas5720_suspend, |
490 | .resume = tas5720_resume, | 490 | .resume = tas5720_resume, |
491 | 491 | ||
492 | .controls = tas5720_snd_controls, | 492 | .component_driver = { |
493 | .num_controls = ARRAY_SIZE(tas5720_snd_controls), | 493 | .controls = tas5720_snd_controls, |
494 | .dapm_widgets = tas5720_dapm_widgets, | 494 | .num_controls = ARRAY_SIZE(tas5720_snd_controls), |
495 | .num_dapm_widgets = ARRAY_SIZE(tas5720_dapm_widgets), | 495 | .dapm_widgets = tas5720_dapm_widgets, |
496 | .dapm_routes = tas5720_audio_map, | 496 | .num_dapm_widgets = ARRAY_SIZE(tas5720_dapm_widgets), |
497 | .num_dapm_routes = ARRAY_SIZE(tas5720_audio_map), | 497 | .dapm_routes = tas5720_audio_map, |
498 | .num_dapm_routes = ARRAY_SIZE(tas5720_audio_map), | ||
499 | }, | ||
498 | }; | 500 | }; |
499 | 501 | ||
500 | /* PCM rates supported by the TAS5720 driver */ | 502 | /* PCM rates supported by the TAS5720 driver */ |
diff --git a/sound/soc/codecs/tfa9879.c b/sound/soc/codecs/tfa9879.c index cb5310d89c0f..95e0a7abeb7a 100644 --- a/sound/soc/codecs/tfa9879.c +++ b/sound/soc/codecs/tfa9879.c | |||
@@ -231,13 +231,14 @@ static const struct snd_soc_dapm_route tfa9879_dapm_routes[] = { | |||
231 | }; | 231 | }; |
232 | 232 | ||
233 | static const struct snd_soc_codec_driver tfa9879_codec = { | 233 | static const struct snd_soc_codec_driver tfa9879_codec = { |
234 | .controls = tfa9879_controls, | 234 | .component_driver = { |
235 | .num_controls = ARRAY_SIZE(tfa9879_controls), | 235 | .controls = tfa9879_controls, |
236 | 236 | .num_controls = ARRAY_SIZE(tfa9879_controls), | |
237 | .dapm_widgets = tfa9879_dapm_widgets, | 237 | .dapm_widgets = tfa9879_dapm_widgets, |
238 | .num_dapm_widgets = ARRAY_SIZE(tfa9879_dapm_widgets), | 238 | .num_dapm_widgets = ARRAY_SIZE(tfa9879_dapm_widgets), |
239 | .dapm_routes = tfa9879_dapm_routes, | 239 | .dapm_routes = tfa9879_dapm_routes, |
240 | .num_dapm_routes = ARRAY_SIZE(tfa9879_dapm_routes), | 240 | .num_dapm_routes = ARRAY_SIZE(tfa9879_dapm_routes), |
241 | }, | ||
241 | }; | 242 | }; |
242 | 243 | ||
243 | static const struct regmap_config tfa9879_regmap = { | 244 | static const struct regmap_config tfa9879_regmap = { |
diff --git a/sound/soc/codecs/tlv320aic23.c b/sound/soc/codecs/tlv320aic23.c index cd8c02b6e4de..410cae0f2060 100644 --- a/sound/soc/codecs/tlv320aic23.c +++ b/sound/soc/codecs/tlv320aic23.c | |||
@@ -583,12 +583,14 @@ static struct snd_soc_codec_driver soc_codec_dev_tlv320aic23 = { | |||
583 | .set_bias_level = tlv320aic23_set_bias_level, | 583 | .set_bias_level = tlv320aic23_set_bias_level, |
584 | .suspend_bias_off = true, | 584 | .suspend_bias_off = true, |
585 | 585 | ||
586 | .controls = tlv320aic23_snd_controls, | 586 | .component_driver = { |
587 | .num_controls = ARRAY_SIZE(tlv320aic23_snd_controls), | 587 | .controls = tlv320aic23_snd_controls, |
588 | .dapm_widgets = tlv320aic23_dapm_widgets, | 588 | .num_controls = ARRAY_SIZE(tlv320aic23_snd_controls), |
589 | .num_dapm_widgets = ARRAY_SIZE(tlv320aic23_dapm_widgets), | 589 | .dapm_widgets = tlv320aic23_dapm_widgets, |
590 | .dapm_routes = tlv320aic23_intercon, | 590 | .num_dapm_widgets = ARRAY_SIZE(tlv320aic23_dapm_widgets), |
591 | .num_dapm_routes = ARRAY_SIZE(tlv320aic23_intercon), | 591 | .dapm_routes = tlv320aic23_intercon, |
592 | .num_dapm_routes = ARRAY_SIZE(tlv320aic23_intercon), | ||
593 | }, | ||
592 | }; | 594 | }; |
593 | 595 | ||
594 | int tlv320aic23_probe(struct device *dev, struct regmap *regmap) | 596 | int tlv320aic23_probe(struct device *dev, struct regmap *regmap) |
diff --git a/sound/soc/codecs/tlv320aic26.c b/sound/soc/codecs/tlv320aic26.c index 2c904d7150ad..14aa96d41719 100644 --- a/sound/soc/codecs/tlv320aic26.c +++ b/sound/soc/codecs/tlv320aic26.c | |||
@@ -321,12 +321,14 @@ static int aic26_probe(struct snd_soc_codec *codec) | |||
321 | 321 | ||
322 | static struct snd_soc_codec_driver aic26_soc_codec_dev = { | 322 | static struct snd_soc_codec_driver aic26_soc_codec_dev = { |
323 | .probe = aic26_probe, | 323 | .probe = aic26_probe, |
324 | .controls = aic26_snd_controls, | 324 | .component_driver = { |
325 | .num_controls = ARRAY_SIZE(aic26_snd_controls), | 325 | .controls = aic26_snd_controls, |
326 | .dapm_widgets = tlv320aic26_dapm_widgets, | 326 | .num_controls = ARRAY_SIZE(aic26_snd_controls), |
327 | .num_dapm_widgets = ARRAY_SIZE(tlv320aic26_dapm_widgets), | 327 | .dapm_widgets = tlv320aic26_dapm_widgets, |
328 | .dapm_routes = tlv320aic26_dapm_routes, | 328 | .num_dapm_widgets = ARRAY_SIZE(tlv320aic26_dapm_widgets), |
329 | .num_dapm_routes = ARRAY_SIZE(tlv320aic26_dapm_routes), | 329 | .dapm_routes = tlv320aic26_dapm_routes, |
330 | .num_dapm_routes = ARRAY_SIZE(tlv320aic26_dapm_routes), | ||
331 | }, | ||
330 | }; | 332 | }; |
331 | 333 | ||
332 | static const struct regmap_config aic26_regmap = { | 334 | static const struct regmap_config aic26_regmap = { |
diff --git a/sound/soc/codecs/tlv320aic31xx.c b/sound/soc/codecs/tlv320aic31xx.c index 3c5e1df01c19..be1a64bfd320 100644 --- a/sound/soc/codecs/tlv320aic31xx.c +++ b/sound/soc/codecs/tlv320aic31xx.c | |||
@@ -273,10 +273,20 @@ static const DECLARE_TLV_DB_SCALE(sp_vol_tlv, -6350, 50, 0); | |||
273 | /* | 273 | /* |
274 | * controls to be exported to the user space | 274 | * controls to be exported to the user space |
275 | */ | 275 | */ |
276 | static const struct snd_kcontrol_new aic31xx_snd_controls[] = { | 276 | static const struct snd_kcontrol_new common31xx_snd_controls[] = { |
277 | SOC_DOUBLE_R_S_TLV("DAC Playback Volume", AIC31XX_LDACVOL, | 277 | SOC_DOUBLE_R_S_TLV("DAC Playback Volume", AIC31XX_LDACVOL, |
278 | AIC31XX_RDACVOL, 0, -127, 48, 7, 0, dac_vol_tlv), | 278 | AIC31XX_RDACVOL, 0, -127, 48, 7, 0, dac_vol_tlv), |
279 | 279 | ||
280 | SOC_DOUBLE_R("HP Driver Playback Switch", AIC31XX_HPLGAIN, | ||
281 | AIC31XX_HPRGAIN, 2, 1, 0), | ||
282 | SOC_DOUBLE_R_TLV("HP Driver Playback Volume", AIC31XX_HPLGAIN, | ||
283 | AIC31XX_HPRGAIN, 3, 0x09, 0, hp_drv_tlv), | ||
284 | |||
285 | SOC_DOUBLE_R_TLV("HP Analog Playback Volume", AIC31XX_LANALOGHPL, | ||
286 | AIC31XX_RANALOGHPR, 0, 0x7F, 1, hp_vol_tlv), | ||
287 | }; | ||
288 | |||
289 | static const struct snd_kcontrol_new aic31xx_snd_controls[] = { | ||
280 | SOC_SINGLE_TLV("ADC Fine Capture Volume", AIC31XX_ADCFGA, 4, 4, 1, | 290 | SOC_SINGLE_TLV("ADC Fine Capture Volume", AIC31XX_ADCFGA, 4, 4, 1, |
281 | adc_fgain_tlv), | 291 | adc_fgain_tlv), |
282 | 292 | ||
@@ -286,14 +296,6 @@ static const struct snd_kcontrol_new aic31xx_snd_controls[] = { | |||
286 | 296 | ||
287 | SOC_SINGLE_TLV("Mic PGA Capture Volume", AIC31XX_MICPGA, 0, | 297 | SOC_SINGLE_TLV("Mic PGA Capture Volume", AIC31XX_MICPGA, 0, |
288 | 119, 0, mic_pga_tlv), | 298 | 119, 0, mic_pga_tlv), |
289 | |||
290 | SOC_DOUBLE_R("HP Driver Playback Switch", AIC31XX_HPLGAIN, | ||
291 | AIC31XX_HPRGAIN, 2, 1, 0), | ||
292 | SOC_DOUBLE_R_TLV("HP Driver Playback Volume", AIC31XX_HPLGAIN, | ||
293 | AIC31XX_HPRGAIN, 3, 0x09, 0, hp_drv_tlv), | ||
294 | |||
295 | SOC_DOUBLE_R_TLV("HP Analog Playback Volume", AIC31XX_LANALOGHPL, | ||
296 | AIC31XX_RANALOGHPR, 0, 0x7F, 1, hp_vol_tlv), | ||
297 | }; | 299 | }; |
298 | 300 | ||
299 | static const struct snd_kcontrol_new aic311x_snd_controls[] = { | 301 | static const struct snd_kcontrol_new aic311x_snd_controls[] = { |
@@ -397,17 +399,28 @@ static int aic31xx_dapm_power_event(struct snd_soc_dapm_widget *w, | |||
397 | return 0; | 399 | return 0; |
398 | } | 400 | } |
399 | 401 | ||
400 | static const struct snd_kcontrol_new left_output_switches[] = { | 402 | static const struct snd_kcontrol_new aic31xx_left_output_switches[] = { |
401 | SOC_DAPM_SINGLE("From Left DAC", AIC31XX_DACMIXERROUTE, 6, 1, 0), | 403 | SOC_DAPM_SINGLE("From Left DAC", AIC31XX_DACMIXERROUTE, 6, 1, 0), |
402 | SOC_DAPM_SINGLE("From MIC1LP", AIC31XX_DACMIXERROUTE, 5, 1, 0), | 404 | SOC_DAPM_SINGLE("From MIC1LP", AIC31XX_DACMIXERROUTE, 5, 1, 0), |
403 | SOC_DAPM_SINGLE("From MIC1RP", AIC31XX_DACMIXERROUTE, 4, 1, 0), | 405 | SOC_DAPM_SINGLE("From MIC1RP", AIC31XX_DACMIXERROUTE, 4, 1, 0), |
404 | }; | 406 | }; |
405 | 407 | ||
406 | static const struct snd_kcontrol_new right_output_switches[] = { | 408 | static const struct snd_kcontrol_new aic31xx_right_output_switches[] = { |
407 | SOC_DAPM_SINGLE("From Right DAC", AIC31XX_DACMIXERROUTE, 2, 1, 0), | 409 | SOC_DAPM_SINGLE("From Right DAC", AIC31XX_DACMIXERROUTE, 2, 1, 0), |
408 | SOC_DAPM_SINGLE("From MIC1RP", AIC31XX_DACMIXERROUTE, 1, 1, 0), | 410 | SOC_DAPM_SINGLE("From MIC1RP", AIC31XX_DACMIXERROUTE, 1, 1, 0), |
409 | }; | 411 | }; |
410 | 412 | ||
413 | static const struct snd_kcontrol_new dac31xx_left_output_switches[] = { | ||
414 | SOC_DAPM_SINGLE("From Left DAC", AIC31XX_DACMIXERROUTE, 6, 1, 0), | ||
415 | SOC_DAPM_SINGLE("From AIN1", AIC31XX_DACMIXERROUTE, 5, 1, 0), | ||
416 | SOC_DAPM_SINGLE("From AIN2", AIC31XX_DACMIXERROUTE, 4, 1, 0), | ||
417 | }; | ||
418 | |||
419 | static const struct snd_kcontrol_new dac31xx_right_output_switches[] = { | ||
420 | SOC_DAPM_SINGLE("From Right DAC", AIC31XX_DACMIXERROUTE, 2, 1, 0), | ||
421 | SOC_DAPM_SINGLE("From AIN2", AIC31XX_DACMIXERROUTE, 1, 1, 0), | ||
422 | }; | ||
423 | |||
411 | static const struct snd_kcontrol_new p_term_mic1lp = | 424 | static const struct snd_kcontrol_new p_term_mic1lp = |
412 | SOC_DAPM_ENUM("MIC1LP P-Terminal", mic1lp_p_enum); | 425 | SOC_DAPM_ENUM("MIC1LP P-Terminal", mic1lp_p_enum); |
413 | 426 | ||
@@ -457,7 +470,7 @@ static int mic_bias_event(struct snd_soc_dapm_widget *w, | |||
457 | return 0; | 470 | return 0; |
458 | } | 471 | } |
459 | 472 | ||
460 | static const struct snd_soc_dapm_widget aic31xx_dapm_widgets[] = { | 473 | static const struct snd_soc_dapm_widget common31xx_dapm_widgets[] = { |
461 | SND_SOC_DAPM_AIF_IN("DAC IN", "DAC Playback", 0, SND_SOC_NOPM, 0, 0), | 474 | SND_SOC_DAPM_AIF_IN("DAC IN", "DAC Playback", 0, SND_SOC_NOPM, 0, 0), |
462 | 475 | ||
463 | SND_SOC_DAPM_MUX("DAC Left Input", | 476 | SND_SOC_DAPM_MUX("DAC Left Input", |
@@ -473,14 +486,7 @@ static const struct snd_soc_dapm_widget aic31xx_dapm_widgets[] = { | |||
473 | AIC31XX_DACSETUP, 6, 0, aic31xx_dapm_power_event, | 486 | AIC31XX_DACSETUP, 6, 0, aic31xx_dapm_power_event, |
474 | SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD), | 487 | SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD), |
475 | 488 | ||
476 | /* Output Mixers */ | 489 | /* HP */ |
477 | SND_SOC_DAPM_MIXER("Output Left", SND_SOC_NOPM, 0, 0, | ||
478 | left_output_switches, | ||
479 | ARRAY_SIZE(left_output_switches)), | ||
480 | SND_SOC_DAPM_MIXER("Output Right", SND_SOC_NOPM, 0, 0, | ||
481 | right_output_switches, | ||
482 | ARRAY_SIZE(right_output_switches)), | ||
483 | |||
484 | SND_SOC_DAPM_SWITCH("HP Left", SND_SOC_NOPM, 0, 0, | 490 | SND_SOC_DAPM_SWITCH("HP Left", SND_SOC_NOPM, 0, 0, |
485 | &aic31xx_dapm_hpl_switch), | 491 | &aic31xx_dapm_hpl_switch), |
486 | SND_SOC_DAPM_SWITCH("HP Right", SND_SOC_NOPM, 0, 0, | 492 | SND_SOC_DAPM_SWITCH("HP Right", SND_SOC_NOPM, 0, 0, |
@@ -494,10 +500,34 @@ static const struct snd_soc_dapm_widget aic31xx_dapm_widgets[] = { | |||
494 | NULL, 0, aic31xx_dapm_power_event, | 500 | NULL, 0, aic31xx_dapm_power_event, |
495 | SND_SOC_DAPM_POST_PMD | SND_SOC_DAPM_POST_PMU), | 501 | SND_SOC_DAPM_POST_PMD | SND_SOC_DAPM_POST_PMU), |
496 | 502 | ||
497 | /* ADC */ | 503 | /* Mic Bias */ |
498 | SND_SOC_DAPM_ADC_E("ADC", "Capture", AIC31XX_ADCSETUP, 7, 0, | 504 | SND_SOC_DAPM_SUPPLY("MICBIAS", SND_SOC_NOPM, 0, 0, mic_bias_event, |
499 | aic31xx_dapm_power_event, SND_SOC_DAPM_POST_PMU | | 505 | SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD), |
500 | SND_SOC_DAPM_POST_PMD), | 506 | |
507 | /* Outputs */ | ||
508 | SND_SOC_DAPM_OUTPUT("HPL"), | ||
509 | SND_SOC_DAPM_OUTPUT("HPR"), | ||
510 | }; | ||
511 | |||
512 | static const struct snd_soc_dapm_widget dac31xx_dapm_widgets[] = { | ||
513 | /* Inputs */ | ||
514 | SND_SOC_DAPM_INPUT("AIN1"), | ||
515 | SND_SOC_DAPM_INPUT("AIN2"), | ||
516 | |||
517 | /* Output Mixers */ | ||
518 | SND_SOC_DAPM_MIXER("Output Left", SND_SOC_NOPM, 0, 0, | ||
519 | dac31xx_left_output_switches, | ||
520 | ARRAY_SIZE(dac31xx_left_output_switches)), | ||
521 | SND_SOC_DAPM_MIXER("Output Right", SND_SOC_NOPM, 0, 0, | ||
522 | dac31xx_right_output_switches, | ||
523 | ARRAY_SIZE(dac31xx_right_output_switches)), | ||
524 | }; | ||
525 | |||
526 | static const struct snd_soc_dapm_widget aic31xx_dapm_widgets[] = { | ||
527 | /* Inputs */ | ||
528 | SND_SOC_DAPM_INPUT("MIC1LP"), | ||
529 | SND_SOC_DAPM_INPUT("MIC1RP"), | ||
530 | SND_SOC_DAPM_INPUT("MIC1LM"), | ||
501 | 531 | ||
502 | /* Input Selection to MIC_PGA */ | 532 | /* Input Selection to MIC_PGA */ |
503 | SND_SOC_DAPM_MUX("MIC1LP P-Terminal", SND_SOC_NOPM, 0, 0, | 533 | SND_SOC_DAPM_MUX("MIC1LP P-Terminal", SND_SOC_NOPM, 0, 0, |
@@ -507,24 +537,25 @@ static const struct snd_soc_dapm_widget aic31xx_dapm_widgets[] = { | |||
507 | SND_SOC_DAPM_MUX("MIC1LM P-Terminal", SND_SOC_NOPM, 0, 0, | 537 | SND_SOC_DAPM_MUX("MIC1LM P-Terminal", SND_SOC_NOPM, 0, 0, |
508 | &p_term_mic1lm), | 538 | &p_term_mic1lm), |
509 | 539 | ||
540 | /* ADC */ | ||
541 | SND_SOC_DAPM_ADC_E("ADC", "Capture", AIC31XX_ADCSETUP, 7, 0, | ||
542 | aic31xx_dapm_power_event, SND_SOC_DAPM_POST_PMU | | ||
543 | SND_SOC_DAPM_POST_PMD), | ||
544 | |||
510 | SND_SOC_DAPM_MUX("MIC1LM M-Terminal", SND_SOC_NOPM, 0, 0, | 545 | SND_SOC_DAPM_MUX("MIC1LM M-Terminal", SND_SOC_NOPM, 0, 0, |
511 | &m_term_mic1lm), | 546 | &m_term_mic1lm), |
547 | |||
512 | /* Enabling & Disabling MIC Gain Ctl */ | 548 | /* Enabling & Disabling MIC Gain Ctl */ |
513 | SND_SOC_DAPM_PGA("MIC_GAIN_CTL", AIC31XX_MICPGA, | 549 | SND_SOC_DAPM_PGA("MIC_GAIN_CTL", AIC31XX_MICPGA, |
514 | 7, 1, NULL, 0), | 550 | 7, 1, NULL, 0), |
515 | 551 | ||
516 | /* Mic Bias */ | 552 | /* Output Mixers */ |
517 | SND_SOC_DAPM_SUPPLY("MICBIAS", SND_SOC_NOPM, 0, 0, mic_bias_event, | 553 | SND_SOC_DAPM_MIXER("Output Left", SND_SOC_NOPM, 0, 0, |
518 | SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD), | 554 | aic31xx_left_output_switches, |
519 | 555 | ARRAY_SIZE(aic31xx_left_output_switches)), | |
520 | /* Outputs */ | 556 | SND_SOC_DAPM_MIXER("Output Right", SND_SOC_NOPM, 0, 0, |
521 | SND_SOC_DAPM_OUTPUT("HPL"), | 557 | aic31xx_right_output_switches, |
522 | SND_SOC_DAPM_OUTPUT("HPR"), | 558 | ARRAY_SIZE(aic31xx_right_output_switches)), |
523 | |||
524 | /* Inputs */ | ||
525 | SND_SOC_DAPM_INPUT("MIC1LP"), | ||
526 | SND_SOC_DAPM_INPUT("MIC1RP"), | ||
527 | SND_SOC_DAPM_INPUT("MIC1LM"), | ||
528 | }; | 559 | }; |
529 | 560 | ||
530 | static const struct snd_soc_dapm_widget aic311x_dapm_widgets[] = { | 561 | static const struct snd_soc_dapm_widget aic311x_dapm_widgets[] = { |
@@ -554,7 +585,7 @@ static const struct snd_soc_dapm_widget aic310x_dapm_widgets[] = { | |||
554 | }; | 585 | }; |
555 | 586 | ||
556 | static const struct snd_soc_dapm_route | 587 | static const struct snd_soc_dapm_route |
557 | aic31xx_audio_map[] = { | 588 | common31xx_audio_map[] = { |
558 | /* DAC Input Routing */ | 589 | /* DAC Input Routing */ |
559 | {"DAC Left Input", "Left Data", "DAC IN"}, | 590 | {"DAC Left Input", "Left Data", "DAC IN"}, |
560 | {"DAC Left Input", "Right Data", "DAC IN"}, | 591 | {"DAC Left Input", "Right Data", "DAC IN"}, |
@@ -565,6 +596,31 @@ aic31xx_audio_map[] = { | |||
565 | {"DAC Left", NULL, "DAC Left Input"}, | 596 | {"DAC Left", NULL, "DAC Left Input"}, |
566 | {"DAC Right", NULL, "DAC Right Input"}, | 597 | {"DAC Right", NULL, "DAC Right Input"}, |
567 | 598 | ||
599 | /* HPL path */ | ||
600 | {"HP Left", "Switch", "Output Left"}, | ||
601 | {"HPL Driver", NULL, "HP Left"}, | ||
602 | {"HPL", NULL, "HPL Driver"}, | ||
603 | |||
604 | /* HPR path */ | ||
605 | {"HP Right", "Switch", "Output Right"}, | ||
606 | {"HPR Driver", NULL, "HP Right"}, | ||
607 | {"HPR", NULL, "HPR Driver"}, | ||
608 | }; | ||
609 | |||
610 | static const struct snd_soc_dapm_route | ||
611 | dac31xx_audio_map[] = { | ||
612 | /* Left Output */ | ||
613 | {"Output Left", "From Left DAC", "DAC Left"}, | ||
614 | {"Output Left", "From AIN1", "AIN1"}, | ||
615 | {"Output Left", "From AIN2", "AIN2"}, | ||
616 | |||
617 | /* Right Output */ | ||
618 | {"Output Right", "From Right DAC", "DAC Right"}, | ||
619 | {"Output Right", "From AIN2", "AIN2"}, | ||
620 | }; | ||
621 | |||
622 | static const struct snd_soc_dapm_route | ||
623 | aic31xx_audio_map[] = { | ||
568 | /* Mic input */ | 624 | /* Mic input */ |
569 | {"MIC1LP P-Terminal", "FFR 10 Ohm", "MIC1LP"}, | 625 | {"MIC1LP P-Terminal", "FFR 10 Ohm", "MIC1LP"}, |
570 | {"MIC1LP P-Terminal", "FFR 20 Ohm", "MIC1LP"}, | 626 | {"MIC1LP P-Terminal", "FFR 20 Ohm", "MIC1LP"}, |
@@ -595,16 +651,6 @@ aic31xx_audio_map[] = { | |||
595 | /* Right Output */ | 651 | /* Right Output */ |
596 | {"Output Right", "From Right DAC", "DAC Right"}, | 652 | {"Output Right", "From Right DAC", "DAC Right"}, |
597 | {"Output Right", "From MIC1RP", "MIC1RP"}, | 653 | {"Output Right", "From MIC1RP", "MIC1RP"}, |
598 | |||
599 | /* HPL path */ | ||
600 | {"HP Left", "Switch", "Output Left"}, | ||
601 | {"HPL Driver", NULL, "HP Left"}, | ||
602 | {"HPL", NULL, "HPL Driver"}, | ||
603 | |||
604 | /* HPR path */ | ||
605 | {"HP Right", "Switch", "Output Right"}, | ||
606 | {"HPR Driver", NULL, "HP Right"}, | ||
607 | {"HPR", NULL, "HPR Driver"}, | ||
608 | }; | 654 | }; |
609 | 655 | ||
610 | static const struct snd_soc_dapm_route | 656 | static const struct snd_soc_dapm_route |
@@ -633,6 +679,13 @@ static int aic31xx_add_controls(struct snd_soc_codec *codec) | |||
633 | int ret = 0; | 679 | int ret = 0; |
634 | struct aic31xx_priv *aic31xx = snd_soc_codec_get_drvdata(codec); | 680 | struct aic31xx_priv *aic31xx = snd_soc_codec_get_drvdata(codec); |
635 | 681 | ||
682 | if (!(aic31xx->pdata.codec_type & DAC31XX_BIT)) | ||
683 | ret = snd_soc_add_codec_controls( | ||
684 | codec, aic31xx_snd_controls, | ||
685 | ARRAY_SIZE(aic31xx_snd_controls)); | ||
686 | if (ret) | ||
687 | return ret; | ||
688 | |||
636 | if (aic31xx->pdata.codec_type & AIC31XX_STEREO_CLASS_D_BIT) | 689 | if (aic31xx->pdata.codec_type & AIC31XX_STEREO_CLASS_D_BIT) |
637 | ret = snd_soc_add_codec_controls( | 690 | ret = snd_soc_add_codec_controls( |
638 | codec, aic311x_snd_controls, | 691 | codec, aic311x_snd_controls, |
@@ -651,6 +704,30 @@ static int aic31xx_add_widgets(struct snd_soc_codec *codec) | |||
651 | struct aic31xx_priv *aic31xx = snd_soc_codec_get_drvdata(codec); | 704 | struct aic31xx_priv *aic31xx = snd_soc_codec_get_drvdata(codec); |
652 | int ret = 0; | 705 | int ret = 0; |
653 | 706 | ||
707 | if (aic31xx->pdata.codec_type & DAC31XX_BIT) { | ||
708 | ret = snd_soc_dapm_new_controls( | ||
709 | dapm, dac31xx_dapm_widgets, | ||
710 | ARRAY_SIZE(dac31xx_dapm_widgets)); | ||
711 | if (ret) | ||
712 | return ret; | ||
713 | |||
714 | ret = snd_soc_dapm_add_routes(dapm, dac31xx_audio_map, | ||
715 | ARRAY_SIZE(dac31xx_audio_map)); | ||
716 | if (ret) | ||
717 | return ret; | ||
718 | } else { | ||
719 | ret = snd_soc_dapm_new_controls( | ||
720 | dapm, aic31xx_dapm_widgets, | ||
721 | ARRAY_SIZE(aic31xx_dapm_widgets)); | ||
722 | if (ret) | ||
723 | return ret; | ||
724 | |||
725 | ret = snd_soc_dapm_add_routes(dapm, aic31xx_audio_map, | ||
726 | ARRAY_SIZE(aic31xx_audio_map)); | ||
727 | if (ret) | ||
728 | return ret; | ||
729 | } | ||
730 | |||
654 | if (aic31xx->pdata.codec_type & AIC31XX_STEREO_CLASS_D_BIT) { | 731 | if (aic31xx->pdata.codec_type & AIC31XX_STEREO_CLASS_D_BIT) { |
655 | ret = snd_soc_dapm_new_controls( | 732 | ret = snd_soc_dapm_new_controls( |
656 | dapm, aic311x_dapm_widgets, | 733 | dapm, aic311x_dapm_widgets, |
@@ -1114,12 +1191,14 @@ static struct snd_soc_codec_driver soc_codec_driver_aic31xx = { | |||
1114 | .set_bias_level = aic31xx_set_bias_level, | 1191 | .set_bias_level = aic31xx_set_bias_level, |
1115 | .suspend_bias_off = true, | 1192 | .suspend_bias_off = true, |
1116 | 1193 | ||
1117 | .controls = aic31xx_snd_controls, | 1194 | .component_driver = { |
1118 | .num_controls = ARRAY_SIZE(aic31xx_snd_controls), | 1195 | .controls = common31xx_snd_controls, |
1119 | .dapm_widgets = aic31xx_dapm_widgets, | 1196 | .num_controls = ARRAY_SIZE(common31xx_snd_controls), |
1120 | .num_dapm_widgets = ARRAY_SIZE(aic31xx_dapm_widgets), | 1197 | .dapm_widgets = common31xx_dapm_widgets, |
1121 | .dapm_routes = aic31xx_audio_map, | 1198 | .num_dapm_widgets = ARRAY_SIZE(common31xx_dapm_widgets), |
1122 | .num_dapm_routes = ARRAY_SIZE(aic31xx_audio_map), | 1199 | .dapm_routes = common31xx_audio_map, |
1200 | .num_dapm_routes = ARRAY_SIZE(common31xx_audio_map), | ||
1201 | }, | ||
1123 | }; | 1202 | }; |
1124 | 1203 | ||
1125 | static const struct snd_soc_dai_ops aic31xx_dai_ops = { | 1204 | static const struct snd_soc_dai_ops aic31xx_dai_ops = { |
@@ -1129,19 +1208,34 @@ static const struct snd_soc_dai_ops aic31xx_dai_ops = { | |||
1129 | .digital_mute = aic31xx_dac_mute, | 1208 | .digital_mute = aic31xx_dac_mute, |
1130 | }; | 1209 | }; |
1131 | 1210 | ||
1211 | static struct snd_soc_dai_driver dac31xx_dai_driver[] = { | ||
1212 | { | ||
1213 | .name = "tlv32dac31xx-hifi", | ||
1214 | .playback = { | ||
1215 | .stream_name = "Playback", | ||
1216 | .channels_min = 2, | ||
1217 | .channels_max = 2, | ||
1218 | .rates = AIC31XX_RATES, | ||
1219 | .formats = AIC31XX_FORMATS, | ||
1220 | }, | ||
1221 | .ops = &aic31xx_dai_ops, | ||
1222 | .symmetric_rates = 1, | ||
1223 | } | ||
1224 | }; | ||
1225 | |||
1132 | static struct snd_soc_dai_driver aic31xx_dai_driver[] = { | 1226 | static struct snd_soc_dai_driver aic31xx_dai_driver[] = { |
1133 | { | 1227 | { |
1134 | .name = "tlv320aic31xx-hifi", | 1228 | .name = "tlv320aic31xx-hifi", |
1135 | .playback = { | 1229 | .playback = { |
1136 | .stream_name = "Playback", | 1230 | .stream_name = "Playback", |
1137 | .channels_min = 1, | 1231 | .channels_min = 2, |
1138 | .channels_max = 2, | 1232 | .channels_max = 2, |
1139 | .rates = AIC31XX_RATES, | 1233 | .rates = AIC31XX_RATES, |
1140 | .formats = AIC31XX_FORMATS, | 1234 | .formats = AIC31XX_FORMATS, |
1141 | }, | 1235 | }, |
1142 | .capture = { | 1236 | .capture = { |
1143 | .stream_name = "Capture", | 1237 | .stream_name = "Capture", |
1144 | .channels_min = 1, | 1238 | .channels_min = 2, |
1145 | .channels_max = 2, | 1239 | .channels_max = 2, |
1146 | .rates = AIC31XX_RATES, | 1240 | .rates = AIC31XX_RATES, |
1147 | .formats = AIC31XX_FORMATS, | 1241 | .formats = AIC31XX_FORMATS, |
@@ -1259,9 +1353,16 @@ static int aic31xx_i2c_probe(struct i2c_client *i2c, | |||
1259 | if (ret) | 1353 | if (ret) |
1260 | return ret; | 1354 | return ret; |
1261 | 1355 | ||
1262 | return snd_soc_register_codec(&i2c->dev, &soc_codec_driver_aic31xx, | 1356 | if (aic31xx->pdata.codec_type & DAC31XX_BIT) |
1263 | aic31xx_dai_driver, | 1357 | return snd_soc_register_codec(&i2c->dev, |
1264 | ARRAY_SIZE(aic31xx_dai_driver)); | 1358 | &soc_codec_driver_aic31xx, |
1359 | dac31xx_dai_driver, | ||
1360 | ARRAY_SIZE(dac31xx_dai_driver)); | ||
1361 | else | ||
1362 | return snd_soc_register_codec(&i2c->dev, | ||
1363 | &soc_codec_driver_aic31xx, | ||
1364 | aic31xx_dai_driver, | ||
1365 | ARRAY_SIZE(aic31xx_dai_driver)); | ||
1265 | } | 1366 | } |
1266 | 1367 | ||
1267 | static int aic31xx_i2c_remove(struct i2c_client *i2c) | 1368 | static int aic31xx_i2c_remove(struct i2c_client *i2c) |
@@ -1277,6 +1378,7 @@ static const struct i2c_device_id aic31xx_i2c_id[] = { | |||
1277 | { "tlv320aic3110", AIC3110 }, | 1378 | { "tlv320aic3110", AIC3110 }, |
1278 | { "tlv320aic3120", AIC3120 }, | 1379 | { "tlv320aic3120", AIC3120 }, |
1279 | { "tlv320aic3111", AIC3111 }, | 1380 | { "tlv320aic3111", AIC3111 }, |
1381 | { "tlv320dac3100", DAC3100 }, | ||
1280 | { } | 1382 | { } |
1281 | }; | 1383 | }; |
1282 | MODULE_DEVICE_TABLE(i2c, aic31xx_i2c_id); | 1384 | MODULE_DEVICE_TABLE(i2c, aic31xx_i2c_id); |
diff --git a/sound/soc/codecs/tlv320aic31xx.h b/sound/soc/codecs/tlv320aic31xx.h index ac9b146526eb..5acd5b69fb83 100644 --- a/sound/soc/codecs/tlv320aic31xx.h +++ b/sound/soc/codecs/tlv320aic31xx.h | |||
@@ -24,12 +24,14 @@ | |||
24 | 24 | ||
25 | #define AIC31XX_STEREO_CLASS_D_BIT 0x1 | 25 | #define AIC31XX_STEREO_CLASS_D_BIT 0x1 |
26 | #define AIC31XX_MINIDSP_BIT 0x2 | 26 | #define AIC31XX_MINIDSP_BIT 0x2 |
27 | #define DAC31XX_BIT 0x4 | ||
27 | 28 | ||
28 | enum aic31xx_type { | 29 | enum aic31xx_type { |
29 | AIC3100 = 0, | 30 | AIC3100 = 0, |
30 | AIC3110 = AIC31XX_STEREO_CLASS_D_BIT, | 31 | AIC3110 = AIC31XX_STEREO_CLASS_D_BIT, |
31 | AIC3120 = AIC31XX_MINIDSP_BIT, | 32 | AIC3120 = AIC31XX_MINIDSP_BIT, |
32 | AIC3111 = (AIC31XX_STEREO_CLASS_D_BIT | AIC31XX_MINIDSP_BIT), | 33 | AIC3111 = (AIC31XX_STEREO_CLASS_D_BIT | AIC31XX_MINIDSP_BIT), |
34 | DAC3100 = DAC31XX_BIT, | ||
33 | }; | 35 | }; |
34 | 36 | ||
35 | struct aic31xx_pdata { | 37 | struct aic31xx_pdata { |
diff --git a/sound/soc/codecs/tlv320aic32x4.c b/sound/soc/codecs/tlv320aic32x4.c index 85d4978d0384..28fdfc5ec544 100644 --- a/sound/soc/codecs/tlv320aic32x4.c +++ b/sound/soc/codecs/tlv320aic32x4.c | |||
@@ -797,12 +797,14 @@ static struct snd_soc_codec_driver soc_codec_dev_aic32x4 = { | |||
797 | .set_bias_level = aic32x4_set_bias_level, | 797 | .set_bias_level = aic32x4_set_bias_level, |
798 | .suspend_bias_off = true, | 798 | .suspend_bias_off = true, |
799 | 799 | ||
800 | .controls = aic32x4_snd_controls, | 800 | .component_driver = { |
801 | .num_controls = ARRAY_SIZE(aic32x4_snd_controls), | 801 | .controls = aic32x4_snd_controls, |
802 | .dapm_widgets = aic32x4_dapm_widgets, | 802 | .num_controls = ARRAY_SIZE(aic32x4_snd_controls), |
803 | .num_dapm_widgets = ARRAY_SIZE(aic32x4_dapm_widgets), | 803 | .dapm_widgets = aic32x4_dapm_widgets, |
804 | .dapm_routes = aic32x4_dapm_routes, | 804 | .num_dapm_widgets = ARRAY_SIZE(aic32x4_dapm_widgets), |
805 | .num_dapm_routes = ARRAY_SIZE(aic32x4_dapm_routes), | 805 | .dapm_routes = aic32x4_dapm_routes, |
806 | .num_dapm_routes = ARRAY_SIZE(aic32x4_dapm_routes), | ||
807 | }, | ||
806 | }; | 808 | }; |
807 | 809 | ||
808 | static int aic32x4_parse_dt(struct aic32x4_priv *aic32x4, | 810 | static int aic32x4_parse_dt(struct aic32x4_priv *aic32x4, |
diff --git a/sound/soc/codecs/tlv320aic3x.c b/sound/soc/codecs/tlv320aic3x.c index a564759845f9..5a8d96ec058c 100644 --- a/sound/soc/codecs/tlv320aic3x.c +++ b/sound/soc/codecs/tlv320aic3x.c | |||
@@ -1670,12 +1670,14 @@ static struct snd_soc_codec_driver soc_codec_dev_aic3x = { | |||
1670 | .idle_bias_off = true, | 1670 | .idle_bias_off = true, |
1671 | .probe = aic3x_probe, | 1671 | .probe = aic3x_probe, |
1672 | .remove = aic3x_remove, | 1672 | .remove = aic3x_remove, |
1673 | .controls = aic3x_snd_controls, | 1673 | .component_driver = { |
1674 | .num_controls = ARRAY_SIZE(aic3x_snd_controls), | 1674 | .controls = aic3x_snd_controls, |
1675 | .dapm_widgets = aic3x_dapm_widgets, | 1675 | .num_controls = ARRAY_SIZE(aic3x_snd_controls), |
1676 | .num_dapm_widgets = ARRAY_SIZE(aic3x_dapm_widgets), | 1676 | .dapm_widgets = aic3x_dapm_widgets, |
1677 | .dapm_routes = intercon, | 1677 | .num_dapm_widgets = ARRAY_SIZE(aic3x_dapm_widgets), |
1678 | .num_dapm_routes = ARRAY_SIZE(intercon), | 1678 | .dapm_routes = intercon, |
1679 | .num_dapm_routes = ARRAY_SIZE(intercon), | ||
1680 | }, | ||
1679 | }; | 1681 | }; |
1680 | 1682 | ||
1681 | /* | 1683 | /* |
diff --git a/sound/soc/codecs/tlv320dac33.c b/sound/soc/codecs/tlv320dac33.c index f7a6ce7e5fb1..7bcf01efdf9a 100644 --- a/sound/soc/codecs/tlv320dac33.c +++ b/sound/soc/codecs/tlv320dac33.c | |||
@@ -90,7 +90,6 @@ static const char *dac33_supply_names[DAC33_NUM_SUPPLIES] = { | |||
90 | 90 | ||
91 | struct tlv320dac33_priv { | 91 | struct tlv320dac33_priv { |
92 | struct mutex mutex; | 92 | struct mutex mutex; |
93 | struct workqueue_struct *dac33_wq; | ||
94 | struct work_struct work; | 93 | struct work_struct work; |
95 | struct snd_soc_codec *codec; | 94 | struct snd_soc_codec *codec; |
96 | struct regulator_bulk_data supplies[DAC33_NUM_SUPPLIES]; | 95 | struct regulator_bulk_data supplies[DAC33_NUM_SUPPLIES]; |
@@ -771,7 +770,7 @@ static irqreturn_t dac33_interrupt_handler(int irq, void *dev) | |||
771 | 770 | ||
772 | /* Do not schedule the workqueue in Mode7 */ | 771 | /* Do not schedule the workqueue in Mode7 */ |
773 | if (dac33->fifo_mode != DAC33_FIFO_MODE7) | 772 | if (dac33->fifo_mode != DAC33_FIFO_MODE7) |
774 | queue_work(dac33->dac33_wq, &dac33->work); | 773 | schedule_work(&dac33->work); |
775 | 774 | ||
776 | return IRQ_HANDLED; | 775 | return IRQ_HANDLED; |
777 | } | 776 | } |
@@ -1127,7 +1126,7 @@ static int dac33_pcm_trigger(struct snd_pcm_substream *substream, int cmd, | |||
1127 | case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: | 1126 | case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: |
1128 | if (dac33->fifo_mode) { | 1127 | if (dac33->fifo_mode) { |
1129 | dac33->state = DAC33_PREFILL; | 1128 | dac33->state = DAC33_PREFILL; |
1130 | queue_work(dac33->dac33_wq, &dac33->work); | 1129 | schedule_work(&dac33->work); |
1131 | } | 1130 | } |
1132 | break; | 1131 | break; |
1133 | case SNDRV_PCM_TRIGGER_STOP: | 1132 | case SNDRV_PCM_TRIGGER_STOP: |
@@ -1135,7 +1134,7 @@ static int dac33_pcm_trigger(struct snd_pcm_substream *substream, int cmd, | |||
1135 | case SNDRV_PCM_TRIGGER_PAUSE_PUSH: | 1134 | case SNDRV_PCM_TRIGGER_PAUSE_PUSH: |
1136 | if (dac33->fifo_mode) { | 1135 | if (dac33->fifo_mode) { |
1137 | dac33->state = DAC33_FLUSH; | 1136 | dac33->state = DAC33_FLUSH; |
1138 | queue_work(dac33->dac33_wq, &dac33->work); | 1137 | schedule_work(&dac33->work); |
1139 | } | 1138 | } |
1140 | break; | 1139 | break; |
1141 | default: | 1140 | default: |
@@ -1410,14 +1409,6 @@ static int dac33_soc_probe(struct snd_soc_codec *codec) | |||
1410 | dac33->irq = -1; | 1409 | dac33->irq = -1; |
1411 | } | 1410 | } |
1412 | if (dac33->irq != -1) { | 1411 | if (dac33->irq != -1) { |
1413 | /* Setup work queue */ | ||
1414 | dac33->dac33_wq = | ||
1415 | create_singlethread_workqueue("tlv320dac33"); | ||
1416 | if (dac33->dac33_wq == NULL) { | ||
1417 | free_irq(dac33->irq, codec); | ||
1418 | return -ENOMEM; | ||
1419 | } | ||
1420 | |||
1421 | INIT_WORK(&dac33->work, dac33_work); | 1412 | INIT_WORK(&dac33->work, dac33_work); |
1422 | } | 1413 | } |
1423 | } | 1414 | } |
@@ -1437,7 +1428,7 @@ static int dac33_soc_remove(struct snd_soc_codec *codec) | |||
1437 | 1428 | ||
1438 | if (dac33->irq >= 0) { | 1429 | if (dac33->irq >= 0) { |
1439 | free_irq(dac33->irq, dac33->codec); | 1430 | free_irq(dac33->irq, dac33->codec); |
1440 | destroy_workqueue(dac33->dac33_wq); | 1431 | flush_work(&dac33->work); |
1441 | } | 1432 | } |
1442 | return 0; | 1433 | return 0; |
1443 | } | 1434 | } |
@@ -1453,12 +1444,14 @@ static struct snd_soc_codec_driver soc_codec_dev_tlv320dac33 = { | |||
1453 | .probe = dac33_soc_probe, | 1444 | .probe = dac33_soc_probe, |
1454 | .remove = dac33_soc_remove, | 1445 | .remove = dac33_soc_remove, |
1455 | 1446 | ||
1456 | .controls = dac33_snd_controls, | 1447 | .component_driver = { |
1457 | .num_controls = ARRAY_SIZE(dac33_snd_controls), | 1448 | .controls = dac33_snd_controls, |
1458 | .dapm_widgets = dac33_dapm_widgets, | 1449 | .num_controls = ARRAY_SIZE(dac33_snd_controls), |
1459 | .num_dapm_widgets = ARRAY_SIZE(dac33_dapm_widgets), | 1450 | .dapm_widgets = dac33_dapm_widgets, |
1460 | .dapm_routes = audio_map, | 1451 | .num_dapm_widgets = ARRAY_SIZE(dac33_dapm_widgets), |
1461 | .num_dapm_routes = ARRAY_SIZE(audio_map), | 1452 | .dapm_routes = audio_map, |
1453 | .num_dapm_routes = ARRAY_SIZE(audio_map), | ||
1454 | }, | ||
1462 | }; | 1455 | }; |
1463 | 1456 | ||
1464 | #define DAC33_RATES (SNDRV_PCM_RATE_44100 | \ | 1457 | #define DAC33_RATES (SNDRV_PCM_RATE_44100 | \ |
diff --git a/sound/soc/codecs/tpa6130a2.c b/sound/soc/codecs/tpa6130a2.c index f1ea052a822e..2e014c80d113 100644 --- a/sound/soc/codecs/tpa6130a2.c +++ b/sound/soc/codecs/tpa6130a2.c | |||
@@ -52,7 +52,7 @@ struct tpa6130a2_data { | |||
52 | 52 | ||
53 | static int tpa6130a2_power(struct tpa6130a2_data *data, bool enable) | 53 | static int tpa6130a2_power(struct tpa6130a2_data *data, bool enable) |
54 | { | 54 | { |
55 | int ret; | 55 | int ret = 0, ret2; |
56 | 56 | ||
57 | if (enable) { | 57 | if (enable) { |
58 | ret = regulator_enable(data->supply); | 58 | ret = regulator_enable(data->supply); |
@@ -64,7 +64,30 @@ static int tpa6130a2_power(struct tpa6130a2_data *data, bool enable) | |||
64 | /* Power on */ | 64 | /* Power on */ |
65 | if (data->power_gpio >= 0) | 65 | if (data->power_gpio >= 0) |
66 | gpio_set_value(data->power_gpio, 1); | 66 | gpio_set_value(data->power_gpio, 1); |
67 | |||
68 | /* Sync registers */ | ||
69 | regcache_cache_only(data->regmap, false); | ||
70 | ret = regcache_sync(data->regmap); | ||
71 | if (ret != 0) { | ||
72 | dev_err(data->dev, | ||
73 | "Failed to sync registers: %d\n", ret); | ||
74 | regcache_cache_only(data->regmap, true); | ||
75 | if (data->power_gpio >= 0) | ||
76 | gpio_set_value(data->power_gpio, 0); | ||
77 | ret2 = regulator_disable(data->supply); | ||
78 | if (ret2 != 0) | ||
79 | dev_err(data->dev, | ||
80 | "Failed to disable supply: %d\n", ret2); | ||
81 | return ret; | ||
82 | } | ||
67 | } else { | 83 | } else { |
84 | /* Powered off device does not retain registers. While device | ||
85 | * is off, any register updates (i.e. volume changes) should | ||
86 | * happen in cache only. | ||
87 | */ | ||
88 | regcache_mark_dirty(data->regmap); | ||
89 | regcache_cache_only(data->regmap, true); | ||
90 | |||
68 | /* Power off */ | 91 | /* Power off */ |
69 | if (data->power_gpio >= 0) | 92 | if (data->power_gpio >= 0) |
70 | gpio_set_value(data->power_gpio, 0); | 93 | gpio_set_value(data->power_gpio, 0); |
@@ -75,9 +98,6 @@ static int tpa6130a2_power(struct tpa6130a2_data *data, bool enable) | |||
75 | "Failed to disable supply: %d\n", ret); | 98 | "Failed to disable supply: %d\n", ret); |
76 | return ret; | 99 | return ret; |
77 | } | 100 | } |
78 | |||
79 | /* device regs does not match the cache state anymore */ | ||
80 | regcache_mark_dirty(data->regmap); | ||
81 | } | 101 | } |
82 | 102 | ||
83 | return ret; | 103 | return ret; |
@@ -88,25 +108,14 @@ static int tpa6130a2_power_event(struct snd_soc_dapm_widget *w, | |||
88 | { | 108 | { |
89 | struct snd_soc_component *c = snd_soc_dapm_to_component(w->dapm); | 109 | struct snd_soc_component *c = snd_soc_dapm_to_component(w->dapm); |
90 | struct tpa6130a2_data *data = snd_soc_component_get_drvdata(c); | 110 | struct tpa6130a2_data *data = snd_soc_component_get_drvdata(c); |
91 | int ret; | ||
92 | 111 | ||
93 | /* before widget power up */ | ||
94 | if (SND_SOC_DAPM_EVENT_ON(event)) { | 112 | if (SND_SOC_DAPM_EVENT_ON(event)) { |
95 | /* Turn on the chip */ | 113 | /* Before widget power up: turn chip on, sync registers */ |
96 | tpa6130a2_power(data, true); | 114 | return tpa6130a2_power(data, true); |
97 | /* Sync the registers */ | ||
98 | ret = regcache_sync(data->regmap); | ||
99 | if (ret < 0) { | ||
100 | dev_err(c->dev, "Failed to initialize chip\n"); | ||
101 | tpa6130a2_power(data, false); | ||
102 | return ret; | ||
103 | } | ||
104 | /* after widget power down */ | ||
105 | } else { | 115 | } else { |
106 | tpa6130a2_power(data, false); | 116 | /* After widget power down: turn chip off */ |
117 | return tpa6130a2_power(data, false); | ||
107 | } | 118 | } |
108 | |||
109 | return 0; | ||
110 | } | 119 | } |
111 | 120 | ||
112 | /* | 121 | /* |
@@ -190,7 +199,7 @@ static const struct snd_soc_dapm_route tpa6130a2_dapm_routes[] = { | |||
190 | { "Right PGA", NULL, "Power" }, | 199 | { "Right PGA", NULL, "Power" }, |
191 | }; | 200 | }; |
192 | 201 | ||
193 | struct snd_soc_component_driver tpa6130a2_component_driver = { | 202 | static const struct snd_soc_component_driver tpa6130a2_component_driver = { |
194 | .name = "tpa6130a2", | 203 | .name = "tpa6130a2", |
195 | .probe = tpa6130a2_component_probe, | 204 | .probe = tpa6130a2_component_probe, |
196 | .dapm_widgets = tpa6130a2_dapm_widgets, | 205 | .dapm_widgets = tpa6130a2_dapm_widgets, |
diff --git a/sound/soc/codecs/twl4030.c b/sound/soc/codecs/twl4030.c index a5a4e9f75c57..a2104d68169d 100644 --- a/sound/soc/codecs/twl4030.c +++ b/sound/soc/codecs/twl4030.c | |||
@@ -2199,12 +2199,14 @@ static struct snd_soc_codec_driver soc_codec_dev_twl4030 = { | |||
2199 | .set_bias_level = twl4030_set_bias_level, | 2199 | .set_bias_level = twl4030_set_bias_level, |
2200 | .idle_bias_off = true, | 2200 | .idle_bias_off = true, |
2201 | 2201 | ||
2202 | .controls = twl4030_snd_controls, | 2202 | .component_driver = { |
2203 | .num_controls = ARRAY_SIZE(twl4030_snd_controls), | 2203 | .controls = twl4030_snd_controls, |
2204 | .dapm_widgets = twl4030_dapm_widgets, | 2204 | .num_controls = ARRAY_SIZE(twl4030_snd_controls), |
2205 | .num_dapm_widgets = ARRAY_SIZE(twl4030_dapm_widgets), | 2205 | .dapm_widgets = twl4030_dapm_widgets, |
2206 | .dapm_routes = intercon, | 2206 | .num_dapm_widgets = ARRAY_SIZE(twl4030_dapm_widgets), |
2207 | .num_dapm_routes = ARRAY_SIZE(intercon), | 2207 | .dapm_routes = intercon, |
2208 | .num_dapm_routes = ARRAY_SIZE(intercon), | ||
2209 | }, | ||
2208 | }; | 2210 | }; |
2209 | 2211 | ||
2210 | static int twl4030_codec_probe(struct platform_device *pdev) | 2212 | static int twl4030_codec_probe(struct platform_device *pdev) |
diff --git a/sound/soc/codecs/twl6040.c b/sound/soc/codecs/twl6040.c index 1f7081043566..748036e851ea 100644 --- a/sound/soc/codecs/twl6040.c +++ b/sound/soc/codecs/twl6040.c | |||
@@ -1156,12 +1156,14 @@ static struct snd_soc_codec_driver soc_codec_dev_twl6040 = { | |||
1156 | .suspend_bias_off = true, | 1156 | .suspend_bias_off = true, |
1157 | .ignore_pmdown_time = true, | 1157 | .ignore_pmdown_time = true, |
1158 | 1158 | ||
1159 | .controls = twl6040_snd_controls, | 1159 | .component_driver = { |
1160 | .num_controls = ARRAY_SIZE(twl6040_snd_controls), | 1160 | .controls = twl6040_snd_controls, |
1161 | .dapm_widgets = twl6040_dapm_widgets, | 1161 | .num_controls = ARRAY_SIZE(twl6040_snd_controls), |
1162 | .num_dapm_widgets = ARRAY_SIZE(twl6040_dapm_widgets), | 1162 | .dapm_widgets = twl6040_dapm_widgets, |
1163 | .dapm_routes = intercon, | 1163 | .num_dapm_widgets = ARRAY_SIZE(twl6040_dapm_widgets), |
1164 | .num_dapm_routes = ARRAY_SIZE(intercon), | 1164 | .dapm_routes = intercon, |
1165 | .num_dapm_routes = ARRAY_SIZE(intercon), | ||
1166 | }, | ||
1165 | }; | 1167 | }; |
1166 | 1168 | ||
1167 | static int twl6040_codec_probe(struct platform_device *pdev) | 1169 | static int twl6040_codec_probe(struct platform_device *pdev) |
diff --git a/sound/soc/codecs/uda134x.c b/sound/soc/codecs/uda134x.c index e4c694c758b8..5fdee874406d 100644 --- a/sound/soc/codecs/uda134x.c +++ b/sound/soc/codecs/uda134x.c | |||
@@ -523,10 +523,12 @@ static struct snd_soc_codec_driver soc_codec_dev_uda134x = { | |||
523 | .set_bias_level = uda134x_set_bias_level, | 523 | .set_bias_level = uda134x_set_bias_level, |
524 | .suspend_bias_off = true, | 524 | .suspend_bias_off = true, |
525 | 525 | ||
526 | .dapm_widgets = uda134x_dapm_widgets, | 526 | .component_driver = { |
527 | .num_dapm_widgets = ARRAY_SIZE(uda134x_dapm_widgets), | 527 | .dapm_widgets = uda134x_dapm_widgets, |
528 | .dapm_routes = uda134x_dapm_routes, | 528 | .num_dapm_widgets = ARRAY_SIZE(uda134x_dapm_widgets), |
529 | .num_dapm_routes = ARRAY_SIZE(uda134x_dapm_routes), | 529 | .dapm_routes = uda134x_dapm_routes, |
530 | .num_dapm_routes = ARRAY_SIZE(uda134x_dapm_routes), | ||
531 | }, | ||
530 | }; | 532 | }; |
531 | 533 | ||
532 | static const struct regmap_config uda134x_regmap_config = { | 534 | static const struct regmap_config uda134x_regmap_config = { |
@@ -544,6 +546,7 @@ static int uda134x_codec_probe(struct platform_device *pdev) | |||
544 | { | 546 | { |
545 | struct uda134x_platform_data *pd = pdev->dev.platform_data; | 547 | struct uda134x_platform_data *pd = pdev->dev.platform_data; |
546 | struct uda134x_priv *uda134x; | 548 | struct uda134x_priv *uda134x; |
549 | int ret; | ||
547 | 550 | ||
548 | if (!pd) { | 551 | if (!pd) { |
549 | dev_err(&pdev->dev, "Missing L3 bitbang function\n"); | 552 | dev_err(&pdev->dev, "Missing L3 bitbang function\n"); |
@@ -557,6 +560,12 @@ static int uda134x_codec_probe(struct platform_device *pdev) | |||
557 | uda134x->pd = pd; | 560 | uda134x->pd = pd; |
558 | platform_set_drvdata(pdev, uda134x); | 561 | platform_set_drvdata(pdev, uda134x); |
559 | 562 | ||
563 | if (pd->l3.use_gpios) { | ||
564 | ret = l3_set_gpio_ops(&pdev->dev, &uda134x->pd->l3); | ||
565 | if (ret < 0) | ||
566 | return ret; | ||
567 | } | ||
568 | |||
560 | uda134x->regmap = devm_regmap_init(&pdev->dev, NULL, pd, | 569 | uda134x->regmap = devm_regmap_init(&pdev->dev, NULL, pd, |
561 | &uda134x_regmap_config); | 570 | &uda134x_regmap_config); |
562 | if (IS_ERR(uda134x->regmap)) | 571 | if (IS_ERR(uda134x->regmap)) |
diff --git a/sound/soc/codecs/uda1380.c b/sound/soc/codecs/uda1380.c index 35f0469ebb16..533e3bb444e4 100644 --- a/sound/soc/codecs/uda1380.c +++ b/sound/soc/codecs/uda1380.c | |||
@@ -765,12 +765,14 @@ static struct snd_soc_codec_driver soc_codec_dev_uda1380 = { | |||
765 | .reg_cache_default = uda1380_reg, | 765 | .reg_cache_default = uda1380_reg, |
766 | .reg_cache_step = 1, | 766 | .reg_cache_step = 1, |
767 | 767 | ||
768 | .controls = uda1380_snd_controls, | 768 | .component_driver = { |
769 | .num_controls = ARRAY_SIZE(uda1380_snd_controls), | 769 | .controls = uda1380_snd_controls, |
770 | .dapm_widgets = uda1380_dapm_widgets, | 770 | .num_controls = ARRAY_SIZE(uda1380_snd_controls), |
771 | .num_dapm_widgets = ARRAY_SIZE(uda1380_dapm_widgets), | 771 | .dapm_widgets = uda1380_dapm_widgets, |
772 | .dapm_routes = uda1380_dapm_routes, | 772 | .num_dapm_widgets = ARRAY_SIZE(uda1380_dapm_widgets), |
773 | .num_dapm_routes = ARRAY_SIZE(uda1380_dapm_routes), | 773 | .dapm_routes = uda1380_dapm_routes, |
774 | .num_dapm_routes = ARRAY_SIZE(uda1380_dapm_routes), | ||
775 | }, | ||
774 | }; | 776 | }; |
775 | 777 | ||
776 | #if IS_ENABLED(CONFIG_I2C) | 778 | #if IS_ENABLED(CONFIG_I2C) |
diff --git a/sound/soc/codecs/wl1273.c b/sound/soc/codecs/wl1273.c index 1b79778098d2..fcffb6e707d9 100644 --- a/sound/soc/codecs/wl1273.c +++ b/sound/soc/codecs/wl1273.c | |||
@@ -484,12 +484,14 @@ static struct snd_soc_codec_driver soc_codec_dev_wl1273 = { | |||
484 | .probe = wl1273_probe, | 484 | .probe = wl1273_probe, |
485 | .remove = wl1273_remove, | 485 | .remove = wl1273_remove, |
486 | 486 | ||
487 | .controls = wl1273_controls, | 487 | .component_driver = { |
488 | .num_controls = ARRAY_SIZE(wl1273_controls), | 488 | .controls = wl1273_controls, |
489 | .dapm_widgets = wl1273_dapm_widgets, | 489 | .num_controls = ARRAY_SIZE(wl1273_controls), |
490 | .num_dapm_widgets = ARRAY_SIZE(wl1273_dapm_widgets), | 490 | .dapm_widgets = wl1273_dapm_widgets, |
491 | .dapm_routes = wl1273_dapm_routes, | 491 | .num_dapm_widgets = ARRAY_SIZE(wl1273_dapm_widgets), |
492 | .num_dapm_routes = ARRAY_SIZE(wl1273_dapm_routes), | 492 | .dapm_routes = wl1273_dapm_routes, |
493 | .num_dapm_routes = ARRAY_SIZE(wl1273_dapm_routes), | ||
494 | }, | ||
493 | }; | 495 | }; |
494 | 496 | ||
495 | static int wl1273_platform_probe(struct platform_device *pdev) | 497 | static int wl1273_platform_probe(struct platform_device *pdev) |
diff --git a/sound/soc/codecs/wm0010.c b/sound/soc/codecs/wm0010.c index e3c34bdc2772..0eb5dcf4c29d 100644 --- a/sound/soc/codecs/wm0010.c +++ b/sound/soc/codecs/wm0010.c | |||
@@ -789,16 +789,18 @@ static int wm0010_set_sysclk(struct snd_soc_codec *codec, int source, | |||
789 | 789 | ||
790 | static int wm0010_probe(struct snd_soc_codec *codec); | 790 | static int wm0010_probe(struct snd_soc_codec *codec); |
791 | 791 | ||
792 | static struct snd_soc_codec_driver soc_codec_dev_wm0010 = { | 792 | static const struct snd_soc_codec_driver soc_codec_dev_wm0010 = { |
793 | .probe = wm0010_probe, | 793 | .probe = wm0010_probe, |
794 | .set_bias_level = wm0010_set_bias_level, | 794 | .set_bias_level = wm0010_set_bias_level, |
795 | .set_sysclk = wm0010_set_sysclk, | 795 | .set_sysclk = wm0010_set_sysclk, |
796 | .idle_bias_off = true, | 796 | .idle_bias_off = true, |
797 | 797 | ||
798 | .dapm_widgets = wm0010_dapm_widgets, | 798 | .component_driver = { |
799 | .num_dapm_widgets = ARRAY_SIZE(wm0010_dapm_widgets), | 799 | .dapm_widgets = wm0010_dapm_widgets, |
800 | .dapm_routes = wm0010_dapm_routes, | 800 | .num_dapm_widgets = ARRAY_SIZE(wm0010_dapm_widgets), |
801 | .num_dapm_routes = ARRAY_SIZE(wm0010_dapm_routes), | 801 | .dapm_routes = wm0010_dapm_routes, |
802 | .num_dapm_routes = ARRAY_SIZE(wm0010_dapm_routes), | ||
803 | }, | ||
802 | }; | 804 | }; |
803 | 805 | ||
804 | #define WM0010_RATES (SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000) | 806 | #define WM0010_RATES (SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000) |
diff --git a/sound/soc/codecs/wm1250-ev1.c b/sound/soc/codecs/wm1250-ev1.c index ec45c5b220b1..cf5f0580df6a 100644 --- a/sound/soc/codecs/wm1250-ev1.c +++ b/sound/soc/codecs/wm1250-ev1.c | |||
@@ -141,12 +141,13 @@ static struct snd_soc_dai_driver wm1250_ev1_dai = { | |||
141 | .ops = &wm1250_ev1_ops, | 141 | .ops = &wm1250_ev1_ops, |
142 | }; | 142 | }; |
143 | 143 | ||
144 | static struct snd_soc_codec_driver soc_codec_dev_wm1250_ev1 = { | 144 | static const struct snd_soc_codec_driver soc_codec_dev_wm1250_ev1 = { |
145 | .dapm_widgets = wm1250_ev1_dapm_widgets, | 145 | .component_driver = { |
146 | .num_dapm_widgets = ARRAY_SIZE(wm1250_ev1_dapm_widgets), | 146 | .dapm_widgets = wm1250_ev1_dapm_widgets, |
147 | .dapm_routes = wm1250_ev1_dapm_routes, | 147 | .num_dapm_widgets = ARRAY_SIZE(wm1250_ev1_dapm_widgets), |
148 | .num_dapm_routes = ARRAY_SIZE(wm1250_ev1_dapm_routes), | 148 | .dapm_routes = wm1250_ev1_dapm_routes, |
149 | 149 | .num_dapm_routes = ARRAY_SIZE(wm1250_ev1_dapm_routes), | |
150 | }, | ||
150 | .set_bias_level = wm1250_ev1_set_bias_level, | 151 | .set_bias_level = wm1250_ev1_set_bias_level, |
151 | .idle_bias_off = true, | 152 | .idle_bias_off = true, |
152 | }; | 153 | }; |
diff --git a/sound/soc/codecs/wm2000.c b/sound/soc/codecs/wm2000.c index f2664396be6f..23cde3a0dc11 100644 --- a/sound/soc/codecs/wm2000.c +++ b/sound/soc/codecs/wm2000.c | |||
@@ -799,18 +799,20 @@ static int wm2000_remove(struct snd_soc_codec *codec) | |||
799 | return wm2000_anc_transition(wm2000, ANC_OFF); | 799 | return wm2000_anc_transition(wm2000, ANC_OFF); |
800 | } | 800 | } |
801 | 801 | ||
802 | static struct snd_soc_codec_driver soc_codec_dev_wm2000 = { | 802 | static const struct snd_soc_codec_driver soc_codec_dev_wm2000 = { |
803 | .probe = wm2000_probe, | 803 | .probe = wm2000_probe, |
804 | .remove = wm2000_remove, | 804 | .remove = wm2000_remove, |
805 | .suspend = wm2000_suspend, | 805 | .suspend = wm2000_suspend, |
806 | .resume = wm2000_resume, | 806 | .resume = wm2000_resume, |
807 | 807 | ||
808 | .dapm_widgets = wm2000_dapm_widgets, | 808 | .component_driver = { |
809 | .num_dapm_widgets = ARRAY_SIZE(wm2000_dapm_widgets), | 809 | .controls = wm2000_controls, |
810 | .dapm_routes = wm2000_audio_map, | 810 | .num_controls = ARRAY_SIZE(wm2000_controls), |
811 | .num_dapm_routes = ARRAY_SIZE(wm2000_audio_map), | 811 | .dapm_widgets = wm2000_dapm_widgets, |
812 | .controls = wm2000_controls, | 812 | .num_dapm_widgets = ARRAY_SIZE(wm2000_dapm_widgets), |
813 | .num_controls = ARRAY_SIZE(wm2000_controls), | 813 | .dapm_routes = wm2000_audio_map, |
814 | .num_dapm_routes = ARRAY_SIZE(wm2000_audio_map), | ||
815 | }, | ||
814 | }; | 816 | }; |
815 | 817 | ||
816 | static int wm2000_i2c_probe(struct i2c_client *i2c, | 818 | static int wm2000_i2c_probe(struct i2c_client *i2c, |
diff --git a/sound/soc/codecs/wm2200.c b/sound/soc/codecs/wm2200.c index fd1439ecb50a..606bf88abfc4 100644 --- a/sound/soc/codecs/wm2200.c +++ b/sound/soc/codecs/wm2200.c | |||
@@ -2103,7 +2103,7 @@ static struct snd_soc_dai_driver wm2200_dai = { | |||
2103 | .ops = &wm2200_dai_ops, | 2103 | .ops = &wm2200_dai_ops, |
2104 | }; | 2104 | }; |
2105 | 2105 | ||
2106 | static struct snd_soc_codec_driver soc_codec_wm2200 = { | 2106 | static const struct snd_soc_codec_driver soc_codec_wm2200 = { |
2107 | .probe = wm2200_probe, | 2107 | .probe = wm2200_probe, |
2108 | 2108 | ||
2109 | .idle_bias_off = true, | 2109 | .idle_bias_off = true, |
@@ -2111,12 +2111,14 @@ static struct snd_soc_codec_driver soc_codec_wm2200 = { | |||
2111 | .set_sysclk = wm2200_set_sysclk, | 2111 | .set_sysclk = wm2200_set_sysclk, |
2112 | .set_pll = wm2200_set_fll, | 2112 | .set_pll = wm2200_set_fll, |
2113 | 2113 | ||
2114 | .controls = wm2200_snd_controls, | 2114 | .component_driver = { |
2115 | .num_controls = ARRAY_SIZE(wm2200_snd_controls), | 2115 | .controls = wm2200_snd_controls, |
2116 | .dapm_widgets = wm2200_dapm_widgets, | 2116 | .num_controls = ARRAY_SIZE(wm2200_snd_controls), |
2117 | .num_dapm_widgets = ARRAY_SIZE(wm2200_dapm_widgets), | 2117 | .dapm_widgets = wm2200_dapm_widgets, |
2118 | .dapm_routes = wm2200_dapm_routes, | 2118 | .num_dapm_widgets = ARRAY_SIZE(wm2200_dapm_widgets), |
2119 | .num_dapm_routes = ARRAY_SIZE(wm2200_dapm_routes), | 2119 | .dapm_routes = wm2200_dapm_routes, |
2120 | .num_dapm_routes = ARRAY_SIZE(wm2200_dapm_routes), | ||
2121 | }, | ||
2120 | }; | 2122 | }; |
2121 | 2123 | ||
2122 | static irqreturn_t wm2200_irq(int irq, void *data) | 2124 | static irqreturn_t wm2200_irq(int irq, void *data) |
diff --git a/sound/soc/codecs/wm5100.c b/sound/soc/codecs/wm5100.c index 512a9d25fe6f..560575000cc5 100644 --- a/sound/soc/codecs/wm5100.c +++ b/sound/soc/codecs/wm5100.c | |||
@@ -2285,7 +2285,7 @@ static int wm5100_gpio_direction_in(struct gpio_chip *chip, unsigned offset) | |||
2285 | (1 << WM5100_GP1_DIR_SHIFT)); | 2285 | (1 << WM5100_GP1_DIR_SHIFT)); |
2286 | } | 2286 | } |
2287 | 2287 | ||
2288 | static struct gpio_chip wm5100_template_chip = { | 2288 | static const struct gpio_chip wm5100_template_chip = { |
2289 | .label = "wm5100", | 2289 | .label = "wm5100", |
2290 | .owner = THIS_MODULE, | 2290 | .owner = THIS_MODULE, |
2291 | .direction_output = wm5100_gpio_direction_out, | 2291 | .direction_output = wm5100_gpio_direction_out, |
@@ -2381,7 +2381,7 @@ static int wm5100_remove(struct snd_soc_codec *codec) | |||
2381 | return 0; | 2381 | return 0; |
2382 | } | 2382 | } |
2383 | 2383 | ||
2384 | static struct snd_soc_codec_driver soc_codec_dev_wm5100 = { | 2384 | static const struct snd_soc_codec_driver soc_codec_dev_wm5100 = { |
2385 | .probe = wm5100_probe, | 2385 | .probe = wm5100_probe, |
2386 | .remove = wm5100_remove, | 2386 | .remove = wm5100_remove, |
2387 | 2387 | ||
@@ -2390,12 +2390,14 @@ static struct snd_soc_codec_driver soc_codec_dev_wm5100 = { | |||
2390 | .idle_bias_off = 1, | 2390 | .idle_bias_off = 1, |
2391 | 2391 | ||
2392 | .seq_notifier = wm5100_seq_notifier, | 2392 | .seq_notifier = wm5100_seq_notifier, |
2393 | .controls = wm5100_snd_controls, | 2393 | .component_driver = { |
2394 | .num_controls = ARRAY_SIZE(wm5100_snd_controls), | 2394 | .controls = wm5100_snd_controls, |
2395 | .dapm_widgets = wm5100_dapm_widgets, | 2395 | .num_controls = ARRAY_SIZE(wm5100_snd_controls), |
2396 | .num_dapm_widgets = ARRAY_SIZE(wm5100_dapm_widgets), | 2396 | .dapm_widgets = wm5100_dapm_widgets, |
2397 | .dapm_routes = wm5100_dapm_routes, | 2397 | .num_dapm_widgets = ARRAY_SIZE(wm5100_dapm_widgets), |
2398 | .num_dapm_routes = ARRAY_SIZE(wm5100_dapm_routes), | 2398 | .dapm_routes = wm5100_dapm_routes, |
2399 | .num_dapm_routes = ARRAY_SIZE(wm5100_dapm_routes), | ||
2400 | }, | ||
2399 | }; | 2401 | }; |
2400 | 2402 | ||
2401 | static const struct regmap_config wm5100_regmap = { | 2403 | static const struct regmap_config wm5100_regmap = { |
diff --git a/sound/soc/codecs/wm5102.c b/sound/soc/codecs/wm5102.c index 846deed6af41..93876c6d48ee 100644 --- a/sound/soc/codecs/wm5102.c +++ b/sound/soc/codecs/wm5102.c | |||
@@ -1521,6 +1521,16 @@ static const struct snd_soc_dapm_route wm5102_dapm_routes[] = { | |||
1521 | { "IN3L", NULL, "SYSCLK" }, | 1521 | { "IN3L", NULL, "SYSCLK" }, |
1522 | { "IN3R", NULL, "SYSCLK" }, | 1522 | { "IN3R", NULL, "SYSCLK" }, |
1523 | 1523 | ||
1524 | { "ASRC1L", NULL, "SYSCLK" }, | ||
1525 | { "ASRC1R", NULL, "SYSCLK" }, | ||
1526 | { "ASRC2L", NULL, "SYSCLK" }, | ||
1527 | { "ASRC2R", NULL, "SYSCLK" }, | ||
1528 | |||
1529 | { "ASRC1L", NULL, "ASYNCCLK" }, | ||
1530 | { "ASRC1R", NULL, "ASYNCCLK" }, | ||
1531 | { "ASRC2L", NULL, "ASYNCCLK" }, | ||
1532 | { "ASRC2R", NULL, "ASYNCCLK" }, | ||
1533 | |||
1524 | { "MICBIAS1", NULL, "MICVDD" }, | 1534 | { "MICBIAS1", NULL, "MICVDD" }, |
1525 | { "MICBIAS2", NULL, "MICVDD" }, | 1535 | { "MICBIAS2", NULL, "MICVDD" }, |
1526 | { "MICBIAS3", NULL, "MICVDD" }, | 1536 | { "MICBIAS3", NULL, "MICVDD" }, |
@@ -1600,7 +1610,6 @@ static const struct snd_soc_dapm_route wm5102_dapm_routes[] = { | |||
1600 | { "Slim3 Capture", NULL, "SYSCLK" }, | 1610 | { "Slim3 Capture", NULL, "SYSCLK" }, |
1601 | 1611 | ||
1602 | { "Audio Trace DSP", NULL, "DSP1" }, | 1612 | { "Audio Trace DSP", NULL, "DSP1" }, |
1603 | { "Audio Trace DSP", NULL, "SYSCLK" }, | ||
1604 | 1613 | ||
1605 | { "IN1L PGA", NULL, "IN1L" }, | 1614 | { "IN1L PGA", NULL, "IN1L" }, |
1606 | { "IN1R PGA", NULL, "IN1R" }, | 1615 | { "IN1R PGA", NULL, "IN1R" }, |
@@ -1990,7 +1999,7 @@ static struct regmap *wm5102_get_regmap(struct device *dev) | |||
1990 | return priv->core.arizona->regmap; | 1999 | return priv->core.arizona->regmap; |
1991 | } | 2000 | } |
1992 | 2001 | ||
1993 | static struct snd_soc_codec_driver soc_codec_dev_wm5102 = { | 2002 | static const struct snd_soc_codec_driver soc_codec_dev_wm5102 = { |
1994 | .probe = wm5102_codec_probe, | 2003 | .probe = wm5102_codec_probe, |
1995 | .remove = wm5102_codec_remove, | 2004 | .remove = wm5102_codec_remove, |
1996 | .get_regmap = wm5102_get_regmap, | 2005 | .get_regmap = wm5102_get_regmap, |
@@ -2000,12 +2009,14 @@ static struct snd_soc_codec_driver soc_codec_dev_wm5102 = { | |||
2000 | .set_sysclk = arizona_set_sysclk, | 2009 | .set_sysclk = arizona_set_sysclk, |
2001 | .set_pll = wm5102_set_fll, | 2010 | .set_pll = wm5102_set_fll, |
2002 | 2011 | ||
2003 | .controls = wm5102_snd_controls, | 2012 | .component_driver = { |
2004 | .num_controls = ARRAY_SIZE(wm5102_snd_controls), | 2013 | .controls = wm5102_snd_controls, |
2005 | .dapm_widgets = wm5102_dapm_widgets, | 2014 | .num_controls = ARRAY_SIZE(wm5102_snd_controls), |
2006 | .num_dapm_widgets = ARRAY_SIZE(wm5102_dapm_widgets), | 2015 | .dapm_widgets = wm5102_dapm_widgets, |
2007 | .dapm_routes = wm5102_dapm_routes, | 2016 | .num_dapm_widgets = ARRAY_SIZE(wm5102_dapm_widgets), |
2008 | .num_dapm_routes = ARRAY_SIZE(wm5102_dapm_routes), | 2017 | .dapm_routes = wm5102_dapm_routes, |
2018 | .num_dapm_routes = ARRAY_SIZE(wm5102_dapm_routes), | ||
2019 | }, | ||
2009 | }; | 2020 | }; |
2010 | 2021 | ||
2011 | static struct snd_compr_ops wm5102_compr_ops = { | 2022 | static struct snd_compr_ops wm5102_compr_ops = { |
diff --git a/sound/soc/codecs/wm5110.c b/sound/soc/codecs/wm5110.c index 156547026a40..06bae3b23fce 100644 --- a/sound/soc/codecs/wm5110.c +++ b/sound/soc/codecs/wm5110.c | |||
@@ -1745,6 +1745,16 @@ static const struct snd_soc_dapm_route wm5110_dapm_routes[] = { | |||
1745 | { "IN4L", NULL, "SYSCLK" }, | 1745 | { "IN4L", NULL, "SYSCLK" }, |
1746 | { "IN4R", NULL, "SYSCLK" }, | 1746 | { "IN4R", NULL, "SYSCLK" }, |
1747 | 1747 | ||
1748 | { "ASRC1L", NULL, "SYSCLK" }, | ||
1749 | { "ASRC1R", NULL, "SYSCLK" }, | ||
1750 | { "ASRC2L", NULL, "SYSCLK" }, | ||
1751 | { "ASRC2R", NULL, "SYSCLK" }, | ||
1752 | |||
1753 | { "ASRC1L", NULL, "ASYNCCLK" }, | ||
1754 | { "ASRC1R", NULL, "ASYNCCLK" }, | ||
1755 | { "ASRC2L", NULL, "ASYNCCLK" }, | ||
1756 | { "ASRC2R", NULL, "ASYNCCLK" }, | ||
1757 | |||
1748 | { "MICBIAS1", NULL, "MICVDD" }, | 1758 | { "MICBIAS1", NULL, "MICVDD" }, |
1749 | { "MICBIAS2", NULL, "MICVDD" }, | 1759 | { "MICBIAS2", NULL, "MICVDD" }, |
1750 | { "MICBIAS3", NULL, "MICVDD" }, | 1760 | { "MICBIAS3", NULL, "MICVDD" }, |
@@ -1832,10 +1842,8 @@ static const struct snd_soc_dapm_route wm5110_dapm_routes[] = { | |||
1832 | { "Slim3 Capture", NULL, "SYSCLK" }, | 1842 | { "Slim3 Capture", NULL, "SYSCLK" }, |
1833 | 1843 | ||
1834 | { "Voice Control DSP", NULL, "DSP3" }, | 1844 | { "Voice Control DSP", NULL, "DSP3" }, |
1835 | { "Voice Control DSP", NULL, "SYSCLK" }, | ||
1836 | 1845 | ||
1837 | { "Audio Trace DSP", NULL, "DSP1" }, | 1846 | { "Audio Trace DSP", NULL, "DSP1" }, |
1838 | { "Audio Trace DSP", NULL, "SYSCLK" }, | ||
1839 | 1847 | ||
1840 | { "IN1L PGA", NULL, "IN1L" }, | 1848 | { "IN1L PGA", NULL, "IN1L" }, |
1841 | { "IN1R PGA", NULL, "IN1R" }, | 1849 | { "IN1R PGA", NULL, "IN1R" }, |
@@ -2347,7 +2355,7 @@ static struct regmap *wm5110_get_regmap(struct device *dev) | |||
2347 | return priv->core.arizona->regmap; | 2355 | return priv->core.arizona->regmap; |
2348 | } | 2356 | } |
2349 | 2357 | ||
2350 | static struct snd_soc_codec_driver soc_codec_dev_wm5110 = { | 2358 | static const struct snd_soc_codec_driver soc_codec_dev_wm5110 = { |
2351 | .probe = wm5110_codec_probe, | 2359 | .probe = wm5110_codec_probe, |
2352 | .remove = wm5110_codec_remove, | 2360 | .remove = wm5110_codec_remove, |
2353 | .get_regmap = wm5110_get_regmap, | 2361 | .get_regmap = wm5110_get_regmap, |
@@ -2357,12 +2365,14 @@ static struct snd_soc_codec_driver soc_codec_dev_wm5110 = { | |||
2357 | .set_sysclk = arizona_set_sysclk, | 2365 | .set_sysclk = arizona_set_sysclk, |
2358 | .set_pll = wm5110_set_fll, | 2366 | .set_pll = wm5110_set_fll, |
2359 | 2367 | ||
2360 | .controls = wm5110_snd_controls, | 2368 | .component_driver = { |
2361 | .num_controls = ARRAY_SIZE(wm5110_snd_controls), | 2369 | .controls = wm5110_snd_controls, |
2362 | .dapm_widgets = wm5110_dapm_widgets, | 2370 | .num_controls = ARRAY_SIZE(wm5110_snd_controls), |
2363 | .num_dapm_widgets = ARRAY_SIZE(wm5110_dapm_widgets), | 2371 | .dapm_widgets = wm5110_dapm_widgets, |
2364 | .dapm_routes = wm5110_dapm_routes, | 2372 | .num_dapm_widgets = ARRAY_SIZE(wm5110_dapm_widgets), |
2365 | .num_dapm_routes = ARRAY_SIZE(wm5110_dapm_routes), | 2373 | .dapm_routes = wm5110_dapm_routes, |
2374 | .num_dapm_routes = ARRAY_SIZE(wm5110_dapm_routes), | ||
2375 | }, | ||
2366 | }; | 2376 | }; |
2367 | 2377 | ||
2368 | static struct snd_compr_ops wm5110_compr_ops = { | 2378 | static struct snd_compr_ops wm5110_compr_ops = { |
diff --git a/sound/soc/codecs/wm8350.c b/sound/soc/codecs/wm8350.c index ffbf3df8ae97..2efc5b41ad0f 100644 --- a/sound/soc/codecs/wm8350.c +++ b/sound/soc/codecs/wm8350.c | |||
@@ -1587,19 +1587,21 @@ static struct regmap *wm8350_get_regmap(struct device *dev) | |||
1587 | return wm8350->regmap; | 1587 | return wm8350->regmap; |
1588 | } | 1588 | } |
1589 | 1589 | ||
1590 | static struct snd_soc_codec_driver soc_codec_dev_wm8350 = { | 1590 | static const struct snd_soc_codec_driver soc_codec_dev_wm8350 = { |
1591 | .probe = wm8350_codec_probe, | 1591 | .probe = wm8350_codec_probe, |
1592 | .remove = wm8350_codec_remove, | 1592 | .remove = wm8350_codec_remove, |
1593 | .get_regmap = wm8350_get_regmap, | 1593 | .get_regmap = wm8350_get_regmap, |
1594 | .set_bias_level = wm8350_set_bias_level, | 1594 | .set_bias_level = wm8350_set_bias_level, |
1595 | .suspend_bias_off = true, | 1595 | .suspend_bias_off = true, |
1596 | 1596 | ||
1597 | .controls = wm8350_snd_controls, | 1597 | .component_driver = { |
1598 | .num_controls = ARRAY_SIZE(wm8350_snd_controls), | 1598 | .controls = wm8350_snd_controls, |
1599 | .dapm_widgets = wm8350_dapm_widgets, | 1599 | .num_controls = ARRAY_SIZE(wm8350_snd_controls), |
1600 | .num_dapm_widgets = ARRAY_SIZE(wm8350_dapm_widgets), | 1600 | .dapm_widgets = wm8350_dapm_widgets, |
1601 | .dapm_routes = wm8350_dapm_routes, | 1601 | .num_dapm_widgets = ARRAY_SIZE(wm8350_dapm_widgets), |
1602 | .num_dapm_routes = ARRAY_SIZE(wm8350_dapm_routes), | 1602 | .dapm_routes = wm8350_dapm_routes, |
1603 | .num_dapm_routes = ARRAY_SIZE(wm8350_dapm_routes), | ||
1604 | }, | ||
1603 | }; | 1605 | }; |
1604 | 1606 | ||
1605 | static int wm8350_probe(struct platform_device *pdev) | 1607 | static int wm8350_probe(struct platform_device *pdev) |
diff --git a/sound/soc/codecs/wm8400.c b/sound/soc/codecs/wm8400.c index b1d346aa4696..6c59fb933bd6 100644 --- a/sound/soc/codecs/wm8400.c +++ b/sound/soc/codecs/wm8400.c | |||
@@ -1332,19 +1332,21 @@ static struct regmap *wm8400_get_regmap(struct device *dev) | |||
1332 | return wm8400->regmap; | 1332 | return wm8400->regmap; |
1333 | } | 1333 | } |
1334 | 1334 | ||
1335 | static struct snd_soc_codec_driver soc_codec_dev_wm8400 = { | 1335 | static const struct snd_soc_codec_driver soc_codec_dev_wm8400 = { |
1336 | .probe = wm8400_codec_probe, | 1336 | .probe = wm8400_codec_probe, |
1337 | .remove = wm8400_codec_remove, | 1337 | .remove = wm8400_codec_remove, |
1338 | .get_regmap = wm8400_get_regmap, | 1338 | .get_regmap = wm8400_get_regmap, |
1339 | .set_bias_level = wm8400_set_bias_level, | 1339 | .set_bias_level = wm8400_set_bias_level, |
1340 | .suspend_bias_off = true, | 1340 | .suspend_bias_off = true, |
1341 | 1341 | ||
1342 | .controls = wm8400_snd_controls, | 1342 | .component_driver = { |
1343 | .num_controls = ARRAY_SIZE(wm8400_snd_controls), | 1343 | .controls = wm8400_snd_controls, |
1344 | .dapm_widgets = wm8400_dapm_widgets, | 1344 | .num_controls = ARRAY_SIZE(wm8400_snd_controls), |
1345 | .num_dapm_widgets = ARRAY_SIZE(wm8400_dapm_widgets), | 1345 | .dapm_widgets = wm8400_dapm_widgets, |
1346 | .dapm_routes = wm8400_dapm_routes, | 1346 | .num_dapm_widgets = ARRAY_SIZE(wm8400_dapm_widgets), |
1347 | .num_dapm_routes = ARRAY_SIZE(wm8400_dapm_routes), | 1347 | .dapm_routes = wm8400_dapm_routes, |
1348 | .num_dapm_routes = ARRAY_SIZE(wm8400_dapm_routes), | ||
1349 | }, | ||
1348 | }; | 1350 | }; |
1349 | 1351 | ||
1350 | static int wm8400_probe(struct platform_device *pdev) | 1352 | static int wm8400_probe(struct platform_device *pdev) |
diff --git a/sound/soc/codecs/wm8510.c b/sound/soc/codecs/wm8510.c index 99e40e629cca..119ceac684ae 100644 --- a/sound/soc/codecs/wm8510.c +++ b/sound/soc/codecs/wm8510.c | |||
@@ -581,17 +581,19 @@ static int wm8510_probe(struct snd_soc_codec *codec) | |||
581 | return 0; | 581 | return 0; |
582 | } | 582 | } |
583 | 583 | ||
584 | static struct snd_soc_codec_driver soc_codec_dev_wm8510 = { | 584 | static const struct snd_soc_codec_driver soc_codec_dev_wm8510 = { |
585 | .probe = wm8510_probe, | 585 | .probe = wm8510_probe, |
586 | .set_bias_level = wm8510_set_bias_level, | 586 | .set_bias_level = wm8510_set_bias_level, |
587 | .suspend_bias_off = true, | 587 | .suspend_bias_off = true, |
588 | 588 | ||
589 | .controls = wm8510_snd_controls, | 589 | .component_driver = { |
590 | .num_controls = ARRAY_SIZE(wm8510_snd_controls), | 590 | .controls = wm8510_snd_controls, |
591 | .dapm_widgets = wm8510_dapm_widgets, | 591 | .num_controls = ARRAY_SIZE(wm8510_snd_controls), |
592 | .num_dapm_widgets = ARRAY_SIZE(wm8510_dapm_widgets), | 592 | .dapm_widgets = wm8510_dapm_widgets, |
593 | .dapm_routes = wm8510_dapm_routes, | 593 | .num_dapm_widgets = ARRAY_SIZE(wm8510_dapm_widgets), |
594 | .num_dapm_routes = ARRAY_SIZE(wm8510_dapm_routes), | 594 | .dapm_routes = wm8510_dapm_routes, |
595 | .num_dapm_routes = ARRAY_SIZE(wm8510_dapm_routes), | ||
596 | }, | ||
595 | }; | 597 | }; |
596 | 598 | ||
597 | static const struct of_device_id wm8510_of_match[] = { | 599 | static const struct of_device_id wm8510_of_match[] = { |
diff --git a/sound/soc/codecs/wm8523.c b/sound/soc/codecs/wm8523.c index aa287a3965e7..deb2e075428e 100644 --- a/sound/soc/codecs/wm8523.c +++ b/sound/soc/codecs/wm8523.c | |||
@@ -413,17 +413,19 @@ static int wm8523_probe(struct snd_soc_codec *codec) | |||
413 | return 0; | 413 | return 0; |
414 | } | 414 | } |
415 | 415 | ||
416 | static struct snd_soc_codec_driver soc_codec_dev_wm8523 = { | 416 | static const struct snd_soc_codec_driver soc_codec_dev_wm8523 = { |
417 | .probe = wm8523_probe, | 417 | .probe = wm8523_probe, |
418 | .set_bias_level = wm8523_set_bias_level, | 418 | .set_bias_level = wm8523_set_bias_level, |
419 | .suspend_bias_off = true, | 419 | .suspend_bias_off = true, |
420 | 420 | ||
421 | .controls = wm8523_controls, | 421 | .component_driver = { |
422 | .num_controls = ARRAY_SIZE(wm8523_controls), | 422 | .controls = wm8523_controls, |
423 | .dapm_widgets = wm8523_dapm_widgets, | 423 | .num_controls = ARRAY_SIZE(wm8523_controls), |
424 | .num_dapm_widgets = ARRAY_SIZE(wm8523_dapm_widgets), | 424 | .dapm_widgets = wm8523_dapm_widgets, |
425 | .dapm_routes = wm8523_dapm_routes, | 425 | .num_dapm_widgets = ARRAY_SIZE(wm8523_dapm_widgets), |
426 | .num_dapm_routes = ARRAY_SIZE(wm8523_dapm_routes), | 426 | .dapm_routes = wm8523_dapm_routes, |
427 | .num_dapm_routes = ARRAY_SIZE(wm8523_dapm_routes), | ||
428 | }, | ||
427 | }; | 429 | }; |
428 | 430 | ||
429 | static const struct of_device_id wm8523_of_match[] = { | 431 | static const struct of_device_id wm8523_of_match[] = { |
diff --git a/sound/soc/codecs/wm8580.c b/sound/soc/codecs/wm8580.c index 66602bf02f6e..faa7287a5253 100644 --- a/sound/soc/codecs/wm8580.c +++ b/sound/soc/codecs/wm8580.c | |||
@@ -899,17 +899,19 @@ static int wm8580_remove(struct snd_soc_codec *codec) | |||
899 | return 0; | 899 | return 0; |
900 | } | 900 | } |
901 | 901 | ||
902 | static struct snd_soc_codec_driver soc_codec_dev_wm8580 = { | 902 | static const struct snd_soc_codec_driver soc_codec_dev_wm8580 = { |
903 | .probe = wm8580_probe, | 903 | .probe = wm8580_probe, |
904 | .remove = wm8580_remove, | 904 | .remove = wm8580_remove, |
905 | .set_bias_level = wm8580_set_bias_level, | 905 | .set_bias_level = wm8580_set_bias_level, |
906 | 906 | ||
907 | .controls = wm8580_snd_controls, | 907 | .component_driver = { |
908 | .num_controls = ARRAY_SIZE(wm8580_snd_controls), | 908 | .controls = wm8580_snd_controls, |
909 | .dapm_widgets = wm8580_dapm_widgets, | 909 | .num_controls = ARRAY_SIZE(wm8580_snd_controls), |
910 | .num_dapm_widgets = ARRAY_SIZE(wm8580_dapm_widgets), | 910 | .dapm_widgets = wm8580_dapm_widgets, |
911 | .dapm_routes = wm8580_dapm_routes, | 911 | .num_dapm_widgets = ARRAY_SIZE(wm8580_dapm_widgets), |
912 | .num_dapm_routes = ARRAY_SIZE(wm8580_dapm_routes), | 912 | .dapm_routes = wm8580_dapm_routes, |
913 | .num_dapm_routes = ARRAY_SIZE(wm8580_dapm_routes), | ||
914 | }, | ||
913 | }; | 915 | }; |
914 | 916 | ||
915 | static const struct of_device_id wm8580_of_match[] = { | 917 | static const struct of_device_id wm8580_of_match[] = { |
diff --git a/sound/soc/codecs/wm8711.c b/sound/soc/codecs/wm8711.c index c759ec068e97..2b376c9c99af 100644 --- a/sound/soc/codecs/wm8711.c +++ b/sound/soc/codecs/wm8711.c | |||
@@ -367,17 +367,19 @@ static int wm8711_probe(struct snd_soc_codec *codec) | |||
367 | 367 | ||
368 | } | 368 | } |
369 | 369 | ||
370 | static struct snd_soc_codec_driver soc_codec_dev_wm8711 = { | 370 | static const struct snd_soc_codec_driver soc_codec_dev_wm8711 = { |
371 | .probe = wm8711_probe, | 371 | .probe = wm8711_probe, |
372 | .set_bias_level = wm8711_set_bias_level, | 372 | .set_bias_level = wm8711_set_bias_level, |
373 | .suspend_bias_off = true, | 373 | .suspend_bias_off = true, |
374 | 374 | ||
375 | .controls = wm8711_snd_controls, | 375 | .component_driver = { |
376 | .num_controls = ARRAY_SIZE(wm8711_snd_controls), | 376 | .controls = wm8711_snd_controls, |
377 | .dapm_widgets = wm8711_dapm_widgets, | 377 | .num_controls = ARRAY_SIZE(wm8711_snd_controls), |
378 | .num_dapm_widgets = ARRAY_SIZE(wm8711_dapm_widgets), | 378 | .dapm_widgets = wm8711_dapm_widgets, |
379 | .dapm_routes = wm8711_intercon, | 379 | .num_dapm_widgets = ARRAY_SIZE(wm8711_dapm_widgets), |
380 | .num_dapm_routes = ARRAY_SIZE(wm8711_intercon), | 380 | .dapm_routes = wm8711_intercon, |
381 | .num_dapm_routes = ARRAY_SIZE(wm8711_intercon), | ||
382 | }, | ||
381 | }; | 383 | }; |
382 | 384 | ||
383 | static const struct of_device_id wm8711_of_match[] = { | 385 | static const struct of_device_id wm8711_of_match[] = { |
diff --git a/sound/soc/codecs/wm8727.c b/sound/soc/codecs/wm8727.c index bb25a75f92a2..7fde077a014b 100644 --- a/sound/soc/codecs/wm8727.c +++ b/sound/soc/codecs/wm8727.c | |||
@@ -53,11 +53,13 @@ static struct snd_soc_dai_driver wm8727_dai = { | |||
53 | }, | 53 | }, |
54 | }; | 54 | }; |
55 | 55 | ||
56 | static struct snd_soc_codec_driver soc_codec_dev_wm8727 = { | 56 | static const struct snd_soc_codec_driver soc_codec_dev_wm8727 = { |
57 | .dapm_widgets = wm8727_dapm_widgets, | 57 | .component_driver = { |
58 | .num_dapm_widgets = ARRAY_SIZE(wm8727_dapm_widgets), | 58 | .dapm_widgets = wm8727_dapm_widgets, |
59 | .dapm_routes = wm8727_dapm_routes, | 59 | .num_dapm_widgets = ARRAY_SIZE(wm8727_dapm_widgets), |
60 | .num_dapm_routes = ARRAY_SIZE(wm8727_dapm_routes), | 60 | .dapm_routes = wm8727_dapm_routes, |
61 | .num_dapm_routes = ARRAY_SIZE(wm8727_dapm_routes), | ||
62 | }, | ||
61 | }; | 63 | }; |
62 | 64 | ||
63 | static int wm8727_probe(struct platform_device *pdev) | 65 | static int wm8727_probe(struct platform_device *pdev) |
diff --git a/sound/soc/codecs/wm8728.c b/sound/soc/codecs/wm8728.c index 1564e6926527..797cc6e7c70f 100644 --- a/sound/soc/codecs/wm8728.c +++ b/sound/soc/codecs/wm8728.c | |||
@@ -211,16 +211,18 @@ static struct snd_soc_dai_driver wm8728_dai = { | |||
211 | .ops = &wm8728_dai_ops, | 211 | .ops = &wm8728_dai_ops, |
212 | }; | 212 | }; |
213 | 213 | ||
214 | static struct snd_soc_codec_driver soc_codec_dev_wm8728 = { | 214 | static const struct snd_soc_codec_driver soc_codec_dev_wm8728 = { |
215 | .set_bias_level = wm8728_set_bias_level, | 215 | .set_bias_level = wm8728_set_bias_level, |
216 | .suspend_bias_off = true, | 216 | .suspend_bias_off = true, |
217 | 217 | ||
218 | .controls = wm8728_snd_controls, | 218 | .component_driver = { |
219 | .num_controls = ARRAY_SIZE(wm8728_snd_controls), | 219 | .controls = wm8728_snd_controls, |
220 | .dapm_widgets = wm8728_dapm_widgets, | 220 | .num_controls = ARRAY_SIZE(wm8728_snd_controls), |
221 | .num_dapm_widgets = ARRAY_SIZE(wm8728_dapm_widgets), | 221 | .dapm_widgets = wm8728_dapm_widgets, |
222 | .dapm_routes = wm8728_intercon, | 222 | .num_dapm_widgets = ARRAY_SIZE(wm8728_dapm_widgets), |
223 | .num_dapm_routes = ARRAY_SIZE(wm8728_intercon), | 223 | .dapm_routes = wm8728_intercon, |
224 | .num_dapm_routes = ARRAY_SIZE(wm8728_intercon), | ||
225 | }, | ||
224 | }; | 226 | }; |
225 | 227 | ||
226 | static const struct of_device_id wm8728_of_match[] = { | 228 | static const struct of_device_id wm8728_of_match[] = { |
diff --git a/sound/soc/codecs/wm8731.c b/sound/soc/codecs/wm8731.c index d18261a44256..4f9a1eb28120 100644 --- a/sound/soc/codecs/wm8731.c +++ b/sound/soc/codecs/wm8731.c | |||
@@ -628,16 +628,18 @@ err_regulator_enable: | |||
628 | return ret; | 628 | return ret; |
629 | } | 629 | } |
630 | 630 | ||
631 | static struct snd_soc_codec_driver soc_codec_dev_wm8731 = { | 631 | static const struct snd_soc_codec_driver soc_codec_dev_wm8731 = { |
632 | .set_bias_level = wm8731_set_bias_level, | 632 | .set_bias_level = wm8731_set_bias_level, |
633 | .suspend_bias_off = true, | 633 | .suspend_bias_off = true, |
634 | 634 | ||
635 | .dapm_widgets = wm8731_dapm_widgets, | 635 | .component_driver = { |
636 | .num_dapm_widgets = ARRAY_SIZE(wm8731_dapm_widgets), | 636 | .controls = wm8731_snd_controls, |
637 | .dapm_routes = wm8731_intercon, | 637 | .num_controls = ARRAY_SIZE(wm8731_snd_controls), |
638 | .num_dapm_routes = ARRAY_SIZE(wm8731_intercon), | 638 | .dapm_widgets = wm8731_dapm_widgets, |
639 | .controls = wm8731_snd_controls, | 639 | .num_dapm_widgets = ARRAY_SIZE(wm8731_dapm_widgets), |
640 | .num_controls = ARRAY_SIZE(wm8731_snd_controls), | 640 | .dapm_routes = wm8731_intercon, |
641 | .num_dapm_routes = ARRAY_SIZE(wm8731_intercon), | ||
642 | }, | ||
641 | }; | 643 | }; |
642 | 644 | ||
643 | static const struct of_device_id wm8731_of_match[] = { | 645 | static const struct of_device_id wm8731_of_match[] = { |
diff --git a/sound/soc/codecs/wm8737.c b/sound/soc/codecs/wm8737.c index e7807601e675..f0cb1c4afe3c 100644 --- a/sound/soc/codecs/wm8737.c +++ b/sound/soc/codecs/wm8737.c | |||
@@ -573,17 +573,19 @@ err_get: | |||
573 | return ret; | 573 | return ret; |
574 | } | 574 | } |
575 | 575 | ||
576 | static struct snd_soc_codec_driver soc_codec_dev_wm8737 = { | 576 | static const struct snd_soc_codec_driver soc_codec_dev_wm8737 = { |
577 | .probe = wm8737_probe, | 577 | .probe = wm8737_probe, |
578 | .set_bias_level = wm8737_set_bias_level, | 578 | .set_bias_level = wm8737_set_bias_level, |
579 | .suspend_bias_off = true, | 579 | .suspend_bias_off = true, |
580 | 580 | ||
581 | .controls = wm8737_snd_controls, | 581 | .component_driver = { |
582 | .num_controls = ARRAY_SIZE(wm8737_snd_controls), | 582 | .controls = wm8737_snd_controls, |
583 | .dapm_widgets = wm8737_dapm_widgets, | 583 | .num_controls = ARRAY_SIZE(wm8737_snd_controls), |
584 | .num_dapm_widgets = ARRAY_SIZE(wm8737_dapm_widgets), | 584 | .dapm_widgets = wm8737_dapm_widgets, |
585 | .dapm_routes = intercon, | 585 | .num_dapm_widgets = ARRAY_SIZE(wm8737_dapm_widgets), |
586 | .num_dapm_routes = ARRAY_SIZE(intercon), | 586 | .dapm_routes = intercon, |
587 | .num_dapm_routes = ARRAY_SIZE(intercon), | ||
588 | }, | ||
587 | }; | 589 | }; |
588 | 590 | ||
589 | static const struct of_device_id wm8737_of_match[] = { | 591 | static const struct of_device_id wm8737_of_match[] = { |
diff --git a/sound/soc/codecs/wm8741.c b/sound/soc/codecs/wm8741.c index 36ef91fe0511..565d477cd790 100644 --- a/sound/soc/codecs/wm8741.c +++ b/sound/soc/codecs/wm8741.c | |||
@@ -497,15 +497,17 @@ static int wm8741_remove(struct snd_soc_codec *codec) | |||
497 | return 0; | 497 | return 0; |
498 | } | 498 | } |
499 | 499 | ||
500 | static struct snd_soc_codec_driver soc_codec_dev_wm8741 = { | 500 | static const struct snd_soc_codec_driver soc_codec_dev_wm8741 = { |
501 | .probe = wm8741_probe, | 501 | .probe = wm8741_probe, |
502 | .remove = wm8741_remove, | 502 | .remove = wm8741_remove, |
503 | .resume = wm8741_resume, | 503 | .resume = wm8741_resume, |
504 | 504 | ||
505 | .dapm_widgets = wm8741_dapm_widgets, | 505 | .component_driver = { |
506 | .num_dapm_widgets = ARRAY_SIZE(wm8741_dapm_widgets), | 506 | .dapm_widgets = wm8741_dapm_widgets, |
507 | .dapm_routes = wm8741_dapm_routes, | 507 | .num_dapm_widgets = ARRAY_SIZE(wm8741_dapm_widgets), |
508 | .num_dapm_routes = ARRAY_SIZE(wm8741_dapm_routes), | 508 | .dapm_routes = wm8741_dapm_routes, |
509 | .num_dapm_routes = ARRAY_SIZE(wm8741_dapm_routes), | ||
510 | }, | ||
509 | }; | 511 | }; |
510 | 512 | ||
511 | static const struct of_device_id wm8741_of_match[] = { | 513 | static const struct of_device_id wm8741_of_match[] = { |
diff --git a/sound/soc/codecs/wm8750.c b/sound/soc/codecs/wm8750.c index bd9dcd2161bc..0da2bbaf06d1 100644 --- a/sound/soc/codecs/wm8750.c +++ b/sound/soc/codecs/wm8750.c | |||
@@ -708,17 +708,19 @@ static int wm8750_probe(struct snd_soc_codec *codec) | |||
708 | return ret; | 708 | return ret; |
709 | } | 709 | } |
710 | 710 | ||
711 | static struct snd_soc_codec_driver soc_codec_dev_wm8750 = { | 711 | static const struct snd_soc_codec_driver soc_codec_dev_wm8750 = { |
712 | .probe = wm8750_probe, | 712 | .probe = wm8750_probe, |
713 | .set_bias_level = wm8750_set_bias_level, | 713 | .set_bias_level = wm8750_set_bias_level, |
714 | .suspend_bias_off = true, | 714 | .suspend_bias_off = true, |
715 | 715 | ||
716 | .controls = wm8750_snd_controls, | 716 | .component_driver = { |
717 | .num_controls = ARRAY_SIZE(wm8750_snd_controls), | 717 | .controls = wm8750_snd_controls, |
718 | .dapm_widgets = wm8750_dapm_widgets, | 718 | .num_controls = ARRAY_SIZE(wm8750_snd_controls), |
719 | .num_dapm_widgets = ARRAY_SIZE(wm8750_dapm_widgets), | 719 | .dapm_widgets = wm8750_dapm_widgets, |
720 | .dapm_routes = wm8750_dapm_routes, | 720 | .num_dapm_widgets = ARRAY_SIZE(wm8750_dapm_widgets), |
721 | .num_dapm_routes = ARRAY_SIZE(wm8750_dapm_routes), | 721 | .dapm_routes = wm8750_dapm_routes, |
722 | .num_dapm_routes = ARRAY_SIZE(wm8750_dapm_routes), | ||
723 | }, | ||
722 | }; | 724 | }; |
723 | 725 | ||
724 | static const struct of_device_id wm8750_of_match[] = { | 726 | static const struct of_device_id wm8750_of_match[] = { |
diff --git a/sound/soc/codecs/wm8753.c b/sound/soc/codecs/wm8753.c index cdcc91282e8a..9bdf5447f6f6 100644 --- a/sound/soc/codecs/wm8753.c +++ b/sound/soc/codecs/wm8753.c | |||
@@ -1478,18 +1478,20 @@ static int wm8753_probe(struct snd_soc_codec *codec) | |||
1478 | return 0; | 1478 | return 0; |
1479 | } | 1479 | } |
1480 | 1480 | ||
1481 | static struct snd_soc_codec_driver soc_codec_dev_wm8753 = { | 1481 | static const struct snd_soc_codec_driver soc_codec_dev_wm8753 = { |
1482 | .probe = wm8753_probe, | 1482 | .probe = wm8753_probe, |
1483 | .resume = wm8753_resume, | 1483 | .resume = wm8753_resume, |
1484 | .set_bias_level = wm8753_set_bias_level, | 1484 | .set_bias_level = wm8753_set_bias_level, |
1485 | .suspend_bias_off = true, | 1485 | .suspend_bias_off = true, |
1486 | 1486 | ||
1487 | .controls = wm8753_snd_controls, | 1487 | .component_driver = { |
1488 | .num_controls = ARRAY_SIZE(wm8753_snd_controls), | 1488 | .controls = wm8753_snd_controls, |
1489 | .dapm_widgets = wm8753_dapm_widgets, | 1489 | .num_controls = ARRAY_SIZE(wm8753_snd_controls), |
1490 | .num_dapm_widgets = ARRAY_SIZE(wm8753_dapm_widgets), | 1490 | .dapm_widgets = wm8753_dapm_widgets, |
1491 | .dapm_routes = wm8753_dapm_routes, | 1491 | .num_dapm_widgets = ARRAY_SIZE(wm8753_dapm_widgets), |
1492 | .num_dapm_routes = ARRAY_SIZE(wm8753_dapm_routes), | 1492 | .dapm_routes = wm8753_dapm_routes, |
1493 | .num_dapm_routes = ARRAY_SIZE(wm8753_dapm_routes), | ||
1494 | }, | ||
1493 | }; | 1495 | }; |
1494 | 1496 | ||
1495 | static const struct of_device_id wm8753_of_match[] = { | 1497 | static const struct of_device_id wm8753_of_match[] = { |
diff --git a/sound/soc/codecs/wm8770.c b/sound/soc/codecs/wm8770.c index df6178464b00..d6edcbbdec12 100644 --- a/sound/soc/codecs/wm8770.c +++ b/sound/soc/codecs/wm8770.c | |||
@@ -608,17 +608,19 @@ err_reg_enable: | |||
608 | return ret; | 608 | return ret; |
609 | } | 609 | } |
610 | 610 | ||
611 | static struct snd_soc_codec_driver soc_codec_dev_wm8770 = { | 611 | static const struct snd_soc_codec_driver soc_codec_dev_wm8770 = { |
612 | .probe = wm8770_probe, | 612 | .probe = wm8770_probe, |
613 | .set_bias_level = wm8770_set_bias_level, | 613 | .set_bias_level = wm8770_set_bias_level, |
614 | .idle_bias_off = true, | 614 | .idle_bias_off = true, |
615 | 615 | ||
616 | .controls = wm8770_snd_controls, | 616 | .component_driver = { |
617 | .num_controls = ARRAY_SIZE(wm8770_snd_controls), | 617 | .controls = wm8770_snd_controls, |
618 | .dapm_widgets = wm8770_dapm_widgets, | 618 | .num_controls = ARRAY_SIZE(wm8770_snd_controls), |
619 | .num_dapm_widgets = ARRAY_SIZE(wm8770_dapm_widgets), | 619 | .dapm_widgets = wm8770_dapm_widgets, |
620 | .dapm_routes = wm8770_intercon, | 620 | .num_dapm_widgets = ARRAY_SIZE(wm8770_dapm_widgets), |
621 | .num_dapm_routes = ARRAY_SIZE(wm8770_intercon), | 621 | .dapm_routes = wm8770_intercon, |
622 | .num_dapm_routes = ARRAY_SIZE(wm8770_intercon), | ||
623 | }, | ||
622 | }; | 624 | }; |
623 | 625 | ||
624 | static const struct of_device_id wm8770_of_match[] = { | 626 | static const struct of_device_id wm8770_of_match[] = { |
diff --git a/sound/soc/codecs/wm8776.c b/sound/soc/codecs/wm8776.c index 5af44f9a8cf2..ae30480b3976 100644 --- a/sound/soc/codecs/wm8776.c +++ b/sound/soc/codecs/wm8776.c | |||
@@ -425,17 +425,19 @@ static int wm8776_probe(struct snd_soc_codec *codec) | |||
425 | return ret; | 425 | return ret; |
426 | } | 426 | } |
427 | 427 | ||
428 | static struct snd_soc_codec_driver soc_codec_dev_wm8776 = { | 428 | static const struct snd_soc_codec_driver soc_codec_dev_wm8776 = { |
429 | .probe = wm8776_probe, | 429 | .probe = wm8776_probe, |
430 | .set_bias_level = wm8776_set_bias_level, | 430 | .set_bias_level = wm8776_set_bias_level, |
431 | .suspend_bias_off = true, | 431 | .suspend_bias_off = true, |
432 | 432 | ||
433 | .controls = wm8776_snd_controls, | 433 | .component_driver = { |
434 | .num_controls = ARRAY_SIZE(wm8776_snd_controls), | 434 | .controls = wm8776_snd_controls, |
435 | .dapm_widgets = wm8776_dapm_widgets, | 435 | .num_controls = ARRAY_SIZE(wm8776_snd_controls), |
436 | .num_dapm_widgets = ARRAY_SIZE(wm8776_dapm_widgets), | 436 | .dapm_widgets = wm8776_dapm_widgets, |
437 | .dapm_routes = routes, | 437 | .num_dapm_widgets = ARRAY_SIZE(wm8776_dapm_widgets), |
438 | .num_dapm_routes = ARRAY_SIZE(routes), | 438 | .dapm_routes = routes, |
439 | .num_dapm_routes = ARRAY_SIZE(routes), | ||
440 | }, | ||
439 | }; | 441 | }; |
440 | 442 | ||
441 | static const struct of_device_id wm8776_of_match[] = { | 443 | static const struct of_device_id wm8776_of_match[] = { |
diff --git a/sound/soc/codecs/wm8782.c b/sound/soc/codecs/wm8782.c index fb55fd845d27..bcda21018505 100644 --- a/sound/soc/codecs/wm8782.c +++ b/sound/soc/codecs/wm8782.c | |||
@@ -50,11 +50,13 @@ static struct snd_soc_dai_driver wm8782_dai = { | |||
50 | }, | 50 | }, |
51 | }; | 51 | }; |
52 | 52 | ||
53 | static struct snd_soc_codec_driver soc_codec_dev_wm8782 = { | 53 | static const struct snd_soc_codec_driver soc_codec_dev_wm8782 = { |
54 | .dapm_widgets = wm8782_dapm_widgets, | 54 | .component_driver = { |
55 | .num_dapm_widgets = ARRAY_SIZE(wm8782_dapm_widgets), | 55 | .dapm_widgets = wm8782_dapm_widgets, |
56 | .dapm_routes = wm8782_dapm_routes, | 56 | .num_dapm_widgets = ARRAY_SIZE(wm8782_dapm_widgets), |
57 | .num_dapm_routes = ARRAY_SIZE(wm8782_dapm_routes), | 57 | .dapm_routes = wm8782_dapm_routes, |
58 | .num_dapm_routes = ARRAY_SIZE(wm8782_dapm_routes), | ||
59 | }, | ||
58 | }; | 60 | }; |
59 | 61 | ||
60 | static int wm8782_probe(struct platform_device *pdev) | 62 | static int wm8782_probe(struct platform_device *pdev) |
diff --git a/sound/soc/codecs/wm8804.c b/sound/soc/codecs/wm8804.c index 8d914702cae4..af95d648265b 100644 --- a/sound/soc/codecs/wm8804.c +++ b/sound/soc/codecs/wm8804.c | |||
@@ -545,10 +545,12 @@ static struct snd_soc_dai_driver wm8804_dai = { | |||
545 | static const struct snd_soc_codec_driver soc_codec_dev_wm8804 = { | 545 | static const struct snd_soc_codec_driver soc_codec_dev_wm8804 = { |
546 | .idle_bias_off = true, | 546 | .idle_bias_off = true, |
547 | 547 | ||
548 | .dapm_widgets = wm8804_dapm_widgets, | 548 | .component_driver = { |
549 | .num_dapm_widgets = ARRAY_SIZE(wm8804_dapm_widgets), | 549 | .dapm_widgets = wm8804_dapm_widgets, |
550 | .dapm_routes = wm8804_dapm_routes, | 550 | .num_dapm_widgets = ARRAY_SIZE(wm8804_dapm_widgets), |
551 | .num_dapm_routes = ARRAY_SIZE(wm8804_dapm_routes), | 551 | .dapm_routes = wm8804_dapm_routes, |
552 | .num_dapm_routes = ARRAY_SIZE(wm8804_dapm_routes), | ||
553 | }, | ||
552 | }; | 554 | }; |
553 | 555 | ||
554 | const struct regmap_config wm8804_regmap_config = { | 556 | const struct regmap_config wm8804_regmap_config = { |
diff --git a/sound/soc/codecs/wm8900.c b/sound/soc/codecs/wm8900.c index 5d8dca88d612..c77b49a29311 100644 --- a/sound/soc/codecs/wm8900.c +++ b/sound/soc/codecs/wm8900.c | |||
@@ -1208,18 +1208,20 @@ static int wm8900_probe(struct snd_soc_codec *codec) | |||
1208 | return 0; | 1208 | return 0; |
1209 | } | 1209 | } |
1210 | 1210 | ||
1211 | static struct snd_soc_codec_driver soc_codec_dev_wm8900 = { | 1211 | static const struct snd_soc_codec_driver soc_codec_dev_wm8900 = { |
1212 | .probe = wm8900_probe, | 1212 | .probe = wm8900_probe, |
1213 | .suspend = wm8900_suspend, | 1213 | .suspend = wm8900_suspend, |
1214 | .resume = wm8900_resume, | 1214 | .resume = wm8900_resume, |
1215 | .set_bias_level = wm8900_set_bias_level, | 1215 | .set_bias_level = wm8900_set_bias_level, |
1216 | 1216 | ||
1217 | .controls = wm8900_snd_controls, | 1217 | .component_driver = { |
1218 | .num_controls = ARRAY_SIZE(wm8900_snd_controls), | 1218 | .controls = wm8900_snd_controls, |
1219 | .dapm_widgets = wm8900_dapm_widgets, | 1219 | .num_controls = ARRAY_SIZE(wm8900_snd_controls), |
1220 | .num_dapm_widgets = ARRAY_SIZE(wm8900_dapm_widgets), | 1220 | .dapm_widgets = wm8900_dapm_widgets, |
1221 | .dapm_routes = wm8900_dapm_routes, | 1221 | .num_dapm_widgets = ARRAY_SIZE(wm8900_dapm_widgets), |
1222 | .num_dapm_routes = ARRAY_SIZE(wm8900_dapm_routes), | 1222 | .dapm_routes = wm8900_dapm_routes, |
1223 | .num_dapm_routes = ARRAY_SIZE(wm8900_dapm_routes), | ||
1224 | }, | ||
1223 | }; | 1225 | }; |
1224 | 1226 | ||
1225 | static const struct regmap_config wm8900_regmap = { | 1227 | static const struct regmap_config wm8900_regmap = { |
diff --git a/sound/soc/codecs/wm8903.c b/sound/soc/codecs/wm8903.c index a26ca490cf31..6e887c2c42b1 100644 --- a/sound/soc/codecs/wm8903.c +++ b/sound/soc/codecs/wm8903.c | |||
@@ -1830,7 +1830,7 @@ static void wm8903_gpio_set(struct gpio_chip *chip, unsigned offset, int value) | |||
1830 | !!value << WM8903_GP1_LVL_SHIFT); | 1830 | !!value << WM8903_GP1_LVL_SHIFT); |
1831 | } | 1831 | } |
1832 | 1832 | ||
1833 | static struct gpio_chip wm8903_template_chip = { | 1833 | static const struct gpio_chip wm8903_template_chip = { |
1834 | .label = "wm8903", | 1834 | .label = "wm8903", |
1835 | .owner = THIS_MODULE, | 1835 | .owner = THIS_MODULE, |
1836 | .request = wm8903_gpio_request, | 1836 | .request = wm8903_gpio_request, |
@@ -1874,18 +1874,20 @@ static void wm8903_free_gpio(struct wm8903_priv *wm8903) | |||
1874 | } | 1874 | } |
1875 | #endif | 1875 | #endif |
1876 | 1876 | ||
1877 | static struct snd_soc_codec_driver soc_codec_dev_wm8903 = { | 1877 | static const struct snd_soc_codec_driver soc_codec_dev_wm8903 = { |
1878 | .resume = wm8903_resume, | 1878 | .resume = wm8903_resume, |
1879 | .set_bias_level = wm8903_set_bias_level, | 1879 | .set_bias_level = wm8903_set_bias_level, |
1880 | .seq_notifier = wm8903_seq_notifier, | 1880 | .seq_notifier = wm8903_seq_notifier, |
1881 | .suspend_bias_off = true, | 1881 | .suspend_bias_off = true, |
1882 | 1882 | ||
1883 | .controls = wm8903_snd_controls, | 1883 | .component_driver = { |
1884 | .num_controls = ARRAY_SIZE(wm8903_snd_controls), | 1884 | .controls = wm8903_snd_controls, |
1885 | .dapm_widgets = wm8903_dapm_widgets, | 1885 | .num_controls = ARRAY_SIZE(wm8903_snd_controls), |
1886 | .num_dapm_widgets = ARRAY_SIZE(wm8903_dapm_widgets), | 1886 | .dapm_widgets = wm8903_dapm_widgets, |
1887 | .dapm_routes = wm8903_intercon, | 1887 | .num_dapm_widgets = ARRAY_SIZE(wm8903_dapm_widgets), |
1888 | .num_dapm_routes = ARRAY_SIZE(wm8903_intercon), | 1888 | .dapm_routes = wm8903_intercon, |
1889 | .num_dapm_routes = ARRAY_SIZE(wm8903_intercon), | ||
1890 | }, | ||
1889 | }; | 1891 | }; |
1890 | 1892 | ||
1891 | static const struct regmap_config wm8903_regmap = { | 1893 | static const struct regmap_config wm8903_regmap = { |
diff --git a/sound/soc/codecs/wm8904.c b/sound/soc/codecs/wm8904.c index edd7a7709194..4fd350e8420d 100644 --- a/sound/soc/codecs/wm8904.c +++ b/sound/soc/codecs/wm8904.c | |||
@@ -2086,7 +2086,7 @@ static int wm8904_remove(struct snd_soc_codec *codec) | |||
2086 | return 0; | 2086 | return 0; |
2087 | } | 2087 | } |
2088 | 2088 | ||
2089 | static struct snd_soc_codec_driver soc_codec_dev_wm8904 = { | 2089 | static const struct snd_soc_codec_driver soc_codec_dev_wm8904 = { |
2090 | .probe = wm8904_probe, | 2090 | .probe = wm8904_probe, |
2091 | .remove = wm8904_remove, | 2091 | .remove = wm8904_remove, |
2092 | .set_bias_level = wm8904_set_bias_level, | 2092 | .set_bias_level = wm8904_set_bias_level, |
diff --git a/sound/soc/codecs/wm8940.c b/sound/soc/codecs/wm8940.c index 1c600819f768..b5935625feeb 100644 --- a/sound/soc/codecs/wm8940.c +++ b/sound/soc/codecs/wm8940.c | |||
@@ -723,17 +723,19 @@ static int wm8940_probe(struct snd_soc_codec *codec) | |||
723 | return ret; | 723 | return ret; |
724 | } | 724 | } |
725 | 725 | ||
726 | static struct snd_soc_codec_driver soc_codec_dev_wm8940 = { | 726 | static const struct snd_soc_codec_driver soc_codec_dev_wm8940 = { |
727 | .probe = wm8940_probe, | 727 | .probe = wm8940_probe, |
728 | .set_bias_level = wm8940_set_bias_level, | 728 | .set_bias_level = wm8940_set_bias_level, |
729 | .suspend_bias_off = true, | 729 | .suspend_bias_off = true, |
730 | 730 | ||
731 | .controls = wm8940_snd_controls, | 731 | .component_driver = { |
732 | .num_controls = ARRAY_SIZE(wm8940_snd_controls), | 732 | .controls = wm8940_snd_controls, |
733 | .dapm_widgets = wm8940_dapm_widgets, | 733 | .num_controls = ARRAY_SIZE(wm8940_snd_controls), |
734 | .num_dapm_widgets = ARRAY_SIZE(wm8940_dapm_widgets), | 734 | .dapm_widgets = wm8940_dapm_widgets, |
735 | .dapm_routes = wm8940_dapm_routes, | 735 | .num_dapm_widgets = ARRAY_SIZE(wm8940_dapm_widgets), |
736 | .num_dapm_routes = ARRAY_SIZE(wm8940_dapm_routes), | 736 | .dapm_routes = wm8940_dapm_routes, |
737 | .num_dapm_routes = ARRAY_SIZE(wm8940_dapm_routes), | ||
738 | }, | ||
737 | }; | 739 | }; |
738 | 740 | ||
739 | static const struct regmap_config wm8940_regmap = { | 741 | static const struct regmap_config wm8940_regmap = { |
diff --git a/sound/soc/codecs/wm8955.c b/sound/soc/codecs/wm8955.c index 9db00d53abe7..1edc7b1df31d 100644 --- a/sound/soc/codecs/wm8955.c +++ b/sound/soc/codecs/wm8955.c | |||
@@ -940,17 +940,19 @@ err_enable: | |||
940 | return ret; | 940 | return ret; |
941 | } | 941 | } |
942 | 942 | ||
943 | static struct snd_soc_codec_driver soc_codec_dev_wm8955 = { | 943 | static const struct snd_soc_codec_driver soc_codec_dev_wm8955 = { |
944 | .probe = wm8955_probe, | 944 | .probe = wm8955_probe, |
945 | .set_bias_level = wm8955_set_bias_level, | 945 | .set_bias_level = wm8955_set_bias_level, |
946 | .suspend_bias_off = true, | 946 | .suspend_bias_off = true, |
947 | 947 | ||
948 | .controls = wm8955_snd_controls, | 948 | .component_driver = { |
949 | .num_controls = ARRAY_SIZE(wm8955_snd_controls), | 949 | .controls = wm8955_snd_controls, |
950 | .dapm_widgets = wm8955_dapm_widgets, | 950 | .num_controls = ARRAY_SIZE(wm8955_snd_controls), |
951 | .num_dapm_widgets = ARRAY_SIZE(wm8955_dapm_widgets), | 951 | .dapm_widgets = wm8955_dapm_widgets, |
952 | .dapm_routes = wm8955_dapm_routes, | 952 | .num_dapm_widgets = ARRAY_SIZE(wm8955_dapm_widgets), |
953 | .num_dapm_routes = ARRAY_SIZE(wm8955_dapm_routes), | 953 | .dapm_routes = wm8955_dapm_routes, |
954 | .num_dapm_routes = ARRAY_SIZE(wm8955_dapm_routes), | ||
955 | }, | ||
954 | }; | 956 | }; |
955 | 957 | ||
956 | static const struct regmap_config wm8955_regmap = { | 958 | static const struct regmap_config wm8955_regmap = { |
diff --git a/sound/soc/codecs/wm8960.c b/sound/soc/codecs/wm8960.c index d7f444f87460..3bf081a7e450 100644 --- a/sound/soc/codecs/wm8960.c +++ b/sound/soc/codecs/wm8960.c | |||
@@ -226,11 +226,10 @@ static const DECLARE_TLV_DB_SCALE(dac_tlv, -12750, 50, 1); | |||
226 | static const DECLARE_TLV_DB_SCALE(bypass_tlv, -2100, 300, 0); | 226 | static const DECLARE_TLV_DB_SCALE(bypass_tlv, -2100, 300, 0); |
227 | static const DECLARE_TLV_DB_SCALE(out_tlv, -12100, 100, 1); | 227 | static const DECLARE_TLV_DB_SCALE(out_tlv, -12100, 100, 1); |
228 | static const DECLARE_TLV_DB_SCALE(lineinboost_tlv, -1500, 300, 1); | 228 | static const DECLARE_TLV_DB_SCALE(lineinboost_tlv, -1500, 300, 1); |
229 | static const unsigned int micboost_tlv[] = { | 229 | static const SNDRV_CTL_TLVD_DECLARE_DB_RANGE(micboost_tlv, |
230 | TLV_DB_RANGE_HEAD(2), | ||
231 | 0, 1, TLV_DB_SCALE_ITEM(0, 1300, 0), | 230 | 0, 1, TLV_DB_SCALE_ITEM(0, 1300, 0), |
232 | 2, 3, TLV_DB_SCALE_ITEM(2000, 900, 0), | 231 | 2, 3, TLV_DB_SCALE_ITEM(2000, 900, 0), |
233 | }; | 232 | ); |
234 | 233 | ||
235 | static const struct snd_kcontrol_new wm8960_snd_controls[] = { | 234 | static const struct snd_kcontrol_new wm8960_snd_controls[] = { |
236 | SOC_DOUBLE_R_TLV("Capture Volume", WM8960_LINVOL, WM8960_RINVOL, | 235 | SOC_DOUBLE_R_TLV("Capture Volume", WM8960_LINVOL, WM8960_RINVOL, |
@@ -1264,7 +1263,7 @@ static int wm8960_probe(struct snd_soc_codec *codec) | |||
1264 | return 0; | 1263 | return 0; |
1265 | } | 1264 | } |
1266 | 1265 | ||
1267 | static struct snd_soc_codec_driver soc_codec_dev_wm8960 = { | 1266 | static const struct snd_soc_codec_driver soc_codec_dev_wm8960 = { |
1268 | .probe = wm8960_probe, | 1267 | .probe = wm8960_probe, |
1269 | .set_bias_level = wm8960_set_bias_level, | 1268 | .set_bias_level = wm8960_set_bias_level, |
1270 | .suspend_bias_off = true, | 1269 | .suspend_bias_off = true, |
diff --git a/sound/soc/codecs/wm8961.c b/sound/soc/codecs/wm8961.c index e30446a04740..e23ceac76015 100644 --- a/sound/soc/codecs/wm8961.c +++ b/sound/soc/codecs/wm8961.c | |||
@@ -882,18 +882,20 @@ static int wm8961_resume(struct snd_soc_codec *codec) | |||
882 | #define wm8961_resume NULL | 882 | #define wm8961_resume NULL |
883 | #endif | 883 | #endif |
884 | 884 | ||
885 | static struct snd_soc_codec_driver soc_codec_dev_wm8961 = { | 885 | static const struct snd_soc_codec_driver soc_codec_dev_wm8961 = { |
886 | .probe = wm8961_probe, | 886 | .probe = wm8961_probe, |
887 | .resume = wm8961_resume, | 887 | .resume = wm8961_resume, |
888 | .set_bias_level = wm8961_set_bias_level, | 888 | .set_bias_level = wm8961_set_bias_level, |
889 | .suspend_bias_off = true, | 889 | .suspend_bias_off = true, |
890 | 890 | ||
891 | .controls = wm8961_snd_controls, | 891 | .component_driver = { |
892 | .num_controls = ARRAY_SIZE(wm8961_snd_controls), | 892 | .controls = wm8961_snd_controls, |
893 | .dapm_widgets = wm8961_dapm_widgets, | 893 | .num_controls = ARRAY_SIZE(wm8961_snd_controls), |
894 | .num_dapm_widgets = ARRAY_SIZE(wm8961_dapm_widgets), | 894 | .dapm_widgets = wm8961_dapm_widgets, |
895 | .dapm_routes = audio_paths, | 895 | .num_dapm_widgets = ARRAY_SIZE(wm8961_dapm_widgets), |
896 | .num_dapm_routes = ARRAY_SIZE(audio_paths), | 896 | .dapm_routes = audio_paths, |
897 | .num_dapm_routes = ARRAY_SIZE(audio_paths), | ||
898 | }, | ||
897 | }; | 899 | }; |
898 | 900 | ||
899 | static const struct regmap_config wm8961_regmap = { | 901 | static const struct regmap_config wm8961_regmap = { |
diff --git a/sound/soc/codecs/wm8962.c b/sound/soc/codecs/wm8962.c index f3109da24769..fd2731d171dd 100644 --- a/sound/soc/codecs/wm8962.c +++ b/sound/soc/codecs/wm8962.c | |||
@@ -3357,7 +3357,7 @@ static int wm8962_gpio_direction_out(struct gpio_chip *chip, | |||
3357 | return 0; | 3357 | return 0; |
3358 | } | 3358 | } |
3359 | 3359 | ||
3360 | static struct gpio_chip wm8962_template_chip = { | 3360 | static const struct gpio_chip wm8962_template_chip = { |
3361 | .label = "wm8962", | 3361 | .label = "wm8962", |
3362 | .owner = THIS_MODULE, | 3362 | .owner = THIS_MODULE, |
3363 | .request = wm8962_gpio_request, | 3363 | .request = wm8962_gpio_request, |
@@ -3479,7 +3479,7 @@ static int wm8962_remove(struct snd_soc_codec *codec) | |||
3479 | return 0; | 3479 | return 0; |
3480 | } | 3480 | } |
3481 | 3481 | ||
3482 | static struct snd_soc_codec_driver soc_codec_dev_wm8962 = { | 3482 | static const struct snd_soc_codec_driver soc_codec_dev_wm8962 = { |
3483 | .probe = wm8962_probe, | 3483 | .probe = wm8962_probe, |
3484 | .remove = wm8962_remove, | 3484 | .remove = wm8962_remove, |
3485 | .set_bias_level = wm8962_set_bias_level, | 3485 | .set_bias_level = wm8962_set_bias_level, |
@@ -3713,7 +3713,7 @@ static int wm8962_i2c_probe(struct i2c_client *i2c, | |||
3713 | ARRAY_SIZE(wm8962_dc_measure)); | 3713 | ARRAY_SIZE(wm8962_dc_measure)); |
3714 | if (ret != 0) | 3714 | if (ret != 0) |
3715 | dev_err(&i2c->dev, | 3715 | dev_err(&i2c->dev, |
3716 | "Failed to configure for DC mesurement: %d\n", | 3716 | "Failed to configure for DC measurement: %d\n", |
3717 | ret); | 3717 | ret); |
3718 | } | 3718 | } |
3719 | 3719 | ||
diff --git a/sound/soc/codecs/wm8971.c b/sound/soc/codecs/wm8971.c index 2cdde32c43c6..887d31cf3945 100644 --- a/sound/soc/codecs/wm8971.c +++ b/sound/soc/codecs/wm8971.c | |||
@@ -649,17 +649,19 @@ static int wm8971_probe(struct snd_soc_codec *codec) | |||
649 | return 0; | 649 | return 0; |
650 | } | 650 | } |
651 | 651 | ||
652 | static struct snd_soc_codec_driver soc_codec_dev_wm8971 = { | 652 | static const struct snd_soc_codec_driver soc_codec_dev_wm8971 = { |
653 | .probe = wm8971_probe, | 653 | .probe = wm8971_probe, |
654 | .set_bias_level = wm8971_set_bias_level, | 654 | .set_bias_level = wm8971_set_bias_level, |
655 | .suspend_bias_off = true, | 655 | .suspend_bias_off = true, |
656 | 656 | ||
657 | .controls = wm8971_snd_controls, | 657 | .component_driver = { |
658 | .num_controls = ARRAY_SIZE(wm8971_snd_controls), | 658 | .controls = wm8971_snd_controls, |
659 | .dapm_widgets = wm8971_dapm_widgets, | 659 | .num_controls = ARRAY_SIZE(wm8971_snd_controls), |
660 | .num_dapm_widgets = ARRAY_SIZE(wm8971_dapm_widgets), | 660 | .dapm_widgets = wm8971_dapm_widgets, |
661 | .dapm_routes = wm8971_dapm_routes, | 661 | .num_dapm_widgets = ARRAY_SIZE(wm8971_dapm_widgets), |
662 | .num_dapm_routes = ARRAY_SIZE(wm8971_dapm_routes), | 662 | .dapm_routes = wm8971_dapm_routes, |
663 | .num_dapm_routes = ARRAY_SIZE(wm8971_dapm_routes), | ||
664 | }, | ||
663 | }; | 665 | }; |
664 | 666 | ||
665 | static const struct regmap_config wm8971_regmap = { | 667 | static const struct regmap_config wm8971_regmap = { |
diff --git a/sound/soc/codecs/wm8974.c b/sound/soc/codecs/wm8974.c index dc8c3b1ebb6f..d414ddd6e197 100644 --- a/sound/soc/codecs/wm8974.c +++ b/sound/soc/codecs/wm8974.c | |||
@@ -676,17 +676,19 @@ static int wm8974_probe(struct snd_soc_codec *codec) | |||
676 | return 0; | 676 | return 0; |
677 | } | 677 | } |
678 | 678 | ||
679 | static struct snd_soc_codec_driver soc_codec_dev_wm8974 = { | 679 | static const struct snd_soc_codec_driver soc_codec_dev_wm8974 = { |
680 | .probe = wm8974_probe, | 680 | .probe = wm8974_probe, |
681 | .set_bias_level = wm8974_set_bias_level, | 681 | .set_bias_level = wm8974_set_bias_level, |
682 | .suspend_bias_off = true, | 682 | .suspend_bias_off = true, |
683 | 683 | ||
684 | .controls = wm8974_snd_controls, | 684 | .component_driver = { |
685 | .num_controls = ARRAY_SIZE(wm8974_snd_controls), | 685 | .controls = wm8974_snd_controls, |
686 | .dapm_widgets = wm8974_dapm_widgets, | 686 | .num_controls = ARRAY_SIZE(wm8974_snd_controls), |
687 | .num_dapm_widgets = ARRAY_SIZE(wm8974_dapm_widgets), | 687 | .dapm_widgets = wm8974_dapm_widgets, |
688 | .dapm_routes = wm8974_dapm_routes, | 688 | .num_dapm_widgets = ARRAY_SIZE(wm8974_dapm_widgets), |
689 | .num_dapm_routes = ARRAY_SIZE(wm8974_dapm_routes), | 689 | .dapm_routes = wm8974_dapm_routes, |
690 | .num_dapm_routes = ARRAY_SIZE(wm8974_dapm_routes), | ||
691 | }, | ||
690 | }; | 692 | }; |
691 | 693 | ||
692 | static int wm8974_i2c_probe(struct i2c_client *i2c, | 694 | static int wm8974_i2c_probe(struct i2c_client *i2c, |
diff --git a/sound/soc/codecs/wm8978.c b/sound/soc/codecs/wm8978.c index d36d6001fbb7..90b2d418ef60 100644 --- a/sound/soc/codecs/wm8978.c +++ b/sound/soc/codecs/wm8978.c | |||
@@ -993,18 +993,20 @@ static int wm8978_probe(struct snd_soc_codec *codec) | |||
993 | return 0; | 993 | return 0; |
994 | } | 994 | } |
995 | 995 | ||
996 | static struct snd_soc_codec_driver soc_codec_dev_wm8978 = { | 996 | static const struct snd_soc_codec_driver soc_codec_dev_wm8978 = { |
997 | .probe = wm8978_probe, | 997 | .probe = wm8978_probe, |
998 | .suspend = wm8978_suspend, | 998 | .suspend = wm8978_suspend, |
999 | .resume = wm8978_resume, | 999 | .resume = wm8978_resume, |
1000 | .set_bias_level = wm8978_set_bias_level, | 1000 | .set_bias_level = wm8978_set_bias_level, |
1001 | 1001 | ||
1002 | .controls = wm8978_snd_controls, | 1002 | .component_driver = { |
1003 | .num_controls = ARRAY_SIZE(wm8978_snd_controls), | 1003 | .controls = wm8978_snd_controls, |
1004 | .dapm_widgets = wm8978_dapm_widgets, | 1004 | .num_controls = ARRAY_SIZE(wm8978_snd_controls), |
1005 | .num_dapm_widgets = ARRAY_SIZE(wm8978_dapm_widgets), | 1005 | .dapm_widgets = wm8978_dapm_widgets, |
1006 | .dapm_routes = wm8978_dapm_routes, | 1006 | .num_dapm_widgets = ARRAY_SIZE(wm8978_dapm_widgets), |
1007 | .num_dapm_routes = ARRAY_SIZE(wm8978_dapm_routes), | 1007 | .dapm_routes = wm8978_dapm_routes, |
1008 | .num_dapm_routes = ARRAY_SIZE(wm8978_dapm_routes), | ||
1009 | }, | ||
1008 | }; | 1010 | }; |
1009 | 1011 | ||
1010 | static const struct regmap_config wm8978_regmap_config = { | 1012 | static const struct regmap_config wm8978_regmap_config = { |
diff --git a/sound/soc/codecs/wm8983.c b/sound/soc/codecs/wm8983.c index 0c002a5712cb..bfdbe72ee687 100644 --- a/sound/soc/codecs/wm8983.c +++ b/sound/soc/codecs/wm8983.c | |||
@@ -976,16 +976,18 @@ static struct snd_soc_dai_driver wm8983_dai = { | |||
976 | .symmetric_rates = 1 | 976 | .symmetric_rates = 1 |
977 | }; | 977 | }; |
978 | 978 | ||
979 | static struct snd_soc_codec_driver soc_codec_dev_wm8983 = { | 979 | static const struct snd_soc_codec_driver soc_codec_dev_wm8983 = { |
980 | .probe = wm8983_probe, | 980 | .probe = wm8983_probe, |
981 | .set_bias_level = wm8983_set_bias_level, | 981 | .set_bias_level = wm8983_set_bias_level, |
982 | .suspend_bias_off = true, | 982 | .suspend_bias_off = true, |
983 | .controls = wm8983_snd_controls, | 983 | .component_driver = { |
984 | .num_controls = ARRAY_SIZE(wm8983_snd_controls), | 984 | .controls = wm8983_snd_controls, |
985 | .dapm_widgets = wm8983_dapm_widgets, | 985 | .num_controls = ARRAY_SIZE(wm8983_snd_controls), |
986 | .num_dapm_widgets = ARRAY_SIZE(wm8983_dapm_widgets), | 986 | .dapm_widgets = wm8983_dapm_widgets, |
987 | .dapm_routes = wm8983_audio_map, | 987 | .num_dapm_widgets = ARRAY_SIZE(wm8983_dapm_widgets), |
988 | .num_dapm_routes = ARRAY_SIZE(wm8983_audio_map), | 988 | .dapm_routes = wm8983_audio_map, |
989 | .num_dapm_routes = ARRAY_SIZE(wm8983_audio_map), | ||
990 | }, | ||
989 | }; | 991 | }; |
990 | 992 | ||
991 | static const struct regmap_config wm8983_regmap = { | 993 | static const struct regmap_config wm8983_regmap = { |
diff --git a/sound/soc/codecs/wm8985.c b/sound/soc/codecs/wm8985.c index 7347abff4b2c..05344f974ff3 100644 --- a/sound/soc/codecs/wm8985.c +++ b/sound/soc/codecs/wm8985.c | |||
@@ -1105,17 +1105,19 @@ static struct snd_soc_dai_driver wm8985_dai = { | |||
1105 | .symmetric_rates = 1 | 1105 | .symmetric_rates = 1 |
1106 | }; | 1106 | }; |
1107 | 1107 | ||
1108 | static struct snd_soc_codec_driver soc_codec_dev_wm8985 = { | 1108 | static const struct snd_soc_codec_driver soc_codec_dev_wm8985 = { |
1109 | .probe = wm8985_probe, | 1109 | .probe = wm8985_probe, |
1110 | .set_bias_level = wm8985_set_bias_level, | 1110 | .set_bias_level = wm8985_set_bias_level, |
1111 | .suspend_bias_off = true, | 1111 | .suspend_bias_off = true, |
1112 | 1112 | ||
1113 | .controls = wm8985_common_snd_controls, | 1113 | .component_driver = { |
1114 | .num_controls = ARRAY_SIZE(wm8985_common_snd_controls), | 1114 | .controls = wm8985_common_snd_controls, |
1115 | .dapm_widgets = wm8985_common_dapm_widgets, | 1115 | .num_controls = ARRAY_SIZE(wm8985_common_snd_controls), |
1116 | .num_dapm_widgets = ARRAY_SIZE(wm8985_common_dapm_widgets), | 1116 | .dapm_widgets = wm8985_common_dapm_widgets, |
1117 | .dapm_routes = wm8985_common_dapm_routes, | 1117 | .num_dapm_widgets = ARRAY_SIZE(wm8985_common_dapm_widgets), |
1118 | .num_dapm_routes = ARRAY_SIZE(wm8985_common_dapm_routes), | 1118 | .dapm_routes = wm8985_common_dapm_routes, |
1119 | .num_dapm_routes = ARRAY_SIZE(wm8985_common_dapm_routes), | ||
1120 | }, | ||
1119 | }; | 1121 | }; |
1120 | 1122 | ||
1121 | static const struct regmap_config wm8985_regmap = { | 1123 | static const struct regmap_config wm8985_regmap = { |
diff --git a/sound/soc/codecs/wm8988.c b/sound/soc/codecs/wm8988.c index 895721a256f0..b0d0219532f2 100644 --- a/sound/soc/codecs/wm8988.c +++ b/sound/soc/codecs/wm8988.c | |||
@@ -817,12 +817,14 @@ static const struct snd_soc_codec_driver soc_codec_dev_wm8988 = { | |||
817 | .set_bias_level = wm8988_set_bias_level, | 817 | .set_bias_level = wm8988_set_bias_level, |
818 | .suspend_bias_off = true, | 818 | .suspend_bias_off = true, |
819 | 819 | ||
820 | .controls = wm8988_snd_controls, | 820 | .component_driver = { |
821 | .num_controls = ARRAY_SIZE(wm8988_snd_controls), | 821 | .controls = wm8988_snd_controls, |
822 | .dapm_widgets = wm8988_dapm_widgets, | 822 | .num_controls = ARRAY_SIZE(wm8988_snd_controls), |
823 | .num_dapm_widgets = ARRAY_SIZE(wm8988_dapm_widgets), | 823 | .dapm_widgets = wm8988_dapm_widgets, |
824 | .dapm_routes = wm8988_dapm_routes, | 824 | .num_dapm_widgets = ARRAY_SIZE(wm8988_dapm_widgets), |
825 | .num_dapm_routes = ARRAY_SIZE(wm8988_dapm_routes), | 825 | .dapm_routes = wm8988_dapm_routes, |
826 | .num_dapm_routes = ARRAY_SIZE(wm8988_dapm_routes), | ||
827 | }, | ||
826 | }; | 828 | }; |
827 | 829 | ||
828 | static const struct regmap_config wm8988_regmap = { | 830 | static const struct regmap_config wm8988_regmap = { |
diff --git a/sound/soc/codecs/wm8990.c b/sound/soc/codecs/wm8990.c index 23ecd30d8bca..a8945001e696 100644 --- a/sound/soc/codecs/wm8990.c +++ b/sound/soc/codecs/wm8990.c | |||
@@ -1294,17 +1294,19 @@ static int wm8990_probe(struct snd_soc_codec *codec) | |||
1294 | return 0; | 1294 | return 0; |
1295 | } | 1295 | } |
1296 | 1296 | ||
1297 | static struct snd_soc_codec_driver soc_codec_dev_wm8990 = { | 1297 | static const struct snd_soc_codec_driver soc_codec_dev_wm8990 = { |
1298 | .probe = wm8990_probe, | 1298 | .probe = wm8990_probe, |
1299 | .set_bias_level = wm8990_set_bias_level, | 1299 | .set_bias_level = wm8990_set_bias_level, |
1300 | .suspend_bias_off = true, | 1300 | .suspend_bias_off = true, |
1301 | 1301 | ||
1302 | .controls = wm8990_snd_controls, | 1302 | .component_driver = { |
1303 | .num_controls = ARRAY_SIZE(wm8990_snd_controls), | 1303 | .controls = wm8990_snd_controls, |
1304 | .dapm_widgets = wm8990_dapm_widgets, | 1304 | .num_controls = ARRAY_SIZE(wm8990_snd_controls), |
1305 | .num_dapm_widgets = ARRAY_SIZE(wm8990_dapm_widgets), | 1305 | .dapm_widgets = wm8990_dapm_widgets, |
1306 | .dapm_routes = wm8990_dapm_routes, | 1306 | .num_dapm_widgets = ARRAY_SIZE(wm8990_dapm_widgets), |
1307 | .num_dapm_routes = ARRAY_SIZE(wm8990_dapm_routes), | 1307 | .dapm_routes = wm8990_dapm_routes, |
1308 | .num_dapm_routes = ARRAY_SIZE(wm8990_dapm_routes), | ||
1309 | }, | ||
1308 | }; | 1310 | }; |
1309 | 1311 | ||
1310 | static const struct regmap_config wm8990_regmap = { | 1312 | static const struct regmap_config wm8990_regmap = { |
diff --git a/sound/soc/codecs/wm8991.c b/sound/soc/codecs/wm8991.c index c9ee0ac6a654..802c0694e5c3 100644 --- a/sound/soc/codecs/wm8991.c +++ b/sound/soc/codecs/wm8991.c | |||
@@ -111,14 +111,24 @@ static bool wm8991_volatile(struct device *dev, unsigned int reg) | |||
111 | } | 111 | } |
112 | } | 112 | } |
113 | 113 | ||
114 | static const DECLARE_TLV_DB_LINEAR(rec_mix_tlv, -1500, 600); | 114 | static const SNDRV_CTL_TLVD_DECLARE_DB_SCALE(in_pga_tlv, -1650, 150, 0); |
115 | static const DECLARE_TLV_DB_LINEAR(in_pga_tlv, -1650, 3000); | 115 | static const SNDRV_CTL_TLVD_DECLARE_DB_SCALE(out_mix_tlv, -2100, 300, 0); |
116 | static const DECLARE_TLV_DB_LINEAR(out_mix_tlv, 0, -2100); | 116 | static const SNDRV_CTL_TLVD_DECLARE_DB_RANGE(out_pga_tlv, |
117 | static const DECLARE_TLV_DB_LINEAR(out_pga_tlv, -7300, 600); | 117 | 0x00, 0x2f, SNDRV_CTL_TLVD_DB_SCALE_ITEM(SNDRV_CTL_TLVD_DB_GAIN_MUTE, 0, 1), |
118 | static const DECLARE_TLV_DB_LINEAR(out_omix_tlv, -600, 0); | 118 | 0x30, 0x7f, SNDRV_CTL_TLVD_DB_SCALE_ITEM(-7300, 100, 0), |
119 | static const DECLARE_TLV_DB_LINEAR(out_dac_tlv, -7163, 0); | 119 | ); |
120 | static const DECLARE_TLV_DB_LINEAR(in_adc_tlv, -7163, 1763); | 120 | static const SNDRV_CTL_TLVD_DECLARE_DB_RANGE(out_dac_tlv, |
121 | static const DECLARE_TLV_DB_LINEAR(out_sidetone_tlv, -3600, 0); | 121 | 0x00, 0xbf, SNDRV_CTL_TLVD_DB_SCALE_ITEM(-71625, 375, 1), |
122 | 0xc0, 0xff, SNDRV_CTL_TLVD_DB_SCALE_ITEM(0, 0, 0), | ||
123 | ); | ||
124 | static const SNDRV_CTL_TLVD_DECLARE_DB_RANGE(in_adc_tlv, | ||
125 | 0x00, 0xef, SNDRV_CTL_TLVD_DB_SCALE_ITEM(-71625, 375, 1), | ||
126 | 0xf0, 0xff, SNDRV_CTL_TLVD_DB_SCALE_ITEM(17625, 0, 0), | ||
127 | ); | ||
128 | static const SNDRV_CTL_TLVD_DECLARE_DB_RANGE(out_sidetone_tlv, | ||
129 | 0x00, 0x0c, SNDRV_CTL_TLVD_DB_SCALE_ITEM(-3600, 300, 0), | ||
130 | 0x0d, 0x0f, SNDRV_CTL_TLVD_DB_SCALE_ITEM(0, 0, 0), | ||
131 | ); | ||
122 | 132 | ||
123 | static int wm899x_outpga_put_volsw_vu(struct snd_kcontrol *kcontrol, | 133 | static int wm899x_outpga_put_volsw_vu(struct snd_kcontrol *kcontrol, |
124 | struct snd_ctl_elem_value *ucontrol) | 134 | struct snd_ctl_elem_value *ucontrol) |
@@ -398,7 +408,7 @@ static int outmixer_event(struct snd_soc_dapm_widget *w, | |||
398 | } | 408 | } |
399 | 409 | ||
400 | /* INMIX dB values */ | 410 | /* INMIX dB values */ |
401 | static const DECLARE_TLV_DB_LINEAR(in_mix_tlv, -1200, 600); | 411 | static const SNDRV_CTL_TLVD_DECLARE_DB_SCALE(in_mix_tlv, -1200, 300, 1); |
402 | 412 | ||
403 | /* Left In PGA Connections */ | 413 | /* Left In PGA Connections */ |
404 | static const struct snd_kcontrol_new wm8991_dapm_lin12_pga_controls[] = { | 414 | static const struct snd_kcontrol_new wm8991_dapm_lin12_pga_controls[] = { |
@@ -1232,16 +1242,18 @@ static struct snd_soc_dai_driver wm8991_dai = { | |||
1232 | .ops = &wm8991_ops | 1242 | .ops = &wm8991_ops |
1233 | }; | 1243 | }; |
1234 | 1244 | ||
1235 | static struct snd_soc_codec_driver soc_codec_dev_wm8991 = { | 1245 | static const struct snd_soc_codec_driver soc_codec_dev_wm8991 = { |
1236 | .set_bias_level = wm8991_set_bias_level, | 1246 | .set_bias_level = wm8991_set_bias_level, |
1237 | .suspend_bias_off = true, | 1247 | .suspend_bias_off = true, |
1238 | 1248 | ||
1239 | .controls = wm8991_snd_controls, | 1249 | .component_driver = { |
1240 | .num_controls = ARRAY_SIZE(wm8991_snd_controls), | 1250 | .controls = wm8991_snd_controls, |
1241 | .dapm_widgets = wm8991_dapm_widgets, | 1251 | .num_controls = ARRAY_SIZE(wm8991_snd_controls), |
1242 | .num_dapm_widgets = ARRAY_SIZE(wm8991_dapm_widgets), | 1252 | .dapm_widgets = wm8991_dapm_widgets, |
1243 | .dapm_routes = wm8991_dapm_routes, | 1253 | .num_dapm_widgets = ARRAY_SIZE(wm8991_dapm_widgets), |
1244 | .num_dapm_routes = ARRAY_SIZE(wm8991_dapm_routes), | 1254 | .dapm_routes = wm8991_dapm_routes, |
1255 | .num_dapm_routes = ARRAY_SIZE(wm8991_dapm_routes), | ||
1256 | }, | ||
1245 | }; | 1257 | }; |
1246 | 1258 | ||
1247 | static const struct regmap_config wm8991_regmap = { | 1259 | static const struct regmap_config wm8991_regmap = { |
diff --git a/sound/soc/codecs/wm8993.c b/sound/soc/codecs/wm8993.c index 8668c4c391b0..195f7bf6eb22 100644 --- a/sound/soc/codecs/wm8993.c +++ b/sound/soc/codecs/wm8993.c | |||
@@ -1613,7 +1613,7 @@ static const struct regmap_config wm8993_regmap = { | |||
1613 | .num_reg_defaults = ARRAY_SIZE(wm8993_reg_defaults), | 1613 | .num_reg_defaults = ARRAY_SIZE(wm8993_reg_defaults), |
1614 | }; | 1614 | }; |
1615 | 1615 | ||
1616 | static struct snd_soc_codec_driver soc_codec_dev_wm8993 = { | 1616 | static const struct snd_soc_codec_driver soc_codec_dev_wm8993 = { |
1617 | .probe = wm8993_probe, | 1617 | .probe = wm8993_probe, |
1618 | .suspend = wm8993_suspend, | 1618 | .suspend = wm8993_suspend, |
1619 | .resume = wm8993_resume, | 1619 | .resume = wm8993_resume, |
diff --git a/sound/soc/codecs/wm8994.c b/sound/soc/codecs/wm8994.c index a18aecb49935..3896523b71e9 100644 --- a/sound/soc/codecs/wm8994.c +++ b/sound/soc/codecs/wm8994.c | |||
@@ -4439,7 +4439,7 @@ static struct regmap *wm8994_get_regmap(struct device *dev) | |||
4439 | return control->regmap; | 4439 | return control->regmap; |
4440 | } | 4440 | } |
4441 | 4441 | ||
4442 | static struct snd_soc_codec_driver soc_codec_dev_wm8994 = { | 4442 | static const struct snd_soc_codec_driver soc_codec_dev_wm8994 = { |
4443 | .probe = wm8994_codec_probe, | 4443 | .probe = wm8994_codec_probe, |
4444 | .remove = wm8994_codec_remove, | 4444 | .remove = wm8994_codec_remove, |
4445 | .suspend = wm8994_codec_suspend, | 4445 | .suspend = wm8994_codec_suspend, |
diff --git a/sound/soc/codecs/wm8995.c b/sound/soc/codecs/wm8995.c index 24500bafb0a8..19b08a5cae62 100644 --- a/sound/soc/codecs/wm8995.c +++ b/sound/soc/codecs/wm8995.c | |||
@@ -2192,12 +2192,14 @@ static const struct snd_soc_codec_driver soc_codec_dev_wm8995 = { | |||
2192 | .set_bias_level = wm8995_set_bias_level, | 2192 | .set_bias_level = wm8995_set_bias_level, |
2193 | .idle_bias_off = true, | 2193 | .idle_bias_off = true, |
2194 | 2194 | ||
2195 | .controls = wm8995_snd_controls, | 2195 | .component_driver = { |
2196 | .num_controls = ARRAY_SIZE(wm8995_snd_controls), | 2196 | .controls = wm8995_snd_controls, |
2197 | .dapm_widgets = wm8995_dapm_widgets, | 2197 | .num_controls = ARRAY_SIZE(wm8995_snd_controls), |
2198 | .num_dapm_widgets = ARRAY_SIZE(wm8995_dapm_widgets), | 2198 | .dapm_widgets = wm8995_dapm_widgets, |
2199 | .dapm_routes = wm8995_intercon, | 2199 | .num_dapm_widgets = ARRAY_SIZE(wm8995_dapm_widgets), |
2200 | .num_dapm_routes = ARRAY_SIZE(wm8995_intercon), | 2200 | .dapm_routes = wm8995_intercon, |
2201 | .num_dapm_routes = ARRAY_SIZE(wm8995_intercon), | ||
2202 | }, | ||
2201 | }; | 2203 | }; |
2202 | 2204 | ||
2203 | static const struct regmap_config wm8995_regmap = { | 2205 | static const struct regmap_config wm8995_regmap = { |
diff --git a/sound/soc/codecs/wm8996.c b/sound/soc/codecs/wm8996.c index a73044251218..8affa4969120 100644 --- a/sound/soc/codecs/wm8996.c +++ b/sound/soc/codecs/wm8996.c | |||
@@ -2184,7 +2184,7 @@ static int wm8996_gpio_direction_in(struct gpio_chip *chip, unsigned offset) | |||
2184 | (1 << WM8996_GP1_DIR_SHIFT)); | 2184 | (1 << WM8996_GP1_DIR_SHIFT)); |
2185 | } | 2185 | } |
2186 | 2186 | ||
2187 | static struct gpio_chip wm8996_template_chip = { | 2187 | static const struct gpio_chip wm8996_template_chip = { |
2188 | .label = "wm8996", | 2188 | .label = "wm8996", |
2189 | .owner = THIS_MODULE, | 2189 | .owner = THIS_MODULE, |
2190 | .direction_output = wm8996_gpio_direction_out, | 2190 | .direction_output = wm8996_gpio_direction_out, |
@@ -2684,18 +2684,20 @@ static int wm8996_remove(struct snd_soc_codec *codec) | |||
2684 | return 0; | 2684 | return 0; |
2685 | } | 2685 | } |
2686 | 2686 | ||
2687 | static struct snd_soc_codec_driver soc_codec_dev_wm8996 = { | 2687 | static const struct snd_soc_codec_driver soc_codec_dev_wm8996 = { |
2688 | .probe = wm8996_probe, | 2688 | .probe = wm8996_probe, |
2689 | .remove = wm8996_remove, | 2689 | .remove = wm8996_remove, |
2690 | .set_bias_level = wm8996_set_bias_level, | 2690 | .set_bias_level = wm8996_set_bias_level, |
2691 | .idle_bias_off = true, | 2691 | .idle_bias_off = true, |
2692 | .seq_notifier = wm8996_seq_notifier, | 2692 | .seq_notifier = wm8996_seq_notifier, |
2693 | .controls = wm8996_snd_controls, | 2693 | .component_driver = { |
2694 | .num_controls = ARRAY_SIZE(wm8996_snd_controls), | 2694 | .controls = wm8996_snd_controls, |
2695 | .dapm_widgets = wm8996_dapm_widgets, | 2695 | .num_controls = ARRAY_SIZE(wm8996_snd_controls), |
2696 | .num_dapm_widgets = ARRAY_SIZE(wm8996_dapm_widgets), | 2696 | .dapm_widgets = wm8996_dapm_widgets, |
2697 | .dapm_routes = wm8996_dapm_routes, | 2697 | .num_dapm_widgets = ARRAY_SIZE(wm8996_dapm_widgets), |
2698 | .num_dapm_routes = ARRAY_SIZE(wm8996_dapm_routes), | 2698 | .dapm_routes = wm8996_dapm_routes, |
2699 | .num_dapm_routes = ARRAY_SIZE(wm8996_dapm_routes), | ||
2700 | }, | ||
2699 | .set_pll = wm8996_set_fll, | 2701 | .set_pll = wm8996_set_fll, |
2700 | }; | 2702 | }; |
2701 | 2703 | ||
diff --git a/sound/soc/codecs/wm8997.c b/sound/soc/codecs/wm8997.c index 6b0785b5a5c5..2f2821b3382f 100644 --- a/sound/soc/codecs/wm8997.c +++ b/sound/soc/codecs/wm8997.c | |||
@@ -1095,7 +1095,7 @@ static struct regmap *wm8997_get_regmap(struct device *dev) | |||
1095 | return priv->core.arizona->regmap; | 1095 | return priv->core.arizona->regmap; |
1096 | } | 1096 | } |
1097 | 1097 | ||
1098 | static struct snd_soc_codec_driver soc_codec_dev_wm8997 = { | 1098 | static const struct snd_soc_codec_driver soc_codec_dev_wm8997 = { |
1099 | .probe = wm8997_codec_probe, | 1099 | .probe = wm8997_codec_probe, |
1100 | .remove = wm8997_codec_remove, | 1100 | .remove = wm8997_codec_remove, |
1101 | .get_regmap = wm8997_get_regmap, | 1101 | .get_regmap = wm8997_get_regmap, |
@@ -1105,12 +1105,14 @@ static struct snd_soc_codec_driver soc_codec_dev_wm8997 = { | |||
1105 | .set_sysclk = arizona_set_sysclk, | 1105 | .set_sysclk = arizona_set_sysclk, |
1106 | .set_pll = wm8997_set_fll, | 1106 | .set_pll = wm8997_set_fll, |
1107 | 1107 | ||
1108 | .controls = wm8997_snd_controls, | 1108 | .component_driver = { |
1109 | .num_controls = ARRAY_SIZE(wm8997_snd_controls), | 1109 | .controls = wm8997_snd_controls, |
1110 | .dapm_widgets = wm8997_dapm_widgets, | 1110 | .num_controls = ARRAY_SIZE(wm8997_snd_controls), |
1111 | .num_dapm_widgets = ARRAY_SIZE(wm8997_dapm_widgets), | 1111 | .dapm_widgets = wm8997_dapm_widgets, |
1112 | .dapm_routes = wm8997_dapm_routes, | 1112 | .num_dapm_widgets = ARRAY_SIZE(wm8997_dapm_widgets), |
1113 | .num_dapm_routes = ARRAY_SIZE(wm8997_dapm_routes), | 1113 | .dapm_routes = wm8997_dapm_routes, |
1114 | .num_dapm_routes = ARRAY_SIZE(wm8997_dapm_routes), | ||
1115 | }, | ||
1114 | }; | 1116 | }; |
1115 | 1117 | ||
1116 | static int wm8997_probe(struct platform_device *pdev) | 1118 | static int wm8997_probe(struct platform_device *pdev) |
diff --git a/sound/soc/codecs/wm8998.c b/sound/soc/codecs/wm8998.c index 3a5c896a2d13..bcc2e1060a6c 100644 --- a/sound/soc/codecs/wm8998.c +++ b/sound/soc/codecs/wm8998.c | |||
@@ -966,6 +966,16 @@ static const struct snd_soc_dapm_route wm8998_dapm_routes[] = { | |||
966 | { "IN2A", NULL, "SYSCLK" }, | 966 | { "IN2A", NULL, "SYSCLK" }, |
967 | { "IN2B", NULL, "SYSCLK" }, | 967 | { "IN2B", NULL, "SYSCLK" }, |
968 | 968 | ||
969 | { "ASRC1L", NULL, "SYSCLK" }, | ||
970 | { "ASRC1R", NULL, "SYSCLK" }, | ||
971 | { "ASRC2L", NULL, "SYSCLK" }, | ||
972 | { "ASRC2R", NULL, "SYSCLK" }, | ||
973 | |||
974 | { "ASRC1L", NULL, "ASYNCCLK" }, | ||
975 | { "ASRC1R", NULL, "ASYNCCLK" }, | ||
976 | { "ASRC2L", NULL, "ASYNCCLK" }, | ||
977 | { "ASRC2R", NULL, "ASYNCCLK" }, | ||
978 | |||
969 | { "SPD1", NULL, "SYSCLK" }, | 979 | { "SPD1", NULL, "SYSCLK" }, |
970 | { "SPD1", NULL, "SPD1TX1" }, | 980 | { "SPD1", NULL, "SPD1TX1" }, |
971 | { "SPD1", NULL, "SPD1TX2" }, | 981 | { "SPD1", NULL, "SPD1TX2" }, |
@@ -1351,7 +1361,7 @@ static struct regmap *wm8998_get_regmap(struct device *dev) | |||
1351 | return priv->core.arizona->regmap; | 1361 | return priv->core.arizona->regmap; |
1352 | } | 1362 | } |
1353 | 1363 | ||
1354 | static struct snd_soc_codec_driver soc_codec_dev_wm8998 = { | 1364 | static const struct snd_soc_codec_driver soc_codec_dev_wm8998 = { |
1355 | .probe = wm8998_codec_probe, | 1365 | .probe = wm8998_codec_probe, |
1356 | .remove = wm8998_codec_remove, | 1366 | .remove = wm8998_codec_remove, |
1357 | .get_regmap = wm8998_get_regmap, | 1367 | .get_regmap = wm8998_get_regmap, |
@@ -1361,12 +1371,14 @@ static struct snd_soc_codec_driver soc_codec_dev_wm8998 = { | |||
1361 | .set_sysclk = arizona_set_sysclk, | 1371 | .set_sysclk = arizona_set_sysclk, |
1362 | .set_pll = wm8998_set_fll, | 1372 | .set_pll = wm8998_set_fll, |
1363 | 1373 | ||
1364 | .controls = wm8998_snd_controls, | 1374 | .component_driver = { |
1365 | .num_controls = ARRAY_SIZE(wm8998_snd_controls), | 1375 | .controls = wm8998_snd_controls, |
1366 | .dapm_widgets = wm8998_dapm_widgets, | 1376 | .num_controls = ARRAY_SIZE(wm8998_snd_controls), |
1367 | .num_dapm_widgets = ARRAY_SIZE(wm8998_dapm_widgets), | 1377 | .dapm_widgets = wm8998_dapm_widgets, |
1368 | .dapm_routes = wm8998_dapm_routes, | 1378 | .num_dapm_widgets = ARRAY_SIZE(wm8998_dapm_widgets), |
1369 | .num_dapm_routes = ARRAY_SIZE(wm8998_dapm_routes), | 1379 | .dapm_routes = wm8998_dapm_routes, |
1380 | .num_dapm_routes = ARRAY_SIZE(wm8998_dapm_routes), | ||
1381 | }, | ||
1370 | }; | 1382 | }; |
1371 | 1383 | ||
1372 | static int wm8998_probe(struct platform_device *pdev) | 1384 | static int wm8998_probe(struct platform_device *pdev) |
diff --git a/sound/soc/codecs/wm9081.c b/sound/soc/codecs/wm9081.c index 363b3b667616..856867ec2813 100644 --- a/sound/soc/codecs/wm9081.c +++ b/sound/soc/codecs/wm9081.c | |||
@@ -1274,7 +1274,7 @@ static int wm9081_probe(struct snd_soc_codec *codec) | |||
1274 | return 0; | 1274 | return 0; |
1275 | } | 1275 | } |
1276 | 1276 | ||
1277 | static struct snd_soc_codec_driver soc_codec_dev_wm9081 = { | 1277 | static const struct snd_soc_codec_driver soc_codec_dev_wm9081 = { |
1278 | .probe = wm9081_probe, | 1278 | .probe = wm9081_probe, |
1279 | 1279 | ||
1280 | .set_sysclk = wm9081_set_sysclk, | 1280 | .set_sysclk = wm9081_set_sysclk, |
@@ -1282,12 +1282,14 @@ static struct snd_soc_codec_driver soc_codec_dev_wm9081 = { | |||
1282 | 1282 | ||
1283 | .idle_bias_off = true, | 1283 | .idle_bias_off = true, |
1284 | 1284 | ||
1285 | .controls = wm9081_snd_controls, | 1285 | .component_driver = { |
1286 | .num_controls = ARRAY_SIZE(wm9081_snd_controls), | 1286 | .controls = wm9081_snd_controls, |
1287 | .dapm_widgets = wm9081_dapm_widgets, | 1287 | .num_controls = ARRAY_SIZE(wm9081_snd_controls), |
1288 | .num_dapm_widgets = ARRAY_SIZE(wm9081_dapm_widgets), | 1288 | .dapm_widgets = wm9081_dapm_widgets, |
1289 | .dapm_routes = wm9081_audio_paths, | 1289 | .num_dapm_widgets = ARRAY_SIZE(wm9081_dapm_widgets), |
1290 | .num_dapm_routes = ARRAY_SIZE(wm9081_audio_paths), | 1290 | .dapm_routes = wm9081_audio_paths, |
1291 | .num_dapm_routes = ARRAY_SIZE(wm9081_audio_paths), | ||
1292 | }, | ||
1291 | }; | 1293 | }; |
1292 | 1294 | ||
1293 | static const struct regmap_config wm9081_regmap = { | 1295 | static const struct regmap_config wm9081_regmap = { |
diff --git a/sound/soc/codecs/wm9090.c b/sound/soc/codecs/wm9090.c index 5d737290f547..5a131385cb2f 100644 --- a/sound/soc/codecs/wm9090.c +++ b/sound/soc/codecs/wm9090.c | |||
@@ -550,7 +550,7 @@ static int wm9090_probe(struct snd_soc_codec *codec) | |||
550 | return 0; | 550 | return 0; |
551 | } | 551 | } |
552 | 552 | ||
553 | static struct snd_soc_codec_driver soc_codec_dev_wm9090 = { | 553 | static const struct snd_soc_codec_driver soc_codec_dev_wm9090 = { |
554 | .probe = wm9090_probe, | 554 | .probe = wm9090_probe, |
555 | .set_bias_level = wm9090_set_bias_level, | 555 | .set_bias_level = wm9090_set_bias_level, |
556 | .suspend_bias_off = true, | 556 | .suspend_bias_off = true, |
diff --git a/sound/soc/codecs/wm9705.c b/sound/soc/codecs/wm9705.c index 744842c76a60..dcdd055db57b 100644 --- a/sound/soc/codecs/wm9705.c +++ b/sound/soc/codecs/wm9705.c | |||
@@ -352,7 +352,7 @@ static int wm9705_soc_remove(struct snd_soc_codec *codec) | |||
352 | return 0; | 352 | return 0; |
353 | } | 353 | } |
354 | 354 | ||
355 | static struct snd_soc_codec_driver soc_codec_dev_wm9705 = { | 355 | static const struct snd_soc_codec_driver soc_codec_dev_wm9705 = { |
356 | .probe = wm9705_soc_probe, | 356 | .probe = wm9705_soc_probe, |
357 | .remove = wm9705_soc_remove, | 357 | .remove = wm9705_soc_remove, |
358 | .suspend = wm9705_soc_suspend, | 358 | .suspend = wm9705_soc_suspend, |
@@ -364,12 +364,14 @@ static struct snd_soc_codec_driver soc_codec_dev_wm9705 = { | |||
364 | .reg_cache_step = 2, | 364 | .reg_cache_step = 2, |
365 | .reg_cache_default = wm9705_reg, | 365 | .reg_cache_default = wm9705_reg, |
366 | 366 | ||
367 | .controls = wm9705_snd_ac97_controls, | 367 | .component_driver = { |
368 | .num_controls = ARRAY_SIZE(wm9705_snd_ac97_controls), | 368 | .controls = wm9705_snd_ac97_controls, |
369 | .dapm_widgets = wm9705_dapm_widgets, | 369 | .num_controls = ARRAY_SIZE(wm9705_snd_ac97_controls), |
370 | .num_dapm_widgets = ARRAY_SIZE(wm9705_dapm_widgets), | 370 | .dapm_widgets = wm9705_dapm_widgets, |
371 | .dapm_routes = wm9705_audio_map, | 371 | .num_dapm_widgets = ARRAY_SIZE(wm9705_dapm_widgets), |
372 | .num_dapm_routes = ARRAY_SIZE(wm9705_audio_map), | 372 | .dapm_routes = wm9705_audio_map, |
373 | .num_dapm_routes = ARRAY_SIZE(wm9705_audio_map), | ||
374 | }, | ||
373 | }; | 375 | }; |
374 | 376 | ||
375 | static int wm9705_probe(struct platform_device *pdev) | 377 | static int wm9705_probe(struct platform_device *pdev) |
diff --git a/sound/soc/codecs/wm9712.c b/sound/soc/codecs/wm9712.c index 488a92224249..557709eac698 100644 --- a/sound/soc/codecs/wm9712.c +++ b/sound/soc/codecs/wm9712.c | |||
@@ -669,7 +669,7 @@ static int wm9712_soc_remove(struct snd_soc_codec *codec) | |||
669 | return 0; | 669 | return 0; |
670 | } | 670 | } |
671 | 671 | ||
672 | static struct snd_soc_codec_driver soc_codec_dev_wm9712 = { | 672 | static const struct snd_soc_codec_driver soc_codec_dev_wm9712 = { |
673 | .probe = wm9712_soc_probe, | 673 | .probe = wm9712_soc_probe, |
674 | .remove = wm9712_soc_remove, | 674 | .remove = wm9712_soc_remove, |
675 | .resume = wm9712_soc_resume, | 675 | .resume = wm9712_soc_resume, |
@@ -682,12 +682,14 @@ static struct snd_soc_codec_driver soc_codec_dev_wm9712 = { | |||
682 | .reg_cache_step = 2, | 682 | .reg_cache_step = 2, |
683 | .reg_cache_default = wm9712_reg, | 683 | .reg_cache_default = wm9712_reg, |
684 | 684 | ||
685 | .controls = wm9712_snd_ac97_controls, | 685 | .component_driver = { |
686 | .num_controls = ARRAY_SIZE(wm9712_snd_ac97_controls), | 686 | .controls = wm9712_snd_ac97_controls, |
687 | .dapm_widgets = wm9712_dapm_widgets, | 687 | .num_controls = ARRAY_SIZE(wm9712_snd_ac97_controls), |
688 | .num_dapm_widgets = ARRAY_SIZE(wm9712_dapm_widgets), | 688 | .dapm_widgets = wm9712_dapm_widgets, |
689 | .dapm_routes = wm9712_audio_map, | 689 | .num_dapm_widgets = ARRAY_SIZE(wm9712_dapm_widgets), |
690 | .num_dapm_routes = ARRAY_SIZE(wm9712_audio_map), | 690 | .dapm_routes = wm9712_audio_map, |
691 | .num_dapm_routes = ARRAY_SIZE(wm9712_audio_map), | ||
692 | }, | ||
691 | }; | 693 | }; |
692 | 694 | ||
693 | static int wm9712_probe(struct platform_device *pdev) | 695 | static int wm9712_probe(struct platform_device *pdev) |
diff --git a/sound/soc/codecs/wm9713.c b/sound/soc/codecs/wm9713.c index 9849643ef809..e4301ddb1b84 100644 --- a/sound/soc/codecs/wm9713.c +++ b/sound/soc/codecs/wm9713.c | |||
@@ -1235,19 +1235,21 @@ static int wm9713_soc_remove(struct snd_soc_codec *codec) | |||
1235 | return 0; | 1235 | return 0; |
1236 | } | 1236 | } |
1237 | 1237 | ||
1238 | static struct snd_soc_codec_driver soc_codec_dev_wm9713 = { | 1238 | static const struct snd_soc_codec_driver soc_codec_dev_wm9713 = { |
1239 | .probe = wm9713_soc_probe, | 1239 | .probe = wm9713_soc_probe, |
1240 | .remove = wm9713_soc_remove, | 1240 | .remove = wm9713_soc_remove, |
1241 | .suspend = wm9713_soc_suspend, | 1241 | .suspend = wm9713_soc_suspend, |
1242 | .resume = wm9713_soc_resume, | 1242 | .resume = wm9713_soc_resume, |
1243 | .set_bias_level = wm9713_set_bias_level, | 1243 | .set_bias_level = wm9713_set_bias_level, |
1244 | 1244 | ||
1245 | .controls = wm9713_snd_ac97_controls, | 1245 | .component_driver = { |
1246 | .num_controls = ARRAY_SIZE(wm9713_snd_ac97_controls), | 1246 | .controls = wm9713_snd_ac97_controls, |
1247 | .dapm_widgets = wm9713_dapm_widgets, | 1247 | .num_controls = ARRAY_SIZE(wm9713_snd_ac97_controls), |
1248 | .num_dapm_widgets = ARRAY_SIZE(wm9713_dapm_widgets), | 1248 | .dapm_widgets = wm9713_dapm_widgets, |
1249 | .dapm_routes = wm9713_audio_map, | 1249 | .num_dapm_widgets = ARRAY_SIZE(wm9713_dapm_widgets), |
1250 | .num_dapm_routes = ARRAY_SIZE(wm9713_audio_map), | 1250 | .dapm_routes = wm9713_audio_map, |
1251 | .num_dapm_routes = ARRAY_SIZE(wm9713_audio_map), | ||
1252 | }, | ||
1251 | }; | 1253 | }; |
1252 | 1254 | ||
1253 | static int wm9713_probe(struct platform_device *pdev) | 1255 | static int wm9713_probe(struct platform_device *pdev) |
diff --git a/sound/soc/codecs/wm_adsp.c b/sound/soc/codecs/wm_adsp.c index 21fbe7d07063..b943dde8dbe5 100644 --- a/sound/soc/codecs/wm_adsp.c +++ b/sound/soc/codecs/wm_adsp.c | |||
@@ -480,7 +480,7 @@ static ssize_t wm_adsp_debugfs_wmfw_read(struct file *file, | |||
480 | 480 | ||
481 | mutex_lock(&dsp->pwr_lock); | 481 | mutex_lock(&dsp->pwr_lock); |
482 | 482 | ||
483 | if (!dsp->wmfw_file_name || !dsp->running) | 483 | if (!dsp->wmfw_file_name || !dsp->booted) |
484 | ret = 0; | 484 | ret = 0; |
485 | else | 485 | else |
486 | ret = simple_read_from_buffer(user_buf, count, ppos, | 486 | ret = simple_read_from_buffer(user_buf, count, ppos, |
@@ -500,7 +500,7 @@ static ssize_t wm_adsp_debugfs_bin_read(struct file *file, | |||
500 | 500 | ||
501 | mutex_lock(&dsp->pwr_lock); | 501 | mutex_lock(&dsp->pwr_lock); |
502 | 502 | ||
503 | if (!dsp->bin_file_name || !dsp->running) | 503 | if (!dsp->bin_file_name || !dsp->booted) |
504 | ret = 0; | 504 | ret = 0; |
505 | else | 505 | else |
506 | ret = simple_read_from_buffer(user_buf, count, ppos, | 506 | ret = simple_read_from_buffer(user_buf, count, ppos, |
@@ -554,6 +554,9 @@ static void wm_adsp2_init_debugfs(struct wm_adsp *dsp, | |||
554 | if (!root) | 554 | if (!root) |
555 | goto err; | 555 | goto err; |
556 | 556 | ||
557 | if (!debugfs_create_bool("booted", S_IRUGO, root, &dsp->booted)) | ||
558 | goto err; | ||
559 | |||
557 | if (!debugfs_create_bool("running", S_IRUGO, root, &dsp->running)) | 560 | if (!debugfs_create_bool("running", S_IRUGO, root, &dsp->running)) |
558 | goto err; | 561 | goto err; |
559 | 562 | ||
@@ -637,7 +640,7 @@ static int wm_adsp_fw_put(struct snd_kcontrol *kcontrol, | |||
637 | 640 | ||
638 | mutex_lock(&dsp[e->shift_l].pwr_lock); | 641 | mutex_lock(&dsp[e->shift_l].pwr_lock); |
639 | 642 | ||
640 | if (dsp[e->shift_l].running || dsp[e->shift_l].compr) | 643 | if (dsp[e->shift_l].booted || dsp[e->shift_l].compr) |
641 | ret = -EBUSY; | 644 | ret = -EBUSY; |
642 | else | 645 | else |
643 | dsp[e->shift_l].fw = ucontrol->value.enumerated.item[0]; | 646 | dsp[e->shift_l].fw = ucontrol->value.enumerated.item[0]; |
@@ -789,7 +792,7 @@ static int wm_coeff_put(struct snd_kcontrol *kctl, | |||
789 | memcpy(ctl->cache, p, ctl->len); | 792 | memcpy(ctl->cache, p, ctl->len); |
790 | 793 | ||
791 | ctl->set = 1; | 794 | ctl->set = 1; |
792 | if (ctl->enabled) | 795 | if (ctl->enabled && ctl->dsp->running) |
793 | ret = wm_coeff_write_control(ctl, p, ctl->len); | 796 | ret = wm_coeff_write_control(ctl, p, ctl->len); |
794 | 797 | ||
795 | mutex_unlock(&ctl->dsp->pwr_lock); | 798 | mutex_unlock(&ctl->dsp->pwr_lock); |
@@ -811,7 +814,7 @@ static int wm_coeff_tlv_put(struct snd_kcontrol *kctl, | |||
811 | ret = -EFAULT; | 814 | ret = -EFAULT; |
812 | } else { | 815 | } else { |
813 | ctl->set = 1; | 816 | ctl->set = 1; |
814 | if (ctl->enabled) | 817 | if (ctl->enabled && ctl->dsp->running) |
815 | ret = wm_coeff_write_control(ctl, ctl->cache, size); | 818 | ret = wm_coeff_write_control(ctl, ctl->cache, size); |
816 | } | 819 | } |
817 | 820 | ||
@@ -871,12 +874,12 @@ static int wm_coeff_get(struct snd_kcontrol *kctl, | |||
871 | mutex_lock(&ctl->dsp->pwr_lock); | 874 | mutex_lock(&ctl->dsp->pwr_lock); |
872 | 875 | ||
873 | if (ctl->flags & WMFW_CTL_FLAG_VOLATILE) { | 876 | if (ctl->flags & WMFW_CTL_FLAG_VOLATILE) { |
874 | if (ctl->enabled) | 877 | if (ctl->enabled && ctl->dsp->running) |
875 | ret = wm_coeff_read_control(ctl, p, ctl->len); | 878 | ret = wm_coeff_read_control(ctl, p, ctl->len); |
876 | else | 879 | else |
877 | ret = -EPERM; | 880 | ret = -EPERM; |
878 | } else { | 881 | } else { |
879 | if (!ctl->flags && ctl->enabled) | 882 | if (!ctl->flags && ctl->enabled && ctl->dsp->running) |
880 | ret = wm_coeff_read_control(ctl, ctl->cache, ctl->len); | 883 | ret = wm_coeff_read_control(ctl, ctl->cache, ctl->len); |
881 | 884 | ||
882 | memcpy(p, ctl->cache, ctl->len); | 885 | memcpy(p, ctl->cache, ctl->len); |
@@ -898,12 +901,12 @@ static int wm_coeff_tlv_get(struct snd_kcontrol *kctl, | |||
898 | mutex_lock(&ctl->dsp->pwr_lock); | 901 | mutex_lock(&ctl->dsp->pwr_lock); |
899 | 902 | ||
900 | if (ctl->flags & WMFW_CTL_FLAG_VOLATILE) { | 903 | if (ctl->flags & WMFW_CTL_FLAG_VOLATILE) { |
901 | if (ctl->enabled) | 904 | if (ctl->enabled && ctl->dsp->running) |
902 | ret = wm_coeff_read_control(ctl, ctl->cache, size); | 905 | ret = wm_coeff_read_control(ctl, ctl->cache, size); |
903 | else | 906 | else |
904 | ret = -EPERM; | 907 | ret = -EPERM; |
905 | } else { | 908 | } else { |
906 | if (!ctl->flags && ctl->enabled) | 909 | if (!ctl->flags && ctl->enabled && ctl->dsp->running) |
907 | ret = wm_coeff_read_control(ctl, ctl->cache, size); | 910 | ret = wm_coeff_read_control(ctl, ctl->cache, size); |
908 | } | 911 | } |
909 | 912 | ||
@@ -2166,13 +2169,20 @@ int wm_adsp1_event(struct snd_soc_dapm_widget *w, | |||
2166 | if (ret != 0) | 2169 | if (ret != 0) |
2167 | goto err_ena; | 2170 | goto err_ena; |
2168 | 2171 | ||
2172 | dsp->booted = true; | ||
2173 | |||
2169 | /* Start the core running */ | 2174 | /* Start the core running */ |
2170 | regmap_update_bits(dsp->regmap, dsp->base + ADSP1_CONTROL_30, | 2175 | regmap_update_bits(dsp->regmap, dsp->base + ADSP1_CONTROL_30, |
2171 | ADSP1_CORE_ENA | ADSP1_START, | 2176 | ADSP1_CORE_ENA | ADSP1_START, |
2172 | ADSP1_CORE_ENA | ADSP1_START); | 2177 | ADSP1_CORE_ENA | ADSP1_START); |
2178 | |||
2179 | dsp->running = true; | ||
2173 | break; | 2180 | break; |
2174 | 2181 | ||
2175 | case SND_SOC_DAPM_PRE_PMD: | 2182 | case SND_SOC_DAPM_PRE_PMD: |
2183 | dsp->running = false; | ||
2184 | dsp->booted = false; | ||
2185 | |||
2176 | /* Halt the core */ | 2186 | /* Halt the core */ |
2177 | regmap_update_bits(dsp->regmap, dsp->base + ADSP1_CONTROL_30, | 2187 | regmap_update_bits(dsp->regmap, dsp->base + ADSP1_CONTROL_30, |
2178 | ADSP1_CORE_ENA | ADSP1_START, 0); | 2188 | ADSP1_CORE_ENA | ADSP1_START, 0); |
@@ -2227,7 +2237,7 @@ static int wm_adsp2_ena(struct wm_adsp *dsp) | |||
2227 | if (val & ADSP2_RAM_RDY) | 2237 | if (val & ADSP2_RAM_RDY) |
2228 | break; | 2238 | break; |
2229 | 2239 | ||
2230 | msleep(1); | 2240 | usleep_range(250, 500); |
2231 | } | 2241 | } |
2232 | 2242 | ||
2233 | if (!(val & ADSP2_RAM_RDY)) { | 2243 | if (!(val & ADSP2_RAM_RDY)) { |
@@ -2249,6 +2259,11 @@ static void wm_adsp2_boot_work(struct work_struct *work) | |||
2249 | 2259 | ||
2250 | mutex_lock(&dsp->pwr_lock); | 2260 | mutex_lock(&dsp->pwr_lock); |
2251 | 2261 | ||
2262 | ret = regmap_update_bits(dsp->regmap, dsp->base + ADSP2_CONTROL, | ||
2263 | ADSP2_MEM_ENA, ADSP2_MEM_ENA); | ||
2264 | if (ret != 0) | ||
2265 | goto err_mutex; | ||
2266 | |||
2252 | ret = wm_adsp2_ena(dsp); | 2267 | ret = wm_adsp2_ena(dsp); |
2253 | if (ret != 0) | 2268 | if (ret != 0) |
2254 | goto err_mutex; | 2269 | goto err_mutex; |
@@ -2270,13 +2285,14 @@ static void wm_adsp2_boot_work(struct work_struct *work) | |||
2270 | if (ret != 0) | 2285 | if (ret != 0) |
2271 | goto err_ena; | 2286 | goto err_ena; |
2272 | 2287 | ||
2273 | /* Sync set controls */ | 2288 | dsp->booted = true; |
2274 | ret = wm_coeff_sync_controls(dsp); | 2289 | |
2290 | /* Turn DSP back off until we are ready to run */ | ||
2291 | ret = regmap_update_bits(dsp->regmap, dsp->base + ADSP2_CONTROL, | ||
2292 | ADSP2_SYS_ENA, 0); | ||
2275 | if (ret != 0) | 2293 | if (ret != 0) |
2276 | goto err_ena; | 2294 | goto err_ena; |
2277 | 2295 | ||
2278 | dsp->running = true; | ||
2279 | |||
2280 | mutex_unlock(&dsp->pwr_lock); | 2296 | mutex_unlock(&dsp->pwr_lock); |
2281 | 2297 | ||
2282 | return; | 2298 | return; |
@@ -2307,6 +2323,7 @@ int wm_adsp2_early_event(struct snd_soc_dapm_widget *w, | |||
2307 | struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); | 2323 | struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); |
2308 | struct wm_adsp *dsps = snd_soc_codec_get_drvdata(codec); | 2324 | struct wm_adsp *dsps = snd_soc_codec_get_drvdata(codec); |
2309 | struct wm_adsp *dsp = &dsps[w->shift]; | 2325 | struct wm_adsp *dsp = &dsps[w->shift]; |
2326 | struct wm_coeff_ctl *ctl; | ||
2310 | 2327 | ||
2311 | dsp->card = codec->component.card; | 2328 | dsp->card = codec->component.card; |
2312 | 2329 | ||
@@ -2315,6 +2332,24 @@ int wm_adsp2_early_event(struct snd_soc_dapm_widget *w, | |||
2315 | wm_adsp2_set_dspclk(dsp, freq); | 2332 | wm_adsp2_set_dspclk(dsp, freq); |
2316 | queue_work(system_unbound_wq, &dsp->boot_work); | 2333 | queue_work(system_unbound_wq, &dsp->boot_work); |
2317 | break; | 2334 | break; |
2335 | case SND_SOC_DAPM_PRE_PMD: | ||
2336 | wm_adsp_debugfs_clear(dsp); | ||
2337 | |||
2338 | dsp->fw_id = 0; | ||
2339 | dsp->fw_id_version = 0; | ||
2340 | |||
2341 | dsp->booted = false; | ||
2342 | |||
2343 | regmap_update_bits(dsp->regmap, dsp->base + ADSP2_CONTROL, | ||
2344 | ADSP2_MEM_ENA, 0); | ||
2345 | |||
2346 | list_for_each_entry(ctl, &dsp->ctl_list, list) | ||
2347 | ctl->enabled = 0; | ||
2348 | |||
2349 | wm_adsp_free_alg_regions(dsp); | ||
2350 | |||
2351 | adsp_dbg(dsp, "Shutdown complete\n"); | ||
2352 | break; | ||
2318 | default: | 2353 | default: |
2319 | break; | 2354 | break; |
2320 | } | 2355 | } |
@@ -2329,16 +2364,24 @@ int wm_adsp2_event(struct snd_soc_dapm_widget *w, | |||
2329 | struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); | 2364 | struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); |
2330 | struct wm_adsp *dsps = snd_soc_codec_get_drvdata(codec); | 2365 | struct wm_adsp *dsps = snd_soc_codec_get_drvdata(codec); |
2331 | struct wm_adsp *dsp = &dsps[w->shift]; | 2366 | struct wm_adsp *dsp = &dsps[w->shift]; |
2332 | struct wm_coeff_ctl *ctl; | ||
2333 | int ret; | 2367 | int ret; |
2334 | 2368 | ||
2335 | switch (event) { | 2369 | switch (event) { |
2336 | case SND_SOC_DAPM_POST_PMU: | 2370 | case SND_SOC_DAPM_POST_PMU: |
2337 | flush_work(&dsp->boot_work); | 2371 | flush_work(&dsp->boot_work); |
2338 | 2372 | ||
2339 | if (!dsp->running) | 2373 | if (!dsp->booted) |
2340 | return -EIO; | 2374 | return -EIO; |
2341 | 2375 | ||
2376 | ret = wm_adsp2_ena(dsp); | ||
2377 | if (ret != 0) | ||
2378 | goto err; | ||
2379 | |||
2380 | /* Sync set controls */ | ||
2381 | ret = wm_coeff_sync_controls(dsp); | ||
2382 | if (ret != 0) | ||
2383 | goto err; | ||
2384 | |||
2342 | ret = regmap_update_bits(dsp->regmap, | 2385 | ret = regmap_update_bits(dsp->regmap, |
2343 | dsp->base + ADSP2_CONTROL, | 2386 | dsp->base + ADSP2_CONTROL, |
2344 | ADSP2_CORE_ENA | ADSP2_START, | 2387 | ADSP2_CORE_ENA | ADSP2_START, |
@@ -2346,6 +2389,8 @@ int wm_adsp2_event(struct snd_soc_dapm_widget *w, | |||
2346 | if (ret != 0) | 2389 | if (ret != 0) |
2347 | goto err; | 2390 | goto err; |
2348 | 2391 | ||
2392 | dsp->running = true; | ||
2393 | |||
2349 | mutex_lock(&dsp->pwr_lock); | 2394 | mutex_lock(&dsp->pwr_lock); |
2350 | 2395 | ||
2351 | if (wm_adsp_fw[dsp->fw].num_caps != 0) | 2396 | if (wm_adsp_fw[dsp->fw].num_caps != 0) |
@@ -2361,10 +2406,6 @@ int wm_adsp2_event(struct snd_soc_dapm_widget *w, | |||
2361 | 2406 | ||
2362 | mutex_lock(&dsp->pwr_lock); | 2407 | mutex_lock(&dsp->pwr_lock); |
2363 | 2408 | ||
2364 | wm_adsp_debugfs_clear(dsp); | ||
2365 | |||
2366 | dsp->fw_id = 0; | ||
2367 | dsp->fw_id_version = 0; | ||
2368 | dsp->running = false; | 2409 | dsp->running = false; |
2369 | 2410 | ||
2370 | regmap_update_bits(dsp->regmap, dsp->base + ADSP2_CONTROL, | 2411 | regmap_update_bits(dsp->regmap, dsp->base + ADSP2_CONTROL, |
@@ -2378,17 +2419,12 @@ int wm_adsp2_event(struct snd_soc_dapm_widget *w, | |||
2378 | regmap_update_bits(dsp->regmap, dsp->base + ADSP2_CONTROL, | 2419 | regmap_update_bits(dsp->regmap, dsp->base + ADSP2_CONTROL, |
2379 | ADSP2_SYS_ENA, 0); | 2420 | ADSP2_SYS_ENA, 0); |
2380 | 2421 | ||
2381 | list_for_each_entry(ctl, &dsp->ctl_list, list) | ||
2382 | ctl->enabled = 0; | ||
2383 | |||
2384 | wm_adsp_free_alg_regions(dsp); | ||
2385 | |||
2386 | if (wm_adsp_fw[dsp->fw].num_caps != 0) | 2422 | if (wm_adsp_fw[dsp->fw].num_caps != 0) |
2387 | wm_adsp_buffer_free(dsp); | 2423 | wm_adsp_buffer_free(dsp); |
2388 | 2424 | ||
2389 | mutex_unlock(&dsp->pwr_lock); | 2425 | mutex_unlock(&dsp->pwr_lock); |
2390 | 2426 | ||
2391 | adsp_dbg(dsp, "Shutdown complete\n"); | 2427 | adsp_dbg(dsp, "Execution stopped\n"); |
2392 | break; | 2428 | break; |
2393 | 2429 | ||
2394 | default: | 2430 | default: |
diff --git a/sound/soc/codecs/wm_adsp.h b/sound/soc/codecs/wm_adsp.h index be3b5bcb7f17..362dd7ce60d8 100644 --- a/sound/soc/codecs/wm_adsp.h +++ b/sound/soc/codecs/wm_adsp.h | |||
@@ -61,6 +61,8 @@ struct wm_adsp { | |||
61 | 61 | ||
62 | int fw; | 62 | int fw; |
63 | int fw_ver; | 63 | int fw_ver; |
64 | |||
65 | bool booted; | ||
64 | bool running; | 66 | bool running; |
65 | 67 | ||
66 | struct list_head ctl_list; | 68 | struct list_head ctl_list; |
@@ -85,9 +87,10 @@ struct wm_adsp { | |||
85 | wm_adsp1_event, SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD) | 87 | wm_adsp1_event, SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD) |
86 | 88 | ||
87 | #define WM_ADSP2(wname, num, event_fn) \ | 89 | #define WM_ADSP2(wname, num, event_fn) \ |
88 | { .id = snd_soc_dapm_dai_link, .name = wname " Preloader", \ | 90 | { .id = snd_soc_dapm_supply, .name = wname " Preloader", \ |
89 | .reg = SND_SOC_NOPM, .shift = num, .event = event_fn, \ | 91 | .reg = SND_SOC_NOPM, .shift = num, .event = event_fn, \ |
90 | .event_flags = SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD }, \ | 92 | .event_flags = SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_PRE_PMD, \ |
93 | .subseq = 100, /* Ensure we run after SYSCLK supply widget */ }, \ | ||
91 | { .id = snd_soc_dapm_out_drv, .name = wname, \ | 94 | { .id = snd_soc_dapm_out_drv, .name = wname, \ |
92 | .reg = SND_SOC_NOPM, .shift = num, .event = wm_adsp2_event, \ | 95 | .reg = SND_SOC_NOPM, .shift = num, .event = wm_adsp2_event, \ |
93 | .event_flags = SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD } | 96 | .event_flags = SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD } |
diff --git a/sound/soc/davinci/davinci-mcasp.c b/sound/soc/davinci/davinci-mcasp.c index 05c2d33aa74d..3c5a9804d3f5 100644 --- a/sound/soc/davinci/davinci-mcasp.c +++ b/sound/soc/davinci/davinci-mcasp.c | |||
@@ -1218,7 +1218,7 @@ static int davinci_mcasp_hw_rule_format(struct snd_pcm_hw_params *params, | |||
1218 | 1218 | ||
1219 | snd_mask_none(&nfmt); | 1219 | snd_mask_none(&nfmt); |
1220 | 1220 | ||
1221 | for (i = 0; i < SNDRV_PCM_FORMAT_LAST; i++) { | 1221 | for (i = 0; i <= SNDRV_PCM_FORMAT_LAST; i++) { |
1222 | if (snd_mask_test(fmt, i)) { | 1222 | if (snd_mask_test(fmt, i)) { |
1223 | uint sbits = snd_pcm_format_width(i); | 1223 | uint sbits = snd_pcm_format_width(i); |
1224 | int ppm; | 1224 | int ppm; |
diff --git a/sound/soc/dwc/designware_i2s.c b/sound/soc/dwc/designware_i2s.c index dc97f4349e66..2998954a1c74 100644 --- a/sound/soc/dwc/designware_i2s.c +++ b/sound/soc/dwc/designware_i2s.c | |||
@@ -577,7 +577,6 @@ static int dw_configure_dai_by_dt(struct dw_i2s_dev *dev, | |||
577 | dev->capability |= DWC_I2S_PLAY; | 577 | dev->capability |= DWC_I2S_PLAY; |
578 | dev->play_dma_data.dt.addr = res->start + I2S_TXDMA; | 578 | dev->play_dma_data.dt.addr = res->start + I2S_TXDMA; |
579 | dev->play_dma_data.dt.addr_width = bus_widths[idx]; | 579 | dev->play_dma_data.dt.addr_width = bus_widths[idx]; |
580 | dev->play_dma_data.dt.chan_name = "TX"; | ||
581 | dev->play_dma_data.dt.fifo_size = fifo_depth * | 580 | dev->play_dma_data.dt.fifo_size = fifo_depth * |
582 | (fifo_width[idx2]) >> 8; | 581 | (fifo_width[idx2]) >> 8; |
583 | dev->play_dma_data.dt.maxburst = 16; | 582 | dev->play_dma_data.dt.maxburst = 16; |
@@ -588,7 +587,6 @@ static int dw_configure_dai_by_dt(struct dw_i2s_dev *dev, | |||
588 | dev->capability |= DWC_I2S_RECORD; | 587 | dev->capability |= DWC_I2S_RECORD; |
589 | dev->capture_dma_data.dt.addr = res->start + I2S_RXDMA; | 588 | dev->capture_dma_data.dt.addr = res->start + I2S_RXDMA; |
590 | dev->capture_dma_data.dt.addr_width = bus_widths[idx]; | 589 | dev->capture_dma_data.dt.addr_width = bus_widths[idx]; |
591 | dev->capture_dma_data.dt.chan_name = "RX"; | ||
592 | dev->capture_dma_data.dt.fifo_size = fifo_depth * | 590 | dev->capture_dma_data.dt.fifo_size = fifo_depth * |
593 | (fifo_width[idx2] >> 8); | 591 | (fifo_width[idx2] >> 8); |
594 | dev->capture_dma_data.dt.maxburst = 16; | 592 | dev->capture_dma_data.dt.maxburst = 16; |
diff --git a/sound/soc/fsl/fsl_asrc.c b/sound/soc/fsl/fsl_asrc.c index c1a0e01cb8e7..1d82f68305c3 100644 --- a/sound/soc/fsl/fsl_asrc.c +++ b/sound/soc/fsl/fsl_asrc.c | |||
@@ -726,7 +726,7 @@ static const struct regmap_config fsl_asrc_regmap_config = { | |||
726 | .readable_reg = fsl_asrc_readable_reg, | 726 | .readable_reg = fsl_asrc_readable_reg, |
727 | .volatile_reg = fsl_asrc_volatile_reg, | 727 | .volatile_reg = fsl_asrc_volatile_reg, |
728 | .writeable_reg = fsl_asrc_writeable_reg, | 728 | .writeable_reg = fsl_asrc_writeable_reg, |
729 | .cache_type = REGCACHE_RBTREE, | 729 | .cache_type = REGCACHE_FLAT, |
730 | }; | 730 | }; |
731 | 731 | ||
732 | /** | 732 | /** |
@@ -879,7 +879,7 @@ static int fsl_asrc_probe(struct platform_device *pdev) | |||
879 | } | 879 | } |
880 | } | 880 | } |
881 | 881 | ||
882 | if (of_device_is_compatible(pdev->dev.of_node, "fsl,imx35-asrc")) { | 882 | if (of_device_is_compatible(np, "fsl,imx35-asrc")) { |
883 | asrc_priv->channel_bits = 3; | 883 | asrc_priv->channel_bits = 3; |
884 | clk_map[IN] = input_clk_map_imx35; | 884 | clk_map[IN] = input_clk_map_imx35; |
885 | clk_map[OUT] = output_clk_map_imx35; | 885 | clk_map[OUT] = output_clk_map_imx35; |
@@ -892,7 +892,7 @@ static int fsl_asrc_probe(struct platform_device *pdev) | |||
892 | ret = fsl_asrc_init(asrc_priv); | 892 | ret = fsl_asrc_init(asrc_priv); |
893 | if (ret) { | 893 | if (ret) { |
894 | dev_err(&pdev->dev, "failed to init asrc %d\n", ret); | 894 | dev_err(&pdev->dev, "failed to init asrc %d\n", ret); |
895 | return -EINVAL; | 895 | return ret; |
896 | } | 896 | } |
897 | 897 | ||
898 | asrc_priv->channel_avail = 10; | 898 | asrc_priv->channel_avail = 10; |
@@ -901,14 +901,14 @@ static int fsl_asrc_probe(struct platform_device *pdev) | |||
901 | &asrc_priv->asrc_rate); | 901 | &asrc_priv->asrc_rate); |
902 | if (ret) { | 902 | if (ret) { |
903 | dev_err(&pdev->dev, "failed to get output rate\n"); | 903 | dev_err(&pdev->dev, "failed to get output rate\n"); |
904 | return -EINVAL; | 904 | return ret; |
905 | } | 905 | } |
906 | 906 | ||
907 | ret = of_property_read_u32(np, "fsl,asrc-width", | 907 | ret = of_property_read_u32(np, "fsl,asrc-width", |
908 | &asrc_priv->asrc_width); | 908 | &asrc_priv->asrc_width); |
909 | if (ret) { | 909 | if (ret) { |
910 | dev_err(&pdev->dev, "failed to get output width\n"); | 910 | dev_err(&pdev->dev, "failed to get output width\n"); |
911 | return -EINVAL; | 911 | return ret; |
912 | } | 912 | } |
913 | 913 | ||
914 | if (asrc_priv->asrc_width != 16 && asrc_priv->asrc_width != 24) { | 914 | if (asrc_priv->asrc_width != 16 && asrc_priv->asrc_width != 24) { |
@@ -933,8 +933,6 @@ static int fsl_asrc_probe(struct platform_device *pdev) | |||
933 | return ret; | 933 | return ret; |
934 | } | 934 | } |
935 | 935 | ||
936 | dev_info(&pdev->dev, "driver registered\n"); | ||
937 | |||
938 | return 0; | 936 | return 0; |
939 | } | 937 | } |
940 | 938 | ||
diff --git a/sound/soc/fsl/fsl_asrc_dma.c b/sound/soc/fsl/fsl_asrc_dma.c index ffc000bc1f15..dc30d780f874 100644 --- a/sound/soc/fsl/fsl_asrc_dma.c +++ b/sound/soc/fsl/fsl_asrc_dma.c | |||
@@ -322,7 +322,7 @@ static snd_pcm_uframes_t fsl_asrc_dma_pcm_pointer(struct snd_pcm_substream *subs | |||
322 | return bytes_to_frames(substream->runtime, pair->pos); | 322 | return bytes_to_frames(substream->runtime, pair->pos); |
323 | } | 323 | } |
324 | 324 | ||
325 | static struct snd_pcm_ops fsl_asrc_dma_pcm_ops = { | 325 | static const struct snd_pcm_ops fsl_asrc_dma_pcm_ops = { |
326 | .ioctl = snd_pcm_lib_ioctl, | 326 | .ioctl = snd_pcm_lib_ioctl, |
327 | .hw_params = fsl_asrc_dma_hw_params, | 327 | .hw_params = fsl_asrc_dma_hw_params, |
328 | .hw_free = fsl_asrc_dma_hw_free, | 328 | .hw_free = fsl_asrc_dma_hw_free, |
diff --git a/sound/soc/fsl/fsl_esai.c b/sound/soc/fsl/fsl_esai.c index 26a90e12ede4..38bfd46f4ad8 100644 --- a/sound/soc/fsl/fsl_esai.c +++ b/sound/soc/fsl/fsl_esai.c | |||
@@ -77,19 +77,19 @@ static irqreturn_t esai_isr(int irq, void *devid) | |||
77 | regmap_read(esai_priv->regmap, REG_ESAI_ESR, &esr); | 77 | regmap_read(esai_priv->regmap, REG_ESAI_ESR, &esr); |
78 | 78 | ||
79 | if (esr & ESAI_ESR_TINIT_MASK) | 79 | if (esr & ESAI_ESR_TINIT_MASK) |
80 | dev_dbg(&pdev->dev, "isr: Transmition Initialized\n"); | 80 | dev_dbg(&pdev->dev, "isr: Transmission Initialized\n"); |
81 | 81 | ||
82 | if (esr & ESAI_ESR_RFF_MASK) | 82 | if (esr & ESAI_ESR_RFF_MASK) |
83 | dev_warn(&pdev->dev, "isr: Receiving overrun\n"); | 83 | dev_warn(&pdev->dev, "isr: Receiving overrun\n"); |
84 | 84 | ||
85 | if (esr & ESAI_ESR_TFE_MASK) | 85 | if (esr & ESAI_ESR_TFE_MASK) |
86 | dev_warn(&pdev->dev, "isr: Transmition underrun\n"); | 86 | dev_warn(&pdev->dev, "isr: Transmission underrun\n"); |
87 | 87 | ||
88 | if (esr & ESAI_ESR_TLS_MASK) | 88 | if (esr & ESAI_ESR_TLS_MASK) |
89 | dev_dbg(&pdev->dev, "isr: Just transmitted the last slot\n"); | 89 | dev_dbg(&pdev->dev, "isr: Just transmitted the last slot\n"); |
90 | 90 | ||
91 | if (esr & ESAI_ESR_TDE_MASK) | 91 | if (esr & ESAI_ESR_TDE_MASK) |
92 | dev_dbg(&pdev->dev, "isr: Transmition data exception\n"); | 92 | dev_dbg(&pdev->dev, "isr: Transmission data exception\n"); |
93 | 93 | ||
94 | if (esr & ESAI_ESR_TED_MASK) | 94 | if (esr & ESAI_ESR_TED_MASK) |
95 | dev_dbg(&pdev->dev, "isr: Transmitting even slots\n"); | 95 | dev_dbg(&pdev->dev, "isr: Transmitting even slots\n"); |
@@ -781,7 +781,7 @@ static const struct regmap_config fsl_esai_regmap_config = { | |||
781 | .readable_reg = fsl_esai_readable_reg, | 781 | .readable_reg = fsl_esai_readable_reg, |
782 | .volatile_reg = fsl_esai_volatile_reg, | 782 | .volatile_reg = fsl_esai_volatile_reg, |
783 | .writeable_reg = fsl_esai_writeable_reg, | 783 | .writeable_reg = fsl_esai_writeable_reg, |
784 | .cache_type = REGCACHE_RBTREE, | 784 | .cache_type = REGCACHE_FLAT, |
785 | }; | 785 | }; |
786 | 786 | ||
787 | static int fsl_esai_probe(struct platform_device *pdev) | 787 | static int fsl_esai_probe(struct platform_device *pdev) |
diff --git a/sound/soc/fsl/fsl_sai.c b/sound/soc/fsl/fsl_sai.c index 2147994ab46f..9fadf7e31c5f 100644 --- a/sound/soc/fsl/fsl_sai.c +++ b/sound/soc/fsl/fsl_sai.c | |||
@@ -801,8 +801,8 @@ static int fsl_sai_probe(struct platform_device *pdev) | |||
801 | 801 | ||
802 | sai->pdev = pdev; | 802 | sai->pdev = pdev; |
803 | 803 | ||
804 | if (of_device_is_compatible(pdev->dev.of_node, "fsl,imx6sx-sai") || | 804 | if (of_device_is_compatible(np, "fsl,imx6sx-sai") || |
805 | of_device_is_compatible(pdev->dev.of_node, "fsl,imx6ul-sai")) | 805 | of_device_is_compatible(np, "fsl,imx6ul-sai")) |
806 | sai->sai_on_imx = true; | 806 | sai->sai_on_imx = true; |
807 | 807 | ||
808 | sai->is_lsb_first = of_property_read_bool(np, "lsb-first"); | 808 | sai->is_lsb_first = of_property_read_bool(np, "lsb-first"); |
@@ -883,7 +883,7 @@ static int fsl_sai_probe(struct platform_device *pdev) | |||
883 | } | 883 | } |
884 | 884 | ||
885 | if (of_find_property(np, "fsl,sai-mclk-direction-output", NULL) && | 885 | if (of_find_property(np, "fsl,sai-mclk-direction-output", NULL) && |
886 | of_device_is_compatible(pdev->dev.of_node, "fsl,imx6ul-sai")) { | 886 | of_device_is_compatible(np, "fsl,imx6ul-sai")) { |
887 | gpr = syscon_regmap_lookup_by_compatible("fsl,imx6ul-iomuxc-gpr"); | 887 | gpr = syscon_regmap_lookup_by_compatible("fsl,imx6ul-iomuxc-gpr"); |
888 | if (IS_ERR(gpr)) { | 888 | if (IS_ERR(gpr)) { |
889 | dev_err(&pdev->dev, "cannot find iomuxc registers\n"); | 889 | dev_err(&pdev->dev, "cannot find iomuxc registers\n"); |
diff --git a/sound/soc/fsl/fsl_spdif.c b/sound/soc/fsl/fsl_spdif.c index beec7934a265..1ff467c9598a 100644 --- a/sound/soc/fsl/fsl_spdif.c +++ b/sound/soc/fsl/fsl_spdif.c | |||
@@ -1103,7 +1103,7 @@ static const struct regmap_config fsl_spdif_regmap_config = { | |||
1103 | .readable_reg = fsl_spdif_readable_reg, | 1103 | .readable_reg = fsl_spdif_readable_reg, |
1104 | .volatile_reg = fsl_spdif_volatile_reg, | 1104 | .volatile_reg = fsl_spdif_volatile_reg, |
1105 | .writeable_reg = fsl_spdif_writeable_reg, | 1105 | .writeable_reg = fsl_spdif_writeable_reg, |
1106 | .cache_type = REGCACHE_RBTREE, | 1106 | .cache_type = REGCACHE_FLAT, |
1107 | }; | 1107 | }; |
1108 | 1108 | ||
1109 | static u32 fsl_spdif_txclk_caldiv(struct fsl_spdif_priv *spdif_priv, | 1109 | static u32 fsl_spdif_txclk_caldiv(struct fsl_spdif_priv *spdif_priv, |
diff --git a/sound/soc/fsl/fsl_ssi.c b/sound/soc/fsl/fsl_ssi.c index bedec4a32581..50349437d961 100644 --- a/sound/soc/fsl/fsl_ssi.c +++ b/sound/soc/fsl/fsl_ssi.c | |||
@@ -182,7 +182,7 @@ static const struct regmap_config fsl_ssi_regconfig = { | |||
182 | .volatile_reg = fsl_ssi_volatile_reg, | 182 | .volatile_reg = fsl_ssi_volatile_reg, |
183 | .precious_reg = fsl_ssi_precious_reg, | 183 | .precious_reg = fsl_ssi_precious_reg, |
184 | .writeable_reg = fsl_ssi_writeable_reg, | 184 | .writeable_reg = fsl_ssi_writeable_reg, |
185 | .cache_type = REGCACHE_RBTREE, | 185 | .cache_type = REGCACHE_FLAT, |
186 | }; | 186 | }; |
187 | 187 | ||
188 | struct fsl_ssi_soc_data { | 188 | struct fsl_ssi_soc_data { |
diff --git a/sound/soc/generic/Kconfig b/sound/soc/generic/Kconfig index c01c5dd68601..d023959b8cd6 100644 --- a/sound/soc/generic/Kconfig +++ b/sound/soc/generic/Kconfig | |||
@@ -6,3 +6,11 @@ config SND_SIMPLE_CARD | |||
6 | select SND_SIMPLE_CARD_UTILS | 6 | select SND_SIMPLE_CARD_UTILS |
7 | help | 7 | help |
8 | This option enables generic simple sound card support | 8 | This option enables generic simple sound card support |
9 | |||
10 | config SND_SIMPLE_SCU_CARD | ||
11 | tristate "ASoC Simple SCU sound card support" | ||
12 | depends on OF | ||
13 | select SND_SIMPLE_CARD_UTILS | ||
14 | help | ||
15 | This option enables generic simple SCU sound card support. | ||
16 | It supports DPCM of multi CPU single Codec system. | ||
diff --git a/sound/soc/generic/Makefile b/sound/soc/generic/Makefile index 2d53c8d70705..ee750f3023ba 100644 --- a/sound/soc/generic/Makefile +++ b/sound/soc/generic/Makefile | |||
@@ -1,5 +1,7 @@ | |||
1 | snd-soc-simple-card-utils-objs := simple-card-utils.o | 1 | snd-soc-simple-card-utils-objs := simple-card-utils.o |
2 | snd-soc-simple-card-objs := simple-card.o | 2 | snd-soc-simple-card-objs := simple-card.o |
3 | snd-soc-simple-scu-card-objs := simple-scu-card.o | ||
3 | 4 | ||
4 | obj-$(CONFIG_SND_SIMPLE_CARD_UTILS) += snd-soc-simple-card-utils.o | 5 | obj-$(CONFIG_SND_SIMPLE_CARD_UTILS) += snd-soc-simple-card-utils.o |
5 | obj-$(CONFIG_SND_SIMPLE_CARD) += snd-soc-simple-card.o | 6 | obj-$(CONFIG_SND_SIMPLE_CARD) += snd-soc-simple-card.o |
7 | obj-$(CONFIG_SND_SIMPLE_SCU_CARD) += snd-soc-simple-scu-card.o | ||
diff --git a/sound/soc/generic/simple-card-utils.c b/sound/soc/generic/simple-card-utils.c index 9599de69a880..1cb39309f5d5 100644 --- a/sound/soc/generic/simple-card-utils.c +++ b/sound/soc/generic/simple-card-utils.c | |||
@@ -7,6 +7,7 @@ | |||
7 | * it under the terms of the GNU General Public License version 2 as | 7 | * it under the terms of the GNU General Public License version 2 as |
8 | * published by the Free Software Foundation. | 8 | * published by the Free Software Foundation. |
9 | */ | 9 | */ |
10 | #include <linux/clk.h> | ||
10 | #include <linux/module.h> | 11 | #include <linux/module.h> |
11 | #include <linux/of.h> | 12 | #include <linux/of.h> |
12 | #include <sound/simple_card_utils.h> | 13 | #include <sound/simple_card_utils.h> |
@@ -97,6 +98,146 @@ int asoc_simple_card_parse_card_name(struct snd_soc_card *card, | |||
97 | } | 98 | } |
98 | EXPORT_SYMBOL_GPL(asoc_simple_card_parse_card_name); | 99 | EXPORT_SYMBOL_GPL(asoc_simple_card_parse_card_name); |
99 | 100 | ||
101 | int asoc_simple_card_parse_clk(struct device_node *node, | ||
102 | struct device_node *dai_of_node, | ||
103 | struct asoc_simple_dai *simple_dai) | ||
104 | { | ||
105 | struct clk *clk; | ||
106 | u32 val; | ||
107 | |||
108 | /* | ||
109 | * Parse dai->sysclk come from "clocks = <&xxx>" | ||
110 | * (if system has common clock) | ||
111 | * or "system-clock-frequency = <xxx>" | ||
112 | * or device's module clock. | ||
113 | */ | ||
114 | clk = of_clk_get(node, 0); | ||
115 | if (!IS_ERR(clk)) { | ||
116 | simple_dai->sysclk = clk_get_rate(clk); | ||
117 | simple_dai->clk = clk; | ||
118 | } else if (!of_property_read_u32(node, "system-clock-frequency", &val)) { | ||
119 | simple_dai->sysclk = val; | ||
120 | } else { | ||
121 | clk = of_clk_get(dai_of_node, 0); | ||
122 | if (!IS_ERR(clk)) | ||
123 | simple_dai->sysclk = clk_get_rate(clk); | ||
124 | } | ||
125 | |||
126 | return 0; | ||
127 | } | ||
128 | EXPORT_SYMBOL_GPL(asoc_simple_card_parse_clk); | ||
129 | |||
130 | int asoc_simple_card_parse_dai(struct device_node *node, | ||
131 | struct device_node **dai_of_node, | ||
132 | const char **dai_name, | ||
133 | const char *list_name, | ||
134 | const char *cells_name, | ||
135 | int *is_single_link) | ||
136 | { | ||
137 | struct of_phandle_args args; | ||
138 | int ret; | ||
139 | |||
140 | if (!node) | ||
141 | return 0; | ||
142 | |||
143 | /* | ||
144 | * Get node via "sound-dai = <&phandle port>" | ||
145 | * it will be used as xxx_of_node on soc_bind_dai_link() | ||
146 | */ | ||
147 | ret = of_parse_phandle_with_args(node, list_name, cells_name, 0, &args); | ||
148 | if (ret) | ||
149 | return ret; | ||
150 | |||
151 | /* Get dai->name */ | ||
152 | if (dai_name) { | ||
153 | ret = snd_soc_of_get_dai_name(node, dai_name); | ||
154 | if (ret < 0) | ||
155 | return ret; | ||
156 | } | ||
157 | |||
158 | *dai_of_node = args.np; | ||
159 | |||
160 | if (is_single_link) | ||
161 | *is_single_link = !args.args_count; | ||
162 | |||
163 | return 0; | ||
164 | } | ||
165 | EXPORT_SYMBOL_GPL(asoc_simple_card_parse_dai); | ||
166 | |||
167 | int asoc_simple_card_init_dai(struct snd_soc_dai *dai, | ||
168 | struct asoc_simple_dai *simple_dai) | ||
169 | { | ||
170 | int ret; | ||
171 | |||
172 | if (simple_dai->sysclk) { | ||
173 | ret = snd_soc_dai_set_sysclk(dai, 0, simple_dai->sysclk, 0); | ||
174 | if (ret && ret != -ENOTSUPP) { | ||
175 | dev_err(dai->dev, "simple-card: set_sysclk error\n"); | ||
176 | return ret; | ||
177 | } | ||
178 | } | ||
179 | |||
180 | if (simple_dai->slots) { | ||
181 | ret = snd_soc_dai_set_tdm_slot(dai, | ||
182 | simple_dai->tx_slot_mask, | ||
183 | simple_dai->rx_slot_mask, | ||
184 | simple_dai->slots, | ||
185 | simple_dai->slot_width); | ||
186 | if (ret && ret != -ENOTSUPP) { | ||
187 | dev_err(dai->dev, "simple-card: set_tdm_slot error\n"); | ||
188 | return ret; | ||
189 | } | ||
190 | } | ||
191 | |||
192 | return 0; | ||
193 | } | ||
194 | EXPORT_SYMBOL_GPL(asoc_simple_card_init_dai); | ||
195 | |||
196 | int asoc_simple_card_canonicalize_dailink(struct snd_soc_dai_link *dai_link) | ||
197 | { | ||
198 | if (!dai_link->cpu_dai_name || !dai_link->codec_dai_name) | ||
199 | return -EINVAL; | ||
200 | |||
201 | /* Assumes platform == cpu */ | ||
202 | if (!dai_link->platform_of_node) | ||
203 | dai_link->platform_of_node = dai_link->cpu_of_node; | ||
204 | |||
205 | return 0; | ||
206 | } | ||
207 | EXPORT_SYMBOL_GPL(asoc_simple_card_canonicalize_dailink); | ||
208 | |||
209 | void asoc_simple_card_canonicalize_cpu(struct snd_soc_dai_link *dai_link, | ||
210 | int is_single_links) | ||
211 | { | ||
212 | /* | ||
213 | * In soc_bind_dai_link() will check cpu name after | ||
214 | * of_node matching if dai_link has cpu_dai_name. | ||
215 | * but, it will never match if name was created by | ||
216 | * fmt_single_name() remove cpu_dai_name if cpu_args | ||
217 | * was 0. See: | ||
218 | * fmt_single_name() | ||
219 | * fmt_multiple_name() | ||
220 | */ | ||
221 | if (is_single_links) | ||
222 | dai_link->cpu_dai_name = NULL; | ||
223 | } | ||
224 | EXPORT_SYMBOL_GPL(asoc_simple_card_canonicalize_cpu); | ||
225 | |||
226 | int asoc_simple_card_clean_reference(struct snd_soc_card *card) | ||
227 | { | ||
228 | struct snd_soc_dai_link *dai_link; | ||
229 | int num_links; | ||
230 | |||
231 | for (num_links = 0, dai_link = card->dai_link; | ||
232 | num_links < card->num_links; | ||
233 | num_links++, dai_link++) { | ||
234 | of_node_put(dai_link->cpu_of_node); | ||
235 | of_node_put(dai_link->codec_of_node); | ||
236 | } | ||
237 | return 0; | ||
238 | } | ||
239 | EXPORT_SYMBOL_GPL(asoc_simple_card_clean_reference); | ||
240 | |||
100 | /* Module information */ | 241 | /* Module information */ |
101 | MODULE_AUTHOR("Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>"); | 242 | MODULE_AUTHOR("Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>"); |
102 | MODULE_DESCRIPTION("ALSA SoC Simple Card Utils"); | 243 | MODULE_DESCRIPTION("ALSA SoC Simple Card Utils"); |
diff --git a/sound/soc/generic/simple-card.c b/sound/soc/generic/simple-card.c index 43295f024982..f608f8d23f3d 100644 --- a/sound/soc/generic/simple-card.c +++ b/sound/soc/generic/simple-card.c | |||
@@ -37,13 +37,15 @@ struct simple_card_data { | |||
37 | unsigned int mclk_fs; | 37 | unsigned int mclk_fs; |
38 | struct asoc_simple_jack hp_jack; | 38 | struct asoc_simple_jack hp_jack; |
39 | struct asoc_simple_jack mic_jack; | 39 | struct asoc_simple_jack mic_jack; |
40 | struct snd_soc_dai_link dai_link[]; /* dynamically allocated */ | 40 | struct snd_soc_dai_link *dai_link; |
41 | }; | 41 | }; |
42 | 42 | ||
43 | #define simple_priv_to_dev(priv) ((priv)->snd_card.dev) | 43 | #define simple_priv_to_dev(priv) ((priv)->snd_card.dev) |
44 | #define simple_priv_to_link(priv, i) ((priv)->snd_card.dai_link + i) | 44 | #define simple_priv_to_link(priv, i) ((priv)->snd_card.dai_link + (i)) |
45 | #define simple_priv_to_props(priv, i) ((priv)->dai_props + i) | 45 | #define simple_priv_to_props(priv, i) ((priv)->dai_props + (i)) |
46 | 46 | ||
47 | #define DAI "sound-dai" | ||
48 | #define CELL "#sound-dai-cells" | ||
47 | #define PREFIX "simple-audio-card," | 49 | #define PREFIX "simple-audio-card," |
48 | 50 | ||
49 | #define asoc_simple_card_init_hp(card, sjack, prefix)\ | 51 | #define asoc_simple_card_init_hp(card, sjack, prefix)\ |
@@ -112,13 +114,13 @@ static int asoc_simple_card_startup(struct snd_pcm_substream *substream) | |||
112 | struct snd_soc_pcm_runtime *rtd = substream->private_data; | 114 | struct snd_soc_pcm_runtime *rtd = substream->private_data; |
113 | struct simple_card_data *priv = snd_soc_card_get_drvdata(rtd->card); | 115 | struct simple_card_data *priv = snd_soc_card_get_drvdata(rtd->card); |
114 | struct simple_dai_props *dai_props = | 116 | struct simple_dai_props *dai_props = |
115 | &priv->dai_props[rtd->num]; | 117 | simple_priv_to_props(priv, rtd->num); |
116 | int ret; | 118 | int ret; |
117 | 119 | ||
118 | ret = clk_prepare_enable(dai_props->cpu_dai.clk); | 120 | ret = clk_prepare_enable(dai_props->cpu_dai.clk); |
119 | if (ret) | 121 | if (ret) |
120 | return ret; | 122 | return ret; |
121 | 123 | ||
122 | ret = clk_prepare_enable(dai_props->codec_dai.clk); | 124 | ret = clk_prepare_enable(dai_props->codec_dai.clk); |
123 | if (ret) | 125 | if (ret) |
124 | clk_disable_unprepare(dai_props->cpu_dai.clk); | 126 | clk_disable_unprepare(dai_props->cpu_dai.clk); |
@@ -131,7 +133,7 @@ static void asoc_simple_card_shutdown(struct snd_pcm_substream *substream) | |||
131 | struct snd_soc_pcm_runtime *rtd = substream->private_data; | 133 | struct snd_soc_pcm_runtime *rtd = substream->private_data; |
132 | struct simple_card_data *priv = snd_soc_card_get_drvdata(rtd->card); | 134 | struct simple_card_data *priv = snd_soc_card_get_drvdata(rtd->card); |
133 | struct simple_dai_props *dai_props = | 135 | struct simple_dai_props *dai_props = |
134 | &priv->dai_props[rtd->num]; | 136 | simple_priv_to_props(priv, rtd->num); |
135 | 137 | ||
136 | clk_disable_unprepare(dai_props->cpu_dai.clk); | 138 | clk_disable_unprepare(dai_props->cpu_dai.clk); |
137 | 139 | ||
@@ -145,7 +147,8 @@ static int asoc_simple_card_hw_params(struct snd_pcm_substream *substream, | |||
145 | struct snd_soc_dai *codec_dai = rtd->codec_dai; | 147 | struct snd_soc_dai *codec_dai = rtd->codec_dai; |
146 | struct snd_soc_dai *cpu_dai = rtd->cpu_dai; | 148 | struct snd_soc_dai *cpu_dai = rtd->cpu_dai; |
147 | struct simple_card_data *priv = snd_soc_card_get_drvdata(rtd->card); | 149 | struct simple_card_data *priv = snd_soc_card_get_drvdata(rtd->card); |
148 | struct simple_dai_props *dai_props = &priv->dai_props[rtd->num]; | 150 | struct simple_dai_props *dai_props = |
151 | simple_priv_to_props(priv, rtd->num); | ||
149 | unsigned int mclk, mclk_fs = 0; | 152 | unsigned int mclk, mclk_fs = 0; |
150 | int ret = 0; | 153 | int ret = 0; |
151 | 154 | ||
@@ -177,51 +180,20 @@ static struct snd_soc_ops asoc_simple_card_ops = { | |||
177 | .hw_params = asoc_simple_card_hw_params, | 180 | .hw_params = asoc_simple_card_hw_params, |
178 | }; | 181 | }; |
179 | 182 | ||
180 | static int __asoc_simple_card_dai_init(struct snd_soc_dai *dai, | ||
181 | struct asoc_simple_dai *set) | ||
182 | { | ||
183 | int ret; | ||
184 | |||
185 | if (set->sysclk) { | ||
186 | ret = snd_soc_dai_set_sysclk(dai, 0, set->sysclk, 0); | ||
187 | if (ret && ret != -ENOTSUPP) { | ||
188 | dev_err(dai->dev, "simple-card: set_sysclk error\n"); | ||
189 | goto err; | ||
190 | } | ||
191 | } | ||
192 | |||
193 | if (set->slots) { | ||
194 | ret = snd_soc_dai_set_tdm_slot(dai, | ||
195 | set->tx_slot_mask, | ||
196 | set->rx_slot_mask, | ||
197 | set->slots, | ||
198 | set->slot_width); | ||
199 | if (ret && ret != -ENOTSUPP) { | ||
200 | dev_err(dai->dev, "simple-card: set_tdm_slot error\n"); | ||
201 | goto err; | ||
202 | } | ||
203 | } | ||
204 | |||
205 | ret = 0; | ||
206 | |||
207 | err: | ||
208 | return ret; | ||
209 | } | ||
210 | |||
211 | static int asoc_simple_card_dai_init(struct snd_soc_pcm_runtime *rtd) | 183 | static int asoc_simple_card_dai_init(struct snd_soc_pcm_runtime *rtd) |
212 | { | 184 | { |
213 | struct simple_card_data *priv = snd_soc_card_get_drvdata(rtd->card); | 185 | struct simple_card_data *priv = snd_soc_card_get_drvdata(rtd->card); |
214 | struct snd_soc_dai *codec = rtd->codec_dai; | 186 | struct snd_soc_dai *codec = rtd->codec_dai; |
215 | struct snd_soc_dai *cpu = rtd->cpu_dai; | 187 | struct snd_soc_dai *cpu = rtd->cpu_dai; |
216 | struct simple_dai_props *dai_props; | 188 | struct simple_dai_props *dai_props = |
189 | simple_priv_to_props(priv, rtd->num); | ||
217 | int ret; | 190 | int ret; |
218 | 191 | ||
219 | dai_props = &priv->dai_props[rtd->num]; | 192 | ret = asoc_simple_card_init_dai(codec, &dai_props->codec_dai); |
220 | ret = __asoc_simple_card_dai_init(codec, &dai_props->codec_dai); | ||
221 | if (ret < 0) | 193 | if (ret < 0) |
222 | return ret; | 194 | return ret; |
223 | 195 | ||
224 | ret = __asoc_simple_card_dai_init(cpu, &dai_props->cpu_dai); | 196 | ret = asoc_simple_card_init_dai(cpu, &dai_props->cpu_dai); |
225 | if (ret < 0) | 197 | if (ret < 0) |
226 | return ret; | 198 | return ret; |
227 | 199 | ||
@@ -236,78 +208,6 @@ static int asoc_simple_card_dai_init(struct snd_soc_pcm_runtime *rtd) | |||
236 | return 0; | 208 | return 0; |
237 | } | 209 | } |
238 | 210 | ||
239 | static int | ||
240 | asoc_simple_card_sub_parse_of(struct device_node *np, | ||
241 | struct asoc_simple_dai *dai, | ||
242 | struct device_node **p_node, | ||
243 | const char **name, | ||
244 | int *args_count) | ||
245 | { | ||
246 | struct of_phandle_args args; | ||
247 | struct clk *clk; | ||
248 | u32 val; | ||
249 | int ret; | ||
250 | |||
251 | if (!np) | ||
252 | return 0; | ||
253 | |||
254 | /* | ||
255 | * Get node via "sound-dai = <&phandle port>" | ||
256 | * it will be used as xxx_of_node on soc_bind_dai_link() | ||
257 | */ | ||
258 | ret = of_parse_phandle_with_args(np, "sound-dai", | ||
259 | "#sound-dai-cells", 0, &args); | ||
260 | if (ret) | ||
261 | return ret; | ||
262 | |||
263 | *p_node = args.np; | ||
264 | |||
265 | if (args_count) | ||
266 | *args_count = args.args_count; | ||
267 | |||
268 | /* Get dai->name */ | ||
269 | if (name) { | ||
270 | ret = snd_soc_of_get_dai_name(np, name); | ||
271 | if (ret < 0) | ||
272 | return ret; | ||
273 | } | ||
274 | |||
275 | if (!dai) | ||
276 | return 0; | ||
277 | |||
278 | /* Parse TDM slot */ | ||
279 | ret = snd_soc_of_parse_tdm_slot(np, &dai->tx_slot_mask, | ||
280 | &dai->rx_slot_mask, | ||
281 | &dai->slots, &dai->slot_width); | ||
282 | if (ret) | ||
283 | return ret; | ||
284 | |||
285 | /* | ||
286 | * Parse dai->sysclk come from "clocks = <&xxx>" | ||
287 | * (if system has common clock) | ||
288 | * or "system-clock-frequency = <xxx>" | ||
289 | * or device's module clock. | ||
290 | */ | ||
291 | if (of_property_read_bool(np, "clocks")) { | ||
292 | clk = of_clk_get(np, 0); | ||
293 | if (IS_ERR(clk)) { | ||
294 | ret = PTR_ERR(clk); | ||
295 | return ret; | ||
296 | } | ||
297 | |||
298 | dai->sysclk = clk_get_rate(clk); | ||
299 | dai->clk = clk; | ||
300 | } else if (!of_property_read_u32(np, "system-clock-frequency", &val)) { | ||
301 | dai->sysclk = val; | ||
302 | } else { | ||
303 | clk = of_clk_get(args.np, 0); | ||
304 | if (!IS_ERR(clk)) | ||
305 | dai->sysclk = clk_get_rate(clk); | ||
306 | } | ||
307 | |||
308 | return 0; | ||
309 | } | ||
310 | |||
311 | static int asoc_simple_card_dai_link_of(struct device_node *node, | 211 | static int asoc_simple_card_dai_link_of(struct device_node *node, |
312 | struct simple_card_data *priv, | 212 | struct simple_card_data *priv, |
313 | int idx, | 213 | int idx, |
@@ -316,13 +216,14 @@ static int asoc_simple_card_dai_link_of(struct device_node *node, | |||
316 | struct device *dev = simple_priv_to_dev(priv); | 216 | struct device *dev = simple_priv_to_dev(priv); |
317 | struct snd_soc_dai_link *dai_link = simple_priv_to_link(priv, idx); | 217 | struct snd_soc_dai_link *dai_link = simple_priv_to_link(priv, idx); |
318 | struct simple_dai_props *dai_props = simple_priv_to_props(priv, idx); | 218 | struct simple_dai_props *dai_props = simple_priv_to_props(priv, idx); |
219 | struct asoc_simple_dai *cpu_dai = &dai_props->cpu_dai; | ||
220 | struct asoc_simple_dai *codec_dai = &dai_props->codec_dai; | ||
319 | struct device_node *cpu = NULL; | 221 | struct device_node *cpu = NULL; |
320 | struct device_node *plat = NULL; | 222 | struct device_node *plat = NULL; |
321 | struct device_node *codec = NULL; | 223 | struct device_node *codec = NULL; |
322 | char prop[128]; | 224 | char prop[128]; |
323 | char *prefix = ""; | 225 | char *prefix = ""; |
324 | int ret, cpu_args; | 226 | int ret, single_cpu; |
325 | u32 val; | ||
326 | 227 | ||
327 | /* For single DAI link & old style of DT node */ | 228 | /* For single DAI link & old style of DT node */ |
328 | if (is_top_level_node) | 229 | if (is_top_level_node) |
@@ -348,36 +249,46 @@ static int asoc_simple_card_dai_link_of(struct device_node *node, | |||
348 | if (ret < 0) | 249 | if (ret < 0) |
349 | goto dai_link_of_err; | 250 | goto dai_link_of_err; |
350 | 251 | ||
351 | if (!of_property_read_u32(node, "mclk-fs", &val)) | 252 | of_property_read_u32(node, "mclk-fs", &dai_props->mclk_fs); |
352 | dai_props->mclk_fs = val; | ||
353 | 253 | ||
354 | ret = asoc_simple_card_sub_parse_of(cpu, &dai_props->cpu_dai, | 254 | ret = asoc_simple_card_parse_cpu(cpu, dai_link, |
355 | &dai_link->cpu_of_node, | 255 | DAI, CELL, &single_cpu); |
356 | &dai_link->cpu_dai_name, | ||
357 | &cpu_args); | ||
358 | if (ret < 0) | 256 | if (ret < 0) |
359 | goto dai_link_of_err; | 257 | goto dai_link_of_err; |
360 | 258 | ||
361 | ret = asoc_simple_card_sub_parse_of(codec, &dai_props->codec_dai, | 259 | ret = asoc_simple_card_parse_codec(codec, dai_link, DAI, CELL); |
362 | &dai_link->codec_of_node, | ||
363 | &dai_link->codec_dai_name, NULL); | ||
364 | if (ret < 0) | 260 | if (ret < 0) |
365 | goto dai_link_of_err; | 261 | goto dai_link_of_err; |
366 | 262 | ||
367 | ret = asoc_simple_card_sub_parse_of(plat, NULL, | 263 | ret = asoc_simple_card_parse_platform(plat, dai_link, DAI, CELL); |
368 | &dai_link->platform_of_node, | ||
369 | NULL, NULL); | ||
370 | if (ret < 0) | 264 | if (ret < 0) |
371 | goto dai_link_of_err; | 265 | goto dai_link_of_err; |
372 | 266 | ||
373 | if (!dai_link->cpu_dai_name || !dai_link->codec_dai_name) { | 267 | ret = snd_soc_of_parse_tdm_slot(cpu, &cpu_dai->tx_slot_mask, |
374 | ret = -EINVAL; | 268 | &cpu_dai->rx_slot_mask, |
269 | &cpu_dai->slots, | ||
270 | &cpu_dai->slot_width); | ||
271 | if (ret < 0) | ||
272 | goto dai_link_of_err; | ||
273 | |||
274 | ret = snd_soc_of_parse_tdm_slot(codec, &codec_dai->tx_slot_mask, | ||
275 | &codec_dai->rx_slot_mask, | ||
276 | &codec_dai->slots, | ||
277 | &codec_dai->slot_width); | ||
278 | if (ret < 0) | ||
279 | goto dai_link_of_err; | ||
280 | |||
281 | ret = asoc_simple_card_parse_clk_cpu(cpu, dai_link, cpu_dai); | ||
282 | if (ret < 0) | ||
375 | goto dai_link_of_err; | 283 | goto dai_link_of_err; |
376 | } | ||
377 | 284 | ||
378 | /* Assumes platform == cpu */ | 285 | ret = asoc_simple_card_parse_clk_codec(codec, dai_link, codec_dai); |
379 | if (!dai_link->platform_of_node) | 286 | if (ret < 0) |
380 | dai_link->platform_of_node = dai_link->cpu_of_node; | 287 | goto dai_link_of_err; |
288 | |||
289 | ret = asoc_simple_card_canonicalize_dailink(dai_link); | ||
290 | if (ret < 0) | ||
291 | goto dai_link_of_err; | ||
381 | 292 | ||
382 | ret = asoc_simple_card_set_dailink_name(dev, dai_link, | 293 | ret = asoc_simple_card_set_dailink_name(dev, dai_link, |
383 | "%s-%s", | 294 | "%s-%s", |
@@ -398,17 +309,7 @@ static int asoc_simple_card_dai_link_of(struct device_node *node, | |||
398 | dai_link->codec_dai_name, | 309 | dai_link->codec_dai_name, |
399 | dai_props->codec_dai.sysclk); | 310 | dai_props->codec_dai.sysclk); |
400 | 311 | ||
401 | /* | 312 | asoc_simple_card_canonicalize_cpu(dai_link, single_cpu); |
402 | * In soc_bind_dai_link() will check cpu name after | ||
403 | * of_node matching if dai_link has cpu_dai_name. | ||
404 | * but, it will never match if name was created by | ||
405 | * fmt_single_name() remove cpu_dai_name if cpu_args | ||
406 | * was 0. See: | ||
407 | * fmt_single_name() | ||
408 | * fmt_multiple_name() | ||
409 | */ | ||
410 | if (!cpu_args) | ||
411 | dai_link->cpu_dai_name = NULL; | ||
412 | 313 | ||
413 | dai_link_of_err: | 314 | dai_link_of_err: |
414 | of_node_put(cpu); | 315 | of_node_put(cpu); |
@@ -417,22 +318,54 @@ dai_link_of_err: | |||
417 | return ret; | 318 | return ret; |
418 | } | 319 | } |
419 | 320 | ||
321 | static int asoc_simple_card_parse_aux_devs(struct device_node *node, | ||
322 | struct simple_card_data *priv) | ||
323 | { | ||
324 | struct device *dev = simple_priv_to_dev(priv); | ||
325 | struct device_node *aux_node; | ||
326 | int i, n, len; | ||
327 | |||
328 | if (!of_find_property(node, PREFIX "aux-devs", &len)) | ||
329 | return 0; /* Ok to have no aux-devs */ | ||
330 | |||
331 | n = len / sizeof(__be32); | ||
332 | if (n <= 0) | ||
333 | return -EINVAL; | ||
334 | |||
335 | priv->snd_card.aux_dev = devm_kzalloc(dev, | ||
336 | n * sizeof(*priv->snd_card.aux_dev), GFP_KERNEL); | ||
337 | if (!priv->snd_card.aux_dev) | ||
338 | return -ENOMEM; | ||
339 | |||
340 | for (i = 0; i < n; i++) { | ||
341 | aux_node = of_parse_phandle(node, PREFIX "aux-devs", i); | ||
342 | if (!aux_node) | ||
343 | return -EINVAL; | ||
344 | priv->snd_card.aux_dev[i].codec_of_node = aux_node; | ||
345 | } | ||
346 | |||
347 | priv->snd_card.num_aux_devs = n; | ||
348 | return 0; | ||
349 | } | ||
350 | |||
420 | static int asoc_simple_card_parse_of(struct device_node *node, | 351 | static int asoc_simple_card_parse_of(struct device_node *node, |
421 | struct simple_card_data *priv) | 352 | struct simple_card_data *priv) |
422 | { | 353 | { |
423 | struct device *dev = simple_priv_to_dev(priv); | 354 | struct device *dev = simple_priv_to_dev(priv); |
424 | u32 val; | 355 | struct device_node *dai_link; |
425 | int ret; | 356 | int ret; |
426 | 357 | ||
427 | if (!node) | 358 | if (!node) |
428 | return -EINVAL; | 359 | return -EINVAL; |
429 | 360 | ||
361 | dai_link = of_get_child_by_name(node, PREFIX "dai-link"); | ||
362 | |||
430 | /* The off-codec widgets */ | 363 | /* The off-codec widgets */ |
431 | if (of_property_read_bool(node, PREFIX "widgets")) { | 364 | if (of_property_read_bool(node, PREFIX "widgets")) { |
432 | ret = snd_soc_of_parse_audio_simple_widgets(&priv->snd_card, | 365 | ret = snd_soc_of_parse_audio_simple_widgets(&priv->snd_card, |
433 | PREFIX "widgets"); | 366 | PREFIX "widgets"); |
434 | if (ret) | 367 | if (ret) |
435 | return ret; | 368 | goto card_parse_end; |
436 | } | 369 | } |
437 | 370 | ||
438 | /* DAPM routes */ | 371 | /* DAPM routes */ |
@@ -440,16 +373,14 @@ static int asoc_simple_card_parse_of(struct device_node *node, | |||
440 | ret = snd_soc_of_parse_audio_routing(&priv->snd_card, | 373 | ret = snd_soc_of_parse_audio_routing(&priv->snd_card, |
441 | PREFIX "routing"); | 374 | PREFIX "routing"); |
442 | if (ret) | 375 | if (ret) |
443 | return ret; | 376 | goto card_parse_end; |
444 | } | 377 | } |
445 | 378 | ||
446 | /* Factor to mclk, used in hw_params() */ | 379 | /* Factor to mclk, used in hw_params() */ |
447 | ret = of_property_read_u32(node, PREFIX "mclk-fs", &val); | 380 | of_property_read_u32(node, PREFIX "mclk-fs", &priv->mclk_fs); |
448 | if (ret == 0) | ||
449 | priv->mclk_fs = val; | ||
450 | 381 | ||
451 | /* Single/Muti DAI link(s) & New style of DT node */ | 382 | /* Single/Muti DAI link(s) & New style of DT node */ |
452 | if (of_get_child_by_name(node, PREFIX "dai-link")) { | 383 | if (dai_link) { |
453 | struct device_node *np = NULL; | 384 | struct device_node *np = NULL; |
454 | int i = 0; | 385 | int i = 0; |
455 | 386 | ||
@@ -459,7 +390,7 @@ static int asoc_simple_card_parse_of(struct device_node *node, | |||
459 | i, false); | 390 | i, false); |
460 | if (ret < 0) { | 391 | if (ret < 0) { |
461 | of_node_put(np); | 392 | of_node_put(np); |
462 | return ret; | 393 | goto card_parse_end; |
463 | } | 394 | } |
464 | i++; | 395 | i++; |
465 | } | 396 | } |
@@ -467,66 +398,55 @@ static int asoc_simple_card_parse_of(struct device_node *node, | |||
467 | /* For single DAI link & old style of DT node */ | 398 | /* For single DAI link & old style of DT node */ |
468 | ret = asoc_simple_card_dai_link_of(node, priv, 0, true); | 399 | ret = asoc_simple_card_dai_link_of(node, priv, 0, true); |
469 | if (ret < 0) | 400 | if (ret < 0) |
470 | return ret; | 401 | goto card_parse_end; |
471 | } | 402 | } |
472 | 403 | ||
473 | ret = asoc_simple_card_parse_card_name(&priv->snd_card, PREFIX); | 404 | ret = asoc_simple_card_parse_card_name(&priv->snd_card, PREFIX); |
474 | if (ret) | 405 | if (ret < 0) |
475 | return ret; | 406 | goto card_parse_end; |
476 | 407 | ||
477 | return 0; | 408 | ret = asoc_simple_card_parse_aux_devs(node, priv); |
478 | } | ||
479 | 409 | ||
480 | /* Decrease the reference count of the device nodes */ | 410 | card_parse_end: |
481 | static int asoc_simple_card_unref(struct snd_soc_card *card) | 411 | of_node_put(dai_link); |
482 | { | ||
483 | struct snd_soc_dai_link *dai_link; | ||
484 | int num_links; | ||
485 | 412 | ||
486 | for (num_links = 0, dai_link = card->dai_link; | 413 | return ret; |
487 | num_links < card->num_links; | ||
488 | num_links++, dai_link++) { | ||
489 | of_node_put(dai_link->cpu_of_node); | ||
490 | of_node_put(dai_link->codec_of_node); | ||
491 | } | ||
492 | return 0; | ||
493 | } | 414 | } |
494 | 415 | ||
495 | static int asoc_simple_card_probe(struct platform_device *pdev) | 416 | static int asoc_simple_card_probe(struct platform_device *pdev) |
496 | { | 417 | { |
497 | struct simple_card_data *priv; | 418 | struct simple_card_data *priv; |
498 | struct snd_soc_dai_link *dai_link; | 419 | struct snd_soc_dai_link *dai_link; |
420 | struct simple_dai_props *dai_props; | ||
499 | struct device_node *np = pdev->dev.of_node; | 421 | struct device_node *np = pdev->dev.of_node; |
500 | struct device *dev = &pdev->dev; | 422 | struct device *dev = &pdev->dev; |
501 | int num_links, ret; | 423 | int num, ret; |
502 | 424 | ||
503 | /* Get the number of DAI links */ | 425 | /* Get the number of DAI links */ |
504 | if (np && of_get_child_by_name(np, PREFIX "dai-link")) | 426 | if (np && of_get_child_by_name(np, PREFIX "dai-link")) |
505 | num_links = of_get_child_count(np); | 427 | num = of_get_child_count(np); |
506 | else | 428 | else |
507 | num_links = 1; | 429 | num = 1; |
508 | 430 | ||
509 | /* Allocate the private data and the DAI link array */ | 431 | /* Allocate the private data and the DAI link array */ |
510 | priv = devm_kzalloc(dev, | 432 | priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); |
511 | sizeof(*priv) + sizeof(*dai_link) * num_links, | ||
512 | GFP_KERNEL); | ||
513 | if (!priv) | 433 | if (!priv) |
514 | return -ENOMEM; | 434 | return -ENOMEM; |
515 | 435 | ||
516 | /* Init snd_soc_card */ | 436 | dai_props = devm_kzalloc(dev, sizeof(*dai_props) * num, GFP_KERNEL); |
517 | priv->snd_card.owner = THIS_MODULE; | 437 | dai_link = devm_kzalloc(dev, sizeof(*dai_link) * num, GFP_KERNEL); |
518 | priv->snd_card.dev = dev; | 438 | if (!dai_props || !dai_link) |
519 | dai_link = priv->dai_link; | ||
520 | priv->snd_card.dai_link = dai_link; | ||
521 | priv->snd_card.num_links = num_links; | ||
522 | |||
523 | /* Get room for the other properties */ | ||
524 | priv->dai_props = devm_kzalloc(dev, | ||
525 | sizeof(*priv->dai_props) * num_links, | ||
526 | GFP_KERNEL); | ||
527 | if (!priv->dai_props) | ||
528 | return -ENOMEM; | 439 | return -ENOMEM; |
529 | 440 | ||
441 | priv->dai_props = dai_props; | ||
442 | priv->dai_link = dai_link; | ||
443 | |||
444 | /* Init snd_soc_card */ | ||
445 | priv->snd_card.owner = THIS_MODULE; | ||
446 | priv->snd_card.dev = dev; | ||
447 | priv->snd_card.dai_link = priv->dai_link; | ||
448 | priv->snd_card.num_links = num; | ||
449 | |||
530 | if (np && of_device_is_available(np)) { | 450 | if (np && of_device_is_available(np)) { |
531 | 451 | ||
532 | ret = asoc_simple_card_parse_of(np, priv); | 452 | ret = asoc_simple_card_parse_of(np, priv); |
@@ -567,7 +487,6 @@ static int asoc_simple_card_probe(struct platform_device *pdev) | |||
567 | sizeof(priv->dai_props->cpu_dai)); | 487 | sizeof(priv->dai_props->cpu_dai)); |
568 | memcpy(&priv->dai_props->codec_dai, &cinfo->codec_dai, | 488 | memcpy(&priv->dai_props->codec_dai, &cinfo->codec_dai, |
569 | sizeof(priv->dai_props->codec_dai)); | 489 | sizeof(priv->dai_props->codec_dai)); |
570 | |||
571 | } | 490 | } |
572 | 491 | ||
573 | snd_soc_card_set_drvdata(&priv->snd_card, priv); | 492 | snd_soc_card_set_drvdata(&priv->snd_card, priv); |
@@ -575,9 +494,9 @@ static int asoc_simple_card_probe(struct platform_device *pdev) | |||
575 | ret = devm_snd_soc_register_card(&pdev->dev, &priv->snd_card); | 494 | ret = devm_snd_soc_register_card(&pdev->dev, &priv->snd_card); |
576 | if (ret >= 0) | 495 | if (ret >= 0) |
577 | return ret; | 496 | return ret; |
578 | |||
579 | err: | 497 | err: |
580 | asoc_simple_card_unref(&priv->snd_card); | 498 | asoc_simple_card_clean_reference(&priv->snd_card); |
499 | |||
581 | return ret; | 500 | return ret; |
582 | } | 501 | } |
583 | 502 | ||
@@ -589,7 +508,7 @@ static int asoc_simple_card_remove(struct platform_device *pdev) | |||
589 | asoc_simple_card_remove_jack(&priv->hp_jack); | 508 | asoc_simple_card_remove_jack(&priv->hp_jack); |
590 | asoc_simple_card_remove_jack(&priv->mic_jack); | 509 | asoc_simple_card_remove_jack(&priv->mic_jack); |
591 | 510 | ||
592 | return asoc_simple_card_unref(card); | 511 | return asoc_simple_card_clean_reference(card); |
593 | } | 512 | } |
594 | 513 | ||
595 | static const struct of_device_id asoc_simple_of_match[] = { | 514 | static const struct of_device_id asoc_simple_of_match[] = { |
@@ -611,6 +530,6 @@ static struct platform_driver asoc_simple_card = { | |||
611 | module_platform_driver(asoc_simple_card); | 530 | module_platform_driver(asoc_simple_card); |
612 | 531 | ||
613 | MODULE_ALIAS("platform:asoc-simple-card"); | 532 | MODULE_ALIAS("platform:asoc-simple-card"); |
614 | MODULE_LICENSE("GPL"); | 533 | MODULE_LICENSE("GPL v2"); |
615 | MODULE_DESCRIPTION("ASoC Simple Sound Card"); | 534 | MODULE_DESCRIPTION("ASoC Simple Sound Card"); |
616 | MODULE_AUTHOR("Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>"); | 535 | MODULE_AUTHOR("Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>"); |
diff --git a/sound/soc/generic/simple-scu-card.c b/sound/soc/generic/simple-scu-card.c new file mode 100644 index 000000000000..b9973a56bcb0 --- /dev/null +++ b/sound/soc/generic/simple-scu-card.c | |||
@@ -0,0 +1,345 @@ | |||
1 | /* | ||
2 | * ASoC simple SCU sound card support | ||
3 | * | ||
4 | * Copyright (C) 2015 Renesas Solutions Corp. | ||
5 | * Kuninori Morimoto <kuninori.morimoto.gx@renesas.com> | ||
6 | * | ||
7 | * based on ${LINUX}/sound/soc/generic/simple-card.c | ||
8 | * | ||
9 | * This program is free software; you can redistribute it and/or modify | ||
10 | * it under the terms of the GNU General Public License version 2 as | ||
11 | * published by the Free Software Foundation. | ||
12 | */ | ||
13 | #include <linux/clk.h> | ||
14 | #include <linux/device.h> | ||
15 | #include <linux/module.h> | ||
16 | #include <linux/of.h> | ||
17 | #include <linux/of_device.h> | ||
18 | #include <linux/platform_device.h> | ||
19 | #include <linux/string.h> | ||
20 | #include <sound/jack.h> | ||
21 | #include <sound/soc.h> | ||
22 | #include <sound/soc-dai.h> | ||
23 | #include <sound/simple_card_utils.h> | ||
24 | |||
25 | struct asoc_simple_card_priv { | ||
26 | struct snd_soc_card snd_card; | ||
27 | struct snd_soc_codec_conf codec_conf; | ||
28 | struct asoc_simple_dai *dai_props; | ||
29 | struct snd_soc_dai_link *dai_link; | ||
30 | u32 convert_rate; | ||
31 | u32 convert_channels; | ||
32 | }; | ||
33 | |||
34 | #define simple_priv_to_dev(priv) ((priv)->snd_card.dev) | ||
35 | #define simple_priv_to_link(priv, i) ((priv)->snd_card.dai_link + (i)) | ||
36 | #define simple_priv_to_props(priv, i) ((priv)->dai_props + (i)) | ||
37 | |||
38 | #define DAI "sound-dai" | ||
39 | #define CELL "#sound-dai-cells" | ||
40 | #define PREFIX "simple-audio-card," | ||
41 | |||
42 | static int asoc_simple_card_startup(struct snd_pcm_substream *substream) | ||
43 | { | ||
44 | struct snd_soc_pcm_runtime *rtd = substream->private_data; | ||
45 | struct asoc_simple_card_priv *priv = snd_soc_card_get_drvdata(rtd->card); | ||
46 | struct asoc_simple_dai *dai_props = | ||
47 | simple_priv_to_props(priv, rtd->num); | ||
48 | |||
49 | return clk_prepare_enable(dai_props->clk); | ||
50 | } | ||
51 | |||
52 | static void asoc_simple_card_shutdown(struct snd_pcm_substream *substream) | ||
53 | { | ||
54 | struct snd_soc_pcm_runtime *rtd = substream->private_data; | ||
55 | struct asoc_simple_card_priv *priv = snd_soc_card_get_drvdata(rtd->card); | ||
56 | struct asoc_simple_dai *dai_props = | ||
57 | simple_priv_to_props(priv, rtd->num); | ||
58 | |||
59 | clk_disable_unprepare(dai_props->clk); | ||
60 | } | ||
61 | |||
62 | static struct snd_soc_ops asoc_simple_card_ops = { | ||
63 | .startup = asoc_simple_card_startup, | ||
64 | .shutdown = asoc_simple_card_shutdown, | ||
65 | }; | ||
66 | |||
67 | static int asoc_simple_card_dai_init(struct snd_soc_pcm_runtime *rtd) | ||
68 | { | ||
69 | struct asoc_simple_card_priv *priv = snd_soc_card_get_drvdata(rtd->card); | ||
70 | struct snd_soc_dai *dai; | ||
71 | struct snd_soc_dai_link *dai_link; | ||
72 | struct asoc_simple_dai *dai_props; | ||
73 | int num = rtd->num; | ||
74 | |||
75 | dai_link = simple_priv_to_link(priv, num); | ||
76 | dai_props = simple_priv_to_props(priv, num); | ||
77 | dai = dai_link->dynamic ? | ||
78 | rtd->cpu_dai : | ||
79 | rtd->codec_dai; | ||
80 | |||
81 | return asoc_simple_card_init_dai(dai, dai_props); | ||
82 | } | ||
83 | |||
84 | static int asoc_simple_card_be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd, | ||
85 | struct snd_pcm_hw_params *params) | ||
86 | { | ||
87 | struct asoc_simple_card_priv *priv = snd_soc_card_get_drvdata(rtd->card); | ||
88 | struct snd_interval *rate = hw_param_interval(params, | ||
89 | SNDRV_PCM_HW_PARAM_RATE); | ||
90 | struct snd_interval *channels = hw_param_interval(params, | ||
91 | SNDRV_PCM_HW_PARAM_CHANNELS); | ||
92 | |||
93 | if (priv->convert_rate) | ||
94 | rate->min = | ||
95 | rate->max = priv->convert_rate; | ||
96 | |||
97 | if (priv->convert_channels) | ||
98 | channels->min = | ||
99 | channels->max = priv->convert_channels; | ||
100 | |||
101 | return 0; | ||
102 | } | ||
103 | |||
104 | static int asoc_simple_card_parse_links(struct device_node *np, | ||
105 | struct asoc_simple_card_priv *priv, | ||
106 | unsigned int daifmt, | ||
107 | int idx, bool is_fe) | ||
108 | { | ||
109 | struct device *dev = simple_priv_to_dev(priv); | ||
110 | struct snd_soc_dai_link *dai_link = simple_priv_to_link(priv, idx); | ||
111 | struct asoc_simple_dai *dai_props = simple_priv_to_props(priv, idx); | ||
112 | int ret; | ||
113 | |||
114 | if (is_fe) { | ||
115 | int is_single_links = 0; | ||
116 | |||
117 | /* BE is dummy */ | ||
118 | dai_link->codec_of_node = NULL; | ||
119 | dai_link->codec_dai_name = "snd-soc-dummy-dai"; | ||
120 | dai_link->codec_name = "snd-soc-dummy"; | ||
121 | |||
122 | /* FE settings */ | ||
123 | dai_link->dynamic = 1; | ||
124 | dai_link->dpcm_merged_format = 1; | ||
125 | |||
126 | ret = asoc_simple_card_parse_cpu(np, dai_link, DAI, CELL, | ||
127 | &is_single_links); | ||
128 | if (ret) | ||
129 | return ret; | ||
130 | |||
131 | ret = asoc_simple_card_parse_clk_cpu(np, dai_link, dai_props); | ||
132 | if (ret < 0) | ||
133 | return ret; | ||
134 | |||
135 | ret = asoc_simple_card_set_dailink_name(dev, dai_link, | ||
136 | "fe.%s", | ||
137 | dai_link->cpu_dai_name); | ||
138 | if (ret < 0) | ||
139 | return ret; | ||
140 | |||
141 | asoc_simple_card_canonicalize_cpu(dai_link, is_single_links); | ||
142 | } else { | ||
143 | /* FE is dummy */ | ||
144 | dai_link->cpu_of_node = NULL; | ||
145 | dai_link->cpu_dai_name = "snd-soc-dummy-dai"; | ||
146 | dai_link->cpu_name = "snd-soc-dummy"; | ||
147 | |||
148 | /* BE settings */ | ||
149 | dai_link->no_pcm = 1; | ||
150 | dai_link->be_hw_params_fixup = asoc_simple_card_be_hw_params_fixup; | ||
151 | |||
152 | ret = asoc_simple_card_parse_codec(np, dai_link, DAI, CELL); | ||
153 | if (ret < 0) | ||
154 | return ret; | ||
155 | |||
156 | ret = asoc_simple_card_parse_clk_codec(np, dai_link, dai_props); | ||
157 | if (ret < 0) | ||
158 | return ret; | ||
159 | |||
160 | ret = asoc_simple_card_set_dailink_name(dev, dai_link, | ||
161 | "be.%s", | ||
162 | dai_link->codec_dai_name); | ||
163 | if (ret < 0) | ||
164 | return ret; | ||
165 | |||
166 | snd_soc_of_parse_audio_prefix(&priv->snd_card, | ||
167 | &priv->codec_conf, | ||
168 | dai_link->codec_of_node, | ||
169 | PREFIX "prefix"); | ||
170 | } | ||
171 | |||
172 | ret = snd_soc_of_parse_tdm_slot(np, | ||
173 | &dai_props->tx_slot_mask, | ||
174 | &dai_props->rx_slot_mask, | ||
175 | &dai_props->slots, | ||
176 | &dai_props->slot_width); | ||
177 | if (ret) | ||
178 | return ret; | ||
179 | |||
180 | ret = asoc_simple_card_canonicalize_dailink(dai_link); | ||
181 | if (ret < 0) | ||
182 | return ret; | ||
183 | |||
184 | dai_link->dai_fmt = daifmt; | ||
185 | dai_link->dpcm_playback = 1; | ||
186 | dai_link->dpcm_capture = 1; | ||
187 | dai_link->ops = &asoc_simple_card_ops; | ||
188 | dai_link->init = asoc_simple_card_dai_init; | ||
189 | |||
190 | dev_dbg(dev, "\t%s / %04x / %d\n", | ||
191 | dai_link->name, | ||
192 | dai_link->dai_fmt, | ||
193 | dai_props->sysclk); | ||
194 | |||
195 | return 0; | ||
196 | } | ||
197 | |||
198 | static int asoc_simple_card_dai_link_of(struct device_node *node, | ||
199 | struct asoc_simple_card_priv *priv) | ||
200 | { | ||
201 | struct device *dev = simple_priv_to_dev(priv); | ||
202 | struct device_node *np; | ||
203 | unsigned int daifmt = 0; | ||
204 | int ret, i; | ||
205 | bool is_fe; | ||
206 | |||
207 | /* find 1st codec */ | ||
208 | np = of_get_child_by_name(node, PREFIX "codec"); | ||
209 | if (!np) | ||
210 | return -ENODEV; | ||
211 | |||
212 | ret = asoc_simple_card_parse_daifmt(dev, node, np, | ||
213 | PREFIX, &daifmt); | ||
214 | if (ret < 0) | ||
215 | return ret; | ||
216 | |||
217 | i = 0; | ||
218 | for_each_child_of_node(node, np) { | ||
219 | is_fe = false; | ||
220 | if (strcmp(np->name, PREFIX "cpu") == 0) | ||
221 | is_fe = true; | ||
222 | |||
223 | ret = asoc_simple_card_parse_links(np, priv, daifmt, i, is_fe); | ||
224 | if (ret < 0) | ||
225 | return ret; | ||
226 | i++; | ||
227 | } | ||
228 | |||
229 | return 0; | ||
230 | } | ||
231 | |||
232 | static int asoc_simple_card_parse_of(struct device_node *node, | ||
233 | struct asoc_simple_card_priv *priv, | ||
234 | struct device *dev) | ||
235 | { | ||
236 | struct asoc_simple_dai *props; | ||
237 | struct snd_soc_dai_link *links; | ||
238 | int ret; | ||
239 | int num; | ||
240 | |||
241 | if (!node) | ||
242 | return -EINVAL; | ||
243 | |||
244 | num = of_get_child_count(node); | ||
245 | props = devm_kzalloc(dev, sizeof(*props) * num, GFP_KERNEL); | ||
246 | links = devm_kzalloc(dev, sizeof(*links) * num, GFP_KERNEL); | ||
247 | if (!props || !links) | ||
248 | return -ENOMEM; | ||
249 | |||
250 | priv->dai_props = props; | ||
251 | priv->dai_link = links; | ||
252 | |||
253 | /* Init snd_soc_card */ | ||
254 | priv->snd_card.owner = THIS_MODULE; | ||
255 | priv->snd_card.dev = dev; | ||
256 | priv->snd_card.dai_link = priv->dai_link; | ||
257 | priv->snd_card.num_links = num; | ||
258 | priv->snd_card.codec_conf = &priv->codec_conf; | ||
259 | priv->snd_card.num_configs = 1; | ||
260 | |||
261 | ret = snd_soc_of_parse_audio_routing(&priv->snd_card, PREFIX "routing"); | ||
262 | if (ret < 0) | ||
263 | return ret; | ||
264 | |||
265 | /* sampling rate convert */ | ||
266 | of_property_read_u32(node, PREFIX "convert-rate", &priv->convert_rate); | ||
267 | |||
268 | /* channels transfer */ | ||
269 | of_property_read_u32(node, PREFIX "convert-channels", &priv->convert_channels); | ||
270 | |||
271 | ret = asoc_simple_card_dai_link_of(node, priv); | ||
272 | if (ret < 0) | ||
273 | return ret; | ||
274 | |||
275 | ret = asoc_simple_card_parse_card_name(&priv->snd_card, PREFIX); | ||
276 | if (ret < 0) | ||
277 | return ret; | ||
278 | |||
279 | dev_dbg(dev, "New card: %s\n", | ||
280 | priv->snd_card.name ? priv->snd_card.name : ""); | ||
281 | dev_dbg(dev, "convert_rate %d\n", priv->convert_rate); | ||
282 | dev_dbg(dev, "convert_channels %d\n", priv->convert_channels); | ||
283 | |||
284 | return 0; | ||
285 | } | ||
286 | |||
287 | static int asoc_simple_card_probe(struct platform_device *pdev) | ||
288 | { | ||
289 | struct asoc_simple_card_priv *priv; | ||
290 | struct device_node *np = pdev->dev.of_node; | ||
291 | struct device *dev = &pdev->dev; | ||
292 | int ret; | ||
293 | |||
294 | /* Allocate the private data */ | ||
295 | priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); | ||
296 | if (!priv) | ||
297 | return -ENOMEM; | ||
298 | |||
299 | ret = asoc_simple_card_parse_of(np, priv, dev); | ||
300 | if (ret < 0) { | ||
301 | if (ret != -EPROBE_DEFER) | ||
302 | dev_err(dev, "parse error %d\n", ret); | ||
303 | goto err; | ||
304 | } | ||
305 | |||
306 | snd_soc_card_set_drvdata(&priv->snd_card, priv); | ||
307 | |||
308 | ret = devm_snd_soc_register_card(&pdev->dev, &priv->snd_card); | ||
309 | if (ret >= 0) | ||
310 | return ret; | ||
311 | err: | ||
312 | asoc_simple_card_clean_reference(&priv->snd_card); | ||
313 | |||
314 | return ret; | ||
315 | } | ||
316 | |||
317 | static int asoc_simple_card_remove(struct platform_device *pdev) | ||
318 | { | ||
319 | struct snd_soc_card *card = platform_get_drvdata(pdev); | ||
320 | |||
321 | return asoc_simple_card_clean_reference(card); | ||
322 | } | ||
323 | |||
324 | static const struct of_device_id asoc_simple_of_match[] = { | ||
325 | { .compatible = "renesas,rsrc-card", }, | ||
326 | { .compatible = "simple-scu-audio-card", }, | ||
327 | {}, | ||
328 | }; | ||
329 | MODULE_DEVICE_TABLE(of, asoc_simple_of_match); | ||
330 | |||
331 | static struct platform_driver asoc_simple_card = { | ||
332 | .driver = { | ||
333 | .name = "simple-scu-audio-card", | ||
334 | .of_match_table = asoc_simple_of_match, | ||
335 | }, | ||
336 | .probe = asoc_simple_card_probe, | ||
337 | .remove = asoc_simple_card_remove, | ||
338 | }; | ||
339 | |||
340 | module_platform_driver(asoc_simple_card); | ||
341 | |||
342 | MODULE_ALIAS("platform:asoc-simple-scu-card"); | ||
343 | MODULE_LICENSE("GPL v2"); | ||
344 | MODULE_DESCRIPTION("ASoC Simple SCU Sound Card"); | ||
345 | MODULE_AUTHOR("Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>"); | ||
diff --git a/sound/soc/img/pistachio-internal-dac.c b/sound/soc/img/pistachio-internal-dac.c index 162a0fd68c7b..53e11c6d4e22 100644 --- a/sound/soc/img/pistachio-internal-dac.c +++ b/sound/soc/img/pistachio-internal-dac.c | |||
@@ -134,12 +134,14 @@ static int pistachio_internal_dac_codec_probe(struct snd_soc_codec *codec) | |||
134 | static const struct snd_soc_codec_driver pistachio_internal_dac_driver = { | 134 | static const struct snd_soc_codec_driver pistachio_internal_dac_driver = { |
135 | .probe = pistachio_internal_dac_codec_probe, | 135 | .probe = pistachio_internal_dac_codec_probe, |
136 | .idle_bias_off = true, | 136 | .idle_bias_off = true, |
137 | .controls = pistachio_internal_dac_snd_controls, | 137 | .component_driver = { |
138 | .num_controls = ARRAY_SIZE(pistachio_internal_dac_snd_controls), | 138 | .controls = pistachio_internal_dac_snd_controls, |
139 | .dapm_widgets = pistachio_internal_dac_widgets, | 139 | .num_controls = ARRAY_SIZE(pistachio_internal_dac_snd_controls), |
140 | .num_dapm_widgets = ARRAY_SIZE(pistachio_internal_dac_widgets), | 140 | .dapm_widgets = pistachio_internal_dac_widgets, |
141 | .dapm_routes = pistachio_internal_dac_routes, | 141 | .num_dapm_widgets = ARRAY_SIZE(pistachio_internal_dac_widgets), |
142 | .num_dapm_routes = ARRAY_SIZE(pistachio_internal_dac_routes), | 142 | .dapm_routes = pistachio_internal_dac_routes, |
143 | .num_dapm_routes = ARRAY_SIZE(pistachio_internal_dac_routes), | ||
144 | }, | ||
143 | }; | 145 | }; |
144 | 146 | ||
145 | static int pistachio_internal_dac_probe(struct platform_device *pdev) | 147 | static int pistachio_internal_dac_probe(struct platform_device *pdev) |
diff --git a/sound/soc/intel/Kconfig b/sound/soc/intel/Kconfig index a20c3dfbcb5d..26eb5a0a5575 100644 --- a/sound/soc/intel/Kconfig +++ b/sound/soc/intel/Kconfig | |||
@@ -25,6 +25,7 @@ config SND_SST_IPC_ACPI | |||
25 | tristate | 25 | tristate |
26 | select SND_SST_IPC | 26 | select SND_SST_IPC |
27 | select SND_SOC_INTEL_SST | 27 | select SND_SOC_INTEL_SST |
28 | select IOSF_MBI | ||
28 | 29 | ||
29 | config SND_SOC_INTEL_SST | 30 | config SND_SOC_INTEL_SST |
30 | tristate | 31 | tristate |
@@ -120,6 +121,17 @@ config SND_SOC_INTEL_BYT_MAX98090_MACH | |||
120 | This adds audio driver for Intel Baytrail platform based boards | 121 | This adds audio driver for Intel Baytrail platform based boards |
121 | with the MAX98090 audio codec. | 122 | with the MAX98090 audio codec. |
122 | 123 | ||
124 | config SND_SOC_INTEL_BDW_RT5677_MACH | ||
125 | tristate "ASoC Audio driver for Intel Broadwell with RT5677 codec" | ||
126 | depends on X86_INTEL_LPSS && GPIOLIB && I2C && DW_DMAC | ||
127 | depends on DW_DMAC_CORE=y | ||
128 | select SND_SOC_INTEL_SST | ||
129 | select SND_SOC_INTEL_HASWELL | ||
130 | select SND_SOC_RT5677 | ||
131 | help | ||
132 | This adds support for Intel Broadwell platform based boards with | ||
133 | the RT5677 audio codec. | ||
134 | |||
123 | config SND_SOC_INTEL_BROADWELL_MACH | 135 | config SND_SOC_INTEL_BROADWELL_MACH |
124 | tristate "ASoC Audio DSP support for Intel Broadwell Wildcatpoint" | 136 | tristate "ASoC Audio DSP support for Intel Broadwell Wildcatpoint" |
125 | depends on X86_INTEL_LPSS && I2C && DW_DMAC && \ | 137 | depends on X86_INTEL_LPSS && I2C && DW_DMAC && \ |
diff --git a/sound/soc/intel/atom/sst-atom-controls.c b/sound/soc/intel/atom/sst-atom-controls.c index 98720a93de8a..0838478c4c3f 100644 --- a/sound/soc/intel/atom/sst-atom-controls.c +++ b/sound/soc/intel/atom/sst-atom-controls.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* | 1 | /* |
2 | * sst-atom-controls.c - Intel MID Platform driver DPCM ALSA controls for Mrfld | 2 | * sst-atom-controls.c - Intel MID Platform driver DPCM ALSA controls for Mrfld |
3 | * | 3 | * |
4 | * Copyright (C) 2013-14 Intel Corp | 4 | * Copyright (C) 2013-14 Intel Corp |
@@ -534,6 +534,7 @@ static const DECLARE_TLV_DB_SCALE(sst_gain_tlv_common, SST_GAIN_MIN_VALUE * 10, | |||
534 | 534 | ||
535 | /* Look up table to convert MIXER SW bit regs to SWM inputs */ | 535 | /* Look up table to convert MIXER SW bit regs to SWM inputs */ |
536 | static const uint swm_mixer_input_ids[SST_SWM_INPUT_COUNT] = { | 536 | static const uint swm_mixer_input_ids[SST_SWM_INPUT_COUNT] = { |
537 | [SST_IP_MODEM] = SST_SWM_IN_MODEM, | ||
537 | [SST_IP_CODEC0] = SST_SWM_IN_CODEC0, | 538 | [SST_IP_CODEC0] = SST_SWM_IN_CODEC0, |
538 | [SST_IP_CODEC1] = SST_SWM_IN_CODEC1, | 539 | [SST_IP_CODEC1] = SST_SWM_IN_CODEC1, |
539 | [SST_IP_LOOP0] = SST_SWM_IN_SPROT_LOOP, | 540 | [SST_IP_LOOP0] = SST_SWM_IN_SPROT_LOOP, |
@@ -674,6 +675,7 @@ static int sst_swm_mixer_event(struct snd_soc_dapm_widget *w, | |||
674 | /* SBA mixers - 16 inputs */ | 675 | /* SBA mixers - 16 inputs */ |
675 | #define SST_SBA_DECLARE_MIX_CONTROLS(kctl_name) \ | 676 | #define SST_SBA_DECLARE_MIX_CONTROLS(kctl_name) \ |
676 | static const struct snd_kcontrol_new kctl_name[] = { \ | 677 | static const struct snd_kcontrol_new kctl_name[] = { \ |
678 | SOC_DAPM_SINGLE("modem_in Switch", SND_SOC_NOPM, SST_IP_MODEM, 1, 0), \ | ||
677 | SOC_DAPM_SINGLE("codec_in0 Switch", SND_SOC_NOPM, SST_IP_CODEC0, 1, 0), \ | 679 | SOC_DAPM_SINGLE("codec_in0 Switch", SND_SOC_NOPM, SST_IP_CODEC0, 1, 0), \ |
678 | SOC_DAPM_SINGLE("codec_in1 Switch", SND_SOC_NOPM, SST_IP_CODEC1, 1, 0), \ | 680 | SOC_DAPM_SINGLE("codec_in1 Switch", SND_SOC_NOPM, SST_IP_CODEC1, 1, 0), \ |
679 | SOC_DAPM_SINGLE("sprot_loop_in Switch", SND_SOC_NOPM, SST_IP_LOOP0, 1, 0), \ | 681 | SOC_DAPM_SINGLE("sprot_loop_in Switch", SND_SOC_NOPM, SST_IP_LOOP0, 1, 0), \ |
@@ -684,6 +686,7 @@ static int sst_swm_mixer_event(struct snd_soc_dapm_widget *w, | |||
684 | } | 686 | } |
685 | 687 | ||
686 | #define SST_SBA_MIXER_GRAPH_MAP(mix_name) \ | 688 | #define SST_SBA_MIXER_GRAPH_MAP(mix_name) \ |
689 | { mix_name, "modem_in Switch", "modem_in" }, \ | ||
687 | { mix_name, "codec_in0 Switch", "codec_in0" }, \ | 690 | { mix_name, "codec_in0 Switch", "codec_in0" }, \ |
688 | { mix_name, "codec_in1 Switch", "codec_in1" }, \ | 691 | { mix_name, "codec_in1 Switch", "codec_in1" }, \ |
689 | { mix_name, "sprot_loop_in Switch", "sprot_loop_in" }, \ | 692 | { mix_name, "sprot_loop_in Switch", "sprot_loop_in" }, \ |
@@ -713,6 +716,7 @@ SST_SBA_DECLARE_MIX_CONTROLS(sst_mix_media_l2_controls); | |||
713 | SST_SBA_DECLARE_MIX_CONTROLS(sst_mix_voip_controls); | 716 | SST_SBA_DECLARE_MIX_CONTROLS(sst_mix_voip_controls); |
714 | SST_SBA_DECLARE_MIX_CONTROLS(sst_mix_codec0_controls); | 717 | SST_SBA_DECLARE_MIX_CONTROLS(sst_mix_codec0_controls); |
715 | SST_SBA_DECLARE_MIX_CONTROLS(sst_mix_codec1_controls); | 718 | SST_SBA_DECLARE_MIX_CONTROLS(sst_mix_codec1_controls); |
719 | SST_SBA_DECLARE_MIX_CONTROLS(sst_mix_modem_controls); | ||
716 | 720 | ||
717 | /* | 721 | /* |
718 | * sst_handle_vb_timer - Start/Stop the DSP scheduler | 722 | * sst_handle_vb_timer - Start/Stop the DSP scheduler |
@@ -931,17 +935,26 @@ void sst_fill_ssp_defaults(struct snd_soc_dai *dai) | |||
931 | int send_ssp_cmd(struct snd_soc_dai *dai, const char *id, bool enable) | 935 | int send_ssp_cmd(struct snd_soc_dai *dai, const char *id, bool enable) |
932 | { | 936 | { |
933 | struct sst_data *drv = snd_soc_dai_get_drvdata(dai); | 937 | struct sst_data *drv = snd_soc_dai_get_drvdata(dai); |
934 | const struct sst_ssp_config *config; | 938 | int ssp_id; |
935 | 939 | ||
936 | dev_info(dai->dev, "Enter: enable=%d port_name=%s\n", enable, id); | 940 | dev_info(dai->dev, "Enter: enable=%d port_name=%s\n", enable, id); |
937 | 941 | ||
942 | if (strcmp(id, "ssp0-port") == 0) | ||
943 | ssp_id = SSP_MODEM; | ||
944 | else if (strcmp(id, "ssp2-port") == 0) | ||
945 | ssp_id = SSP_CODEC; | ||
946 | else { | ||
947 | dev_dbg(dai->dev, "port %s is not supported\n", id); | ||
948 | return -1; | ||
949 | } | ||
950 | |||
938 | SST_FILL_DEFAULT_DESTINATION(drv->ssp_cmd.header.dst); | 951 | SST_FILL_DEFAULT_DESTINATION(drv->ssp_cmd.header.dst); |
939 | drv->ssp_cmd.header.command_id = SBA_HW_SET_SSP; | 952 | drv->ssp_cmd.header.command_id = SBA_HW_SET_SSP; |
940 | drv->ssp_cmd.header.length = sizeof(struct sst_cmd_sba_hw_set_ssp) | 953 | drv->ssp_cmd.header.length = sizeof(struct sst_cmd_sba_hw_set_ssp) |
941 | - sizeof(struct sst_dsp_header); | 954 | - sizeof(struct sst_dsp_header); |
942 | 955 | ||
943 | config = &sst_ssp_configs; | 956 | drv->ssp_cmd.selection = ssp_id; |
944 | dev_dbg(dai->dev, "ssp_id: %u\n", config->ssp_id); | 957 | dev_dbg(dai->dev, "ssp_id: %u\n", ssp_id); |
945 | 958 | ||
946 | if (enable) | 959 | if (enable) |
947 | drv->ssp_cmd.switch_state = SST_SWITCH_ON; | 960 | drv->ssp_cmd.switch_state = SST_SWITCH_ON; |
@@ -1047,8 +1060,10 @@ static int sst_set_media_loop(struct snd_soc_dapm_widget *w, | |||
1047 | } | 1060 | } |
1048 | 1061 | ||
1049 | static const struct snd_soc_dapm_widget sst_dapm_widgets[] = { | 1062 | static const struct snd_soc_dapm_widget sst_dapm_widgets[] = { |
1063 | SST_AIF_IN("modem_in", sst_set_be_modules), | ||
1050 | SST_AIF_IN("codec_in0", sst_set_be_modules), | 1064 | SST_AIF_IN("codec_in0", sst_set_be_modules), |
1051 | SST_AIF_IN("codec_in1", sst_set_be_modules), | 1065 | SST_AIF_IN("codec_in1", sst_set_be_modules), |
1066 | SST_AIF_OUT("modem_out", sst_set_be_modules), | ||
1052 | SST_AIF_OUT("codec_out0", sst_set_be_modules), | 1067 | SST_AIF_OUT("codec_out0", sst_set_be_modules), |
1053 | SST_AIF_OUT("codec_out1", sst_set_be_modules), | 1068 | SST_AIF_OUT("codec_out1", sst_set_be_modules), |
1054 | 1069 | ||
@@ -1103,6 +1118,9 @@ static const struct snd_soc_dapm_widget sst_dapm_widgets[] = { | |||
1103 | sst_mix_codec0_controls, sst_swm_mixer_event), | 1118 | sst_mix_codec0_controls, sst_swm_mixer_event), |
1104 | SST_SWM_MIXER("codec_out1 mix 0", SND_SOC_NOPM, SST_TASK_SBA, SST_SWM_OUT_CODEC1, | 1119 | SST_SWM_MIXER("codec_out1 mix 0", SND_SOC_NOPM, SST_TASK_SBA, SST_SWM_OUT_CODEC1, |
1105 | sst_mix_codec1_controls, sst_swm_mixer_event), | 1120 | sst_mix_codec1_controls, sst_swm_mixer_event), |
1121 | SST_SWM_MIXER("modem_out mix 0", SND_SOC_NOPM, SST_TASK_SBA, SST_SWM_OUT_MODEM, | ||
1122 | sst_mix_modem_controls, sst_swm_mixer_event), | ||
1123 | |||
1106 | }; | 1124 | }; |
1107 | 1125 | ||
1108 | static const struct snd_soc_dapm_route intercon[] = { | 1126 | static const struct snd_soc_dapm_route intercon[] = { |
@@ -1148,6 +1166,9 @@ static const struct snd_soc_dapm_route intercon[] = { | |||
1148 | SST_SBA_MIXER_GRAPH_MAP("codec_out0 mix 0"), | 1166 | SST_SBA_MIXER_GRAPH_MAP("codec_out0 mix 0"), |
1149 | {"codec_out1", NULL, "codec_out1 mix 0"}, | 1167 | {"codec_out1", NULL, "codec_out1 mix 0"}, |
1150 | SST_SBA_MIXER_GRAPH_MAP("codec_out1 mix 0"), | 1168 | SST_SBA_MIXER_GRAPH_MAP("codec_out1 mix 0"), |
1169 | {"modem_out", NULL, "modem_out mix 0"}, | ||
1170 | SST_SBA_MIXER_GRAPH_MAP("modem_out mix 0"), | ||
1171 | |||
1151 | 1172 | ||
1152 | }; | 1173 | }; |
1153 | static const char * const slot_names[] = { | 1174 | static const char * const slot_names[] = { |
@@ -1217,6 +1238,9 @@ static const struct snd_kcontrol_new sst_gain_controls[] = { | |||
1217 | SST_GAIN("media_loop2_out", SST_PATH_INDEX_MEDIA_LOOP2_OUT, SST_TASK_SBA, 0, &sst_gains[13]), | 1238 | SST_GAIN("media_loop2_out", SST_PATH_INDEX_MEDIA_LOOP2_OUT, SST_TASK_SBA, 0, &sst_gains[13]), |
1218 | SST_GAIN("sprot_loop_out", SST_PATH_INDEX_SPROT_LOOP_OUT, SST_TASK_SBA, 0, &sst_gains[14]), | 1239 | SST_GAIN("sprot_loop_out", SST_PATH_INDEX_SPROT_LOOP_OUT, SST_TASK_SBA, 0, &sst_gains[14]), |
1219 | SST_VOLUME("media0_in", SST_PATH_INDEX_MEDIA0_IN, SST_TASK_MMX, 0, &sst_gains[15]), | 1240 | SST_VOLUME("media0_in", SST_PATH_INDEX_MEDIA0_IN, SST_TASK_MMX, 0, &sst_gains[15]), |
1241 | SST_GAIN("modem_in", SST_PATH_INDEX_MODEM_IN, SST_TASK_SBA, 0, &sst_gains[16]), | ||
1242 | SST_GAIN("modem_out", SST_PATH_INDEX_MODEM_OUT, SST_TASK_SBA, 0, &sst_gains[17]), | ||
1243 | |||
1220 | }; | 1244 | }; |
1221 | 1245 | ||
1222 | #define SST_GAIN_NUM_CONTROLS 3 | 1246 | #define SST_GAIN_NUM_CONTROLS 3 |
diff --git a/sound/soc/intel/atom/sst-atom-controls.h b/sound/soc/intel/atom/sst-atom-controls.h index e0113112f668..351d81469685 100644 --- a/sound/soc/intel/atom/sst-atom-controls.h +++ b/sound/soc/intel/atom/sst-atom-controls.h | |||
@@ -35,6 +35,8 @@ enum { | |||
35 | /* define a bit for each mixer input */ | 35 | /* define a bit for each mixer input */ |
36 | #define SST_MIX_IP(x) (x) | 36 | #define SST_MIX_IP(x) (x) |
37 | 37 | ||
38 | #define SST_IP_MODEM SST_MIX_IP(0) | ||
39 | #define SST_IP_BT SST_MIX_IP(1) | ||
38 | #define SST_IP_CODEC0 SST_MIX_IP(2) | 40 | #define SST_IP_CODEC0 SST_MIX_IP(2) |
39 | #define SST_IP_CODEC1 SST_MIX_IP(3) | 41 | #define SST_IP_CODEC1 SST_MIX_IP(3) |
40 | #define SST_IP_LOOP0 SST_MIX_IP(4) | 42 | #define SST_IP_LOOP0 SST_MIX_IP(4) |
@@ -63,6 +65,7 @@ enum { | |||
63 | * Audio DSP Path Ids. Specified by the audio DSP FW | 65 | * Audio DSP Path Ids. Specified by the audio DSP FW |
64 | */ | 66 | */ |
65 | enum sst_path_index { | 67 | enum sst_path_index { |
68 | SST_PATH_INDEX_MODEM_OUT = (0x00 << SST_PATH_ID_SHIFT), | ||
66 | SST_PATH_INDEX_CODEC_OUT0 = (0x02 << SST_PATH_ID_SHIFT), | 69 | SST_PATH_INDEX_CODEC_OUT0 = (0x02 << SST_PATH_ID_SHIFT), |
67 | SST_PATH_INDEX_CODEC_OUT1 = (0x03 << SST_PATH_ID_SHIFT), | 70 | SST_PATH_INDEX_CODEC_OUT1 = (0x03 << SST_PATH_ID_SHIFT), |
68 | 71 | ||
@@ -80,6 +83,7 @@ enum sst_path_index { | |||
80 | 83 | ||
81 | 84 | ||
82 | /* Start of input paths */ | 85 | /* Start of input paths */ |
86 | SST_PATH_INDEX_MODEM_IN = (0x80 << SST_PATH_ID_SHIFT), | ||
83 | SST_PATH_INDEX_CODEC_IN0 = (0x82 << SST_PATH_ID_SHIFT), | 87 | SST_PATH_INDEX_CODEC_IN0 = (0x82 << SST_PATH_ID_SHIFT), |
84 | SST_PATH_INDEX_CODEC_IN1 = (0x83 << SST_PATH_ID_SHIFT), | 88 | SST_PATH_INDEX_CODEC_IN1 = (0x83 << SST_PATH_ID_SHIFT), |
85 | 89 | ||
@@ -105,6 +109,7 @@ enum sst_path_index { | |||
105 | * path IDs | 109 | * path IDs |
106 | */ | 110 | */ |
107 | enum sst_swm_inputs { | 111 | enum sst_swm_inputs { |
112 | SST_SWM_IN_MODEM = (SST_PATH_INDEX_MODEM_IN | SST_DEFAULT_CELL_NBR), | ||
108 | SST_SWM_IN_CODEC0 = (SST_PATH_INDEX_CODEC_IN0 | SST_DEFAULT_CELL_NBR), | 113 | SST_SWM_IN_CODEC0 = (SST_PATH_INDEX_CODEC_IN0 | SST_DEFAULT_CELL_NBR), |
109 | SST_SWM_IN_CODEC1 = (SST_PATH_INDEX_CODEC_IN1 | SST_DEFAULT_CELL_NBR), | 114 | SST_SWM_IN_CODEC1 = (SST_PATH_INDEX_CODEC_IN1 | SST_DEFAULT_CELL_NBR), |
110 | SST_SWM_IN_SPROT_LOOP = (SST_PATH_INDEX_SPROT_LOOP_IN | SST_DEFAULT_CELL_NBR), | 115 | SST_SWM_IN_SPROT_LOOP = (SST_PATH_INDEX_SPROT_LOOP_IN | SST_DEFAULT_CELL_NBR), |
@@ -124,6 +129,7 @@ enum sst_swm_inputs { | |||
124 | * path IDs | 129 | * path IDs |
125 | */ | 130 | */ |
126 | enum sst_swm_outputs { | 131 | enum sst_swm_outputs { |
132 | SST_SWM_OUT_MODEM = (SST_PATH_INDEX_MODEM_OUT | SST_DEFAULT_CELL_NBR), | ||
127 | SST_SWM_OUT_CODEC0 = (SST_PATH_INDEX_CODEC_OUT0 | SST_DEFAULT_CELL_NBR), | 133 | SST_SWM_OUT_CODEC0 = (SST_PATH_INDEX_CODEC_OUT0 | SST_DEFAULT_CELL_NBR), |
128 | SST_SWM_OUT_CODEC1 = (SST_PATH_INDEX_CODEC_OUT1 | SST_DEFAULT_CELL_NBR), | 134 | SST_SWM_OUT_CODEC1 = (SST_PATH_INDEX_CODEC_OUT1 | SST_DEFAULT_CELL_NBR), |
129 | SST_SWM_OUT_SPROT_LOOP = (SST_PATH_INDEX_SPROT_LOOP_OUT | SST_DEFAULT_CELL_NBR), | 135 | SST_SWM_OUT_SPROT_LOOP = (SST_PATH_INDEX_SPROT_LOOP_OUT | SST_DEFAULT_CELL_NBR), |
diff --git a/sound/soc/intel/atom/sst-mfld-platform-pcm.c b/sound/soc/intel/atom/sst-mfld-platform-pcm.c index 52ed434cbca6..25c6d87c818e 100644 --- a/sound/soc/intel/atom/sst-mfld-platform-pcm.c +++ b/sound/soc/intel/atom/sst-mfld-platform-pcm.c | |||
@@ -670,7 +670,7 @@ static snd_pcm_uframes_t sst_platform_pcm_pointer | |||
670 | return str_info->buffer_ptr; | 670 | return str_info->buffer_ptr; |
671 | } | 671 | } |
672 | 672 | ||
673 | static struct snd_pcm_ops sst_platform_ops = { | 673 | static const struct snd_pcm_ops sst_platform_ops = { |
674 | .open = sst_platform_open, | 674 | .open = sst_platform_open, |
675 | .ioctl = snd_pcm_lib_ioctl, | 675 | .ioctl = snd_pcm_lib_ioctl, |
676 | .trigger = sst_platform_pcm_trigger, | 676 | .trigger = sst_platform_pcm_trigger, |
diff --git a/sound/soc/intel/atom/sst/sst.c b/sound/soc/intel/atom/sst/sst.c index a4b458e77089..9b6e27385dc9 100644 --- a/sound/soc/intel/atom/sst/sst.c +++ b/sound/soc/intel/atom/sst/sst.c | |||
@@ -190,7 +190,8 @@ int sst_driver_ops(struct intel_sst_drv *sst) | |||
190 | 190 | ||
191 | default: | 191 | default: |
192 | dev_err(sst->dev, | 192 | dev_err(sst->dev, |
193 | "SST Driver capablities missing for dev_id: %x", sst->dev_id); | 193 | "SST Driver capabilities missing for dev_id: %x", |
194 | sst->dev_id); | ||
194 | return -EINVAL; | 195 | return -EINVAL; |
195 | }; | 196 | }; |
196 | } | 197 | } |
@@ -441,7 +442,7 @@ static int intel_sst_suspend(struct device *dev) | |||
441 | struct stream_info *stream = &ctx->streams[i]; | 442 | struct stream_info *stream = &ctx->streams[i]; |
442 | 443 | ||
443 | if (stream->status == STREAM_RUNNING) { | 444 | if (stream->status == STREAM_RUNNING) { |
444 | dev_err(dev, "stream %d is running, cant susupend, abort\n", i); | 445 | dev_err(dev, "stream %d is running, can't suspend, abort\n", i); |
445 | return -EBUSY; | 446 | return -EBUSY; |
446 | } | 447 | } |
447 | } | 448 | } |
diff --git a/sound/soc/intel/atom/sst/sst_acpi.c b/sound/soc/intel/atom/sst/sst_acpi.c index 4d3184971227..ba5c0d71720a 100644 --- a/sound/soc/intel/atom/sst/sst_acpi.c +++ b/sound/soc/intel/atom/sst/sst_acpi.c | |||
@@ -39,6 +39,8 @@ | |||
39 | #include <acpi/platform/aclinux.h> | 39 | #include <acpi/platform/aclinux.h> |
40 | #include <acpi/actypes.h> | 40 | #include <acpi/actypes.h> |
41 | #include <acpi/acpi_bus.h> | 41 | #include <acpi/acpi_bus.h> |
42 | #include <asm/cpu_device_id.h> | ||
43 | #include <asm/iosf_mbi.h> | ||
42 | #include "../sst-mfld-platform.h" | 44 | #include "../sst-mfld-platform.h" |
43 | #include "../../common/sst-dsp.h" | 45 | #include "../../common/sst-dsp.h" |
44 | #include "../../common/sst-acpi.h" | 46 | #include "../../common/sst-acpi.h" |
@@ -113,6 +115,28 @@ static const struct sst_res_info byt_rvp_res_info = { | |||
113 | .acpi_ipc_irq_index = 5, | 115 | .acpi_ipc_irq_index = 5, |
114 | }; | 116 | }; |
115 | 117 | ||
118 | /* BYTCR has different BIOS from BYT */ | ||
119 | static const struct sst_res_info bytcr_res_info = { | ||
120 | .shim_offset = 0x140000, | ||
121 | .shim_size = 0x000100, | ||
122 | .shim_phy_addr = SST_BYT_SHIM_PHY_ADDR, | ||
123 | .ssp0_offset = 0xa0000, | ||
124 | .ssp0_size = 0x1000, | ||
125 | .dma0_offset = 0x98000, | ||
126 | .dma0_size = 0x4000, | ||
127 | .dma1_offset = 0x9c000, | ||
128 | .dma1_size = 0x4000, | ||
129 | .iram_offset = 0x0c0000, | ||
130 | .iram_size = 0x14000, | ||
131 | .dram_offset = 0x100000, | ||
132 | .dram_size = 0x28000, | ||
133 | .mbox_offset = 0x144000, | ||
134 | .mbox_size = 0x1000, | ||
135 | .acpi_lpe_res_index = 0, | ||
136 | .acpi_ddr_index = 2, | ||
137 | .acpi_ipc_irq_index = 0 | ||
138 | }; | ||
139 | |||
116 | static struct sst_platform_info byt_rvp_platform_data = { | 140 | static struct sst_platform_info byt_rvp_platform_data = { |
117 | .probe_data = &byt_fwparse_info, | 141 | .probe_data = &byt_fwparse_info, |
118 | .ipc_info = &byt_ipc_info, | 142 | .ipc_info = &byt_ipc_info, |
@@ -142,7 +166,7 @@ static int sst_platform_get_resources(struct intel_sst_drv *ctx) | |||
142 | rsrc = platform_get_resource(pdev, IORESOURCE_MEM, | 166 | rsrc = platform_get_resource(pdev, IORESOURCE_MEM, |
143 | ctx->pdata->res_info->acpi_lpe_res_index); | 167 | ctx->pdata->res_info->acpi_lpe_res_index); |
144 | if (!rsrc) { | 168 | if (!rsrc) { |
145 | dev_err(ctx->dev, "Invalid SHIM base from IFWI"); | 169 | dev_err(ctx->dev, "Invalid SHIM base from IFWI\n"); |
146 | return -EIO; | 170 | return -EIO; |
147 | } | 171 | } |
148 | dev_info(ctx->dev, "LPE base: %#x size:%#x", (unsigned int) rsrc->start, | 172 | dev_info(ctx->dev, "LPE base: %#x size:%#x", (unsigned int) rsrc->start, |
@@ -154,7 +178,7 @@ static int sst_platform_get_resources(struct intel_sst_drv *ctx) | |||
154 | ctx->iram = devm_ioremap_nocache(ctx->dev, ctx->iram_base, | 178 | ctx->iram = devm_ioremap_nocache(ctx->dev, ctx->iram_base, |
155 | ctx->pdata->res_info->iram_size); | 179 | ctx->pdata->res_info->iram_size); |
156 | if (!ctx->iram) { | 180 | if (!ctx->iram) { |
157 | dev_err(ctx->dev, "unable to map IRAM"); | 181 | dev_err(ctx->dev, "unable to map IRAM\n"); |
158 | return -EIO; | 182 | return -EIO; |
159 | } | 183 | } |
160 | 184 | ||
@@ -164,7 +188,7 @@ static int sst_platform_get_resources(struct intel_sst_drv *ctx) | |||
164 | ctx->dram = devm_ioremap_nocache(ctx->dev, ctx->dram_base, | 188 | ctx->dram = devm_ioremap_nocache(ctx->dev, ctx->dram_base, |
165 | ctx->pdata->res_info->dram_size); | 189 | ctx->pdata->res_info->dram_size); |
166 | if (!ctx->dram) { | 190 | if (!ctx->dram) { |
167 | dev_err(ctx->dev, "unable to map DRAM"); | 191 | dev_err(ctx->dev, "unable to map DRAM\n"); |
168 | return -EIO; | 192 | return -EIO; |
169 | } | 193 | } |
170 | 194 | ||
@@ -173,7 +197,7 @@ static int sst_platform_get_resources(struct intel_sst_drv *ctx) | |||
173 | ctx->shim = devm_ioremap_nocache(ctx->dev, ctx->shim_phy_add, | 197 | ctx->shim = devm_ioremap_nocache(ctx->dev, ctx->shim_phy_add, |
174 | ctx->pdata->res_info->shim_size); | 198 | ctx->pdata->res_info->shim_size); |
175 | if (!ctx->shim) { | 199 | if (!ctx->shim) { |
176 | dev_err(ctx->dev, "unable to map SHIM"); | 200 | dev_err(ctx->dev, "unable to map SHIM\n"); |
177 | return -EIO; | 201 | return -EIO; |
178 | } | 202 | } |
179 | 203 | ||
@@ -186,7 +210,7 @@ static int sst_platform_get_resources(struct intel_sst_drv *ctx) | |||
186 | ctx->mailbox = devm_ioremap_nocache(ctx->dev, ctx->mailbox_add, | 210 | ctx->mailbox = devm_ioremap_nocache(ctx->dev, ctx->mailbox_add, |
187 | ctx->pdata->res_info->mbox_size); | 211 | ctx->pdata->res_info->mbox_size); |
188 | if (!ctx->mailbox) { | 212 | if (!ctx->mailbox) { |
189 | dev_err(ctx->dev, "unable to map mailbox"); | 213 | dev_err(ctx->dev, "unable to map mailbox\n"); |
190 | return -EIO; | 214 | return -EIO; |
191 | } | 215 | } |
192 | 216 | ||
@@ -196,7 +220,7 @@ static int sst_platform_get_resources(struct intel_sst_drv *ctx) | |||
196 | rsrc = platform_get_resource(pdev, IORESOURCE_MEM, | 220 | rsrc = platform_get_resource(pdev, IORESOURCE_MEM, |
197 | ctx->pdata->res_info->acpi_ddr_index); | 221 | ctx->pdata->res_info->acpi_ddr_index); |
198 | if (!rsrc) { | 222 | if (!rsrc) { |
199 | dev_err(ctx->dev, "Invalid DDR base from IFWI"); | 223 | dev_err(ctx->dev, "Invalid DDR base from IFWI\n"); |
200 | return -EIO; | 224 | return -EIO; |
201 | } | 225 | } |
202 | ctx->ddr_base = rsrc->start; | 226 | ctx->ddr_base = rsrc->start; |
@@ -205,7 +229,7 @@ static int sst_platform_get_resources(struct intel_sst_drv *ctx) | |||
205 | ctx->ddr = devm_ioremap_nocache(ctx->dev, ctx->ddr_base, | 229 | ctx->ddr = devm_ioremap_nocache(ctx->dev, ctx->ddr_base, |
206 | resource_size(rsrc)); | 230 | resource_size(rsrc)); |
207 | if (!ctx->ddr) { | 231 | if (!ctx->ddr) { |
208 | dev_err(ctx->dev, "unable to map DDR"); | 232 | dev_err(ctx->dev, "unable to map DDR\n"); |
209 | return -EIO; | 233 | return -EIO; |
210 | } | 234 | } |
211 | 235 | ||
@@ -215,6 +239,46 @@ static int sst_platform_get_resources(struct intel_sst_drv *ctx) | |||
215 | return 0; | 239 | return 0; |
216 | } | 240 | } |
217 | 241 | ||
242 | |||
243 | static int is_byt_cr(struct device *dev, bool *bytcr) | ||
244 | { | ||
245 | int status = 0; | ||
246 | |||
247 | if (IS_ENABLED(CONFIG_IOSF_MBI)) { | ||
248 | static const struct x86_cpu_id cpu_ids[] = { | ||
249 | { X86_VENDOR_INTEL, 6, 55 }, /* Valleyview, Bay Trail */ | ||
250 | {} | ||
251 | }; | ||
252 | u32 bios_status; | ||
253 | |||
254 | if (!x86_match_cpu(cpu_ids) || !iosf_mbi_available()) { | ||
255 | /* bail silently */ | ||
256 | return status; | ||
257 | } | ||
258 | |||
259 | status = iosf_mbi_read(BT_MBI_UNIT_PMC, /* 0x04 PUNIT */ | ||
260 | MBI_REG_READ, /* 0x10 */ | ||
261 | 0x006, /* BIOS_CONFIG */ | ||
262 | &bios_status); | ||
263 | |||
264 | if (status) { | ||
265 | dev_err(dev, "could not read PUNIT BIOS_CONFIG\n"); | ||
266 | } else { | ||
267 | /* bits 26:27 mirror PMIC options */ | ||
268 | bios_status = (bios_status >> 26) & 3; | ||
269 | |||
270 | if ((bios_status == 1) || (bios_status == 3)) | ||
271 | *bytcr = true; | ||
272 | else | ||
273 | dev_info(dev, "BYT-CR not detected\n"); | ||
274 | } | ||
275 | } else { | ||
276 | dev_info(dev, "IOSF_MBI not enabled, no BYT-CR detection\n"); | ||
277 | } | ||
278 | return status; | ||
279 | } | ||
280 | |||
281 | |||
218 | static int sst_acpi_probe(struct platform_device *pdev) | 282 | static int sst_acpi_probe(struct platform_device *pdev) |
219 | { | 283 | { |
220 | struct device *dev = &pdev->dev; | 284 | struct device *dev = &pdev->dev; |
@@ -226,11 +290,12 @@ static int sst_acpi_probe(struct platform_device *pdev) | |||
226 | struct platform_device *plat_dev; | 290 | struct platform_device *plat_dev; |
227 | struct sst_platform_info *pdata; | 291 | struct sst_platform_info *pdata; |
228 | unsigned int dev_id; | 292 | unsigned int dev_id; |
293 | bool bytcr = false; | ||
229 | 294 | ||
230 | id = acpi_match_device(dev->driver->acpi_match_table, dev); | 295 | id = acpi_match_device(dev->driver->acpi_match_table, dev); |
231 | if (!id) | 296 | if (!id) |
232 | return -ENODEV; | 297 | return -ENODEV; |
233 | dev_dbg(dev, "for %s", id->id); | 298 | dev_dbg(dev, "for %s\n", id->id); |
234 | 299 | ||
235 | mach = (struct sst_acpi_mach *)id->driver_data; | 300 | mach = (struct sst_acpi_mach *)id->driver_data; |
236 | mach = sst_acpi_find_machine(mach); | 301 | mach = sst_acpi_find_machine(mach); |
@@ -251,6 +316,18 @@ static int sst_acpi_probe(struct platform_device *pdev) | |||
251 | 316 | ||
252 | dev_dbg(dev, "ACPI device id: %x\n", dev_id); | 317 | dev_dbg(dev, "ACPI device id: %x\n", dev_id); |
253 | 318 | ||
319 | ret = sst_alloc_drv_context(&ctx, dev, dev_id); | ||
320 | if (ret < 0) | ||
321 | return ret; | ||
322 | |||
323 | ret = is_byt_cr(dev, &bytcr); | ||
324 | if (!((ret < 0) || (bytcr == false))) { | ||
325 | dev_info(dev, "Detected Baytrail-CR platform\n"); | ||
326 | |||
327 | /* override resource info */ | ||
328 | byt_rvp_platform_data.res_info = &bytcr_res_info; | ||
329 | } | ||
330 | |||
254 | plat_dev = platform_device_register_data(dev, pdata->platform, -1, | 331 | plat_dev = platform_device_register_data(dev, pdata->platform, -1, |
255 | NULL, 0); | 332 | NULL, 0); |
256 | if (IS_ERR(plat_dev)) { | 333 | if (IS_ERR(plat_dev)) { |
@@ -271,10 +348,6 @@ static int sst_acpi_probe(struct platform_device *pdev) | |||
271 | return PTR_ERR(mdev); | 348 | return PTR_ERR(mdev); |
272 | } | 349 | } |
273 | 350 | ||
274 | ret = sst_alloc_drv_context(&ctx, dev, dev_id); | ||
275 | if (ret < 0) | ||
276 | return ret; | ||
277 | |||
278 | /* Fill sst platform data */ | 351 | /* Fill sst platform data */ |
279 | ctx->pdata = pdata; | 352 | ctx->pdata = pdata; |
280 | strcpy(ctx->firmware_name, mach->fw_filename); | 353 | strcpy(ctx->firmware_name, mach->fw_filename); |
diff --git a/sound/soc/intel/atom/sst/sst_ipc.c b/sound/soc/intel/atom/sst/sst_ipc.c index 8afa6fe7b0b0..bfc889950bb2 100644 --- a/sound/soc/intel/atom/sst/sst_ipc.c +++ b/sound/soc/intel/atom/sst/sst_ipc.c | |||
@@ -267,6 +267,9 @@ static void process_fw_async_msg(struct intel_sst_drv *sst_drv_ctx, | |||
267 | "Period elapsed rcvd for pipe id 0x%x\n", | 267 | "Period elapsed rcvd for pipe id 0x%x\n", |
268 | pipe_id); | 268 | pipe_id); |
269 | stream = &sst_drv_ctx->streams[str_id]; | 269 | stream = &sst_drv_ctx->streams[str_id]; |
270 | /* If stream is dropped, skip processing this message*/ | ||
271 | if (stream->status == STREAM_INIT) | ||
272 | break; | ||
270 | if (stream->period_elapsed) | 273 | if (stream->period_elapsed) |
271 | stream->period_elapsed(stream->pcm_substream); | 274 | stream->period_elapsed(stream->pcm_substream); |
272 | if (stream->compr_cb) | 275 | if (stream->compr_cb) |
diff --git a/sound/soc/intel/atom/sst/sst_pvt.c b/sound/soc/intel/atom/sst/sst_pvt.c index adb32fefd693..b1e6b8f34a6a 100644 --- a/sound/soc/intel/atom/sst/sst_pvt.c +++ b/sound/soc/intel/atom/sst/sst_pvt.c | |||
@@ -279,17 +279,15 @@ int sst_prepare_and_post_msg(struct intel_sst_drv *sst, | |||
279 | 279 | ||
280 | if (response) { | 280 | if (response) { |
281 | ret = sst_wait_timeout(sst, block); | 281 | ret = sst_wait_timeout(sst, block); |
282 | if (ret < 0) { | 282 | if (ret < 0) |
283 | goto out; | 283 | goto out; |
284 | } else if(block->data) { | 284 | |
285 | if (!data) | 285 | if (data && block->data) { |
286 | goto out; | 286 | *data = kmemdup(block->data, block->size, GFP_KERNEL); |
287 | *data = kzalloc(block->size, GFP_KERNEL); | 287 | if (!*data) { |
288 | if (!(*data)) { | ||
289 | ret = -ENOMEM; | 288 | ret = -ENOMEM; |
290 | goto out; | 289 | goto out; |
291 | } else | 290 | } |
292 | memcpy(data, (void *) block->data, block->size); | ||
293 | } | 291 | } |
294 | } | 292 | } |
295 | out: | 293 | out: |
diff --git a/sound/soc/intel/baytrail/sst-baytrail-ipc.c b/sound/soc/intel/baytrail/sst-baytrail-ipc.c index 5bbaa667bec1..c8455b47388b 100644 --- a/sound/soc/intel/baytrail/sst-baytrail-ipc.c +++ b/sound/soc/intel/baytrail/sst-baytrail-ipc.c | |||
@@ -184,15 +184,9 @@ struct sst_byt { | |||
184 | 184 | ||
185 | static inline u64 sst_byt_header(int msg_id, int data, bool large, int str_id) | 185 | static inline u64 sst_byt_header(int msg_id, int data, bool large, int str_id) |
186 | { | 186 | { |
187 | u64 header; | 187 | return IPC_HEADER_MSG_ID(msg_id) | IPC_HEADER_STR_ID(str_id) | |
188 | 188 | IPC_HEADER_LARGE(large) | IPC_HEADER_DATA(data) | | |
189 | header = IPC_HEADER_MSG_ID(msg_id) | | 189 | SST_BYT_IPCX_BUSY; |
190 | IPC_HEADER_STR_ID(str_id) | | ||
191 | IPC_HEADER_LARGE(large) | | ||
192 | IPC_HEADER_DATA(data) | | ||
193 | SST_BYT_IPCX_BUSY; | ||
194 | |||
195 | return header; | ||
196 | } | 190 | } |
197 | 191 | ||
198 | static inline u16 sst_byt_header_msg_id(u64 header) | 192 | static inline u16 sst_byt_header_msg_id(u64 header) |
diff --git a/sound/soc/intel/boards/Makefile b/sound/soc/intel/boards/Makefile index dac03a06bfd8..5639f10774e6 100644 --- a/sound/soc/intel/boards/Makefile +++ b/sound/soc/intel/boards/Makefile | |||
@@ -1,6 +1,7 @@ | |||
1 | snd-soc-sst-haswell-objs := haswell.o | 1 | snd-soc-sst-haswell-objs := haswell.o |
2 | snd-soc-sst-byt-rt5640-mach-objs := byt-rt5640.o | 2 | snd-soc-sst-byt-rt5640-mach-objs := byt-rt5640.o |
3 | snd-soc-sst-byt-max98090-mach-objs := byt-max98090.o | 3 | snd-soc-sst-byt-max98090-mach-objs := byt-max98090.o |
4 | snd-soc-sst-bdw-rt5677-mach-objs := bdw-rt5677.o | ||
4 | snd-soc-sst-broadwell-objs := broadwell.o | 5 | snd-soc-sst-broadwell-objs := broadwell.o |
5 | snd-soc-sst-bxt-da7219_max98357a-objs := bxt_da7219_max98357a.o | 6 | snd-soc-sst-bxt-da7219_max98357a-objs := bxt_da7219_max98357a.o |
6 | snd-soc-sst-bxt-rt298-objs := bxt_rt298.o | 7 | snd-soc-sst-bxt-rt298-objs := bxt_rt298.o |
@@ -19,6 +20,7 @@ obj-$(CONFIG_SND_SOC_INTEL_BYT_MAX98090_MACH) += snd-soc-sst-byt-max98090-mach.o | |||
19 | obj-$(CONFIG_SND_SOC_INTEL_BXT_DA7219_MAX98357A_MACH) += snd-soc-sst-bxt-da7219_max98357a.o | 20 | obj-$(CONFIG_SND_SOC_INTEL_BXT_DA7219_MAX98357A_MACH) += snd-soc-sst-bxt-da7219_max98357a.o |
20 | obj-$(CONFIG_SND_SOC_INTEL_BXT_RT298_MACH) += snd-soc-sst-bxt-rt298.o | 21 | obj-$(CONFIG_SND_SOC_INTEL_BXT_RT298_MACH) += snd-soc-sst-bxt-rt298.o |
21 | obj-$(CONFIG_SND_SOC_INTEL_BROADWELL_MACH) += snd-soc-sst-broadwell.o | 22 | obj-$(CONFIG_SND_SOC_INTEL_BROADWELL_MACH) += snd-soc-sst-broadwell.o |
23 | obj-$(CONFIG_SND_SOC_INTEL_BDW_RT5677_MACH) += snd-soc-sst-bdw-rt5677-mach.o | ||
22 | obj-$(CONFIG_SND_SOC_INTEL_BYTCR_RT5640_MACH) += snd-soc-sst-bytcr-rt5640.o | 24 | obj-$(CONFIG_SND_SOC_INTEL_BYTCR_RT5640_MACH) += snd-soc-sst-bytcr-rt5640.o |
23 | obj-$(CONFIG_SND_SOC_INTEL_BYTCR_RT5651_MACH) += snd-soc-sst-bytcr-rt5651.o | 25 | obj-$(CONFIG_SND_SOC_INTEL_BYTCR_RT5651_MACH) += snd-soc-sst-bytcr-rt5651.o |
24 | obj-$(CONFIG_SND_SOC_INTEL_CHT_BSW_RT5672_MACH) += snd-soc-sst-cht-bsw-rt5672.o | 26 | obj-$(CONFIG_SND_SOC_INTEL_CHT_BSW_RT5672_MACH) += snd-soc-sst-cht-bsw-rt5672.o |
diff --git a/sound/soc/intel/boards/bdw-rt5677.c b/sound/soc/intel/boards/bdw-rt5677.c new file mode 100644 index 000000000000..547e6705bf6d --- /dev/null +++ b/sound/soc/intel/boards/bdw-rt5677.c | |||
@@ -0,0 +1,347 @@ | |||
1 | /* | ||
2 | * ASoC machine driver for Intel Broadwell platforms with RT5677 codec | ||
3 | * | ||
4 | * Copyright (c) 2014, The Chromium OS Authors. All rights reserved. | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify it | ||
7 | * under the terms and conditions of the GNU General Public License, | ||
8 | * version 2, as published by the Free Software Foundation. | ||
9 | * | ||
10 | * This program is distributed in the hope it will be useful, but WITHOUT | ||
11 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
12 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
13 | * more details. | ||
14 | * | ||
15 | * You should have received a copy of the GNU General Public License | ||
16 | * along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
17 | */ | ||
18 | |||
19 | #include <linux/module.h> | ||
20 | #include <linux/platform_device.h> | ||
21 | #include <linux/gpio/consumer.h> | ||
22 | #include <linux/delay.h> | ||
23 | #include <sound/core.h> | ||
24 | #include <sound/pcm.h> | ||
25 | #include <sound/soc.h> | ||
26 | #include <sound/pcm_params.h> | ||
27 | #include <sound/jack.h> | ||
28 | |||
29 | #include "../common/sst-dsp.h" | ||
30 | #include "../haswell/sst-haswell-ipc.h" | ||
31 | |||
32 | #include "../../codecs/rt5677.h" | ||
33 | |||
34 | struct bdw_rt5677_priv { | ||
35 | struct gpio_desc *gpio_hp_en; | ||
36 | struct snd_soc_codec *codec; | ||
37 | }; | ||
38 | |||
39 | static int bdw_rt5677_event_hp(struct snd_soc_dapm_widget *w, | ||
40 | struct snd_kcontrol *k, int event) | ||
41 | { | ||
42 | struct snd_soc_dapm_context *dapm = w->dapm; | ||
43 | struct snd_soc_card *card = dapm->card; | ||
44 | struct bdw_rt5677_priv *bdw_rt5677 = snd_soc_card_get_drvdata(card); | ||
45 | |||
46 | if (SND_SOC_DAPM_EVENT_ON(event)) | ||
47 | msleep(70); | ||
48 | |||
49 | gpiod_set_value_cansleep(bdw_rt5677->gpio_hp_en, | ||
50 | SND_SOC_DAPM_EVENT_ON(event)); | ||
51 | |||
52 | return 0; | ||
53 | } | ||
54 | |||
55 | static const struct snd_soc_dapm_widget bdw_rt5677_widgets[] = { | ||
56 | SND_SOC_DAPM_HP("Headphone", bdw_rt5677_event_hp), | ||
57 | SND_SOC_DAPM_SPK("Speaker", NULL), | ||
58 | SND_SOC_DAPM_MIC("Headset Mic", NULL), | ||
59 | SND_SOC_DAPM_MIC("Local DMICs", NULL), | ||
60 | SND_SOC_DAPM_MIC("Remote DMICs", NULL), | ||
61 | }; | ||
62 | |||
63 | static const struct snd_soc_dapm_route bdw_rt5677_map[] = { | ||
64 | /* Speakers */ | ||
65 | {"Speaker", NULL, "PDM1L"}, | ||
66 | {"Speaker", NULL, "PDM1R"}, | ||
67 | |||
68 | /* Headset jack connectors */ | ||
69 | {"Headphone", NULL, "LOUT1"}, | ||
70 | {"Headphone", NULL, "LOUT2"}, | ||
71 | {"IN1P", NULL, "Headset Mic"}, | ||
72 | {"IN1N", NULL, "Headset Mic"}, | ||
73 | |||
74 | /* Digital MICs | ||
75 | * Local DMICs: the two DMICs on the mainboard | ||
76 | * Remote DMICs: the two DMICs on the camera module | ||
77 | */ | ||
78 | {"DMIC L1", NULL, "Remote DMICs"}, | ||
79 | {"DMIC R1", NULL, "Remote DMICs"}, | ||
80 | {"DMIC L2", NULL, "Local DMICs"}, | ||
81 | {"DMIC R2", NULL, "Local DMICs"}, | ||
82 | |||
83 | /* CODEC BE connections */ | ||
84 | {"SSP0 CODEC IN", NULL, "AIF1 Capture"}, | ||
85 | {"AIF1 Playback", NULL, "SSP0 CODEC OUT"}, | ||
86 | }; | ||
87 | |||
88 | static const struct snd_kcontrol_new bdw_rt5677_controls[] = { | ||
89 | SOC_DAPM_PIN_SWITCH("Speaker"), | ||
90 | SOC_DAPM_PIN_SWITCH("Headphone"), | ||
91 | SOC_DAPM_PIN_SWITCH("Headset Mic"), | ||
92 | SOC_DAPM_PIN_SWITCH("Local DMICs"), | ||
93 | SOC_DAPM_PIN_SWITCH("Remote DMICs"), | ||
94 | }; | ||
95 | |||
96 | |||
97 | static struct snd_soc_jack headphone_jack; | ||
98 | static struct snd_soc_jack mic_jack; | ||
99 | |||
100 | static struct snd_soc_jack_pin headphone_jack_pin = { | ||
101 | .pin = "Headphone", | ||
102 | .mask = SND_JACK_HEADPHONE, | ||
103 | }; | ||
104 | |||
105 | static struct snd_soc_jack_pin mic_jack_pin = { | ||
106 | .pin = "Headset Mic", | ||
107 | .mask = SND_JACK_MICROPHONE, | ||
108 | }; | ||
109 | |||
110 | static struct snd_soc_jack_gpio headphone_jack_gpio = { | ||
111 | .name = "plug-det", | ||
112 | .report = SND_JACK_HEADPHONE, | ||
113 | .debounce_time = 200, | ||
114 | }; | ||
115 | |||
116 | static struct snd_soc_jack_gpio mic_jack_gpio = { | ||
117 | .name = "mic-present", | ||
118 | .report = SND_JACK_MICROPHONE, | ||
119 | .debounce_time = 200, | ||
120 | .invert = 1, | ||
121 | }; | ||
122 | |||
123 | static int broadwell_ssp0_fixup(struct snd_soc_pcm_runtime *rtd, | ||
124 | struct snd_pcm_hw_params *params) | ||
125 | { | ||
126 | struct snd_interval *rate = hw_param_interval(params, | ||
127 | SNDRV_PCM_HW_PARAM_RATE); | ||
128 | struct snd_interval *channels = hw_param_interval(params, | ||
129 | SNDRV_PCM_HW_PARAM_CHANNELS); | ||
130 | |||
131 | /* The ADSP will covert the FE rate to 48k, stereo */ | ||
132 | rate->min = rate->max = 48000; | ||
133 | channels->min = channels->max = 2; | ||
134 | |||
135 | /* set SSP0 to 16 bit */ | ||
136 | snd_mask_set(¶ms->masks[SNDRV_PCM_HW_PARAM_FORMAT - | ||
137 | SNDRV_PCM_HW_PARAM_FIRST_MASK], | ||
138 | SNDRV_PCM_FORMAT_S16_LE); | ||
139 | return 0; | ||
140 | } | ||
141 | |||
142 | static int bdw_rt5677_hw_params(struct snd_pcm_substream *substream, | ||
143 | struct snd_pcm_hw_params *params) | ||
144 | { | ||
145 | struct snd_soc_pcm_runtime *rtd = substream->private_data; | ||
146 | struct snd_soc_dai *codec_dai = rtd->codec_dai; | ||
147 | int ret; | ||
148 | |||
149 | ret = snd_soc_dai_set_sysclk(codec_dai, RT5677_SCLK_S_MCLK, 24576000, | ||
150 | SND_SOC_CLOCK_IN); | ||
151 | if (ret < 0) { | ||
152 | dev_err(rtd->dev, "can't set codec sysclk configuration\n"); | ||
153 | return ret; | ||
154 | } | ||
155 | |||
156 | return ret; | ||
157 | } | ||
158 | |||
159 | static struct snd_soc_ops bdw_rt5677_ops = { | ||
160 | .hw_params = bdw_rt5677_hw_params, | ||
161 | }; | ||
162 | |||
163 | static int bdw_rt5677_rtd_init(struct snd_soc_pcm_runtime *rtd) | ||
164 | { | ||
165 | struct sst_pdata *pdata = dev_get_platdata(rtd->platform->dev); | ||
166 | struct sst_hsw *broadwell = pdata->dsp; | ||
167 | int ret; | ||
168 | |||
169 | /* Set ADSP SSP port settings */ | ||
170 | ret = sst_hsw_device_set_config(broadwell, SST_HSW_DEVICE_SSP_0, | ||
171 | SST_HSW_DEVICE_MCLK_FREQ_24_MHZ, | ||
172 | SST_HSW_DEVICE_CLOCK_MASTER, 9); | ||
173 | if (ret < 0) { | ||
174 | dev_err(rtd->dev, "error: failed to set device config\n"); | ||
175 | return ret; | ||
176 | } | ||
177 | |||
178 | return 0; | ||
179 | } | ||
180 | |||
181 | static int bdw_rt5677_init(struct snd_soc_pcm_runtime *rtd) | ||
182 | { | ||
183 | struct bdw_rt5677_priv *bdw_rt5677 = | ||
184 | snd_soc_card_get_drvdata(rtd->card); | ||
185 | struct snd_soc_codec *codec = rtd->codec; | ||
186 | struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec); | ||
187 | |||
188 | /* Enable codec ASRC function for Stereo DAC/Stereo1 ADC/DMIC/I2S1. | ||
189 | * The ASRC clock source is clk_i2s1_asrc. | ||
190 | */ | ||
191 | rt5677_sel_asrc_clk_src(codec, RT5677_DA_STEREO_FILTER | | ||
192 | RT5677_AD_STEREO1_FILTER | RT5677_I2S1_SOURCE, | ||
193 | RT5677_CLK_SEL_I2S1_ASRC); | ||
194 | |||
195 | /* Request rt5677 GPIO for headphone amp control */ | ||
196 | bdw_rt5677->gpio_hp_en = devm_gpiod_get_index(codec->dev, | ||
197 | "headphone-enable", 0, 0); | ||
198 | if (IS_ERR(bdw_rt5677->gpio_hp_en)) { | ||
199 | dev_err(codec->dev, "Can't find HP_AMP_SHDN_L gpio\n"); | ||
200 | return PTR_ERR(bdw_rt5677->gpio_hp_en); | ||
201 | } | ||
202 | gpiod_direction_output(bdw_rt5677->gpio_hp_en, 0); | ||
203 | |||
204 | /* Create and initialize headphone jack */ | ||
205 | if (!snd_soc_card_jack_new(rtd->card, "Headphone Jack", | ||
206 | SND_JACK_HEADPHONE, &headphone_jack, | ||
207 | &headphone_jack_pin, 1)) { | ||
208 | headphone_jack_gpio.gpiod_dev = codec->dev; | ||
209 | if (snd_soc_jack_add_gpios(&headphone_jack, 1, | ||
210 | &headphone_jack_gpio)) | ||
211 | dev_err(codec->dev, "Can't add headphone jack gpio\n"); | ||
212 | } else { | ||
213 | dev_err(codec->dev, "Can't create headphone jack\n"); | ||
214 | } | ||
215 | |||
216 | /* Create and initialize mic jack */ | ||
217 | if (!snd_soc_card_jack_new(rtd->card, "Mic Jack", | ||
218 | SND_JACK_MICROPHONE, &mic_jack, | ||
219 | &mic_jack_pin, 1)) { | ||
220 | mic_jack_gpio.gpiod_dev = codec->dev; | ||
221 | if (snd_soc_jack_add_gpios(&mic_jack, 1, &mic_jack_gpio)) | ||
222 | dev_err(codec->dev, "Can't add mic jack gpio\n"); | ||
223 | } else { | ||
224 | dev_err(codec->dev, "Can't create mic jack\n"); | ||
225 | } | ||
226 | bdw_rt5677->codec = codec; | ||
227 | |||
228 | snd_soc_dapm_force_enable_pin(dapm, "MICBIAS1"); | ||
229 | return 0; | ||
230 | } | ||
231 | |||
232 | /* broadwell digital audio interface glue - connects codec <--> CPU */ | ||
233 | static struct snd_soc_dai_link bdw_rt5677_dais[] = { | ||
234 | /* Front End DAI links */ | ||
235 | { | ||
236 | .name = "System PCM", | ||
237 | .stream_name = "System Playback/Capture", | ||
238 | .cpu_dai_name = "System Pin", | ||
239 | .platform_name = "haswell-pcm-audio", | ||
240 | .dynamic = 1, | ||
241 | .codec_name = "snd-soc-dummy", | ||
242 | .codec_dai_name = "snd-soc-dummy-dai", | ||
243 | .init = bdw_rt5677_rtd_init, | ||
244 | .trigger = { | ||
245 | SND_SOC_DPCM_TRIGGER_POST, | ||
246 | SND_SOC_DPCM_TRIGGER_POST | ||
247 | }, | ||
248 | .dpcm_capture = 1, | ||
249 | .dpcm_playback = 1, | ||
250 | }, | ||
251 | |||
252 | /* Back End DAI links */ | ||
253 | { | ||
254 | /* SSP0 - Codec */ | ||
255 | .name = "Codec", | ||
256 | .id = 0, | ||
257 | .cpu_dai_name = "snd-soc-dummy-dai", | ||
258 | .platform_name = "snd-soc-dummy", | ||
259 | .no_pcm = 1, | ||
260 | .codec_name = "i2c-RT5677CE:00", | ||
261 | .codec_dai_name = "rt5677-aif1", | ||
262 | .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | | ||
263 | SND_SOC_DAIFMT_CBS_CFS, | ||
264 | .ignore_suspend = 1, | ||
265 | .ignore_pmdown_time = 1, | ||
266 | .be_hw_params_fixup = broadwell_ssp0_fixup, | ||
267 | .ops = &bdw_rt5677_ops, | ||
268 | .dpcm_playback = 1, | ||
269 | .dpcm_capture = 1, | ||
270 | .init = bdw_rt5677_init, | ||
271 | }, | ||
272 | }; | ||
273 | |||
274 | static int bdw_rt5677_suspend_pre(struct snd_soc_card *card) | ||
275 | { | ||
276 | struct bdw_rt5677_priv *bdw_rt5677 = snd_soc_card_get_drvdata(card); | ||
277 | struct snd_soc_dapm_context *dapm; | ||
278 | |||
279 | if (bdw_rt5677->codec) { | ||
280 | dapm = snd_soc_codec_get_dapm(bdw_rt5677->codec); | ||
281 | snd_soc_dapm_disable_pin(dapm, "MICBIAS1"); | ||
282 | } | ||
283 | return 0; | ||
284 | } | ||
285 | |||
286 | static int bdw_rt5677_resume_post(struct snd_soc_card *card) | ||
287 | { | ||
288 | struct bdw_rt5677_priv *bdw_rt5677 = snd_soc_card_get_drvdata(card); | ||
289 | struct snd_soc_dapm_context *dapm; | ||
290 | |||
291 | if (bdw_rt5677->codec) { | ||
292 | dapm = snd_soc_codec_get_dapm(bdw_rt5677->codec); | ||
293 | snd_soc_dapm_force_enable_pin(dapm, "MICBIAS1"); | ||
294 | } | ||
295 | return 0; | ||
296 | } | ||
297 | |||
298 | /* ASoC machine driver for Broadwell DSP + RT5677 */ | ||
299 | static struct snd_soc_card bdw_rt5677_card = { | ||
300 | .name = "bdw-rt5677", | ||
301 | .owner = THIS_MODULE, | ||
302 | .dai_link = bdw_rt5677_dais, | ||
303 | .num_links = ARRAY_SIZE(bdw_rt5677_dais), | ||
304 | .dapm_widgets = bdw_rt5677_widgets, | ||
305 | .num_dapm_widgets = ARRAY_SIZE(bdw_rt5677_widgets), | ||
306 | .dapm_routes = bdw_rt5677_map, | ||
307 | .num_dapm_routes = ARRAY_SIZE(bdw_rt5677_map), | ||
308 | .controls = bdw_rt5677_controls, | ||
309 | .num_controls = ARRAY_SIZE(bdw_rt5677_controls), | ||
310 | .fully_routed = true, | ||
311 | .suspend_pre = bdw_rt5677_suspend_pre, | ||
312 | .resume_post = bdw_rt5677_resume_post, | ||
313 | }; | ||
314 | |||
315 | static int bdw_rt5677_probe(struct platform_device *pdev) | ||
316 | { | ||
317 | struct bdw_rt5677_priv *bdw_rt5677; | ||
318 | |||
319 | bdw_rt5677_card.dev = &pdev->dev; | ||
320 | |||
321 | /* Allocate driver private struct */ | ||
322 | bdw_rt5677 = devm_kzalloc(&pdev->dev, sizeof(struct bdw_rt5677_priv), | ||
323 | GFP_KERNEL); | ||
324 | if (!bdw_rt5677) { | ||
325 | dev_err(&pdev->dev, "Can't allocate bdw_rt5677\n"); | ||
326 | return -ENOMEM; | ||
327 | } | ||
328 | |||
329 | snd_soc_card_set_drvdata(&bdw_rt5677_card, bdw_rt5677); | ||
330 | |||
331 | return devm_snd_soc_register_card(&pdev->dev, &bdw_rt5677_card); | ||
332 | } | ||
333 | |||
334 | static struct platform_driver bdw_rt5677_audio = { | ||
335 | .probe = bdw_rt5677_probe, | ||
336 | .driver = { | ||
337 | .name = "bdw-rt5677", | ||
338 | }, | ||
339 | }; | ||
340 | |||
341 | module_platform_driver(bdw_rt5677_audio) | ||
342 | |||
343 | /* Module information */ | ||
344 | MODULE_AUTHOR("Ben Zhang"); | ||
345 | MODULE_DESCRIPTION("Intel Broadwell RT5677 machine driver"); | ||
346 | MODULE_LICENSE("GPL v2"); | ||
347 | MODULE_ALIAS("platform:bdw-rt5677"); | ||
diff --git a/sound/soc/intel/boards/bxt_da7219_max98357a.c b/sound/soc/intel/boards/bxt_da7219_max98357a.c index 3774b117d365..6532b8f0ab2f 100644 --- a/sound/soc/intel/boards/bxt_da7219_max98357a.c +++ b/sound/soc/intel/boards/bxt_da7219_max98357a.c | |||
@@ -37,6 +37,7 @@ enum { | |||
37 | BXT_DPCM_AUDIO_PB = 0, | 37 | BXT_DPCM_AUDIO_PB = 0, |
38 | BXT_DPCM_AUDIO_CP, | 38 | BXT_DPCM_AUDIO_CP, |
39 | BXT_DPCM_AUDIO_REF_CP, | 39 | BXT_DPCM_AUDIO_REF_CP, |
40 | BXT_DPCM_AUDIO_DMIC_CP, | ||
40 | BXT_DPCM_AUDIO_HDMI1_PB, | 41 | BXT_DPCM_AUDIO_HDMI1_PB, |
41 | BXT_DPCM_AUDIO_HDMI2_PB, | 42 | BXT_DPCM_AUDIO_HDMI2_PB, |
42 | BXT_DPCM_AUDIO_HDMI3_PB, | 43 | BXT_DPCM_AUDIO_HDMI3_PB, |
@@ -252,10 +253,56 @@ static struct snd_soc_ops broxton_da7219_ops = { | |||
252 | .hw_free = broxton_da7219_hw_free, | 253 | .hw_free = broxton_da7219_hw_free, |
253 | }; | 254 | }; |
254 | 255 | ||
256 | static int broxton_dmic_fixup(struct snd_soc_pcm_runtime *rtd, | ||
257 | struct snd_pcm_hw_params *params) | ||
258 | { | ||
259 | struct snd_interval *channels = hw_param_interval(params, | ||
260 | SNDRV_PCM_HW_PARAM_CHANNELS); | ||
261 | channels->min = channels->max = DUAL_CHANNEL; | ||
262 | |||
263 | return 0; | ||
264 | } | ||
265 | |||
266 | static int broxton_dmic_startup(struct snd_pcm_substream *substream) | ||
267 | { | ||
268 | struct snd_pcm_runtime *runtime = substream->runtime; | ||
269 | |||
270 | runtime->hw.channels_max = DUAL_CHANNEL; | ||
271 | snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS, | ||
272 | &constraints_channels); | ||
273 | |||
274 | return snd_pcm_hw_constraint_list(substream->runtime, 0, | ||
275 | SNDRV_PCM_HW_PARAM_RATE, &constraints_rates); | ||
276 | } | ||
277 | |||
278 | static const struct snd_soc_ops broxton_dmic_ops = { | ||
279 | .startup = broxton_dmic_startup, | ||
280 | }; | ||
281 | |||
282 | static const unsigned int rates_16000[] = { | ||
283 | 16000, | ||
284 | }; | ||
285 | |||
286 | static const struct snd_pcm_hw_constraint_list constraints_16000 = { | ||
287 | .count = ARRAY_SIZE(rates_16000), | ||
288 | .list = rates_16000, | ||
289 | }; | ||
290 | |||
291 | static int broxton_refcap_startup(struct snd_pcm_substream *substream) | ||
292 | { | ||
293 | return snd_pcm_hw_constraint_list(substream->runtime, 0, | ||
294 | SNDRV_PCM_HW_PARAM_RATE, | ||
295 | &constraints_16000); | ||
296 | }; | ||
297 | |||
298 | static struct snd_soc_ops broxton_refcap_ops = { | ||
299 | .startup = broxton_refcap_startup, | ||
300 | }; | ||
301 | |||
255 | /* broxton digital audio interface glue - connects codec <--> CPU */ | 302 | /* broxton digital audio interface glue - connects codec <--> CPU */ |
256 | static struct snd_soc_dai_link broxton_dais[] = { | 303 | static struct snd_soc_dai_link broxton_dais[] = { |
257 | /* Front End DAI links */ | 304 | /* Front End DAI links */ |
258 | [BXT_DPCM_AUDIO_PB] | 305 | [BXT_DPCM_AUDIO_PB] = |
259 | { | 306 | { |
260 | .name = "Bxt Audio Port", | 307 | .name = "Bxt Audio Port", |
261 | .stream_name = "Audio", | 308 | .stream_name = "Audio", |
@@ -271,7 +318,7 @@ static struct snd_soc_dai_link broxton_dais[] = { | |||
271 | .dpcm_playback = 1, | 318 | .dpcm_playback = 1, |
272 | .ops = &broxton_da7219_fe_ops, | 319 | .ops = &broxton_da7219_fe_ops, |
273 | }, | 320 | }, |
274 | [BXT_DPCM_AUDIO_CP] | 321 | [BXT_DPCM_AUDIO_CP] = |
275 | { | 322 | { |
276 | .name = "Bxt Audio Capture Port", | 323 | .name = "Bxt Audio Capture Port", |
277 | .stream_name = "Audio Record", | 324 | .stream_name = "Audio Record", |
@@ -286,7 +333,7 @@ static struct snd_soc_dai_link broxton_dais[] = { | |||
286 | .dpcm_capture = 1, | 333 | .dpcm_capture = 1, |
287 | .ops = &broxton_da7219_fe_ops, | 334 | .ops = &broxton_da7219_fe_ops, |
288 | }, | 335 | }, |
289 | [BXT_DPCM_AUDIO_REF_CP] | 336 | [BXT_DPCM_AUDIO_REF_CP] = |
290 | { | 337 | { |
291 | .name = "Bxt Audio Reference cap", | 338 | .name = "Bxt Audio Reference cap", |
292 | .stream_name = "Refcap", | 339 | .stream_name = "Refcap", |
@@ -299,8 +346,23 @@ static struct snd_soc_dai_link broxton_dais[] = { | |||
299 | .ignore_suspend = 1, | 346 | .ignore_suspend = 1, |
300 | .nonatomic = 1, | 347 | .nonatomic = 1, |
301 | .dynamic = 1, | 348 | .dynamic = 1, |
349 | .ops = &broxton_refcap_ops, | ||
350 | }, | ||
351 | [BXT_DPCM_AUDIO_DMIC_CP] | ||
352 | { | ||
353 | .name = "Bxt Audio DMIC cap", | ||
354 | .stream_name = "dmiccap", | ||
355 | .cpu_dai_name = "DMIC Pin", | ||
356 | .codec_name = "snd-soc-dummy", | ||
357 | .codec_dai_name = "snd-soc-dummy-dai", | ||
358 | .platform_name = "0000:00:0e.0", | ||
359 | .init = NULL, | ||
360 | .dpcm_capture = 1, | ||
361 | .nonatomic = 1, | ||
362 | .dynamic = 1, | ||
363 | .ops = &broxton_dmic_ops, | ||
302 | }, | 364 | }, |
303 | [BXT_DPCM_AUDIO_HDMI1_PB] | 365 | [BXT_DPCM_AUDIO_HDMI1_PB] = |
304 | { | 366 | { |
305 | .name = "Bxt HDMI Port1", | 367 | .name = "Bxt HDMI Port1", |
306 | .stream_name = "Hdmi1", | 368 | .stream_name = "Hdmi1", |
@@ -313,7 +375,7 @@ static struct snd_soc_dai_link broxton_dais[] = { | |||
313 | .nonatomic = 1, | 375 | .nonatomic = 1, |
314 | .dynamic = 1, | 376 | .dynamic = 1, |
315 | }, | 377 | }, |
316 | [BXT_DPCM_AUDIO_HDMI2_PB] | 378 | [BXT_DPCM_AUDIO_HDMI2_PB] = |
317 | { | 379 | { |
318 | .name = "Bxt HDMI Port2", | 380 | .name = "Bxt HDMI Port2", |
319 | .stream_name = "Hdmi2", | 381 | .stream_name = "Hdmi2", |
@@ -326,7 +388,7 @@ static struct snd_soc_dai_link broxton_dais[] = { | |||
326 | .nonatomic = 1, | 388 | .nonatomic = 1, |
327 | .dynamic = 1, | 389 | .dynamic = 1, |
328 | }, | 390 | }, |
329 | [BXT_DPCM_AUDIO_HDMI3_PB] | 391 | [BXT_DPCM_AUDIO_HDMI3_PB] = |
330 | { | 392 | { |
331 | .name = "Bxt HDMI Port3", | 393 | .name = "Bxt HDMI Port3", |
332 | .stream_name = "Hdmi3", | 394 | .stream_name = "Hdmi3", |
@@ -382,6 +444,7 @@ static struct snd_soc_dai_link broxton_dais[] = { | |||
382 | .codec_dai_name = "dmic-hifi", | 444 | .codec_dai_name = "dmic-hifi", |
383 | .platform_name = "0000:00:0e.0", | 445 | .platform_name = "0000:00:0e.0", |
384 | .ignore_suspend = 1, | 446 | .ignore_suspend = 1, |
447 | .be_hw_params_fixup = broxton_dmic_fixup, | ||
385 | .dpcm_capture = 1, | 448 | .dpcm_capture = 1, |
386 | .no_pcm = 1, | 449 | .no_pcm = 1, |
387 | }, | 450 | }, |
diff --git a/sound/soc/intel/boards/bxt_rt298.c b/sound/soc/intel/boards/bxt_rt298.c index 253d7bfbf511..d610bdca1608 100644 --- a/sound/soc/intel/boards/bxt_rt298.c +++ b/sound/soc/intel/boards/bxt_rt298.c | |||
@@ -271,7 +271,7 @@ static const struct snd_soc_ops broxton_rt286_fe_ops = { | |||
271 | /* broxton digital audio interface glue - connects codec <--> CPU */ | 271 | /* broxton digital audio interface glue - connects codec <--> CPU */ |
272 | static struct snd_soc_dai_link broxton_rt298_dais[] = { | 272 | static struct snd_soc_dai_link broxton_rt298_dais[] = { |
273 | /* Front End DAI links */ | 273 | /* Front End DAI links */ |
274 | [BXT_DPCM_AUDIO_PB] | 274 | [BXT_DPCM_AUDIO_PB] = |
275 | { | 275 | { |
276 | .name = "Bxt Audio Port", | 276 | .name = "Bxt Audio Port", |
277 | .stream_name = "Audio", | 277 | .stream_name = "Audio", |
@@ -286,7 +286,7 @@ static struct snd_soc_dai_link broxton_rt298_dais[] = { | |||
286 | .dpcm_playback = 1, | 286 | .dpcm_playback = 1, |
287 | .ops = &broxton_rt286_fe_ops, | 287 | .ops = &broxton_rt286_fe_ops, |
288 | }, | 288 | }, |
289 | [BXT_DPCM_AUDIO_CP] | 289 | [BXT_DPCM_AUDIO_CP] = |
290 | { | 290 | { |
291 | .name = "Bxt Audio Capture Port", | 291 | .name = "Bxt Audio Capture Port", |
292 | .stream_name = "Audio Record", | 292 | .stream_name = "Audio Record", |
@@ -300,7 +300,7 @@ static struct snd_soc_dai_link broxton_rt298_dais[] = { | |||
300 | .dpcm_capture = 1, | 300 | .dpcm_capture = 1, |
301 | .ops = &broxton_rt286_fe_ops, | 301 | .ops = &broxton_rt286_fe_ops, |
302 | }, | 302 | }, |
303 | [BXT_DPCM_AUDIO_REF_CP] | 303 | [BXT_DPCM_AUDIO_REF_CP] = |
304 | { | 304 | { |
305 | .name = "Bxt Audio Reference cap", | 305 | .name = "Bxt Audio Reference cap", |
306 | .stream_name = "refcap", | 306 | .stream_name = "refcap", |
@@ -313,7 +313,7 @@ static struct snd_soc_dai_link broxton_rt298_dais[] = { | |||
313 | .nonatomic = 1, | 313 | .nonatomic = 1, |
314 | .dynamic = 1, | 314 | .dynamic = 1, |
315 | }, | 315 | }, |
316 | [BXT_DPCM_AUDIO_DMIC_CP] | 316 | [BXT_DPCM_AUDIO_DMIC_CP] = |
317 | { | 317 | { |
318 | .name = "Bxt Audio DMIC cap", | 318 | .name = "Bxt Audio DMIC cap", |
319 | .stream_name = "dmiccap", | 319 | .stream_name = "dmiccap", |
@@ -327,7 +327,7 @@ static struct snd_soc_dai_link broxton_rt298_dais[] = { | |||
327 | .dynamic = 1, | 327 | .dynamic = 1, |
328 | .ops = &broxton_dmic_ops, | 328 | .ops = &broxton_dmic_ops, |
329 | }, | 329 | }, |
330 | [BXT_DPCM_AUDIO_HDMI1_PB] | 330 | [BXT_DPCM_AUDIO_HDMI1_PB] = |
331 | { | 331 | { |
332 | .name = "Bxt HDMI Port1", | 332 | .name = "Bxt HDMI Port1", |
333 | .stream_name = "Hdmi1", | 333 | .stream_name = "Hdmi1", |
@@ -340,7 +340,7 @@ static struct snd_soc_dai_link broxton_rt298_dais[] = { | |||
340 | .nonatomic = 1, | 340 | .nonatomic = 1, |
341 | .dynamic = 1, | 341 | .dynamic = 1, |
342 | }, | 342 | }, |
343 | [BXT_DPCM_AUDIO_HDMI2_PB] | 343 | [BXT_DPCM_AUDIO_HDMI2_PB] = |
344 | { | 344 | { |
345 | .name = "Bxt HDMI Port2", | 345 | .name = "Bxt HDMI Port2", |
346 | .stream_name = "Hdmi2", | 346 | .stream_name = "Hdmi2", |
@@ -353,7 +353,7 @@ static struct snd_soc_dai_link broxton_rt298_dais[] = { | |||
353 | .nonatomic = 1, | 353 | .nonatomic = 1, |
354 | .dynamic = 1, | 354 | .dynamic = 1, |
355 | }, | 355 | }, |
356 | [BXT_DPCM_AUDIO_HDMI3_PB] | 356 | [BXT_DPCM_AUDIO_HDMI3_PB] = |
357 | { | 357 | { |
358 | .name = "Bxt HDMI Port3", | 358 | .name = "Bxt HDMI Port3", |
359 | .stream_name = "Hdmi3", | 359 | .stream_name = "Hdmi3", |
diff --git a/sound/soc/intel/boards/bytcr_rt5640.c b/sound/soc/intel/boards/bytcr_rt5640.c index 88efb62439ba..bff77a1f27fc 100644 --- a/sound/soc/intel/boards/bytcr_rt5640.c +++ b/sound/soc/intel/boards/bytcr_rt5640.c | |||
@@ -24,6 +24,9 @@ | |||
24 | #include <linux/device.h> | 24 | #include <linux/device.h> |
25 | #include <linux/dmi.h> | 25 | #include <linux/dmi.h> |
26 | #include <linux/slab.h> | 26 | #include <linux/slab.h> |
27 | #include <asm/cpu_device_id.h> | ||
28 | #include <asm/platform_sst_audio.h> | ||
29 | #include <linux/clk.h> | ||
27 | #include <sound/pcm.h> | 30 | #include <sound/pcm.h> |
28 | #include <sound/pcm_params.h> | 31 | #include <sound/pcm_params.h> |
29 | #include <sound/soc.h> | 32 | #include <sound/soc.h> |
@@ -31,42 +34,153 @@ | |||
31 | #include "../../codecs/rt5640.h" | 34 | #include "../../codecs/rt5640.h" |
32 | #include "../atom/sst-atom-controls.h" | 35 | #include "../atom/sst-atom-controls.h" |
33 | #include "../common/sst-acpi.h" | 36 | #include "../common/sst-acpi.h" |
37 | #include "../common/sst-dsp.h" | ||
34 | 38 | ||
35 | enum { | 39 | enum { |
36 | BYT_RT5640_DMIC1_MAP, | 40 | BYT_RT5640_DMIC1_MAP, |
37 | BYT_RT5640_DMIC2_MAP, | 41 | BYT_RT5640_DMIC2_MAP, |
38 | BYT_RT5640_IN1_MAP, | 42 | BYT_RT5640_IN1_MAP, |
43 | BYT_RT5640_IN3_MAP, | ||
39 | }; | 44 | }; |
40 | 45 | ||
41 | #define BYT_RT5640_MAP(quirk) ((quirk) & 0xff) | 46 | #define BYT_RT5640_MAP(quirk) ((quirk) & 0xff) |
42 | #define BYT_RT5640_DMIC_EN BIT(16) | 47 | #define BYT_RT5640_DMIC_EN BIT(16) |
48 | #define BYT_RT5640_MONO_SPEAKER BIT(17) | ||
49 | #define BYT_RT5640_DIFF_MIC BIT(18) /* defaut is single-ended */ | ||
50 | #define BYT_RT5640_SSP2_AIF2 BIT(19) /* default is using AIF1 */ | ||
51 | #define BYT_RT5640_SSP0_AIF1 BIT(20) | ||
52 | #define BYT_RT5640_SSP0_AIF2 BIT(21) | ||
53 | #define BYT_RT5640_MCLK_EN BIT(22) | ||
54 | #define BYT_RT5640_MCLK_25MHZ BIT(23) | ||
55 | |||
56 | struct byt_rt5640_private { | ||
57 | struct clk *mclk; | ||
58 | }; | ||
43 | 59 | ||
44 | static unsigned long byt_rt5640_quirk = BYT_RT5640_DMIC1_MAP | | 60 | static unsigned long byt_rt5640_quirk = BYT_RT5640_DMIC1_MAP | |
45 | BYT_RT5640_DMIC_EN; | 61 | BYT_RT5640_DMIC_EN | |
62 | BYT_RT5640_MCLK_EN; | ||
63 | |||
64 | static void log_quirks(struct device *dev) | ||
65 | { | ||
66 | if (BYT_RT5640_MAP(byt_rt5640_quirk) == BYT_RT5640_DMIC1_MAP) | ||
67 | dev_info(dev, "quirk DMIC1_MAP enabled"); | ||
68 | if (BYT_RT5640_MAP(byt_rt5640_quirk) == BYT_RT5640_DMIC2_MAP) | ||
69 | dev_info(dev, "quirk DMIC2_MAP enabled"); | ||
70 | if (BYT_RT5640_MAP(byt_rt5640_quirk) == BYT_RT5640_IN1_MAP) | ||
71 | dev_info(dev, "quirk IN1_MAP enabled"); | ||
72 | if (BYT_RT5640_MAP(byt_rt5640_quirk) == BYT_RT5640_IN3_MAP) | ||
73 | dev_info(dev, "quirk IN3_MAP enabled"); | ||
74 | if (byt_rt5640_quirk & BYT_RT5640_DMIC_EN) | ||
75 | dev_info(dev, "quirk DMIC enabled"); | ||
76 | if (byt_rt5640_quirk & BYT_RT5640_MONO_SPEAKER) | ||
77 | dev_info(dev, "quirk MONO_SPEAKER enabled"); | ||
78 | if (byt_rt5640_quirk & BYT_RT5640_DIFF_MIC) | ||
79 | dev_info(dev, "quirk DIFF_MIC enabled"); | ||
80 | if (byt_rt5640_quirk & BYT_RT5640_SSP2_AIF2) | ||
81 | dev_info(dev, "quirk SSP2_AIF2 enabled"); | ||
82 | if (byt_rt5640_quirk & BYT_RT5640_SSP0_AIF1) | ||
83 | dev_info(dev, "quirk SSP0_AIF1 enabled"); | ||
84 | if (byt_rt5640_quirk & BYT_RT5640_SSP0_AIF2) | ||
85 | dev_info(dev, "quirk SSP0_AIF2 enabled"); | ||
86 | if (byt_rt5640_quirk & BYT_RT5640_MCLK_EN) | ||
87 | dev_info(dev, "quirk MCLK_EN enabled"); | ||
88 | if (byt_rt5640_quirk & BYT_RT5640_MCLK_25MHZ) | ||
89 | dev_info(dev, "quirk MCLK_25MHZ enabled"); | ||
90 | } | ||
91 | |||
92 | |||
93 | #define BYT_CODEC_DAI1 "rt5640-aif1" | ||
94 | #define BYT_CODEC_DAI2 "rt5640-aif2" | ||
95 | |||
96 | static inline struct snd_soc_dai *byt_get_codec_dai(struct snd_soc_card *card) | ||
97 | { | ||
98 | struct snd_soc_pcm_runtime *rtd; | ||
99 | |||
100 | list_for_each_entry(rtd, &card->rtd_list, list) { | ||
101 | if (!strncmp(rtd->codec_dai->name, BYT_CODEC_DAI1, | ||
102 | strlen(BYT_CODEC_DAI1))) | ||
103 | return rtd->codec_dai; | ||
104 | if (!strncmp(rtd->codec_dai->name, BYT_CODEC_DAI2, | ||
105 | strlen(BYT_CODEC_DAI2))) | ||
106 | return rtd->codec_dai; | ||
107 | |||
108 | } | ||
109 | return NULL; | ||
110 | } | ||
111 | |||
112 | static int platform_clock_control(struct snd_soc_dapm_widget *w, | ||
113 | struct snd_kcontrol *k, int event) | ||
114 | { | ||
115 | struct snd_soc_dapm_context *dapm = w->dapm; | ||
116 | struct snd_soc_card *card = dapm->card; | ||
117 | struct snd_soc_dai *codec_dai; | ||
118 | struct byt_rt5640_private *priv = snd_soc_card_get_drvdata(card); | ||
119 | int ret; | ||
120 | |||
121 | codec_dai = byt_get_codec_dai(card); | ||
122 | if (!codec_dai) { | ||
123 | dev_err(card->dev, | ||
124 | "Codec dai not found; Unable to set platform clock\n"); | ||
125 | return -EIO; | ||
126 | } | ||
127 | |||
128 | if (SND_SOC_DAPM_EVENT_ON(event)) { | ||
129 | if ((byt_rt5640_quirk & BYT_RT5640_MCLK_EN) && priv->mclk) { | ||
130 | ret = clk_prepare_enable(priv->mclk); | ||
131 | if (ret < 0) { | ||
132 | dev_err(card->dev, | ||
133 | "could not configure MCLK state"); | ||
134 | return ret; | ||
135 | } | ||
136 | } | ||
137 | ret = snd_soc_dai_set_sysclk(codec_dai, RT5640_SCLK_S_PLL1, | ||
138 | 48000 * 512, | ||
139 | SND_SOC_CLOCK_IN); | ||
140 | } else { | ||
141 | /* | ||
142 | * Set codec clock source to internal clock before | ||
143 | * turning off the platform clock. Codec needs clock | ||
144 | * for Jack detection and button press | ||
145 | */ | ||
146 | ret = snd_soc_dai_set_sysclk(codec_dai, RT5640_SCLK_S_RCCLK, | ||
147 | 0, | ||
148 | SND_SOC_CLOCK_IN); | ||
149 | if (!ret) { | ||
150 | if ((byt_rt5640_quirk & BYT_RT5640_MCLK_EN) && priv->mclk) | ||
151 | clk_disable_unprepare(priv->mclk); | ||
152 | } | ||
153 | } | ||
154 | |||
155 | if (ret < 0) { | ||
156 | dev_err(card->dev, "can't set codec sysclk: %d\n", ret); | ||
157 | return ret; | ||
158 | } | ||
159 | |||
160 | return 0; | ||
161 | } | ||
46 | 162 | ||
47 | static const struct snd_soc_dapm_widget byt_rt5640_widgets[] = { | 163 | static const struct snd_soc_dapm_widget byt_rt5640_widgets[] = { |
48 | SND_SOC_DAPM_HP("Headphone", NULL), | 164 | SND_SOC_DAPM_HP("Headphone", NULL), |
49 | SND_SOC_DAPM_MIC("Headset Mic", NULL), | 165 | SND_SOC_DAPM_MIC("Headset Mic", NULL), |
50 | SND_SOC_DAPM_MIC("Internal Mic", NULL), | 166 | SND_SOC_DAPM_MIC("Internal Mic", NULL), |
51 | SND_SOC_DAPM_SPK("Speaker", NULL), | 167 | SND_SOC_DAPM_SPK("Speaker", NULL), |
168 | SND_SOC_DAPM_SUPPLY("Platform Clock", SND_SOC_NOPM, 0, 0, | ||
169 | platform_clock_control, SND_SOC_DAPM_PRE_PMU | | ||
170 | SND_SOC_DAPM_POST_PMD), | ||
171 | |||
52 | }; | 172 | }; |
53 | 173 | ||
54 | static const struct snd_soc_dapm_route byt_rt5640_audio_map[] = { | 174 | static const struct snd_soc_dapm_route byt_rt5640_audio_map[] = { |
55 | {"AIF1 Playback", NULL, "ssp2 Tx"}, | 175 | {"Headphone", NULL, "Platform Clock"}, |
56 | {"ssp2 Tx", NULL, "codec_out0"}, | 176 | {"Headset Mic", NULL, "Platform Clock"}, |
57 | {"ssp2 Tx", NULL, "codec_out1"}, | 177 | {"Internal Mic", NULL, "Platform Clock"}, |
58 | {"codec_in0", NULL, "ssp2 Rx"}, | 178 | {"Speaker", NULL, "Platform Clock"}, |
59 | {"codec_in1", NULL, "ssp2 Rx"}, | ||
60 | {"ssp2 Rx", NULL, "AIF1 Capture"}, | ||
61 | 179 | ||
62 | {"Headset Mic", NULL, "MICBIAS1"}, | 180 | {"Headset Mic", NULL, "MICBIAS1"}, |
63 | {"IN2P", NULL, "Headset Mic"}, | 181 | {"IN2P", NULL, "Headset Mic"}, |
64 | {"Headphone", NULL, "HPOL"}, | 182 | {"Headphone", NULL, "HPOL"}, |
65 | {"Headphone", NULL, "HPOR"}, | 183 | {"Headphone", NULL, "HPOR"}, |
66 | {"Speaker", NULL, "SPOLP"}, | ||
67 | {"Speaker", NULL, "SPOLN"}, | ||
68 | {"Speaker", NULL, "SPORP"}, | ||
69 | {"Speaker", NULL, "SPORN"}, | ||
70 | }; | 184 | }; |
71 | 185 | ||
72 | static const struct snd_soc_dapm_route byt_rt5640_intmic_dmic1_map[] = { | 186 | static const struct snd_soc_dapm_route byt_rt5640_intmic_dmic1_map[] = { |
@@ -82,6 +196,59 @@ static const struct snd_soc_dapm_route byt_rt5640_intmic_in1_map[] = { | |||
82 | {"IN1P", NULL, "Internal Mic"}, | 196 | {"IN1P", NULL, "Internal Mic"}, |
83 | }; | 197 | }; |
84 | 198 | ||
199 | static const struct snd_soc_dapm_route byt_rt5640_intmic_in3_map[] = { | ||
200 | {"Internal Mic", NULL, "MICBIAS1"}, | ||
201 | {"IN3P", NULL, "Internal Mic"}, | ||
202 | }; | ||
203 | |||
204 | static const struct snd_soc_dapm_route byt_rt5640_ssp2_aif1_map[] = { | ||
205 | {"ssp2 Tx", NULL, "codec_out0"}, | ||
206 | {"ssp2 Tx", NULL, "codec_out1"}, | ||
207 | {"codec_in0", NULL, "ssp2 Rx"}, | ||
208 | {"codec_in1", NULL, "ssp2 Rx"}, | ||
209 | |||
210 | {"AIF1 Playback", NULL, "ssp2 Tx"}, | ||
211 | {"ssp2 Rx", NULL, "AIF1 Capture"}, | ||
212 | }; | ||
213 | |||
214 | static const struct snd_soc_dapm_route byt_rt5640_ssp2_aif2_map[] = { | ||
215 | {"ssp2 Tx", NULL, "codec_out0"}, | ||
216 | {"ssp2 Tx", NULL, "codec_out1"}, | ||
217 | {"codec_in0", NULL, "ssp2 Rx"}, | ||
218 | {"codec_in1", NULL, "ssp2 Rx"}, | ||
219 | |||
220 | {"AIF2 Playback", NULL, "ssp2 Tx"}, | ||
221 | {"ssp2 Rx", NULL, "AIF2 Capture"}, | ||
222 | }; | ||
223 | |||
224 | static const struct snd_soc_dapm_route byt_rt5640_ssp0_aif1_map[] = { | ||
225 | {"ssp0 Tx", NULL, "modem_out"}, | ||
226 | {"modem_in", NULL, "ssp0 Rx"}, | ||
227 | |||
228 | {"AIF1 Playback", NULL, "ssp0 Tx"}, | ||
229 | {"ssp0 Rx", NULL, "AIF1 Capture"}, | ||
230 | }; | ||
231 | |||
232 | static const struct snd_soc_dapm_route byt_rt5640_ssp0_aif2_map[] = { | ||
233 | {"ssp0 Tx", NULL, "modem_out"}, | ||
234 | {"modem_in", NULL, "ssp0 Rx"}, | ||
235 | |||
236 | {"AIF2 Playback", NULL, "ssp0 Tx"}, | ||
237 | {"ssp0 Rx", NULL, "AIF2 Capture"}, | ||
238 | }; | ||
239 | |||
240 | static const struct snd_soc_dapm_route byt_rt5640_stereo_spk_map[] = { | ||
241 | {"Speaker", NULL, "SPOLP"}, | ||
242 | {"Speaker", NULL, "SPOLN"}, | ||
243 | {"Speaker", NULL, "SPORP"}, | ||
244 | {"Speaker", NULL, "SPORN"}, | ||
245 | }; | ||
246 | |||
247 | static const struct snd_soc_dapm_route byt_rt5640_mono_spk_map[] = { | ||
248 | {"Speaker", NULL, "SPOLP"}, | ||
249 | {"Speaker", NULL, "SPOLN"}, | ||
250 | }; | ||
251 | |||
85 | static const struct snd_kcontrol_new byt_rt5640_controls[] = { | 252 | static const struct snd_kcontrol_new byt_rt5640_controls[] = { |
86 | SOC_DAPM_PIN_SWITCH("Headphone"), | 253 | SOC_DAPM_PIN_SWITCH("Headphone"), |
87 | SOC_DAPM_PIN_SWITCH("Headset Mic"), | 254 | SOC_DAPM_PIN_SWITCH("Headset Mic"), |
@@ -96,19 +263,46 @@ static int byt_rt5640_aif1_hw_params(struct snd_pcm_substream *substream, | |||
96 | struct snd_soc_dai *codec_dai = rtd->codec_dai; | 263 | struct snd_soc_dai *codec_dai = rtd->codec_dai; |
97 | int ret; | 264 | int ret; |
98 | 265 | ||
99 | snd_soc_dai_set_bclk_ratio(codec_dai, 50); | ||
100 | |||
101 | ret = snd_soc_dai_set_sysclk(codec_dai, RT5640_SCLK_S_PLL1, | 266 | ret = snd_soc_dai_set_sysclk(codec_dai, RT5640_SCLK_S_PLL1, |
102 | params_rate(params) * 512, | 267 | params_rate(params) * 512, |
103 | SND_SOC_CLOCK_IN); | 268 | SND_SOC_CLOCK_IN); |
269 | |||
104 | if (ret < 0) { | 270 | if (ret < 0) { |
105 | dev_err(rtd->dev, "can't set codec clock %d\n", ret); | 271 | dev_err(rtd->dev, "can't set codec clock %d\n", ret); |
106 | return ret; | 272 | return ret; |
107 | } | 273 | } |
108 | 274 | ||
109 | ret = snd_soc_dai_set_pll(codec_dai, 0, RT5640_PLL1_S_BCLK1, | 275 | if (!(byt_rt5640_quirk & BYT_RT5640_MCLK_EN)) { |
110 | params_rate(params) * 50, | 276 | /* use bitclock as PLL input */ |
111 | params_rate(params) * 512); | 277 | if ((byt_rt5640_quirk & BYT_RT5640_SSP0_AIF1) || |
278 | (byt_rt5640_quirk & BYT_RT5640_SSP0_AIF2)) { | ||
279 | |||
280 | /* 2x16 bit slots on SSP0 */ | ||
281 | ret = snd_soc_dai_set_pll(codec_dai, 0, | ||
282 | RT5640_PLL1_S_BCLK1, | ||
283 | params_rate(params) * 32, | ||
284 | params_rate(params) * 512); | ||
285 | } else { | ||
286 | /* 2x15 bit slots on SSP2 */ | ||
287 | ret = snd_soc_dai_set_pll(codec_dai, 0, | ||
288 | RT5640_PLL1_S_BCLK1, | ||
289 | params_rate(params) * 50, | ||
290 | params_rate(params) * 512); | ||
291 | } | ||
292 | } else { | ||
293 | if (byt_rt5640_quirk & BYT_RT5640_MCLK_25MHZ) { | ||
294 | ret = snd_soc_dai_set_pll(codec_dai, 0, | ||
295 | RT5640_PLL1_S_MCLK, | ||
296 | 25000000, | ||
297 | params_rate(params) * 512); | ||
298 | } else { | ||
299 | ret = snd_soc_dai_set_pll(codec_dai, 0, | ||
300 | RT5640_PLL1_S_MCLK, | ||
301 | 19200000, | ||
302 | params_rate(params) * 512); | ||
303 | } | ||
304 | } | ||
305 | |||
112 | if (ret < 0) { | 306 | if (ret < 0) { |
113 | dev_err(rtd->dev, "can't set codec pll: %d\n", ret); | 307 | dev_err(rtd->dev, "can't set codec pll: %d\n", ret); |
114 | return ret; | 308 | return ret; |
@@ -127,27 +321,73 @@ static const struct dmi_system_id byt_rt5640_quirk_table[] = { | |||
127 | { | 321 | { |
128 | .callback = byt_rt5640_quirk_cb, | 322 | .callback = byt_rt5640_quirk_cb, |
129 | .matches = { | 323 | .matches = { |
130 | DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), | 324 | DMI_EXACT_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), |
131 | DMI_MATCH(DMI_PRODUCT_NAME, "T100TA"), | 325 | DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "T100TA"), |
326 | }, | ||
327 | .driver_data = (unsigned long *)(BYT_RT5640_IN1_MAP | | ||
328 | BYT_RT5640_MCLK_EN), | ||
329 | }, | ||
330 | { | ||
331 | .callback = byt_rt5640_quirk_cb, | ||
332 | .matches = { | ||
333 | DMI_EXACT_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), | ||
334 | DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "T100TAF"), | ||
132 | }, | 335 | }, |
133 | .driver_data = (unsigned long *)BYT_RT5640_IN1_MAP, | 336 | .driver_data = (unsigned long *)(BYT_RT5640_IN1_MAP | |
337 | BYT_RT5640_MONO_SPEAKER | | ||
338 | BYT_RT5640_DIFF_MIC | | ||
339 | BYT_RT5640_SSP0_AIF2 | | ||
340 | BYT_RT5640_MCLK_EN | ||
341 | ), | ||
134 | }, | 342 | }, |
135 | { | 343 | { |
136 | .callback = byt_rt5640_quirk_cb, | 344 | .callback = byt_rt5640_quirk_cb, |
137 | .matches = { | 345 | .matches = { |
138 | DMI_MATCH(DMI_SYS_VENDOR, "DellInc."), | 346 | DMI_EXACT_MATCH(DMI_SYS_VENDOR, "DellInc."), |
139 | DMI_MATCH(DMI_PRODUCT_NAME, "Venue 8 Pro 5830"), | 347 | DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "Venue 8 Pro 5830"), |
140 | }, | 348 | }, |
141 | .driver_data = (unsigned long *)(BYT_RT5640_DMIC2_MAP | | 349 | .driver_data = (unsigned long *)(BYT_RT5640_DMIC2_MAP | |
350 | BYT_RT5640_DMIC_EN | | ||
351 | BYT_RT5640_MCLK_EN), | ||
352 | }, | ||
353 | { | ||
354 | .callback = byt_rt5640_quirk_cb, | ||
355 | .matches = { | ||
356 | DMI_EXACT_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"), | ||
357 | DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "HP ElitePad 1000 G2"), | ||
358 | }, | ||
359 | .driver_data = (unsigned long *)(BYT_RT5640_IN1_MAP | | ||
360 | BYT_RT5640_MCLK_EN), | ||
361 | }, | ||
362 | { | ||
363 | .callback = byt_rt5640_quirk_cb, | ||
364 | .matches = { | ||
365 | DMI_MATCH(DMI_SYS_VENDOR, "Circuitco"), | ||
366 | DMI_MATCH(DMI_PRODUCT_NAME, "Minnowboard Max B3 PLATFORM"), | ||
367 | }, | ||
368 | .driver_data = (unsigned long *)(BYT_RT5640_DMIC1_MAP | | ||
142 | BYT_RT5640_DMIC_EN), | 369 | BYT_RT5640_DMIC_EN), |
143 | }, | 370 | }, |
144 | { | 371 | { |
145 | .callback = byt_rt5640_quirk_cb, | 372 | .callback = byt_rt5640_quirk_cb, |
146 | .matches = { | 373 | .matches = { |
147 | DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"), | 374 | DMI_MATCH(DMI_BOARD_VENDOR, "TECLAST"), |
148 | DMI_MATCH(DMI_PRODUCT_NAME, "HP ElitePad 1000 G2"), | 375 | DMI_MATCH(DMI_BOARD_NAME, "tPAD"), |
149 | }, | 376 | }, |
150 | .driver_data = (unsigned long *)BYT_RT5640_IN1_MAP, | 377 | .driver_data = (unsigned long *)(BYT_RT5640_IN3_MAP | |
378 | BYT_RT5640_MCLK_EN | | ||
379 | BYT_RT5640_SSP0_AIF1), | ||
380 | }, | ||
381 | { | ||
382 | .callback = byt_rt5640_quirk_cb, | ||
383 | .matches = { | ||
384 | DMI_MATCH(DMI_SYS_VENDOR, "Acer"), | ||
385 | DMI_MATCH(DMI_PRODUCT_NAME, "Aspire SW5-012"), | ||
386 | }, | ||
387 | .driver_data = (unsigned long *)(BYT_RT5640_IN1_MAP | | ||
388 | BYT_RT5640_MCLK_EN | | ||
389 | BYT_RT5640_SSP0_AIF1), | ||
390 | |||
151 | }, | 391 | }, |
152 | {} | 392 | {} |
153 | }; | 393 | }; |
@@ -158,13 +398,18 @@ static int byt_rt5640_init(struct snd_soc_pcm_runtime *runtime) | |||
158 | struct snd_soc_codec *codec = runtime->codec; | 398 | struct snd_soc_codec *codec = runtime->codec; |
159 | struct snd_soc_card *card = runtime->card; | 399 | struct snd_soc_card *card = runtime->card; |
160 | const struct snd_soc_dapm_route *custom_map; | 400 | const struct snd_soc_dapm_route *custom_map; |
401 | struct byt_rt5640_private *priv = snd_soc_card_get_drvdata(card); | ||
161 | int num_routes; | 402 | int num_routes; |
162 | 403 | ||
163 | card->dapm.idle_bias_off = true; | 404 | card->dapm.idle_bias_off = true; |
164 | 405 | ||
165 | rt5640_sel_asrc_clk_src(codec, | 406 | rt5640_sel_asrc_clk_src(codec, |
166 | RT5640_DA_STEREO_FILTER | | 407 | RT5640_DA_STEREO_FILTER | |
167 | RT5640_AD_STEREO_FILTER, | 408 | RT5640_DA_MONO_L_FILTER | |
409 | RT5640_DA_MONO_R_FILTER | | ||
410 | RT5640_AD_STEREO_FILTER | | ||
411 | RT5640_AD_MONO_L_FILTER | | ||
412 | RT5640_AD_MONO_R_FILTER, | ||
168 | RT5640_CLK_SEL_ASRC); | 413 | RT5640_CLK_SEL_ASRC); |
169 | 414 | ||
170 | ret = snd_soc_add_card_controls(card, byt_rt5640_controls, | 415 | ret = snd_soc_add_card_controls(card, byt_rt5640_controls, |
@@ -179,6 +424,10 @@ static int byt_rt5640_init(struct snd_soc_pcm_runtime *runtime) | |||
179 | custom_map = byt_rt5640_intmic_in1_map; | 424 | custom_map = byt_rt5640_intmic_in1_map; |
180 | num_routes = ARRAY_SIZE(byt_rt5640_intmic_in1_map); | 425 | num_routes = ARRAY_SIZE(byt_rt5640_intmic_in1_map); |
181 | break; | 426 | break; |
427 | case BYT_RT5640_IN3_MAP: | ||
428 | custom_map = byt_rt5640_intmic_in3_map; | ||
429 | num_routes = ARRAY_SIZE(byt_rt5640_intmic_in3_map); | ||
430 | break; | ||
182 | case BYT_RT5640_DMIC2_MAP: | 431 | case BYT_RT5640_DMIC2_MAP: |
183 | custom_map = byt_rt5640_intmic_dmic2_map; | 432 | custom_map = byt_rt5640_intmic_dmic2_map; |
184 | num_routes = ARRAY_SIZE(byt_rt5640_intmic_dmic2_map); | 433 | num_routes = ARRAY_SIZE(byt_rt5640_intmic_dmic2_map); |
@@ -192,6 +441,43 @@ static int byt_rt5640_init(struct snd_soc_pcm_runtime *runtime) | |||
192 | if (ret) | 441 | if (ret) |
193 | return ret; | 442 | return ret; |
194 | 443 | ||
444 | if (byt_rt5640_quirk & BYT_RT5640_SSP2_AIF2) { | ||
445 | ret = snd_soc_dapm_add_routes(&card->dapm, | ||
446 | byt_rt5640_ssp2_aif2_map, | ||
447 | ARRAY_SIZE(byt_rt5640_ssp2_aif2_map)); | ||
448 | } else if (byt_rt5640_quirk & BYT_RT5640_SSP0_AIF1) { | ||
449 | ret = snd_soc_dapm_add_routes(&card->dapm, | ||
450 | byt_rt5640_ssp0_aif1_map, | ||
451 | ARRAY_SIZE(byt_rt5640_ssp0_aif1_map)); | ||
452 | } else if (byt_rt5640_quirk & BYT_RT5640_SSP0_AIF2) { | ||
453 | ret = snd_soc_dapm_add_routes(&card->dapm, | ||
454 | byt_rt5640_ssp0_aif2_map, | ||
455 | ARRAY_SIZE(byt_rt5640_ssp0_aif2_map)); | ||
456 | } else { | ||
457 | ret = snd_soc_dapm_add_routes(&card->dapm, | ||
458 | byt_rt5640_ssp2_aif1_map, | ||
459 | ARRAY_SIZE(byt_rt5640_ssp2_aif1_map)); | ||
460 | } | ||
461 | if (ret) | ||
462 | return ret; | ||
463 | |||
464 | if (byt_rt5640_quirk & BYT_RT5640_MONO_SPEAKER) { | ||
465 | ret = snd_soc_dapm_add_routes(&card->dapm, | ||
466 | byt_rt5640_mono_spk_map, | ||
467 | ARRAY_SIZE(byt_rt5640_mono_spk_map)); | ||
468 | } else { | ||
469 | ret = snd_soc_dapm_add_routes(&card->dapm, | ||
470 | byt_rt5640_stereo_spk_map, | ||
471 | ARRAY_SIZE(byt_rt5640_stereo_spk_map)); | ||
472 | } | ||
473 | if (ret) | ||
474 | return ret; | ||
475 | |||
476 | if (byt_rt5640_quirk & BYT_RT5640_DIFF_MIC) { | ||
477 | snd_soc_update_bits(codec, RT5640_IN1_IN2, RT5640_IN_DF1, | ||
478 | RT5640_IN_DF1); | ||
479 | } | ||
480 | |||
195 | if (byt_rt5640_quirk & BYT_RT5640_DMIC_EN) { | 481 | if (byt_rt5640_quirk & BYT_RT5640_DMIC_EN) { |
196 | ret = rt5640_dmic_enable(codec, 0, 0); | 482 | ret = rt5640_dmic_enable(codec, 0, 0); |
197 | if (ret) | 483 | if (ret) |
@@ -201,6 +487,30 @@ static int byt_rt5640_init(struct snd_soc_pcm_runtime *runtime) | |||
201 | snd_soc_dapm_ignore_suspend(&card->dapm, "Headphone"); | 487 | snd_soc_dapm_ignore_suspend(&card->dapm, "Headphone"); |
202 | snd_soc_dapm_ignore_suspend(&card->dapm, "Speaker"); | 488 | snd_soc_dapm_ignore_suspend(&card->dapm, "Speaker"); |
203 | 489 | ||
490 | if ((byt_rt5640_quirk & BYT_RT5640_MCLK_EN) && priv->mclk) { | ||
491 | /* | ||
492 | * The firmware might enable the clock at | ||
493 | * boot (this information may or may not | ||
494 | * be reflected in the enable clock register). | ||
495 | * To change the rate we must disable the clock | ||
496 | * first to cover these cases. Due to common | ||
497 | * clock framework restrictions that do not allow | ||
498 | * to disable a clock that has not been enabled, | ||
499 | * we need to enable the clock first. | ||
500 | */ | ||
501 | ret = clk_prepare_enable(priv->mclk); | ||
502 | if (!ret) | ||
503 | clk_disable_unprepare(priv->mclk); | ||
504 | |||
505 | if (byt_rt5640_quirk & BYT_RT5640_MCLK_25MHZ) | ||
506 | ret = clk_set_rate(priv->mclk, 25000000); | ||
507 | else | ||
508 | ret = clk_set_rate(priv->mclk, 19200000); | ||
509 | |||
510 | if (ret) | ||
511 | dev_err(card->dev, "unable to set MCLK rate\n"); | ||
512 | } | ||
513 | |||
204 | return ret; | 514 | return ret; |
205 | } | 515 | } |
206 | 516 | ||
@@ -221,34 +531,63 @@ static int byt_rt5640_codec_fixup(struct snd_soc_pcm_runtime *rtd, | |||
221 | SNDRV_PCM_HW_PARAM_CHANNELS); | 531 | SNDRV_PCM_HW_PARAM_CHANNELS); |
222 | int ret; | 532 | int ret; |
223 | 533 | ||
224 | /* The DSP will covert the FE rate to 48k, stereo, 24bits */ | 534 | /* The DSP will covert the FE rate to 48k, stereo */ |
225 | rate->min = rate->max = 48000; | 535 | rate->min = rate->max = 48000; |
226 | channels->min = channels->max = 2; | 536 | channels->min = channels->max = 2; |
227 | 537 | ||
228 | /* set SSP2 to 24-bit */ | 538 | if ((byt_rt5640_quirk & BYT_RT5640_SSP0_AIF1) || |
229 | params_set_format(params, SNDRV_PCM_FORMAT_S24_LE); | 539 | (byt_rt5640_quirk & BYT_RT5640_SSP0_AIF2)) { |
540 | |||
541 | /* set SSP0 to 16-bit */ | ||
542 | params_set_format(params, SNDRV_PCM_FORMAT_S16_LE); | ||
543 | |||
544 | /* | ||
545 | * Default mode for SSP configuration is TDM 4 slot, override config | ||
546 | * with explicit setting to I2S 2ch 16-bit. The word length is set with | ||
547 | * dai_set_tdm_slot() since there is no other API exposed | ||
548 | */ | ||
549 | ret = snd_soc_dai_set_fmt(rtd->cpu_dai, | ||
550 | SND_SOC_DAIFMT_I2S | | ||
551 | SND_SOC_DAIFMT_NB_IF | | ||
552 | SND_SOC_DAIFMT_CBS_CFS | ||
553 | ); | ||
554 | if (ret < 0) { | ||
555 | dev_err(rtd->dev, "can't set format to I2S, err %d\n", ret); | ||
556 | return ret; | ||
557 | } | ||
230 | 558 | ||
231 | /* | 559 | ret = snd_soc_dai_set_tdm_slot(rtd->cpu_dai, 0x3, 0x3, 2, 16); |
232 | * Default mode for SSP configuration is TDM 4 slot, override config | 560 | if (ret < 0) { |
233 | * with explicit setting to I2S 2ch 24-bit. The word length is set with | 561 | dev_err(rtd->dev, "can't set I2S config, err %d\n", ret); |
234 | * dai_set_tdm_slot() since there is no other API exposed | 562 | return ret; |
235 | */ | 563 | } |
236 | ret = snd_soc_dai_set_fmt(rtd->cpu_dai, | ||
237 | SND_SOC_DAIFMT_I2S | | ||
238 | SND_SOC_DAIFMT_NB_IF | | ||
239 | SND_SOC_DAIFMT_CBS_CFS | ||
240 | ); | ||
241 | if (ret < 0) { | ||
242 | dev_err(rtd->dev, "can't set format to I2S, err %d\n", ret); | ||
243 | return ret; | ||
244 | } | ||
245 | 564 | ||
246 | ret = snd_soc_dai_set_tdm_slot(rtd->cpu_dai, 0x3, 0x3, 2, 24); | 565 | } else { |
247 | if (ret < 0) { | 566 | |
248 | dev_err(rtd->dev, "can't set I2S config, err %d\n", ret); | 567 | /* set SSP2 to 24-bit */ |
249 | return ret; | 568 | params_set_format(params, SNDRV_PCM_FORMAT_S24_LE); |
250 | } | 569 | |
570 | /* | ||
571 | * Default mode for SSP configuration is TDM 4 slot, override config | ||
572 | * with explicit setting to I2S 2ch 24-bit. The word length is set with | ||
573 | * dai_set_tdm_slot() since there is no other API exposed | ||
574 | */ | ||
575 | ret = snd_soc_dai_set_fmt(rtd->cpu_dai, | ||
576 | SND_SOC_DAIFMT_I2S | | ||
577 | SND_SOC_DAIFMT_NB_IF | | ||
578 | SND_SOC_DAIFMT_CBS_CFS | ||
579 | ); | ||
580 | if (ret < 0) { | ||
581 | dev_err(rtd->dev, "can't set format to I2S, err %d\n", ret); | ||
582 | return ret; | ||
583 | } | ||
251 | 584 | ||
585 | ret = snd_soc_dai_set_tdm_slot(rtd->cpu_dai, 0x3, 0x3, 2, 24); | ||
586 | if (ret < 0) { | ||
587 | dev_err(rtd->dev, "can't set I2S config, err %d\n", ret); | ||
588 | return ret; | ||
589 | } | ||
590 | } | ||
252 | return 0; | 591 | return 0; |
253 | } | 592 | } |
254 | 593 | ||
@@ -305,10 +644,10 @@ static struct snd_soc_dai_link byt_rt5640_dais[] = { | |||
305 | { | 644 | { |
306 | .name = "SSP2-Codec", | 645 | .name = "SSP2-Codec", |
307 | .id = 1, | 646 | .id = 1, |
308 | .cpu_dai_name = "ssp2-port", | 647 | .cpu_dai_name = "ssp2-port", /* overwritten for ssp0 routing */ |
309 | .platform_name = "sst-mfld-platform", | 648 | .platform_name = "sst-mfld-platform", |
310 | .no_pcm = 1, | 649 | .no_pcm = 1, |
311 | .codec_dai_name = "rt5640-aif1", | 650 | .codec_dai_name = "rt5640-aif1", /* changed w/ quirk */ |
312 | .codec_name = "i2c-10EC5640:00", /* overwritten with HID */ | 651 | .codec_name = "i2c-10EC5640:00", /* overwritten with HID */ |
313 | .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | 652 | .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF |
314 | | SND_SOC_DAIFMT_CBS_CFS, | 653 | | SND_SOC_DAIFMT_CBS_CFS, |
@@ -335,6 +674,21 @@ static struct snd_soc_card byt_rt5640_card = { | |||
335 | }; | 674 | }; |
336 | 675 | ||
337 | static char byt_rt5640_codec_name[16]; /* i2c-<HID>:00 with HID being 8 chars */ | 676 | static char byt_rt5640_codec_name[16]; /* i2c-<HID>:00 with HID being 8 chars */ |
677 | static char byt_rt5640_codec_aif_name[12]; /* = "rt5640-aif[1|2]" */ | ||
678 | static char byt_rt5640_cpu_dai_name[10]; /* = "ssp[0|2]-port" */ | ||
679 | |||
680 | static bool is_valleyview(void) | ||
681 | { | ||
682 | static const struct x86_cpu_id cpu_ids[] = { | ||
683 | { X86_VENDOR_INTEL, 6, 55 }, /* Valleyview, Bay Trail */ | ||
684 | {} | ||
685 | }; | ||
686 | |||
687 | if (!x86_match_cpu(cpu_ids)) | ||
688 | return false; | ||
689 | return true; | ||
690 | } | ||
691 | |||
338 | 692 | ||
339 | static int snd_byt_rt5640_mc_probe(struct platform_device *pdev) | 693 | static int snd_byt_rt5640_mc_probe(struct platform_device *pdev) |
340 | { | 694 | { |
@@ -343,10 +697,16 @@ static int snd_byt_rt5640_mc_probe(struct platform_device *pdev) | |||
343 | const char *i2c_name = NULL; | 697 | const char *i2c_name = NULL; |
344 | int i; | 698 | int i; |
345 | int dai_index; | 699 | int dai_index; |
700 | struct byt_rt5640_private *priv; | ||
701 | |||
702 | priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_ATOMIC); | ||
703 | if (!priv) | ||
704 | return -ENOMEM; | ||
346 | 705 | ||
347 | /* register the soc card */ | 706 | /* register the soc card */ |
348 | byt_rt5640_card.dev = &pdev->dev; | 707 | byt_rt5640_card.dev = &pdev->dev; |
349 | mach = byt_rt5640_card.dev->platform_data; | 708 | mach = byt_rt5640_card.dev->platform_data; |
709 | snd_soc_card_set_drvdata(&byt_rt5640_card, priv); | ||
350 | 710 | ||
351 | /* fix index of codec dai */ | 711 | /* fix index of codec dai */ |
352 | dai_index = MERR_DPCM_COMPR + 1; | 712 | dai_index = MERR_DPCM_COMPR + 1; |
@@ -366,8 +726,57 @@ static int snd_byt_rt5640_mc_probe(struct platform_device *pdev) | |||
366 | byt_rt5640_dais[dai_index].codec_name = byt_rt5640_codec_name; | 726 | byt_rt5640_dais[dai_index].codec_name = byt_rt5640_codec_name; |
367 | } | 727 | } |
368 | 728 | ||
729 | /* | ||
730 | * swap SSP0 if bytcr is detected | ||
731 | * (will be overridden if DMI quirk is detected) | ||
732 | */ | ||
733 | if (is_valleyview()) { | ||
734 | struct sst_platform_info *p_info = mach->pdata; | ||
735 | const struct sst_res_info *res_info = p_info->res_info; | ||
736 | |||
737 | /* TODO: use CHAN package info from BIOS to detect AIF1/AIF2 */ | ||
738 | if (res_info->acpi_ipc_irq_index == 0) { | ||
739 | byt_rt5640_quirk |= BYT_RT5640_SSP0_AIF2; | ||
740 | } | ||
741 | } | ||
742 | |||
369 | /* check quirks before creating card */ | 743 | /* check quirks before creating card */ |
370 | dmi_check_system(byt_rt5640_quirk_table); | 744 | dmi_check_system(byt_rt5640_quirk_table); |
745 | log_quirks(&pdev->dev); | ||
746 | |||
747 | if ((byt_rt5640_quirk & BYT_RT5640_SSP2_AIF2) || | ||
748 | (byt_rt5640_quirk & BYT_RT5640_SSP0_AIF2)) { | ||
749 | |||
750 | /* fixup codec aif name */ | ||
751 | snprintf(byt_rt5640_codec_aif_name, | ||
752 | sizeof(byt_rt5640_codec_aif_name), | ||
753 | "%s", "rt5640-aif2"); | ||
754 | |||
755 | byt_rt5640_dais[dai_index].codec_dai_name = | ||
756 | byt_rt5640_codec_aif_name; | ||
757 | } | ||
758 | |||
759 | if ((byt_rt5640_quirk & BYT_RT5640_SSP0_AIF1) || | ||
760 | (byt_rt5640_quirk & BYT_RT5640_SSP0_AIF2)) { | ||
761 | |||
762 | /* fixup cpu dai name name */ | ||
763 | snprintf(byt_rt5640_cpu_dai_name, | ||
764 | sizeof(byt_rt5640_cpu_dai_name), | ||
765 | "%s", "ssp0-port"); | ||
766 | |||
767 | byt_rt5640_dais[dai_index].cpu_dai_name = | ||
768 | byt_rt5640_cpu_dai_name; | ||
769 | } | ||
770 | |||
771 | if ((byt_rt5640_quirk & BYT_RT5640_MCLK_EN) && (is_valleyview())) { | ||
772 | priv->mclk = devm_clk_get(&pdev->dev, "pmc_plt_clk_3"); | ||
773 | if (IS_ERR(priv->mclk)) { | ||
774 | dev_err(&pdev->dev, | ||
775 | "Failed to get MCLK from pmc_plt_clk_3: %ld\n", | ||
776 | PTR_ERR(priv->mclk)); | ||
777 | return PTR_ERR(priv->mclk); | ||
778 | } | ||
779 | } | ||
371 | 780 | ||
372 | ret_val = devm_snd_soc_register_card(&pdev->dev, &byt_rt5640_card); | 781 | ret_val = devm_snd_soc_register_card(&pdev->dev, &byt_rt5640_card); |
373 | 782 | ||
diff --git a/sound/soc/intel/common/sst-acpi.c b/sound/soc/intel/common/sst-acpi.c index 2c5eda14d510..1285cc597b6b 100644 --- a/sound/soc/intel/common/sst-acpi.c +++ b/sound/soc/intel/common/sst-acpi.c | |||
@@ -199,6 +199,7 @@ static struct sst_acpi_desc sst_acpi_haswell_desc = { | |||
199 | 199 | ||
200 | static struct sst_acpi_mach broadwell_machines[] = { | 200 | static struct sst_acpi_mach broadwell_machines[] = { |
201 | { "INT343A", "broadwell-audio", "intel/IntcSST2.bin", NULL, NULL, NULL }, | 201 | { "INT343A", "broadwell-audio", "intel/IntcSST2.bin", NULL, NULL, NULL }, |
202 | { "RT5677CE", "bdw-rt5677", "intel/IntcSST2.bin", NULL, NULL, NULL }, | ||
202 | {} | 203 | {} |
203 | }; | 204 | }; |
204 | 205 | ||
diff --git a/sound/soc/intel/haswell/sst-haswell-pcm.c b/sound/soc/intel/haswell/sst-haswell-pcm.c index 3154525c2b83..9e4094e2c6e3 100644 --- a/sound/soc/intel/haswell/sst-haswell-pcm.c +++ b/sound/soc/intel/haswell/sst-haswell-pcm.c | |||
@@ -871,7 +871,7 @@ out: | |||
871 | return ret; | 871 | return ret; |
872 | } | 872 | } |
873 | 873 | ||
874 | static struct snd_pcm_ops hsw_pcm_ops = { | 874 | static const struct snd_pcm_ops hsw_pcm_ops = { |
875 | .open = hsw_pcm_open, | 875 | .open = hsw_pcm_open, |
876 | .close = hsw_pcm_close, | 876 | .close = hsw_pcm_close, |
877 | .ioctl = snd_pcm_lib_ioctl, | 877 | .ioctl = snd_pcm_lib_ioctl, |
diff --git a/sound/soc/intel/skylake/bxt-sst.c b/sound/soc/intel/skylake/bxt-sst.c index 2663781278aa..1d251d59bcb9 100644 --- a/sound/soc/intel/skylake/bxt-sst.c +++ b/sound/soc/intel/skylake/bxt-sst.c | |||
@@ -23,6 +23,7 @@ | |||
23 | #include "../common/sst-dsp.h" | 23 | #include "../common/sst-dsp.h" |
24 | #include "../common/sst-dsp-priv.h" | 24 | #include "../common/sst-dsp-priv.h" |
25 | #include "skl-sst-ipc.h" | 25 | #include "skl-sst-ipc.h" |
26 | #include "skl-tplg-interface.h" | ||
26 | 27 | ||
27 | #define BXT_BASEFW_TIMEOUT 3000 | 28 | #define BXT_BASEFW_TIMEOUT 3000 |
28 | #define BXT_INIT_TIMEOUT 500 | 29 | #define BXT_INIT_TIMEOUT 500 |
@@ -40,11 +41,73 @@ | |||
40 | #define BXT_INSTANCE_ID 0 | 41 | #define BXT_INSTANCE_ID 0 |
41 | #define BXT_BASE_FW_MODULE_ID 0 | 42 | #define BXT_BASE_FW_MODULE_ID 0 |
42 | 43 | ||
44 | #define BXT_ADSP_FW_BIN_HDR_OFFSET 0x2000 | ||
45 | |||
43 | static unsigned int bxt_get_errorcode(struct sst_dsp *ctx) | 46 | static unsigned int bxt_get_errorcode(struct sst_dsp *ctx) |
44 | { | 47 | { |
45 | return sst_dsp_shim_read(ctx, BXT_ADSP_ERROR_CODE); | 48 | return sst_dsp_shim_read(ctx, BXT_ADSP_ERROR_CODE); |
46 | } | 49 | } |
47 | 50 | ||
51 | static int | ||
52 | bxt_load_library(struct sst_dsp *ctx, struct skl_dfw_manifest *minfo) | ||
53 | { | ||
54 | struct snd_dma_buffer dmab; | ||
55 | struct skl_sst *skl = ctx->thread_context; | ||
56 | const struct firmware *fw = NULL; | ||
57 | struct firmware stripped_fw; | ||
58 | int ret = 0, i, dma_id, stream_tag; | ||
59 | |||
60 | /* library indices start from 1 to N. 0 represents base FW */ | ||
61 | for (i = 1; i < minfo->lib_count; i++) { | ||
62 | ret = request_firmware(&fw, minfo->lib[i].name, ctx->dev); | ||
63 | if (ret < 0) { | ||
64 | dev_err(ctx->dev, "Request lib %s failed:%d\n", | ||
65 | minfo->lib[i].name, ret); | ||
66 | return ret; | ||
67 | } | ||
68 | |||
69 | if (skl->is_first_boot) { | ||
70 | ret = snd_skl_parse_uuids(ctx, fw, | ||
71 | BXT_ADSP_FW_BIN_HDR_OFFSET, i); | ||
72 | if (ret < 0) | ||
73 | goto load_library_failed; | ||
74 | } | ||
75 | |||
76 | stripped_fw.data = fw->data; | ||
77 | stripped_fw.size = fw->size; | ||
78 | skl_dsp_strip_extended_manifest(&stripped_fw); | ||
79 | |||
80 | stream_tag = ctx->dsp_ops.prepare(ctx->dev, 0x40, | ||
81 | stripped_fw.size, &dmab); | ||
82 | if (stream_tag <= 0) { | ||
83 | dev_err(ctx->dev, "Lib prepare DMA err: %x\n", | ||
84 | stream_tag); | ||
85 | ret = stream_tag; | ||
86 | goto load_library_failed; | ||
87 | } | ||
88 | |||
89 | dma_id = stream_tag - 1; | ||
90 | memcpy(dmab.area, stripped_fw.data, stripped_fw.size); | ||
91 | |||
92 | ctx->dsp_ops.trigger(ctx->dev, true, stream_tag); | ||
93 | ret = skl_sst_ipc_load_library(&skl->ipc, dma_id, i); | ||
94 | if (ret < 0) | ||
95 | dev_err(ctx->dev, "IPC Load Lib for %s fail: %d\n", | ||
96 | minfo->lib[i].name, ret); | ||
97 | |||
98 | ctx->dsp_ops.trigger(ctx->dev, false, stream_tag); | ||
99 | ctx->dsp_ops.cleanup(ctx->dev, &dmab, stream_tag); | ||
100 | release_firmware(fw); | ||
101 | fw = NULL; | ||
102 | } | ||
103 | |||
104 | return ret; | ||
105 | |||
106 | load_library_failed: | ||
107 | release_firmware(fw); | ||
108 | return ret; | ||
109 | } | ||
110 | |||
48 | /* | 111 | /* |
49 | * First boot sequence has some extra steps. Core 0 waits for power | 112 | * First boot sequence has some extra steps. Core 0 waits for power |
50 | * status on core 1, so power up core 1 also momentarily, keep it in | 113 | * status on core 1, so power up core 1 also momentarily, keep it in |
@@ -157,8 +220,6 @@ static int sst_transfer_fw_host_dma(struct sst_dsp *ctx) | |||
157 | return ret; | 220 | return ret; |
158 | } | 221 | } |
159 | 222 | ||
160 | #define BXT_ADSP_FW_BIN_HDR_OFFSET 0x2000 | ||
161 | |||
162 | static int bxt_load_base_firmware(struct sst_dsp *ctx) | 223 | static int bxt_load_base_firmware(struct sst_dsp *ctx) |
163 | { | 224 | { |
164 | struct firmware stripped_fw; | 225 | struct firmware stripped_fw; |
@@ -175,9 +236,12 @@ static int bxt_load_base_firmware(struct sst_dsp *ctx) | |||
175 | if (ctx->fw == NULL) | 236 | if (ctx->fw == NULL) |
176 | goto sst_load_base_firmware_failed; | 237 | goto sst_load_base_firmware_failed; |
177 | 238 | ||
178 | ret = snd_skl_parse_uuids(ctx, BXT_ADSP_FW_BIN_HDR_OFFSET); | 239 | /* prase uuids on first boot */ |
179 | if (ret < 0) | 240 | if (skl->is_first_boot) { |
180 | goto sst_load_base_firmware_failed; | 241 | ret = snd_skl_parse_uuids(ctx, ctx->fw, BXT_ADSP_FW_BIN_HDR_OFFSET, 0); |
242 | if (ret < 0) | ||
243 | goto sst_load_base_firmware_failed; | ||
244 | } | ||
181 | 245 | ||
182 | stripped_fw.data = ctx->fw->data; | 246 | stripped_fw.data = ctx->fw->data; |
183 | stripped_fw.size = ctx->fw->size; | 247 | stripped_fw.size = ctx->fw->size; |
@@ -230,12 +294,23 @@ static int bxt_set_dsp_D0(struct sst_dsp *ctx, unsigned int core_id) | |||
230 | int ret; | 294 | int ret; |
231 | struct skl_ipc_dxstate_info dx; | 295 | struct skl_ipc_dxstate_info dx; |
232 | unsigned int core_mask = SKL_DSP_CORE_MASK(core_id); | 296 | unsigned int core_mask = SKL_DSP_CORE_MASK(core_id); |
297 | struct skl_dfw_manifest *minfo = &skl->manifest; | ||
233 | 298 | ||
234 | if (skl->fw_loaded == false) { | 299 | if (skl->fw_loaded == false) { |
235 | skl->boot_complete = false; | 300 | skl->boot_complete = false; |
236 | ret = bxt_load_base_firmware(ctx); | 301 | ret = bxt_load_base_firmware(ctx); |
237 | if (ret < 0) | 302 | if (ret < 0) { |
238 | dev_err(ctx->dev, "reload fw failed: %d\n", ret); | 303 | dev_err(ctx->dev, "reload fw failed: %d\n", ret); |
304 | return ret; | ||
305 | } | ||
306 | |||
307 | if (minfo->lib_count > 1) { | ||
308 | ret = bxt_load_library(ctx, minfo); | ||
309 | if (ret < 0) { | ||
310 | dev_err(ctx->dev, "reload libs failed: %d\n", ret); | ||
311 | return ret; | ||
312 | } | ||
313 | } | ||
239 | return ret; | 314 | return ret; |
240 | } | 315 | } |
241 | 316 | ||
@@ -329,7 +404,7 @@ static int bxt_set_dsp_D3(struct sst_dsp *ctx, unsigned int core_id) | |||
329 | 404 | ||
330 | ret = skl_dsp_disable_core(ctx, core_mask); | 405 | ret = skl_dsp_disable_core(ctx, core_mask); |
331 | if (ret < 0) { | 406 | if (ret < 0) { |
332 | dev_err(ctx->dev, "Failed to disable core %d", ret); | 407 | dev_err(ctx->dev, "Failed to disable core %d\n", ret); |
333 | return ret; | 408 | return ret; |
334 | } | 409 | } |
335 | skl->cores.state[core_id] = SKL_DSP_RESET; | 410 | skl->cores.state[core_id] = SKL_DSP_RESET; |
@@ -341,6 +416,7 @@ static struct skl_dsp_fw_ops bxt_fw_ops = { | |||
341 | .set_state_D3 = bxt_set_dsp_D3, | 416 | .set_state_D3 = bxt_set_dsp_D3, |
342 | .load_fw = bxt_load_base_firmware, | 417 | .load_fw = bxt_load_base_firmware, |
343 | .get_fw_errcode = bxt_get_errorcode, | 418 | .get_fw_errcode = bxt_get_errorcode, |
419 | .load_library = bxt_load_library, | ||
344 | }; | 420 | }; |
345 | 421 | ||
346 | static struct sst_ops skl_ops = { | 422 | static struct sst_ops skl_ops = { |
@@ -397,22 +473,40 @@ int bxt_sst_dsp_init(struct device *dev, void __iomem *mmio_base, int irq, | |||
397 | skl->cores.count = 2; | 473 | skl->cores.count = 2; |
398 | skl->boot_complete = false; | 474 | skl->boot_complete = false; |
399 | init_waitqueue_head(&skl->boot_wait); | 475 | init_waitqueue_head(&skl->boot_wait); |
476 | skl->is_first_boot = true; | ||
477 | |||
478 | if (dsp) | ||
479 | *dsp = skl; | ||
480 | |||
481 | return 0; | ||
482 | } | ||
483 | EXPORT_SYMBOL_GPL(bxt_sst_dsp_init); | ||
484 | |||
485 | int bxt_sst_init_fw(struct device *dev, struct skl_sst *ctx) | ||
486 | { | ||
487 | int ret; | ||
488 | struct sst_dsp *sst = ctx->dsp; | ||
400 | 489 | ||
401 | ret = sst->fw_ops.load_fw(sst); | 490 | ret = sst->fw_ops.load_fw(sst); |
402 | if (ret < 0) { | 491 | if (ret < 0) { |
403 | dev_err(dev, "Load base fw failed: %x", ret); | 492 | dev_err(dev, "Load base fw failed: %x\n", ret); |
404 | return ret; | 493 | return ret; |
405 | } | 494 | } |
406 | 495 | ||
407 | skl_dsp_init_core_state(sst); | 496 | skl_dsp_init_core_state(sst); |
408 | 497 | ||
409 | if (dsp) | 498 | if (ctx->manifest.lib_count > 1) { |
410 | *dsp = skl; | 499 | ret = sst->fw_ops.load_library(sst, &ctx->manifest); |
500 | if (ret < 0) { | ||
501 | dev_err(dev, "Load Library failed : %x\n", ret); | ||
502 | return ret; | ||
503 | } | ||
504 | } | ||
505 | ctx->is_first_boot = false; | ||
411 | 506 | ||
412 | return 0; | 507 | return 0; |
413 | } | 508 | } |
414 | EXPORT_SYMBOL_GPL(bxt_sst_dsp_init); | 509 | EXPORT_SYMBOL_GPL(bxt_sst_init_fw); |
415 | |||
416 | 510 | ||
417 | void bxt_sst_dsp_cleanup(struct device *dev, struct skl_sst *ctx) | 511 | void bxt_sst_dsp_cleanup(struct device *dev, struct skl_sst *ctx) |
418 | { | 512 | { |
diff --git a/sound/soc/intel/skylake/skl-messages.c b/sound/soc/intel/skylake/skl-messages.c index 44ab595ce21a..805b7f2173f3 100644 --- a/sound/soc/intel/skylake/skl-messages.c +++ b/sound/soc/intel/skylake/skl-messages.c | |||
@@ -203,32 +203,35 @@ static const struct skl_dsp_ops dsp_ops[] = { | |||
203 | .id = 0x9d70, | 203 | .id = 0x9d70, |
204 | .loader_ops = skl_get_loader_ops, | 204 | .loader_ops = skl_get_loader_ops, |
205 | .init = skl_sst_dsp_init, | 205 | .init = skl_sst_dsp_init, |
206 | .init_fw = skl_sst_init_fw, | ||
206 | .cleanup = skl_sst_dsp_cleanup | 207 | .cleanup = skl_sst_dsp_cleanup |
207 | }, | 208 | }, |
208 | { | 209 | { |
209 | .id = 0x9d71, | 210 | .id = 0x9d71, |
210 | .loader_ops = skl_get_loader_ops, | 211 | .loader_ops = skl_get_loader_ops, |
211 | .init = skl_sst_dsp_init, | 212 | .init = skl_sst_dsp_init, |
213 | .init_fw = skl_sst_init_fw, | ||
212 | .cleanup = skl_sst_dsp_cleanup | 214 | .cleanup = skl_sst_dsp_cleanup |
213 | }, | 215 | }, |
214 | { | 216 | { |
215 | .id = 0x5a98, | 217 | .id = 0x5a98, |
216 | .loader_ops = bxt_get_loader_ops, | 218 | .loader_ops = bxt_get_loader_ops, |
217 | .init = bxt_sst_dsp_init, | 219 | .init = bxt_sst_dsp_init, |
220 | .init_fw = bxt_sst_init_fw, | ||
218 | .cleanup = bxt_sst_dsp_cleanup | 221 | .cleanup = bxt_sst_dsp_cleanup |
219 | }, | 222 | }, |
220 | }; | 223 | }; |
221 | 224 | ||
222 | static int skl_get_dsp_ops(int pci_id) | 225 | const struct skl_dsp_ops *skl_get_dsp_ops(int pci_id) |
223 | { | 226 | { |
224 | int i; | 227 | int i; |
225 | 228 | ||
226 | for (i = 0; i < ARRAY_SIZE(dsp_ops); i++) { | 229 | for (i = 0; i < ARRAY_SIZE(dsp_ops); i++) { |
227 | if (dsp_ops[i].id == pci_id) | 230 | if (dsp_ops[i].id == pci_id) |
228 | return i; | 231 | return &dsp_ops[i]; |
229 | } | 232 | } |
230 | 233 | ||
231 | return -EINVAL; | 234 | return NULL; |
232 | } | 235 | } |
233 | 236 | ||
234 | int skl_init_dsp(struct skl *skl) | 237 | int skl_init_dsp(struct skl *skl) |
@@ -238,7 +241,8 @@ int skl_init_dsp(struct skl *skl) | |||
238 | struct hdac_bus *bus = ebus_to_hbus(ebus); | 241 | struct hdac_bus *bus = ebus_to_hbus(ebus); |
239 | struct skl_dsp_loader_ops loader_ops; | 242 | struct skl_dsp_loader_ops loader_ops; |
240 | int irq = bus->irq; | 243 | int irq = bus->irq; |
241 | int ret, index; | 244 | const struct skl_dsp_ops *ops; |
245 | int ret; | ||
242 | 246 | ||
243 | /* enable ppcap interrupt */ | 247 | /* enable ppcap interrupt */ |
244 | snd_hdac_ext_bus_ppcap_enable(&skl->ebus, true); | 248 | snd_hdac_ext_bus_ppcap_enable(&skl->ebus, true); |
@@ -251,18 +255,18 @@ int skl_init_dsp(struct skl *skl) | |||
251 | return -ENXIO; | 255 | return -ENXIO; |
252 | } | 256 | } |
253 | 257 | ||
254 | index = skl_get_dsp_ops(skl->pci->device); | 258 | ops = skl_get_dsp_ops(skl->pci->device); |
255 | if (index < 0) | 259 | if (!ops) |
256 | return -EINVAL; | 260 | return -EIO; |
257 | 261 | ||
258 | loader_ops = dsp_ops[index].loader_ops(); | 262 | loader_ops = ops->loader_ops(); |
259 | ret = dsp_ops[index].init(bus->dev, mmio_base, irq, | 263 | ret = ops->init(bus->dev, mmio_base, irq, |
260 | skl->fw_name, loader_ops, &skl->skl_sst); | 264 | skl->fw_name, loader_ops, |
265 | &skl->skl_sst); | ||
261 | 266 | ||
262 | if (ret < 0) | 267 | if (ret < 0) |
263 | return ret; | 268 | return ret; |
264 | 269 | ||
265 | skl_dsp_enable_notification(skl->skl_sst, false); | ||
266 | dev_dbg(bus->dev, "dsp registration status=%d\n", ret); | 270 | dev_dbg(bus->dev, "dsp registration status=%d\n", ret); |
267 | 271 | ||
268 | return ret; | 272 | return ret; |
@@ -273,16 +277,16 @@ int skl_free_dsp(struct skl *skl) | |||
273 | struct hdac_ext_bus *ebus = &skl->ebus; | 277 | struct hdac_ext_bus *ebus = &skl->ebus; |
274 | struct hdac_bus *bus = ebus_to_hbus(ebus); | 278 | struct hdac_bus *bus = ebus_to_hbus(ebus); |
275 | struct skl_sst *ctx = skl->skl_sst; | 279 | struct skl_sst *ctx = skl->skl_sst; |
276 | int index; | 280 | const struct skl_dsp_ops *ops; |
277 | 281 | ||
278 | /* disable ppcap interrupt */ | 282 | /* disable ppcap interrupt */ |
279 | snd_hdac_ext_bus_ppcap_int_enable(&skl->ebus, false); | 283 | snd_hdac_ext_bus_ppcap_int_enable(&skl->ebus, false); |
280 | 284 | ||
281 | index = skl_get_dsp_ops(skl->pci->device); | 285 | ops = skl_get_dsp_ops(skl->pci->device); |
282 | if (index < 0) | 286 | if (!ops) |
283 | return -EIO; | 287 | return -EIO; |
284 | 288 | ||
285 | dsp_ops[index].cleanup(bus->dev, ctx); | 289 | ops->cleanup(bus->dev, ctx); |
286 | 290 | ||
287 | if (ctx->dsp->addr.lpe) | 291 | if (ctx->dsp->addr.lpe) |
288 | iounmap(ctx->dsp->addr.lpe); | 292 | iounmap(ctx->dsp->addr.lpe); |
@@ -296,7 +300,7 @@ int skl_suspend_dsp(struct skl *skl) | |||
296 | int ret; | 300 | int ret; |
297 | 301 | ||
298 | /* if ppcap is not supported return 0 */ | 302 | /* if ppcap is not supported return 0 */ |
299 | if (!skl->ebus.ppcap) | 303 | if (!skl->ebus.bus.ppcap) |
300 | return 0; | 304 | return 0; |
301 | 305 | ||
302 | ret = skl_dsp_sleep(ctx->dsp); | 306 | ret = skl_dsp_sleep(ctx->dsp); |
@@ -316,13 +320,17 @@ int skl_resume_dsp(struct skl *skl) | |||
316 | int ret; | 320 | int ret; |
317 | 321 | ||
318 | /* if ppcap is not supported return 0 */ | 322 | /* if ppcap is not supported return 0 */ |
319 | if (!skl->ebus.ppcap) | 323 | if (!skl->ebus.bus.ppcap) |
320 | return 0; | 324 | return 0; |
321 | 325 | ||
322 | /* enable ppcap interrupt */ | 326 | /* enable ppcap interrupt */ |
323 | snd_hdac_ext_bus_ppcap_enable(&skl->ebus, true); | 327 | snd_hdac_ext_bus_ppcap_enable(&skl->ebus, true); |
324 | snd_hdac_ext_bus_ppcap_int_enable(&skl->ebus, true); | 328 | snd_hdac_ext_bus_ppcap_int_enable(&skl->ebus, true); |
325 | 329 | ||
330 | /* check if DSP 1st boot is done */ | ||
331 | if (skl->skl_sst->is_first_boot == true) | ||
332 | return 0; | ||
333 | |||
326 | ret = skl_dsp_wake(ctx->dsp); | 334 | ret = skl_dsp_wake(ctx->dsp); |
327 | if (ret < 0) | 335 | if (ret < 0) |
328 | return ret; | 336 | return ret; |
@@ -672,6 +680,7 @@ static u16 skl_get_module_param_size(struct skl_sst *ctx, | |||
672 | return param_size; | 680 | return param_size; |
673 | 681 | ||
674 | case SKL_MODULE_TYPE_BASE_OUTFMT: | 682 | case SKL_MODULE_TYPE_BASE_OUTFMT: |
683 | case SKL_MODULE_TYPE_KPB: | ||
675 | return sizeof(struct skl_base_outfmt_cfg); | 684 | return sizeof(struct skl_base_outfmt_cfg); |
676 | 685 | ||
677 | default: | 686 | default: |
@@ -725,6 +734,7 @@ static int skl_set_module_format(struct skl_sst *ctx, | |||
725 | break; | 734 | break; |
726 | 735 | ||
727 | case SKL_MODULE_TYPE_BASE_OUTFMT: | 736 | case SKL_MODULE_TYPE_BASE_OUTFMT: |
737 | case SKL_MODULE_TYPE_KPB: | ||
728 | skl_set_base_outfmt_format(ctx, module_config, *param_data); | 738 | skl_set_base_outfmt_format(ctx, module_config, *param_data); |
729 | break; | 739 | break; |
730 | 740 | ||
@@ -779,6 +789,7 @@ static int skl_alloc_queue(struct skl_module_pin *mpin, | |||
779 | mpin[i].in_use = true; | 789 | mpin[i].in_use = true; |
780 | mpin[i].id.module_id = id.module_id; | 790 | mpin[i].id.module_id = id.module_id; |
781 | mpin[i].id.instance_id = id.instance_id; | 791 | mpin[i].id.instance_id = id.instance_id; |
792 | mpin[i].id.pvt_id = id.pvt_id; | ||
782 | mpin[i].tgt_mcfg = tgt_cfg; | 793 | mpin[i].tgt_mcfg = tgt_cfg; |
783 | return i; | 794 | return i; |
784 | } | 795 | } |
@@ -802,6 +813,7 @@ static void skl_free_queue(struct skl_module_pin *mpin, int q_index) | |||
802 | mpin[q_index].in_use = false; | 813 | mpin[q_index].in_use = false; |
803 | mpin[q_index].id.module_id = 0; | 814 | mpin[q_index].id.module_id = 0; |
804 | mpin[q_index].id.instance_id = 0; | 815 | mpin[q_index].id.instance_id = 0; |
816 | mpin[q_index].id.pvt_id = 0; | ||
805 | } | 817 | } |
806 | mpin[q_index].pin_state = SKL_PIN_UNBIND; | 818 | mpin[q_index].pin_state = SKL_PIN_UNBIND; |
807 | mpin[q_index].tgt_mcfg = NULL; | 819 | mpin[q_index].tgt_mcfg = NULL; |
@@ -842,7 +854,7 @@ int skl_init_module(struct skl_sst *ctx, | |||
842 | struct skl_ipc_init_instance_msg msg; | 854 | struct skl_ipc_init_instance_msg msg; |
843 | 855 | ||
844 | dev_dbg(ctx->dev, "%s: module_id = %d instance=%d\n", __func__, | 856 | dev_dbg(ctx->dev, "%s: module_id = %d instance=%d\n", __func__, |
845 | mconfig->id.module_id, mconfig->id.instance_id); | 857 | mconfig->id.module_id, mconfig->id.pvt_id); |
846 | 858 | ||
847 | if (mconfig->pipe->state != SKL_PIPE_CREATED) { | 859 | if (mconfig->pipe->state != SKL_PIPE_CREATED) { |
848 | dev_err(ctx->dev, "Pipe not created state= %d pipe_id= %d\n", | 860 | dev_err(ctx->dev, "Pipe not created state= %d pipe_id= %d\n", |
@@ -858,10 +870,11 @@ int skl_init_module(struct skl_sst *ctx, | |||
858 | } | 870 | } |
859 | 871 | ||
860 | msg.module_id = mconfig->id.module_id; | 872 | msg.module_id = mconfig->id.module_id; |
861 | msg.instance_id = mconfig->id.instance_id; | 873 | msg.instance_id = mconfig->id.pvt_id; |
862 | msg.ppl_instance_id = mconfig->pipe->ppl_id; | 874 | msg.ppl_instance_id = mconfig->pipe->ppl_id; |
863 | msg.param_data_size = module_config_size; | 875 | msg.param_data_size = module_config_size; |
864 | msg.core_id = mconfig->core_id; | 876 | msg.core_id = mconfig->core_id; |
877 | msg.domain = mconfig->domain; | ||
865 | 878 | ||
866 | ret = skl_ipc_init_instance(&ctx->ipc, &msg, param_data); | 879 | ret = skl_ipc_init_instance(&ctx->ipc, &msg, param_data); |
867 | if (ret < 0) { | 880 | if (ret < 0) { |
@@ -878,9 +891,9 @@ static void skl_dump_bind_info(struct skl_sst *ctx, struct skl_module_cfg | |||
878 | *src_module, struct skl_module_cfg *dst_module) | 891 | *src_module, struct skl_module_cfg *dst_module) |
879 | { | 892 | { |
880 | dev_dbg(ctx->dev, "%s: src module_id = %d src_instance=%d\n", | 893 | dev_dbg(ctx->dev, "%s: src module_id = %d src_instance=%d\n", |
881 | __func__, src_module->id.module_id, src_module->id.instance_id); | 894 | __func__, src_module->id.module_id, src_module->id.pvt_id); |
882 | dev_dbg(ctx->dev, "%s: dst_module=%d dst_instacne=%d\n", __func__, | 895 | dev_dbg(ctx->dev, "%s: dst_module=%d dst_instacne=%d\n", __func__, |
883 | dst_module->id.module_id, dst_module->id.instance_id); | 896 | dst_module->id.module_id, dst_module->id.pvt_id); |
884 | 897 | ||
885 | dev_dbg(ctx->dev, "src_module state = %d dst module state = %d\n", | 898 | dev_dbg(ctx->dev, "src_module state = %d dst module state = %d\n", |
886 | src_module->m_state, dst_module->m_state); | 899 | src_module->m_state, dst_module->m_state); |
@@ -927,9 +940,9 @@ int skl_unbind_modules(struct skl_sst *ctx, | |||
927 | return 0; | 940 | return 0; |
928 | 941 | ||
929 | msg.module_id = src_mcfg->id.module_id; | 942 | msg.module_id = src_mcfg->id.module_id; |
930 | msg.instance_id = src_mcfg->id.instance_id; | 943 | msg.instance_id = src_mcfg->id.pvt_id; |
931 | msg.dst_module_id = dst_mcfg->id.module_id; | 944 | msg.dst_module_id = dst_mcfg->id.module_id; |
932 | msg.dst_instance_id = dst_mcfg->id.instance_id; | 945 | msg.dst_instance_id = dst_mcfg->id.pvt_id; |
933 | msg.bind = false; | 946 | msg.bind = false; |
934 | 947 | ||
935 | ret = skl_ipc_bind_unbind(&ctx->ipc, &msg); | 948 | ret = skl_ipc_bind_unbind(&ctx->ipc, &msg); |
@@ -988,9 +1001,9 @@ int skl_bind_modules(struct skl_sst *ctx, | |||
988 | msg.src_queue, msg.dst_queue); | 1001 | msg.src_queue, msg.dst_queue); |
989 | 1002 | ||
990 | msg.module_id = src_mcfg->id.module_id; | 1003 | msg.module_id = src_mcfg->id.module_id; |
991 | msg.instance_id = src_mcfg->id.instance_id; | 1004 | msg.instance_id = src_mcfg->id.pvt_id; |
992 | msg.dst_module_id = dst_mcfg->id.module_id; | 1005 | msg.dst_module_id = dst_mcfg->id.module_id; |
993 | msg.dst_instance_id = dst_mcfg->id.instance_id; | 1006 | msg.dst_instance_id = dst_mcfg->id.pvt_id; |
994 | msg.bind = true; | 1007 | msg.bind = true; |
995 | 1008 | ||
996 | ret = skl_ipc_bind_unbind(&ctx->ipc, &msg); | 1009 | ret = skl_ipc_bind_unbind(&ctx->ipc, &msg); |
@@ -1168,7 +1181,7 @@ int skl_set_module_params(struct skl_sst *ctx, u32 *params, int size, | |||
1168 | struct skl_ipc_large_config_msg msg; | 1181 | struct skl_ipc_large_config_msg msg; |
1169 | 1182 | ||
1170 | msg.module_id = mcfg->id.module_id; | 1183 | msg.module_id = mcfg->id.module_id; |
1171 | msg.instance_id = mcfg->id.instance_id; | 1184 | msg.instance_id = mcfg->id.pvt_id; |
1172 | msg.param_data_size = size; | 1185 | msg.param_data_size = size; |
1173 | msg.large_param_id = param_id; | 1186 | msg.large_param_id = param_id; |
1174 | 1187 | ||
@@ -1181,7 +1194,7 @@ int skl_get_module_params(struct skl_sst *ctx, u32 *params, int size, | |||
1181 | struct skl_ipc_large_config_msg msg; | 1194 | struct skl_ipc_large_config_msg msg; |
1182 | 1195 | ||
1183 | msg.module_id = mcfg->id.module_id; | 1196 | msg.module_id = mcfg->id.module_id; |
1184 | msg.instance_id = mcfg->id.instance_id; | 1197 | msg.instance_id = mcfg->id.pvt_id; |
1185 | msg.param_data_size = size; | 1198 | msg.param_data_size = size; |
1186 | msg.large_param_id = param_id; | 1199 | msg.large_param_id = param_id; |
1187 | 1200 | ||
diff --git a/sound/soc/intel/skylake/skl-pcm.c b/sound/soc/intel/skylake/skl-pcm.c index 6e05bf8622f7..58c728662600 100644 --- a/sound/soc/intel/skylake/skl-pcm.c +++ b/sound/soc/intel/skylake/skl-pcm.c | |||
@@ -106,7 +106,7 @@ static void skl_set_pcm_constrains(struct hdac_ext_bus *ebus, | |||
106 | 106 | ||
107 | static enum hdac_ext_stream_type skl_get_host_stream_type(struct hdac_ext_bus *ebus) | 107 | static enum hdac_ext_stream_type skl_get_host_stream_type(struct hdac_ext_bus *ebus) |
108 | { | 108 | { |
109 | if (ebus->ppcap) | 109 | if ((ebus_to_hbus(ebus))->ppcap) |
110 | return HDAC_EXT_STREAM_TYPE_HOST; | 110 | return HDAC_EXT_STREAM_TYPE_HOST; |
111 | else | 111 | else |
112 | return HDAC_EXT_STREAM_TYPE_COUPLED; | 112 | return HDAC_EXT_STREAM_TYPE_COUPLED; |
@@ -188,7 +188,7 @@ static int skl_get_format(struct snd_pcm_substream *substream, | |||
188 | struct hdac_ext_bus *ebus = dev_get_drvdata(dai->dev); | 188 | struct hdac_ext_bus *ebus = dev_get_drvdata(dai->dev); |
189 | int format_val = 0; | 189 | int format_val = 0; |
190 | 190 | ||
191 | if (ebus->ppcap) { | 191 | if ((ebus_to_hbus(ebus))->ppcap) { |
192 | struct snd_pcm_runtime *runtime = substream->runtime; | 192 | struct snd_pcm_runtime *runtime = substream->runtime; |
193 | 193 | ||
194 | format_val = snd_hdac_calc_stream_format(runtime->rate, | 194 | format_val = snd_hdac_calc_stream_format(runtime->rate, |
@@ -648,7 +648,8 @@ static struct snd_soc_dai_driver skl_platform_dai[] = { | |||
648 | .channels_min = HDA_MONO, | 648 | .channels_min = HDA_MONO, |
649 | .channels_max = HDA_STEREO, | 649 | .channels_max = HDA_STEREO, |
650 | .rates = SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_8000, | 650 | .rates = SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_8000, |
651 | .formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE, | 651 | .formats = SNDRV_PCM_FMTBIT_S16_LE | |
652 | SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE, | ||
652 | }, | 653 | }, |
653 | .capture = { | 654 | .capture = { |
654 | .stream_name = "System Capture", | 655 | .stream_name = "System Capture", |
@@ -1020,7 +1021,7 @@ static int skl_platform_pcm_trigger(struct snd_pcm_substream *substream, | |||
1020 | { | 1021 | { |
1021 | struct hdac_ext_bus *ebus = get_bus_ctx(substream); | 1022 | struct hdac_ext_bus *ebus = get_bus_ctx(substream); |
1022 | 1023 | ||
1023 | if (!ebus->ppcap) | 1024 | if (!(ebus_to_hbus(ebus))->ppcap) |
1024 | return skl_coupled_trigger(substream, cmd); | 1025 | return skl_coupled_trigger(substream, cmd); |
1025 | 1026 | ||
1026 | return 0; | 1027 | return 0; |
@@ -1093,7 +1094,7 @@ static int skl_get_time_info(struct snd_pcm_substream *substream, | |||
1093 | return 0; | 1094 | return 0; |
1094 | } | 1095 | } |
1095 | 1096 | ||
1096 | static struct snd_pcm_ops skl_platform_ops = { | 1097 | static const struct snd_pcm_ops skl_platform_ops = { |
1097 | .open = skl_platform_open, | 1098 | .open = skl_platform_open, |
1098 | .ioctl = snd_pcm_lib_ioctl, | 1099 | .ioctl = snd_pcm_lib_ioctl, |
1099 | .trigger = skl_platform_pcm_trigger, | 1100 | .trigger = skl_platform_pcm_trigger, |
@@ -1138,20 +1139,67 @@ static int skl_pcm_new(struct snd_soc_pcm_runtime *rtd) | |||
1138 | return retval; | 1139 | return retval; |
1139 | } | 1140 | } |
1140 | 1141 | ||
1142 | static int skl_populate_modules(struct skl *skl) | ||
1143 | { | ||
1144 | struct skl_pipeline *p; | ||
1145 | struct skl_pipe_module *m; | ||
1146 | struct snd_soc_dapm_widget *w; | ||
1147 | struct skl_module_cfg *mconfig; | ||
1148 | int ret; | ||
1149 | |||
1150 | list_for_each_entry(p, &skl->ppl_list, node) { | ||
1151 | list_for_each_entry(m, &p->pipe->w_list, node) { | ||
1152 | |||
1153 | w = m->w; | ||
1154 | mconfig = w->priv; | ||
1155 | |||
1156 | ret = snd_skl_get_module_info(skl->skl_sst, mconfig); | ||
1157 | if (ret < 0) { | ||
1158 | dev_err(skl->skl_sst->dev, | ||
1159 | "query module info failed:%d\n", ret); | ||
1160 | goto err; | ||
1161 | } | ||
1162 | } | ||
1163 | } | ||
1164 | err: | ||
1165 | return ret; | ||
1166 | } | ||
1167 | |||
1141 | static int skl_platform_soc_probe(struct snd_soc_platform *platform) | 1168 | static int skl_platform_soc_probe(struct snd_soc_platform *platform) |
1142 | { | 1169 | { |
1143 | struct hdac_ext_bus *ebus = dev_get_drvdata(platform->dev); | 1170 | struct hdac_ext_bus *ebus = dev_get_drvdata(platform->dev); |
1144 | struct skl *skl = ebus_to_skl(ebus); | 1171 | struct skl *skl = ebus_to_skl(ebus); |
1172 | const struct skl_dsp_ops *ops; | ||
1145 | int ret; | 1173 | int ret; |
1146 | 1174 | ||
1147 | if (ebus->ppcap) { | 1175 | pm_runtime_get_sync(platform->dev); |
1176 | if ((ebus_to_hbus(ebus))->ppcap) { | ||
1148 | ret = skl_tplg_init(platform, ebus); | 1177 | ret = skl_tplg_init(platform, ebus); |
1149 | if (ret < 0) { | 1178 | if (ret < 0) { |
1150 | dev_err(platform->dev, "Failed to init topology!\n"); | 1179 | dev_err(platform->dev, "Failed to init topology!\n"); |
1151 | return ret; | 1180 | return ret; |
1152 | } | 1181 | } |
1153 | skl->platform = platform; | 1182 | skl->platform = platform; |
1183 | |||
1184 | /* load the firmwares, since all is set */ | ||
1185 | ops = skl_get_dsp_ops(skl->pci->device); | ||
1186 | if (!ops) | ||
1187 | return -EIO; | ||
1188 | |||
1189 | if (skl->skl_sst->is_first_boot == false) { | ||
1190 | dev_err(platform->dev, "DSP reports first boot done!!!\n"); | ||
1191 | return -EIO; | ||
1192 | } | ||
1193 | |||
1194 | ret = ops->init_fw(platform->dev, skl->skl_sst); | ||
1195 | if (ret < 0) { | ||
1196 | dev_err(platform->dev, "Failed to boot first fw: %d\n", ret); | ||
1197 | return ret; | ||
1198 | } | ||
1199 | skl_populate_modules(skl); | ||
1154 | } | 1200 | } |
1201 | pm_runtime_mark_last_busy(platform->dev); | ||
1202 | pm_runtime_put_autosuspend(platform->dev); | ||
1155 | 1203 | ||
1156 | return 0; | 1204 | return 0; |
1157 | } | 1205 | } |
diff --git a/sound/soc/intel/skylake/skl-sst-cldma.c b/sound/soc/intel/skylake/skl-sst-cldma.c index da2329d17f4d..efa2532114ba 100644 --- a/sound/soc/intel/skylake/skl-sst-cldma.c +++ b/sound/soc/intel/skylake/skl-sst-cldma.c | |||
@@ -341,14 +341,14 @@ int skl_cldma_prepare(struct sst_dsp *ctx) | |||
341 | ret = ctx->dsp_ops.alloc_dma_buf(ctx->dev, | 341 | ret = ctx->dsp_ops.alloc_dma_buf(ctx->dev, |
342 | &ctx->cl_dev.dmab_data, ctx->cl_dev.bufsize); | 342 | &ctx->cl_dev.dmab_data, ctx->cl_dev.bufsize); |
343 | if (ret < 0) { | 343 | if (ret < 0) { |
344 | dev_err(ctx->dev, "Alloc buffer for base fw failed: %x", ret); | 344 | dev_err(ctx->dev, "Alloc buffer for base fw failed: %x\n", ret); |
345 | return ret; | 345 | return ret; |
346 | } | 346 | } |
347 | /* Setup Code loader BDL */ | 347 | /* Setup Code loader BDL */ |
348 | ret = ctx->dsp_ops.alloc_dma_buf(ctx->dev, | 348 | ret = ctx->dsp_ops.alloc_dma_buf(ctx->dev, |
349 | &ctx->cl_dev.dmab_bdl, PAGE_SIZE); | 349 | &ctx->cl_dev.dmab_bdl, PAGE_SIZE); |
350 | if (ret < 0) { | 350 | if (ret < 0) { |
351 | dev_err(ctx->dev, "Alloc buffer for blde failed: %x", ret); | 351 | dev_err(ctx->dev, "Alloc buffer for blde failed: %x\n", ret); |
352 | ctx->dsp_ops.free_dma_buf(ctx->dev, &ctx->cl_dev.dmab_data); | 352 | ctx->dsp_ops.free_dma_buf(ctx->dev, &ctx->cl_dev.dmab_data); |
353 | return ret; | 353 | return ret; |
354 | } | 354 | } |
diff --git a/sound/soc/intel/skylake/skl-sst-dsp.h b/sound/soc/intel/skylake/skl-sst-dsp.h index 0f8629ef79ac..b9e71d051fb1 100644 --- a/sound/soc/intel/skylake/skl-sst-dsp.h +++ b/sound/soc/intel/skylake/skl-sst-dsp.h | |||
@@ -20,6 +20,7 @@ | |||
20 | #include <sound/memalloc.h> | 20 | #include <sound/memalloc.h> |
21 | #include "skl-sst-cldma.h" | 21 | #include "skl-sst-cldma.h" |
22 | #include "skl-tplg-interface.h" | 22 | #include "skl-tplg-interface.h" |
23 | #include "skl-topology.h" | ||
23 | 24 | ||
24 | struct sst_dsp; | 25 | struct sst_dsp; |
25 | struct skl_sst; | 26 | struct skl_sst; |
@@ -133,6 +134,8 @@ enum skl_dsp_states { | |||
133 | struct skl_dsp_fw_ops { | 134 | struct skl_dsp_fw_ops { |
134 | int (*load_fw)(struct sst_dsp *ctx); | 135 | int (*load_fw)(struct sst_dsp *ctx); |
135 | /* FW module parser/loader */ | 136 | /* FW module parser/loader */ |
137 | int (*load_library)(struct sst_dsp *ctx, | ||
138 | struct skl_dfw_manifest *minfo); | ||
136 | int (*parse_fw)(struct sst_dsp *ctx); | 139 | int (*parse_fw)(struct sst_dsp *ctx); |
137 | int (*set_state_D0)(struct sst_dsp *ctx, unsigned int core_id); | 140 | int (*set_state_D0)(struct sst_dsp *ctx, unsigned int core_id); |
138 | int (*set_state_D3)(struct sst_dsp *ctx, unsigned int core_id); | 141 | int (*set_state_D3)(struct sst_dsp *ctx, unsigned int core_id); |
@@ -203,12 +206,21 @@ int skl_sst_dsp_init(struct device *dev, void __iomem *mmio_base, int irq, | |||
203 | int bxt_sst_dsp_init(struct device *dev, void __iomem *mmio_base, int irq, | 206 | int bxt_sst_dsp_init(struct device *dev, void __iomem *mmio_base, int irq, |
204 | const char *fw_name, struct skl_dsp_loader_ops dsp_ops, | 207 | const char *fw_name, struct skl_dsp_loader_ops dsp_ops, |
205 | struct skl_sst **dsp); | 208 | struct skl_sst **dsp); |
209 | int skl_sst_init_fw(struct device *dev, struct skl_sst *ctx); | ||
210 | int bxt_sst_init_fw(struct device *dev, struct skl_sst *ctx); | ||
206 | void skl_sst_dsp_cleanup(struct device *dev, struct skl_sst *ctx); | 211 | void skl_sst_dsp_cleanup(struct device *dev, struct skl_sst *ctx); |
207 | void bxt_sst_dsp_cleanup(struct device *dev, struct skl_sst *ctx); | 212 | void bxt_sst_dsp_cleanup(struct device *dev, struct skl_sst *ctx); |
208 | 213 | ||
209 | int snd_skl_get_module_info(struct skl_sst *ctx, u8 *uuid, | 214 | int snd_skl_get_module_info(struct skl_sst *ctx, |
210 | struct skl_dfw_module *dfw_config); | 215 | struct skl_module_cfg *mconfig); |
211 | int snd_skl_parse_uuids(struct sst_dsp *ctx, unsigned int offset); | 216 | int snd_skl_parse_uuids(struct sst_dsp *ctx, const struct firmware *fw, |
217 | unsigned int offset, int index); | ||
218 | int skl_get_pvt_id(struct skl_sst *ctx, | ||
219 | struct skl_module_cfg *mconfig); | ||
220 | int skl_put_pvt_id(struct skl_sst *ctx, | ||
221 | struct skl_module_cfg *mconfig); | ||
222 | int skl_get_pvt_instance_id_map(struct skl_sst *ctx, | ||
223 | int module_id, int instance_id); | ||
212 | void skl_freeup_uuid_list(struct skl_sst *ctx); | 224 | void skl_freeup_uuid_list(struct skl_sst *ctx); |
213 | 225 | ||
214 | int skl_dsp_strip_extended_manifest(struct firmware *fw); | 226 | int skl_dsp_strip_extended_manifest(struct firmware *fw); |
diff --git a/sound/soc/intel/skylake/skl-sst-ipc.c b/sound/soc/intel/skylake/skl-sst-ipc.c index 96f2f6889b18..0bd01e62622c 100644 --- a/sound/soc/intel/skylake/skl-sst-ipc.c +++ b/sound/soc/intel/skylake/skl-sst-ipc.c | |||
@@ -114,6 +114,11 @@ | |||
114 | #define IPC_CORE_ID(x) (((x) & IPC_CORE_ID_MASK) \ | 114 | #define IPC_CORE_ID(x) (((x) & IPC_CORE_ID_MASK) \ |
115 | << IPC_CORE_ID_SHIFT) | 115 | << IPC_CORE_ID_SHIFT) |
116 | 116 | ||
117 | #define IPC_DOMAIN_SHIFT 28 | ||
118 | #define IPC_DOMAIN_MASK 0x1 | ||
119 | #define IPC_DOMAIN(x) (((x) & IPC_DOMAIN_MASK) \ | ||
120 | << IPC_DOMAIN_SHIFT) | ||
121 | |||
117 | /* Bind/Unbind message extension register */ | 122 | /* Bind/Unbind message extension register */ |
118 | #define IPC_DST_MOD_ID_SHIFT 0 | 123 | #define IPC_DST_MOD_ID_SHIFT 0 |
119 | #define IPC_DST_MOD_ID(x) (((x) & IPC_MOD_ID_MASK) \ | 124 | #define IPC_DST_MOD_ID(x) (((x) & IPC_MOD_ID_MASK) \ |
@@ -190,6 +195,7 @@ enum skl_ipc_glb_type { | |||
190 | IPC_GLB_GET_PPL_CONTEXT_SIZE = 21, | 195 | IPC_GLB_GET_PPL_CONTEXT_SIZE = 21, |
191 | IPC_GLB_SAVE_PPL = 22, | 196 | IPC_GLB_SAVE_PPL = 22, |
192 | IPC_GLB_RESTORE_PPL = 23, | 197 | IPC_GLB_RESTORE_PPL = 23, |
198 | IPC_GLB_LOAD_LIBRARY = 24, | ||
193 | IPC_GLB_NOTIFY = 26, | 199 | IPC_GLB_NOTIFY = 26, |
194 | IPC_GLB_MAX_IPC_MSG_NUMBER = 31 /* Maximum message number */ | 200 | IPC_GLB_MAX_IPC_MSG_NUMBER = 31 /* Maximum message number */ |
195 | }; | 201 | }; |
@@ -338,7 +344,7 @@ static int skl_ipc_process_notification(struct sst_generic_ipc *ipc, | |||
338 | break; | 344 | break; |
339 | 345 | ||
340 | default: | 346 | default: |
341 | dev_err(ipc->dev, "ipc: Unhandled error msg=%x", | 347 | dev_err(ipc->dev, "ipc: Unhandled error msg=%x\n", |
342 | header.primary); | 348 | header.primary); |
343 | break; | 349 | break; |
344 | } | 350 | } |
@@ -379,13 +385,13 @@ static void skl_ipc_process_reply(struct sst_generic_ipc *ipc, | |||
379 | break; | 385 | break; |
380 | 386 | ||
381 | default: | 387 | default: |
382 | dev_err(ipc->dev, "Unknown ipc reply: 0x%x", reply); | 388 | dev_err(ipc->dev, "Unknown ipc reply: 0x%x\n", reply); |
383 | msg->errno = -EINVAL; | 389 | msg->errno = -EINVAL; |
384 | break; | 390 | break; |
385 | } | 391 | } |
386 | 392 | ||
387 | if (reply != IPC_GLB_REPLY_SUCCESS) { | 393 | if (reply != IPC_GLB_REPLY_SUCCESS) { |
388 | dev_err(ipc->dev, "ipc FW reply: reply=%d", reply); | 394 | dev_err(ipc->dev, "ipc FW reply: reply=%d\n", reply); |
389 | dev_err(ipc->dev, "FW Error Code: %u\n", | 395 | dev_err(ipc->dev, "FW Error Code: %u\n", |
390 | ipc->dsp->fw_ops.get_fw_errcode(ipc->dsp)); | 396 | ipc->dsp->fw_ops.get_fw_errcode(ipc->dsp)); |
391 | } | 397 | } |
@@ -434,9 +440,9 @@ irqreturn_t skl_dsp_irq_thread_handler(int irq, void *context) | |||
434 | hipcte = sst_dsp_shim_read_unlocked(dsp, SKL_ADSP_REG_HIPCTE); | 440 | hipcte = sst_dsp_shim_read_unlocked(dsp, SKL_ADSP_REG_HIPCTE); |
435 | header.primary = hipct; | 441 | header.primary = hipct; |
436 | header.extension = hipcte; | 442 | header.extension = hipcte; |
437 | dev_dbg(dsp->dev, "IPC irq: Firmware respond primary:%x", | 443 | dev_dbg(dsp->dev, "IPC irq: Firmware respond primary:%x\n", |
438 | header.primary); | 444 | header.primary); |
439 | dev_dbg(dsp->dev, "IPC irq: Firmware respond extension:%x", | 445 | dev_dbg(dsp->dev, "IPC irq: Firmware respond extension:%x\n", |
440 | header.extension); | 446 | header.extension); |
441 | 447 | ||
442 | if (IPC_GLB_NOTIFY_RSP_TYPE(header.primary)) { | 448 | if (IPC_GLB_NOTIFY_RSP_TYPE(header.primary)) { |
@@ -704,6 +710,7 @@ int skl_ipc_init_instance(struct sst_generic_ipc *ipc, | |||
704 | header.extension = IPC_CORE_ID(msg->core_id); | 710 | header.extension = IPC_CORE_ID(msg->core_id); |
705 | header.extension |= IPC_PPL_INSTANCE_ID(msg->ppl_instance_id); | 711 | header.extension |= IPC_PPL_INSTANCE_ID(msg->ppl_instance_id); |
706 | header.extension |= IPC_PARAM_BLOCK_SIZE(param_block_size); | 712 | header.extension |= IPC_PARAM_BLOCK_SIZE(param_block_size); |
713 | header.extension |= IPC_DOMAIN(msg->domain); | ||
707 | 714 | ||
708 | dev_dbg(ipc->dev, "In %s primary =%x ext=%x\n", __func__, | 715 | dev_dbg(ipc->dev, "In %s primary =%x ext=%x\n", __func__, |
709 | header.primary, header.extension); | 716 | header.primary, header.extension); |
@@ -742,7 +749,7 @@ int skl_ipc_bind_unbind(struct sst_generic_ipc *ipc, | |||
742 | header.extension); | 749 | header.extension); |
743 | ret = sst_ipc_tx_message_wait(ipc, *ipc_header, NULL, 0, NULL, 0); | 750 | ret = sst_ipc_tx_message_wait(ipc, *ipc_header, NULL, 0, NULL, 0); |
744 | if (ret < 0) { | 751 | if (ret < 0) { |
745 | dev_err(ipc->dev, "ipc: bind/unbind faileden"); | 752 | dev_err(ipc->dev, "ipc: bind/unbind failed\n"); |
746 | return ret; | 753 | return ret; |
747 | } | 754 | } |
748 | 755 | ||
@@ -902,3 +909,25 @@ int skl_ipc_get_large_config(struct sst_generic_ipc *ipc, | |||
902 | return ret; | 909 | return ret; |
903 | } | 910 | } |
904 | EXPORT_SYMBOL_GPL(skl_ipc_get_large_config); | 911 | EXPORT_SYMBOL_GPL(skl_ipc_get_large_config); |
912 | |||
913 | int skl_sst_ipc_load_library(struct sst_generic_ipc *ipc, | ||
914 | u8 dma_id, u8 table_id) | ||
915 | { | ||
916 | struct skl_ipc_header header = {0}; | ||
917 | u64 *ipc_header = (u64 *)(&header); | ||
918 | int ret = 0; | ||
919 | |||
920 | header.primary = IPC_MSG_TARGET(IPC_FW_GEN_MSG); | ||
921 | header.primary |= IPC_MSG_DIR(IPC_MSG_REQUEST); | ||
922 | header.primary |= IPC_GLB_TYPE(IPC_GLB_LOAD_LIBRARY); | ||
923 | header.primary |= IPC_MOD_INSTANCE_ID(table_id); | ||
924 | header.primary |= IPC_MOD_ID(dma_id); | ||
925 | |||
926 | ret = sst_ipc_tx_message_wait(ipc, *ipc_header, NULL, 0, NULL, 0); | ||
927 | |||
928 | if (ret < 0) | ||
929 | dev_err(ipc->dev, "ipc: load lib failed\n"); | ||
930 | |||
931 | return ret; | ||
932 | } | ||
933 | EXPORT_SYMBOL_GPL(skl_sst_ipc_load_library); | ||
diff --git a/sound/soc/intel/skylake/skl-sst-ipc.h b/sound/soc/intel/skylake/skl-sst-ipc.h index 2e3d4e80ef97..0334ed4af031 100644 --- a/sound/soc/intel/skylake/skl-sst-ipc.h +++ b/sound/soc/intel/skylake/skl-sst-ipc.h | |||
@@ -66,7 +66,7 @@ struct skl_sst { | |||
66 | 66 | ||
67 | /* callback for miscbdge */ | 67 | /* callback for miscbdge */ |
68 | void (*enable_miscbdcge)(struct device *dev, bool enable); | 68 | void (*enable_miscbdcge)(struct device *dev, bool enable); |
69 | /*Is CGCTL.MISCBDCGE disabled*/ | 69 | /* Is CGCTL.MISCBDCGE disabled */ |
70 | bool miscbdcg_disabled; | 70 | bool miscbdcg_disabled; |
71 | 71 | ||
72 | /* Populate module information */ | 72 | /* Populate module information */ |
@@ -75,8 +75,14 @@ struct skl_sst { | |||
75 | /* Is firmware loaded */ | 75 | /* Is firmware loaded */ |
76 | bool fw_loaded; | 76 | bool fw_loaded; |
77 | 77 | ||
78 | /* first boot ? */ | ||
79 | bool is_first_boot; | ||
80 | |||
78 | /* multi-core */ | 81 | /* multi-core */ |
79 | struct skl_dsp_cores cores; | 82 | struct skl_dsp_cores cores; |
83 | |||
84 | /* tplg manifest */ | ||
85 | struct skl_dfw_manifest manifest; | ||
80 | }; | 86 | }; |
81 | 87 | ||
82 | struct skl_ipc_init_instance_msg { | 88 | struct skl_ipc_init_instance_msg { |
@@ -85,6 +91,7 @@ struct skl_ipc_init_instance_msg { | |||
85 | u16 param_data_size; | 91 | u16 param_data_size; |
86 | u8 ppl_instance_id; | 92 | u8 ppl_instance_id; |
87 | u8 core_id; | 93 | u8 core_id; |
94 | u8 domain; | ||
88 | }; | 95 | }; |
89 | 96 | ||
90 | struct skl_ipc_bind_unbind_msg { | 97 | struct skl_ipc_bind_unbind_msg { |
@@ -145,6 +152,9 @@ int skl_ipc_set_large_config(struct sst_generic_ipc *ipc, | |||
145 | int skl_ipc_get_large_config(struct sst_generic_ipc *ipc, | 152 | int skl_ipc_get_large_config(struct sst_generic_ipc *ipc, |
146 | struct skl_ipc_large_config_msg *msg, u32 *param); | 153 | struct skl_ipc_large_config_msg *msg, u32 *param); |
147 | 154 | ||
155 | int skl_sst_ipc_load_library(struct sst_generic_ipc *ipc, | ||
156 | u8 dma_id, u8 table_id); | ||
157 | |||
148 | void skl_ipc_int_enable(struct sst_dsp *dsp); | 158 | void skl_ipc_int_enable(struct sst_dsp *dsp); |
149 | void skl_ipc_op_int_enable(struct sst_dsp *ctx); | 159 | void skl_ipc_op_int_enable(struct sst_dsp *ctx); |
150 | void skl_ipc_op_int_disable(struct sst_dsp *ctx); | 160 | void skl_ipc_op_int_disable(struct sst_dsp *ctx); |
diff --git a/sound/soc/intel/skylake/skl-sst-utils.c b/sound/soc/intel/skylake/skl-sst-utils.c index ddcb52a51854..8dc03039b311 100644 --- a/sound/soc/intel/skylake/skl-sst-utils.c +++ b/sound/soc/intel/skylake/skl-sst-utils.c | |||
@@ -28,11 +28,6 @@ | |||
28 | /* FW Extended Manifest Header id = $AE1 */ | 28 | /* FW Extended Manifest Header id = $AE1 */ |
29 | #define SKL_EXT_MANIFEST_HEADER_MAGIC 0x31454124 | 29 | #define SKL_EXT_MANIFEST_HEADER_MAGIC 0x31454124 |
30 | 30 | ||
31 | struct skl_dfw_module_mod { | ||
32 | char name[100]; | ||
33 | struct skl_dfw_module skl_dfw_mod; | ||
34 | }; | ||
35 | |||
36 | struct UUID { | 31 | struct UUID { |
37 | u8 id[16]; | 32 | u8 id[16]; |
38 | }; | 33 | }; |
@@ -99,10 +94,15 @@ struct adsp_fw_hdr { | |||
99 | u32 load_offset; | 94 | u32 load_offset; |
100 | } __packed; | 95 | } __packed; |
101 | 96 | ||
97 | #define MAX_INSTANCE_BUFF 2 | ||
98 | |||
102 | struct uuid_module { | 99 | struct uuid_module { |
103 | uuid_le uuid; | 100 | uuid_le uuid; |
104 | int id; | 101 | int id; |
105 | int is_loadable; | 102 | int is_loadable; |
103 | int max_instance; | ||
104 | u64 pvt_id[MAX_INSTANCE_BUFF]; | ||
105 | int *instance_id; | ||
106 | 106 | ||
107 | struct list_head list; | 107 | struct list_head list; |
108 | }; | 108 | }; |
@@ -115,13 +115,13 @@ struct skl_ext_manifest_hdr { | |||
115 | u32 entries; | 115 | u32 entries; |
116 | }; | 116 | }; |
117 | 117 | ||
118 | int snd_skl_get_module_info(struct skl_sst *ctx, u8 *uuid, | 118 | int snd_skl_get_module_info(struct skl_sst *ctx, |
119 | struct skl_dfw_module *dfw_config) | 119 | struct skl_module_cfg *mconfig) |
120 | { | 120 | { |
121 | struct uuid_module *module; | 121 | struct uuid_module *module; |
122 | uuid_le *uuid_mod; | 122 | uuid_le *uuid_mod; |
123 | 123 | ||
124 | uuid_mod = (uuid_le *)uuid; | 124 | uuid_mod = (uuid_le *)mconfig->guid; |
125 | 125 | ||
126 | if (list_empty(&ctx->uuid_list)) { | 126 | if (list_empty(&ctx->uuid_list)) { |
127 | dev_err(ctx->dev, "Module list is empty\n"); | 127 | dev_err(ctx->dev, "Module list is empty\n"); |
@@ -130,8 +130,8 @@ int snd_skl_get_module_info(struct skl_sst *ctx, u8 *uuid, | |||
130 | 130 | ||
131 | list_for_each_entry(module, &ctx->uuid_list, list) { | 131 | list_for_each_entry(module, &ctx->uuid_list, list) { |
132 | if (uuid_le_cmp(*uuid_mod, module->uuid) == 0) { | 132 | if (uuid_le_cmp(*uuid_mod, module->uuid) == 0) { |
133 | dfw_config->module_id = module->id; | 133 | mconfig->id.module_id = module->id; |
134 | dfw_config->is_loadable = module->is_loadable; | 134 | mconfig->is_loadable = module->is_loadable; |
135 | 135 | ||
136 | return 0; | 136 | return 0; |
137 | } | 137 | } |
@@ -141,15 +141,154 @@ int snd_skl_get_module_info(struct skl_sst *ctx, u8 *uuid, | |||
141 | } | 141 | } |
142 | EXPORT_SYMBOL_GPL(snd_skl_get_module_info); | 142 | EXPORT_SYMBOL_GPL(snd_skl_get_module_info); |
143 | 143 | ||
144 | static int skl_get_pvtid_map(struct uuid_module *module, int instance_id) | ||
145 | { | ||
146 | int pvt_id; | ||
147 | |||
148 | for (pvt_id = 0; pvt_id < module->max_instance; pvt_id++) { | ||
149 | if (module->instance_id[pvt_id] == instance_id) | ||
150 | return pvt_id; | ||
151 | } | ||
152 | return -EINVAL; | ||
153 | } | ||
154 | |||
155 | int skl_get_pvt_instance_id_map(struct skl_sst *ctx, | ||
156 | int module_id, int instance_id) | ||
157 | { | ||
158 | struct uuid_module *module; | ||
159 | |||
160 | list_for_each_entry(module, &ctx->uuid_list, list) { | ||
161 | if (module->id == module_id) | ||
162 | return skl_get_pvtid_map(module, instance_id); | ||
163 | } | ||
164 | |||
165 | return -EINVAL; | ||
166 | } | ||
167 | EXPORT_SYMBOL_GPL(skl_get_pvt_instance_id_map); | ||
168 | |||
169 | static inline int skl_getid_32(struct uuid_module *module, u64 *val, | ||
170 | int word1_mask, int word2_mask) | ||
171 | { | ||
172 | int index, max_inst, pvt_id; | ||
173 | u32 mask_val; | ||
174 | |||
175 | max_inst = module->max_instance; | ||
176 | mask_val = (u32)(*val >> word1_mask); | ||
177 | |||
178 | if (mask_val != 0xffffffff) { | ||
179 | index = ffz(mask_val); | ||
180 | pvt_id = index + word1_mask + word2_mask; | ||
181 | if (pvt_id <= (max_inst - 1)) { | ||
182 | *val |= 1 << (index + word1_mask); | ||
183 | return pvt_id; | ||
184 | } | ||
185 | } | ||
186 | |||
187 | return -EINVAL; | ||
188 | } | ||
189 | |||
190 | static inline int skl_pvtid_128(struct uuid_module *module) | ||
191 | { | ||
192 | int j, i, word1_mask, word2_mask = 0, pvt_id; | ||
193 | |||
194 | for (j = 0; j < MAX_INSTANCE_BUFF; j++) { | ||
195 | word1_mask = 0; | ||
196 | |||
197 | for (i = 0; i < 2; i++) { | ||
198 | pvt_id = skl_getid_32(module, &module->pvt_id[j], | ||
199 | word1_mask, word2_mask); | ||
200 | if (pvt_id >= 0) | ||
201 | return pvt_id; | ||
202 | |||
203 | word1_mask += 32; | ||
204 | if ((word1_mask + word2_mask) >= module->max_instance) | ||
205 | return -EINVAL; | ||
206 | } | ||
207 | |||
208 | word2_mask += 64; | ||
209 | if (word2_mask >= module->max_instance) | ||
210 | return -EINVAL; | ||
211 | } | ||
212 | |||
213 | return -EINVAL; | ||
214 | } | ||
215 | |||
216 | /** | ||
217 | * skl_get_pvt_id: generate a private id for use as module id | ||
218 | * | ||
219 | * @ctx: driver context | ||
220 | * @mconfig: module configuration data | ||
221 | * | ||
222 | * This generates a 128 bit private unique id for a module TYPE so that | ||
223 | * module instance is unique | ||
224 | */ | ||
225 | int skl_get_pvt_id(struct skl_sst *ctx, struct skl_module_cfg *mconfig) | ||
226 | { | ||
227 | struct uuid_module *module; | ||
228 | uuid_le *uuid_mod; | ||
229 | int pvt_id; | ||
230 | |||
231 | uuid_mod = (uuid_le *)mconfig->guid; | ||
232 | |||
233 | list_for_each_entry(module, &ctx->uuid_list, list) { | ||
234 | if (uuid_le_cmp(*uuid_mod, module->uuid) == 0) { | ||
235 | |||
236 | pvt_id = skl_pvtid_128(module); | ||
237 | if (pvt_id >= 0) { | ||
238 | module->instance_id[pvt_id] = | ||
239 | mconfig->id.instance_id; | ||
240 | return pvt_id; | ||
241 | } | ||
242 | } | ||
243 | } | ||
244 | |||
245 | return -EINVAL; | ||
246 | } | ||
247 | EXPORT_SYMBOL_GPL(skl_get_pvt_id); | ||
248 | |||
249 | /** | ||
250 | * skl_put_pvt_id: free up the private id allocated | ||
251 | * | ||
252 | * @ctx: driver context | ||
253 | * @mconfig: module configuration data | ||
254 | * | ||
255 | * This frees a 128 bit private unique id previously generated | ||
256 | */ | ||
257 | int skl_put_pvt_id(struct skl_sst *ctx, struct skl_module_cfg *mconfig) | ||
258 | { | ||
259 | int i; | ||
260 | uuid_le *uuid_mod; | ||
261 | struct uuid_module *module; | ||
262 | |||
263 | uuid_mod = (uuid_le *)mconfig->guid; | ||
264 | list_for_each_entry(module, &ctx->uuid_list, list) { | ||
265 | if (uuid_le_cmp(*uuid_mod, module->uuid) == 0) { | ||
266 | |||
267 | if (mconfig->id.pvt_id != 0) | ||
268 | i = (mconfig->id.pvt_id) / 64; | ||
269 | else | ||
270 | i = 0; | ||
271 | |||
272 | module->pvt_id[i] &= ~(1 << (mconfig->id.pvt_id)); | ||
273 | mconfig->id.pvt_id = -1; | ||
274 | return 0; | ||
275 | } | ||
276 | } | ||
277 | |||
278 | return -EINVAL; | ||
279 | } | ||
280 | EXPORT_SYMBOL_GPL(skl_put_pvt_id); | ||
281 | |||
144 | /* | 282 | /* |
145 | * Parse the firmware binary to get the UUID, module id | 283 | * Parse the firmware binary to get the UUID, module id |
146 | * and loadable flags | 284 | * and loadable flags |
147 | */ | 285 | */ |
148 | int snd_skl_parse_uuids(struct sst_dsp *ctx, unsigned int offset) | 286 | int snd_skl_parse_uuids(struct sst_dsp *ctx, const struct firmware *fw, |
287 | unsigned int offset, int index) | ||
149 | { | 288 | { |
150 | struct adsp_fw_hdr *adsp_hdr; | 289 | struct adsp_fw_hdr *adsp_hdr; |
151 | struct adsp_module_entry *mod_entry; | 290 | struct adsp_module_entry *mod_entry; |
152 | int i, num_entry; | 291 | int i, num_entry, size; |
153 | uuid_le *uuid_bin; | 292 | uuid_le *uuid_bin; |
154 | const char *buf; | 293 | const char *buf; |
155 | struct skl_sst *skl = ctx->thread_context; | 294 | struct skl_sst *skl = ctx->thread_context; |
@@ -158,8 +297,8 @@ int snd_skl_parse_uuids(struct sst_dsp *ctx, unsigned int offset) | |||
158 | unsigned int safe_file; | 297 | unsigned int safe_file; |
159 | 298 | ||
160 | /* Get the FW pointer to derive ADSP header */ | 299 | /* Get the FW pointer to derive ADSP header */ |
161 | stripped_fw.data = ctx->fw->data; | 300 | stripped_fw.data = fw->data; |
162 | stripped_fw.size = ctx->fw->size; | 301 | stripped_fw.size = fw->size; |
163 | 302 | ||
164 | skl_dsp_strip_extended_manifest(&stripped_fw); | 303 | skl_dsp_strip_extended_manifest(&stripped_fw); |
165 | 304 | ||
@@ -210,8 +349,15 @@ int snd_skl_parse_uuids(struct sst_dsp *ctx, unsigned int offset) | |||
210 | uuid_bin = (uuid_le *)mod_entry->uuid.id; | 349 | uuid_bin = (uuid_le *)mod_entry->uuid.id; |
211 | memcpy(&module->uuid, uuid_bin, sizeof(module->uuid)); | 350 | memcpy(&module->uuid, uuid_bin, sizeof(module->uuid)); |
212 | 351 | ||
213 | module->id = i; | 352 | module->id = (i | (index << 12)); |
214 | module->is_loadable = mod_entry->type.load_type; | 353 | module->is_loadable = mod_entry->type.load_type; |
354 | module->max_instance = mod_entry->instance_max_count; | ||
355 | size = sizeof(int) * mod_entry->instance_max_count; | ||
356 | module->instance_id = devm_kzalloc(ctx->dev, size, GFP_KERNEL); | ||
357 | if (!module->instance_id) { | ||
358 | kfree(module); | ||
359 | return -ENOMEM; | ||
360 | } | ||
215 | 361 | ||
216 | list_add_tail(&module->list, &skl->uuid_list); | 362 | list_add_tail(&module->list, &skl->uuid_list); |
217 | 363 | ||
diff --git a/sound/soc/intel/skylake/skl-sst.c b/sound/soc/intel/skylake/skl-sst.c index 588f899ceb65..8fc3178bc79c 100644 --- a/sound/soc/intel/skylake/skl-sst.c +++ b/sound/soc/intel/skylake/skl-sst.c | |||
@@ -88,13 +88,15 @@ static int skl_load_base_firmware(struct sst_dsp *ctx) | |||
88 | } | 88 | } |
89 | } | 89 | } |
90 | 90 | ||
91 | ret = snd_skl_parse_uuids(ctx, SKL_ADSP_FW_BIN_HDR_OFFSET); | 91 | /* prase uuids on first boot */ |
92 | if (ret < 0) { | 92 | if (skl->is_first_boot) { |
93 | dev_err(ctx->dev, | 93 | ret = snd_skl_parse_uuids(ctx, ctx->fw, SKL_ADSP_FW_BIN_HDR_OFFSET, 0); |
94 | "UUID parsing err: %d\n", ret); | 94 | if (ret < 0) { |
95 | release_firmware(ctx->fw); | 95 | dev_err(ctx->dev, "UUID parsing err: %d\n", ret); |
96 | skl_dsp_disable_core(ctx, SKL_DSP_CORE0_MASK); | 96 | release_firmware(ctx->fw); |
97 | return ret; | 97 | skl_dsp_disable_core(ctx, SKL_DSP_CORE0_MASK); |
98 | return ret; | ||
99 | } | ||
98 | } | 100 | } |
99 | 101 | ||
100 | /* check for extended manifest */ | 102 | /* check for extended manifest */ |
@@ -105,13 +107,13 @@ static int skl_load_base_firmware(struct sst_dsp *ctx) | |||
105 | 107 | ||
106 | ret = skl_dsp_boot(ctx); | 108 | ret = skl_dsp_boot(ctx); |
107 | if (ret < 0) { | 109 | if (ret < 0) { |
108 | dev_err(ctx->dev, "Boot dsp core failed ret: %d", ret); | 110 | dev_err(ctx->dev, "Boot dsp core failed ret: %d\n", ret); |
109 | goto skl_load_base_firmware_failed; | 111 | goto skl_load_base_firmware_failed; |
110 | } | 112 | } |
111 | 113 | ||
112 | ret = skl_cldma_prepare(ctx); | 114 | ret = skl_cldma_prepare(ctx); |
113 | if (ret < 0) { | 115 | if (ret < 0) { |
114 | dev_err(ctx->dev, "CL dma prepare failed : %d", ret); | 116 | dev_err(ctx->dev, "CL dma prepare failed : %d\n", ret); |
115 | goto skl_load_base_firmware_failed; | 117 | goto skl_load_base_firmware_failed; |
116 | } | 118 | } |
117 | 119 | ||
@@ -484,25 +486,32 @@ int skl_sst_dsp_init(struct device *dev, void __iomem *mmio_base, int irq, | |||
484 | return ret; | 486 | return ret; |
485 | 487 | ||
486 | skl->cores.count = 2; | 488 | skl->cores.count = 2; |
489 | skl->is_first_boot = true; | ||
490 | |||
491 | if (dsp) | ||
492 | *dsp = skl; | ||
493 | |||
494 | return ret; | ||
495 | } | ||
496 | EXPORT_SYMBOL_GPL(skl_sst_dsp_init); | ||
497 | |||
498 | int skl_sst_init_fw(struct device *dev, struct skl_sst *ctx) | ||
499 | { | ||
500 | int ret; | ||
501 | struct sst_dsp *sst = ctx->dsp; | ||
487 | 502 | ||
488 | ret = sst->fw_ops.load_fw(sst); | 503 | ret = sst->fw_ops.load_fw(sst); |
489 | if (ret < 0) { | 504 | if (ret < 0) { |
490 | dev_err(dev, "Load base fw failed : %d", ret); | 505 | dev_err(dev, "Load base fw failed : %d\n", ret); |
491 | goto cleanup; | 506 | return ret; |
492 | } | 507 | } |
493 | 508 | ||
494 | skl_dsp_init_core_state(sst); | 509 | skl_dsp_init_core_state(sst); |
510 | ctx->is_first_boot = false; | ||
495 | 511 | ||
496 | if (dsp) | 512 | return 0; |
497 | *dsp = skl; | ||
498 | |||
499 | return ret; | ||
500 | |||
501 | cleanup: | ||
502 | skl_sst_dsp_cleanup(dev, skl); | ||
503 | return ret; | ||
504 | } | 513 | } |
505 | EXPORT_SYMBOL_GPL(skl_sst_dsp_init); | 514 | EXPORT_SYMBOL_GPL(skl_sst_init_fw); |
506 | 515 | ||
507 | void skl_sst_dsp_cleanup(struct device *dev, struct skl_sst *ctx) | 516 | void skl_sst_dsp_cleanup(struct device *dev, struct skl_sst *ctx) |
508 | { | 517 | { |
diff --git a/sound/soc/intel/skylake/skl-topology.c b/sound/soc/intel/skylake/skl-topology.c index cc0150fc2601..b5b1934d8550 100644 --- a/sound/soc/intel/skylake/skl-topology.c +++ b/sound/soc/intel/skylake/skl-topology.c | |||
@@ -21,6 +21,7 @@ | |||
21 | #include <linux/firmware.h> | 21 | #include <linux/firmware.h> |
22 | #include <sound/soc.h> | 22 | #include <sound/soc.h> |
23 | #include <sound/soc-topology.h> | 23 | #include <sound/soc-topology.h> |
24 | #include <uapi/sound/snd_sst_tokens.h> | ||
24 | #include "skl-sst-dsp.h" | 25 | #include "skl-sst-dsp.h" |
25 | #include "skl-sst-ipc.h" | 26 | #include "skl-sst-ipc.h" |
26 | #include "skl-topology.h" | 27 | #include "skl-topology.h" |
@@ -32,6 +33,8 @@ | |||
32 | #define SKL_CH_FIXUP_MASK (1 << 0) | 33 | #define SKL_CH_FIXUP_MASK (1 << 0) |
33 | #define SKL_RATE_FIXUP_MASK (1 << 1) | 34 | #define SKL_RATE_FIXUP_MASK (1 << 1) |
34 | #define SKL_FMT_FIXUP_MASK (1 << 2) | 35 | #define SKL_FMT_FIXUP_MASK (1 << 2) |
36 | #define SKL_IN_DIR_BIT_MASK BIT(0) | ||
37 | #define SKL_PIN_COUNT_MASK GENMASK(7, 4) | ||
35 | 38 | ||
36 | /* | 39 | /* |
37 | * SKL DSP driver modelling uses only few DAPM widgets so for rest we will | 40 | * SKL DSP driver modelling uses only few DAPM widgets so for rest we will |
@@ -473,6 +476,14 @@ skl_tplg_init_pipe_modules(struct skl *skl, struct skl_pipe *pipe) | |||
473 | w = w_module->w; | 476 | w = w_module->w; |
474 | mconfig = w->priv; | 477 | mconfig = w->priv; |
475 | 478 | ||
479 | /* check if module ids are populated */ | ||
480 | if (mconfig->id.module_id < 0) { | ||
481 | dev_err(skl->skl_sst->dev, | ||
482 | "module %pUL id not populated\n", | ||
483 | (uuid_le *)mconfig->guid); | ||
484 | return -EIO; | ||
485 | } | ||
486 | |||
476 | /* check resource available */ | 487 | /* check resource available */ |
477 | if (!skl_is_pipe_mcps_avail(skl, mconfig)) | 488 | if (!skl_is_pipe_mcps_avail(skl, mconfig)) |
478 | return -ENOMEM; | 489 | return -ENOMEM; |
@@ -494,12 +505,15 @@ skl_tplg_init_pipe_modules(struct skl *skl, struct skl_pipe *pipe) | |||
494 | * FE/BE params | 505 | * FE/BE params |
495 | */ | 506 | */ |
496 | skl_tplg_update_module_params(w, ctx); | 507 | skl_tplg_update_module_params(w, ctx); |
497 | 508 | mconfig->id.pvt_id = skl_get_pvt_id(ctx, mconfig); | |
509 | if (mconfig->id.pvt_id < 0) | ||
510 | return ret; | ||
498 | skl_tplg_set_module_init_data(w); | 511 | skl_tplg_set_module_init_data(w); |
499 | ret = skl_init_module(ctx, mconfig); | 512 | ret = skl_init_module(ctx, mconfig); |
500 | if (ret < 0) | 513 | if (ret < 0) { |
514 | skl_put_pvt_id(ctx, mconfig); | ||
501 | return ret; | 515 | return ret; |
502 | 516 | } | |
503 | skl_tplg_alloc_pipe_mcps(skl, mconfig); | 517 | skl_tplg_alloc_pipe_mcps(skl, mconfig); |
504 | ret = skl_tplg_set_module_params(w, ctx); | 518 | ret = skl_tplg_set_module_params(w, ctx); |
505 | if (ret < 0) | 519 | if (ret < 0) |
@@ -512,6 +526,7 @@ skl_tplg_init_pipe_modules(struct skl *skl, struct skl_pipe *pipe) | |||
512 | static int skl_tplg_unload_pipe_modules(struct skl_sst *ctx, | 526 | static int skl_tplg_unload_pipe_modules(struct skl_sst *ctx, |
513 | struct skl_pipe *pipe) | 527 | struct skl_pipe *pipe) |
514 | { | 528 | { |
529 | int ret; | ||
515 | struct skl_pipe_module *w_module = NULL; | 530 | struct skl_pipe_module *w_module = NULL; |
516 | struct skl_module_cfg *mconfig = NULL; | 531 | struct skl_module_cfg *mconfig = NULL; |
517 | 532 | ||
@@ -519,9 +534,13 @@ static int skl_tplg_unload_pipe_modules(struct skl_sst *ctx, | |||
519 | mconfig = w_module->w->priv; | 534 | mconfig = w_module->w->priv; |
520 | 535 | ||
521 | if (mconfig->is_loadable && ctx->dsp->fw_ops.unload_mod && | 536 | if (mconfig->is_loadable && ctx->dsp->fw_ops.unload_mod && |
522 | mconfig->m_state > SKL_MODULE_UNINIT) | 537 | mconfig->m_state > SKL_MODULE_UNINIT) { |
523 | return ctx->dsp->fw_ops.unload_mod(ctx->dsp, | 538 | ret = ctx->dsp->fw_ops.unload_mod(ctx->dsp, |
524 | mconfig->id.module_id); | 539 | mconfig->id.module_id); |
540 | if (ret < 0) | ||
541 | return -EIO; | ||
542 | } | ||
543 | skl_put_pvt_id(ctx, mconfig); | ||
525 | } | 544 | } |
526 | 545 | ||
527 | /* no modules to unload in this path, so return */ | 546 | /* no modules to unload in this path, so return */ |
@@ -588,6 +607,26 @@ static int skl_tplg_mixer_dapm_pre_pmu_event(struct snd_soc_dapm_widget *w, | |||
588 | return 0; | 607 | return 0; |
589 | } | 608 | } |
590 | 609 | ||
610 | static int skl_fill_sink_instance_id(struct skl_sst *ctx, | ||
611 | struct skl_algo_data *alg_data) | ||
612 | { | ||
613 | struct skl_kpb_params *params = (struct skl_kpb_params *)alg_data->params; | ||
614 | struct skl_mod_inst_map *inst; | ||
615 | int i, pvt_id; | ||
616 | |||
617 | inst = params->map; | ||
618 | |||
619 | for (i = 0; i < params->num_modules; i++) { | ||
620 | pvt_id = skl_get_pvt_instance_id_map(ctx, | ||
621 | inst->mod_id, inst->inst_id); | ||
622 | if (pvt_id < 0) | ||
623 | return -EINVAL; | ||
624 | inst->inst_id = pvt_id; | ||
625 | inst++; | ||
626 | } | ||
627 | return 0; | ||
628 | } | ||
629 | |||
591 | /* | 630 | /* |
592 | * Some modules require params to be set after the module is bound to | 631 | * Some modules require params to be set after the module is bound to |
593 | * all pins connected. | 632 | * all pins connected. |
@@ -636,6 +675,8 @@ static int skl_tplg_set_module_bind_params(struct snd_soc_dapm_widget *w, | |||
636 | bc = (struct skl_algo_data *)sb->dobj.private; | 675 | bc = (struct skl_algo_data *)sb->dobj.private; |
637 | 676 | ||
638 | if (bc->set_params == SKL_PARAM_BIND) { | 677 | if (bc->set_params == SKL_PARAM_BIND) { |
678 | if (mconfig->m_type == SKL_MODULE_TYPE_KPB) | ||
679 | skl_fill_sink_instance_id(ctx, bc); | ||
639 | ret = skl_set_module_params(ctx, | 680 | ret = skl_set_module_params(ctx, |
640 | (u32 *)bc->params, bc->max, | 681 | (u32 *)bc->params, bc->max, |
641 | bc->param_id, mconfig); | 682 | bc->param_id, mconfig); |
@@ -1460,85 +1501,570 @@ static const struct snd_soc_tplg_bytes_ext_ops skl_tlv_ops[] = { | |||
1460 | skl_tplg_tlv_control_set}, | 1501 | skl_tplg_tlv_control_set}, |
1461 | }; | 1502 | }; |
1462 | 1503 | ||
1463 | /* | 1504 | static int skl_tplg_fill_pipe_tkn(struct device *dev, |
1464 | * The topology binary passes the pin info for a module so initialize the pin | 1505 | struct skl_pipe *pipe, u32 tkn, |
1465 | * info passed into module instance | 1506 | u32 tkn_val) |
1466 | */ | ||
1467 | static void skl_fill_module_pin_info(struct skl_dfw_module_pin *dfw_pin, | ||
1468 | struct skl_module_pin *m_pin, | ||
1469 | bool is_dynamic, int max_pin) | ||
1470 | { | 1507 | { |
1471 | int i; | ||
1472 | 1508 | ||
1473 | for (i = 0; i < max_pin; i++) { | 1509 | switch (tkn) { |
1474 | m_pin[i].id.module_id = dfw_pin[i].module_id; | 1510 | case SKL_TKN_U32_PIPE_CONN_TYPE: |
1475 | m_pin[i].id.instance_id = dfw_pin[i].instance_id; | 1511 | pipe->conn_type = tkn_val; |
1476 | m_pin[i].in_use = false; | 1512 | break; |
1477 | m_pin[i].is_dynamic = is_dynamic; | 1513 | |
1478 | m_pin[i].pin_state = SKL_PIN_UNBIND; | 1514 | case SKL_TKN_U32_PIPE_PRIORITY: |
1515 | pipe->pipe_priority = tkn_val; | ||
1516 | break; | ||
1517 | |||
1518 | case SKL_TKN_U32_PIPE_MEM_PGS: | ||
1519 | pipe->memory_pages = tkn_val; | ||
1520 | break; | ||
1521 | |||
1522 | default: | ||
1523 | dev_err(dev, "Token not handled %d\n", tkn); | ||
1524 | return -EINVAL; | ||
1479 | } | 1525 | } |
1526 | |||
1527 | return 0; | ||
1480 | } | 1528 | } |
1481 | 1529 | ||
1482 | /* | 1530 | /* |
1483 | * Add pipeline from topology binary into driver pipeline list | 1531 | * Add pipeline by parsing the relevant tokens |
1484 | * | 1532 | * Return an existing pipe if the pipe already exists. |
1485 | * If already added we return that instance | ||
1486 | * Otherwise we create a new instance and add into driver list | ||
1487 | */ | 1533 | */ |
1488 | static struct skl_pipe *skl_tplg_add_pipe(struct device *dev, | 1534 | static int skl_tplg_add_pipe(struct device *dev, |
1489 | struct skl *skl, struct skl_dfw_pipe *dfw_pipe) | 1535 | struct skl_module_cfg *mconfig, struct skl *skl, |
1536 | struct snd_soc_tplg_vendor_value_elem *tkn_elem) | ||
1490 | { | 1537 | { |
1491 | struct skl_pipeline *ppl; | 1538 | struct skl_pipeline *ppl; |
1492 | struct skl_pipe *pipe; | 1539 | struct skl_pipe *pipe; |
1493 | struct skl_pipe_params *params; | 1540 | struct skl_pipe_params *params; |
1494 | 1541 | ||
1495 | list_for_each_entry(ppl, &skl->ppl_list, node) { | 1542 | list_for_each_entry(ppl, &skl->ppl_list, node) { |
1496 | if (ppl->pipe->ppl_id == dfw_pipe->pipe_id) | 1543 | if (ppl->pipe->ppl_id == tkn_elem->value) { |
1497 | return ppl->pipe; | 1544 | mconfig->pipe = ppl->pipe; |
1545 | return EEXIST; | ||
1546 | } | ||
1498 | } | 1547 | } |
1499 | 1548 | ||
1500 | ppl = devm_kzalloc(dev, sizeof(*ppl), GFP_KERNEL); | 1549 | ppl = devm_kzalloc(dev, sizeof(*ppl), GFP_KERNEL); |
1501 | if (!ppl) | 1550 | if (!ppl) |
1502 | return NULL; | 1551 | return -ENOMEM; |
1503 | 1552 | ||
1504 | pipe = devm_kzalloc(dev, sizeof(*pipe), GFP_KERNEL); | 1553 | pipe = devm_kzalloc(dev, sizeof(*pipe), GFP_KERNEL); |
1505 | if (!pipe) | 1554 | if (!pipe) |
1506 | return NULL; | 1555 | return -ENOMEM; |
1507 | 1556 | ||
1508 | params = devm_kzalloc(dev, sizeof(*params), GFP_KERNEL); | 1557 | params = devm_kzalloc(dev, sizeof(*params), GFP_KERNEL); |
1509 | if (!params) | 1558 | if (!params) |
1510 | return NULL; | 1559 | return -ENOMEM; |
1511 | 1560 | ||
1512 | pipe->ppl_id = dfw_pipe->pipe_id; | ||
1513 | pipe->memory_pages = dfw_pipe->memory_pages; | ||
1514 | pipe->pipe_priority = dfw_pipe->pipe_priority; | ||
1515 | pipe->conn_type = dfw_pipe->conn_type; | ||
1516 | pipe->state = SKL_PIPE_INVALID; | ||
1517 | pipe->p_params = params; | 1561 | pipe->p_params = params; |
1562 | pipe->ppl_id = tkn_elem->value; | ||
1518 | INIT_LIST_HEAD(&pipe->w_list); | 1563 | INIT_LIST_HEAD(&pipe->w_list); |
1519 | 1564 | ||
1520 | ppl->pipe = pipe; | 1565 | ppl->pipe = pipe; |
1521 | list_add(&ppl->node, &skl->ppl_list); | 1566 | list_add(&ppl->node, &skl->ppl_list); |
1522 | 1567 | ||
1523 | return ppl->pipe; | 1568 | mconfig->pipe = pipe; |
1569 | mconfig->pipe->state = SKL_PIPE_INVALID; | ||
1570 | |||
1571 | return 0; | ||
1572 | } | ||
1573 | |||
1574 | static int skl_tplg_fill_pin(struct device *dev, u32 tkn, | ||
1575 | struct skl_module_pin *m_pin, | ||
1576 | int pin_index, u32 value) | ||
1577 | { | ||
1578 | switch (tkn) { | ||
1579 | case SKL_TKN_U32_PIN_MOD_ID: | ||
1580 | m_pin[pin_index].id.module_id = value; | ||
1581 | break; | ||
1582 | |||
1583 | case SKL_TKN_U32_PIN_INST_ID: | ||
1584 | m_pin[pin_index].id.instance_id = value; | ||
1585 | break; | ||
1586 | |||
1587 | default: | ||
1588 | dev_err(dev, "%d Not a pin token\n", value); | ||
1589 | return -EINVAL; | ||
1590 | } | ||
1591 | |||
1592 | return 0; | ||
1593 | } | ||
1594 | |||
1595 | /* | ||
1596 | * Parse for pin config specific tokens to fill up the | ||
1597 | * module private data | ||
1598 | */ | ||
1599 | static int skl_tplg_fill_pins_info(struct device *dev, | ||
1600 | struct skl_module_cfg *mconfig, | ||
1601 | struct snd_soc_tplg_vendor_value_elem *tkn_elem, | ||
1602 | int dir, int pin_count) | ||
1603 | { | ||
1604 | int ret; | ||
1605 | struct skl_module_pin *m_pin; | ||
1606 | |||
1607 | switch (dir) { | ||
1608 | case SKL_DIR_IN: | ||
1609 | m_pin = mconfig->m_in_pin; | ||
1610 | break; | ||
1611 | |||
1612 | case SKL_DIR_OUT: | ||
1613 | m_pin = mconfig->m_out_pin; | ||
1614 | break; | ||
1615 | |||
1616 | default: | ||
1617 | dev_err(dev, "Invalid direction value\n"); | ||
1618 | return -EINVAL; | ||
1619 | } | ||
1620 | |||
1621 | ret = skl_tplg_fill_pin(dev, tkn_elem->token, | ||
1622 | m_pin, pin_count, tkn_elem->value); | ||
1623 | |||
1624 | if (ret < 0) | ||
1625 | return ret; | ||
1626 | |||
1627 | m_pin[pin_count].in_use = false; | ||
1628 | m_pin[pin_count].pin_state = SKL_PIN_UNBIND; | ||
1629 | |||
1630 | return 0; | ||
1631 | } | ||
1632 | |||
1633 | /* | ||
1634 | * Fill up input/output module config format based | ||
1635 | * on the direction | ||
1636 | */ | ||
1637 | static int skl_tplg_fill_fmt(struct device *dev, | ||
1638 | struct skl_module_cfg *mconfig, u32 tkn, | ||
1639 | u32 value, u32 dir, u32 pin_count) | ||
1640 | { | ||
1641 | struct skl_module_fmt *dst_fmt; | ||
1642 | |||
1643 | switch (dir) { | ||
1644 | case SKL_DIR_IN: | ||
1645 | dst_fmt = mconfig->in_fmt; | ||
1646 | dst_fmt += pin_count; | ||
1647 | break; | ||
1648 | |||
1649 | case SKL_DIR_OUT: | ||
1650 | dst_fmt = mconfig->out_fmt; | ||
1651 | dst_fmt += pin_count; | ||
1652 | break; | ||
1653 | |||
1654 | default: | ||
1655 | dev_err(dev, "Invalid direction value\n"); | ||
1656 | return -EINVAL; | ||
1657 | } | ||
1658 | |||
1659 | switch (tkn) { | ||
1660 | case SKL_TKN_U32_FMT_CH: | ||
1661 | dst_fmt->channels = value; | ||
1662 | break; | ||
1663 | |||
1664 | case SKL_TKN_U32_FMT_FREQ: | ||
1665 | dst_fmt->s_freq = value; | ||
1666 | break; | ||
1667 | |||
1668 | case SKL_TKN_U32_FMT_BIT_DEPTH: | ||
1669 | dst_fmt->bit_depth = value; | ||
1670 | break; | ||
1671 | |||
1672 | case SKL_TKN_U32_FMT_SAMPLE_SIZE: | ||
1673 | dst_fmt->valid_bit_depth = value; | ||
1674 | break; | ||
1675 | |||
1676 | case SKL_TKN_U32_FMT_CH_CONFIG: | ||
1677 | dst_fmt->ch_cfg = value; | ||
1678 | break; | ||
1679 | |||
1680 | case SKL_TKN_U32_FMT_INTERLEAVE: | ||
1681 | dst_fmt->interleaving_style = value; | ||
1682 | break; | ||
1683 | |||
1684 | case SKL_TKN_U32_FMT_SAMPLE_TYPE: | ||
1685 | dst_fmt->sample_type = value; | ||
1686 | break; | ||
1687 | |||
1688 | case SKL_TKN_U32_FMT_CH_MAP: | ||
1689 | dst_fmt->ch_map = value; | ||
1690 | break; | ||
1691 | |||
1692 | default: | ||
1693 | dev_err(dev, "Invalid token %d\n", tkn); | ||
1694 | return -EINVAL; | ||
1695 | } | ||
1696 | |||
1697 | return 0; | ||
1524 | } | 1698 | } |
1525 | 1699 | ||
1526 | static void skl_tplg_fill_fmt(struct skl_module_fmt *dst_fmt, | 1700 | static int skl_tplg_get_uuid(struct device *dev, struct skl_module_cfg *mconfig, |
1527 | struct skl_dfw_module_fmt *src_fmt, | 1701 | struct snd_soc_tplg_vendor_uuid_elem *uuid_tkn) |
1528 | int pins) | 1702 | { |
1703 | if (uuid_tkn->token == SKL_TKN_UUID) | ||
1704 | memcpy(&mconfig->guid, &uuid_tkn->uuid, 16); | ||
1705 | else { | ||
1706 | dev_err(dev, "Not an UUID token tkn %d\n", uuid_tkn->token); | ||
1707 | return -EINVAL; | ||
1708 | } | ||
1709 | |||
1710 | return 0; | ||
1711 | } | ||
1712 | |||
1713 | static void skl_tplg_fill_pin_dynamic_val( | ||
1714 | struct skl_module_pin *mpin, u32 pin_count, u32 value) | ||
1529 | { | 1715 | { |
1530 | int i; | 1716 | int i; |
1531 | 1717 | ||
1532 | for (i = 0; i < pins; i++) { | 1718 | for (i = 0; i < pin_count; i++) |
1533 | dst_fmt[i].channels = src_fmt[i].channels; | 1719 | mpin[i].is_dynamic = value; |
1534 | dst_fmt[i].s_freq = src_fmt[i].freq; | 1720 | } |
1535 | dst_fmt[i].bit_depth = src_fmt[i].bit_depth; | 1721 | |
1536 | dst_fmt[i].valid_bit_depth = src_fmt[i].valid_bit_depth; | 1722 | /* |
1537 | dst_fmt[i].ch_cfg = src_fmt[i].ch_cfg; | 1723 | * Parse tokens to fill up the module private data |
1538 | dst_fmt[i].ch_map = src_fmt[i].ch_map; | 1724 | */ |
1539 | dst_fmt[i].interleaving_style = src_fmt[i].interleaving_style; | 1725 | static int skl_tplg_get_token(struct device *dev, |
1540 | dst_fmt[i].sample_type = src_fmt[i].sample_type; | 1726 | struct snd_soc_tplg_vendor_value_elem *tkn_elem, |
1727 | struct skl *skl, struct skl_module_cfg *mconfig) | ||
1728 | { | ||
1729 | int tkn_count = 0; | ||
1730 | int ret; | ||
1731 | static int is_pipe_exists; | ||
1732 | static int pin_index, dir; | ||
1733 | |||
1734 | if (tkn_elem->token > SKL_TKN_MAX) | ||
1735 | return -EINVAL; | ||
1736 | |||
1737 | switch (tkn_elem->token) { | ||
1738 | case SKL_TKN_U8_IN_QUEUE_COUNT: | ||
1739 | mconfig->max_in_queue = tkn_elem->value; | ||
1740 | mconfig->m_in_pin = devm_kzalloc(dev, mconfig->max_in_queue * | ||
1741 | sizeof(*mconfig->m_in_pin), | ||
1742 | GFP_KERNEL); | ||
1743 | if (!mconfig->m_in_pin) | ||
1744 | return -ENOMEM; | ||
1745 | |||
1746 | break; | ||
1747 | |||
1748 | case SKL_TKN_U8_OUT_QUEUE_COUNT: | ||
1749 | mconfig->max_out_queue = tkn_elem->value; | ||
1750 | mconfig->m_out_pin = devm_kzalloc(dev, mconfig->max_out_queue * | ||
1751 | sizeof(*mconfig->m_out_pin), | ||
1752 | GFP_KERNEL); | ||
1753 | |||
1754 | if (!mconfig->m_out_pin) | ||
1755 | return -ENOMEM; | ||
1756 | |||
1757 | break; | ||
1758 | |||
1759 | case SKL_TKN_U8_DYN_IN_PIN: | ||
1760 | if (!mconfig->m_in_pin) | ||
1761 | return -ENOMEM; | ||
1762 | |||
1763 | skl_tplg_fill_pin_dynamic_val(mconfig->m_in_pin, | ||
1764 | mconfig->max_in_queue, tkn_elem->value); | ||
1765 | |||
1766 | break; | ||
1767 | |||
1768 | case SKL_TKN_U8_DYN_OUT_PIN: | ||
1769 | if (!mconfig->m_out_pin) | ||
1770 | return -ENOMEM; | ||
1771 | |||
1772 | skl_tplg_fill_pin_dynamic_val(mconfig->m_out_pin, | ||
1773 | mconfig->max_out_queue, tkn_elem->value); | ||
1774 | |||
1775 | break; | ||
1776 | |||
1777 | case SKL_TKN_U8_TIME_SLOT: | ||
1778 | mconfig->time_slot = tkn_elem->value; | ||
1779 | break; | ||
1780 | |||
1781 | case SKL_TKN_U8_CORE_ID: | ||
1782 | mconfig->core_id = tkn_elem->value; | ||
1783 | |||
1784 | case SKL_TKN_U8_MOD_TYPE: | ||
1785 | mconfig->m_type = tkn_elem->value; | ||
1786 | break; | ||
1787 | |||
1788 | case SKL_TKN_U8_DEV_TYPE: | ||
1789 | mconfig->dev_type = tkn_elem->value; | ||
1790 | break; | ||
1791 | |||
1792 | case SKL_TKN_U8_HW_CONN_TYPE: | ||
1793 | mconfig->hw_conn_type = tkn_elem->value; | ||
1794 | break; | ||
1795 | |||
1796 | case SKL_TKN_U16_MOD_INST_ID: | ||
1797 | mconfig->id.instance_id = | ||
1798 | tkn_elem->value; | ||
1799 | break; | ||
1800 | |||
1801 | case SKL_TKN_U32_MEM_PAGES: | ||
1802 | mconfig->mem_pages = tkn_elem->value; | ||
1803 | break; | ||
1804 | |||
1805 | case SKL_TKN_U32_MAX_MCPS: | ||
1806 | mconfig->mcps = tkn_elem->value; | ||
1807 | break; | ||
1808 | |||
1809 | case SKL_TKN_U32_OBS: | ||
1810 | mconfig->obs = tkn_elem->value; | ||
1811 | break; | ||
1812 | |||
1813 | case SKL_TKN_U32_IBS: | ||
1814 | mconfig->ibs = tkn_elem->value; | ||
1815 | break; | ||
1816 | |||
1817 | case SKL_TKN_U32_VBUS_ID: | ||
1818 | mconfig->vbus_id = tkn_elem->value; | ||
1819 | break; | ||
1820 | |||
1821 | case SKL_TKN_U32_PARAMS_FIXUP: | ||
1822 | mconfig->params_fixup = tkn_elem->value; | ||
1823 | break; | ||
1824 | |||
1825 | case SKL_TKN_U32_CONVERTER: | ||
1826 | mconfig->converter = tkn_elem->value; | ||
1827 | break; | ||
1828 | |||
1829 | case SKL_TKN_U32_PIPE_ID: | ||
1830 | ret = skl_tplg_add_pipe(dev, | ||
1831 | mconfig, skl, tkn_elem); | ||
1832 | |||
1833 | if (ret < 0) | ||
1834 | return is_pipe_exists; | ||
1835 | |||
1836 | if (ret == EEXIST) | ||
1837 | is_pipe_exists = 1; | ||
1838 | |||
1839 | break; | ||
1840 | |||
1841 | case SKL_TKN_U32_PIPE_CONN_TYPE: | ||
1842 | case SKL_TKN_U32_PIPE_PRIORITY: | ||
1843 | case SKL_TKN_U32_PIPE_MEM_PGS: | ||
1844 | if (is_pipe_exists) { | ||
1845 | ret = skl_tplg_fill_pipe_tkn(dev, mconfig->pipe, | ||
1846 | tkn_elem->token, tkn_elem->value); | ||
1847 | if (ret < 0) | ||
1848 | return ret; | ||
1849 | } | ||
1850 | |||
1851 | break; | ||
1852 | |||
1853 | /* | ||
1854 | * SKL_TKN_U32_DIR_PIN_COUNT token has the value for both | ||
1855 | * direction and the pin count. The first four bits represent | ||
1856 | * direction and next four the pin count. | ||
1857 | */ | ||
1858 | case SKL_TKN_U32_DIR_PIN_COUNT: | ||
1859 | dir = tkn_elem->value & SKL_IN_DIR_BIT_MASK; | ||
1860 | pin_index = (tkn_elem->value & | ||
1861 | SKL_PIN_COUNT_MASK) >> 4; | ||
1862 | |||
1863 | break; | ||
1864 | |||
1865 | case SKL_TKN_U32_FMT_CH: | ||
1866 | case SKL_TKN_U32_FMT_FREQ: | ||
1867 | case SKL_TKN_U32_FMT_BIT_DEPTH: | ||
1868 | case SKL_TKN_U32_FMT_SAMPLE_SIZE: | ||
1869 | case SKL_TKN_U32_FMT_CH_CONFIG: | ||
1870 | case SKL_TKN_U32_FMT_INTERLEAVE: | ||
1871 | case SKL_TKN_U32_FMT_SAMPLE_TYPE: | ||
1872 | case SKL_TKN_U32_FMT_CH_MAP: | ||
1873 | ret = skl_tplg_fill_fmt(dev, mconfig, tkn_elem->token, | ||
1874 | tkn_elem->value, dir, pin_index); | ||
1875 | |||
1876 | if (ret < 0) | ||
1877 | return ret; | ||
1878 | |||
1879 | break; | ||
1880 | |||
1881 | case SKL_TKN_U32_PIN_MOD_ID: | ||
1882 | case SKL_TKN_U32_PIN_INST_ID: | ||
1883 | ret = skl_tplg_fill_pins_info(dev, | ||
1884 | mconfig, tkn_elem, dir, | ||
1885 | pin_index); | ||
1886 | if (ret < 0) | ||
1887 | return ret; | ||
1888 | |||
1889 | break; | ||
1890 | |||
1891 | case SKL_TKN_U32_CAPS_SIZE: | ||
1892 | mconfig->formats_config.caps_size = | ||
1893 | tkn_elem->value; | ||
1894 | |||
1895 | break; | ||
1896 | |||
1897 | case SKL_TKN_U32_PROC_DOMAIN: | ||
1898 | mconfig->domain = | ||
1899 | tkn_elem->value; | ||
1900 | |||
1901 | break; | ||
1902 | |||
1903 | case SKL_TKN_U8_IN_PIN_TYPE: | ||
1904 | case SKL_TKN_U8_OUT_PIN_TYPE: | ||
1905 | case SKL_TKN_U8_CONN_TYPE: | ||
1906 | break; | ||
1907 | |||
1908 | default: | ||
1909 | dev_err(dev, "Token %d not handled\n", | ||
1910 | tkn_elem->token); | ||
1911 | return -EINVAL; | ||
1912 | } | ||
1913 | |||
1914 | tkn_count++; | ||
1915 | |||
1916 | return tkn_count; | ||
1917 | } | ||
1918 | |||
1919 | /* | ||
1920 | * Parse the vendor array for specific tokens to construct | ||
1921 | * module private data | ||
1922 | */ | ||
1923 | static int skl_tplg_get_tokens(struct device *dev, | ||
1924 | char *pvt_data, struct skl *skl, | ||
1925 | struct skl_module_cfg *mconfig, int block_size) | ||
1926 | { | ||
1927 | struct snd_soc_tplg_vendor_array *array; | ||
1928 | struct snd_soc_tplg_vendor_value_elem *tkn_elem; | ||
1929 | int tkn_count = 0, ret; | ||
1930 | int off = 0, tuple_size = 0; | ||
1931 | |||
1932 | if (block_size <= 0) | ||
1933 | return -EINVAL; | ||
1934 | |||
1935 | while (tuple_size < block_size) { | ||
1936 | array = (struct snd_soc_tplg_vendor_array *)(pvt_data + off); | ||
1937 | |||
1938 | off += array->size; | ||
1939 | |||
1940 | switch (array->type) { | ||
1941 | case SND_SOC_TPLG_TUPLE_TYPE_STRING: | ||
1942 | dev_warn(dev, "no string tokens expected for skl tplg\n"); | ||
1943 | continue; | ||
1944 | |||
1945 | case SND_SOC_TPLG_TUPLE_TYPE_UUID: | ||
1946 | ret = skl_tplg_get_uuid(dev, mconfig, array->uuid); | ||
1947 | if (ret < 0) | ||
1948 | return ret; | ||
1949 | |||
1950 | tuple_size += sizeof(*array->uuid); | ||
1951 | |||
1952 | continue; | ||
1953 | |||
1954 | default: | ||
1955 | tkn_elem = array->value; | ||
1956 | tkn_count = 0; | ||
1957 | break; | ||
1958 | } | ||
1959 | |||
1960 | while (tkn_count <= (array->num_elems - 1)) { | ||
1961 | ret = skl_tplg_get_token(dev, tkn_elem, | ||
1962 | skl, mconfig); | ||
1963 | |||
1964 | if (ret < 0) | ||
1965 | return ret; | ||
1966 | |||
1967 | tkn_count = tkn_count + ret; | ||
1968 | tkn_elem++; | ||
1969 | } | ||
1970 | |||
1971 | tuple_size += tkn_count * sizeof(*tkn_elem); | ||
1972 | } | ||
1973 | |||
1974 | return 0; | ||
1975 | } | ||
1976 | |||
1977 | /* | ||
1978 | * Every data block is preceded by a descriptor to read the number | ||
1979 | * of data blocks, they type of the block and it's size | ||
1980 | */ | ||
1981 | static int skl_tplg_get_desc_blocks(struct device *dev, | ||
1982 | struct snd_soc_tplg_vendor_array *array) | ||
1983 | { | ||
1984 | struct snd_soc_tplg_vendor_value_elem *tkn_elem; | ||
1985 | |||
1986 | tkn_elem = array->value; | ||
1987 | |||
1988 | switch (tkn_elem->token) { | ||
1989 | case SKL_TKN_U8_NUM_BLOCKS: | ||
1990 | case SKL_TKN_U8_BLOCK_TYPE: | ||
1991 | case SKL_TKN_U16_BLOCK_SIZE: | ||
1992 | return tkn_elem->value; | ||
1993 | |||
1994 | default: | ||
1995 | dev_err(dev, "Invalid descriptor token %d\n", tkn_elem->token); | ||
1996 | break; | ||
1997 | } | ||
1998 | |||
1999 | return -EINVAL; | ||
2000 | } | ||
2001 | |||
2002 | /* | ||
2003 | * Parse the private data for the token and corresponding value. | ||
2004 | * The private data can have multiple data blocks. So, a data block | ||
2005 | * is preceded by a descriptor for number of blocks and a descriptor | ||
2006 | * for the type and size of the suceeding data block. | ||
2007 | */ | ||
2008 | static int skl_tplg_get_pvt_data(struct snd_soc_tplg_dapm_widget *tplg_w, | ||
2009 | struct skl *skl, struct device *dev, | ||
2010 | struct skl_module_cfg *mconfig) | ||
2011 | { | ||
2012 | struct snd_soc_tplg_vendor_array *array; | ||
2013 | int num_blocks, block_size = 0, block_type, off = 0; | ||
2014 | char *data; | ||
2015 | int ret; | ||
2016 | |||
2017 | /* Read the NUM_DATA_BLOCKS descriptor */ | ||
2018 | array = (struct snd_soc_tplg_vendor_array *)tplg_w->priv.data; | ||
2019 | ret = skl_tplg_get_desc_blocks(dev, array); | ||
2020 | if (ret < 0) | ||
2021 | return ret; | ||
2022 | num_blocks = ret; | ||
2023 | |||
2024 | off += array->size; | ||
2025 | array = (struct snd_soc_tplg_vendor_array *)(tplg_w->priv.data + off); | ||
2026 | |||
2027 | /* Read the BLOCK_TYPE and BLOCK_SIZE descriptor */ | ||
2028 | while (num_blocks > 0) { | ||
2029 | ret = skl_tplg_get_desc_blocks(dev, array); | ||
2030 | |||
2031 | if (ret < 0) | ||
2032 | return ret; | ||
2033 | block_type = ret; | ||
2034 | off += array->size; | ||
2035 | |||
2036 | array = (struct snd_soc_tplg_vendor_array *) | ||
2037 | (tplg_w->priv.data + off); | ||
2038 | |||
2039 | ret = skl_tplg_get_desc_blocks(dev, array); | ||
2040 | |||
2041 | if (ret < 0) | ||
2042 | return ret; | ||
2043 | block_size = ret; | ||
2044 | off += array->size; | ||
2045 | |||
2046 | array = (struct snd_soc_tplg_vendor_array *) | ||
2047 | (tplg_w->priv.data + off); | ||
2048 | |||
2049 | data = (tplg_w->priv.data + off); | ||
2050 | |||
2051 | if (block_type == SKL_TYPE_TUPLE) { | ||
2052 | ret = skl_tplg_get_tokens(dev, data, | ||
2053 | skl, mconfig, block_size); | ||
2054 | |||
2055 | if (ret < 0) | ||
2056 | return ret; | ||
2057 | |||
2058 | --num_blocks; | ||
2059 | } else { | ||
2060 | if (mconfig->formats_config.caps_size > 0) | ||
2061 | memcpy(mconfig->formats_config.caps, data, | ||
2062 | mconfig->formats_config.caps_size); | ||
2063 | --num_blocks; | ||
2064 | } | ||
1541 | } | 2065 | } |
2066 | |||
2067 | return 0; | ||
1542 | } | 2068 | } |
1543 | 2069 | ||
1544 | static void skl_clear_pin_config(struct snd_soc_platform *platform, | 2070 | static void skl_clear_pin_config(struct snd_soc_platform *platform, |
@@ -1606,9 +2132,6 @@ static int skl_tplg_widget_load(struct snd_soc_component *cmpnt, | |||
1606 | struct skl *skl = ebus_to_skl(ebus); | 2132 | struct skl *skl = ebus_to_skl(ebus); |
1607 | struct hdac_bus *bus = ebus_to_hbus(ebus); | 2133 | struct hdac_bus *bus = ebus_to_hbus(ebus); |
1608 | struct skl_module_cfg *mconfig; | 2134 | struct skl_module_cfg *mconfig; |
1609 | struct skl_pipe *pipe; | ||
1610 | struct skl_dfw_module *dfw_config = | ||
1611 | (struct skl_dfw_module *)tplg_w->priv.data; | ||
1612 | 2135 | ||
1613 | if (!tplg_w->priv.size) | 2136 | if (!tplg_w->priv.size) |
1614 | goto bind_event; | 2137 | goto bind_event; |
@@ -1619,76 +2142,17 @@ static int skl_tplg_widget_load(struct snd_soc_component *cmpnt, | |||
1619 | return -ENOMEM; | 2142 | return -ENOMEM; |
1620 | 2143 | ||
1621 | w->priv = mconfig; | 2144 | w->priv = mconfig; |
1622 | memcpy(&mconfig->guid, &dfw_config->uuid, 16); | ||
1623 | 2145 | ||
1624 | ret = snd_skl_get_module_info(skl->skl_sst, mconfig->guid, dfw_config); | 2146 | /* |
2147 | * module binary can be loaded later, so set it to query when | ||
2148 | * module is load for a use case | ||
2149 | */ | ||
2150 | mconfig->id.module_id = -1; | ||
2151 | |||
2152 | /* Parse private data for tuples */ | ||
2153 | ret = skl_tplg_get_pvt_data(tplg_w, skl, bus->dev, mconfig); | ||
1625 | if (ret < 0) | 2154 | if (ret < 0) |
1626 | return ret; | 2155 | return ret; |
1627 | |||
1628 | mconfig->id.module_id = dfw_config->module_id; | ||
1629 | mconfig->id.instance_id = dfw_config->instance_id; | ||
1630 | mconfig->mcps = dfw_config->max_mcps; | ||
1631 | mconfig->ibs = dfw_config->ibs; | ||
1632 | mconfig->obs = dfw_config->obs; | ||
1633 | mconfig->core_id = dfw_config->core_id; | ||
1634 | mconfig->max_in_queue = dfw_config->max_in_queue; | ||
1635 | mconfig->max_out_queue = dfw_config->max_out_queue; | ||
1636 | mconfig->is_loadable = dfw_config->is_loadable; | ||
1637 | skl_tplg_fill_fmt(mconfig->in_fmt, dfw_config->in_fmt, | ||
1638 | MODULE_MAX_IN_PINS); | ||
1639 | skl_tplg_fill_fmt(mconfig->out_fmt, dfw_config->out_fmt, | ||
1640 | MODULE_MAX_OUT_PINS); | ||
1641 | |||
1642 | mconfig->params_fixup = dfw_config->params_fixup; | ||
1643 | mconfig->converter = dfw_config->converter; | ||
1644 | mconfig->m_type = dfw_config->module_type; | ||
1645 | mconfig->vbus_id = dfw_config->vbus_id; | ||
1646 | mconfig->mem_pages = dfw_config->mem_pages; | ||
1647 | |||
1648 | pipe = skl_tplg_add_pipe(bus->dev, skl, &dfw_config->pipe); | ||
1649 | if (pipe) | ||
1650 | mconfig->pipe = pipe; | ||
1651 | |||
1652 | mconfig->dev_type = dfw_config->dev_type; | ||
1653 | mconfig->hw_conn_type = dfw_config->hw_conn_type; | ||
1654 | mconfig->time_slot = dfw_config->time_slot; | ||
1655 | mconfig->formats_config.caps_size = dfw_config->caps.caps_size; | ||
1656 | |||
1657 | mconfig->m_in_pin = devm_kzalloc(bus->dev, (mconfig->max_in_queue) * | ||
1658 | sizeof(*mconfig->m_in_pin), | ||
1659 | GFP_KERNEL); | ||
1660 | if (!mconfig->m_in_pin) | ||
1661 | return -ENOMEM; | ||
1662 | |||
1663 | mconfig->m_out_pin = devm_kzalloc(bus->dev, (mconfig->max_out_queue) * | ||
1664 | sizeof(*mconfig->m_out_pin), | ||
1665 | GFP_KERNEL); | ||
1666 | if (!mconfig->m_out_pin) | ||
1667 | return -ENOMEM; | ||
1668 | |||
1669 | skl_fill_module_pin_info(dfw_config->in_pin, mconfig->m_in_pin, | ||
1670 | dfw_config->is_dynamic_in_pin, | ||
1671 | mconfig->max_in_queue); | ||
1672 | |||
1673 | skl_fill_module_pin_info(dfw_config->out_pin, mconfig->m_out_pin, | ||
1674 | dfw_config->is_dynamic_out_pin, | ||
1675 | mconfig->max_out_queue); | ||
1676 | |||
1677 | |||
1678 | if (mconfig->formats_config.caps_size == 0) | ||
1679 | goto bind_event; | ||
1680 | |||
1681 | mconfig->formats_config.caps = (u32 *)devm_kzalloc(bus->dev, | ||
1682 | mconfig->formats_config.caps_size, GFP_KERNEL); | ||
1683 | |||
1684 | if (mconfig->formats_config.caps == NULL) | ||
1685 | return -ENOMEM; | ||
1686 | |||
1687 | memcpy(mconfig->formats_config.caps, dfw_config->caps.caps, | ||
1688 | dfw_config->caps.caps_size); | ||
1689 | mconfig->formats_config.param_id = dfw_config->caps.param_id; | ||
1690 | mconfig->formats_config.set_params = dfw_config->caps.set_params; | ||
1691 | |||
1692 | bind_event: | 2156 | bind_event: |
1693 | if (tplg_w->event_type == 0) { | 2157 | if (tplg_w->event_type == 0) { |
1694 | dev_dbg(bus->dev, "ASoC: No event handler required\n"); | 2158 | dev_dbg(bus->dev, "ASoC: No event handler required\n"); |
@@ -1767,11 +2231,229 @@ static int skl_tplg_control_load(struct snd_soc_component *cmpnt, | |||
1767 | return 0; | 2231 | return 0; |
1768 | } | 2232 | } |
1769 | 2233 | ||
2234 | static int skl_tplg_fill_str_mfest_tkn(struct device *dev, | ||
2235 | struct snd_soc_tplg_vendor_string_elem *str_elem, | ||
2236 | struct skl_dfw_manifest *minfo) | ||
2237 | { | ||
2238 | int tkn_count = 0; | ||
2239 | static int ref_count; | ||
2240 | |||
2241 | switch (str_elem->token) { | ||
2242 | case SKL_TKN_STR_LIB_NAME: | ||
2243 | if (ref_count > minfo->lib_count - 1) { | ||
2244 | ref_count = 0; | ||
2245 | return -EINVAL; | ||
2246 | } | ||
2247 | |||
2248 | strncpy(minfo->lib[ref_count].name, str_elem->string, | ||
2249 | ARRAY_SIZE(minfo->lib[ref_count].name)); | ||
2250 | ref_count++; | ||
2251 | tkn_count++; | ||
2252 | break; | ||
2253 | |||
2254 | default: | ||
2255 | dev_err(dev, "Not a string token %d\n", str_elem->token); | ||
2256 | break; | ||
2257 | } | ||
2258 | |||
2259 | return tkn_count; | ||
2260 | } | ||
2261 | |||
2262 | static int skl_tplg_get_str_tkn(struct device *dev, | ||
2263 | struct snd_soc_tplg_vendor_array *array, | ||
2264 | struct skl_dfw_manifest *minfo) | ||
2265 | { | ||
2266 | int tkn_count = 0, ret; | ||
2267 | struct snd_soc_tplg_vendor_string_elem *str_elem; | ||
2268 | |||
2269 | str_elem = (struct snd_soc_tplg_vendor_string_elem *)array->value; | ||
2270 | while (tkn_count < array->num_elems) { | ||
2271 | ret = skl_tplg_fill_str_mfest_tkn(dev, str_elem, minfo); | ||
2272 | str_elem++; | ||
2273 | |||
2274 | if (ret < 0) | ||
2275 | return ret; | ||
2276 | |||
2277 | tkn_count = tkn_count + ret; | ||
2278 | } | ||
2279 | |||
2280 | return tkn_count; | ||
2281 | } | ||
2282 | |||
2283 | static int skl_tplg_get_int_tkn(struct device *dev, | ||
2284 | struct snd_soc_tplg_vendor_value_elem *tkn_elem, | ||
2285 | struct skl_dfw_manifest *minfo) | ||
2286 | { | ||
2287 | int tkn_count = 0; | ||
2288 | |||
2289 | switch (tkn_elem->token) { | ||
2290 | case SKL_TKN_U32_LIB_COUNT: | ||
2291 | minfo->lib_count = tkn_elem->value; | ||
2292 | tkn_count++; | ||
2293 | break; | ||
2294 | |||
2295 | default: | ||
2296 | dev_err(dev, "Not a manifest token %d\n", tkn_elem->token); | ||
2297 | return -EINVAL; | ||
2298 | } | ||
2299 | |||
2300 | return tkn_count; | ||
2301 | } | ||
2302 | |||
2303 | /* | ||
2304 | * Fill the manifest structure by parsing the tokens based on the | ||
2305 | * type. | ||
2306 | */ | ||
2307 | static int skl_tplg_get_manifest_tkn(struct device *dev, | ||
2308 | char *pvt_data, struct skl_dfw_manifest *minfo, | ||
2309 | int block_size) | ||
2310 | { | ||
2311 | int tkn_count = 0, ret; | ||
2312 | int off = 0, tuple_size = 0; | ||
2313 | struct snd_soc_tplg_vendor_array *array; | ||
2314 | struct snd_soc_tplg_vendor_value_elem *tkn_elem; | ||
2315 | |||
2316 | if (block_size <= 0) | ||
2317 | return -EINVAL; | ||
2318 | |||
2319 | while (tuple_size < block_size) { | ||
2320 | array = (struct snd_soc_tplg_vendor_array *)(pvt_data + off); | ||
2321 | off += array->size; | ||
2322 | switch (array->type) { | ||
2323 | case SND_SOC_TPLG_TUPLE_TYPE_STRING: | ||
2324 | ret = skl_tplg_get_str_tkn(dev, array, minfo); | ||
2325 | |||
2326 | if (ret < 0) | ||
2327 | return ret; | ||
2328 | tkn_count += ret; | ||
2329 | |||
2330 | tuple_size += tkn_count * | ||
2331 | sizeof(struct snd_soc_tplg_vendor_string_elem); | ||
2332 | continue; | ||
2333 | |||
2334 | case SND_SOC_TPLG_TUPLE_TYPE_UUID: | ||
2335 | dev_warn(dev, "no uuid tokens for skl tplf manifest\n"); | ||
2336 | continue; | ||
2337 | |||
2338 | default: | ||
2339 | tkn_elem = array->value; | ||
2340 | tkn_count = 0; | ||
2341 | break; | ||
2342 | } | ||
2343 | |||
2344 | while (tkn_count <= array->num_elems - 1) { | ||
2345 | ret = skl_tplg_get_int_tkn(dev, | ||
2346 | tkn_elem, minfo); | ||
2347 | if (ret < 0) | ||
2348 | return ret; | ||
2349 | |||
2350 | tkn_count = tkn_count + ret; | ||
2351 | tkn_elem++; | ||
2352 | tuple_size += tkn_count * | ||
2353 | sizeof(struct snd_soc_tplg_vendor_value_elem); | ||
2354 | break; | ||
2355 | } | ||
2356 | tkn_count = 0; | ||
2357 | } | ||
2358 | |||
2359 | return 0; | ||
2360 | } | ||
2361 | |||
2362 | /* | ||
2363 | * Parse manifest private data for tokens. The private data block is | ||
2364 | * preceded by descriptors for type and size of data block. | ||
2365 | */ | ||
2366 | static int skl_tplg_get_manifest_data(struct snd_soc_tplg_manifest *manifest, | ||
2367 | struct device *dev, struct skl_dfw_manifest *minfo) | ||
2368 | { | ||
2369 | struct snd_soc_tplg_vendor_array *array; | ||
2370 | int num_blocks, block_size = 0, block_type, off = 0; | ||
2371 | char *data; | ||
2372 | int ret; | ||
2373 | |||
2374 | /* Read the NUM_DATA_BLOCKS descriptor */ | ||
2375 | array = (struct snd_soc_tplg_vendor_array *)manifest->priv.data; | ||
2376 | ret = skl_tplg_get_desc_blocks(dev, array); | ||
2377 | if (ret < 0) | ||
2378 | return ret; | ||
2379 | num_blocks = ret; | ||
2380 | |||
2381 | off += array->size; | ||
2382 | array = (struct snd_soc_tplg_vendor_array *) | ||
2383 | (manifest->priv.data + off); | ||
2384 | |||
2385 | /* Read the BLOCK_TYPE and BLOCK_SIZE descriptor */ | ||
2386 | while (num_blocks > 0) { | ||
2387 | ret = skl_tplg_get_desc_blocks(dev, array); | ||
2388 | |||
2389 | if (ret < 0) | ||
2390 | return ret; | ||
2391 | block_type = ret; | ||
2392 | off += array->size; | ||
2393 | |||
2394 | array = (struct snd_soc_tplg_vendor_array *) | ||
2395 | (manifest->priv.data + off); | ||
2396 | |||
2397 | ret = skl_tplg_get_desc_blocks(dev, array); | ||
2398 | |||
2399 | if (ret < 0) | ||
2400 | return ret; | ||
2401 | block_size = ret; | ||
2402 | off += array->size; | ||
2403 | |||
2404 | array = (struct snd_soc_tplg_vendor_array *) | ||
2405 | (manifest->priv.data + off); | ||
2406 | |||
2407 | data = (manifest->priv.data + off); | ||
2408 | |||
2409 | if (block_type == SKL_TYPE_TUPLE) { | ||
2410 | ret = skl_tplg_get_manifest_tkn(dev, data, minfo, | ||
2411 | block_size); | ||
2412 | |||
2413 | if (ret < 0) | ||
2414 | return ret; | ||
2415 | |||
2416 | --num_blocks; | ||
2417 | } else { | ||
2418 | return -EINVAL; | ||
2419 | } | ||
2420 | } | ||
2421 | |||
2422 | return 0; | ||
2423 | } | ||
2424 | |||
2425 | static int skl_manifest_load(struct snd_soc_component *cmpnt, | ||
2426 | struct snd_soc_tplg_manifest *manifest) | ||
2427 | { | ||
2428 | struct skl_dfw_manifest *minfo; | ||
2429 | struct hdac_ext_bus *ebus = snd_soc_component_get_drvdata(cmpnt); | ||
2430 | struct hdac_bus *bus = ebus_to_hbus(ebus); | ||
2431 | struct skl *skl = ebus_to_skl(ebus); | ||
2432 | int ret = 0; | ||
2433 | |||
2434 | /* proceed only if we have private data defined */ | ||
2435 | if (manifest->priv.size == 0) | ||
2436 | return 0; | ||
2437 | |||
2438 | minfo = &skl->skl_sst->manifest; | ||
2439 | |||
2440 | skl_tplg_get_manifest_data(manifest, bus->dev, minfo); | ||
2441 | |||
2442 | if (minfo->lib_count > HDA_MAX_LIB) { | ||
2443 | dev_err(bus->dev, "Exceeding max Library count. Got:%d\n", | ||
2444 | minfo->lib_count); | ||
2445 | ret = -EINVAL; | ||
2446 | } | ||
2447 | |||
2448 | return ret; | ||
2449 | } | ||
2450 | |||
1770 | static struct snd_soc_tplg_ops skl_tplg_ops = { | 2451 | static struct snd_soc_tplg_ops skl_tplg_ops = { |
1771 | .widget_load = skl_tplg_widget_load, | 2452 | .widget_load = skl_tplg_widget_load, |
1772 | .control_load = skl_tplg_control_load, | 2453 | .control_load = skl_tplg_control_load, |
1773 | .bytes_ext_ops = skl_tlv_ops, | 2454 | .bytes_ext_ops = skl_tlv_ops, |
1774 | .bytes_ext_ops_count = ARRAY_SIZE(skl_tlv_ops), | 2455 | .bytes_ext_ops_count = ARRAY_SIZE(skl_tlv_ops), |
2456 | .manifest = skl_manifest_load, | ||
1775 | }; | 2457 | }; |
1776 | 2458 | ||
1777 | /* | 2459 | /* |
diff --git a/sound/soc/intel/skylake/skl-topology.h b/sound/soc/intel/skylake/skl-topology.h index 22d3ef83817d..a519360f42a6 100644 --- a/sound/soc/intel/skylake/skl-topology.h +++ b/sound/soc/intel/skylake/skl-topology.h | |||
@@ -133,7 +133,7 @@ struct skl_i2s_config_blob { | |||
133 | struct skl_dma_control { | 133 | struct skl_dma_control { |
134 | u32 node_id; | 134 | u32 node_id; |
135 | u32 config_length; | 135 | u32 config_length; |
136 | u32 config_data[1]; | 136 | u32 config_data[0]; |
137 | } __packed; | 137 | } __packed; |
138 | 138 | ||
139 | struct skl_cpr_cfg { | 139 | struct skl_cpr_cfg { |
@@ -215,9 +215,20 @@ struct skl_module_fmt { | |||
215 | 215 | ||
216 | struct skl_module_cfg; | 216 | struct skl_module_cfg; |
217 | 217 | ||
218 | struct skl_mod_inst_map { | ||
219 | u16 mod_id; | ||
220 | u16 inst_id; | ||
221 | }; | ||
222 | |||
223 | struct skl_kpb_params { | ||
224 | u32 num_modules; | ||
225 | struct skl_mod_inst_map map[0]; | ||
226 | }; | ||
227 | |||
218 | struct skl_module_inst_id { | 228 | struct skl_module_inst_id { |
219 | u32 module_id; | 229 | int module_id; |
220 | u32 instance_id; | 230 | u32 instance_id; |
231 | int pvt_id; | ||
221 | }; | 232 | }; |
222 | 233 | ||
223 | enum skl_module_pin_state { | 234 | enum skl_module_pin_state { |
diff --git a/sound/soc/intel/skylake/skl-tplg-interface.h b/sound/soc/intel/skylake/skl-tplg-interface.h index a32e5e9cc530..2f6281e056d6 100644 --- a/sound/soc/intel/skylake/skl-tplg-interface.h +++ b/sound/soc/intel/skylake/skl-tplg-interface.h | |||
@@ -80,7 +80,8 @@ enum skl_module_type { | |||
80 | SKL_MODULE_TYPE_UPDWMIX, | 80 | SKL_MODULE_TYPE_UPDWMIX, |
81 | SKL_MODULE_TYPE_SRCINT, | 81 | SKL_MODULE_TYPE_SRCINT, |
82 | SKL_MODULE_TYPE_ALGO, | 82 | SKL_MODULE_TYPE_ALGO, |
83 | SKL_MODULE_TYPE_BASE_OUTFMT | 83 | SKL_MODULE_TYPE_BASE_OUTFMT, |
84 | SKL_MODULE_TYPE_KPB, | ||
84 | }; | 85 | }; |
85 | 86 | ||
86 | enum skl_core_affinity { | 87 | enum skl_core_affinity { |
@@ -148,84 +149,34 @@ enum skl_module_param_type { | |||
148 | SKL_PARAM_BIND | 149 | SKL_PARAM_BIND |
149 | }; | 150 | }; |
150 | 151 | ||
151 | struct skl_dfw_module_pin { | 152 | struct skl_dfw_algo_data { |
152 | u16 module_id; | ||
153 | u16 instance_id; | ||
154 | } __packed; | ||
155 | |||
156 | struct skl_dfw_module_fmt { | ||
157 | u32 channels; | ||
158 | u32 freq; | ||
159 | u32 bit_depth; | ||
160 | u32 valid_bit_depth; | ||
161 | u32 ch_cfg; | ||
162 | u32 interleaving_style; | ||
163 | u32 sample_type; | ||
164 | u32 ch_map; | ||
165 | } __packed; | ||
166 | |||
167 | struct skl_dfw_module_caps { | ||
168 | u32 set_params:2; | 153 | u32 set_params:2; |
169 | u32 rsvd:30; | 154 | u32 rsvd:30; |
170 | u32 param_id; | 155 | u32 param_id; |
171 | u32 caps_size; | 156 | u32 max; |
172 | u32 caps[HDA_SST_CFG_MAX]; | 157 | char params[0]; |
173 | }; | ||
174 | |||
175 | struct skl_dfw_pipe { | ||
176 | u8 pipe_id; | ||
177 | u8 pipe_priority; | ||
178 | u16 conn_type:4; | ||
179 | u16 rsvd:4; | ||
180 | u16 memory_pages:8; | ||
181 | } __packed; | 158 | } __packed; |
182 | 159 | ||
183 | struct skl_dfw_module { | 160 | #define LIB_NAME_LENGTH 128 |
184 | u8 uuid[16]; | 161 | #define HDA_MAX_LIB 16 |
185 | 162 | ||
186 | u16 module_id; | 163 | struct lib_info { |
187 | u16 instance_id; | 164 | char name[LIB_NAME_LENGTH]; |
188 | u32 max_mcps; | ||
189 | u32 mem_pages; | ||
190 | u32 obs; | ||
191 | u32 ibs; | ||
192 | u32 vbus_id; | ||
193 | |||
194 | u32 max_in_queue:8; | ||
195 | u32 max_out_queue:8; | ||
196 | u32 time_slot:8; | ||
197 | u32 core_id:4; | ||
198 | u32 rsvd1:4; | ||
199 | |||
200 | u32 module_type:8; | ||
201 | u32 conn_type:4; | ||
202 | u32 dev_type:4; | ||
203 | u32 hw_conn_type:4; | ||
204 | u32 rsvd2:12; | ||
205 | |||
206 | u32 params_fixup:8; | ||
207 | u32 converter:8; | ||
208 | u32 input_pin_type:1; | ||
209 | u32 output_pin_type:1; | ||
210 | u32 is_dynamic_in_pin:1; | ||
211 | u32 is_dynamic_out_pin:1; | ||
212 | u32 is_loadable:1; | ||
213 | u32 rsvd3:11; | ||
214 | |||
215 | struct skl_dfw_pipe pipe; | ||
216 | struct skl_dfw_module_fmt in_fmt[MAX_IN_QUEUE]; | ||
217 | struct skl_dfw_module_fmt out_fmt[MAX_OUT_QUEUE]; | ||
218 | struct skl_dfw_module_pin in_pin[MAX_IN_QUEUE]; | ||
219 | struct skl_dfw_module_pin out_pin[MAX_OUT_QUEUE]; | ||
220 | struct skl_dfw_module_caps caps; | ||
221 | } __packed; | 165 | } __packed; |
222 | 166 | ||
223 | struct skl_dfw_algo_data { | 167 | struct skl_dfw_manifest { |
224 | u32 set_params:2; | 168 | u32 lib_count; |
225 | u32 rsvd:30; | 169 | struct lib_info lib[HDA_MAX_LIB]; |
226 | u32 param_id; | ||
227 | u32 max; | ||
228 | char params[0]; | ||
229 | } __packed; | 170 | } __packed; |
230 | 171 | ||
172 | enum skl_tkn_dir { | ||
173 | SKL_DIR_IN, | ||
174 | SKL_DIR_OUT | ||
175 | }; | ||
176 | |||
177 | enum skl_tuple_type { | ||
178 | SKL_TYPE_TUPLE, | ||
179 | SKL_TYPE_DATA | ||
180 | }; | ||
181 | |||
231 | #endif | 182 | #endif |
diff --git a/sound/soc/intel/skylake/skl.c b/sound/soc/intel/skylake/skl.c index e3e764167765..2989c164dafe 100644 --- a/sound/soc/intel/skylake/skl.c +++ b/sound/soc/intel/skylake/skl.c | |||
@@ -587,7 +587,7 @@ static int skl_first_init(struct hdac_ext_bus *ebus) | |||
587 | return -ENXIO; | 587 | return -ENXIO; |
588 | } | 588 | } |
589 | 589 | ||
590 | snd_hdac_ext_bus_parse_capabilities(ebus); | 590 | snd_hdac_bus_parse_capabilities(bus); |
591 | 591 | ||
592 | if (skl_acquire_irq(ebus, 0) < 0) | 592 | if (skl_acquire_irq(ebus, 0) < 0) |
593 | return -EBUSY; | 593 | return -EBUSY; |
@@ -684,7 +684,7 @@ static int skl_probe(struct pci_dev *pci, | |||
684 | skl_dmic_data.dmic_num = skl_get_dmic_geo(skl); | 684 | skl_dmic_data.dmic_num = skl_get_dmic_geo(skl); |
685 | 685 | ||
686 | /* check if dsp is there */ | 686 | /* check if dsp is there */ |
687 | if (ebus->ppcap) { | 687 | if (bus->ppcap) { |
688 | err = skl_machine_device_register(skl, | 688 | err = skl_machine_device_register(skl, |
689 | (void *)pci_id->driver_data); | 689 | (void *)pci_id->driver_data); |
690 | if (err < 0) | 690 | if (err < 0) |
@@ -698,7 +698,7 @@ static int skl_probe(struct pci_dev *pci, | |||
698 | skl->skl_sst->enable_miscbdcge = skl_enable_miscbdcge; | 698 | skl->skl_sst->enable_miscbdcge = skl_enable_miscbdcge; |
699 | 699 | ||
700 | } | 700 | } |
701 | if (ebus->mlcap) | 701 | if (bus->mlcap) |
702 | snd_hdac_ext_bus_get_ml_capabilities(ebus); | 702 | snd_hdac_ext_bus_get_ml_capabilities(ebus); |
703 | 703 | ||
704 | /* create device for soc dmic */ | 704 | /* create device for soc dmic */ |
diff --git a/sound/soc/intel/skylake/skl.h b/sound/soc/intel/skylake/skl.h index 9064e5b0d676..5d4fbb094c48 100644 --- a/sound/soc/intel/skylake/skl.h +++ b/sound/soc/intel/skylake/skl.h | |||
@@ -105,6 +105,7 @@ struct skl_dsp_ops { | |||
105 | int irq, const char *fw_name, | 105 | int irq, const char *fw_name, |
106 | struct skl_dsp_loader_ops loader_ops, | 106 | struct skl_dsp_loader_ops loader_ops, |
107 | struct skl_sst **skl_sst); | 107 | struct skl_sst **skl_sst); |
108 | int (*init_fw)(struct device *dev, struct skl_sst *ctx); | ||
108 | void (*cleanup)(struct device *dev, struct skl_sst *ctx); | 109 | void (*cleanup)(struct device *dev, struct skl_sst *ctx); |
109 | }; | 110 | }; |
110 | 111 | ||
@@ -123,4 +124,5 @@ int skl_free_dsp(struct skl *skl); | |||
123 | int skl_suspend_dsp(struct skl *skl); | 124 | int skl_suspend_dsp(struct skl *skl); |
124 | int skl_resume_dsp(struct skl *skl); | 125 | int skl_resume_dsp(struct skl *skl); |
125 | void skl_cleanup_resources(struct skl *skl); | 126 | void skl_cleanup_resources(struct skl *skl); |
127 | const struct skl_dsp_ops *skl_get_dsp_ops(int pci_id); | ||
126 | #endif /* __SOUND_SOC_SKL_H */ | 128 | #endif /* __SOUND_SOC_SKL_H */ |
diff --git a/sound/soc/kirkwood/kirkwood-dma.c b/sound/soc/kirkwood/kirkwood-dma.c index dbfdfe99c69d..dafd22e874e9 100644 --- a/sound/soc/kirkwood/kirkwood-dma.c +++ b/sound/soc/kirkwood/kirkwood-dma.c | |||
@@ -242,7 +242,7 @@ static snd_pcm_uframes_t kirkwood_dma_pointer(struct snd_pcm_substream | |||
242 | return count; | 242 | return count; |
243 | } | 243 | } |
244 | 244 | ||
245 | static struct snd_pcm_ops kirkwood_dma_ops = { | 245 | static const struct snd_pcm_ops kirkwood_dma_ops = { |
246 | .open = kirkwood_dma_open, | 246 | .open = kirkwood_dma_open, |
247 | .close = kirkwood_dma_close, | 247 | .close = kirkwood_dma_close, |
248 | .ioctl = snd_pcm_lib_ioctl, | 248 | .ioctl = snd_pcm_lib_ioctl, |
diff --git a/sound/soc/mediatek/common/mtk-afe-fe-dai.c b/sound/soc/mediatek/common/mtk-afe-fe-dai.c index b788791b0a35..ac231d33d8fe 100644 --- a/sound/soc/mediatek/common/mtk-afe-fe-dai.c +++ b/sound/soc/mediatek/common/mtk-afe-fe-dai.c | |||
@@ -23,7 +23,8 @@ | |||
23 | 23 | ||
24 | #define AFE_BASE_END_OFFSET 8 | 24 | #define AFE_BASE_END_OFFSET 8 |
25 | 25 | ||
26 | int mtk_regmap_update_bits(struct regmap *map, int reg, unsigned int mask, | 26 | static int mtk_regmap_update_bits(struct regmap *map, int reg, |
27 | unsigned int mask, | ||
27 | unsigned int val) | 28 | unsigned int val) |
28 | { | 29 | { |
29 | if (reg < 0) | 30 | if (reg < 0) |
@@ -31,7 +32,7 @@ int mtk_regmap_update_bits(struct regmap *map, int reg, unsigned int mask, | |||
31 | return regmap_update_bits(map, reg, mask, val); | 32 | return regmap_update_bits(map, reg, mask, val); |
32 | } | 33 | } |
33 | 34 | ||
34 | int mtk_regmap_write(struct regmap *map, int reg, unsigned int val) | 35 | static int mtk_regmap_write(struct regmap *map, int reg, unsigned int val) |
35 | { | 36 | { |
36 | if (reg < 0) | 37 | if (reg < 0) |
37 | return 0; | 38 | return 0; |
diff --git a/sound/soc/omap/mcbsp.c b/sound/soc/omap/mcbsp.c index 76ce33199bf9..06fec5699cc8 100644 --- a/sound/soc/omap/mcbsp.c +++ b/sound/soc/omap/mcbsp.c | |||
@@ -221,7 +221,8 @@ void omap_mcbsp_config(struct omap_mcbsp *mcbsp, | |||
221 | 221 | ||
222 | /* Enable TX/RX sync error interrupts by default */ | 222 | /* Enable TX/RX sync error interrupts by default */ |
223 | if (mcbsp->irq) | 223 | if (mcbsp->irq) |
224 | MCBSP_WRITE(mcbsp, IRQEN, RSYNCERREN | XSYNCERREN); | 224 | MCBSP_WRITE(mcbsp, IRQEN, RSYNCERREN | XSYNCERREN | |
225 | RUNDFLEN | ROVFLEN | XUNDFLEN | XOVFLEN); | ||
225 | } | 226 | } |
226 | 227 | ||
227 | /** | 228 | /** |
diff --git a/sound/soc/omap/omap-abe-twl6040.c b/sound/soc/omap/omap-abe-twl6040.c index f61b3b58083b..89fe95e877db 100644 --- a/sound/soc/omap/omap-abe-twl6040.c +++ b/sound/soc/omap/omap-abe-twl6040.c | |||
@@ -305,23 +305,14 @@ static int omap_abe_probe(struct platform_device *pdev) | |||
305 | 305 | ||
306 | snd_soc_card_set_drvdata(card, priv); | 306 | snd_soc_card_set_drvdata(card, priv); |
307 | 307 | ||
308 | ret = snd_soc_register_card(card); | 308 | ret = devm_snd_soc_register_card(&pdev->dev, card); |
309 | if (ret) | 309 | if (ret) |
310 | dev_err(&pdev->dev, "snd_soc_register_card() failed: %d\n", | 310 | dev_err(&pdev->dev, "devm_snd_soc_register_card() failed: %d\n", |
311 | ret); | 311 | ret); |
312 | 312 | ||
313 | return ret; | 313 | return ret; |
314 | } | 314 | } |
315 | 315 | ||
316 | static int omap_abe_remove(struct platform_device *pdev) | ||
317 | { | ||
318 | struct snd_soc_card *card = platform_get_drvdata(pdev); | ||
319 | |||
320 | snd_soc_unregister_card(card); | ||
321 | |||
322 | return 0; | ||
323 | } | ||
324 | |||
325 | static const struct of_device_id omap_abe_of_match[] = { | 316 | static const struct of_device_id omap_abe_of_match[] = { |
326 | {.compatible = "ti,abe-twl6040", }, | 317 | {.compatible = "ti,abe-twl6040", }, |
327 | { }, | 318 | { }, |
@@ -335,7 +326,6 @@ static struct platform_driver omap_abe_driver = { | |||
335 | .of_match_table = omap_abe_of_match, | 326 | .of_match_table = omap_abe_of_match, |
336 | }, | 327 | }, |
337 | .probe = omap_abe_probe, | 328 | .probe = omap_abe_probe, |
338 | .remove = omap_abe_remove, | ||
339 | }; | 329 | }; |
340 | 330 | ||
341 | static int __init omap_abe_init(void) | 331 | static int __init omap_abe_init(void) |
diff --git a/sound/soc/omap/omap-pcm.c b/sound/soc/omap/omap-pcm.c index a84f677234f0..94e9ff791f3a 100644 --- a/sound/soc/omap/omap-pcm.c +++ b/sound/soc/omap/omap-pcm.c | |||
@@ -58,7 +58,7 @@ static void omap_pcm_limit_supported_formats(void) | |||
58 | { | 58 | { |
59 | int i; | 59 | int i; |
60 | 60 | ||
61 | for (i = 0; i < SNDRV_PCM_FORMAT_LAST; i++) { | 61 | for (i = 0; i <= SNDRV_PCM_FORMAT_LAST; i++) { |
62 | switch (snd_pcm_format_physical_width(i)) { | 62 | switch (snd_pcm_format_physical_width(i)) { |
63 | case 8: | 63 | case 8: |
64 | case 16: | 64 | case 16: |
diff --git a/sound/soc/qcom/apq8016_sbc.c b/sound/soc/qcom/apq8016_sbc.c index 1289543c8fb2..07f91e918b23 100644 --- a/sound/soc/qcom/apq8016_sbc.c +++ b/sound/soc/qcom/apq8016_sbc.c | |||
@@ -85,6 +85,15 @@ static struct apq8016_sbc_data *apq8016_sbc_parse_of(struct snd_soc_card *card) | |||
85 | return ERR_PTR(ret); | 85 | return ERR_PTR(ret); |
86 | } | 86 | } |
87 | 87 | ||
88 | /* DAPM routes */ | ||
89 | if (of_property_read_bool(node, "qcom,audio-routing")) { | ||
90 | ret = snd_soc_of_parse_audio_routing(card, | ||
91 | "qcom,audio-routing"); | ||
92 | if (ret) | ||
93 | return ERR_PTR(ret); | ||
94 | } | ||
95 | |||
96 | |||
88 | /* Populate links */ | 97 | /* Populate links */ |
89 | num_links = of_get_child_count(node); | 98 | num_links = of_get_child_count(node); |
90 | 99 | ||
@@ -147,6 +156,15 @@ static struct apq8016_sbc_data *apq8016_sbc_parse_of(struct snd_soc_card *card) | |||
147 | return data; | 156 | return data; |
148 | } | 157 | } |
149 | 158 | ||
159 | static const struct snd_soc_dapm_widget apq8016_sbc_dapm_widgets[] = { | ||
160 | |||
161 | SND_SOC_DAPM_MIC("Handset Mic", NULL), | ||
162 | SND_SOC_DAPM_MIC("Headset Mic", NULL), | ||
163 | SND_SOC_DAPM_MIC("Secondary Mic", NULL), | ||
164 | SND_SOC_DAPM_MIC("Digital Mic1", NULL), | ||
165 | SND_SOC_DAPM_MIC("Digital Mic2", NULL), | ||
166 | }; | ||
167 | |||
150 | static int apq8016_sbc_platform_probe(struct platform_device *pdev) | 168 | static int apq8016_sbc_platform_probe(struct platform_device *pdev) |
151 | { | 169 | { |
152 | struct device *dev = &pdev->dev; | 170 | struct device *dev = &pdev->dev; |
@@ -159,6 +177,8 @@ static int apq8016_sbc_platform_probe(struct platform_device *pdev) | |||
159 | return -ENOMEM; | 177 | return -ENOMEM; |
160 | 178 | ||
161 | card->dev = dev; | 179 | card->dev = dev; |
180 | card->dapm_widgets = apq8016_sbc_dapm_widgets; | ||
181 | card->num_dapm_widgets = ARRAY_SIZE(apq8016_sbc_dapm_widgets); | ||
162 | data = apq8016_sbc_parse_of(card); | 182 | data = apq8016_sbc_parse_of(card); |
163 | if (IS_ERR(data)) { | 183 | if (IS_ERR(data)) { |
164 | dev_err(&pdev->dev, "Error resolving dai links: %ld\n", | 184 | dev_err(&pdev->dev, "Error resolving dai links: %ld\n", |
diff --git a/sound/soc/qcom/lpass-platform.c b/sound/soc/qcom/lpass-platform.c index db000c6987a1..e2ff538a8aa5 100644 --- a/sound/soc/qcom/lpass-platform.c +++ b/sound/soc/qcom/lpass-platform.c | |||
@@ -84,9 +84,9 @@ static int lpass_platform_pcmops_hw_params(struct snd_pcm_substream *substream, | |||
84 | struct snd_pcm_hw_params *params) | 84 | struct snd_pcm_hw_params *params) |
85 | { | 85 | { |
86 | struct snd_soc_pcm_runtime *soc_runtime = substream->private_data; | 86 | struct snd_soc_pcm_runtime *soc_runtime = substream->private_data; |
87 | struct lpass_pcm_data *pcm_data = snd_soc_pcm_get_drvdata(soc_runtime); | ||
88 | struct lpass_data *drvdata = | 87 | struct lpass_data *drvdata = |
89 | snd_soc_platform_get_drvdata(soc_runtime->platform); | 88 | snd_soc_platform_get_drvdata(soc_runtime->platform); |
89 | struct lpass_pcm_data *pcm_data = drvdata->private_data; | ||
90 | struct lpass_variant *v = drvdata->variant; | 90 | struct lpass_variant *v = drvdata->variant; |
91 | snd_pcm_format_t format = params_format(params); | 91 | snd_pcm_format_t format = params_format(params); |
92 | unsigned int channels = params_channels(params); | 92 | unsigned int channels = params_channels(params); |
@@ -177,9 +177,9 @@ static int lpass_platform_pcmops_hw_params(struct snd_pcm_substream *substream, | |||
177 | static int lpass_platform_pcmops_hw_free(struct snd_pcm_substream *substream) | 177 | static int lpass_platform_pcmops_hw_free(struct snd_pcm_substream *substream) |
178 | { | 178 | { |
179 | struct snd_soc_pcm_runtime *soc_runtime = substream->private_data; | 179 | struct snd_soc_pcm_runtime *soc_runtime = substream->private_data; |
180 | struct lpass_pcm_data *pcm_data = snd_soc_pcm_get_drvdata(soc_runtime); | ||
181 | struct lpass_data *drvdata = | 180 | struct lpass_data *drvdata = |
182 | snd_soc_platform_get_drvdata(soc_runtime->platform); | 181 | snd_soc_platform_get_drvdata(soc_runtime->platform); |
182 | struct lpass_pcm_data *pcm_data = drvdata->private_data; | ||
183 | struct lpass_variant *v = drvdata->variant; | 183 | struct lpass_variant *v = drvdata->variant; |
184 | unsigned int reg; | 184 | unsigned int reg; |
185 | int ret; | 185 | int ret; |
@@ -201,9 +201,9 @@ static int lpass_platform_pcmops_prepare(struct snd_pcm_substream *substream) | |||
201 | { | 201 | { |
202 | struct snd_pcm_runtime *runtime = substream->runtime; | 202 | struct snd_pcm_runtime *runtime = substream->runtime; |
203 | struct snd_soc_pcm_runtime *soc_runtime = substream->private_data; | 203 | struct snd_soc_pcm_runtime *soc_runtime = substream->private_data; |
204 | struct lpass_pcm_data *pcm_data = snd_soc_pcm_get_drvdata(soc_runtime); | ||
205 | struct lpass_data *drvdata = | 204 | struct lpass_data *drvdata = |
206 | snd_soc_platform_get_drvdata(soc_runtime->platform); | 205 | snd_soc_platform_get_drvdata(soc_runtime->platform); |
206 | struct lpass_pcm_data *pcm_data = drvdata->private_data; | ||
207 | struct lpass_variant *v = drvdata->variant; | 207 | struct lpass_variant *v = drvdata->variant; |
208 | int ret, ch, dir = substream->stream; | 208 | int ret, ch, dir = substream->stream; |
209 | 209 | ||
@@ -255,9 +255,9 @@ static int lpass_platform_pcmops_trigger(struct snd_pcm_substream *substream, | |||
255 | int cmd) | 255 | int cmd) |
256 | { | 256 | { |
257 | struct snd_soc_pcm_runtime *soc_runtime = substream->private_data; | 257 | struct snd_soc_pcm_runtime *soc_runtime = substream->private_data; |
258 | struct lpass_pcm_data *pcm_data = snd_soc_pcm_get_drvdata(soc_runtime); | ||
259 | struct lpass_data *drvdata = | 258 | struct lpass_data *drvdata = |
260 | snd_soc_platform_get_drvdata(soc_runtime->platform); | 259 | snd_soc_platform_get_drvdata(soc_runtime->platform); |
260 | struct lpass_pcm_data *pcm_data = drvdata->private_data; | ||
261 | struct lpass_variant *v = drvdata->variant; | 261 | struct lpass_variant *v = drvdata->variant; |
262 | int ret, ch, dir = substream->stream; | 262 | int ret, ch, dir = substream->stream; |
263 | 263 | ||
@@ -331,9 +331,9 @@ static snd_pcm_uframes_t lpass_platform_pcmops_pointer( | |||
331 | struct snd_pcm_substream *substream) | 331 | struct snd_pcm_substream *substream) |
332 | { | 332 | { |
333 | struct snd_soc_pcm_runtime *soc_runtime = substream->private_data; | 333 | struct snd_soc_pcm_runtime *soc_runtime = substream->private_data; |
334 | struct lpass_pcm_data *pcm_data = snd_soc_pcm_get_drvdata(soc_runtime); | ||
335 | struct lpass_data *drvdata = | 334 | struct lpass_data *drvdata = |
336 | snd_soc_platform_get_drvdata(soc_runtime->platform); | 335 | snd_soc_platform_get_drvdata(soc_runtime->platform); |
336 | struct lpass_pcm_data *pcm_data = drvdata->private_data; | ||
337 | struct lpass_variant *v = drvdata->variant; | 337 | struct lpass_variant *v = drvdata->variant; |
338 | unsigned int base_addr, curr_addr; | 338 | unsigned int base_addr, curr_addr; |
339 | int ret, ch, dir = substream->stream; | 339 | int ret, ch, dir = substream->stream; |
@@ -372,7 +372,7 @@ static int lpass_platform_pcmops_mmap(struct snd_pcm_substream *substream, | |||
372 | runtime->dma_bytes); | 372 | runtime->dma_bytes); |
373 | } | 373 | } |
374 | 374 | ||
375 | static struct snd_pcm_ops lpass_platform_pcm_ops = { | 375 | static const struct snd_pcm_ops lpass_platform_pcm_ops = { |
376 | .open = lpass_platform_pcmops_open, | 376 | .open = lpass_platform_pcmops_open, |
377 | .ioctl = snd_pcm_lib_ioctl, | 377 | .ioctl = snd_pcm_lib_ioctl, |
378 | .hw_params = lpass_platform_pcmops_hw_params, | 378 | .hw_params = lpass_platform_pcmops_hw_params, |
@@ -483,7 +483,7 @@ static int lpass_platform_pcm_new(struct snd_soc_pcm_runtime *soc_runtime) | |||
483 | return -ENOMEM; | 483 | return -ENOMEM; |
484 | 484 | ||
485 | data->i2s_port = cpu_dai->driver->id; | 485 | data->i2s_port = cpu_dai->driver->id; |
486 | snd_soc_pcm_set_drvdata(soc_runtime, data); | 486 | drvdata->private_data = data; |
487 | 487 | ||
488 | psubstream = pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream; | 488 | psubstream = pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream; |
489 | if (psubstream) { | 489 | if (psubstream) { |
@@ -570,8 +570,8 @@ static void lpass_platform_pcm_free(struct snd_pcm *pcm) | |||
570 | substream = pcm->streams[i].substream; | 570 | substream = pcm->streams[i].substream; |
571 | if (substream) { | 571 | if (substream) { |
572 | rt = substream->private_data; | 572 | rt = substream->private_data; |
573 | data = snd_soc_pcm_get_drvdata(rt); | ||
574 | drvdata = snd_soc_platform_get_drvdata(rt->platform); | 573 | drvdata = snd_soc_platform_get_drvdata(rt->platform); |
574 | data = drvdata->private_data; | ||
575 | 575 | ||
576 | ch = (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) | 576 | ch = (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) |
577 | ? data->rdma_ch | 577 | ? data->rdma_ch |
diff --git a/sound/soc/qcom/lpass.h b/sound/soc/qcom/lpass.h index 30714ad1e138..35b3cea8207d 100644 --- a/sound/soc/qcom/lpass.h +++ b/sound/soc/qcom/lpass.h | |||
@@ -58,6 +58,8 @@ struct lpass_data { | |||
58 | /* 8016 specific */ | 58 | /* 8016 specific */ |
59 | struct clk *pcnoc_mport_clk; | 59 | struct clk *pcnoc_mport_clk; |
60 | struct clk *pcnoc_sway_clk; | 60 | struct clk *pcnoc_sway_clk; |
61 | |||
62 | void *private_data; | ||
61 | }; | 63 | }; |
62 | 64 | ||
63 | /* Vairant data per each SOC */ | 65 | /* Vairant data per each SOC */ |
diff --git a/sound/soc/rockchip/Kconfig b/sound/soc/rockchip/Kconfig index f1e0c703e0d2..c783f9a22595 100644 --- a/sound/soc/rockchip/Kconfig +++ b/sound/soc/rockchip/Kconfig | |||
@@ -41,3 +41,15 @@ config SND_SOC_ROCKCHIP_RT5645 | |||
41 | help | 41 | help |
42 | Say Y or M here if you want to add support for SoC audio on Rockchip | 42 | Say Y or M here if you want to add support for SoC audio on Rockchip |
43 | boards using the RT5645/RT5650 codec, such as Veyron. | 43 | boards using the RT5645/RT5650 codec, such as Veyron. |
44 | |||
45 | config SND_SOC_RK3399_GRU_SOUND | ||
46 | tristate "ASoC support multiple codecs for Rockchip RK3399 GRU boards" | ||
47 | depends on SND_SOC_ROCKCHIP && I2C && GPIOLIB && CLKDEV_LOOKUP && SPI | ||
48 | select SND_SOC_ROCKCHIP_I2S | ||
49 | select SND_SOC_MAX98357A | ||
50 | select SND_SOC_RT5514 | ||
51 | select SND_SOC_DA7219 | ||
52 | select SND_SOC_RT5514_SPI | ||
53 | help | ||
54 | Say Y or M here if you want to add support multiple codecs for SoC | ||
55 | audio on Rockchip RK3399 GRU boards. | ||
diff --git a/sound/soc/rockchip/Makefile b/sound/soc/rockchip/Makefile index c0bf560125f3..84e5c7c700e7 100644 --- a/sound/soc/rockchip/Makefile +++ b/sound/soc/rockchip/Makefile | |||
@@ -7,6 +7,8 @@ obj-$(CONFIG_SND_SOC_ROCKCHIP_SPDIF) += snd-soc-rockchip-spdif.o | |||
7 | 7 | ||
8 | snd-soc-rockchip-max98090-objs := rockchip_max98090.o | 8 | snd-soc-rockchip-max98090-objs := rockchip_max98090.o |
9 | snd-soc-rockchip-rt5645-objs := rockchip_rt5645.o | 9 | snd-soc-rockchip-rt5645-objs := rockchip_rt5645.o |
10 | snd-soc-rk3399-gru-sound-objs := rk3399_gru_sound.o | ||
10 | 11 | ||
11 | obj-$(CONFIG_SND_SOC_ROCKCHIP_MAX98090) += snd-soc-rockchip-max98090.o | 12 | obj-$(CONFIG_SND_SOC_ROCKCHIP_MAX98090) += snd-soc-rockchip-max98090.o |
12 | obj-$(CONFIG_SND_SOC_ROCKCHIP_RT5645) += snd-soc-rockchip-rt5645.o | 13 | obj-$(CONFIG_SND_SOC_ROCKCHIP_RT5645) += snd-soc-rockchip-rt5645.o |
14 | obj-$(CONFIG_SND_SOC_RK3399_GRU_SOUND) += snd-soc-rk3399-gru-sound.o | ||
diff --git a/sound/soc/rockchip/rk3399_gru_sound.c b/sound/soc/rockchip/rk3399_gru_sound.c new file mode 100644 index 000000000000..9ed735a6cf49 --- /dev/null +++ b/sound/soc/rockchip/rk3399_gru_sound.c | |||
@@ -0,0 +1,397 @@ | |||
1 | /* | ||
2 | * Rockchip machine ASoC driver for boards using MAX98357A/RT5514/DA7219 | ||
3 | * | ||
4 | * Copyright (c) 2016, ROCKCHIP CORPORATION. All rights reserved. | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify it | ||
7 | * under the terms and conditions of the GNU General Public License, | ||
8 | * version 2, as published by the Free Software Foundation. | ||
9 | * | ||
10 | * This program is distributed in the hope it will be useful, but WITHOUT | ||
11 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
12 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
13 | * more details. | ||
14 | * | ||
15 | * You should have received a copy of the GNU General Public License | ||
16 | * along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
17 | */ | ||
18 | |||
19 | #include <linux/module.h> | ||
20 | #include <linux/platform_device.h> | ||
21 | #include <linux/slab.h> | ||
22 | #include <linux/gpio.h> | ||
23 | #include <linux/of_gpio.h> | ||
24 | #include <linux/delay.h> | ||
25 | #include <linux/spi/spi.h> | ||
26 | #include <linux/input.h> | ||
27 | #include <sound/core.h> | ||
28 | #include <sound/jack.h> | ||
29 | #include <sound/pcm.h> | ||
30 | #include <sound/pcm_params.h> | ||
31 | #include <sound/soc.h> | ||
32 | #include "rockchip_i2s.h" | ||
33 | #include "../codecs/da7219.h" | ||
34 | #include "../codecs/da7219-aad.h" | ||
35 | #include "../codecs/rt5514.h" | ||
36 | |||
37 | #define DRV_NAME "rk3399-gru-sound" | ||
38 | |||
39 | #define SOUND_FS 256 | ||
40 | |||
41 | unsigned int rt5514_dmic_delay; | ||
42 | |||
43 | static struct snd_soc_jack rockchip_sound_jack; | ||
44 | |||
45 | static const struct snd_soc_dapm_widget rockchip_dapm_widgets[] = { | ||
46 | SND_SOC_DAPM_HP("Headphones", NULL), | ||
47 | SND_SOC_DAPM_SPK("Speakers", NULL), | ||
48 | SND_SOC_DAPM_MIC("Headset Mic", NULL), | ||
49 | SND_SOC_DAPM_MIC("Int Mic", NULL), | ||
50 | }; | ||
51 | |||
52 | static const struct snd_soc_dapm_route rockchip_dapm_routes[] = { | ||
53 | /* Input Lines */ | ||
54 | {"MIC", NULL, "Headset Mic"}, | ||
55 | {"DMIC1L", NULL, "Int Mic"}, | ||
56 | {"DMIC1R", NULL, "Int Mic"}, | ||
57 | |||
58 | /* Output Lines */ | ||
59 | {"Headphones", NULL, "HPL"}, | ||
60 | {"Headphones", NULL, "HPR"}, | ||
61 | {"Speakers", NULL, "Speaker"}, | ||
62 | }; | ||
63 | |||
64 | static const struct snd_kcontrol_new rockchip_controls[] = { | ||
65 | SOC_DAPM_PIN_SWITCH("Headphones"), | ||
66 | SOC_DAPM_PIN_SWITCH("Speakers"), | ||
67 | SOC_DAPM_PIN_SWITCH("Headset Mic"), | ||
68 | SOC_DAPM_PIN_SWITCH("Int Mic"), | ||
69 | }; | ||
70 | |||
71 | static int rockchip_sound_max98357a_hw_params(struct snd_pcm_substream *substream, | ||
72 | struct snd_pcm_hw_params *params) | ||
73 | { | ||
74 | struct snd_soc_pcm_runtime *rtd = substream->private_data; | ||
75 | unsigned int mclk; | ||
76 | int ret; | ||
77 | |||
78 | /* max98357a supports these sample rates */ | ||
79 | switch (params_rate(params)) { | ||
80 | case 8000: | ||
81 | case 16000: | ||
82 | case 48000: | ||
83 | case 96000: | ||
84 | mclk = params_rate(params) * SOUND_FS; | ||
85 | break; | ||
86 | default: | ||
87 | dev_err(rtd->card->dev, "%s() doesn't support this sample rate: %d\n", | ||
88 | __func__, params_rate(params)); | ||
89 | return -EINVAL; | ||
90 | } | ||
91 | |||
92 | ret = snd_soc_dai_set_sysclk(rtd->cpu_dai, 0, mclk, 0); | ||
93 | if (ret) { | ||
94 | dev_err(rtd->card->dev, "%s() error setting sysclk to %u: %d\n", | ||
95 | __func__, mclk, ret); | ||
96 | return ret; | ||
97 | } | ||
98 | |||
99 | return 0; | ||
100 | } | ||
101 | |||
102 | static int rockchip_sound_rt5514_hw_params(struct snd_pcm_substream *substream, | ||
103 | struct snd_pcm_hw_params *params) | ||
104 | { | ||
105 | struct snd_soc_pcm_runtime *rtd = substream->private_data; | ||
106 | struct snd_soc_dai *cpu_dai = rtd->cpu_dai; | ||
107 | struct snd_soc_dai *codec_dai = rtd->codec_dai; | ||
108 | unsigned int mclk; | ||
109 | int ret; | ||
110 | |||
111 | mclk = params_rate(params) * SOUND_FS; | ||
112 | |||
113 | ret = snd_soc_dai_set_sysclk(cpu_dai, 0, mclk, | ||
114 | SND_SOC_CLOCK_OUT); | ||
115 | if (ret < 0) { | ||
116 | dev_err(rtd->card->dev, "Can't set cpu clock out %d\n", ret); | ||
117 | return ret; | ||
118 | } | ||
119 | |||
120 | ret = snd_soc_dai_set_sysclk(codec_dai, RT5514_SCLK_S_MCLK, | ||
121 | mclk, SND_SOC_CLOCK_IN); | ||
122 | if (ret) { | ||
123 | dev_err(rtd->card->dev, "%s() error setting sysclk to %u: %d\n", | ||
124 | __func__, params_rate(params) * 512, ret); | ||
125 | return ret; | ||
126 | } | ||
127 | |||
128 | /* Wait for DMIC stable */ | ||
129 | msleep(rt5514_dmic_delay); | ||
130 | |||
131 | return 0; | ||
132 | } | ||
133 | |||
134 | static int rockchip_sound_da7219_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 *cpu_dai = rtd->cpu_dai; | ||
139 | struct snd_soc_dai *codec_dai = rtd->codec_dai; | ||
140 | int mclk, ret; | ||
141 | |||
142 | /* in bypass mode, the mclk has to be one of the frequencies below */ | ||
143 | switch (params_rate(params)) { | ||
144 | case 8000: | ||
145 | case 16000: | ||
146 | case 24000: | ||
147 | case 32000: | ||
148 | case 48000: | ||
149 | case 64000: | ||
150 | case 96000: | ||
151 | mclk = 12288000; | ||
152 | break; | ||
153 | case 11025: | ||
154 | case 22050: | ||
155 | case 44100: | ||
156 | case 88200: | ||
157 | mclk = 11289600; | ||
158 | break; | ||
159 | default: | ||
160 | return -EINVAL; | ||
161 | } | ||
162 | |||
163 | ret = snd_soc_dai_set_sysclk(cpu_dai, 0, mclk, | ||
164 | SND_SOC_CLOCK_OUT); | ||
165 | if (ret < 0) { | ||
166 | dev_err(codec_dai->dev, "Can't set cpu clock out %d\n", ret); | ||
167 | return ret; | ||
168 | } | ||
169 | |||
170 | ret = snd_soc_dai_set_sysclk(codec_dai, 0, mclk, | ||
171 | SND_SOC_CLOCK_IN); | ||
172 | if (ret < 0) { | ||
173 | dev_err(codec_dai->dev, "Can't set codec clock in %d\n", ret); | ||
174 | return ret; | ||
175 | } | ||
176 | |||
177 | ret = snd_soc_dai_set_pll(codec_dai, 0, DA7219_SYSCLK_MCLK, 0, 0); | ||
178 | if (ret < 0) { | ||
179 | dev_err(codec_dai->dev, "Can't set pll sysclk mclk %d\n", ret); | ||
180 | return ret; | ||
181 | } | ||
182 | |||
183 | return 0; | ||
184 | } | ||
185 | |||
186 | static int rockchip_sound_da7219_init(struct snd_soc_pcm_runtime *rtd) | ||
187 | { | ||
188 | struct snd_soc_codec *codec = rtd->codec_dais[0]->codec; | ||
189 | struct snd_soc_dai *codec_dai = rtd->codec_dai; | ||
190 | int ret; | ||
191 | |||
192 | /* We need default MCLK and PLL settings for the accessory detection */ | ||
193 | ret = snd_soc_dai_set_sysclk(codec_dai, 0, 12288000, | ||
194 | SND_SOC_CLOCK_IN); | ||
195 | if (ret < 0) { | ||
196 | dev_err(codec_dai->dev, "Init can't set codec clock in %d\n", ret); | ||
197 | return ret; | ||
198 | } | ||
199 | |||
200 | ret = snd_soc_dai_set_pll(codec_dai, 0, DA7219_SYSCLK_MCLK, 0, 0); | ||
201 | if (ret < 0) { | ||
202 | dev_err(codec_dai->dev, "Init can't set pll sysclk mclk %d\n", ret); | ||
203 | return ret; | ||
204 | } | ||
205 | |||
206 | /* Enable Headset and 4 Buttons Jack detection */ | ||
207 | ret = snd_soc_card_jack_new(rtd->card, "Headset Jack", | ||
208 | SND_JACK_HEADSET | SND_JACK_LINEOUT | | ||
209 | SND_JACK_BTN_0 | SND_JACK_BTN_1 | | ||
210 | SND_JACK_BTN_2 | SND_JACK_BTN_3, | ||
211 | &rockchip_sound_jack, NULL, 0); | ||
212 | |||
213 | if (ret) { | ||
214 | dev_err(rtd->card->dev, "New Headset Jack failed! (%d)\n", ret); | ||
215 | return ret; | ||
216 | } | ||
217 | |||
218 | snd_jack_set_key(rockchip_sound_jack.jack, SND_JACK_BTN_0, KEY_MEDIA); | ||
219 | snd_jack_set_key( | ||
220 | rockchip_sound_jack.jack, SND_JACK_BTN_1, KEY_VOLUMEUP); | ||
221 | snd_jack_set_key( | ||
222 | rockchip_sound_jack.jack, SND_JACK_BTN_2, KEY_VOLUMEDOWN); | ||
223 | snd_jack_set_key( | ||
224 | rockchip_sound_jack.jack, SND_JACK_BTN_3, KEY_VOICECOMMAND); | ||
225 | |||
226 | da7219_aad_jack_det(codec, &rockchip_sound_jack); | ||
227 | |||
228 | return 0; | ||
229 | } | ||
230 | |||
231 | static struct snd_soc_ops rockchip_sound_max98357a_ops = { | ||
232 | .hw_params = rockchip_sound_max98357a_hw_params, | ||
233 | }; | ||
234 | |||
235 | static struct snd_soc_ops rockchip_sound_rt5514_ops = { | ||
236 | .hw_params = rockchip_sound_rt5514_hw_params, | ||
237 | }; | ||
238 | |||
239 | static struct snd_soc_ops rockchip_sound_da7219_ops = { | ||
240 | .hw_params = rockchip_sound_da7219_hw_params, | ||
241 | }; | ||
242 | |||
243 | enum { | ||
244 | DAILINK_MAX98357A, | ||
245 | DAILINK_RT5514, | ||
246 | DAILINK_DA7219, | ||
247 | DAILINK_RT5514_DSP, | ||
248 | }; | ||
249 | |||
250 | #define DAILINK_ENTITIES (DAILINK_DA7219 + 1) | ||
251 | |||
252 | static struct snd_soc_dai_link rockchip_dailinks[] = { | ||
253 | [DAILINK_MAX98357A] = { | ||
254 | .name = "MAX98357A", | ||
255 | .stream_name = "MAX98357A PCM", | ||
256 | .codec_dai_name = "HiFi", | ||
257 | .ops = &rockchip_sound_max98357a_ops, | ||
258 | /* set max98357a as slave */ | ||
259 | .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | | ||
260 | SND_SOC_DAIFMT_CBS_CFS, | ||
261 | }, | ||
262 | [DAILINK_RT5514] = { | ||
263 | .name = "RT5514", | ||
264 | .stream_name = "RT5514 PCM", | ||
265 | .codec_dai_name = "rt5514-aif1", | ||
266 | .ops = &rockchip_sound_rt5514_ops, | ||
267 | /* set rt5514 as slave */ | ||
268 | .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | | ||
269 | SND_SOC_DAIFMT_CBS_CFS, | ||
270 | }, | ||
271 | [DAILINK_DA7219] = { | ||
272 | .name = "DA7219", | ||
273 | .stream_name = "DA7219 PCM", | ||
274 | .codec_dai_name = "da7219-hifi", | ||
275 | .init = rockchip_sound_da7219_init, | ||
276 | .ops = &rockchip_sound_da7219_ops, | ||
277 | /* set da7219 as slave */ | ||
278 | .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | | ||
279 | SND_SOC_DAIFMT_CBS_CFS, | ||
280 | }, | ||
281 | /* RT5514 DSP for voice wakeup via spi bus */ | ||
282 | [DAILINK_RT5514_DSP] = { | ||
283 | .name = "RT5514 DSP", | ||
284 | .stream_name = "Wake on Voice", | ||
285 | .codec_name = "snd-soc-dummy", | ||
286 | .codec_dai_name = "snd-soc-dummy-dai", | ||
287 | }, | ||
288 | }; | ||
289 | |||
290 | static struct snd_soc_card rockchip_sound_card = { | ||
291 | .name = "rk3399-gru-sound", | ||
292 | .owner = THIS_MODULE, | ||
293 | .dai_link = rockchip_dailinks, | ||
294 | .num_links = ARRAY_SIZE(rockchip_dailinks), | ||
295 | .dapm_widgets = rockchip_dapm_widgets, | ||
296 | .num_dapm_widgets = ARRAY_SIZE(rockchip_dapm_widgets), | ||
297 | .dapm_routes = rockchip_dapm_routes, | ||
298 | .num_dapm_routes = ARRAY_SIZE(rockchip_dapm_routes), | ||
299 | .controls = rockchip_controls, | ||
300 | .num_controls = ARRAY_SIZE(rockchip_controls), | ||
301 | }; | ||
302 | |||
303 | static int rockchip_sound_match_stub(struct device *dev, void *data) | ||
304 | { | ||
305 | return 1; | ||
306 | } | ||
307 | |||
308 | static int rockchip_sound_probe(struct platform_device *pdev) | ||
309 | { | ||
310 | struct snd_soc_card *card = &rockchip_sound_card; | ||
311 | struct device_node *cpu_node; | ||
312 | struct device *dev; | ||
313 | struct device_driver *drv; | ||
314 | int i, ret; | ||
315 | |||
316 | cpu_node = of_parse_phandle(pdev->dev.of_node, "rockchip,cpu", 0); | ||
317 | if (!cpu_node) { | ||
318 | dev_err(&pdev->dev, "Property 'rockchip,cpu' missing or invalid\n"); | ||
319 | return -EINVAL; | ||
320 | } | ||
321 | |||
322 | for (i = 0; i < DAILINK_ENTITIES; i++) { | ||
323 | rockchip_dailinks[i].platform_of_node = cpu_node; | ||
324 | rockchip_dailinks[i].cpu_of_node = cpu_node; | ||
325 | |||
326 | rockchip_dailinks[i].codec_of_node = | ||
327 | of_parse_phandle(pdev->dev.of_node, "rockchip,codec", i); | ||
328 | if (!rockchip_dailinks[i].codec_of_node) { | ||
329 | dev_err(&pdev->dev, | ||
330 | "Property[%d] 'rockchip,codec' missing or invalid\n", i); | ||
331 | return -EINVAL; | ||
332 | } | ||
333 | } | ||
334 | |||
335 | /** | ||
336 | * To acquire the spi driver of the rt5514 and set the dai-links names | ||
337 | * for soc_bind_dai_link | ||
338 | */ | ||
339 | drv = driver_find("rt5514", &spi_bus_type); | ||
340 | if (!drv) { | ||
341 | dev_err(&pdev->dev, "Can not find the rt5514 driver at the spi bus\n"); | ||
342 | return -EINVAL; | ||
343 | } | ||
344 | |||
345 | dev = driver_find_device(drv, NULL, NULL, rockchip_sound_match_stub); | ||
346 | if (!dev) { | ||
347 | dev_err(&pdev->dev, "Can not find the rt5514 device\n"); | ||
348 | return -ENODEV; | ||
349 | } | ||
350 | |||
351 | /* Set DMIC delay */ | ||
352 | ret = device_property_read_u32(&pdev->dev, "dmic-delay", | ||
353 | &rt5514_dmic_delay); | ||
354 | if (ret) { | ||
355 | rt5514_dmic_delay = 0; | ||
356 | dev_dbg(&pdev->dev, | ||
357 | "no optional property 'dmic-delay' found, default: no delay\n"); | ||
358 | } | ||
359 | |||
360 | rockchip_dailinks[DAILINK_RT5514_DSP].cpu_name = kstrdup_const(dev_name(dev), GFP_KERNEL); | ||
361 | rockchip_dailinks[DAILINK_RT5514_DSP].cpu_dai_name = kstrdup_const(dev_name(dev), GFP_KERNEL); | ||
362 | rockchip_dailinks[DAILINK_RT5514_DSP].platform_name = kstrdup_const(dev_name(dev), GFP_KERNEL); | ||
363 | |||
364 | card->dev = &pdev->dev; | ||
365 | platform_set_drvdata(pdev, card); | ||
366 | |||
367 | ret = devm_snd_soc_register_card(&pdev->dev, card); | ||
368 | if (ret) | ||
369 | dev_err(&pdev->dev, "%s snd_soc_register_card fail %d\n", | ||
370 | __func__, ret); | ||
371 | |||
372 | return ret; | ||
373 | } | ||
374 | |||
375 | static const struct of_device_id rockchip_sound_of_match[] = { | ||
376 | { .compatible = "rockchip,rk3399-gru-sound", }, | ||
377 | {}, | ||
378 | }; | ||
379 | |||
380 | static struct platform_driver rockchip_sound_driver = { | ||
381 | .probe = rockchip_sound_probe, | ||
382 | .driver = { | ||
383 | .name = DRV_NAME, | ||
384 | .of_match_table = rockchip_sound_of_match, | ||
385 | #ifdef CONFIG_PM | ||
386 | .pm = &snd_soc_pm_ops, | ||
387 | #endif | ||
388 | }, | ||
389 | }; | ||
390 | |||
391 | module_platform_driver(rockchip_sound_driver); | ||
392 | |||
393 | MODULE_AUTHOR("Xing Zheng <zhengxing@rock-chips.com>"); | ||
394 | MODULE_DESCRIPTION("Rockchip ASoC Machine Driver"); | ||
395 | MODULE_LICENSE("GPL v2"); | ||
396 | MODULE_ALIAS("platform:" DRV_NAME); | ||
397 | MODULE_DEVICE_TABLE(of, rockchip_sound_of_match); | ||
diff --git a/sound/soc/rockchip/rockchip_i2s.c b/sound/soc/rockchip/rockchip_i2s.c index 652e8c5ea166..974915cb4c4f 100644 --- a/sound/soc/rockchip/rockchip_i2s.c +++ b/sound/soc/rockchip/rockchip_i2s.c | |||
@@ -57,6 +57,7 @@ static int i2s_runtime_suspend(struct device *dev) | |||
57 | { | 57 | { |
58 | struct rk_i2s_dev *i2s = dev_get_drvdata(dev); | 58 | struct rk_i2s_dev *i2s = dev_get_drvdata(dev); |
59 | 59 | ||
60 | regcache_cache_only(i2s->regmap, true); | ||
60 | clk_disable_unprepare(i2s->mclk); | 61 | clk_disable_unprepare(i2s->mclk); |
61 | 62 | ||
62 | return 0; | 63 | return 0; |
@@ -73,7 +74,14 @@ static int i2s_runtime_resume(struct device *dev) | |||
73 | return ret; | 74 | return ret; |
74 | } | 75 | } |
75 | 76 | ||
76 | return 0; | 77 | regcache_cache_only(i2s->regmap, false); |
78 | regcache_mark_dirty(i2s->regmap); | ||
79 | |||
80 | ret = regcache_sync(i2s->regmap); | ||
81 | if (ret) | ||
82 | clk_disable_unprepare(i2s->mclk); | ||
83 | |||
84 | return ret; | ||
77 | } | 85 | } |
78 | 86 | ||
79 | static inline struct rk_i2s_dev *to_info(struct snd_soc_dai *dai) | 87 | static inline struct rk_i2s_dev *to_info(struct snd_soc_dai *dai) |
diff --git a/sound/soc/rockchip/rockchip_spdif.c b/sound/soc/rockchip/rockchip_spdif.c index 4ca265737eda..fa8101d1e16f 100644 --- a/sound/soc/rockchip/rockchip_spdif.c +++ b/sound/soc/rockchip/rockchip_spdif.c | |||
@@ -65,6 +65,7 @@ static int __maybe_unused rk_spdif_runtime_suspend(struct device *dev) | |||
65 | { | 65 | { |
66 | struct rk_spdif_dev *spdif = dev_get_drvdata(dev); | 66 | struct rk_spdif_dev *spdif = dev_get_drvdata(dev); |
67 | 67 | ||
68 | regcache_cache_only(spdif->regmap, true); | ||
68 | clk_disable_unprepare(spdif->mclk); | 69 | clk_disable_unprepare(spdif->mclk); |
69 | clk_disable_unprepare(spdif->hclk); | 70 | clk_disable_unprepare(spdif->hclk); |
70 | 71 | ||
@@ -88,7 +89,16 @@ static int __maybe_unused rk_spdif_runtime_resume(struct device *dev) | |||
88 | return ret; | 89 | return ret; |
89 | } | 90 | } |
90 | 91 | ||
91 | return 0; | 92 | regcache_cache_only(spdif->regmap, false); |
93 | regcache_mark_dirty(spdif->regmap); | ||
94 | |||
95 | ret = regcache_sync(spdif->regmap); | ||
96 | if (ret) { | ||
97 | clk_disable_unprepare(spdif->mclk); | ||
98 | clk_disable_unprepare(spdif->hclk); | ||
99 | } | ||
100 | |||
101 | return ret; | ||
92 | } | 102 | } |
93 | 103 | ||
94 | static int rk_spdif_hw_params(struct snd_pcm_substream *substream, | 104 | static int rk_spdif_hw_params(struct snd_pcm_substream *substream, |
diff --git a/sound/soc/samsung/Kconfig b/sound/soc/samsung/Kconfig index 7b722b0094d9..f6023b46c107 100644 --- a/sound/soc/samsung/Kconfig +++ b/sound/soc/samsung/Kconfig | |||
@@ -1,12 +1,14 @@ | |||
1 | config SND_SOC_SAMSUNG | 1 | menuconfig SND_SOC_SAMSUNG |
2 | tristate "ASoC support for Samsung" | 2 | tristate "ASoC support for Samsung" |
3 | depends on (PLAT_SAMSUNG || ARCH_EXYNOS) | 3 | depends on (PLAT_SAMSUNG || ARCH_EXYNOS) |
4 | select SND_SOC_GENERIC_DMAENGINE_PCM | 4 | select SND_SOC_GENERIC_DMAENGINE_PCM |
5 | help | 5 | ---help--- |
6 | Say Y or M if you want to add support for codecs attached to | 6 | Say Y or M if you want to add support for codecs attached to |
7 | the Samsung SoCs' Audio interfaces. You will also need to | 7 | the Samsung SoCs' Audio interfaces. You will also need to |
8 | select the audio interfaces to support below. | 8 | select the audio interfaces to support below. |
9 | 9 | ||
10 | if SND_SOC_SAMSUNG | ||
11 | |||
10 | config SND_S3C24XX_I2S | 12 | config SND_S3C24XX_I2S |
11 | tristate | 13 | tristate |
12 | 14 | ||
@@ -18,22 +20,22 @@ config SND_S3C2412_SOC_I2S | |||
18 | select SND_S3C_I2SV2_SOC | 20 | select SND_S3C_I2SV2_SOC |
19 | 21 | ||
20 | config SND_SAMSUNG_PCM | 22 | config SND_SAMSUNG_PCM |
21 | tristate | 23 | tristate "Samsung PCM interface support" |
22 | 24 | ||
23 | config SND_SAMSUNG_AC97 | 25 | config SND_SAMSUNG_AC97 |
24 | tristate | 26 | tristate |
25 | select SND_SOC_AC97_BUS | 27 | select SND_SOC_AC97_BUS |
26 | 28 | ||
27 | config SND_SAMSUNG_SPDIF | 29 | config SND_SAMSUNG_SPDIF |
28 | tristate | 30 | tristate "Samsung SPDIF transmitter support" |
29 | select SND_SOC_SPDIF | 31 | select SND_SOC_SPDIF |
30 | 32 | ||
31 | config SND_SAMSUNG_I2S | 33 | config SND_SAMSUNG_I2S |
32 | tristate | 34 | tristate "Samsung I2S interface support" |
33 | 35 | ||
34 | config SND_SOC_SAMSUNG_NEO1973_WM8753 | 36 | config SND_SOC_SAMSUNG_NEO1973_WM8753 |
35 | tristate "Audio support for Openmoko Neo1973 Smartphones (GTA02)" | 37 | tristate "Audio support for Openmoko Neo1973 Smartphones (GTA02)" |
36 | depends on SND_SOC_SAMSUNG && MACH_NEO1973_GTA02 | 38 | depends on MACH_NEO1973_GTA02 |
37 | select SND_S3C24XX_I2S | 39 | select SND_S3C24XX_I2S |
38 | select SND_SOC_WM8753 | 40 | select SND_SOC_WM8753 |
39 | select SND_SOC_BT_SCO | 41 | select SND_SOC_BT_SCO |
@@ -43,7 +45,7 @@ config SND_SOC_SAMSUNG_NEO1973_WM8753 | |||
43 | 45 | ||
44 | config SND_SOC_SAMSUNG_JIVE_WM8750 | 46 | config SND_SOC_SAMSUNG_JIVE_WM8750 |
45 | tristate "SoC I2S Audio support for Jive" | 47 | tristate "SoC I2S Audio support for Jive" |
46 | depends on SND_SOC_SAMSUNG && MACH_JIVE && I2C | 48 | depends on MACH_JIVE && I2C |
47 | select SND_SOC_WM8750 | 49 | select SND_SOC_WM8750 |
48 | select SND_S3C2412_SOC_I2S | 50 | select SND_S3C2412_SOC_I2S |
49 | help | 51 | help |
@@ -51,7 +53,7 @@ config SND_SOC_SAMSUNG_JIVE_WM8750 | |||
51 | 53 | ||
52 | config SND_SOC_SAMSUNG_SMDK_WM8580 | 54 | config SND_SOC_SAMSUNG_SMDK_WM8580 |
53 | tristate "SoC I2S Audio support for WM8580 on SMDK" | 55 | tristate "SoC I2S Audio support for WM8580 on SMDK" |
54 | depends on SND_SOC_SAMSUNG && (MACH_SMDK6410 || MACH_SMDKC100 || MACH_SMDKV210 || MACH_SMDKC110) | 56 | depends on MACH_SMDK6410 || MACH_SMDKC100 || MACH_SMDKV210 || MACH_SMDKC110 |
55 | depends on I2C | 57 | depends on I2C |
56 | select SND_SOC_WM8580 | 58 | select SND_SOC_WM8580 |
57 | select SND_SAMSUNG_I2S | 59 | select SND_SAMSUNG_I2S |
@@ -60,7 +62,6 @@ config SND_SOC_SAMSUNG_SMDK_WM8580 | |||
60 | 62 | ||
61 | config SND_SOC_SAMSUNG_SMDK_WM8994 | 63 | config SND_SOC_SAMSUNG_SMDK_WM8994 |
62 | tristate "SoC I2S Audio support for WM8994 on SMDK" | 64 | tristate "SoC I2S Audio support for WM8994 on SMDK" |
63 | depends on SND_SOC_SAMSUNG | ||
64 | depends on I2C=y | 65 | depends on I2C=y |
65 | select MFD_WM8994 | 66 | select MFD_WM8994 |
66 | select SND_SOC_WM8994 | 67 | select SND_SOC_WM8994 |
@@ -70,7 +71,7 @@ config SND_SOC_SAMSUNG_SMDK_WM8994 | |||
70 | 71 | ||
71 | config SND_SOC_SAMSUNG_SMDK2443_WM9710 | 72 | config SND_SOC_SAMSUNG_SMDK2443_WM9710 |
72 | tristate "SoC AC97 Audio support for SMDK2443 - WM9710" | 73 | tristate "SoC AC97 Audio support for SMDK2443 - WM9710" |
73 | depends on SND_SOC_SAMSUNG && MACH_SMDK2443 | 74 | depends on MACH_SMDK2443 |
74 | select AC97_BUS | 75 | select AC97_BUS |
75 | select SND_SOC_AC97_CODEC | 76 | select SND_SOC_AC97_CODEC |
76 | select SND_SAMSUNG_AC97 | 77 | select SND_SAMSUNG_AC97 |
@@ -80,7 +81,7 @@ config SND_SOC_SAMSUNG_SMDK2443_WM9710 | |||
80 | 81 | ||
81 | config SND_SOC_SAMSUNG_LN2440SBC_ALC650 | 82 | config SND_SOC_SAMSUNG_LN2440SBC_ALC650 |
82 | tristate "SoC AC97 Audio support for LN2440SBC - ALC650" | 83 | tristate "SoC AC97 Audio support for LN2440SBC - ALC650" |
83 | depends on SND_SOC_SAMSUNG && ARCH_S3C24XX | 84 | depends on ARCH_S3C24XX |
84 | select AC97_BUS | 85 | select AC97_BUS |
85 | select SND_SOC_AC97_CODEC | 86 | select SND_SOC_AC97_CODEC |
86 | select SND_SAMSUNG_AC97 | 87 | select SND_SAMSUNG_AC97 |
@@ -90,7 +91,7 @@ config SND_SOC_SAMSUNG_LN2440SBC_ALC650 | |||
90 | 91 | ||
91 | config SND_SOC_SAMSUNG_S3C24XX_UDA134X | 92 | config SND_SOC_SAMSUNG_S3C24XX_UDA134X |
92 | tristate "SoC I2S Audio support UDA134X wired to a S3C24XX" | 93 | tristate "SoC I2S Audio support UDA134X wired to a S3C24XX" |
93 | depends on SND_SOC_SAMSUNG && ARCH_S3C24XX | 94 | depends on ARCH_S3C24XX |
94 | select SND_S3C24XX_I2S | 95 | select SND_S3C24XX_I2S |
95 | select SND_SOC_L3 | 96 | select SND_SOC_L3 |
96 | select SND_SOC_UDA134X | 97 | select SND_SOC_UDA134X |
@@ -102,21 +103,21 @@ config SND_SOC_SAMSUNG_SIMTEC | |||
102 | 103 | ||
103 | config SND_SOC_SAMSUNG_SIMTEC_TLV320AIC23 | 104 | config SND_SOC_SAMSUNG_SIMTEC_TLV320AIC23 |
104 | tristate "SoC I2S Audio support for TLV320AIC23 on Simtec boards" | 105 | tristate "SoC I2S Audio support for TLV320AIC23 on Simtec boards" |
105 | depends on SND_SOC_SAMSUNG && ARCH_S3C24XX && I2C | 106 | depends on ARCH_S3C24XX && I2C |
106 | select SND_S3C24XX_I2S | 107 | select SND_S3C24XX_I2S |
107 | select SND_SOC_TLV320AIC23_I2C | 108 | select SND_SOC_TLV320AIC23_I2C |
108 | select SND_SOC_SAMSUNG_SIMTEC | 109 | select SND_SOC_SAMSUNG_SIMTEC |
109 | 110 | ||
110 | config SND_SOC_SAMSUNG_SIMTEC_HERMES | 111 | config SND_SOC_SAMSUNG_SIMTEC_HERMES |
111 | tristate "SoC I2S Audio support for Simtec Hermes board" | 112 | tristate "SoC I2S Audio support for Simtec Hermes board" |
112 | depends on SND_SOC_SAMSUNG && ARCH_S3C24XX && I2C | 113 | depends on ARCH_S3C24XX && I2C |
113 | select SND_S3C24XX_I2S | 114 | select SND_S3C24XX_I2S |
114 | select SND_SOC_TLV320AIC3X | 115 | select SND_SOC_TLV320AIC3X |
115 | select SND_SOC_SAMSUNG_SIMTEC | 116 | select SND_SOC_SAMSUNG_SIMTEC |
116 | 117 | ||
117 | config SND_SOC_SAMSUNG_H1940_UDA1380 | 118 | config SND_SOC_SAMSUNG_H1940_UDA1380 |
118 | tristate "Audio support for the HP iPAQ H1940" | 119 | tristate "Audio support for the HP iPAQ H1940" |
119 | depends on SND_SOC_SAMSUNG && ARCH_H1940 && I2C | 120 | depends on ARCH_H1940 && I2C |
120 | select SND_S3C24XX_I2S | 121 | select SND_S3C24XX_I2S |
121 | select SND_SOC_UDA1380 | 122 | select SND_SOC_UDA1380 |
122 | help | 123 | help |
@@ -124,7 +125,7 @@ config SND_SOC_SAMSUNG_H1940_UDA1380 | |||
124 | 125 | ||
125 | config SND_SOC_SAMSUNG_RX1950_UDA1380 | 126 | config SND_SOC_SAMSUNG_RX1950_UDA1380 |
126 | tristate "Audio support for the HP iPAQ RX1950" | 127 | tristate "Audio support for the HP iPAQ RX1950" |
127 | depends on SND_SOC_SAMSUNG && MACH_RX1950 && I2C | 128 | depends on MACH_RX1950 && I2C |
128 | select SND_S3C24XX_I2S | 129 | select SND_S3C24XX_I2S |
129 | select SND_SOC_UDA1380 | 130 | select SND_SOC_UDA1380 |
130 | help | 131 | help |
@@ -132,7 +133,7 @@ config SND_SOC_SAMSUNG_RX1950_UDA1380 | |||
132 | 133 | ||
133 | config SND_SOC_SAMSUNG_SMDK_WM9713 | 134 | config SND_SOC_SAMSUNG_SMDK_WM9713 |
134 | tristate "SoC AC97 Audio support for SMDK with WM9713" | 135 | tristate "SoC AC97 Audio support for SMDK with WM9713" |
135 | depends on SND_SOC_SAMSUNG && (MACH_SMDK6410 || MACH_SMDKC100 || MACH_SMDKV210 || MACH_SMDKC110) | 136 | depends on MACH_SMDK6410 || MACH_SMDKC100 || MACH_SMDKV210 || MACH_SMDKC110 |
136 | select SND_SOC_WM9713 | 137 | select SND_SOC_WM9713 |
137 | select SND_SAMSUNG_AC97 | 138 | select SND_SAMSUNG_AC97 |
138 | help | 139 | help |
@@ -140,20 +141,19 @@ config SND_SOC_SAMSUNG_SMDK_WM9713 | |||
140 | 141 | ||
141 | config SND_SOC_SMARTQ | 142 | config SND_SOC_SMARTQ |
142 | tristate "SoC I2S Audio support for SmartQ board" | 143 | tristate "SoC I2S Audio support for SmartQ board" |
143 | depends on SND_SOC_SAMSUNG && MACH_SMARTQ && I2C | 144 | depends on MACH_SMARTQ && I2C |
144 | select SND_SAMSUNG_I2S | 145 | select SND_SAMSUNG_I2S |
145 | select SND_SOC_WM8750 | 146 | select SND_SOC_WM8750 |
146 | 147 | ||
147 | config SND_SOC_SAMSUNG_SMDK_SPDIF | 148 | config SND_SOC_SAMSUNG_SMDK_SPDIF |
148 | tristate "SoC S/PDIF Audio support for SMDK" | 149 | tristate "SoC S/PDIF Audio support for SMDK" |
149 | depends on SND_SOC_SAMSUNG | ||
150 | select SND_SAMSUNG_SPDIF | 150 | select SND_SAMSUNG_SPDIF |
151 | help | 151 | help |
152 | Say Y if you want to add support for SoC S/PDIF audio on the SMDK. | 152 | Say Y if you want to add support for SoC S/PDIF audio on the SMDK. |
153 | 153 | ||
154 | config SND_SOC_SMDK_WM8580_PCM | 154 | config SND_SOC_SMDK_WM8580_PCM |
155 | tristate "SoC PCM Audio support for WM8580 on SMDK" | 155 | tristate "SoC PCM Audio support for WM8580 on SMDK" |
156 | depends on SND_SOC_SAMSUNG && (MACH_SMDKV210 || MACH_SMDKC110) | 156 | depends on MACH_SMDKV210 || MACH_SMDKC110 |
157 | depends on I2C | 157 | depends on I2C |
158 | select SND_SOC_WM8580 | 158 | select SND_SOC_WM8580 |
159 | select SND_SAMSUNG_PCM | 159 | select SND_SAMSUNG_PCM |
@@ -162,7 +162,6 @@ config SND_SOC_SMDK_WM8580_PCM | |||
162 | 162 | ||
163 | config SND_SOC_SMDK_WM8994_PCM | 163 | config SND_SOC_SMDK_WM8994_PCM |
164 | tristate "SoC PCM Audio support for WM8994 on SMDK" | 164 | tristate "SoC PCM Audio support for WM8994 on SMDK" |
165 | depends on SND_SOC_SAMSUNG | ||
166 | depends on I2C=y | 165 | depends on I2C=y |
167 | select MFD_WM8994 | 166 | select MFD_WM8994 |
168 | select SND_SOC_WM8994 | 167 | select SND_SOC_WM8994 |
@@ -172,7 +171,7 @@ config SND_SOC_SMDK_WM8994_PCM | |||
172 | 171 | ||
173 | config SND_SOC_SPEYSIDE | 172 | config SND_SOC_SPEYSIDE |
174 | tristate "Audio support for Wolfson Speyside" | 173 | tristate "Audio support for Wolfson Speyside" |
175 | depends on SND_SOC_SAMSUNG && I2C && SPI_MASTER | 174 | depends on I2C && SPI_MASTER |
176 | depends on MACH_WLF_CRAGG_6410 || COMPILE_TEST | 175 | depends on MACH_WLF_CRAGG_6410 || COMPILE_TEST |
177 | select SND_SAMSUNG_I2S | 176 | select SND_SAMSUNG_I2S |
178 | select SND_SOC_WM8996 | 177 | select SND_SOC_WM8996 |
@@ -182,14 +181,14 @@ config SND_SOC_SPEYSIDE | |||
182 | 181 | ||
183 | config SND_SOC_TOBERMORY | 182 | config SND_SOC_TOBERMORY |
184 | tristate "Audio support for Wolfson Tobermory" | 183 | tristate "Audio support for Wolfson Tobermory" |
185 | depends on SND_SOC_SAMSUNG && INPUT && I2C | 184 | depends on INPUT && I2C |
186 | depends on MACH_WLF_CRAGG_6410 || COMPILE_TEST | 185 | depends on MACH_WLF_CRAGG_6410 || COMPILE_TEST |
187 | select SND_SAMSUNG_I2S | 186 | select SND_SAMSUNG_I2S |
188 | select SND_SOC_WM8962 | 187 | select SND_SOC_WM8962 |
189 | 188 | ||
190 | config SND_SOC_BELLS | 189 | config SND_SOC_BELLS |
191 | tristate "Audio support for Wolfson Bells" | 190 | tristate "Audio support for Wolfson Bells" |
192 | depends on SND_SOC_SAMSUNG && MFD_ARIZONA && I2C && SPI_MASTER | 191 | depends on MFD_ARIZONA && I2C && SPI_MASTER |
193 | depends on MACH_WLF_CRAGG_6410 || COMPILE_TEST | 192 | depends on MACH_WLF_CRAGG_6410 || COMPILE_TEST |
194 | select SND_SAMSUNG_I2S | 193 | select SND_SAMSUNG_I2S |
195 | select SND_SOC_WM5102 | 194 | select SND_SOC_WM5102 |
@@ -200,7 +199,7 @@ config SND_SOC_BELLS | |||
200 | 199 | ||
201 | config SND_SOC_LOWLAND | 200 | config SND_SOC_LOWLAND |
202 | tristate "Audio support for Wolfson Lowland" | 201 | tristate "Audio support for Wolfson Lowland" |
203 | depends on SND_SOC_SAMSUNG && I2C | 202 | depends on I2C |
204 | depends on MACH_WLF_CRAGG_6410 || COMPILE_TEST | 203 | depends on MACH_WLF_CRAGG_6410 || COMPILE_TEST |
205 | select SND_SAMSUNG_I2S | 204 | select SND_SAMSUNG_I2S |
206 | select SND_SOC_WM5100 | 205 | select SND_SOC_WM5100 |
@@ -208,7 +207,7 @@ config SND_SOC_LOWLAND | |||
208 | 207 | ||
209 | config SND_SOC_LITTLEMILL | 208 | config SND_SOC_LITTLEMILL |
210 | tristate "Audio support for Wolfson Littlemill" | 209 | tristate "Audio support for Wolfson Littlemill" |
211 | depends on SND_SOC_SAMSUNG && I2C | 210 | depends on I2C |
212 | depends on MACH_WLF_CRAGG_6410 || COMPILE_TEST | 211 | depends on MACH_WLF_CRAGG_6410 || COMPILE_TEST |
213 | select SND_SAMSUNG_I2S | 212 | select SND_SAMSUNG_I2S |
214 | select MFD_WM8994 | 213 | select MFD_WM8994 |
@@ -216,7 +215,7 @@ config SND_SOC_LITTLEMILL | |||
216 | 215 | ||
217 | config SND_SOC_SNOW | 216 | config SND_SOC_SNOW |
218 | tristate "Audio support for Google Snow boards" | 217 | tristate "Audio support for Google Snow boards" |
219 | depends on SND_SOC_SAMSUNG && I2C | 218 | depends on I2C |
220 | select SND_SOC_MAX98090 | 219 | select SND_SOC_MAX98090 |
221 | select SND_SOC_MAX98095 | 220 | select SND_SOC_MAX98095 |
222 | select SND_SAMSUNG_I2S | 221 | select SND_SAMSUNG_I2S |
@@ -226,6 +225,8 @@ config SND_SOC_SNOW | |||
226 | 225 | ||
227 | config SND_SOC_ARNDALE_RT5631_ALC5631 | 226 | config SND_SOC_ARNDALE_RT5631_ALC5631 |
228 | tristate "Audio support for RT5631(ALC5631) on Arndale Board" | 227 | tristate "Audio support for RT5631(ALC5631) on Arndale Board" |
229 | depends on SND_SOC_SAMSUNG && I2C | 228 | depends on I2C |
230 | select SND_SAMSUNG_I2S | 229 | select SND_SAMSUNG_I2S |
231 | select SND_SOC_RT5631 | 230 | select SND_SOC_RT5631 |
231 | |||
232 | endif #SND_SOC_SAMSUNG | ||
diff --git a/sound/soc/samsung/ac97.c b/sound/soc/samsung/ac97.c index 547d31032088..97d6700b1009 100644 --- a/sound/soc/samsung/ac97.c +++ b/sound/soc/samsung/ac97.c | |||
@@ -38,16 +38,16 @@ struct s3c_ac97_info { | |||
38 | }; | 38 | }; |
39 | static struct s3c_ac97_info s3c_ac97; | 39 | static struct s3c_ac97_info s3c_ac97; |
40 | 40 | ||
41 | static struct s3c_dma_params s3c_ac97_pcm_out = { | 41 | static struct snd_dmaengine_dai_dma_data s3c_ac97_pcm_out = { |
42 | .dma_size = 4, | 42 | .addr_width = 4, |
43 | }; | 43 | }; |
44 | 44 | ||
45 | static struct s3c_dma_params s3c_ac97_pcm_in = { | 45 | static struct snd_dmaengine_dai_dma_data s3c_ac97_pcm_in = { |
46 | .dma_size = 4, | 46 | .addr_width = 4, |
47 | }; | 47 | }; |
48 | 48 | ||
49 | static struct s3c_dma_params s3c_ac97_mic_in = { | 49 | static struct snd_dmaengine_dai_dma_data s3c_ac97_mic_in = { |
50 | .dma_size = 4, | 50 | .addr_width = 4, |
51 | }; | 51 | }; |
52 | 52 | ||
53 | static void s3c_ac97_activate(struct snd_ac97 *ac97) | 53 | static void s3c_ac97_activate(struct snd_ac97 *ac97) |
@@ -74,7 +74,7 @@ static void s3c_ac97_activate(struct snd_ac97 *ac97) | |||
74 | writel(ac_glbctrl, s3c_ac97.regs + S3C_AC97_GLBCTRL); | 74 | writel(ac_glbctrl, s3c_ac97.regs + S3C_AC97_GLBCTRL); |
75 | 75 | ||
76 | if (!wait_for_completion_timeout(&s3c_ac97.done, HZ)) | 76 | if (!wait_for_completion_timeout(&s3c_ac97.done, HZ)) |
77 | pr_err("AC97: Unable to activate!"); | 77 | pr_err("AC97: Unable to activate!\n"); |
78 | } | 78 | } |
79 | 79 | ||
80 | static unsigned short s3c_ac97_read(struct snd_ac97 *ac97, | 80 | static unsigned short s3c_ac97_read(struct snd_ac97 *ac97, |
@@ -100,7 +100,7 @@ static unsigned short s3c_ac97_read(struct snd_ac97 *ac97, | |||
100 | writel(ac_glbctrl, s3c_ac97.regs + S3C_AC97_GLBCTRL); | 100 | writel(ac_glbctrl, s3c_ac97.regs + S3C_AC97_GLBCTRL); |
101 | 101 | ||
102 | if (!wait_for_completion_timeout(&s3c_ac97.done, HZ)) | 102 | if (!wait_for_completion_timeout(&s3c_ac97.done, HZ)) |
103 | pr_err("AC97: Unable to read!"); | 103 | pr_err("AC97: Unable to read!\n"); |
104 | 104 | ||
105 | stat = readl(s3c_ac97.regs + S3C_AC97_STAT); | 105 | stat = readl(s3c_ac97.regs + S3C_AC97_STAT); |
106 | addr = (stat >> 16) & 0x7f; | 106 | addr = (stat >> 16) & 0x7f; |
@@ -137,7 +137,7 @@ static void s3c_ac97_write(struct snd_ac97 *ac97, unsigned short reg, | |||
137 | writel(ac_glbctrl, s3c_ac97.regs + S3C_AC97_GLBCTRL); | 137 | writel(ac_glbctrl, s3c_ac97.regs + S3C_AC97_GLBCTRL); |
138 | 138 | ||
139 | if (!wait_for_completion_timeout(&s3c_ac97.done, HZ)) | 139 | if (!wait_for_completion_timeout(&s3c_ac97.done, HZ)) |
140 | pr_err("AC97: Unable to write!"); | 140 | pr_err("AC97: Unable to write!\n"); |
141 | 141 | ||
142 | ac_codec_cmd = readl(s3c_ac97.regs + S3C_AC97_CODEC_CMD); | 142 | ac_codec_cmd = readl(s3c_ac97.regs + S3C_AC97_CODEC_CMD); |
143 | ac_codec_cmd |= S3C_AC97_CODEC_CMD_READ; | 143 | ac_codec_cmd |= S3C_AC97_CODEC_CMD_READ; |
@@ -273,14 +273,14 @@ static const struct snd_soc_dai_ops s3c_ac97_mic_dai_ops = { | |||
273 | 273 | ||
274 | static int s3c_ac97_dai_probe(struct snd_soc_dai *dai) | 274 | static int s3c_ac97_dai_probe(struct snd_soc_dai *dai) |
275 | { | 275 | { |
276 | samsung_asoc_init_dma_data(dai, &s3c_ac97_pcm_out, &s3c_ac97_pcm_in); | 276 | snd_soc_dai_init_dma_data(dai, &s3c_ac97_pcm_out, &s3c_ac97_pcm_in); |
277 | 277 | ||
278 | return 0; | 278 | return 0; |
279 | } | 279 | } |
280 | 280 | ||
281 | static int s3c_ac97_mic_dai_probe(struct snd_soc_dai *dai) | 281 | static int s3c_ac97_mic_dai_probe(struct snd_soc_dai *dai) |
282 | { | 282 | { |
283 | samsung_asoc_init_dma_data(dai, NULL, &s3c_ac97_mic_in); | 283 | snd_soc_dai_init_dma_data(dai, NULL, &s3c_ac97_mic_in); |
284 | 284 | ||
285 | return 0; | 285 | return 0; |
286 | } | 286 | } |
@@ -346,12 +346,12 @@ static int s3c_ac97_probe(struct platform_device *pdev) | |||
346 | if (IS_ERR(s3c_ac97.regs)) | 346 | if (IS_ERR(s3c_ac97.regs)) |
347 | return PTR_ERR(s3c_ac97.regs); | 347 | return PTR_ERR(s3c_ac97.regs); |
348 | 348 | ||
349 | s3c_ac97_pcm_out.slave = ac97_pdata->dma_playback; | 349 | s3c_ac97_pcm_out.filter_data = ac97_pdata->dma_playback; |
350 | s3c_ac97_pcm_out.dma_addr = mem_res->start + S3C_AC97_PCM_DATA; | 350 | s3c_ac97_pcm_out.addr = mem_res->start + S3C_AC97_PCM_DATA; |
351 | s3c_ac97_pcm_in.slave = ac97_pdata->dma_capture; | 351 | s3c_ac97_pcm_in.filter_data = ac97_pdata->dma_capture; |
352 | s3c_ac97_pcm_in.dma_addr = mem_res->start + S3C_AC97_PCM_DATA; | 352 | s3c_ac97_pcm_in.addr = mem_res->start + S3C_AC97_PCM_DATA; |
353 | s3c_ac97_mic_in.slave = ac97_pdata->dma_capture_mic; | 353 | s3c_ac97_mic_in.filter_data = ac97_pdata->dma_capture_mic; |
354 | s3c_ac97_mic_in.dma_addr = mem_res->start + S3C_AC97_MIC_DATA; | 354 | s3c_ac97_mic_in.addr = mem_res->start + S3C_AC97_MIC_DATA; |
355 | 355 | ||
356 | init_completion(&s3c_ac97.done); | 356 | init_completion(&s3c_ac97.done); |
357 | mutex_init(&s3c_ac97.lock); | 357 | mutex_init(&s3c_ac97.lock); |
diff --git a/sound/soc/samsung/dma.h b/sound/soc/samsung/dma.h index 3830f297e0b6..7ae580d677c8 100644 --- a/sound/soc/samsung/dma.h +++ b/sound/soc/samsung/dma.h | |||
@@ -1,6 +1,4 @@ | |||
1 | /* | 1 | /* |
2 | * dma.h -- | ||
3 | * | ||
4 | * This program is free software; you can redistribute it and/or modify it | 2 | * This program is free software; you can redistribute it and/or modify it |
5 | * under the terms of the GNU General Public License as published by the | 3 | * under the terms of the GNU General Public License as published by the |
6 | * Free Software Foundation; either version 2 of the License, or (at your | 4 | * Free Software Foundation; either version 2 of the License, or (at your |
@@ -9,27 +7,15 @@ | |||
9 | * ALSA PCM interface for the Samsung SoC | 7 | * ALSA PCM interface for the Samsung SoC |
10 | */ | 8 | */ |
11 | 9 | ||
12 | #ifndef _S3C_AUDIO_H | 10 | #ifndef _SAMSUNG_DMA_H |
13 | #define _S3C_AUDIO_H | 11 | #define _SAMSUNG_DMA_H |
14 | 12 | ||
15 | #include <sound/dmaengine_pcm.h> | 13 | #include <sound/dmaengine_pcm.h> |
16 | #include <linux/dmaengine.h> | ||
17 | |||
18 | struct s3c_dma_params { | ||
19 | void *slave; /* Channel ID */ | ||
20 | dma_addr_t dma_addr; | ||
21 | int dma_size; /* Size of the DMA transfer */ | ||
22 | char *ch_name; | ||
23 | struct snd_dmaengine_dai_dma_data dma_data; | ||
24 | }; | ||
25 | 14 | ||
26 | void samsung_asoc_init_dma_data(struct snd_soc_dai *dai, | ||
27 | struct s3c_dma_params *playback, | ||
28 | struct s3c_dma_params *capture); | ||
29 | /* | 15 | /* |
30 | * @tx, @rx arguments can be NULL if the DMA channel names are "tx", "rx", | 16 | * @tx, @rx arguments can be NULL if the DMA channel names are "tx", "rx", |
31 | * otherwise actual DMA channel names must be passed to this function. | 17 | * otherwise actual DMA channel names must be passed to this function. |
32 | */ | 18 | */ |
33 | int samsung_asoc_dma_platform_register(struct device *dev, dma_filter_fn filter, | 19 | int samsung_asoc_dma_platform_register(struct device *dev, dma_filter_fn filter, |
34 | const char *tx, const char *rx); | 20 | const char *tx, const char *rx); |
35 | #endif | 21 | #endif /* _SAMSUNG_DMA_H */ |
diff --git a/sound/soc/samsung/dmaengine.c b/sound/soc/samsung/dmaengine.c index 2c87f380bfc4..9104c98deeb7 100644 --- a/sound/soc/samsung/dmaengine.c +++ b/sound/soc/samsung/dmaengine.c | |||
@@ -16,49 +16,18 @@ | |||
16 | */ | 16 | */ |
17 | 17 | ||
18 | #include <linux/module.h> | 18 | #include <linux/module.h> |
19 | #include <linux/amba/pl08x.h> | ||
20 | #include <linux/platform_data/dma-s3c24xx.h> | ||
21 | |||
22 | #include <sound/core.h> | 19 | #include <sound/core.h> |
23 | #include <sound/pcm.h> | 20 | #include <sound/pcm.h> |
24 | #include <sound/pcm_params.h> | 21 | #include <sound/pcm_params.h> |
25 | #include <sound/dmaengine_pcm.h> | 22 | #include <sound/dmaengine_pcm.h> |
26 | #include <sound/soc.h> | 23 | #include <sound/soc.h> |
27 | #include <sound/soc-dai.h> | ||
28 | 24 | ||
29 | #include "dma.h" | 25 | #include "dma.h" |
30 | 26 | ||
31 | void samsung_asoc_init_dma_data(struct snd_soc_dai *dai, | ||
32 | struct s3c_dma_params *playback, | ||
33 | struct s3c_dma_params *capture) | ||
34 | { | ||
35 | struct snd_dmaengine_dai_dma_data *playback_data = NULL; | ||
36 | struct snd_dmaengine_dai_dma_data *capture_data = NULL; | ||
37 | |||
38 | if (playback) { | ||
39 | playback_data = &playback->dma_data; | ||
40 | playback_data->filter_data = playback->slave; | ||
41 | playback_data->chan_name = playback->ch_name; | ||
42 | playback_data->addr = playback->dma_addr; | ||
43 | playback_data->addr_width = playback->dma_size; | ||
44 | } | ||
45 | if (capture) { | ||
46 | capture_data = &capture->dma_data; | ||
47 | capture_data->filter_data = capture->slave; | ||
48 | capture_data->chan_name = capture->ch_name; | ||
49 | capture_data->addr = capture->dma_addr; | ||
50 | capture_data->addr_width = capture->dma_size; | ||
51 | } | ||
52 | |||
53 | snd_soc_dai_init_dma_data(dai, playback_data, capture_data); | ||
54 | } | ||
55 | EXPORT_SYMBOL_GPL(samsung_asoc_init_dma_data); | ||
56 | |||
57 | int samsung_asoc_dma_platform_register(struct device *dev, dma_filter_fn filter, | 27 | int samsung_asoc_dma_platform_register(struct device *dev, dma_filter_fn filter, |
58 | const char *tx, const char *rx) | 28 | const char *tx, const char *rx) |
59 | { | 29 | { |
60 | unsigned int flags = SND_DMAENGINE_PCM_FLAG_COMPAT; | 30 | unsigned int flags = SND_DMAENGINE_PCM_FLAG_COMPAT; |
61 | |||
62 | struct snd_dmaengine_pcm_config *pcm_conf; | 31 | struct snd_dmaengine_pcm_config *pcm_conf; |
63 | 32 | ||
64 | pcm_conf = devm_kzalloc(dev, sizeof(*pcm_conf), GFP_KERNEL); | 33 | pcm_conf = devm_kzalloc(dev, sizeof(*pcm_conf), GFP_KERNEL); |
diff --git a/sound/soc/samsung/i2s.c b/sound/soc/samsung/i2s.c index 50635ee8ff20..7e32cf4581f8 100644 --- a/sound/soc/samsung/i2s.c +++ b/sound/soc/samsung/i2s.c | |||
@@ -87,9 +87,9 @@ struct i2s_dai { | |||
87 | /* Driver for this DAI */ | 87 | /* Driver for this DAI */ |
88 | struct snd_soc_dai_driver i2s_dai_drv; | 88 | struct snd_soc_dai_driver i2s_dai_drv; |
89 | /* DMA parameters */ | 89 | /* DMA parameters */ |
90 | struct s3c_dma_params dma_playback; | 90 | struct snd_dmaengine_dai_dma_data dma_playback; |
91 | struct s3c_dma_params dma_capture; | 91 | struct snd_dmaengine_dai_dma_data dma_capture; |
92 | struct s3c_dma_params idma_playback; | 92 | struct snd_dmaengine_dai_dma_data idma_playback; |
93 | dma_filter_fn filter; | 93 | dma_filter_fn filter; |
94 | u32 quirks; | 94 | u32 quirks; |
95 | u32 suspend_i2smod; | 95 | u32 suspend_i2smod; |
@@ -692,15 +692,15 @@ static int i2s_hw_params(struct snd_pcm_substream *substream, | |||
692 | break; | 692 | break; |
693 | case 2: | 693 | case 2: |
694 | if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) | 694 | if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) |
695 | i2s->dma_playback.dma_size = 4; | 695 | i2s->dma_playback.addr_width = 4; |
696 | else | 696 | else |
697 | i2s->dma_capture.dma_size = 4; | 697 | i2s->dma_capture.addr_width = 4; |
698 | break; | 698 | break; |
699 | case 1: | 699 | case 1: |
700 | if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) | 700 | if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) |
701 | i2s->dma_playback.dma_size = 2; | 701 | i2s->dma_playback.addr_width = 2; |
702 | else | 702 | else |
703 | i2s->dma_capture.dma_size = 2; | 703 | i2s->dma_capture.addr_width = 2; |
704 | 704 | ||
705 | break; | 705 | break; |
706 | default: | 706 | default: |
@@ -754,7 +754,7 @@ static int i2s_hw_params(struct snd_pcm_substream *substream, | |||
754 | writel(mod, i2s->addr + I2SMOD); | 754 | writel(mod, i2s->addr + I2SMOD); |
755 | spin_unlock_irqrestore(i2s->lock, flags); | 755 | spin_unlock_irqrestore(i2s->lock, flags); |
756 | 756 | ||
757 | samsung_asoc_init_dma_data(dai, &i2s->dma_playback, &i2s->dma_capture); | 757 | snd_soc_dai_init_dma_data(dai, &i2s->dma_playback, &i2s->dma_capture); |
758 | 758 | ||
759 | i2s->frmclk = params_rate(params); | 759 | i2s->frmclk = params_rate(params); |
760 | 760 | ||
@@ -991,10 +991,10 @@ static int samsung_i2s_dai_probe(struct snd_soc_dai *dai) | |||
991 | unsigned long flags; | 991 | unsigned long flags; |
992 | 992 | ||
993 | if (is_secondary(i2s)) { /* If this is probe on the secondary DAI */ | 993 | if (is_secondary(i2s)) { /* If this is probe on the secondary DAI */ |
994 | samsung_asoc_init_dma_data(dai, &other->sec_dai->dma_playback, | 994 | snd_soc_dai_init_dma_data(dai, &other->sec_dai->dma_playback, |
995 | NULL); | 995 | NULL); |
996 | } else { | 996 | } else { |
997 | samsung_asoc_init_dma_data(dai, &i2s->dma_playback, | 997 | snd_soc_dai_init_dma_data(dai, &i2s->dma_playback, |
998 | &i2s->dma_capture); | 998 | &i2s->dma_capture); |
999 | 999 | ||
1000 | if (i2s->quirks & QUIRK_NEED_RSTCLR) | 1000 | if (i2s->quirks & QUIRK_NEED_RSTCLR) |
@@ -1002,7 +1002,7 @@ static int samsung_i2s_dai_probe(struct snd_soc_dai *dai) | |||
1002 | 1002 | ||
1003 | if (i2s->quirks & QUIRK_SUPPORTS_IDMA) | 1003 | if (i2s->quirks & QUIRK_SUPPORTS_IDMA) |
1004 | idma_reg_addr_init(i2s->addr, | 1004 | idma_reg_addr_init(i2s->addr, |
1005 | i2s->sec_dai->idma_playback.dma_addr); | 1005 | i2s->sec_dai->idma_playback.addr); |
1006 | } | 1006 | } |
1007 | 1007 | ||
1008 | /* Reset any constraint on RFS and BFS */ | 1008 | /* Reset any constraint on RFS and BFS */ |
@@ -1262,8 +1262,8 @@ static int samsung_i2s_probe(struct platform_device *pdev) | |||
1262 | return -EINVAL; | 1262 | return -EINVAL; |
1263 | } | 1263 | } |
1264 | 1264 | ||
1265 | pri_dai->dma_playback.slave = i2s_pdata->dma_playback; | 1265 | pri_dai->dma_playback.filter_data = i2s_pdata->dma_playback; |
1266 | pri_dai->dma_capture.slave = i2s_pdata->dma_capture; | 1266 | pri_dai->dma_capture.filter_data = i2s_pdata->dma_capture; |
1267 | pri_dai->filter = i2s_pdata->dma_filter; | 1267 | pri_dai->filter = i2s_pdata->dma_filter; |
1268 | 1268 | ||
1269 | if (&i2s_pdata->type) | 1269 | if (&i2s_pdata->type) |
@@ -1302,12 +1302,12 @@ static int samsung_i2s_probe(struct platform_device *pdev) | |||
1302 | dev_err(&pdev->dev, "failed to enable clock: %d\n", ret); | 1302 | dev_err(&pdev->dev, "failed to enable clock: %d\n", ret); |
1303 | return ret; | 1303 | return ret; |
1304 | } | 1304 | } |
1305 | pri_dai->dma_playback.dma_addr = regs_base + I2STXD; | 1305 | pri_dai->dma_playback.addr = regs_base + I2STXD; |
1306 | pri_dai->dma_capture.dma_addr = regs_base + I2SRXD; | 1306 | pri_dai->dma_capture.addr = regs_base + I2SRXD; |
1307 | pri_dai->dma_playback.ch_name = "tx"; | 1307 | pri_dai->dma_playback.chan_name = "tx"; |
1308 | pri_dai->dma_capture.ch_name = "rx"; | 1308 | pri_dai->dma_capture.chan_name = "rx"; |
1309 | pri_dai->dma_playback.dma_size = 4; | 1309 | pri_dai->dma_playback.addr_width = 4; |
1310 | pri_dai->dma_capture.dma_size = 4; | 1310 | pri_dai->dma_capture.addr_width = 4; |
1311 | pri_dai->quirks = quirks; | 1311 | pri_dai->quirks = quirks; |
1312 | pri_dai->variant_regs = i2s_dai_data->i2s_variant_regs; | 1312 | pri_dai->variant_regs = i2s_dai_data->i2s_variant_regs; |
1313 | 1313 | ||
@@ -1318,31 +1318,33 @@ static int samsung_i2s_probe(struct platform_device *pdev) | |||
1318 | sec_dai = i2s_alloc_dai(pdev, true); | 1318 | sec_dai = i2s_alloc_dai(pdev, true); |
1319 | if (!sec_dai) { | 1319 | if (!sec_dai) { |
1320 | dev_err(&pdev->dev, "Unable to alloc I2S_sec\n"); | 1320 | dev_err(&pdev->dev, "Unable to alloc I2S_sec\n"); |
1321 | return -ENOMEM; | 1321 | ret = -ENOMEM; |
1322 | goto err_disable_clk; | ||
1322 | } | 1323 | } |
1323 | 1324 | ||
1324 | sec_dai->lock = &pri_dai->spinlock; | 1325 | sec_dai->lock = &pri_dai->spinlock; |
1325 | sec_dai->variant_regs = pri_dai->variant_regs; | 1326 | sec_dai->variant_regs = pri_dai->variant_regs; |
1326 | sec_dai->dma_playback.dma_addr = regs_base + I2STXDS; | 1327 | sec_dai->dma_playback.addr = regs_base + I2STXDS; |
1327 | sec_dai->dma_playback.ch_name = "tx-sec"; | 1328 | sec_dai->dma_playback.chan_name = "tx-sec"; |
1328 | 1329 | ||
1329 | if (!np) { | 1330 | if (!np) { |
1330 | sec_dai->dma_playback.slave = i2s_pdata->dma_play_sec; | 1331 | sec_dai->dma_playback.filter_data = i2s_pdata->dma_play_sec; |
1331 | sec_dai->filter = i2s_pdata->dma_filter; | 1332 | sec_dai->filter = i2s_pdata->dma_filter; |
1332 | } | 1333 | } |
1333 | 1334 | ||
1334 | sec_dai->dma_playback.dma_size = 4; | 1335 | sec_dai->dma_playback.addr_width = 4; |
1335 | sec_dai->addr = pri_dai->addr; | 1336 | sec_dai->addr = pri_dai->addr; |
1336 | sec_dai->clk = pri_dai->clk; | 1337 | sec_dai->clk = pri_dai->clk; |
1337 | sec_dai->quirks = quirks; | 1338 | sec_dai->quirks = quirks; |
1338 | sec_dai->idma_playback.dma_addr = idma_addr; | 1339 | sec_dai->idma_playback.addr = idma_addr; |
1339 | sec_dai->pri_dai = pri_dai; | 1340 | sec_dai->pri_dai = pri_dai; |
1340 | pri_dai->sec_dai = sec_dai; | 1341 | pri_dai->sec_dai = sec_dai; |
1341 | } | 1342 | } |
1342 | 1343 | ||
1343 | if (i2s_pdata && i2s_pdata->cfg_gpio && i2s_pdata->cfg_gpio(pdev)) { | 1344 | if (i2s_pdata && i2s_pdata->cfg_gpio && i2s_pdata->cfg_gpio(pdev)) { |
1344 | dev_err(&pdev->dev, "Unable to configure gpio\n"); | 1345 | dev_err(&pdev->dev, "Unable to configure gpio\n"); |
1345 | return -EINVAL; | 1346 | ret = -EINVAL; |
1347 | goto err_disable_clk; | ||
1346 | } | 1348 | } |
1347 | 1349 | ||
1348 | ret = devm_snd_soc_register_component(&pri_dai->pdev->dev, | 1350 | ret = devm_snd_soc_register_component(&pri_dai->pdev->dev, |
@@ -1366,6 +1368,8 @@ static int samsung_i2s_probe(struct platform_device *pdev) | |||
1366 | err_free_dai: | 1368 | err_free_dai: |
1367 | if (sec_dai) | 1369 | if (sec_dai) |
1368 | i2s_free_sec_dai(sec_dai); | 1370 | i2s_free_sec_dai(sec_dai); |
1371 | err_disable_clk: | ||
1372 | clk_disable_unprepare(pri_dai->clk); | ||
1369 | return ret; | 1373 | return ret; |
1370 | } | 1374 | } |
1371 | 1375 | ||
diff --git a/sound/soc/samsung/idma.c b/sound/soc/samsung/idma.c index 4ed29ffc1c54..3e408158625d 100644 --- a/sound/soc/samsung/idma.c +++ b/sound/soc/samsung/idma.c | |||
@@ -22,7 +22,6 @@ | |||
22 | 22 | ||
23 | #include "i2s.h" | 23 | #include "i2s.h" |
24 | #include "idma.h" | 24 | #include "idma.h" |
25 | #include "dma.h" | ||
26 | #include "i2s-regs.h" | 25 | #include "i2s-regs.h" |
27 | 26 | ||
28 | #define ST_RUNNING (1<<0) | 27 | #define ST_RUNNING (1<<0) |
diff --git a/sound/soc/samsung/pcm.c b/sound/soc/samsung/pcm.c index 490c1a87fd66..43e367a9acc3 100644 --- a/sound/soc/samsung/pcm.c +++ b/sound/soc/samsung/pcm.c | |||
@@ -127,25 +127,25 @@ struct s3c_pcm_info { | |||
127 | struct clk *pclk; | 127 | struct clk *pclk; |
128 | struct clk *cclk; | 128 | struct clk *cclk; |
129 | 129 | ||
130 | struct s3c_dma_params *dma_playback; | 130 | struct snd_dmaengine_dai_dma_data *dma_playback; |
131 | struct s3c_dma_params *dma_capture; | 131 | struct snd_dmaengine_dai_dma_data *dma_capture; |
132 | }; | 132 | }; |
133 | 133 | ||
134 | static struct s3c_dma_params s3c_pcm_stereo_out[] = { | 134 | static struct snd_dmaengine_dai_dma_data s3c_pcm_stereo_out[] = { |
135 | [0] = { | 135 | [0] = { |
136 | .dma_size = 4, | 136 | .addr_width = 4, |
137 | }, | 137 | }, |
138 | [1] = { | 138 | [1] = { |
139 | .dma_size = 4, | 139 | .addr_width = 4, |
140 | }, | 140 | }, |
141 | }; | 141 | }; |
142 | 142 | ||
143 | static struct s3c_dma_params s3c_pcm_stereo_in[] = { | 143 | static struct snd_dmaengine_dai_dma_data s3c_pcm_stereo_in[] = { |
144 | [0] = { | 144 | [0] = { |
145 | .dma_size = 4, | 145 | .addr_width = 4, |
146 | }, | 146 | }, |
147 | [1] = { | 147 | [1] = { |
148 | .dma_size = 4, | 148 | .addr_width = 4, |
149 | }, | 149 | }, |
150 | }; | 150 | }; |
151 | 151 | ||
@@ -552,15 +552,13 @@ static int s3c_pcm_dev_probe(struct platform_device *pdev) | |||
552 | } | 552 | } |
553 | clk_prepare_enable(pcm->pclk); | 553 | clk_prepare_enable(pcm->pclk); |
554 | 554 | ||
555 | s3c_pcm_stereo_in[pdev->id].dma_addr = mem_res->start | 555 | s3c_pcm_stereo_in[pdev->id].addr = mem_res->start + S3C_PCM_RXFIFO; |
556 | + S3C_PCM_RXFIFO; | 556 | s3c_pcm_stereo_out[pdev->id].addr = mem_res->start + S3C_PCM_TXFIFO; |
557 | s3c_pcm_stereo_out[pdev->id].dma_addr = mem_res->start | ||
558 | + S3C_PCM_TXFIFO; | ||
559 | 557 | ||
560 | filter = NULL; | 558 | filter = NULL; |
561 | if (pcm_pdata) { | 559 | if (pcm_pdata) { |
562 | s3c_pcm_stereo_in[pdev->id].slave = pcm_pdata->dma_capture; | 560 | s3c_pcm_stereo_in[pdev->id].filter_data = pcm_pdata->dma_capture; |
563 | s3c_pcm_stereo_out[pdev->id].slave = pcm_pdata->dma_playback; | 561 | s3c_pcm_stereo_out[pdev->id].filter_data = pcm_pdata->dma_playback; |
564 | filter = pcm_pdata->dma_filter; | 562 | filter = pcm_pdata->dma_filter; |
565 | } | 563 | } |
566 | 564 | ||
diff --git a/sound/soc/samsung/s3c-i2s-v2.c b/sound/soc/samsung/s3c-i2s-v2.c index bf8ae79b0fd2..644f186fd35c 100644 --- a/sound/soc/samsung/s3c-i2s-v2.c +++ b/sound/soc/samsung/s3c-i2s-v2.c | |||
@@ -24,7 +24,6 @@ | |||
24 | 24 | ||
25 | #include "regs-i2s-v2.h" | 25 | #include "regs-i2s-v2.h" |
26 | #include "s3c-i2s-v2.h" | 26 | #include "s3c-i2s-v2.h" |
27 | #include "dma.h" | ||
28 | 27 | ||
29 | #undef S3C_IIS_V2_SUPPORTED | 28 | #undef S3C_IIS_V2_SUPPORTED |
30 | 29 | ||
@@ -302,7 +301,7 @@ static int s3c_i2sv2_hw_params(struct snd_pcm_substream *substream, | |||
302 | struct snd_soc_dai *dai) | 301 | struct snd_soc_dai *dai) |
303 | { | 302 | { |
304 | struct s3c_i2sv2_info *i2s = to_info(dai); | 303 | struct s3c_i2sv2_info *i2s = to_info(dai); |
305 | struct s3c_dma_params *dma_data; | 304 | struct snd_dmaengine_dai_dma_data *dma_data; |
306 | u32 iismod; | 305 | u32 iismod; |
307 | 306 | ||
308 | pr_debug("Entered %s\n", __func__); | 307 | pr_debug("Entered %s\n", __func__); |
diff --git a/sound/soc/samsung/s3c-i2s-v2.h b/sound/soc/samsung/s3c-i2s-v2.h index d0684145ed1f..182d80564e37 100644 --- a/sound/soc/samsung/s3c-i2s-v2.h +++ b/sound/soc/samsung/s3c-i2s-v2.h | |||
@@ -60,8 +60,8 @@ struct s3c_i2sv2_info { | |||
60 | 60 | ||
61 | unsigned char master; | 61 | unsigned char master; |
62 | 62 | ||
63 | struct s3c_dma_params *dma_playback; | 63 | struct snd_dmaengine_dai_dma_data *dma_playback; |
64 | struct s3c_dma_params *dma_capture; | 64 | struct snd_dmaengine_dai_dma_data *dma_capture; |
65 | 65 | ||
66 | u32 suspend_iismod; | 66 | u32 suspend_iismod; |
67 | u32 suspend_iiscon; | 67 | u32 suspend_iiscon; |
diff --git a/sound/soc/samsung/s3c2412-i2s.c b/sound/soc/samsung/s3c2412-i2s.c index d45dffb297d8..3e89fbc0c51d 100644 --- a/sound/soc/samsung/s3c2412-i2s.c +++ b/sound/soc/samsung/s3c2412-i2s.c | |||
@@ -34,14 +34,14 @@ | |||
34 | 34 | ||
35 | #include <linux/platform_data/asoc-s3c.h> | 35 | #include <linux/platform_data/asoc-s3c.h> |
36 | 36 | ||
37 | static struct s3c_dma_params s3c2412_i2s_pcm_stereo_out = { | 37 | static struct snd_dmaengine_dai_dma_data s3c2412_i2s_pcm_stereo_out = { |
38 | .ch_name = "tx", | 38 | .chan_name = "tx", |
39 | .dma_size = 4, | 39 | .addr_width = 4, |
40 | }; | 40 | }; |
41 | 41 | ||
42 | static struct s3c_dma_params s3c2412_i2s_pcm_stereo_in = { | 42 | static struct snd_dmaengine_dai_dma_data s3c2412_i2s_pcm_stereo_in = { |
43 | .ch_name = "rx", | 43 | .chan_name = "rx", |
44 | .dma_size = 4, | 44 | .addr_width = 4, |
45 | }; | 45 | }; |
46 | 46 | ||
47 | static struct s3c_i2sv2_info s3c2412_i2s; | 47 | static struct s3c_i2sv2_info s3c2412_i2s; |
@@ -52,8 +52,8 @@ static int s3c2412_i2s_probe(struct snd_soc_dai *dai) | |||
52 | 52 | ||
53 | pr_debug("Entered %s\n", __func__); | 53 | pr_debug("Entered %s\n", __func__); |
54 | 54 | ||
55 | samsung_asoc_init_dma_data(dai, &s3c2412_i2s_pcm_stereo_out, | 55 | snd_soc_dai_init_dma_data(dai, &s3c2412_i2s_pcm_stereo_out, |
56 | &s3c2412_i2s_pcm_stereo_in); | 56 | &s3c2412_i2s_pcm_stereo_in); |
57 | 57 | ||
58 | ret = s3c_i2sv2_probe(dai, &s3c2412_i2s, S3C2410_PA_IIS); | 58 | ret = s3c_i2sv2_probe(dai, &s3c2412_i2s, S3C2410_PA_IIS); |
59 | if (ret) | 59 | if (ret) |
@@ -163,10 +163,10 @@ static int s3c2412_iis_dev_probe(struct platform_device *pdev) | |||
163 | if (IS_ERR(s3c2412_i2s.regs)) | 163 | if (IS_ERR(s3c2412_i2s.regs)) |
164 | return PTR_ERR(s3c2412_i2s.regs); | 164 | return PTR_ERR(s3c2412_i2s.regs); |
165 | 165 | ||
166 | s3c2412_i2s_pcm_stereo_out.dma_addr = res->start + S3C2412_IISTXD; | 166 | s3c2412_i2s_pcm_stereo_out.addr = res->start + S3C2412_IISTXD; |
167 | s3c2412_i2s_pcm_stereo_out.slave = pdata->dma_playback; | 167 | s3c2412_i2s_pcm_stereo_out.filter_data = pdata->dma_playback; |
168 | s3c2412_i2s_pcm_stereo_in.dma_addr = res->start + S3C2412_IISRXD; | 168 | s3c2412_i2s_pcm_stereo_in.addr = res->start + S3C2412_IISRXD; |
169 | s3c2412_i2s_pcm_stereo_in.slave = pdata->dma_capture; | 169 | s3c2412_i2s_pcm_stereo_in.filter_data = pdata->dma_capture; |
170 | 170 | ||
171 | ret = s3c_i2sv2_register_component(&pdev->dev, -1, | 171 | ret = s3c_i2sv2_register_component(&pdev->dev, -1, |
172 | &s3c2412_i2s_component, | 172 | &s3c2412_i2s_component, |
diff --git a/sound/soc/samsung/s3c24xx-i2s.c b/sound/soc/samsung/s3c24xx-i2s.c index 3e76f2a75a24..c78a936a3099 100644 --- a/sound/soc/samsung/s3c24xx-i2s.c +++ b/sound/soc/samsung/s3c24xx-i2s.c | |||
@@ -32,14 +32,14 @@ | |||
32 | 32 | ||
33 | #include <linux/platform_data/asoc-s3c.h> | 33 | #include <linux/platform_data/asoc-s3c.h> |
34 | 34 | ||
35 | static struct s3c_dma_params s3c24xx_i2s_pcm_stereo_out = { | 35 | static struct snd_dmaengine_dai_dma_data s3c24xx_i2s_pcm_stereo_out = { |
36 | .ch_name = "tx", | 36 | .chan_name = "tx", |
37 | .dma_size = 2, | 37 | .addr_width = 2, |
38 | }; | 38 | }; |
39 | 39 | ||
40 | static struct s3c_dma_params s3c24xx_i2s_pcm_stereo_in = { | 40 | static struct snd_dmaengine_dai_dma_data s3c24xx_i2s_pcm_stereo_in = { |
41 | .ch_name = "rx", | 41 | .chan_name = "rx", |
42 | .dma_size = 2, | 42 | .addr_width = 2, |
43 | }; | 43 | }; |
44 | 44 | ||
45 | struct s3c24xx_i2s_info { | 45 | struct s3c24xx_i2s_info { |
@@ -360,8 +360,8 @@ static int s3c24xx_i2s_probe(struct snd_soc_dai *dai) | |||
360 | { | 360 | { |
361 | pr_debug("Entered %s\n", __func__); | 361 | pr_debug("Entered %s\n", __func__); |
362 | 362 | ||
363 | samsung_asoc_init_dma_data(dai, &s3c24xx_i2s_pcm_stereo_out, | 363 | snd_soc_dai_init_dma_data(dai, &s3c24xx_i2s_pcm_stereo_out, |
364 | &s3c24xx_i2s_pcm_stereo_in); | 364 | &s3c24xx_i2s_pcm_stereo_in); |
365 | 365 | ||
366 | s3c24xx_i2s.iis_clk = devm_clk_get(dai->dev, "iis"); | 366 | s3c24xx_i2s.iis_clk = devm_clk_get(dai->dev, "iis"); |
367 | if (IS_ERR(s3c24xx_i2s.iis_clk)) { | 367 | if (IS_ERR(s3c24xx_i2s.iis_clk)) { |
@@ -469,10 +469,10 @@ static int s3c24xx_iis_dev_probe(struct platform_device *pdev) | |||
469 | if (IS_ERR(s3c24xx_i2s.regs)) | 469 | if (IS_ERR(s3c24xx_i2s.regs)) |
470 | return PTR_ERR(s3c24xx_i2s.regs); | 470 | return PTR_ERR(s3c24xx_i2s.regs); |
471 | 471 | ||
472 | s3c24xx_i2s_pcm_stereo_out.dma_addr = res->start + S3C2410_IISFIFO; | 472 | s3c24xx_i2s_pcm_stereo_out.addr = res->start + S3C2410_IISFIFO; |
473 | s3c24xx_i2s_pcm_stereo_out.slave = pdata->dma_playback; | 473 | s3c24xx_i2s_pcm_stereo_out.filter_data = pdata->dma_playback; |
474 | s3c24xx_i2s_pcm_stereo_in.dma_addr = res->start + S3C2410_IISFIFO; | 474 | s3c24xx_i2s_pcm_stereo_in.addr = res->start + S3C2410_IISFIFO; |
475 | s3c24xx_i2s_pcm_stereo_in.slave = pdata->dma_capture; | 475 | s3c24xx_i2s_pcm_stereo_in.filter_data = pdata->dma_capture; |
476 | 476 | ||
477 | ret = devm_snd_soc_register_component(&pdev->dev, | 477 | ret = devm_snd_soc_register_component(&pdev->dev, |
478 | &s3c24xx_i2s_component, &s3c24xx_i2s_dai, 1); | 478 | &s3c24xx_i2s_component, &s3c24xx_i2s_dai, 1); |
diff --git a/sound/soc/samsung/s3c24xx_uda134x.c b/sound/soc/samsung/s3c24xx_uda134x.c index 92e88bca386e..7853fbe6ccc9 100644 --- a/sound/soc/samsung/s3c24xx_uda134x.c +++ b/sound/soc/samsung/s3c24xx_uda134x.c | |||
@@ -54,8 +54,6 @@ static struct snd_pcm_hw_constraint_list hw_constraints_rates = { | |||
54 | }; | 54 | }; |
55 | #endif | 55 | #endif |
56 | 56 | ||
57 | static struct platform_device *s3c24xx_uda134x_snd_device; | ||
58 | |||
59 | static int s3c24xx_uda134x_startup(struct snd_pcm_substream *substream) | 57 | static int s3c24xx_uda134x_startup(struct snd_pcm_substream *substream) |
60 | { | 58 | { |
61 | struct snd_soc_pcm_runtime *rtd = substream->private_data; | 59 | struct snd_soc_pcm_runtime *rtd = substream->private_data; |
@@ -66,17 +64,17 @@ static int s3c24xx_uda134x_startup(struct snd_pcm_substream *substream) | |||
66 | int ret = 0; | 64 | int ret = 0; |
67 | 65 | ||
68 | mutex_lock(&clk_lock); | 66 | mutex_lock(&clk_lock); |
69 | pr_debug("%s %d\n", __func__, clk_users); | 67 | |
70 | if (clk_users == 0) { | 68 | if (clk_users == 0) { |
71 | xtal = clk_get(&s3c24xx_uda134x_snd_device->dev, "xtal"); | 69 | xtal = clk_get(rtd->dev, "xtal"); |
72 | if (IS_ERR(xtal)) { | 70 | if (IS_ERR(xtal)) { |
73 | printk(KERN_ERR "%s cannot get xtal\n", __func__); | 71 | dev_err(rtd->dev, "%s cannot get xtal\n", __func__); |
74 | ret = PTR_ERR(xtal); | 72 | ret = PTR_ERR(xtal); |
75 | } else { | 73 | } else { |
76 | pclk = clk_get(cpu_dai->dev, "iis"); | 74 | pclk = clk_get(cpu_dai->dev, "iis"); |
77 | if (IS_ERR(pclk)) { | 75 | if (IS_ERR(pclk)) { |
78 | printk(KERN_ERR "%s cannot get pclk\n", | 76 | dev_err(rtd->dev, "%s cannot get pclk\n", |
79 | __func__); | 77 | __func__); |
80 | clk_put(xtal); | 78 | clk_put(xtal); |
81 | ret = PTR_ERR(pclk); | 79 | ret = PTR_ERR(pclk); |
82 | } | 80 | } |
@@ -102,8 +100,8 @@ static int s3c24xx_uda134x_startup(struct snd_pcm_substream *substream) | |||
102 | SNDRV_PCM_HW_PARAM_RATE, | 100 | SNDRV_PCM_HW_PARAM_RATE, |
103 | &hw_constraints_rates); | 101 | &hw_constraints_rates); |
104 | if (ret < 0) | 102 | if (ret < 0) |
105 | printk(KERN_ERR "%s cannot set constraints\n", | 103 | dev_err(rtd->dev, "%s cannot set constraints\n", |
106 | __func__); | 104 | __func__); |
107 | #endif | 105 | #endif |
108 | } | 106 | } |
109 | return ret; | 107 | return ret; |
@@ -112,7 +110,6 @@ static int s3c24xx_uda134x_startup(struct snd_pcm_substream *substream) | |||
112 | static void s3c24xx_uda134x_shutdown(struct snd_pcm_substream *substream) | 110 | static void s3c24xx_uda134x_shutdown(struct snd_pcm_substream *substream) |
113 | { | 111 | { |
114 | mutex_lock(&clk_lock); | 112 | mutex_lock(&clk_lock); |
115 | pr_debug("%s %d\n", __func__, clk_users); | ||
116 | clk_users -= 1; | 113 | clk_users -= 1; |
117 | if (clk_users == 0) { | 114 | if (clk_users == 0) { |
118 | clk_put(xtal); | 115 | clk_put(xtal); |
@@ -159,18 +156,19 @@ static int s3c24xx_uda134x_hw_params(struct snd_pcm_substream *substream, | |||
159 | clk_source = S3C24XX_CLKSRC_PCLK; | 156 | clk_source = S3C24XX_CLKSRC_PCLK; |
160 | div = bi % 33; | 157 | div = bi % 33; |
161 | } | 158 | } |
162 | pr_debug("%s desired rate %lu, %d\n", __func__, rate, bi); | 159 | |
160 | dev_dbg(rtd->dev, "%s desired rate %lu, %d\n", __func__, rate, bi); | ||
163 | 161 | ||
164 | clk = (fs_mode == S3C2410_IISMOD_384FS ? 384 : 256) * rate; | 162 | clk = (fs_mode == S3C2410_IISMOD_384FS ? 384 : 256) * rate; |
165 | pr_debug("%s will use: %s %s %d sysclk %d err %ld\n", __func__, | 163 | |
166 | fs_mode == S3C2410_IISMOD_384FS ? "384FS" : "256FS", | 164 | dev_dbg(rtd->dev, "%s will use: %s %s %d sysclk %d err %ld\n", __func__, |
167 | clk_source == S3C24XX_CLKSRC_MPLL ? "MPLLin" : "PCLK", | 165 | fs_mode == S3C2410_IISMOD_384FS ? "384FS" : "256FS", |
168 | div, clk, err); | 166 | clk_source == S3C24XX_CLKSRC_MPLL ? "MPLLin" : "PCLK", |
167 | div, clk, err); | ||
169 | 168 | ||
170 | if ((err * 100 / rate) > 5) { | 169 | if ((err * 100 / rate) > 5) { |
171 | printk(KERN_ERR "S3C24XX_UDA134X: effective frequency " | 170 | dev_err(rtd->dev, "effective frequency too different " |
172 | "too different from desired (%ld%%)\n", | 171 | "from desired (%ld%%)\n", err * 100 / rate); |
173 | err * 100 / rate); | ||
174 | return -EINVAL; | 172 | return -EINVAL; |
175 | } | 173 | } |
176 | 174 | ||
@@ -227,115 +225,27 @@ static struct snd_soc_card snd_soc_s3c24xx_uda134x = { | |||
227 | .num_links = 1, | 225 | .num_links = 1, |
228 | }; | 226 | }; |
229 | 227 | ||
230 | static struct s3c24xx_uda134x_platform_data *s3c24xx_uda134x_l3_pins; | ||
231 | |||
232 | static void setdat(int v) | ||
233 | { | ||
234 | gpio_set_value(s3c24xx_uda134x_l3_pins->l3_data, v > 0); | ||
235 | } | ||
236 | |||
237 | static void setclk(int v) | ||
238 | { | ||
239 | gpio_set_value(s3c24xx_uda134x_l3_pins->l3_clk, v > 0); | ||
240 | } | ||
241 | |||
242 | static void setmode(int v) | ||
243 | { | ||
244 | gpio_set_value(s3c24xx_uda134x_l3_pins->l3_mode, v > 0); | ||
245 | } | ||
246 | |||
247 | /* FIXME - This must be codec platform data but in which board file ?? */ | ||
248 | static struct uda134x_platform_data s3c24xx_uda134x = { | ||
249 | .l3 = { | ||
250 | .setdat = setdat, | ||
251 | .setclk = setclk, | ||
252 | .setmode = setmode, | ||
253 | .data_hold = 1, | ||
254 | .data_setup = 1, | ||
255 | .clock_high = 1, | ||
256 | .mode_hold = 1, | ||
257 | .mode = 1, | ||
258 | .mode_setup = 1, | ||
259 | }, | ||
260 | }; | ||
261 | |||
262 | static int s3c24xx_uda134x_setup_pin(int pin, char *fun) | ||
263 | { | ||
264 | if (gpio_request(pin, "s3c24xx_uda134x") < 0) { | ||
265 | printk(KERN_ERR "S3C24XX_UDA134X SoC Audio: " | ||
266 | "l3 %s pin already in use", fun); | ||
267 | return -EBUSY; | ||
268 | } | ||
269 | gpio_direction_output(pin, 0); | ||
270 | return 0; | ||
271 | } | ||
272 | |||
273 | static int s3c24xx_uda134x_probe(struct platform_device *pdev) | 228 | static int s3c24xx_uda134x_probe(struct platform_device *pdev) |
274 | { | 229 | { |
230 | struct snd_soc_card *card = &snd_soc_s3c24xx_uda134x; | ||
275 | int ret; | 231 | int ret; |
276 | 232 | ||
277 | printk(KERN_INFO "S3C24XX_UDA134X SoC Audio driver\n"); | 233 | platform_set_drvdata(pdev, card); |
234 | card->dev = &pdev->dev; | ||
278 | 235 | ||
279 | s3c24xx_uda134x_l3_pins = pdev->dev.platform_data; | 236 | ret = devm_snd_soc_register_card(&pdev->dev, card); |
280 | if (s3c24xx_uda134x_l3_pins == NULL) { | 237 | if (ret) |
281 | printk(KERN_ERR "S3C24XX_UDA134X SoC Audio: " | 238 | dev_err(&pdev->dev, "failed to register card: %d\n", ret); |
282 | "unable to find platform data\n"); | ||
283 | return -ENODEV; | ||
284 | } | ||
285 | s3c24xx_uda134x.power = s3c24xx_uda134x_l3_pins->power; | ||
286 | s3c24xx_uda134x.model = s3c24xx_uda134x_l3_pins->model; | ||
287 | |||
288 | if (s3c24xx_uda134x_setup_pin(s3c24xx_uda134x_l3_pins->l3_data, | ||
289 | "data") < 0) | ||
290 | return -EBUSY; | ||
291 | if (s3c24xx_uda134x_setup_pin(s3c24xx_uda134x_l3_pins->l3_clk, | ||
292 | "clk") < 0) { | ||
293 | gpio_free(s3c24xx_uda134x_l3_pins->l3_data); | ||
294 | return -EBUSY; | ||
295 | } | ||
296 | if (s3c24xx_uda134x_setup_pin(s3c24xx_uda134x_l3_pins->l3_mode, | ||
297 | "mode") < 0) { | ||
298 | gpio_free(s3c24xx_uda134x_l3_pins->l3_data); | ||
299 | gpio_free(s3c24xx_uda134x_l3_pins->l3_clk); | ||
300 | return -EBUSY; | ||
301 | } | ||
302 | |||
303 | s3c24xx_uda134x_snd_device = platform_device_alloc("soc-audio", -1); | ||
304 | if (!s3c24xx_uda134x_snd_device) { | ||
305 | printk(KERN_ERR "S3C24XX_UDA134X SoC Audio: " | ||
306 | "Unable to register\n"); | ||
307 | return -ENOMEM; | ||
308 | } | ||
309 | |||
310 | platform_set_drvdata(s3c24xx_uda134x_snd_device, | ||
311 | &snd_soc_s3c24xx_uda134x); | ||
312 | platform_device_add_data(s3c24xx_uda134x_snd_device, &s3c24xx_uda134x, sizeof(s3c24xx_uda134x)); | ||
313 | ret = platform_device_add(s3c24xx_uda134x_snd_device); | ||
314 | if (ret) { | ||
315 | printk(KERN_ERR "S3C24XX_UDA134X SoC Audio: Unable to add\n"); | ||
316 | platform_device_put(s3c24xx_uda134x_snd_device); | ||
317 | } | ||
318 | 239 | ||
319 | return ret; | 240 | return ret; |
320 | } | 241 | } |
321 | 242 | ||
322 | static int s3c24xx_uda134x_remove(struct platform_device *pdev) | ||
323 | { | ||
324 | platform_device_unregister(s3c24xx_uda134x_snd_device); | ||
325 | gpio_free(s3c24xx_uda134x_l3_pins->l3_data); | ||
326 | gpio_free(s3c24xx_uda134x_l3_pins->l3_clk); | ||
327 | gpio_free(s3c24xx_uda134x_l3_pins->l3_mode); | ||
328 | return 0; | ||
329 | } | ||
330 | |||
331 | static struct platform_driver s3c24xx_uda134x_driver = { | 243 | static struct platform_driver s3c24xx_uda134x_driver = { |
332 | .probe = s3c24xx_uda134x_probe, | 244 | .probe = s3c24xx_uda134x_probe, |
333 | .remove = s3c24xx_uda134x_remove, | ||
334 | .driver = { | 245 | .driver = { |
335 | .name = "s3c24xx_uda134x", | 246 | .name = "s3c24xx_uda134x", |
336 | }, | 247 | }, |
337 | }; | 248 | }; |
338 | |||
339 | module_platform_driver(s3c24xx_uda134x_driver); | 249 | module_platform_driver(s3c24xx_uda134x_driver); |
340 | 250 | ||
341 | MODULE_AUTHOR("Zoltan Devai, Christian Pellegrin <chripell@evolware.org>"); | 251 | MODULE_AUTHOR("Zoltan Devai, Christian Pellegrin <chripell@evolware.org>"); |
diff --git a/sound/soc/samsung/smdk_wm8580pcm.c b/sound/soc/samsung/smdk_wm8580pcm.c index 6deec5234c92..a6d223310c67 100644 --- a/sound/soc/samsung/smdk_wm8580pcm.c +++ b/sound/soc/samsung/smdk_wm8580pcm.c | |||
@@ -16,7 +16,6 @@ | |||
16 | #include <asm/mach-types.h> | 16 | #include <asm/mach-types.h> |
17 | 17 | ||
18 | #include "../codecs/wm8580.h" | 18 | #include "../codecs/wm8580.h" |
19 | #include "dma.h" | ||
20 | #include "pcm.h" | 19 | #include "pcm.h" |
21 | 20 | ||
22 | /* | 21 | /* |
diff --git a/sound/soc/samsung/smdk_wm8994pcm.c b/sound/soc/samsung/smdk_wm8994pcm.c index b1c89ec2d999..2e621496be8b 100644 --- a/sound/soc/samsung/smdk_wm8994pcm.c +++ b/sound/soc/samsung/smdk_wm8994pcm.c | |||
@@ -15,7 +15,6 @@ | |||
15 | #include <sound/pcm_params.h> | 15 | #include <sound/pcm_params.h> |
16 | 16 | ||
17 | #include "../codecs/wm8994.h" | 17 | #include "../codecs/wm8994.h" |
18 | #include "dma.h" | ||
19 | #include "pcm.h" | 18 | #include "pcm.h" |
20 | 19 | ||
21 | /* | 20 | /* |
diff --git a/sound/soc/samsung/spdif.c b/sound/soc/samsung/spdif.c index 0cb9c8567546..26c1fbed4d35 100644 --- a/sound/soc/samsung/spdif.c +++ b/sound/soc/samsung/spdif.c | |||
@@ -90,10 +90,10 @@ struct samsung_spdif_info { | |||
90 | u32 saved_clkcon; | 90 | u32 saved_clkcon; |
91 | u32 saved_con; | 91 | u32 saved_con; |
92 | u32 saved_cstas; | 92 | u32 saved_cstas; |
93 | struct s3c_dma_params *dma_playback; | 93 | struct snd_dmaengine_dai_dma_data *dma_playback; |
94 | }; | 94 | }; |
95 | 95 | ||
96 | static struct s3c_dma_params spdif_stereo_out; | 96 | static struct snd_dmaengine_dai_dma_data spdif_stereo_out; |
97 | static struct samsung_spdif_info spdif_info; | 97 | static struct samsung_spdif_info spdif_info; |
98 | 98 | ||
99 | static inline struct samsung_spdif_info *to_info(struct snd_soc_dai *cpu_dai) | 99 | static inline struct samsung_spdif_info *to_info(struct snd_soc_dai *cpu_dai) |
@@ -179,7 +179,7 @@ static int spdif_hw_params(struct snd_pcm_substream *substream, | |||
179 | struct snd_soc_pcm_runtime *rtd = substream->private_data; | 179 | struct snd_soc_pcm_runtime *rtd = substream->private_data; |
180 | struct samsung_spdif_info *spdif = to_info(rtd->cpu_dai); | 180 | struct samsung_spdif_info *spdif = to_info(rtd->cpu_dai); |
181 | void __iomem *regs = spdif->regs; | 181 | void __iomem *regs = spdif->regs; |
182 | struct s3c_dma_params *dma_data; | 182 | struct snd_dmaengine_dai_dma_data *dma_data; |
183 | u32 con, clkcon, cstas; | 183 | u32 con, clkcon, cstas; |
184 | unsigned long flags; | 184 | unsigned long flags; |
185 | int i, ratio; | 185 | int i, ratio; |
@@ -425,11 +425,11 @@ static int spdif_probe(struct platform_device *pdev) | |||
425 | goto err4; | 425 | goto err4; |
426 | } | 426 | } |
427 | 427 | ||
428 | spdif_stereo_out.dma_size = 2; | 428 | spdif_stereo_out.addr_width = 2; |
429 | spdif_stereo_out.dma_addr = mem_res->start + DATA_OUTBUF; | 429 | spdif_stereo_out.addr = mem_res->start + DATA_OUTBUF; |
430 | filter = NULL; | 430 | filter = NULL; |
431 | if (spdif_pdata) { | 431 | if (spdif_pdata) { |
432 | spdif_stereo_out.slave = spdif_pdata->dma_playback; | 432 | spdif_stereo_out.filter_data = spdif_pdata->dma_playback; |
433 | filter = spdif_pdata->dma_filter; | 433 | filter = spdif_pdata->dma_filter; |
434 | } | 434 | } |
435 | 435 | ||
diff --git a/sound/soc/sh/Kconfig b/sound/soc/sh/Kconfig index 9311f119feb5..6db6405d952f 100644 --- a/sound/soc/sh/Kconfig +++ b/sound/soc/sh/Kconfig | |||
@@ -42,12 +42,6 @@ config SND_SOC_RCAR | |||
42 | help | 42 | help |
43 | This option enables R-Car SRU/SCU/SSIU/SSI sound support | 43 | This option enables R-Car SRU/SCU/SSIU/SSI sound support |
44 | 44 | ||
45 | config SND_SOC_RSRC_CARD | ||
46 | tristate "Renesas Sampling Rate Convert Sound Card" | ||
47 | select SND_SIMPLE_CARD_UTILS | ||
48 | help | ||
49 | This option enables simple sound if you need sampling rate convert | ||
50 | |||
51 | ## | 45 | ## |
52 | ## Boards | 46 | ## Boards |
53 | ## | 47 | ## |
diff --git a/sound/soc/sh/rcar/Makefile b/sound/soc/sh/rcar/Makefile index a89ddf758695..9c3d5aed99d1 100644 --- a/sound/soc/sh/rcar/Makefile +++ b/sound/soc/sh/rcar/Makefile | |||
@@ -1,5 +1,2 @@ | |||
1 | snd-soc-rcar-objs := core.o gen.o dma.o adg.o ssi.o ssiu.o src.o ctu.o mix.o dvc.o cmd.o | 1 | snd-soc-rcar-objs := core.o gen.o dma.o adg.o ssi.o ssiu.o src.o ctu.o mix.o dvc.o cmd.o |
2 | obj-$(CONFIG_SND_SOC_RCAR) += snd-soc-rcar.o | 2 | obj-$(CONFIG_SND_SOC_RCAR) += snd-soc-rcar.o |
3 | |||
4 | snd-soc-rsrc-card-objs := rsrc-card.o | ||
5 | obj-$(CONFIG_SND_SOC_RSRC_CARD) += snd-soc-rsrc-card.o | ||
diff --git a/sound/soc/sh/rcar/core.c b/sound/soc/sh/rcar/core.c index 3351a701c60e..f18141098b50 100644 --- a/sound/soc/sh/rcar/core.c +++ b/sound/soc/sh/rcar/core.c | |||
@@ -110,6 +110,7 @@ MODULE_DEVICE_TABLE(of, rsnd_of_match); | |||
110 | /* | 110 | /* |
111 | * rsnd_mod functions | 111 | * rsnd_mod functions |
112 | */ | 112 | */ |
113 | #ifdef DEBUG | ||
113 | void rsnd_mod_make_sure(struct rsnd_mod *mod, enum rsnd_mod_type type) | 114 | void rsnd_mod_make_sure(struct rsnd_mod *mod, enum rsnd_mod_type type) |
114 | { | 115 | { |
115 | if (mod->type != type) { | 116 | if (mod->type != type) { |
@@ -120,6 +121,7 @@ void rsnd_mod_make_sure(struct rsnd_mod *mod, enum rsnd_mod_type type) | |||
120 | rsnd_mod_name(mod), rsnd_mod_id(mod)); | 121 | rsnd_mod_name(mod), rsnd_mod_id(mod)); |
121 | } | 122 | } |
122 | } | 123 | } |
124 | #endif | ||
123 | 125 | ||
124 | char *rsnd_mod_name(struct rsnd_mod *mod) | 126 | char *rsnd_mod_name(struct rsnd_mod *mod) |
125 | { | 127 | { |
@@ -574,6 +576,7 @@ static int rsnd_soc_dai_trigger(struct snd_pcm_substream *substream, int cmd, | |||
574 | 576 | ||
575 | switch (cmd) { | 577 | switch (cmd) { |
576 | case SNDRV_PCM_TRIGGER_START: | 578 | case SNDRV_PCM_TRIGGER_START: |
579 | case SNDRV_PCM_TRIGGER_RESUME: | ||
577 | rsnd_dai_stream_init(io, substream); | 580 | rsnd_dai_stream_init(io, substream); |
578 | 581 | ||
579 | ret = rsnd_dai_call(init, io, priv); | 582 | ret = rsnd_dai_call(init, io, priv); |
@@ -590,6 +593,7 @@ static int rsnd_soc_dai_trigger(struct snd_pcm_substream *substream, int cmd, | |||
590 | 593 | ||
591 | break; | 594 | break; |
592 | case SNDRV_PCM_TRIGGER_STOP: | 595 | case SNDRV_PCM_TRIGGER_STOP: |
596 | case SNDRV_PCM_TRIGGER_SUSPEND: | ||
593 | ret = rsnd_dai_call(irq, io, priv, 0); | 597 | ret = rsnd_dai_call(irq, io, priv, 0); |
594 | 598 | ||
595 | ret |= rsnd_dai_call(stop, io, priv); | 599 | ret |= rsnd_dai_call(stop, io, priv); |
diff --git a/sound/soc/sh/rcar/rsrc-card.c b/sound/soc/sh/rcar/rsrc-card.c deleted file mode 100644 index fa37f842b62f..000000000000 --- a/sound/soc/sh/rcar/rsrc-card.c +++ /dev/null | |||
@@ -1,486 +0,0 @@ | |||
1 | /* | ||
2 | * Renesas Sampling Rate Convert Sound Card for DPCM | ||
3 | * | ||
4 | * Copyright (C) 2015 Renesas Solutions Corp. | ||
5 | * Kuninori Morimoto <kuninori.morimoto.gx@renesas.com> | ||
6 | * | ||
7 | * based on ${LINUX}/sound/soc/generic/simple-card.c | ||
8 | * | ||
9 | * This program is free software; you can redistribute it and/or modify | ||
10 | * it under the terms of the GNU General Public License version 2 as | ||
11 | * published by the Free Software Foundation. | ||
12 | */ | ||
13 | #include <linux/clk.h> | ||
14 | #include <linux/device.h> | ||
15 | #include <linux/module.h> | ||
16 | #include <linux/of.h> | ||
17 | #include <linux/of_device.h> | ||
18 | #include <linux/platform_device.h> | ||
19 | #include <linux/string.h> | ||
20 | #include <sound/jack.h> | ||
21 | #include <sound/soc.h> | ||
22 | #include <sound/soc-dai.h> | ||
23 | #include <sound/simple_card_utils.h> | ||
24 | |||
25 | struct rsrc_card_of_data { | ||
26 | const char *prefix; | ||
27 | const struct snd_soc_dapm_route *routes; | ||
28 | int num_routes; | ||
29 | }; | ||
30 | |||
31 | static const struct snd_soc_dapm_route routes_ssi0_ak4642[] = { | ||
32 | {"ak4642 Playback", NULL, "DAI0 Playback"}, | ||
33 | {"DAI0 Capture", NULL, "ak4642 Capture"}, | ||
34 | }; | ||
35 | |||
36 | static const struct rsrc_card_of_data routes_of_ssi0_ak4642 = { | ||
37 | .prefix = "ak4642", | ||
38 | .routes = routes_ssi0_ak4642, | ||
39 | .num_routes = ARRAY_SIZE(routes_ssi0_ak4642), | ||
40 | }; | ||
41 | |||
42 | static const struct of_device_id rsrc_card_of_match[] = { | ||
43 | { .compatible = "renesas,rsrc-card,lager", .data = &routes_of_ssi0_ak4642 }, | ||
44 | { .compatible = "renesas,rsrc-card,koelsch", .data = &routes_of_ssi0_ak4642 }, | ||
45 | { .compatible = "renesas,rsrc-card", }, | ||
46 | {}, | ||
47 | }; | ||
48 | MODULE_DEVICE_TABLE(of, rsrc_card_of_match); | ||
49 | |||
50 | #define IDX_CPU 0 | ||
51 | #define IDX_CODEC 1 | ||
52 | struct rsrc_card_priv { | ||
53 | struct snd_soc_card snd_card; | ||
54 | struct snd_soc_codec_conf codec_conf; | ||
55 | struct asoc_simple_dai *dai_props; | ||
56 | struct snd_soc_dai_link *dai_link; | ||
57 | u32 convert_rate; | ||
58 | u32 convert_channels; | ||
59 | }; | ||
60 | |||
61 | #define rsrc_priv_to_dev(priv) ((priv)->snd_card.dev) | ||
62 | #define rsrc_priv_to_link(priv, i) ((priv)->snd_card.dai_link + (i)) | ||
63 | #define rsrc_priv_to_props(priv, i) ((priv)->dai_props + (i)) | ||
64 | |||
65 | static int rsrc_card_startup(struct snd_pcm_substream *substream) | ||
66 | { | ||
67 | struct snd_soc_pcm_runtime *rtd = substream->private_data; | ||
68 | struct rsrc_card_priv *priv = snd_soc_card_get_drvdata(rtd->card); | ||
69 | struct asoc_simple_dai *dai_props = | ||
70 | rsrc_priv_to_props(priv, rtd->num); | ||
71 | |||
72 | return clk_prepare_enable(dai_props->clk); | ||
73 | } | ||
74 | |||
75 | static void rsrc_card_shutdown(struct snd_pcm_substream *substream) | ||
76 | { | ||
77 | struct snd_soc_pcm_runtime *rtd = substream->private_data; | ||
78 | struct rsrc_card_priv *priv = snd_soc_card_get_drvdata(rtd->card); | ||
79 | struct asoc_simple_dai *dai_props = | ||
80 | rsrc_priv_to_props(priv, rtd->num); | ||
81 | |||
82 | clk_disable_unprepare(dai_props->clk); | ||
83 | } | ||
84 | |||
85 | static struct snd_soc_ops rsrc_card_ops = { | ||
86 | .startup = rsrc_card_startup, | ||
87 | .shutdown = rsrc_card_shutdown, | ||
88 | }; | ||
89 | |||
90 | static int rsrc_card_dai_init(struct snd_soc_pcm_runtime *rtd) | ||
91 | { | ||
92 | struct rsrc_card_priv *priv = snd_soc_card_get_drvdata(rtd->card); | ||
93 | struct snd_soc_dai *dai; | ||
94 | struct snd_soc_dai_link *dai_link; | ||
95 | struct asoc_simple_dai *dai_props; | ||
96 | int num = rtd->num; | ||
97 | int ret; | ||
98 | |||
99 | dai_link = rsrc_priv_to_link(priv, num); | ||
100 | dai_props = rsrc_priv_to_props(priv, num); | ||
101 | dai = dai_link->dynamic ? | ||
102 | rtd->cpu_dai : | ||
103 | rtd->codec_dai; | ||
104 | |||
105 | if (dai_props->sysclk) { | ||
106 | ret = snd_soc_dai_set_sysclk(dai, 0, dai_props->sysclk, 0); | ||
107 | if (ret && ret != -ENOTSUPP) { | ||
108 | dev_err(dai->dev, "set_sysclk error\n"); | ||
109 | goto err; | ||
110 | } | ||
111 | } | ||
112 | |||
113 | if (dai_props->slots) { | ||
114 | ret = snd_soc_dai_set_tdm_slot(dai, | ||
115 | dai_props->tx_slot_mask, | ||
116 | dai_props->rx_slot_mask, | ||
117 | dai_props->slots, | ||
118 | dai_props->slot_width); | ||
119 | if (ret && ret != -ENOTSUPP) { | ||
120 | dev_err(dai->dev, "set_tdm_slot error\n"); | ||
121 | goto err; | ||
122 | } | ||
123 | } | ||
124 | |||
125 | ret = 0; | ||
126 | |||
127 | err: | ||
128 | return ret; | ||
129 | } | ||
130 | |||
131 | static int rsrc_card_be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd, | ||
132 | struct snd_pcm_hw_params *params) | ||
133 | { | ||
134 | struct rsrc_card_priv *priv = snd_soc_card_get_drvdata(rtd->card); | ||
135 | struct snd_interval *rate = hw_param_interval(params, | ||
136 | SNDRV_PCM_HW_PARAM_RATE); | ||
137 | struct snd_interval *channels = hw_param_interval(params, | ||
138 | SNDRV_PCM_HW_PARAM_CHANNELS); | ||
139 | |||
140 | if (priv->convert_rate) | ||
141 | rate->min = | ||
142 | rate->max = priv->convert_rate; | ||
143 | |||
144 | if (priv->convert_channels) | ||
145 | channels->min = | ||
146 | channels->max = priv->convert_channels; | ||
147 | |||
148 | return 0; | ||
149 | } | ||
150 | |||
151 | static int rsrc_card_parse_links(struct device_node *np, | ||
152 | struct rsrc_card_priv *priv, | ||
153 | int idx, bool is_fe) | ||
154 | { | ||
155 | struct device *dev = rsrc_priv_to_dev(priv); | ||
156 | struct snd_soc_dai_link *dai_link = rsrc_priv_to_link(priv, idx); | ||
157 | struct asoc_simple_dai *dai_props = rsrc_priv_to_props(priv, idx); | ||
158 | struct of_phandle_args args; | ||
159 | int ret; | ||
160 | |||
161 | /* | ||
162 | * Get node via "sound-dai = <&phandle port>" | ||
163 | * it will be used as xxx_of_node on soc_bind_dai_link() | ||
164 | */ | ||
165 | ret = of_parse_phandle_with_args(np, "sound-dai", | ||
166 | "#sound-dai-cells", 0, &args); | ||
167 | if (ret) | ||
168 | return ret; | ||
169 | |||
170 | /* Parse TDM slot */ | ||
171 | ret = snd_soc_of_parse_tdm_slot(np, | ||
172 | &dai_props->tx_slot_mask, | ||
173 | &dai_props->rx_slot_mask, | ||
174 | &dai_props->slots, | ||
175 | &dai_props->slot_width); | ||
176 | if (ret) | ||
177 | return ret; | ||
178 | |||
179 | if (is_fe) { | ||
180 | /* BE is dummy */ | ||
181 | dai_link->codec_of_node = NULL; | ||
182 | dai_link->codec_dai_name = "snd-soc-dummy-dai"; | ||
183 | dai_link->codec_name = "snd-soc-dummy"; | ||
184 | |||
185 | /* FE settings */ | ||
186 | dai_link->dynamic = 1; | ||
187 | dai_link->dpcm_merged_format = 1; | ||
188 | dai_link->cpu_of_node = args.np; | ||
189 | ret = snd_soc_of_get_dai_name(np, &dai_link->cpu_dai_name); | ||
190 | if (ret < 0) | ||
191 | return ret; | ||
192 | |||
193 | ret = asoc_simple_card_set_dailink_name(dev, dai_link, | ||
194 | "fe.%s", | ||
195 | dai_link->cpu_dai_name); | ||
196 | if (ret < 0) | ||
197 | return ret; | ||
198 | |||
199 | /* | ||
200 | * In soc_bind_dai_link() will check cpu name after | ||
201 | * of_node matching if dai_link has cpu_dai_name. | ||
202 | * but, it will never match if name was created by | ||
203 | * fmt_single_name() remove cpu_dai_name if cpu_args | ||
204 | * was 0. See: | ||
205 | * fmt_single_name() | ||
206 | * fmt_multiple_name() | ||
207 | */ | ||
208 | if (!args.args_count) | ||
209 | dai_link->cpu_dai_name = NULL; | ||
210 | } else { | ||
211 | const struct rsrc_card_of_data *of_data; | ||
212 | |||
213 | of_data = of_device_get_match_data(dev); | ||
214 | |||
215 | /* FE is dummy */ | ||
216 | dai_link->cpu_of_node = NULL; | ||
217 | dai_link->cpu_dai_name = "snd-soc-dummy-dai"; | ||
218 | dai_link->cpu_name = "snd-soc-dummy"; | ||
219 | |||
220 | /* BE settings */ | ||
221 | dai_link->no_pcm = 1; | ||
222 | dai_link->be_hw_params_fixup = rsrc_card_be_hw_params_fixup; | ||
223 | dai_link->codec_of_node = args.np; | ||
224 | ret = snd_soc_of_get_dai_name(np, &dai_link->codec_dai_name); | ||
225 | if (ret < 0) | ||
226 | return ret; | ||
227 | |||
228 | ret = asoc_simple_card_set_dailink_name(dev, dai_link, | ||
229 | "be.%s", | ||
230 | dai_link->codec_dai_name); | ||
231 | if (ret < 0) | ||
232 | return ret; | ||
233 | |||
234 | /* additional name prefix */ | ||
235 | if (of_data) { | ||
236 | priv->codec_conf.of_node = dai_link->codec_of_node; | ||
237 | priv->codec_conf.name_prefix = of_data->prefix; | ||
238 | } else { | ||
239 | snd_soc_of_parse_audio_prefix(&priv->snd_card, | ||
240 | &priv->codec_conf, | ||
241 | dai_link->codec_of_node, | ||
242 | "audio-prefix"); | ||
243 | } | ||
244 | } | ||
245 | |||
246 | /* Simple Card assumes platform == cpu */ | ||
247 | dai_link->platform_of_node = dai_link->cpu_of_node; | ||
248 | dai_link->dpcm_playback = 1; | ||
249 | dai_link->dpcm_capture = 1; | ||
250 | dai_link->ops = &rsrc_card_ops; | ||
251 | dai_link->init = rsrc_card_dai_init; | ||
252 | |||
253 | return 0; | ||
254 | } | ||
255 | |||
256 | static int rsrc_card_parse_clk(struct device_node *np, | ||
257 | struct rsrc_card_priv *priv, | ||
258 | int idx, bool is_fe) | ||
259 | { | ||
260 | struct snd_soc_dai_link *dai_link = rsrc_priv_to_link(priv, idx); | ||
261 | struct asoc_simple_dai *dai_props = rsrc_priv_to_props(priv, idx); | ||
262 | struct clk *clk; | ||
263 | struct device_node *of_np = is_fe ? dai_link->cpu_of_node : | ||
264 | dai_link->codec_of_node; | ||
265 | u32 val; | ||
266 | |||
267 | /* | ||
268 | * Parse dai->sysclk come from "clocks = <&xxx>" | ||
269 | * (if system has common clock) | ||
270 | * or "system-clock-frequency = <xxx>" | ||
271 | * or device's module clock. | ||
272 | */ | ||
273 | if (of_property_read_bool(np, "clocks")) { | ||
274 | clk = of_clk_get(np, 0); | ||
275 | if (IS_ERR(clk)) | ||
276 | return PTR_ERR(clk); | ||
277 | |||
278 | dai_props->sysclk = clk_get_rate(clk); | ||
279 | dai_props->clk = clk; | ||
280 | } else if (!of_property_read_u32(np, "system-clock-frequency", &val)) { | ||
281 | dai_props->sysclk = val; | ||
282 | } else { | ||
283 | clk = of_clk_get(of_np, 0); | ||
284 | if (!IS_ERR(clk)) | ||
285 | dai_props->sysclk = clk_get_rate(clk); | ||
286 | } | ||
287 | |||
288 | return 0; | ||
289 | } | ||
290 | |||
291 | static int rsrc_card_dai_sub_link_of(struct device_node *node, | ||
292 | struct device_node *np, | ||
293 | struct rsrc_card_priv *priv, | ||
294 | int idx, bool is_fe) | ||
295 | { | ||
296 | struct device *dev = rsrc_priv_to_dev(priv); | ||
297 | struct snd_soc_dai_link *dai_link = rsrc_priv_to_link(priv, idx); | ||
298 | struct asoc_simple_dai *dai_props = rsrc_priv_to_props(priv, idx); | ||
299 | int ret; | ||
300 | |||
301 | ret = rsrc_card_parse_links(np, priv, idx, is_fe); | ||
302 | if (ret < 0) | ||
303 | return ret; | ||
304 | |||
305 | ret = rsrc_card_parse_clk(np, priv, idx, is_fe); | ||
306 | if (ret < 0) | ||
307 | return ret; | ||
308 | |||
309 | dev_dbg(dev, "\t%s / %04x / %d\n", | ||
310 | dai_link->name, | ||
311 | dai_link->dai_fmt, | ||
312 | dai_props->sysclk); | ||
313 | |||
314 | return ret; | ||
315 | } | ||
316 | |||
317 | static int rsrc_card_dai_link_of(struct device_node *node, | ||
318 | struct rsrc_card_priv *priv) | ||
319 | { | ||
320 | struct device *dev = rsrc_priv_to_dev(priv); | ||
321 | struct snd_soc_dai_link *dai_link; | ||
322 | struct device_node *np; | ||
323 | unsigned int daifmt = 0; | ||
324 | int ret, i; | ||
325 | bool is_fe; | ||
326 | |||
327 | /* find 1st codec */ | ||
328 | i = 0; | ||
329 | for_each_child_of_node(node, np) { | ||
330 | dai_link = rsrc_priv_to_link(priv, i); | ||
331 | |||
332 | if (strcmp(np->name, "codec") == 0) { | ||
333 | ret = asoc_simple_card_parse_daifmt(dev, node, np, | ||
334 | NULL, &daifmt); | ||
335 | if (ret < 0) | ||
336 | return ret; | ||
337 | break; | ||
338 | } | ||
339 | i++; | ||
340 | } | ||
341 | |||
342 | i = 0; | ||
343 | for_each_child_of_node(node, np) { | ||
344 | dai_link = rsrc_priv_to_link(priv, i); | ||
345 | dai_link->dai_fmt = daifmt; | ||
346 | |||
347 | is_fe = false; | ||
348 | if (strcmp(np->name, "cpu") == 0) | ||
349 | is_fe = true; | ||
350 | |||
351 | ret = rsrc_card_dai_sub_link_of(node, np, priv, i, is_fe); | ||
352 | if (ret < 0) | ||
353 | return ret; | ||
354 | i++; | ||
355 | } | ||
356 | |||
357 | return 0; | ||
358 | } | ||
359 | |||
360 | static int rsrc_card_parse_of(struct device_node *node, | ||
361 | struct rsrc_card_priv *priv, | ||
362 | struct device *dev) | ||
363 | { | ||
364 | const struct rsrc_card_of_data *of_data = of_device_get_match_data(dev); | ||
365 | struct asoc_simple_dai *props; | ||
366 | struct snd_soc_dai_link *links; | ||
367 | int ret; | ||
368 | int num; | ||
369 | |||
370 | if (!node) | ||
371 | return -EINVAL; | ||
372 | |||
373 | num = of_get_child_count(node); | ||
374 | props = devm_kzalloc(dev, sizeof(*props) * num, GFP_KERNEL); | ||
375 | links = devm_kzalloc(dev, sizeof(*links) * num, GFP_KERNEL); | ||
376 | if (!props || !links) | ||
377 | return -ENOMEM; | ||
378 | |||
379 | priv->dai_props = props; | ||
380 | priv->dai_link = links; | ||
381 | |||
382 | /* Init snd_soc_card */ | ||
383 | priv->snd_card.owner = THIS_MODULE; | ||
384 | priv->snd_card.dev = dev; | ||
385 | priv->snd_card.dai_link = priv->dai_link; | ||
386 | priv->snd_card.num_links = num; | ||
387 | priv->snd_card.codec_conf = &priv->codec_conf; | ||
388 | priv->snd_card.num_configs = 1; | ||
389 | |||
390 | if (of_data) { | ||
391 | priv->snd_card.of_dapm_routes = of_data->routes; | ||
392 | priv->snd_card.num_of_dapm_routes = of_data->num_routes; | ||
393 | } else { | ||
394 | snd_soc_of_parse_audio_routing(&priv->snd_card, | ||
395 | "audio-routing"); | ||
396 | } | ||
397 | |||
398 | /* sampling rate convert */ | ||
399 | of_property_read_u32(node, "convert-rate", &priv->convert_rate); | ||
400 | |||
401 | /* channels transfer */ | ||
402 | of_property_read_u32(node, "convert-channels", &priv->convert_channels); | ||
403 | |||
404 | dev_dbg(dev, "New rsrc-audio-card: %s\n", | ||
405 | priv->snd_card.name ? priv->snd_card.name : ""); | ||
406 | dev_dbg(dev, "SRC : convert_rate %d\n", priv->convert_rate); | ||
407 | dev_dbg(dev, "CTU : convert_channels %d\n", priv->convert_channels); | ||
408 | |||
409 | ret = rsrc_card_dai_link_of(node, priv); | ||
410 | if (ret < 0) | ||
411 | return ret; | ||
412 | |||
413 | ret = asoc_simple_card_parse_card_name(&priv->snd_card, "card-"); | ||
414 | if (ret < 0) | ||
415 | return ret; | ||
416 | |||
417 | return 0; | ||
418 | } | ||
419 | |||
420 | /* Decrease the reference count of the device nodes */ | ||
421 | static int rsrc_card_unref(struct snd_soc_card *card) | ||
422 | { | ||
423 | struct snd_soc_dai_link *dai_link; | ||
424 | int num_links; | ||
425 | |||
426 | for (num_links = 0, dai_link = card->dai_link; | ||
427 | num_links < card->num_links; | ||
428 | num_links++, dai_link++) { | ||
429 | of_node_put(dai_link->cpu_of_node); | ||
430 | of_node_put(dai_link->codec_of_node); | ||
431 | } | ||
432 | return 0; | ||
433 | } | ||
434 | |||
435 | static int rsrc_card_probe(struct platform_device *pdev) | ||
436 | { | ||
437 | struct rsrc_card_priv *priv; | ||
438 | struct device_node *np = pdev->dev.of_node; | ||
439 | struct device *dev = &pdev->dev; | ||
440 | int ret; | ||
441 | |||
442 | /* Allocate the private data */ | ||
443 | priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); | ||
444 | if (!priv) | ||
445 | return -ENOMEM; | ||
446 | |||
447 | ret = rsrc_card_parse_of(np, priv, dev); | ||
448 | if (ret < 0) { | ||
449 | if (ret != -EPROBE_DEFER) | ||
450 | dev_err(dev, "parse error %d\n", ret); | ||
451 | goto err; | ||
452 | } | ||
453 | |||
454 | snd_soc_card_set_drvdata(&priv->snd_card, priv); | ||
455 | |||
456 | ret = devm_snd_soc_register_card(&pdev->dev, &priv->snd_card); | ||
457 | if (ret >= 0) | ||
458 | return ret; | ||
459 | err: | ||
460 | rsrc_card_unref(&priv->snd_card); | ||
461 | |||
462 | return ret; | ||
463 | } | ||
464 | |||
465 | static int rsrc_card_remove(struct platform_device *pdev) | ||
466 | { | ||
467 | struct snd_soc_card *card = platform_get_drvdata(pdev); | ||
468 | |||
469 | return rsrc_card_unref(card); | ||
470 | } | ||
471 | |||
472 | static struct platform_driver rsrc_card = { | ||
473 | .driver = { | ||
474 | .name = "renesas-src-audio-card", | ||
475 | .of_match_table = rsrc_card_of_match, | ||
476 | }, | ||
477 | .probe = rsrc_card_probe, | ||
478 | .remove = rsrc_card_remove, | ||
479 | }; | ||
480 | |||
481 | module_platform_driver(rsrc_card); | ||
482 | |||
483 | MODULE_ALIAS("platform:renesas-src-audio-card"); | ||
484 | MODULE_LICENSE("GPL"); | ||
485 | MODULE_DESCRIPTION("Renesas Sampling Rate Convert Sound Card"); | ||
486 | MODULE_AUTHOR("Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>"); | ||
diff --git a/sound/soc/sh/rcar/ssi.c b/sound/soc/sh/rcar/ssi.c index 5f848f054745..6cb6db005fc4 100644 --- a/sound/soc/sh/rcar/ssi.c +++ b/sound/soc/sh/rcar/ssi.c | |||
@@ -928,7 +928,7 @@ int rsnd_ssi_probe(struct rsnd_priv *priv) | |||
928 | } | 928 | } |
929 | 929 | ||
930 | ops = &rsnd_ssi_non_ops; | 930 | ops = &rsnd_ssi_non_ops; |
931 | if (of_get_property(np, "pio-transfer", NULL)) | 931 | if (of_property_read_bool(np, "pio-transfer")) |
932 | ops = &rsnd_ssi_pio_ops; | 932 | ops = &rsnd_ssi_pio_ops; |
933 | else | 933 | else |
934 | ops = &rsnd_ssi_dma_ops; | 934 | ops = &rsnd_ssi_dma_ops; |
diff --git a/sound/soc/soc-ac97.c b/sound/soc/soc-ac97.c index bc4a55bb3fd9..6c8b0b0c56ec 100644 --- a/sound/soc/soc-ac97.c +++ b/sound/soc/soc-ac97.c | |||
@@ -116,7 +116,7 @@ static int snd_soc_ac97_gpio_direction_out(struct gpio_chip *chip, | |||
116 | return snd_soc_update_bits(codec, AC97_GPIO_CFG, 1 << offset, 0); | 116 | return snd_soc_update_bits(codec, AC97_GPIO_CFG, 1 << offset, 0); |
117 | } | 117 | } |
118 | 118 | ||
119 | static struct gpio_chip snd_soc_ac97_gpio_chip = { | 119 | static const struct gpio_chip snd_soc_ac97_gpio_chip = { |
120 | .label = "snd_soc_ac97", | 120 | .label = "snd_soc_ac97", |
121 | .owner = THIS_MODULE, | 121 | .owner = THIS_MODULE, |
122 | .request = snd_soc_ac97_gpio_request, | 122 | .request = snd_soc_ac97_gpio_request, |
diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c index 4afa8dba5e98..c0bbcd903261 100644 --- a/sound/soc/soc-core.c +++ b/sound/soc/soc-core.c | |||
@@ -3332,19 +3332,6 @@ int snd_soc_register_codec(struct device *dev, | |||
3332 | if (ret) | 3332 | if (ret) |
3333 | goto err_free; | 3333 | goto err_free; |
3334 | 3334 | ||
3335 | if (codec_drv->controls) { | ||
3336 | codec->component.controls = codec_drv->controls; | ||
3337 | codec->component.num_controls = codec_drv->num_controls; | ||
3338 | } | ||
3339 | if (codec_drv->dapm_widgets) { | ||
3340 | codec->component.dapm_widgets = codec_drv->dapm_widgets; | ||
3341 | codec->component.num_dapm_widgets = codec_drv->num_dapm_widgets; | ||
3342 | } | ||
3343 | if (codec_drv->dapm_routes) { | ||
3344 | codec->component.dapm_routes = codec_drv->dapm_routes; | ||
3345 | codec->component.num_dapm_routes = codec_drv->num_dapm_routes; | ||
3346 | } | ||
3347 | |||
3348 | if (codec_drv->probe) | 3335 | if (codec_drv->probe) |
3349 | codec->component.probe = snd_soc_codec_drv_probe; | 3336 | codec->component.probe = snd_soc_codec_drv_probe; |
3350 | if (codec_drv->remove) | 3337 | if (codec_drv->remove) |
@@ -3732,7 +3719,7 @@ unsigned int snd_soc_of_parse_daifmt(struct device_node *np, | |||
3732 | * SND_SOC_DAIFMT_CLOCK_MASK area | 3719 | * SND_SOC_DAIFMT_CLOCK_MASK area |
3733 | */ | 3720 | */ |
3734 | snprintf(prop, sizeof(prop), "%scontinuous-clock", prefix); | 3721 | snprintf(prop, sizeof(prop), "%scontinuous-clock", prefix); |
3735 | if (of_get_property(np, prop, NULL)) | 3722 | if (of_property_read_bool(np, prop)) |
3736 | format |= SND_SOC_DAIFMT_CONT; | 3723 | format |= SND_SOC_DAIFMT_CONT; |
3737 | else | 3724 | else |
3738 | format |= SND_SOC_DAIFMT_GATED; | 3725 | format |= SND_SOC_DAIFMT_GATED; |
diff --git a/sound/soc/soc-dapm.c b/sound/soc/soc-dapm.c index d908ff8f9755..3bbe32ee4630 100644 --- a/sound/soc/soc-dapm.c +++ b/sound/soc/soc-dapm.c | |||
@@ -823,6 +823,7 @@ static int dapm_create_or_share_kcontrol(struct snd_soc_dapm_widget *w, | |||
823 | case snd_soc_dapm_switch: | 823 | case snd_soc_dapm_switch: |
824 | case snd_soc_dapm_mixer: | 824 | case snd_soc_dapm_mixer: |
825 | case snd_soc_dapm_pga: | 825 | case snd_soc_dapm_pga: |
826 | case snd_soc_dapm_out_drv: | ||
826 | wname_in_long_name = true; | 827 | wname_in_long_name = true; |
827 | kcname_in_long_name = true; | 828 | kcname_in_long_name = true; |
828 | break; | 829 | break; |
@@ -1169,7 +1170,7 @@ static int is_connected_input_ep(struct snd_soc_dapm_widget *widget, | |||
1169 | * @custom_stop_condition: (optional) a function meant to stop the widget graph | 1170 | * @custom_stop_condition: (optional) a function meant to stop the widget graph |
1170 | * walk based on custom logic. | 1171 | * walk based on custom logic. |
1171 | * | 1172 | * |
1172 | * Queries DAPM graph as to whether an valid audio stream path exists for | 1173 | * Queries DAPM graph as to whether a valid audio stream path exists for |
1173 | * the initial stream specified by name. This takes into account | 1174 | * the initial stream specified by name. This takes into account |
1174 | * current mixer and mux kcontrol settings. Creates list of valid widgets. | 1175 | * current mixer and mux kcontrol settings. Creates list of valid widgets. |
1175 | * | 1176 | * |
@@ -1294,8 +1295,7 @@ static int dapm_widget_power_check(struct snd_soc_dapm_widget *w) | |||
1294 | return w->new_power; | 1295 | return w->new_power; |
1295 | } | 1296 | } |
1296 | 1297 | ||
1297 | /* Generic check to see if a widget should be powered. | 1298 | /* Generic check to see if a widget should be powered. */ |
1298 | */ | ||
1299 | static int dapm_generic_check_power(struct snd_soc_dapm_widget *w) | 1299 | static int dapm_generic_check_power(struct snd_soc_dapm_widget *w) |
1300 | { | 1300 | { |
1301 | int in, out; | 1301 | int in, out; |
@@ -1646,7 +1646,7 @@ static void dapm_pre_sequence_async(void *data, async_cookie_t cookie) | |||
1646 | struct snd_soc_dapm_context *d = data; | 1646 | struct snd_soc_dapm_context *d = data; |
1647 | int ret; | 1647 | int ret; |
1648 | 1648 | ||
1649 | /* If we're off and we're not supposed to be go into STANDBY */ | 1649 | /* If we're off and we're not supposed to go into STANDBY */ |
1650 | if (d->bias_level == SND_SOC_BIAS_OFF && | 1650 | if (d->bias_level == SND_SOC_BIAS_OFF && |
1651 | d->target_bias_level != SND_SOC_BIAS_OFF) { | 1651 | d->target_bias_level != SND_SOC_BIAS_OFF) { |
1652 | if (d->dev) | 1652 | if (d->dev) |
@@ -1798,7 +1798,7 @@ static bool dapm_idle_bias_off(struct snd_soc_dapm_context *dapm) | |||
1798 | * A complete path is a route that has valid endpoints i.e.:- | 1798 | * A complete path is a route that has valid endpoints i.e.:- |
1799 | * | 1799 | * |
1800 | * o DAC to output pin. | 1800 | * o DAC to output pin. |
1801 | * o Input Pin to ADC. | 1801 | * o Input pin to ADC. |
1802 | * o Input pin to Output pin (bypass, sidetone) | 1802 | * o Input pin to Output pin (bypass, sidetone) |
1803 | * o DAC to ADC (loopback). | 1803 | * o DAC to ADC (loopback). |
1804 | */ | 1804 | */ |
@@ -2114,7 +2114,7 @@ static inline void dapm_debugfs_cleanup(struct snd_soc_dapm_context *dapm) | |||
2114 | * soc_dapm_connect_path() - Connects or disconnects a path | 2114 | * soc_dapm_connect_path() - Connects or disconnects a path |
2115 | * @path: The path to update | 2115 | * @path: The path to update |
2116 | * @connect: The new connect state of the path. True if the path is connected, | 2116 | * @connect: The new connect state of the path. True if the path is connected, |
2117 | * false if it is disconneted. | 2117 | * false if it is disconnected. |
2118 | * @reason: The reason why the path changed (for debugging only) | 2118 | * @reason: The reason why the path changed (for debugging only) |
2119 | */ | 2119 | */ |
2120 | static void soc_dapm_connect_path(struct snd_soc_dapm_path *path, | 2120 | static void soc_dapm_connect_path(struct snd_soc_dapm_path *path, |
@@ -2233,7 +2233,7 @@ static ssize_t dapm_widget_show_component(struct snd_soc_component *cmpnt, | |||
2233 | if (w->dapm != dapm) | 2233 | if (w->dapm != dapm) |
2234 | continue; | 2234 | continue; |
2235 | 2235 | ||
2236 | /* only display widgets that burnm power */ | 2236 | /* only display widgets that burn power */ |
2237 | switch (w->id) { | 2237 | switch (w->id) { |
2238 | case snd_soc_dapm_hp: | 2238 | case snd_soc_dapm_hp: |
2239 | case snd_soc_dapm_mic: | 2239 | case snd_soc_dapm_mic: |
@@ -2461,7 +2461,7 @@ static void dapm_update_widget_flags(struct snd_soc_dapm_widget *w) | |||
2461 | 2461 | ||
2462 | switch (w->id) { | 2462 | switch (w->id) { |
2463 | case snd_soc_dapm_input: | 2463 | case snd_soc_dapm_input: |
2464 | /* On a fully routed card a input is never a source */ | 2464 | /* On a fully routed card an input is never a source */ |
2465 | if (w->dapm->card->fully_routed) | 2465 | if (w->dapm->card->fully_routed) |
2466 | return; | 2466 | return; |
2467 | ep = SND_SOC_DAPM_EP_SOURCE; | 2467 | ep = SND_SOC_DAPM_EP_SOURCE; |
@@ -3049,6 +3049,9 @@ int snd_soc_dapm_get_volsw(struct snd_kcontrol *kcontrol, | |||
3049 | } | 3049 | } |
3050 | mutex_unlock(&card->dapm_mutex); | 3050 | mutex_unlock(&card->dapm_mutex); |
3051 | 3051 | ||
3052 | if (ret) | ||
3053 | return ret; | ||
3054 | |||
3052 | if (invert) | 3055 | if (invert) |
3053 | ucontrol->value.integer.value[0] = max - val; | 3056 | ucontrol->value.integer.value[0] = max - val; |
3054 | else | 3057 | else |
@@ -3200,7 +3203,7 @@ int snd_soc_dapm_put_enum_double(struct snd_kcontrol *kcontrol, | |||
3200 | if (e->shift_l != e->shift_r) { | 3203 | if (e->shift_l != e->shift_r) { |
3201 | if (item[1] > e->items) | 3204 | if (item[1] > e->items) |
3202 | return -EINVAL; | 3205 | return -EINVAL; |
3203 | val |= snd_soc_enum_item_to_val(e, item[1]) << e->shift_l; | 3206 | val |= snd_soc_enum_item_to_val(e, item[1]) << e->shift_r; |
3204 | mask |= e->mask << e->shift_r; | 3207 | mask |= e->mask << e->shift_r; |
3205 | } | 3208 | } |
3206 | 3209 | ||
@@ -3445,7 +3448,7 @@ snd_soc_dapm_new_control_unlocked(struct snd_soc_dapm_context *dapm, | |||
3445 | w->endpoints[dir] = -1; | 3448 | w->endpoints[dir] = -1; |
3446 | } | 3449 | } |
3447 | 3450 | ||
3448 | /* machine layer set ups unconnected pins and insertions */ | 3451 | /* machine layer sets up unconnected pins and insertions */ |
3449 | w->connected = 1; | 3452 | w->connected = 1; |
3450 | return w; | 3453 | return w; |
3451 | } | 3454 | } |
diff --git a/sound/soc/soc-ops.c b/sound/soc/soc-ops.c index a513a34a51d2..9fc1a7bb8b95 100644 --- a/sound/soc/soc-ops.c +++ b/sound/soc/soc-ops.c | |||
@@ -77,7 +77,7 @@ int snd_soc_get_enum_double(struct snd_kcontrol *kcontrol, | |||
77 | item = snd_soc_enum_val_to_item(e, val); | 77 | item = snd_soc_enum_val_to_item(e, val); |
78 | ucontrol->value.enumerated.item[0] = item; | 78 | ucontrol->value.enumerated.item[0] = item; |
79 | if (e->shift_l != e->shift_r) { | 79 | if (e->shift_l != e->shift_r) { |
80 | val = (reg_val >> e->shift_l) & e->mask; | 80 | val = (reg_val >> e->shift_r) & e->mask; |
81 | item = snd_soc_enum_val_to_item(e, val); | 81 | item = snd_soc_enum_val_to_item(e, val); |
82 | ucontrol->value.enumerated.item[1] = item; | 82 | ucontrol->value.enumerated.item[1] = item; |
83 | } | 83 | } |
diff --git a/sound/soc/soc-pcm.c b/sound/soc/soc-pcm.c index 60d702f8b9f0..d56a16a0f6fa 100644 --- a/sound/soc/soc-pcm.c +++ b/sound/soc/soc-pcm.c | |||
@@ -1694,6 +1694,9 @@ static int dpcm_apply_symmetry(struct snd_pcm_substream *fe_substream, | |||
1694 | struct snd_soc_pcm_runtime *rtd = be_substream->private_data; | 1694 | struct snd_soc_pcm_runtime *rtd = be_substream->private_data; |
1695 | int i; | 1695 | int i; |
1696 | 1696 | ||
1697 | if (rtd->dai_link->be_hw_params_fixup) | ||
1698 | continue; | ||
1699 | |||
1697 | if (soc_pcm_has_symmetry(be_substream)) | 1700 | if (soc_pcm_has_symmetry(be_substream)) |
1698 | be_substream->runtime->hw.info |= SNDRV_PCM_INFO_JOINT_DUPLEX; | 1701 | be_substream->runtime->hw.info |= SNDRV_PCM_INFO_JOINT_DUPLEX; |
1699 | 1702 | ||
@@ -1790,7 +1793,7 @@ int dpcm_be_dai_shutdown(struct snd_soc_pcm_runtime *fe, int stream) | |||
1790 | continue; | 1793 | continue; |
1791 | 1794 | ||
1792 | dev_dbg(be->dev, "ASoC: close BE %s\n", | 1795 | dev_dbg(be->dev, "ASoC: close BE %s\n", |
1793 | dpcm->fe->dai_link->name); | 1796 | be->dai_link->name); |
1794 | 1797 | ||
1795 | soc_pcm_close(be_substream); | 1798 | soc_pcm_close(be_substream); |
1796 | be_substream->runtime = NULL; | 1799 | be_substream->runtime = NULL; |
@@ -1856,7 +1859,7 @@ int dpcm_be_dai_hw_free(struct snd_soc_pcm_runtime *fe, int stream) | |||
1856 | continue; | 1859 | continue; |
1857 | 1860 | ||
1858 | dev_dbg(be->dev, "ASoC: hw_free BE %s\n", | 1861 | dev_dbg(be->dev, "ASoC: hw_free BE %s\n", |
1859 | dpcm->fe->dai_link->name); | 1862 | be->dai_link->name); |
1860 | 1863 | ||
1861 | soc_pcm_hw_free(be_substream); | 1864 | soc_pcm_hw_free(be_substream); |
1862 | 1865 | ||
@@ -1934,7 +1937,7 @@ int dpcm_be_dai_hw_params(struct snd_soc_pcm_runtime *fe, int stream) | |||
1934 | continue; | 1937 | continue; |
1935 | 1938 | ||
1936 | dev_dbg(be->dev, "ASoC: hw_params BE %s\n", | 1939 | dev_dbg(be->dev, "ASoC: hw_params BE %s\n", |
1937 | dpcm->fe->dai_link->name); | 1940 | be->dai_link->name); |
1938 | 1941 | ||
1939 | ret = soc_pcm_hw_params(be_substream, &dpcm->hw_params); | 1942 | ret = soc_pcm_hw_params(be_substream, &dpcm->hw_params); |
1940 | if (ret < 0) { | 1943 | if (ret < 0) { |
@@ -2014,7 +2017,7 @@ static int dpcm_do_trigger(struct snd_soc_dpcm *dpcm, | |||
2014 | int ret; | 2017 | int ret; |
2015 | 2018 | ||
2016 | dev_dbg(dpcm->be->dev, "ASoC: trigger BE %s cmd %d\n", | 2019 | dev_dbg(dpcm->be->dev, "ASoC: trigger BE %s cmd %d\n", |
2017 | dpcm->fe->dai_link->name, cmd); | 2020 | dpcm->be->dai_link->name, cmd); |
2018 | 2021 | ||
2019 | ret = soc_pcm_trigger(substream, cmd); | 2022 | ret = soc_pcm_trigger(substream, cmd); |
2020 | if (ret < 0) | 2023 | if (ret < 0) |
@@ -2229,7 +2232,7 @@ int dpcm_be_dai_prepare(struct snd_soc_pcm_runtime *fe, int stream) | |||
2229 | continue; | 2232 | continue; |
2230 | 2233 | ||
2231 | dev_dbg(be->dev, "ASoC: prepare BE %s\n", | 2234 | dev_dbg(be->dev, "ASoC: prepare BE %s\n", |
2232 | dpcm->fe->dai_link->name); | 2235 | be->dai_link->name); |
2233 | 2236 | ||
2234 | ret = soc_pcm_prepare(be_substream); | 2237 | ret = soc_pcm_prepare(be_substream); |
2235 | if (ret < 0) { | 2238 | if (ret < 0) { |
diff --git a/sound/soc/soc-topology.c b/sound/soc/soc-topology.c index ee7f15aa46fc..6b05047a4134 100644 --- a/sound/soc/soc-topology.c +++ b/sound/soc/soc-topology.c | |||
@@ -48,9 +48,10 @@ | |||
48 | #define SOC_TPLG_PASS_PCM_DAI 4 | 48 | #define SOC_TPLG_PASS_PCM_DAI 4 |
49 | #define SOC_TPLG_PASS_GRAPH 5 | 49 | #define SOC_TPLG_PASS_GRAPH 5 |
50 | #define SOC_TPLG_PASS_PINS 6 | 50 | #define SOC_TPLG_PASS_PINS 6 |
51 | #define SOC_TPLG_PASS_BE_DAI 7 | ||
51 | 52 | ||
52 | #define SOC_TPLG_PASS_START SOC_TPLG_PASS_MANIFEST | 53 | #define SOC_TPLG_PASS_START SOC_TPLG_PASS_MANIFEST |
53 | #define SOC_TPLG_PASS_END SOC_TPLG_PASS_PINS | 54 | #define SOC_TPLG_PASS_END SOC_TPLG_PASS_BE_DAI |
54 | 55 | ||
55 | struct soc_tplg { | 56 | struct soc_tplg { |
56 | const struct firmware *fw; | 57 | const struct firmware *fw; |
@@ -1475,6 +1476,7 @@ widget: | |||
1475 | if (widget == NULL) { | 1476 | if (widget == NULL) { |
1476 | dev_err(tplg->dev, "ASoC: failed to create widget %s controls\n", | 1477 | dev_err(tplg->dev, "ASoC: failed to create widget %s controls\n", |
1477 | w->name); | 1478 | w->name); |
1479 | ret = -ENOMEM; | ||
1478 | goto hdr_err; | 1480 | goto hdr_err; |
1479 | } | 1481 | } |
1480 | 1482 | ||
@@ -1554,6 +1556,25 @@ static void set_stream_info(struct snd_soc_pcm_stream *stream, | |||
1554 | stream->rate_min = caps->rate_min; | 1556 | stream->rate_min = caps->rate_min; |
1555 | stream->rate_max = caps->rate_max; | 1557 | stream->rate_max = caps->rate_max; |
1556 | stream->formats = caps->formats; | 1558 | stream->formats = caps->formats; |
1559 | stream->sig_bits = caps->sig_bits; | ||
1560 | } | ||
1561 | |||
1562 | static void set_dai_flags(struct snd_soc_dai_driver *dai_drv, | ||
1563 | unsigned int flag_mask, unsigned int flags) | ||
1564 | { | ||
1565 | if (flag_mask & SND_SOC_TPLG_DAI_FLGBIT_SYMMETRIC_RATES) | ||
1566 | dai_drv->symmetric_rates = | ||
1567 | flags & SND_SOC_TPLG_DAI_FLGBIT_SYMMETRIC_RATES ? 1 : 0; | ||
1568 | |||
1569 | if (flag_mask & SND_SOC_TPLG_DAI_FLGBIT_SYMMETRIC_CHANNELS) | ||
1570 | dai_drv->symmetric_channels = | ||
1571 | flags & SND_SOC_TPLG_DAI_FLGBIT_SYMMETRIC_CHANNELS ? | ||
1572 | 1 : 0; | ||
1573 | |||
1574 | if (flag_mask & SND_SOC_TPLG_DAI_FLGBIT_SYMMETRIC_SAMPLEBITS) | ||
1575 | dai_drv->symmetric_samplebits = | ||
1576 | flags & SND_SOC_TPLG_DAI_FLGBIT_SYMMETRIC_SAMPLEBITS ? | ||
1577 | 1 : 0; | ||
1557 | } | 1578 | } |
1558 | 1579 | ||
1559 | static int soc_tplg_dai_create(struct soc_tplg *tplg, | 1580 | static int soc_tplg_dai_create(struct soc_tplg *tplg, |
@@ -1690,8 +1711,96 @@ static int soc_tplg_pcm_elems_load(struct soc_tplg *tplg, | |||
1690 | return 0; | 1711 | return 0; |
1691 | } | 1712 | } |
1692 | 1713 | ||
1714 | /* * | ||
1715 | * soc_tplg_be_dai_config - Find and configure an existing BE DAI. | ||
1716 | * @tplg: topology context | ||
1717 | * @be: topology BE DAI configs. | ||
1718 | * | ||
1719 | * The BE dai should already be registered by the platform driver. The | ||
1720 | * platform driver should specify the BE DAI name and ID for matching. | ||
1721 | */ | ||
1722 | static int soc_tplg_be_dai_config(struct soc_tplg *tplg, | ||
1723 | struct snd_soc_tplg_be_dai *be) | ||
1724 | { | ||
1725 | struct snd_soc_dai_link_component dai_component = {0}; | ||
1726 | struct snd_soc_dai *dai; | ||
1727 | struct snd_soc_dai_driver *dai_drv; | ||
1728 | struct snd_soc_pcm_stream *stream; | ||
1729 | struct snd_soc_tplg_stream_caps *caps; | ||
1730 | int ret; | ||
1731 | |||
1732 | dai_component.dai_name = be->dai_name; | ||
1733 | dai = snd_soc_find_dai(&dai_component); | ||
1734 | if (!dai) { | ||
1735 | dev_err(tplg->dev, "ASoC: BE DAI %s not registered\n", | ||
1736 | be->dai_name); | ||
1737 | return -EINVAL; | ||
1738 | } | ||
1739 | |||
1740 | if (be->dai_id != dai->id) { | ||
1741 | dev_err(tplg->dev, "ASoC: BE DAI %s id mismatch\n", | ||
1742 | be->dai_name); | ||
1743 | return -EINVAL; | ||
1744 | } | ||
1745 | |||
1746 | dai_drv = dai->driver; | ||
1747 | if (!dai_drv) | ||
1748 | return -EINVAL; | ||
1749 | |||
1750 | if (be->playback) { | ||
1751 | stream = &dai_drv->playback; | ||
1752 | caps = &be->caps[SND_SOC_TPLG_STREAM_PLAYBACK]; | ||
1753 | set_stream_info(stream, caps); | ||
1754 | } | ||
1755 | |||
1756 | if (be->capture) { | ||
1757 | stream = &dai_drv->capture; | ||
1758 | caps = &be->caps[SND_SOC_TPLG_STREAM_CAPTURE]; | ||
1759 | set_stream_info(stream, caps); | ||
1760 | } | ||
1761 | |||
1762 | if (be->flag_mask) | ||
1763 | set_dai_flags(dai_drv, be->flag_mask, be->flags); | ||
1764 | |||
1765 | /* pass control to component driver for optional further init */ | ||
1766 | ret = soc_tplg_dai_load(tplg, dai_drv); | ||
1767 | if (ret < 0) { | ||
1768 | dev_err(tplg->comp->dev, "ASoC: DAI loading failed\n"); | ||
1769 | return ret; | ||
1770 | } | ||
1771 | |||
1772 | return 0; | ||
1773 | } | ||
1774 | |||
1775 | static int soc_tplg_be_dai_elems_load(struct soc_tplg *tplg, | ||
1776 | struct snd_soc_tplg_hdr *hdr) | ||
1777 | { | ||
1778 | struct snd_soc_tplg_be_dai *be; | ||
1779 | int count = hdr->count; | ||
1780 | int i; | ||
1781 | |||
1782 | if (tplg->pass != SOC_TPLG_PASS_BE_DAI) | ||
1783 | return 0; | ||
1784 | |||
1785 | /* config the existing BE DAIs */ | ||
1786 | for (i = 0; i < count; i++) { | ||
1787 | be = (struct snd_soc_tplg_be_dai *)tplg->pos; | ||
1788 | if (be->size != sizeof(*be)) { | ||
1789 | dev_err(tplg->dev, "ASoC: invalid BE DAI size\n"); | ||
1790 | return -EINVAL; | ||
1791 | } | ||
1792 | |||
1793 | soc_tplg_be_dai_config(tplg, be); | ||
1794 | tplg->pos += (sizeof(*be) + be->priv.size); | ||
1795 | } | ||
1796 | |||
1797 | dev_dbg(tplg->dev, "ASoC: Configure %d BE DAIs\n", count); | ||
1798 | return 0; | ||
1799 | } | ||
1800 | |||
1801 | |||
1693 | static int soc_tplg_manifest_load(struct soc_tplg *tplg, | 1802 | static int soc_tplg_manifest_load(struct soc_tplg *tplg, |
1694 | struct snd_soc_tplg_hdr *hdr) | 1803 | struct snd_soc_tplg_hdr *hdr) |
1695 | { | 1804 | { |
1696 | struct snd_soc_tplg_manifest *manifest; | 1805 | struct snd_soc_tplg_manifest *manifest; |
1697 | 1806 | ||
@@ -1793,6 +1902,8 @@ static int soc_tplg_load_header(struct soc_tplg *tplg, | |||
1793 | return soc_tplg_dapm_widget_elems_load(tplg, hdr); | 1902 | return soc_tplg_dapm_widget_elems_load(tplg, hdr); |
1794 | case SND_SOC_TPLG_TYPE_PCM: | 1903 | case SND_SOC_TPLG_TYPE_PCM: |
1795 | return soc_tplg_pcm_elems_load(tplg, hdr); | 1904 | return soc_tplg_pcm_elems_load(tplg, hdr); |
1905 | case SND_SOC_TPLG_TYPE_BE_DAI: | ||
1906 | return soc_tplg_be_dai_elems_load(tplg, hdr); | ||
1796 | case SND_SOC_TPLG_TYPE_MANIFEST: | 1907 | case SND_SOC_TPLG_TYPE_MANIFEST: |
1797 | return soc_tplg_manifest_load(tplg, hdr); | 1908 | return soc_tplg_manifest_load(tplg, hdr); |
1798 | default: | 1909 | default: |
diff --git a/sound/soc/soc-utils.c b/sound/soc/soc-utils.c index 53dd085d3ee2..393e8f0fe2cc 100644 --- a/sound/soc/soc-utils.c +++ b/sound/soc/soc-utils.c | |||
@@ -80,7 +80,7 @@ static int dummy_dma_open(struct snd_pcm_substream *substream) | |||
80 | return 0; | 80 | return 0; |
81 | } | 81 | } |
82 | 82 | ||
83 | static struct snd_pcm_ops dummy_dma_ops = { | 83 | static const struct snd_pcm_ops dummy_dma_ops = { |
84 | .open = dummy_dma_open, | 84 | .open = dummy_dma_open, |
85 | .ioctl = snd_pcm_lib_ioctl, | 85 | .ioctl = snd_pcm_lib_ioctl, |
86 | }; | 86 | }; |
diff --git a/sound/soc/sti/sti_uniperif.c b/sound/soc/sti/sti_uniperif.c index 488ef4ed8fba..549fac349fa0 100644 --- a/sound/soc/sti/sti_uniperif.c +++ b/sound/soc/sti/sti_uniperif.c | |||
@@ -19,6 +19,84 @@ | |||
19 | #define UNIPERIF_MAX_FRAME_SZ 0x20 | 19 | #define UNIPERIF_MAX_FRAME_SZ 0x20 |
20 | #define UNIPERIF_ALLOWED_FRAME_SZ (0x08 | 0x10 | 0x18 | UNIPERIF_MAX_FRAME_SZ) | 20 | #define UNIPERIF_ALLOWED_FRAME_SZ (0x08 | 0x10 | 0x18 | UNIPERIF_MAX_FRAME_SZ) |
21 | 21 | ||
22 | struct sti_uniperiph_dev_data { | ||
23 | unsigned int id; /* Nb available player instances */ | ||
24 | unsigned int version; /* player IP version */ | ||
25 | unsigned int stream; | ||
26 | const char *dai_names; | ||
27 | enum uniperif_type type; | ||
28 | }; | ||
29 | |||
30 | static const struct sti_uniperiph_dev_data sti_uniplayer_hdmi = { | ||
31 | .id = 0, | ||
32 | .version = SND_ST_UNIPERIF_VERSION_UNI_PLR_TOP_1_0, | ||
33 | .stream = SNDRV_PCM_STREAM_PLAYBACK, | ||
34 | .dai_names = "Uni Player #0 (HDMI)", | ||
35 | .type = SND_ST_UNIPERIF_TYPE_HDMI | ||
36 | }; | ||
37 | |||
38 | static const struct sti_uniperiph_dev_data sti_uniplayer_pcm_out = { | ||
39 | .id = 1, | ||
40 | .version = SND_ST_UNIPERIF_VERSION_UNI_PLR_TOP_1_0, | ||
41 | .stream = SNDRV_PCM_STREAM_PLAYBACK, | ||
42 | .dai_names = "Uni Player #1 (PCM OUT)", | ||
43 | .type = SND_ST_UNIPERIF_TYPE_PCM | SND_ST_UNIPERIF_TYPE_TDM, | ||
44 | }; | ||
45 | |||
46 | static const struct sti_uniperiph_dev_data sti_uniplayer_dac = { | ||
47 | .id = 2, | ||
48 | .version = SND_ST_UNIPERIF_VERSION_UNI_PLR_TOP_1_0, | ||
49 | .stream = SNDRV_PCM_STREAM_PLAYBACK, | ||
50 | .dai_names = "Uni Player #2 (DAC)", | ||
51 | .type = SND_ST_UNIPERIF_TYPE_PCM, | ||
52 | }; | ||
53 | |||
54 | static const struct sti_uniperiph_dev_data sti_uniplayer_spdif = { | ||
55 | .id = 3, | ||
56 | .version = SND_ST_UNIPERIF_VERSION_UNI_PLR_TOP_1_0, | ||
57 | .stream = SNDRV_PCM_STREAM_PLAYBACK, | ||
58 | .dai_names = "Uni Player #3 (SPDIF)", | ||
59 | .type = SND_ST_UNIPERIF_TYPE_SPDIF | ||
60 | }; | ||
61 | |||
62 | static const struct sti_uniperiph_dev_data sti_unireader_pcm_in = { | ||
63 | .id = 0, | ||
64 | .version = SND_ST_UNIPERIF_VERSION_UNI_RDR_1_0, | ||
65 | .stream = SNDRV_PCM_STREAM_CAPTURE, | ||
66 | .dai_names = "Uni Reader #0 (PCM IN)", | ||
67 | .type = SND_ST_UNIPERIF_TYPE_PCM | SND_ST_UNIPERIF_TYPE_TDM, | ||
68 | }; | ||
69 | |||
70 | static const struct sti_uniperiph_dev_data sti_unireader_hdmi_in = { | ||
71 | .id = 1, | ||
72 | .version = SND_ST_UNIPERIF_VERSION_UNI_RDR_1_0, | ||
73 | .stream = SNDRV_PCM_STREAM_CAPTURE, | ||
74 | .dai_names = "Uni Reader #1 (HDMI IN)", | ||
75 | .type = SND_ST_UNIPERIF_TYPE_PCM, | ||
76 | }; | ||
77 | |||
78 | static const struct of_device_id snd_soc_sti_match[] = { | ||
79 | { .compatible = "st,stih407-uni-player-hdmi", | ||
80 | .data = &sti_uniplayer_hdmi | ||
81 | }, | ||
82 | { .compatible = "st,stih407-uni-player-pcm-out", | ||
83 | .data = &sti_uniplayer_pcm_out | ||
84 | }, | ||
85 | { .compatible = "st,stih407-uni-player-dac", | ||
86 | .data = &sti_uniplayer_dac | ||
87 | }, | ||
88 | { .compatible = "st,stih407-uni-player-spdif", | ||
89 | .data = &sti_uniplayer_spdif | ||
90 | }, | ||
91 | { .compatible = "st,stih407-uni-reader-pcm_in", | ||
92 | .data = &sti_unireader_pcm_in | ||
93 | }, | ||
94 | { .compatible = "st,stih407-uni-reader-hdmi", | ||
95 | .data = &sti_unireader_hdmi_in | ||
96 | }, | ||
97 | {}, | ||
98 | }; | ||
99 | |||
22 | int sti_uniperiph_set_tdm_slot(struct snd_soc_dai *dai, unsigned int tx_mask, | 100 | int sti_uniperiph_set_tdm_slot(struct snd_soc_dai *dai, unsigned int tx_mask, |
23 | unsigned int rx_mask, int slots, | 101 | unsigned int rx_mask, int slots, |
24 | int slot_width) | 102 | int slot_width) |
@@ -167,8 +245,8 @@ static int sti_uniperiph_dai_create_ctrl(struct snd_soc_dai *dai) | |||
167 | * Uniperipheral instance ID | 245 | * Uniperipheral instance ID |
168 | */ | 246 | */ |
169 | ctrl = &uni->snd_ctrls[i]; | 247 | ctrl = &uni->snd_ctrls[i]; |
170 | ctrl->index = uni->info->id; | 248 | ctrl->index = uni->id; |
171 | ctrl->device = uni->info->id; | 249 | ctrl->device = uni->id; |
172 | } | 250 | } |
173 | 251 | ||
174 | return snd_soc_add_dai_controls(dai, uni->snd_ctrls, uni->num_ctrls); | 252 | return snd_soc_add_dai_controls(dai, uni->snd_ctrls, uni->num_ctrls); |
@@ -186,7 +264,7 @@ int sti_uniperiph_dai_hw_params(struct snd_pcm_substream *substream, | |||
186 | struct snd_dmaengine_dai_dma_data *dma_data; | 264 | struct snd_dmaengine_dai_dma_data *dma_data; |
187 | int transfer_size; | 265 | int transfer_size; |
188 | 266 | ||
189 | if (uni->info->type == SND_ST_UNIPERIF_TYPE_TDM) | 267 | if (uni->type == SND_ST_UNIPERIF_TYPE_TDM) |
190 | /* transfer size = user frame size (in 32-bits FIFO cell) */ | 268 | /* transfer size = user frame size (in 32-bits FIFO cell) */ |
191 | transfer_size = snd_soc_params_to_frame_size(params) / 32; | 269 | transfer_size = snd_soc_params_to_frame_size(params) / 32; |
192 | else | 270 | else |
@@ -235,7 +313,7 @@ static int sti_uniperiph_dai_resume(struct snd_soc_dai *dai) | |||
235 | struct uniperif *uni = priv->dai_data.uni; | 313 | struct uniperif *uni = priv->dai_data.uni; |
236 | int ret; | 314 | int ret; |
237 | 315 | ||
238 | if (of_device_is_compatible(dai->dev->of_node, "st,sti-uni-player")) { | 316 | if (priv->dai_data.stream == SNDRV_PCM_STREAM_PLAYBACK) { |
239 | ret = uni_player_resume(uni); | 317 | ret = uni_player_resume(uni); |
240 | if (ret) | 318 | if (ret) |
241 | return ret; | 319 | return ret; |
@@ -256,7 +334,7 @@ static int sti_uniperiph_dai_probe(struct snd_soc_dai *dai) | |||
256 | struct sti_uniperiph_dai *dai_data = &priv->dai_data; | 334 | struct sti_uniperiph_dai *dai_data = &priv->dai_data; |
257 | 335 | ||
258 | /* DMA settings*/ | 336 | /* DMA settings*/ |
259 | if (of_device_is_compatible(dai->dev->of_node, "st,sti-uni-player")) | 337 | if (priv->dai_data.stream == SNDRV_PCM_STREAM_PLAYBACK) |
260 | snd_soc_dai_init_dma_data(dai, &dai_data->dma_data, NULL); | 338 | snd_soc_dai_init_dma_data(dai, &dai_data->dma_data, NULL); |
261 | else | 339 | else |
262 | snd_soc_dai_init_dma_data(dai, NULL, &dai_data->dma_data); | 340 | snd_soc_dai_init_dma_data(dai, NULL, &dai_data->dma_data); |
@@ -280,25 +358,32 @@ static const struct snd_soc_component_driver sti_uniperiph_dai_component = { | |||
280 | static int sti_uniperiph_cpu_dai_of(struct device_node *node, | 358 | static int sti_uniperiph_cpu_dai_of(struct device_node *node, |
281 | struct sti_uniperiph_data *priv) | 359 | struct sti_uniperiph_data *priv) |
282 | { | 360 | { |
283 | const char *str; | ||
284 | int ret; | ||
285 | struct device *dev = &priv->pdev->dev; | 361 | struct device *dev = &priv->pdev->dev; |
286 | struct sti_uniperiph_dai *dai_data = &priv->dai_data; | 362 | struct sti_uniperiph_dai *dai_data = &priv->dai_data; |
287 | struct snd_soc_dai_driver *dai = priv->dai; | 363 | struct snd_soc_dai_driver *dai = priv->dai; |
288 | struct snd_soc_pcm_stream *stream; | 364 | struct snd_soc_pcm_stream *stream; |
289 | struct uniperif *uni; | 365 | struct uniperif *uni; |
366 | const struct of_device_id *of_id; | ||
367 | const struct sti_uniperiph_dev_data *dev_data; | ||
368 | const char *mode; | ||
369 | |||
370 | /* Populate data structure depending on compatibility */ | ||
371 | of_id = of_match_node(snd_soc_sti_match, node); | ||
372 | if (!of_id->data) { | ||
373 | dev_err(dev, "data associated to device is missing"); | ||
374 | return -EINVAL; | ||
375 | } | ||
376 | dev_data = (struct sti_uniperiph_dev_data *)of_id->data; | ||
290 | 377 | ||
291 | uni = devm_kzalloc(dev, sizeof(*uni), GFP_KERNEL); | 378 | uni = devm_kzalloc(dev, sizeof(*uni), GFP_KERNEL); |
292 | if (!uni) | 379 | if (!uni) |
293 | return -ENOMEM; | 380 | return -ENOMEM; |
294 | 381 | ||
382 | uni->id = dev_data->id; | ||
383 | uni->ver = dev_data->version; | ||
384 | |||
295 | *dai = sti_uniperiph_dai_template; | 385 | *dai = sti_uniperiph_dai_template; |
296 | ret = of_property_read_string(node, "dai-name", &str); | 386 | dai->name = dev_data->dai_names; |
297 | if (ret < 0) { | ||
298 | dev_err(dev, "%s: dai name missing.\n", __func__); | ||
299 | return -EINVAL; | ||
300 | } | ||
301 | dai->name = str; | ||
302 | 387 | ||
303 | /* Get resources */ | 388 | /* Get resources */ |
304 | uni->mem_region = platform_get_resource(priv->pdev, IORESOURCE_MEM, 0); | 389 | uni->mem_region = platform_get_resource(priv->pdev, IORESOURCE_MEM, 0); |
@@ -322,9 +407,20 @@ static int sti_uniperiph_cpu_dai_of(struct device_node *node, | |||
322 | return -ENXIO; | 407 | return -ENXIO; |
323 | } | 408 | } |
324 | 409 | ||
410 | uni->type = dev_data->type; | ||
411 | |||
412 | /* check if player should be configured for tdm */ | ||
413 | if (dev_data->type & SND_ST_UNIPERIF_TYPE_TDM) { | ||
414 | if (!of_property_read_string(node, "st,tdm-mode", &mode)) | ||
415 | uni->type = SND_ST_UNIPERIF_TYPE_TDM; | ||
416 | else | ||
417 | uni->type = SND_ST_UNIPERIF_TYPE_PCM; | ||
418 | } | ||
419 | |||
325 | dai_data->uni = uni; | 420 | dai_data->uni = uni; |
421 | dai_data->stream = dev_data->stream; | ||
326 | 422 | ||
327 | if (of_device_is_compatible(node, "st,sti-uni-player")) { | 423 | if (priv->dai_data.stream == SNDRV_PCM_STREAM_PLAYBACK) { |
328 | uni_player_init(priv->pdev, uni); | 424 | uni_player_init(priv->pdev, uni); |
329 | stream = &dai->playback; | 425 | stream = &dai->playback; |
330 | } else { | 426 | } else { |
@@ -376,12 +472,6 @@ static int sti_uniperiph_probe(struct platform_device *pdev) | |||
376 | &dmaengine_pcm_config, 0); | 472 | &dmaengine_pcm_config, 0); |
377 | } | 473 | } |
378 | 474 | ||
379 | static const struct of_device_id snd_soc_sti_match[] = { | ||
380 | { .compatible = "st,sti-uni-player", }, | ||
381 | { .compatible = "st,sti-uni-reader", }, | ||
382 | {}, | ||
383 | }; | ||
384 | |||
385 | static struct platform_driver sti_uniperiph_driver = { | 475 | static struct platform_driver sti_uniperiph_driver = { |
386 | .driver = { | 476 | .driver = { |
387 | .name = "sti-uniperiph-dai", | 477 | .name = "sti-uniperiph-dai", |
diff --git a/sound/soc/sti/uniperif.h b/sound/soc/sti/uniperif.h index eb9933c62ad6..1993c655fb79 100644 --- a/sound/soc/sti/uniperif.h +++ b/sound/soc/sti/uniperif.h | |||
@@ -1220,16 +1220,16 @@ | |||
1220 | #define UNIPERIF_FIFO_FRAMES 4 /* FDMA trigger limit in frames */ | 1220 | #define UNIPERIF_FIFO_FRAMES 4 /* FDMA trigger limit in frames */ |
1221 | 1221 | ||
1222 | #define UNIPERIF_TYPE_IS_HDMI(p) \ | 1222 | #define UNIPERIF_TYPE_IS_HDMI(p) \ |
1223 | ((p)->info->type == SND_ST_UNIPERIF_TYPE_HDMI) | 1223 | ((p)->type == SND_ST_UNIPERIF_TYPE_HDMI) |
1224 | #define UNIPERIF_TYPE_IS_PCM(p) \ | 1224 | #define UNIPERIF_TYPE_IS_PCM(p) \ |
1225 | ((p)->info->type == SND_ST_UNIPERIF_TYPE_PCM) | 1225 | ((p)->type == SND_ST_UNIPERIF_TYPE_PCM) |
1226 | #define UNIPERIF_TYPE_IS_SPDIF(p) \ | 1226 | #define UNIPERIF_TYPE_IS_SPDIF(p) \ |
1227 | ((p)->info->type == SND_ST_UNIPERIF_TYPE_SPDIF) | 1227 | ((p)->type == SND_ST_UNIPERIF_TYPE_SPDIF) |
1228 | #define UNIPERIF_TYPE_IS_IEC958(p) \ | 1228 | #define UNIPERIF_TYPE_IS_IEC958(p) \ |
1229 | (UNIPERIF_TYPE_IS_HDMI(p) || \ | 1229 | (UNIPERIF_TYPE_IS_HDMI(p) || \ |
1230 | UNIPERIF_TYPE_IS_SPDIF(p)) | 1230 | UNIPERIF_TYPE_IS_SPDIF(p)) |
1231 | #define UNIPERIF_TYPE_IS_TDM(p) \ | 1231 | #define UNIPERIF_TYPE_IS_TDM(p) \ |
1232 | ((p)->info->type == SND_ST_UNIPERIF_TYPE_TDM) | 1232 | ((p)->type == SND_ST_UNIPERIF_TYPE_TDM) |
1233 | 1233 | ||
1234 | /* | 1234 | /* |
1235 | * Uniperipheral IP revisions | 1235 | * Uniperipheral IP revisions |
@@ -1249,11 +1249,11 @@ enum uniperif_version { | |||
1249 | }; | 1249 | }; |
1250 | 1250 | ||
1251 | enum uniperif_type { | 1251 | enum uniperif_type { |
1252 | SND_ST_UNIPERIF_TYPE_NONE, | 1252 | SND_ST_UNIPERIF_TYPE_NONE = 0x00, |
1253 | SND_ST_UNIPERIF_TYPE_HDMI, | 1253 | SND_ST_UNIPERIF_TYPE_HDMI = 0x01, |
1254 | SND_ST_UNIPERIF_TYPE_PCM, | 1254 | SND_ST_UNIPERIF_TYPE_PCM = 0x02, |
1255 | SND_ST_UNIPERIF_TYPE_SPDIF, | 1255 | SND_ST_UNIPERIF_TYPE_SPDIF = 0x04, |
1256 | SND_ST_UNIPERIF_TYPE_TDM | 1256 | SND_ST_UNIPERIF_TYPE_TDM = 0x08 |
1257 | }; | 1257 | }; |
1258 | 1258 | ||
1259 | enum uniperif_state { | 1259 | enum uniperif_state { |
@@ -1278,12 +1278,6 @@ enum uniperif_word_pos { | |||
1278 | WORD_MAX | 1278 | WORD_MAX |
1279 | }; | 1279 | }; |
1280 | 1280 | ||
1281 | struct uniperif_info { | ||
1282 | int id; /* instance value of the uniperipheral IP */ | ||
1283 | enum uniperif_type type; | ||
1284 | int underflow_enabled; /* Underflow recovery mode */ | ||
1285 | }; | ||
1286 | |||
1287 | struct uniperif_iec958_settings { | 1281 | struct uniperif_iec958_settings { |
1288 | enum uniperif_iec958_encoding_mode encoding_mode; | 1282 | enum uniperif_iec958_encoding_mode encoding_mode; |
1289 | struct snd_aes_iec958 iec958; | 1283 | struct snd_aes_iec958 iec958; |
@@ -1298,8 +1292,10 @@ struct dai_tdm_slot { | |||
1298 | 1292 | ||
1299 | struct uniperif { | 1293 | struct uniperif { |
1300 | /* System information */ | 1294 | /* System information */ |
1301 | struct uniperif_info *info; | 1295 | enum uniperif_type type; |
1296 | int underflow_enabled; /* Underflow recovery mode */ | ||
1302 | struct device *dev; | 1297 | struct device *dev; |
1298 | int id; /* instance value of the uniperipheral IP */ | ||
1303 | int ver; /* IP version, used by register access macros */ | 1299 | int ver; /* IP version, used by register access macros */ |
1304 | struct regmap_field *clk_sel; | 1300 | struct regmap_field *clk_sel; |
1305 | struct regmap_field *valid_sel; | 1301 | struct regmap_field *valid_sel; |
diff --git a/sound/soc/sti/uniperif_player.c b/sound/soc/sti/uniperif_player.c index 1ac2db205a0d..1bc8ebc2528e 100644 --- a/sound/soc/sti/uniperif_player.c +++ b/sound/soc/sti/uniperif_player.c | |||
@@ -100,7 +100,7 @@ static irqreturn_t uni_player_irq_handler(int irq, void *dev_id) | |||
100 | dev_err(player->dev, "FIFO underflow error detected"); | 100 | dev_err(player->dev, "FIFO underflow error detected"); |
101 | 101 | ||
102 | /* Interrupt is just for information when underflow recovery */ | 102 | /* Interrupt is just for information when underflow recovery */ |
103 | if (player->info->underflow_enabled) { | 103 | if (player->underflow_enabled) { |
104 | /* Update state to underflow */ | 104 | /* Update state to underflow */ |
105 | player->state = UNIPERIF_STATE_UNDERFLOW; | 105 | player->state = UNIPERIF_STATE_UNDERFLOW; |
106 | 106 | ||
@@ -134,7 +134,7 @@ static irqreturn_t uni_player_irq_handler(int irq, void *dev_id) | |||
134 | 134 | ||
135 | /* Check for underflow recovery done */ | 135 | /* Check for underflow recovery done */ |
136 | if (unlikely(status & UNIPERIF_ITM_UNDERFLOW_REC_DONE_MASK(player))) { | 136 | if (unlikely(status & UNIPERIF_ITM_UNDERFLOW_REC_DONE_MASK(player))) { |
137 | if (!player->info->underflow_enabled) { | 137 | if (!player->underflow_enabled) { |
138 | dev_err(player->dev, "unexpected Underflow recovering"); | 138 | dev_err(player->dev, "unexpected Underflow recovering"); |
139 | return -EPERM; | 139 | return -EPERM; |
140 | } | 140 | } |
@@ -764,7 +764,7 @@ static int uni_player_prepare(struct snd_pcm_substream *substream, | |||
764 | } | 764 | } |
765 | 765 | ||
766 | /* Calculate transfer size (in fifo cells and bytes) for frame count */ | 766 | /* Calculate transfer size (in fifo cells and bytes) for frame count */ |
767 | if (player->info->type == SND_ST_UNIPERIF_TYPE_TDM) { | 767 | if (player->type == SND_ST_UNIPERIF_TYPE_TDM) { |
768 | /* transfer size = user frame size (in 32 bits FIFO cell) */ | 768 | /* transfer size = user frame size (in 32 bits FIFO cell) */ |
769 | transfer_size = | 769 | transfer_size = |
770 | sti_uniperiph_get_user_frame_size(runtime) / 4; | 770 | sti_uniperiph_get_user_frame_size(runtime) / 4; |
@@ -794,7 +794,7 @@ static int uni_player_prepare(struct snd_pcm_substream *substream, | |||
794 | SET_UNIPERIF_CONFIG_DMA_TRIG_LIMIT(player, trigger_limit); | 794 | SET_UNIPERIF_CONFIG_DMA_TRIG_LIMIT(player, trigger_limit); |
795 | 795 | ||
796 | /* Uniperipheral setup depends on player type */ | 796 | /* Uniperipheral setup depends on player type */ |
797 | switch (player->info->type) { | 797 | switch (player->type) { |
798 | case SND_ST_UNIPERIF_TYPE_HDMI: | 798 | case SND_ST_UNIPERIF_TYPE_HDMI: |
799 | ret = uni_player_prepare_iec958(player, runtime); | 799 | ret = uni_player_prepare_iec958(player, runtime); |
800 | break; | 800 | break; |
@@ -884,7 +884,7 @@ static int uni_player_start(struct uniperif *player) | |||
884 | SET_UNIPERIF_ITM_BSET_FIFO_ERROR(player); | 884 | SET_UNIPERIF_ITM_BSET_FIFO_ERROR(player); |
885 | 885 | ||
886 | /* Enable underflow recovery interrupts */ | 886 | /* Enable underflow recovery interrupts */ |
887 | if (player->info->underflow_enabled) { | 887 | if (player->underflow_enabled) { |
888 | SET_UNIPERIF_ITM_BSET_UNDERFLOW_REC_DONE(player); | 888 | SET_UNIPERIF_ITM_BSET_UNDERFLOW_REC_DONE(player); |
889 | SET_UNIPERIF_ITM_BSET_UNDERFLOW_REC_FAILED(player); | 889 | SET_UNIPERIF_ITM_BSET_UNDERFLOW_REC_FAILED(player); |
890 | } | 890 | } |
@@ -893,8 +893,10 @@ static int uni_player_start(struct uniperif *player) | |||
893 | SET_UNIPERIF_SOFT_RST_SOFT_RST(player); | 893 | SET_UNIPERIF_SOFT_RST_SOFT_RST(player); |
894 | 894 | ||
895 | ret = reset_player(player); | 895 | ret = reset_player(player); |
896 | if (ret < 0) | 896 | if (ret < 0) { |
897 | clk_disable_unprepare(player->clk); | ||
897 | return ret; | 898 | return ret; |
899 | } | ||
898 | 900 | ||
899 | /* | 901 | /* |
900 | * Does not use IEC61937 features of the uniperipheral hardware. | 902 | * Does not use IEC61937 features of the uniperipheral hardware. |
@@ -1021,8 +1023,8 @@ static int uni_player_parse_dt_audio_glue(struct platform_device *pdev, | |||
1021 | struct reg_field regfield[2] = { | 1023 | struct reg_field regfield[2] = { |
1022 | /* PCM_CLK_SEL */ | 1024 | /* PCM_CLK_SEL */ |
1023 | REG_FIELD(SYS_CFG_AUDIO_GLUE, | 1025 | REG_FIELD(SYS_CFG_AUDIO_GLUE, |
1024 | 8 + player->info->id, | 1026 | 8 + player->id, |
1025 | 8 + player->info->id), | 1027 | 8 + player->id), |
1026 | /* PCMP_VALID_SEL */ | 1028 | /* PCMP_VALID_SEL */ |
1027 | REG_FIELD(SYS_CFG_AUDIO_GLUE, 0, 1) | 1029 | REG_FIELD(SYS_CFG_AUDIO_GLUE, 0, 1) |
1028 | }; | 1030 | }; |
@@ -1040,60 +1042,6 @@ static int uni_player_parse_dt_audio_glue(struct platform_device *pdev, | |||
1040 | return 0; | 1042 | return 0; |
1041 | } | 1043 | } |
1042 | 1044 | ||
1043 | static int uni_player_parse_dt(struct platform_device *pdev, | ||
1044 | struct uniperif *player) | ||
1045 | { | ||
1046 | struct uniperif_info *info; | ||
1047 | struct device *dev = &pdev->dev; | ||
1048 | struct device_node *pnode = pdev->dev.of_node; | ||
1049 | const char *mode; | ||
1050 | |||
1051 | /* Allocate memory for the info structure */ | ||
1052 | info = devm_kzalloc(dev, sizeof(*info), GFP_KERNEL); | ||
1053 | if (!info) | ||
1054 | return -ENOMEM; | ||
1055 | |||
1056 | if (of_property_read_u32(pnode, "st,version", &player->ver) || | ||
1057 | player->ver == SND_ST_UNIPERIF_VERSION_UNKNOWN) { | ||
1058 | dev_err(dev, "Unknown uniperipheral version "); | ||
1059 | return -EINVAL; | ||
1060 | } | ||
1061 | /* Underflow recovery is only supported on later ip revisions */ | ||
1062 | if (player->ver >= SND_ST_UNIPERIF_VERSION_UNI_PLR_TOP_1_0) | ||
1063 | info->underflow_enabled = 1; | ||
1064 | |||
1065 | if (of_property_read_u32(pnode, "st,uniperiph-id", &info->id)) { | ||
1066 | dev_err(dev, "uniperipheral id not defined"); | ||
1067 | return -EINVAL; | ||
1068 | } | ||
1069 | |||
1070 | /* Read the device mode property */ | ||
1071 | if (of_property_read_string(pnode, "st,mode", &mode)) { | ||
1072 | dev_err(dev, "uniperipheral mode not defined"); | ||
1073 | return -EINVAL; | ||
1074 | } | ||
1075 | |||
1076 | if (strcasecmp(mode, "hdmi") == 0) | ||
1077 | info->type = SND_ST_UNIPERIF_TYPE_HDMI; | ||
1078 | else if (strcasecmp(mode, "pcm") == 0) | ||
1079 | info->type = SND_ST_UNIPERIF_TYPE_PCM; | ||
1080 | else if (strcasecmp(mode, "spdif") == 0) | ||
1081 | info->type = SND_ST_UNIPERIF_TYPE_SPDIF; | ||
1082 | else if (strcasecmp(mode, "tdm") == 0) | ||
1083 | info->type = SND_ST_UNIPERIF_TYPE_TDM; | ||
1084 | else | ||
1085 | info->type = SND_ST_UNIPERIF_TYPE_NONE; | ||
1086 | |||
1087 | /* Save the info structure */ | ||
1088 | player->info = info; | ||
1089 | |||
1090 | /* Get PCM_CLK_SEL & PCMP_VALID_SEL from audio-glue-ctrl SoC reg */ | ||
1091 | if (uni_player_parse_dt_audio_glue(pdev, player)) | ||
1092 | return -EINVAL; | ||
1093 | |||
1094 | return 0; | ||
1095 | } | ||
1096 | |||
1097 | static const struct snd_soc_dai_ops uni_player_dai_ops = { | 1045 | static const struct snd_soc_dai_ops uni_player_dai_ops = { |
1098 | .startup = uni_player_startup, | 1046 | .startup = uni_player_startup, |
1099 | .shutdown = uni_player_shutdown, | 1047 | .shutdown = uni_player_shutdown, |
@@ -1114,13 +1062,18 @@ int uni_player_init(struct platform_device *pdev, | |||
1114 | player->state = UNIPERIF_STATE_STOPPED; | 1062 | player->state = UNIPERIF_STATE_STOPPED; |
1115 | player->dai_ops = &uni_player_dai_ops; | 1063 | player->dai_ops = &uni_player_dai_ops; |
1116 | 1064 | ||
1117 | ret = uni_player_parse_dt(pdev, player); | 1065 | /* Get PCM_CLK_SEL & PCMP_VALID_SEL from audio-glue-ctrl SoC reg */ |
1066 | ret = uni_player_parse_dt_audio_glue(pdev, player); | ||
1118 | 1067 | ||
1119 | if (ret < 0) { | 1068 | if (ret < 0) { |
1120 | dev_err(player->dev, "Failed to parse DeviceTree"); | 1069 | dev_err(player->dev, "Failed to parse DeviceTree"); |
1121 | return ret; | 1070 | return ret; |
1122 | } | 1071 | } |
1123 | 1072 | ||
1073 | /* Underflow recovery is only supported on later ip revisions */ | ||
1074 | if (player->ver >= SND_ST_UNIPERIF_VERSION_UNI_PLR_TOP_1_0) | ||
1075 | player->underflow_enabled = 1; | ||
1076 | |||
1124 | if (UNIPERIF_TYPE_IS_TDM(player)) | 1077 | if (UNIPERIF_TYPE_IS_TDM(player)) |
1125 | player->hw = &uni_tdm_hw; | 1078 | player->hw = &uni_tdm_hw; |
1126 | else | 1079 | else |
@@ -1144,8 +1097,8 @@ int uni_player_init(struct platform_device *pdev, | |||
1144 | 1097 | ||
1145 | /* connect to I2S/TDM TX bus */ | 1098 | /* connect to I2S/TDM TX bus */ |
1146 | if (player->valid_sel && | 1099 | if (player->valid_sel && |
1147 | (player->info->id == UNIPERIF_PLAYER_I2S_OUT)) { | 1100 | (player->id == UNIPERIF_PLAYER_I2S_OUT)) { |
1148 | ret = regmap_field_write(player->valid_sel, player->info->id); | 1101 | ret = regmap_field_write(player->valid_sel, player->id); |
1149 | if (ret) { | 1102 | if (ret) { |
1150 | dev_err(player->dev, | 1103 | dev_err(player->dev, |
1151 | "%s: unable to connect to tdm bus", __func__); | 1104 | "%s: unable to connect to tdm bus", __func__); |
diff --git a/sound/soc/sti/uniperif_reader.c b/sound/soc/sti/uniperif_reader.c index eb74a328c928..0e1c3ee56675 100644 --- a/sound/soc/sti/uniperif_reader.c +++ b/sound/soc/sti/uniperif_reader.c | |||
@@ -13,6 +13,7 @@ | |||
13 | 13 | ||
14 | #include "uniperif.h" | 14 | #include "uniperif.h" |
15 | 15 | ||
16 | #define UNIPERIF_READER_I2S_IN 0 /* reader id connected to I2S/TDM TX bus */ | ||
16 | /* | 17 | /* |
17 | * Note: snd_pcm_hardware is linked to DMA controller but is declared here to | 18 | * Note: snd_pcm_hardware is linked to DMA controller but is declared here to |
18 | * integrate unireader capability in term of rate and supported channels | 19 | * integrate unireader capability in term of rate and supported channels |
@@ -195,7 +196,7 @@ static int uni_reader_prepare(struct snd_pcm_substream *substream, | |||
195 | } | 196 | } |
196 | 197 | ||
197 | /* Calculate transfer size (in fifo cells and bytes) for frame count */ | 198 | /* Calculate transfer size (in fifo cells and bytes) for frame count */ |
198 | if (reader->info->type == SND_ST_UNIPERIF_TYPE_TDM) { | 199 | if (reader->type == SND_ST_UNIPERIF_TYPE_TDM) { |
199 | /* transfer size = unip frame size (in 32 bits FIFO cell) */ | 200 | /* transfer size = unip frame size (in 32 bits FIFO cell) */ |
200 | transfer_size = | 201 | transfer_size = |
201 | sti_uniperiph_get_user_frame_size(runtime) / 4; | 202 | sti_uniperiph_get_user_frame_size(runtime) / 4; |
@@ -280,7 +281,7 @@ static int uni_reader_prepare(struct snd_pcm_substream *substream, | |||
280 | SET_UNIPERIF_ITM_BSET_MEM_BLK_READ(reader); | 281 | SET_UNIPERIF_ITM_BSET_MEM_BLK_READ(reader); |
281 | 282 | ||
282 | /* Enable underflow recovery interrupts */ | 283 | /* Enable underflow recovery interrupts */ |
283 | if (reader->info->underflow_enabled) { | 284 | if (reader->underflow_enabled) { |
284 | SET_UNIPERIF_ITM_BSET_UNDERFLOW_REC_DONE(reader); | 285 | SET_UNIPERIF_ITM_BSET_UNDERFLOW_REC_DONE(reader); |
285 | SET_UNIPERIF_ITM_BSET_UNDERFLOW_REC_FAILED(reader); | 286 | SET_UNIPERIF_ITM_BSET_UNDERFLOW_REC_FAILED(reader); |
286 | } | 287 | } |
@@ -394,41 +395,6 @@ static void uni_reader_shutdown(struct snd_pcm_substream *substream, | |||
394 | } | 395 | } |
395 | } | 396 | } |
396 | 397 | ||
397 | static int uni_reader_parse_dt(struct platform_device *pdev, | ||
398 | struct uniperif *reader) | ||
399 | { | ||
400 | struct uniperif_info *info; | ||
401 | struct device_node *node = pdev->dev.of_node; | ||
402 | const char *mode; | ||
403 | |||
404 | /* Allocate memory for the info structure */ | ||
405 | info = devm_kzalloc(&pdev->dev, sizeof(*info), GFP_KERNEL); | ||
406 | if (!info) | ||
407 | return -ENOMEM; | ||
408 | |||
409 | if (of_property_read_u32(node, "st,version", &reader->ver) || | ||
410 | reader->ver == SND_ST_UNIPERIF_VERSION_UNKNOWN) { | ||
411 | dev_err(&pdev->dev, "Unknown uniperipheral version "); | ||
412 | return -EINVAL; | ||
413 | } | ||
414 | |||
415 | /* Read the device mode property */ | ||
416 | if (of_property_read_string(node, "st,mode", &mode)) { | ||
417 | dev_err(&pdev->dev, "uniperipheral mode not defined"); | ||
418 | return -EINVAL; | ||
419 | } | ||
420 | |||
421 | if (strcasecmp(mode, "tdm") == 0) | ||
422 | info->type = SND_ST_UNIPERIF_TYPE_TDM; | ||
423 | else | ||
424 | info->type = SND_ST_UNIPERIF_TYPE_PCM; | ||
425 | |||
426 | /* Save the info structure */ | ||
427 | reader->info = info; | ||
428 | |||
429 | return 0; | ||
430 | } | ||
431 | |||
432 | static const struct snd_soc_dai_ops uni_reader_dai_ops = { | 398 | static const struct snd_soc_dai_ops uni_reader_dai_ops = { |
433 | .startup = uni_reader_startup, | 399 | .startup = uni_reader_startup, |
434 | .shutdown = uni_reader_shutdown, | 400 | .shutdown = uni_reader_shutdown, |
@@ -448,12 +414,6 @@ int uni_reader_init(struct platform_device *pdev, | |||
448 | reader->state = UNIPERIF_STATE_STOPPED; | 414 | reader->state = UNIPERIF_STATE_STOPPED; |
449 | reader->dai_ops = &uni_reader_dai_ops; | 415 | reader->dai_ops = &uni_reader_dai_ops; |
450 | 416 | ||
451 | ret = uni_reader_parse_dt(pdev, reader); | ||
452 | if (ret < 0) { | ||
453 | dev_err(reader->dev, "Failed to parse DeviceTree"); | ||
454 | return ret; | ||
455 | } | ||
456 | |||
457 | if (UNIPERIF_TYPE_IS_TDM(reader)) | 417 | if (UNIPERIF_TYPE_IS_TDM(reader)) |
458 | reader->hw = &uni_tdm_hw; | 418 | reader->hw = &uni_tdm_hw; |
459 | else | 419 | else |
diff --git a/sound/soc/sunxi/Kconfig b/sound/soc/sunxi/Kconfig index 2a954bd01fd8..dd2368297fd3 100644 --- a/sound/soc/sunxi/Kconfig +++ b/sound/soc/sunxi/Kconfig | |||
@@ -1,4 +1,5 @@ | |||
1 | menu "Allwinner SoC Audio support" | 1 | menu "Allwinner SoC Audio support" |
2 | depends on ARCH_SUNXI || COMPILE_TEST | ||
2 | 3 | ||
3 | config SND_SUN4I_CODEC | 4 | config SND_SUN4I_CODEC |
4 | tristate "Allwinner A10 Codec Support" | 5 | tristate "Allwinner A10 Codec Support" |
diff --git a/sound/soc/sunxi/sun4i-codec.c b/sound/soc/sunxi/sun4i-codec.c index 44f170c73b06..e047ec06d538 100644 --- a/sound/soc/sunxi/sun4i-codec.c +++ b/sound/soc/sunxi/sun4i-codec.c | |||
@@ -96,8 +96,8 @@ | |||
96 | /* Other various ADC registers */ | 96 | /* Other various ADC registers */ |
97 | #define SUN4I_CODEC_DAC_TXCNT (0x30) | 97 | #define SUN4I_CODEC_DAC_TXCNT (0x30) |
98 | #define SUN4I_CODEC_ADC_RXCNT (0x34) | 98 | #define SUN4I_CODEC_ADC_RXCNT (0x34) |
99 | #define SUN4I_CODEC_AC_SYS_VERI (0x38) | 99 | #define SUN7I_CODEC_AC_DAC_CAL (0x38) |
100 | #define SUN4I_CODEC_AC_MIC_PHONE_CAL (0x3c) | 100 | #define SUN7I_CODEC_AC_MIC_PHONE_CAL (0x3c) |
101 | 101 | ||
102 | struct sun4i_codec { | 102 | struct sun4i_codec { |
103 | struct device *dev; | 103 | struct device *dev; |
@@ -509,7 +509,7 @@ static const struct snd_kcontrol_new sun4i_codec_pa_mute = | |||
509 | 509 | ||
510 | static DECLARE_TLV_DB_SCALE(sun4i_codec_pa_volume_scale, -6300, 100, 1); | 510 | static DECLARE_TLV_DB_SCALE(sun4i_codec_pa_volume_scale, -6300, 100, 1); |
511 | 511 | ||
512 | static const struct snd_kcontrol_new sun4i_codec_widgets[] = { | 512 | static const struct snd_kcontrol_new sun4i_codec_controls[] = { |
513 | SOC_SINGLE_TLV("Power Amplifier Volume", SUN4I_CODEC_DAC_ACTL, | 513 | SOC_SINGLE_TLV("Power Amplifier Volume", SUN4I_CODEC_DAC_ACTL, |
514 | SUN4I_CODEC_DAC_ACTL_PA_VOL, 0x3F, 0, | 514 | SUN4I_CODEC_DAC_ACTL_PA_VOL, 0x3F, 0, |
515 | sun4i_codec_pa_volume_scale), | 515 | sun4i_codec_pa_volume_scale), |
@@ -628,12 +628,14 @@ static const struct snd_soc_dapm_route sun4i_codec_codec_dapm_routes[] = { | |||
628 | }; | 628 | }; |
629 | 629 | ||
630 | static struct snd_soc_codec_driver sun4i_codec_codec = { | 630 | static struct snd_soc_codec_driver sun4i_codec_codec = { |
631 | .controls = sun4i_codec_widgets, | 631 | .component_driver = { |
632 | .num_controls = ARRAY_SIZE(sun4i_codec_widgets), | 632 | .controls = sun4i_codec_controls, |
633 | .dapm_widgets = sun4i_codec_codec_dapm_widgets, | 633 | .num_controls = ARRAY_SIZE(sun4i_codec_controls), |
634 | .num_dapm_widgets = ARRAY_SIZE(sun4i_codec_codec_dapm_widgets), | 634 | .dapm_widgets = sun4i_codec_codec_dapm_widgets, |
635 | .dapm_routes = sun4i_codec_codec_dapm_routes, | 635 | .num_dapm_widgets = ARRAY_SIZE(sun4i_codec_codec_dapm_widgets), |
636 | .num_dapm_routes = ARRAY_SIZE(sun4i_codec_codec_dapm_routes), | 636 | .dapm_routes = sun4i_codec_codec_dapm_routes, |
637 | .num_dapm_routes = ARRAY_SIZE(sun4i_codec_codec_dapm_routes), | ||
638 | }, | ||
637 | }; | 639 | }; |
638 | 640 | ||
639 | static const struct snd_soc_component_driver sun4i_codec_component = { | 641 | static const struct snd_soc_component_driver sun4i_codec_component = { |
@@ -680,12 +682,37 @@ static const struct regmap_config sun4i_codec_regmap_config = { | |||
680 | .reg_bits = 32, | 682 | .reg_bits = 32, |
681 | .reg_stride = 4, | 683 | .reg_stride = 4, |
682 | .val_bits = 32, | 684 | .val_bits = 32, |
683 | .max_register = SUN4I_CODEC_AC_MIC_PHONE_CAL, | 685 | .max_register = SUN4I_CODEC_ADC_RXCNT, |
686 | }; | ||
687 | |||
688 | static const struct regmap_config sun7i_codec_regmap_config = { | ||
689 | .reg_bits = 32, | ||
690 | .reg_stride = 4, | ||
691 | .val_bits = 32, | ||
692 | .max_register = SUN7I_CODEC_AC_MIC_PHONE_CAL, | ||
693 | }; | ||
694 | |||
695 | struct sun4i_codec_quirks { | ||
696 | const struct regmap_config *regmap_config; | ||
697 | }; | ||
698 | |||
699 | static const struct sun4i_codec_quirks sun4i_codec_quirks = { | ||
700 | .regmap_config = &sun4i_codec_regmap_config, | ||
701 | }; | ||
702 | |||
703 | static const struct sun4i_codec_quirks sun7i_codec_quirks = { | ||
704 | .regmap_config = &sun7i_codec_regmap_config, | ||
684 | }; | 705 | }; |
685 | 706 | ||
686 | static const struct of_device_id sun4i_codec_of_match[] = { | 707 | static const struct of_device_id sun4i_codec_of_match[] = { |
687 | { .compatible = "allwinner,sun4i-a10-codec" }, | 708 | { |
688 | { .compatible = "allwinner,sun7i-a20-codec" }, | 709 | .compatible = "allwinner,sun4i-a10-codec", |
710 | .data = &sun4i_codec_quirks, | ||
711 | }, | ||
712 | { | ||
713 | .compatible = "allwinner,sun7i-a20-codec", | ||
714 | .data = &sun7i_codec_quirks, | ||
715 | }, | ||
689 | {} | 716 | {} |
690 | }; | 717 | }; |
691 | MODULE_DEVICE_TABLE(of, sun4i_codec_of_match); | 718 | MODULE_DEVICE_TABLE(of, sun4i_codec_of_match); |
@@ -758,6 +785,7 @@ static int sun4i_codec_probe(struct platform_device *pdev) | |||
758 | { | 785 | { |
759 | struct snd_soc_card *card; | 786 | struct snd_soc_card *card; |
760 | struct sun4i_codec *scodec; | 787 | struct sun4i_codec *scodec; |
788 | const struct sun4i_codec_quirks *quirks; | ||
761 | struct resource *res; | 789 | struct resource *res; |
762 | void __iomem *base; | 790 | void __iomem *base; |
763 | int ret; | 791 | int ret; |
@@ -775,8 +803,14 @@ static int sun4i_codec_probe(struct platform_device *pdev) | |||
775 | return PTR_ERR(base); | 803 | return PTR_ERR(base); |
776 | } | 804 | } |
777 | 805 | ||
806 | quirks = of_device_get_match_data(&pdev->dev); | ||
807 | if (quirks == NULL) { | ||
808 | dev_err(&pdev->dev, "Failed to determine the quirks to use\n"); | ||
809 | return -ENODEV; | ||
810 | } | ||
811 | |||
778 | scodec->regmap = devm_regmap_init_mmio(&pdev->dev, base, | 812 | scodec->regmap = devm_regmap_init_mmio(&pdev->dev, base, |
779 | &sun4i_codec_regmap_config); | 813 | quirks->regmap_config); |
780 | if (IS_ERR(scodec->regmap)) { | 814 | if (IS_ERR(scodec->regmap)) { |
781 | dev_err(&pdev->dev, "Failed to create our regmap\n"); | 815 | dev_err(&pdev->dev, "Failed to create our regmap\n"); |
782 | return PTR_ERR(scodec->regmap); | 816 | return PTR_ERR(scodec->regmap); |
diff --git a/sound/soc/sunxi/sun4i-spdif.c b/sound/soc/sunxi/sun4i-spdif.c index 0b04fb02125c..88fbb3a1e660 100644 --- a/sound/soc/sunxi/sun4i-spdif.c +++ b/sound/soc/sunxi/sun4i-spdif.c | |||
@@ -29,6 +29,7 @@ | |||
29 | #include <linux/module.h> | 29 | #include <linux/module.h> |
30 | #include <linux/platform_device.h> | 30 | #include <linux/platform_device.h> |
31 | #include <linux/pm_runtime.h> | 31 | #include <linux/pm_runtime.h> |
32 | #include <linux/reset.h> | ||
32 | #include <sound/dmaengine_pcm.h> | 33 | #include <sound/dmaengine_pcm.h> |
33 | #include <sound/pcm_params.h> | 34 | #include <sound/pcm_params.h> |
34 | #include <sound/soc.h> | 35 | #include <sound/soc.h> |
@@ -162,6 +163,7 @@ struct sun4i_spdif_dev { | |||
162 | struct platform_device *pdev; | 163 | struct platform_device *pdev; |
163 | struct clk *spdif_clk; | 164 | struct clk *spdif_clk; |
164 | struct clk *apb_clk; | 165 | struct clk *apb_clk; |
166 | struct reset_control *rst; | ||
165 | struct snd_soc_dai_driver cpu_dai_drv; | 167 | struct snd_soc_dai_driver cpu_dai_drv; |
166 | struct regmap *regmap; | 168 | struct regmap *regmap; |
167 | struct snd_dmaengine_dai_dma_data dma_params_tx; | 169 | struct snd_dmaengine_dai_dma_data dma_params_tx; |
@@ -411,6 +413,7 @@ static const struct snd_soc_dapm_route dit_routes[] = { | |||
411 | 413 | ||
412 | static const struct of_device_id sun4i_spdif_of_match[] = { | 414 | static const struct of_device_id sun4i_spdif_of_match[] = { |
413 | { .compatible = "allwinner,sun4i-a10-spdif", }, | 415 | { .compatible = "allwinner,sun4i-a10-spdif", }, |
416 | { .compatible = "allwinner,sun6i-a31-spdif", }, | ||
414 | { /* sentinel */ } | 417 | { /* sentinel */ } |
415 | }; | 418 | }; |
416 | MODULE_DEVICE_TABLE(of, sun4i_spdif_of_match); | 419 | MODULE_DEVICE_TABLE(of, sun4i_spdif_of_match); |
@@ -482,11 +485,23 @@ static int sun4i_spdif_probe(struct platform_device *pdev) | |||
482 | } | 485 | } |
483 | 486 | ||
484 | host->dma_params_tx.addr = res->start + SUN4I_SPDIF_TXFIFO; | 487 | host->dma_params_tx.addr = res->start + SUN4I_SPDIF_TXFIFO; |
485 | host->dma_params_tx.maxburst = 4; | 488 | host->dma_params_tx.maxburst = 8; |
486 | host->dma_params_tx.addr_width = DMA_SLAVE_BUSWIDTH_2_BYTES; | 489 | host->dma_params_tx.addr_width = DMA_SLAVE_BUSWIDTH_2_BYTES; |
487 | 490 | ||
488 | platform_set_drvdata(pdev, host); | 491 | platform_set_drvdata(pdev, host); |
489 | 492 | ||
493 | if (of_device_is_compatible(pdev->dev.of_node, | ||
494 | "allwinner,sun6i-a31-spdif")) { | ||
495 | host->rst = devm_reset_control_get_optional(&pdev->dev, NULL); | ||
496 | if (IS_ERR(host->rst) && PTR_ERR(host->rst) == -EPROBE_DEFER) { | ||
497 | ret = -EPROBE_DEFER; | ||
498 | dev_err(&pdev->dev, "Failed to get reset: %d\n", ret); | ||
499 | goto err_disable_apb_clk; | ||
500 | } | ||
501 | if (!IS_ERR(host->rst)) | ||
502 | reset_control_deassert(host->rst); | ||
503 | } | ||
504 | |||
490 | ret = devm_snd_soc_register_component(&pdev->dev, | 505 | ret = devm_snd_soc_register_component(&pdev->dev, |
491 | &sun4i_spdif_component, &sun4i_spdif_dai, 1); | 506 | &sun4i_spdif_component, &sun4i_spdif_dai, 1); |
492 | if (ret) | 507 | if (ret) |
diff --git a/sound/soc/tegra/Kconfig b/sound/soc/tegra/Kconfig index a6768f832c6f..efbe8d4c019e 100644 --- a/sound/soc/tegra/Kconfig +++ b/sound/soc/tegra/Kconfig | |||
@@ -138,3 +138,14 @@ config SND_SOC_TEGRA_RT5677 | |||
138 | help | 138 | help |
139 | Say Y or M here if you want to add support for SoC audio on Tegra | 139 | Say Y or M here if you want to add support for SoC audio on Tegra |
140 | boards using the RT5677 codec, such as Ryu. | 140 | boards using the RT5677 codec, such as Ryu. |
141 | |||
142 | config SND_SOC_TEGRA_SGTL5000 | ||
143 | tristate "SoC Audio support for Tegra boards using a SGTL5000 codec" | ||
144 | depends on SND_SOC_TEGRA && I2C && GPIOLIB | ||
145 | select SND_SOC_TEGRA20_I2S if ARCH_TEGRA_2x_SOC | ||
146 | select SND_SOC_TEGRA30_I2S if ARCH_TEGRA_3x_SOC | ||
147 | select SND_SOC_SGTL5000 | ||
148 | help | ||
149 | Say Y or M here if you want to add support for SoC audio on Tegra | ||
150 | boards using the SGTL5000 codec, such as Apalis T30, Apalis TK1 or | ||
151 | Colibri T30. | ||
diff --git a/sound/soc/tegra/Makefile b/sound/soc/tegra/Makefile index 9171655ad843..f214a3fd0024 100644 --- a/sound/soc/tegra/Makefile +++ b/sound/soc/tegra/Makefile | |||
@@ -26,6 +26,7 @@ snd-soc-tegra-wm9712-objs := tegra_wm9712.o | |||
26 | snd-soc-tegra-trimslice-objs := trimslice.o | 26 | snd-soc-tegra-trimslice-objs := trimslice.o |
27 | snd-soc-tegra-alc5632-objs := tegra_alc5632.o | 27 | snd-soc-tegra-alc5632-objs := tegra_alc5632.o |
28 | snd-soc-tegra-max98090-objs := tegra_max98090.o | 28 | snd-soc-tegra-max98090-objs := tegra_max98090.o |
29 | snd-soc-tegra-sgtl5000-objs := tegra_sgtl5000.o | ||
29 | 30 | ||
30 | obj-$(CONFIG_SND_SOC_TEGRA_RT5640) += snd-soc-tegra-rt5640.o | 31 | obj-$(CONFIG_SND_SOC_TEGRA_RT5640) += snd-soc-tegra-rt5640.o |
31 | obj-$(CONFIG_SND_SOC_TEGRA_RT5677) += snd-soc-tegra-rt5677.o | 32 | obj-$(CONFIG_SND_SOC_TEGRA_RT5677) += snd-soc-tegra-rt5677.o |
@@ -35,3 +36,4 @@ obj-$(CONFIG_SND_SOC_TEGRA_WM9712) += snd-soc-tegra-wm9712.o | |||
35 | obj-$(CONFIG_SND_SOC_TEGRA_TRIMSLICE) += snd-soc-tegra-trimslice.o | 36 | obj-$(CONFIG_SND_SOC_TEGRA_TRIMSLICE) += snd-soc-tegra-trimslice.o |
36 | obj-$(CONFIG_SND_SOC_TEGRA_ALC5632) += snd-soc-tegra-alc5632.o | 37 | obj-$(CONFIG_SND_SOC_TEGRA_ALC5632) += snd-soc-tegra-alc5632.o |
37 | obj-$(CONFIG_SND_SOC_TEGRA_MAX98090) += snd-soc-tegra-max98090.o | 38 | obj-$(CONFIG_SND_SOC_TEGRA_MAX98090) += snd-soc-tegra-max98090.o |
39 | obj-$(CONFIG_SND_SOC_TEGRA_SGTL5000) += snd-soc-tegra-sgtl5000.o \ No newline at end of file | ||
diff --git a/sound/soc/tegra/tegra_rt5640.c b/sound/soc/tegra/tegra_rt5640.c index 773daecaa5e8..e5ef4e9c4ac5 100644 --- a/sound/soc/tegra/tegra_rt5640.c +++ b/sound/soc/tegra/tegra_rt5640.c | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * tegra_rt5640.c - Tegra machine ASoC driver for boards using WM8903 codec. | 2 | * tegra_rt5640.c - Tegra machine ASoC driver for boards using RT5640 codec. |
3 | * | 3 | * |
4 | * Copyright (c) 2013, NVIDIA CORPORATION. All rights reserved. | 4 | * Copyright (c) 2013, NVIDIA CORPORATION. All rights reserved. |
5 | * | 5 | * |
diff --git a/sound/soc/tegra/tegra_sgtl5000.c b/sound/soc/tegra/tegra_sgtl5000.c new file mode 100644 index 000000000000..1e76869dd488 --- /dev/null +++ b/sound/soc/tegra/tegra_sgtl5000.c | |||
@@ -0,0 +1,212 @@ | |||
1 | /* | ||
2 | * tegra_sgtl5000.c - Tegra machine ASoC driver for boards using SGTL5000 codec | ||
3 | * | ||
4 | * Author: Marcel Ziswiler <marcel@ziswiler.com> | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify it | ||
7 | * under the terms and conditions of the GNU General Public License, | ||
8 | * version 2, as published by the Free Software Foundation. | ||
9 | * | ||
10 | * This program is distributed in the hope it will be useful, but WITHOUT | ||
11 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
12 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
13 | * more details. | ||
14 | * | ||
15 | * You should have received a copy of the GNU General Public License | ||
16 | * along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
17 | * | ||
18 | * Based on code copyright/by: | ||
19 | * | ||
20 | * Copyright (C) 2010-2012 - NVIDIA, Inc. | ||
21 | * (c) 2009, 2010 Nvidia Graphics Pvt. Ltd. | ||
22 | * Copyright 2007 Wolfson Microelectronics PLC. | ||
23 | */ | ||
24 | |||
25 | #include <linux/module.h> | ||
26 | #include <linux/platform_device.h> | ||
27 | #include <linux/slab.h> | ||
28 | #include <linux/gpio.h> | ||
29 | #include <linux/of_gpio.h> | ||
30 | |||
31 | #include <sound/core.h> | ||
32 | #include <sound/pcm.h> | ||
33 | #include <sound/pcm_params.h> | ||
34 | #include <sound/soc.h> | ||
35 | |||
36 | #include "../codecs/sgtl5000.h" | ||
37 | |||
38 | #include "tegra_asoc_utils.h" | ||
39 | |||
40 | #define DRV_NAME "tegra-snd-sgtl5000" | ||
41 | |||
42 | struct tegra_sgtl5000 { | ||
43 | struct tegra_asoc_utils_data util_data; | ||
44 | }; | ||
45 | |||
46 | static int tegra_sgtl5000_hw_params(struct snd_pcm_substream *substream, | ||
47 | struct snd_pcm_hw_params *params) | ||
48 | { | ||
49 | struct snd_soc_pcm_runtime *rtd = substream->private_data; | ||
50 | struct snd_soc_dai *codec_dai = rtd->codec_dai; | ||
51 | struct snd_soc_card *card = rtd->card; | ||
52 | struct tegra_sgtl5000 *machine = snd_soc_card_get_drvdata(card); | ||
53 | int srate, mclk; | ||
54 | int err; | ||
55 | |||
56 | srate = params_rate(params); | ||
57 | switch (srate) { | ||
58 | case 11025: | ||
59 | case 22050: | ||
60 | case 44100: | ||
61 | case 88200: | ||
62 | mclk = 11289600; | ||
63 | break; | ||
64 | default: | ||
65 | mclk = 12288000; | ||
66 | break; | ||
67 | } | ||
68 | |||
69 | err = tegra_asoc_utils_set_rate(&machine->util_data, srate, mclk); | ||
70 | if (err < 0) { | ||
71 | dev_err(card->dev, "Can't configure clocks\n"); | ||
72 | return err; | ||
73 | } | ||
74 | |||
75 | err = snd_soc_dai_set_sysclk(codec_dai, SGTL5000_SYSCLK, mclk, | ||
76 | SND_SOC_CLOCK_IN); | ||
77 | if (err < 0) { | ||
78 | dev_err(card->dev, "codec_dai clock not set\n"); | ||
79 | return err; | ||
80 | } | ||
81 | |||
82 | return 0; | ||
83 | } | ||
84 | |||
85 | static struct snd_soc_ops tegra_sgtl5000_ops = { | ||
86 | .hw_params = tegra_sgtl5000_hw_params, | ||
87 | }; | ||
88 | |||
89 | static const struct snd_soc_dapm_widget tegra_sgtl5000_dapm_widgets[] = { | ||
90 | SND_SOC_DAPM_HP("Headphone Jack", NULL), | ||
91 | SND_SOC_DAPM_LINE("Line In Jack", NULL), | ||
92 | SND_SOC_DAPM_MIC("Mic Jack", NULL), | ||
93 | }; | ||
94 | |||
95 | static struct snd_soc_dai_link tegra_sgtl5000_dai = { | ||
96 | .name = "sgtl5000", | ||
97 | .stream_name = "HiFi", | ||
98 | .codec_dai_name = "sgtl5000", | ||
99 | .ops = &tegra_sgtl5000_ops, | ||
100 | .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | | ||
101 | SND_SOC_DAIFMT_CBS_CFS, | ||
102 | }; | ||
103 | |||
104 | static struct snd_soc_card snd_soc_tegra_sgtl5000 = { | ||
105 | .name = "tegra-sgtl5000", | ||
106 | .owner = THIS_MODULE, | ||
107 | .dai_link = &tegra_sgtl5000_dai, | ||
108 | .num_links = 1, | ||
109 | .dapm_widgets = tegra_sgtl5000_dapm_widgets, | ||
110 | .num_dapm_widgets = ARRAY_SIZE(tegra_sgtl5000_dapm_widgets), | ||
111 | .fully_routed = true, | ||
112 | }; | ||
113 | |||
114 | static int tegra_sgtl5000_driver_probe(struct platform_device *pdev) | ||
115 | { | ||
116 | struct device_node *np = pdev->dev.of_node; | ||
117 | struct snd_soc_card *card = &snd_soc_tegra_sgtl5000; | ||
118 | struct tegra_sgtl5000 *machine; | ||
119 | int ret; | ||
120 | |||
121 | machine = devm_kzalloc(&pdev->dev, sizeof(struct tegra_sgtl5000), | ||
122 | GFP_KERNEL); | ||
123 | if (!machine) { | ||
124 | dev_err(&pdev->dev, "Can't allocate tegra_sgtl5000 struct\n"); | ||
125 | return -ENOMEM; | ||
126 | } | ||
127 | |||
128 | card->dev = &pdev->dev; | ||
129 | platform_set_drvdata(pdev, card); | ||
130 | snd_soc_card_set_drvdata(card, machine); | ||
131 | |||
132 | ret = snd_soc_of_parse_card_name(card, "nvidia,model"); | ||
133 | if (ret) | ||
134 | goto err; | ||
135 | |||
136 | ret = snd_soc_of_parse_audio_routing(card, "nvidia,audio-routing"); | ||
137 | if (ret) | ||
138 | goto err; | ||
139 | |||
140 | tegra_sgtl5000_dai.codec_of_node = of_parse_phandle(np, | ||
141 | "nvidia,audio-codec", 0); | ||
142 | if (!tegra_sgtl5000_dai.codec_of_node) { | ||
143 | dev_err(&pdev->dev, | ||
144 | "Property 'nvidia,audio-codec' missing or invalid\n"); | ||
145 | ret = -EINVAL; | ||
146 | goto err; | ||
147 | } | ||
148 | |||
149 | tegra_sgtl5000_dai.cpu_of_node = of_parse_phandle(np, | ||
150 | "nvidia,i2s-controller", 0); | ||
151 | if (!tegra_sgtl5000_dai.cpu_of_node) { | ||
152 | dev_err(&pdev->dev, | ||
153 | "Property 'nvidia,i2s-controller' missing/invalid\n"); | ||
154 | ret = -EINVAL; | ||
155 | goto err; | ||
156 | } | ||
157 | |||
158 | tegra_sgtl5000_dai.platform_of_node = tegra_sgtl5000_dai.cpu_of_node; | ||
159 | |||
160 | ret = tegra_asoc_utils_init(&machine->util_data, &pdev->dev); | ||
161 | if (ret) | ||
162 | goto err; | ||
163 | |||
164 | ret = snd_soc_register_card(card); | ||
165 | if (ret) { | ||
166 | dev_err(&pdev->dev, "snd_soc_register_card failed (%d)\n", | ||
167 | ret); | ||
168 | goto err_fini_utils; | ||
169 | } | ||
170 | |||
171 | return 0; | ||
172 | |||
173 | err_fini_utils: | ||
174 | tegra_asoc_utils_fini(&machine->util_data); | ||
175 | err: | ||
176 | return ret; | ||
177 | } | ||
178 | |||
179 | static int tegra_sgtl5000_driver_remove(struct platform_device *pdev) | ||
180 | { | ||
181 | struct snd_soc_card *card = platform_get_drvdata(pdev); | ||
182 | struct tegra_sgtl5000 *machine = snd_soc_card_get_drvdata(card); | ||
183 | int ret; | ||
184 | |||
185 | ret = snd_soc_unregister_card(card); | ||
186 | |||
187 | tegra_asoc_utils_fini(&machine->util_data); | ||
188 | |||
189 | return ret; | ||
190 | } | ||
191 | |||
192 | static const struct of_device_id tegra_sgtl5000_of_match[] = { | ||
193 | { .compatible = "nvidia,tegra-audio-sgtl5000", }, | ||
194 | { /* sentinel */ }, | ||
195 | }; | ||
196 | |||
197 | static struct platform_driver tegra_sgtl5000_driver = { | ||
198 | .driver = { | ||
199 | .name = DRV_NAME, | ||
200 | .pm = &snd_soc_pm_ops, | ||
201 | .of_match_table = tegra_sgtl5000_of_match, | ||
202 | }, | ||
203 | .probe = tegra_sgtl5000_driver_probe, | ||
204 | .remove = tegra_sgtl5000_driver_remove, | ||
205 | }; | ||
206 | module_platform_driver(tegra_sgtl5000_driver); | ||
207 | |||
208 | MODULE_AUTHOR("Marcel Ziswiler <marcel@ziswiler.com>"); | ||
209 | MODULE_DESCRIPTION("Tegra SGTL5000 machine ASoC driver"); | ||
210 | MODULE_LICENSE("GPL v2"); | ||
211 | MODULE_ALIAS("platform:" DRV_NAME); | ||
212 | MODULE_DEVICE_TABLE(of, tegra_sgtl5000_of_match); | ||
diff --git a/sound/soc/ux500/ux500_msp_dai.c b/sound/soc/ux500/ux500_msp_dai.c index 6d5698b25bd4..b343efd9be5b 100644 --- a/sound/soc/ux500/ux500_msp_dai.c +++ b/sound/soc/ux500/ux500_msp_dai.c | |||
@@ -187,7 +187,7 @@ static int setup_clocking(struct snd_soc_dai *dai, | |||
187 | 187 | ||
188 | default: | 188 | default: |
189 | dev_err(dai->dev, | 189 | dev_err(dai->dev, |
190 | "%s: Error: Unsopported inversion (fmt = 0x%x)!\n", | 190 | "%s: Error: Unsupported inversion (fmt = 0x%x)!\n", |
191 | __func__, fmt); | 191 | __func__, fmt); |
192 | 192 | ||
193 | return -EINVAL; | 193 | return -EINVAL; |
@@ -218,7 +218,7 @@ static int setup_clocking(struct snd_soc_dai *dai, | |||
218 | break; | 218 | break; |
219 | 219 | ||
220 | default: | 220 | default: |
221 | dev_err(dai->dev, "%s: Error: Unsopported master (fmt = 0x%x)!\n", | 221 | dev_err(dai->dev, "%s: Error: Unsupported master (fmt = 0x%x)!\n", |
222 | __func__, fmt); | 222 | __func__, fmt); |
223 | 223 | ||
224 | return -EINVAL; | 224 | return -EINVAL; |
@@ -374,7 +374,7 @@ static int setup_msp_config(struct snd_pcm_substream *substream, | |||
374 | break; | 374 | break; |
375 | 375 | ||
376 | default: | 376 | default: |
377 | dev_err(dai->dev, "%s: Error: Unsopported format (%d)!\n", | 377 | dev_err(dai->dev, "%s: Error: Unsupported format (%d)!\n", |
378 | __func__, fmt); | 378 | __func__, fmt); |
379 | return -EINVAL; | 379 | return -EINVAL; |
380 | } | 380 | } |
diff --git a/sound/usb/caiaq/audio.c b/sound/usb/caiaq/audio.c index 327f8642ca80..8f66ba730d69 100644 --- a/sound/usb/caiaq/audio.c +++ b/sound/usb/caiaq/audio.c | |||
@@ -739,7 +739,6 @@ static struct urb **alloc_urbs(struct snd_usb_caiaqdev *cdev, int dir, int *ret) | |||
739 | for (i = 0; i < N_URBS; i++) { | 739 | for (i = 0; i < N_URBS; i++) { |
740 | urbs[i] = usb_alloc_urb(FRAMES_PER_URB, GFP_KERNEL); | 740 | urbs[i] = usb_alloc_urb(FRAMES_PER_URB, GFP_KERNEL); |
741 | if (!urbs[i]) { | 741 | if (!urbs[i]) { |
742 | dev_err(dev, "unable to usb_alloc_urb(), OOM!?\n"); | ||
743 | *ret = -ENOMEM; | 742 | *ret = -ENOMEM; |
744 | return urbs; | 743 | return urbs; |
745 | } | 744 | } |
diff --git a/sound/usb/card.h b/sound/usb/card.h index 71778ca4b26a..111b0f009afa 100644 --- a/sound/usb/card.h +++ b/sound/usb/card.h | |||
@@ -92,7 +92,7 @@ struct snd_usb_endpoint { | |||
92 | unsigned int curframesize; /* current packet size in frames (for capture) */ | 92 | unsigned int curframesize; /* current packet size in frames (for capture) */ |
93 | unsigned int syncmaxsize; /* sync endpoint packet size */ | 93 | unsigned int syncmaxsize; /* sync endpoint packet size */ |
94 | unsigned int fill_max:1; /* fill max packet size always */ | 94 | unsigned int fill_max:1; /* fill max packet size always */ |
95 | unsigned int udh01_fb_quirk:1; /* corrupted feedback data */ | 95 | unsigned int tenor_fb_quirk:1; /* corrupted feedback data */ |
96 | unsigned int datainterval; /* log_2 of data packet interval */ | 96 | unsigned int datainterval; /* log_2 of data packet interval */ |
97 | unsigned int syncinterval; /* P for adaptive mode, 0 otherwise */ | 97 | unsigned int syncinterval; /* P for adaptive mode, 0 otherwise */ |
98 | unsigned char silence_value; | 98 | unsigned char silence_value; |
diff --git a/sound/usb/endpoint.c b/sound/usb/endpoint.c index c07a7eda42a2..c470251cea4b 100644 --- a/sound/usb/endpoint.c +++ b/sound/usb/endpoint.c | |||
@@ -502,10 +502,6 @@ struct snd_usb_endpoint *snd_usb_add_endpoint(struct snd_usb_audio *chip, | |||
502 | ep->syncinterval = 3; | 502 | ep->syncinterval = 3; |
503 | 503 | ||
504 | ep->syncmaxsize = le16_to_cpu(get_endpoint(alts, 1)->wMaxPacketSize); | 504 | ep->syncmaxsize = le16_to_cpu(get_endpoint(alts, 1)->wMaxPacketSize); |
505 | |||
506 | if (chip->usb_id == USB_ID(0x0644, 0x8038) /* TEAC UD-H01 */ && | ||
507 | ep->syncmaxsize == 4) | ||
508 | ep->udh01_fb_quirk = 1; | ||
509 | } | 505 | } |
510 | 506 | ||
511 | list_add_tail(&ep->list, &chip->ep_list); | 507 | list_add_tail(&ep->list, &chip->ep_list); |
@@ -1171,15 +1167,16 @@ void snd_usb_handle_sync_urb(struct snd_usb_endpoint *ep, | |||
1171 | if (f == 0) | 1167 | if (f == 0) |
1172 | return; | 1168 | return; |
1173 | 1169 | ||
1174 | if (unlikely(sender->udh01_fb_quirk)) { | 1170 | if (unlikely(sender->tenor_fb_quirk)) { |
1175 | /* | 1171 | /* |
1176 | * The TEAC UD-H01 firmware sometimes changes the feedback value | 1172 | * Devices based on Tenor 8802 chipsets (TEAC UD-H01 |
1173 | * and others) sometimes change the feedback value | ||
1177 | * by +/- 0x1.0000. | 1174 | * by +/- 0x1.0000. |
1178 | */ | 1175 | */ |
1179 | if (f < ep->freqn - 0x8000) | 1176 | if (f < ep->freqn - 0x8000) |
1180 | f += 0x10000; | 1177 | f += 0xf000; |
1181 | else if (f > ep->freqn + 0x8000) | 1178 | else if (f > ep->freqn + 0x8000) |
1182 | f -= 0x10000; | 1179 | f -= 0xf000; |
1183 | } else if (unlikely(ep->freqshift == INT_MIN)) { | 1180 | } else if (unlikely(ep->freqshift == INT_MIN)) { |
1184 | /* | 1181 | /* |
1185 | * The first time we see a feedback value, determine its format | 1182 | * The first time we see a feedback value, determine its format |
diff --git a/sound/usb/format.c b/sound/usb/format.c index 789d19ec035d..2c44386e5569 100644 --- a/sound/usb/format.c +++ b/sound/usb/format.c | |||
@@ -176,10 +176,8 @@ static int parse_audio_format_rates_v1(struct snd_usb_audio *chip, struct audiof | |||
176 | int r, idx; | 176 | int r, idx; |
177 | 177 | ||
178 | fp->rate_table = kmalloc(sizeof(int) * nr_rates, GFP_KERNEL); | 178 | fp->rate_table = kmalloc(sizeof(int) * nr_rates, GFP_KERNEL); |
179 | if (fp->rate_table == NULL) { | 179 | if (fp->rate_table == NULL) |
180 | usb_audio_err(chip, "cannot malloc\n"); | ||
181 | return -ENOMEM; | 180 | return -ENOMEM; |
182 | } | ||
183 | 181 | ||
184 | fp->nr_rates = 0; | 182 | fp->nr_rates = 0; |
185 | fp->rate_min = fp->rate_max = 0; | 183 | fp->rate_min = fp->rate_max = 0; |
diff --git a/sound/usb/line6/Kconfig b/sound/usb/line6/Kconfig index f4585d378ef3..39b400392d71 100644 --- a/sound/usb/line6/Kconfig +++ b/sound/usb/line6/Kconfig | |||
@@ -2,6 +2,7 @@ config SND_USB_LINE6 | |||
2 | tristate | 2 | tristate |
3 | select SND_RAWMIDI | 3 | select SND_RAWMIDI |
4 | select SND_PCM | 4 | select SND_PCM |
5 | select SND_HWDEP | ||
5 | 6 | ||
6 | config SND_USB_POD | 7 | config SND_USB_POD |
7 | tristate "Line 6 POD USB support" | 8 | tristate "Line 6 POD USB support" |
@@ -21,10 +22,10 @@ config SND_USB_POD | |||
21 | re-amping) | 22 | re-amping) |
22 | 23 | ||
23 | config SND_USB_PODHD | 24 | config SND_USB_PODHD |
24 | tristate "Line 6 POD HD300/400/500 USB support" | 25 | tristate "Line 6 POD X3/HD300/400/500 USB support" |
25 | select SND_USB_LINE6 | 26 | select SND_USB_LINE6 |
26 | help | 27 | help |
27 | This is a driver for POD HD300, 400 and 500 devices. | 28 | This is a driver for POD X3, HD300, 400 and 500 devices. |
28 | 29 | ||
29 | config SND_USB_TONEPORT | 30 | config SND_USB_TONEPORT |
30 | tristate "TonePort GX, UX1 and UX2 USB support" | 31 | tristate "TonePort GX, UX1 and UX2 USB support" |
diff --git a/sound/usb/line6/capture.c b/sound/usb/line6/capture.c index f518fbbe88de..7c812565f90d 100644 --- a/sound/usb/line6/capture.c +++ b/sound/usb/line6/capture.c | |||
@@ -29,10 +29,10 @@ static int submit_audio_in_urb(struct snd_line6_pcm *line6pcm) | |||
29 | int ret; | 29 | int ret; |
30 | struct urb *urb_in; | 30 | struct urb *urb_in; |
31 | 31 | ||
32 | index = | 32 | index = find_first_zero_bit(&line6pcm->in.active_urbs, |
33 | find_first_zero_bit(&line6pcm->in.active_urbs, LINE6_ISO_BUFFERS); | 33 | line6pcm->line6->iso_buffers); |
34 | 34 | ||
35 | if (index < 0 || index >= LINE6_ISO_BUFFERS) { | 35 | if (index < 0 || index >= line6pcm->line6->iso_buffers) { |
36 | dev_err(line6pcm->line6->ifcdev, "no free URB found\n"); | 36 | dev_err(line6pcm->line6->ifcdev, "no free URB found\n"); |
37 | return -EINVAL; | 37 | return -EINVAL; |
38 | } | 38 | } |
@@ -44,13 +44,13 @@ static int submit_audio_in_urb(struct snd_line6_pcm *line6pcm) | |||
44 | struct usb_iso_packet_descriptor *fin = | 44 | struct usb_iso_packet_descriptor *fin = |
45 | &urb_in->iso_frame_desc[i]; | 45 | &urb_in->iso_frame_desc[i]; |
46 | fin->offset = urb_size; | 46 | fin->offset = urb_size; |
47 | fin->length = line6pcm->max_packet_size; | 47 | fin->length = line6pcm->max_packet_size_in; |
48 | urb_size += line6pcm->max_packet_size; | 48 | urb_size += line6pcm->max_packet_size_in; |
49 | } | 49 | } |
50 | 50 | ||
51 | urb_in->transfer_buffer = | 51 | urb_in->transfer_buffer = |
52 | line6pcm->in.buffer + | 52 | line6pcm->in.buffer + |
53 | index * LINE6_ISO_PACKETS * line6pcm->max_packet_size; | 53 | index * LINE6_ISO_PACKETS * line6pcm->max_packet_size_in; |
54 | urb_in->transfer_buffer_length = urb_size; | 54 | urb_in->transfer_buffer_length = urb_size; |
55 | urb_in->context = line6pcm; | 55 | urb_in->context = line6pcm; |
56 | 56 | ||
@@ -73,7 +73,7 @@ int line6_submit_audio_in_all_urbs(struct snd_line6_pcm *line6pcm) | |||
73 | { | 73 | { |
74 | int ret = 0, i; | 74 | int ret = 0, i; |
75 | 75 | ||
76 | for (i = 0; i < LINE6_ISO_BUFFERS; ++i) { | 76 | for (i = 0; i < line6pcm->line6->iso_buffers; ++i) { |
77 | ret = submit_audio_in_urb(line6pcm); | 77 | ret = submit_audio_in_urb(line6pcm); |
78 | if (ret < 0) | 78 | if (ret < 0) |
79 | break; | 79 | break; |
@@ -90,7 +90,9 @@ void line6_capture_copy(struct snd_line6_pcm *line6pcm, char *fbuf, int fsize) | |||
90 | struct snd_pcm_substream *substream = | 90 | struct snd_pcm_substream *substream = |
91 | get_substream(line6pcm, SNDRV_PCM_STREAM_CAPTURE); | 91 | get_substream(line6pcm, SNDRV_PCM_STREAM_CAPTURE); |
92 | struct snd_pcm_runtime *runtime = substream->runtime; | 92 | struct snd_pcm_runtime *runtime = substream->runtime; |
93 | const int bytes_per_frame = line6pcm->properties->bytes_per_frame; | 93 | const int bytes_per_frame = |
94 | line6pcm->properties->bytes_per_channel * | ||
95 | line6pcm->properties->capture_hw.channels_max; | ||
94 | int frames = fsize / bytes_per_frame; | 96 | int frames = fsize / bytes_per_frame; |
95 | 97 | ||
96 | if (runtime == NULL) | 98 | if (runtime == NULL) |
@@ -154,7 +156,7 @@ static void audio_in_callback(struct urb *urb) | |||
154 | line6pcm->in.last_frame = urb->start_frame; | 156 | line6pcm->in.last_frame = urb->start_frame; |
155 | 157 | ||
156 | /* find index of URB */ | 158 | /* find index of URB */ |
157 | for (index = 0; index < LINE6_ISO_BUFFERS; ++index) | 159 | for (index = 0; index < line6pcm->line6->iso_buffers; ++index) |
158 | if (urb == line6pcm->in.urbs[index]) | 160 | if (urb == line6pcm->in.urbs[index]) |
159 | break; | 161 | break; |
160 | 162 | ||
@@ -173,17 +175,27 @@ static void audio_in_callback(struct urb *urb) | |||
173 | fbuf = urb->transfer_buffer + fin->offset; | 175 | fbuf = urb->transfer_buffer + fin->offset; |
174 | fsize = fin->actual_length; | 176 | fsize = fin->actual_length; |
175 | 177 | ||
176 | if (fsize > line6pcm->max_packet_size) { | 178 | if (fsize > line6pcm->max_packet_size_in) { |
177 | dev_err(line6pcm->line6->ifcdev, | 179 | dev_err(line6pcm->line6->ifcdev, |
178 | "driver and/or device bug: packet too large (%d > %d)\n", | 180 | "driver and/or device bug: packet too large (%d > %d)\n", |
179 | fsize, line6pcm->max_packet_size); | 181 | fsize, line6pcm->max_packet_size_in); |
180 | } | 182 | } |
181 | 183 | ||
182 | length += fsize; | 184 | length += fsize; |
183 | 185 | ||
184 | /* the following assumes LINE6_ISO_PACKETS == 1: */ | 186 | BUILD_BUG_ON_MSG(LINE6_ISO_PACKETS != 1, |
187 | "The following code assumes LINE6_ISO_PACKETS == 1"); | ||
188 | /* TODO: | ||
189 | * Also, if iso_buffers != 2, the prev frame is almost random at | ||
190 | * playback side. | ||
191 | * This needs to be redesigned. It should be "stable", but we may | ||
192 | * experience sync problems on such high-speed configs. | ||
193 | */ | ||
194 | |||
185 | line6pcm->prev_fbuf = fbuf; | 195 | line6pcm->prev_fbuf = fbuf; |
186 | line6pcm->prev_fsize = fsize; | 196 | line6pcm->prev_fsize = fsize / |
197 | (line6pcm->properties->bytes_per_channel * | ||
198 | line6pcm->properties->capture_hw.channels_max); | ||
187 | 199 | ||
188 | if (!test_bit(LINE6_STREAM_IMPULSE, &line6pcm->in.running) && | 200 | if (!test_bit(LINE6_STREAM_IMPULSE, &line6pcm->in.running) && |
189 | test_bit(LINE6_STREAM_PCM, &line6pcm->in.running) && | 201 | test_bit(LINE6_STREAM_PCM, &line6pcm->in.running) && |
@@ -220,6 +232,8 @@ static int snd_line6_capture_open(struct snd_pcm_substream *substream) | |||
220 | if (err < 0) | 232 | if (err < 0) |
221 | return err; | 233 | return err; |
222 | 234 | ||
235 | line6_pcm_acquire(line6pcm, LINE6_STREAM_CAPTURE_HELPER, false); | ||
236 | |||
223 | runtime->hw = line6pcm->properties->capture_hw; | 237 | runtime->hw = line6pcm->properties->capture_hw; |
224 | return 0; | 238 | return 0; |
225 | } | 239 | } |
@@ -227,6 +241,9 @@ static int snd_line6_capture_open(struct snd_pcm_substream *substream) | |||
227 | /* close capture callback */ | 241 | /* close capture callback */ |
228 | static int snd_line6_capture_close(struct snd_pcm_substream *substream) | 242 | static int snd_line6_capture_close(struct snd_pcm_substream *substream) |
229 | { | 243 | { |
244 | struct snd_line6_pcm *line6pcm = snd_pcm_substream_chip(substream); | ||
245 | |||
246 | line6_pcm_release(line6pcm, LINE6_STREAM_CAPTURE_HELPER); | ||
230 | return 0; | 247 | return 0; |
231 | } | 248 | } |
232 | 249 | ||
@@ -247,8 +264,13 @@ int line6_create_audio_in_urbs(struct snd_line6_pcm *line6pcm) | |||
247 | struct usb_line6 *line6 = line6pcm->line6; | 264 | struct usb_line6 *line6 = line6pcm->line6; |
248 | int i; | 265 | int i; |
249 | 266 | ||
267 | line6pcm->in.urbs = kzalloc( | ||
268 | sizeof(struct urb *) * line6->iso_buffers, GFP_KERNEL); | ||
269 | if (line6pcm->in.urbs == NULL) | ||
270 | return -ENOMEM; | ||
271 | |||
250 | /* create audio URBs and fill in constant values: */ | 272 | /* create audio URBs and fill in constant values: */ |
251 | for (i = 0; i < LINE6_ISO_BUFFERS; ++i) { | 273 | for (i = 0; i < line6->iso_buffers; ++i) { |
252 | struct urb *urb; | 274 | struct urb *urb; |
253 | 275 | ||
254 | /* URB for audio in: */ | 276 | /* URB for audio in: */ |
diff --git a/sound/usb/line6/driver.c b/sound/usb/line6/driver.c index 81b7da8e56d3..14e587e70655 100644 --- a/sound/usb/line6/driver.c +++ b/sound/usb/line6/driver.c | |||
@@ -17,6 +17,7 @@ | |||
17 | 17 | ||
18 | #include <sound/core.h> | 18 | #include <sound/core.h> |
19 | #include <sound/initval.h> | 19 | #include <sound/initval.h> |
20 | #include <sound/hwdep.h> | ||
20 | 21 | ||
21 | #include "capture.h" | 22 | #include "capture.h" |
22 | #include "driver.h" | 23 | #include "driver.h" |
@@ -29,7 +30,7 @@ | |||
29 | /* | 30 | /* |
30 | This is Line 6's MIDI manufacturer ID. | 31 | This is Line 6's MIDI manufacturer ID. |
31 | */ | 32 | */ |
32 | const unsigned char line6_midi_id[] = { | 33 | const unsigned char line6_midi_id[3] = { |
33 | 0x00, 0x01, 0x0c | 34 | 0x00, 0x01, 0x0c |
34 | }; | 35 | }; |
35 | EXPORT_SYMBOL_GPL(line6_midi_id); | 36 | EXPORT_SYMBOL_GPL(line6_midi_id); |
@@ -66,10 +67,17 @@ static int line6_start_listen(struct usb_line6 *line6) | |||
66 | { | 67 | { |
67 | int err; | 68 | int err; |
68 | 69 | ||
69 | usb_fill_int_urb(line6->urb_listen, line6->usbdev, | 70 | if (line6->properties->capabilities & LINE6_CAP_CONTROL_MIDI) { |
70 | usb_rcvintpipe(line6->usbdev, line6->properties->ep_ctrl_r), | 71 | usb_fill_int_urb(line6->urb_listen, line6->usbdev, |
71 | line6->buffer_listen, LINE6_BUFSIZE_LISTEN, | 72 | usb_rcvintpipe(line6->usbdev, line6->properties->ep_ctrl_r), |
72 | line6_data_received, line6, line6->interval); | 73 | line6->buffer_listen, LINE6_BUFSIZE_LISTEN, |
74 | line6_data_received, line6, line6->interval); | ||
75 | } else { | ||
76 | usb_fill_bulk_urb(line6->urb_listen, line6->usbdev, | ||
77 | usb_rcvbulkpipe(line6->usbdev, line6->properties->ep_ctrl_r), | ||
78 | line6->buffer_listen, LINE6_BUFSIZE_LISTEN, | ||
79 | line6_data_received, line6); | ||
80 | } | ||
73 | line6->urb_listen->actual_length = 0; | 81 | line6->urb_listen->actual_length = 0; |
74 | err = usb_submit_urb(line6->urb_listen, GFP_ATOMIC); | 82 | err = usb_submit_urb(line6->urb_listen, GFP_ATOMIC); |
75 | return err; | 83 | return err; |
@@ -90,6 +98,7 @@ static int line6_send_raw_message(struct usb_line6 *line6, const char *buffer, | |||
90 | int size) | 98 | int size) |
91 | { | 99 | { |
92 | int i, done = 0; | 100 | int i, done = 0; |
101 | const struct line6_properties *properties = line6->properties; | ||
93 | 102 | ||
94 | for (i = 0; i < size; i += line6->max_packet_size) { | 103 | for (i = 0; i < size; i += line6->max_packet_size) { |
95 | int partial; | 104 | int partial; |
@@ -97,15 +106,21 @@ static int line6_send_raw_message(struct usb_line6 *line6, const char *buffer, | |||
97 | int frag_size = min(line6->max_packet_size, size - i); | 106 | int frag_size = min(line6->max_packet_size, size - i); |
98 | int retval; | 107 | int retval; |
99 | 108 | ||
100 | retval = usb_interrupt_msg(line6->usbdev, | 109 | if (properties->capabilities & LINE6_CAP_CONTROL_MIDI) { |
101 | usb_sndintpipe(line6->usbdev, | 110 | retval = usb_interrupt_msg(line6->usbdev, |
102 | line6->properties->ep_ctrl_w), | 111 | usb_sndintpipe(line6->usbdev, properties->ep_ctrl_w), |
103 | (char *)frag_buf, frag_size, | 112 | (char *)frag_buf, frag_size, |
104 | &partial, LINE6_TIMEOUT * HZ); | 113 | &partial, LINE6_TIMEOUT * HZ); |
114 | } else { | ||
115 | retval = usb_bulk_msg(line6->usbdev, | ||
116 | usb_sndbulkpipe(line6->usbdev, properties->ep_ctrl_w), | ||
117 | (char *)frag_buf, frag_size, | ||
118 | &partial, LINE6_TIMEOUT * HZ); | ||
119 | } | ||
105 | 120 | ||
106 | if (retval) { | 121 | if (retval) { |
107 | dev_err(line6->ifcdev, | 122 | dev_err(line6->ifcdev, |
108 | "usb_interrupt_msg failed (%d)\n", retval); | 123 | "usb_bulk_msg failed (%d)\n", retval); |
109 | break; | 124 | break; |
110 | } | 125 | } |
111 | 126 | ||
@@ -140,10 +155,17 @@ static int line6_send_raw_message_async_part(struct message *msg, | |||
140 | int done = msg->done; | 155 | int done = msg->done; |
141 | int bytes = min(msg->size - done, line6->max_packet_size); | 156 | int bytes = min(msg->size - done, line6->max_packet_size); |
142 | 157 | ||
143 | usb_fill_int_urb(urb, line6->usbdev, | 158 | if (line6->properties->capabilities & LINE6_CAP_CONTROL_MIDI) { |
144 | usb_sndintpipe(line6->usbdev, line6->properties->ep_ctrl_w), | 159 | usb_fill_int_urb(urb, line6->usbdev, |
145 | (char *)msg->buffer + done, bytes, | 160 | usb_sndintpipe(line6->usbdev, line6->properties->ep_ctrl_w), |
146 | line6_async_request_sent, msg, line6->interval); | 161 | (char *)msg->buffer + done, bytes, |
162 | line6_async_request_sent, msg, line6->interval); | ||
163 | } else { | ||
164 | usb_fill_bulk_urb(urb, line6->usbdev, | ||
165 | usb_sndbulkpipe(line6->usbdev, line6->properties->ep_ctrl_w), | ||
166 | (char *)msg->buffer + done, bytes, | ||
167 | line6_async_request_sent, msg); | ||
168 | } | ||
147 | 169 | ||
148 | msg->done += bytes; | 170 | msg->done += bytes; |
149 | retval = usb_submit_urb(urb, GFP_ATOMIC); | 171 | retval = usb_submit_urb(urb, GFP_ATOMIC); |
@@ -269,28 +291,36 @@ static void line6_data_received(struct urb *urb) | |||
269 | if (urb->status == -ESHUTDOWN) | 291 | if (urb->status == -ESHUTDOWN) |
270 | return; | 292 | return; |
271 | 293 | ||
272 | done = | 294 | if (line6->properties->capabilities & LINE6_CAP_CONTROL_MIDI) { |
273 | line6_midibuf_write(mb, urb->transfer_buffer, urb->actual_length); | 295 | done = |
296 | line6_midibuf_write(mb, urb->transfer_buffer, urb->actual_length); | ||
274 | 297 | ||
275 | if (done < urb->actual_length) { | 298 | if (done < urb->actual_length) { |
276 | line6_midibuf_ignore(mb, done); | 299 | line6_midibuf_ignore(mb, done); |
277 | dev_dbg(line6->ifcdev, "%d %d buffer overflow - message skipped\n", | 300 | dev_dbg(line6->ifcdev, "%d %d buffer overflow - message skipped\n", |
278 | done, urb->actual_length); | 301 | done, urb->actual_length); |
279 | } | 302 | } |
280 | 303 | ||
281 | for (;;) { | 304 | for (;;) { |
282 | done = | 305 | done = |
283 | line6_midibuf_read(mb, line6->buffer_message, | 306 | line6_midibuf_read(mb, line6->buffer_message, |
284 | LINE6_MESSAGE_MAXLEN); | 307 | LINE6_MIDI_MESSAGE_MAXLEN); |
285 | 308 | ||
286 | if (done == 0) | 309 | if (done == 0) |
287 | break; | 310 | break; |
288 | 311 | ||
289 | line6->message_length = done; | 312 | line6->message_length = done; |
290 | line6_midi_receive(line6, line6->buffer_message, done); | 313 | line6_midi_receive(line6, line6->buffer_message, done); |
291 | 314 | ||
315 | if (line6->process_message) | ||
316 | line6->process_message(line6); | ||
317 | } | ||
318 | } else { | ||
319 | line6->buffer_message = urb->transfer_buffer; | ||
320 | line6->message_length = urb->actual_length; | ||
292 | if (line6->process_message) | 321 | if (line6->process_message) |
293 | line6->process_message(line6); | 322 | line6->process_message(line6); |
323 | line6->buffer_message = NULL; | ||
294 | } | 324 | } |
295 | 325 | ||
296 | line6_start_listen(line6); | 326 | line6_start_listen(line6); |
@@ -447,12 +477,16 @@ static void line6_destruct(struct snd_card *card) | |||
447 | struct usb_line6 *line6 = card->private_data; | 477 | struct usb_line6 *line6 = card->private_data; |
448 | struct usb_device *usbdev = line6->usbdev; | 478 | struct usb_device *usbdev = line6->usbdev; |
449 | 479 | ||
450 | /* free buffer memory first: */ | 480 | /* Free buffer memory first. We cannot depend on the existence of private |
481 | * data from the (podhd) module, it may be gone already during this call | ||
482 | */ | ||
451 | kfree(line6->buffer_message); | 483 | kfree(line6->buffer_message); |
484 | |||
452 | kfree(line6->buffer_listen); | 485 | kfree(line6->buffer_listen); |
453 | 486 | ||
454 | /* then free URBs: */ | 487 | /* then free URBs: */ |
455 | usb_free_urb(line6->urb_listen); | 488 | usb_free_urb(line6->urb_listen); |
489 | line6->urb_listen = NULL; | ||
456 | 490 | ||
457 | /* decrement reference counters: */ | 491 | /* decrement reference counters: */ |
458 | usb_put_dev(usbdev); | 492 | usb_put_dev(usbdev); |
@@ -462,13 +496,29 @@ static void line6_destruct(struct snd_card *card) | |||
462 | static void line6_get_interval(struct usb_line6 *line6) | 496 | static void line6_get_interval(struct usb_line6 *line6) |
463 | { | 497 | { |
464 | struct usb_device *usbdev = line6->usbdev; | 498 | struct usb_device *usbdev = line6->usbdev; |
499 | const struct line6_properties *properties = line6->properties; | ||
500 | int pipe; | ||
465 | struct usb_host_endpoint *ep; | 501 | struct usb_host_endpoint *ep; |
466 | unsigned pipe = usb_rcvintpipe(usbdev, line6->properties->ep_ctrl_r); | ||
467 | unsigned epnum = usb_pipeendpoint(pipe); | ||
468 | 502 | ||
469 | ep = usbdev->ep_in[epnum]; | 503 | if (properties->capabilities & LINE6_CAP_CONTROL_MIDI) { |
504 | pipe = | ||
505 | usb_rcvintpipe(line6->usbdev, line6->properties->ep_ctrl_r); | ||
506 | } else { | ||
507 | pipe = | ||
508 | usb_rcvbulkpipe(line6->usbdev, line6->properties->ep_ctrl_r); | ||
509 | } | ||
510 | ep = usbdev->ep_in[usb_pipeendpoint(pipe)]; | ||
511 | |||
470 | if (ep) { | 512 | if (ep) { |
471 | line6->interval = ep->desc.bInterval; | 513 | line6->interval = ep->desc.bInterval; |
514 | if (usbdev->speed == USB_SPEED_LOW) { | ||
515 | line6->intervals_per_second = USB_LOW_INTERVALS_PER_SECOND; | ||
516 | line6->iso_buffers = USB_LOW_ISO_BUFFERS; | ||
517 | } else { | ||
518 | line6->intervals_per_second = USB_HIGH_INTERVALS_PER_SECOND; | ||
519 | line6->iso_buffers = USB_HIGH_ISO_BUFFERS; | ||
520 | } | ||
521 | |||
472 | line6->max_packet_size = le16_to_cpu(ep->desc.wMaxPacketSize); | 522 | line6->max_packet_size = le16_to_cpu(ep->desc.wMaxPacketSize); |
473 | } else { | 523 | } else { |
474 | dev_err(line6->ifcdev, | 524 | dev_err(line6->ifcdev, |
@@ -478,6 +528,138 @@ static void line6_get_interval(struct usb_line6 *line6) | |||
478 | } | 528 | } |
479 | } | 529 | } |
480 | 530 | ||
531 | |||
532 | /* Enable buffering of incoming messages, flush the buffer */ | ||
533 | static int line6_hwdep_open(struct snd_hwdep *hw, struct file *file) | ||
534 | { | ||
535 | struct usb_line6 *line6 = hw->private_data; | ||
536 | |||
537 | /* NOTE: hwdep layer provides atomicity here */ | ||
538 | |||
539 | line6->messages.active = 1; | ||
540 | |||
541 | return 0; | ||
542 | } | ||
543 | |||
544 | /* Stop buffering */ | ||
545 | static int line6_hwdep_release(struct snd_hwdep *hw, struct file *file) | ||
546 | { | ||
547 | struct usb_line6 *line6 = hw->private_data; | ||
548 | |||
549 | line6->messages.active = 0; | ||
550 | |||
551 | return 0; | ||
552 | } | ||
553 | |||
554 | /* Read from circular buffer, return to user */ | ||
555 | static long | ||
556 | line6_hwdep_read(struct snd_hwdep *hwdep, char __user *buf, long count, | ||
557 | loff_t *offset) | ||
558 | { | ||
559 | struct usb_line6 *line6 = hwdep->private_data; | ||
560 | long rv = 0; | ||
561 | unsigned int out_count; | ||
562 | |||
563 | if (mutex_lock_interruptible(&line6->messages.read_lock)) | ||
564 | return -ERESTARTSYS; | ||
565 | |||
566 | while (kfifo_len(&line6->messages.fifo) == 0) { | ||
567 | mutex_unlock(&line6->messages.read_lock); | ||
568 | |||
569 | rv = wait_event_interruptible( | ||
570 | line6->messages.wait_queue, | ||
571 | kfifo_len(&line6->messages.fifo) != 0); | ||
572 | if (rv < 0) | ||
573 | return rv; | ||
574 | |||
575 | if (mutex_lock_interruptible(&line6->messages.read_lock)) | ||
576 | return -ERESTARTSYS; | ||
577 | } | ||
578 | |||
579 | if (kfifo_peek_len(&line6->messages.fifo) > count) { | ||
580 | /* Buffer too small; allow re-read of the current item... */ | ||
581 | rv = -EINVAL; | ||
582 | } else { | ||
583 | rv = kfifo_to_user(&line6->messages.fifo, buf, count, &out_count); | ||
584 | if (rv == 0) | ||
585 | rv = out_count; | ||
586 | } | ||
587 | |||
588 | mutex_unlock(&line6->messages.read_lock); | ||
589 | return rv; | ||
590 | } | ||
591 | |||
592 | /* Write directly (no buffering) to device by user*/ | ||
593 | static long | ||
594 | line6_hwdep_write(struct snd_hwdep *hwdep, const char __user *data, long count, | ||
595 | loff_t *offset) | ||
596 | { | ||
597 | struct usb_line6 *line6 = hwdep->private_data; | ||
598 | int rv; | ||
599 | char *data_copy; | ||
600 | |||
601 | if (count > line6->max_packet_size * LINE6_RAW_MESSAGES_MAXCOUNT) { | ||
602 | /* This is an arbitrary limit - still better than nothing... */ | ||
603 | return -EINVAL; | ||
604 | } | ||
605 | |||
606 | data_copy = memdup_user(data, count); | ||
607 | if (IS_ERR(ERR_PTR)) | ||
608 | return -ENOMEM; | ||
609 | |||
610 | rv = line6_send_raw_message(line6, data_copy, count); | ||
611 | |||
612 | kfree(data_copy); | ||
613 | return rv; | ||
614 | } | ||
615 | |||
616 | static const struct snd_hwdep_ops hwdep_ops = { | ||
617 | .open = line6_hwdep_open, | ||
618 | .release = line6_hwdep_release, | ||
619 | .read = line6_hwdep_read, | ||
620 | .write = line6_hwdep_write, | ||
621 | }; | ||
622 | |||
623 | /* Insert into circular buffer */ | ||
624 | static void line6_hwdep_push_message(struct usb_line6 *line6) | ||
625 | { | ||
626 | if (!line6->messages.active) | ||
627 | return; | ||
628 | |||
629 | if (kfifo_avail(&line6->messages.fifo) >= line6->message_length) { | ||
630 | /* No race condition here, there's only one writer */ | ||
631 | kfifo_in(&line6->messages.fifo, | ||
632 | line6->buffer_message, line6->message_length); | ||
633 | } /* else TODO: signal overflow */ | ||
634 | |||
635 | wake_up_interruptible(&line6->messages.wait_queue); | ||
636 | } | ||
637 | |||
638 | static int line6_hwdep_init(struct usb_line6 *line6) | ||
639 | { | ||
640 | int err; | ||
641 | struct snd_hwdep *hwdep; | ||
642 | |||
643 | /* TODO: usb_driver_claim_interface(); */ | ||
644 | line6->process_message = line6_hwdep_push_message; | ||
645 | line6->messages.active = 0; | ||
646 | init_waitqueue_head(&line6->messages.wait_queue); | ||
647 | mutex_init(&line6->messages.read_lock); | ||
648 | INIT_KFIFO(line6->messages.fifo); | ||
649 | |||
650 | err = snd_hwdep_new(line6->card, "config", 0, &hwdep); | ||
651 | if (err < 0) | ||
652 | goto end; | ||
653 | strcpy(hwdep->name, "config"); | ||
654 | hwdep->iface = SNDRV_HWDEP_IFACE_LINE6; | ||
655 | hwdep->ops = hwdep_ops; | ||
656 | hwdep->private_data = line6; | ||
657 | hwdep->exclusive = true; | ||
658 | |||
659 | end: | ||
660 | return err; | ||
661 | } | ||
662 | |||
481 | static int line6_init_cap_control(struct usb_line6 *line6) | 663 | static int line6_init_cap_control(struct usb_line6 *line6) |
482 | { | 664 | { |
483 | int ret; | 665 | int ret; |
@@ -487,14 +669,20 @@ static int line6_init_cap_control(struct usb_line6 *line6) | |||
487 | if (!line6->buffer_listen) | 669 | if (!line6->buffer_listen) |
488 | return -ENOMEM; | 670 | return -ENOMEM; |
489 | 671 | ||
490 | line6->buffer_message = kmalloc(LINE6_MESSAGE_MAXLEN, GFP_KERNEL); | ||
491 | if (!line6->buffer_message) | ||
492 | return -ENOMEM; | ||
493 | |||
494 | line6->urb_listen = usb_alloc_urb(0, GFP_KERNEL); | 672 | line6->urb_listen = usb_alloc_urb(0, GFP_KERNEL); |
495 | if (!line6->urb_listen) | 673 | if (!line6->urb_listen) |
496 | return -ENOMEM; | 674 | return -ENOMEM; |
497 | 675 | ||
676 | if (line6->properties->capabilities & LINE6_CAP_CONTROL_MIDI) { | ||
677 | line6->buffer_message = kmalloc(LINE6_MIDI_MESSAGE_MAXLEN, GFP_KERNEL); | ||
678 | if (!line6->buffer_message) | ||
679 | return -ENOMEM; | ||
680 | } else { | ||
681 | ret = line6_hwdep_init(line6); | ||
682 | if (ret < 0) | ||
683 | return ret; | ||
684 | } | ||
685 | |||
498 | ret = line6_start_listen(line6); | 686 | ret = line6_start_listen(line6); |
499 | if (ret < 0) { | 687 | if (ret < 0) { |
500 | dev_err(line6->ifcdev, "cannot start listening: %d\n", ret); | 688 | dev_err(line6->ifcdev, "cannot start listening: %d\n", ret); |
@@ -558,6 +746,7 @@ int line6_probe(struct usb_interface *interface, | |||
558 | /* query interface number */ | 746 | /* query interface number */ |
559 | interface_number = interface->cur_altsetting->desc.bInterfaceNumber; | 747 | interface_number = interface->cur_altsetting->desc.bInterfaceNumber; |
560 | 748 | ||
749 | /* TODO reserves the bus bandwidth even without actual transfer */ | ||
561 | ret = usb_set_interface(usbdev, interface_number, | 750 | ret = usb_set_interface(usbdev, interface_number, |
562 | properties->altsetting); | 751 | properties->altsetting); |
563 | if (ret < 0) { | 752 | if (ret < 0) { |
@@ -565,9 +754,8 @@ int line6_probe(struct usb_interface *interface, | |||
565 | goto error; | 754 | goto error; |
566 | } | 755 | } |
567 | 756 | ||
568 | line6_get_interval(line6); | ||
569 | |||
570 | if (properties->capabilities & LINE6_CAP_CONTROL) { | 757 | if (properties->capabilities & LINE6_CAP_CONTROL) { |
758 | line6_get_interval(line6); | ||
571 | ret = line6_init_cap_control(line6); | 759 | ret = line6_init_cap_control(line6); |
572 | if (ret < 0) | 760 | if (ret < 0) |
573 | goto error; | 761 | goto error; |
@@ -670,3 +858,4 @@ EXPORT_SYMBOL_GPL(line6_resume); | |||
670 | MODULE_AUTHOR(DRIVER_AUTHOR); | 858 | MODULE_AUTHOR(DRIVER_AUTHOR); |
671 | MODULE_DESCRIPTION(DRIVER_DESC); | 859 | MODULE_DESCRIPTION(DRIVER_DESC); |
672 | MODULE_LICENSE("GPL"); | 860 | MODULE_LICENSE("GPL"); |
861 | |||
diff --git a/sound/usb/line6/driver.h b/sound/usb/line6/driver.h index 7da643e79e3b..7e3a3aada222 100644 --- a/sound/usb/line6/driver.h +++ b/sound/usb/line6/driver.h | |||
@@ -12,21 +12,37 @@ | |||
12 | #ifndef DRIVER_H | 12 | #ifndef DRIVER_H |
13 | #define DRIVER_H | 13 | #define DRIVER_H |
14 | 14 | ||
15 | #include <linux/spinlock.h> | ||
16 | #include <linux/usb.h> | 15 | #include <linux/usb.h> |
16 | #include <linux/mutex.h> | ||
17 | #include <linux/kfifo.h> | ||
17 | #include <sound/core.h> | 18 | #include <sound/core.h> |
18 | 19 | ||
19 | #include "midi.h" | 20 | #include "midi.h" |
20 | 21 | ||
21 | #define USB_INTERVALS_PER_SECOND 1000 | 22 | /* USB 1.1 speed configuration */ |
23 | #define USB_LOW_INTERVALS_PER_SECOND 1000 | ||
24 | #define USB_LOW_ISO_BUFFERS 2 | ||
25 | |||
26 | /* USB 2.0+ speed configuration */ | ||
27 | #define USB_HIGH_INTERVALS_PER_SECOND 8000 | ||
28 | #define USB_HIGH_ISO_BUFFERS 16 | ||
22 | 29 | ||
23 | /* Fallback USB interval and max packet size values */ | 30 | /* Fallback USB interval and max packet size values */ |
24 | #define LINE6_FALLBACK_INTERVAL 10 | 31 | #define LINE6_FALLBACK_INTERVAL 10 |
25 | #define LINE6_FALLBACK_MAXPACKETSIZE 16 | 32 | #define LINE6_FALLBACK_MAXPACKETSIZE 16 |
26 | 33 | ||
27 | #define LINE6_TIMEOUT 1 | 34 | #define LINE6_TIMEOUT 1 |
28 | #define LINE6_BUFSIZE_LISTEN 32 | 35 | #define LINE6_BUFSIZE_LISTEN 64 |
29 | #define LINE6_MESSAGE_MAXLEN 256 | 36 | #define LINE6_MIDI_MESSAGE_MAXLEN 256 |
37 | |||
38 | #define LINE6_RAW_MESSAGES_MAXCOUNT_ORDER 7 | ||
39 | /* 4k packets are common, BUFSIZE * MAXCOUNT should be bigger... */ | ||
40 | #define LINE6_RAW_MESSAGES_MAXCOUNT (1 << LINE6_RAW_MESSAGES_MAXCOUNT_ORDER) | ||
41 | |||
42 | |||
43 | #if LINE6_BUFSIZE_LISTEN > 65535 | ||
44 | #error "Use dynamic fifo instead" | ||
45 | #endif | ||
30 | 46 | ||
31 | /* | 47 | /* |
32 | Line 6 MIDI control commands | 48 | Line 6 MIDI control commands |
@@ -94,8 +110,12 @@ enum { | |||
94 | LINE6_CAP_CONTROL = 1 << 0, | 110 | LINE6_CAP_CONTROL = 1 << 0, |
95 | /* device supports PCM input/output via USB */ | 111 | /* device supports PCM input/output via USB */ |
96 | LINE6_CAP_PCM = 1 << 1, | 112 | LINE6_CAP_PCM = 1 << 1, |
97 | /* device support hardware monitoring */ | 113 | /* device supports hardware monitoring */ |
98 | LINE6_CAP_HWMON = 1 << 2, | 114 | LINE6_CAP_HWMON = 1 << 2, |
115 | /* device requires output data when input is read */ | ||
116 | LINE6_CAP_IN_NEEDS_OUT = 1 << 3, | ||
117 | /* device uses raw MIDI via USB (data endpoints) */ | ||
118 | LINE6_CAP_CONTROL_MIDI = 1 << 4, | ||
99 | }; | 119 | }; |
100 | 120 | ||
101 | /* | 121 | /* |
@@ -109,10 +129,15 @@ struct usb_line6 { | |||
109 | /* Properties */ | 129 | /* Properties */ |
110 | const struct line6_properties *properties; | 130 | const struct line6_properties *properties; |
111 | 131 | ||
112 | /* Interval (ms) */ | 132 | /* Interval for data USB packets */ |
113 | int interval; | 133 | int interval; |
134 | /* ...for isochronous transfers framing */ | ||
135 | int intervals_per_second; | ||
136 | |||
137 | /* Number of isochronous URBs used for frame transfers */ | ||
138 | int iso_buffers; | ||
114 | 139 | ||
115 | /* Maximum size of USB packet */ | 140 | /* Maximum size of data USB packet */ |
116 | int max_packet_size; | 141 | int max_packet_size; |
117 | 142 | ||
118 | /* Device representing the USB interface */ | 143 | /* Device representing the USB interface */ |
@@ -129,18 +154,30 @@ struct usb_line6 { | |||
129 | /* Line 6 MIDI device data structure */ | 154 | /* Line 6 MIDI device data structure */ |
130 | struct snd_line6_midi *line6midi; | 155 | struct snd_line6_midi *line6midi; |
131 | 156 | ||
132 | /* URB for listening to PODxt Pro control endpoint */ | 157 | /* URB for listening to POD data endpoint */ |
133 | struct urb *urb_listen; | 158 | struct urb *urb_listen; |
134 | 159 | ||
135 | /* Buffer for listening to PODxt Pro control endpoint */ | 160 | /* Buffer for incoming data from POD data endpoint */ |
136 | unsigned char *buffer_listen; | 161 | unsigned char *buffer_listen; |
137 | 162 | ||
138 | /* Buffer for message to be processed */ | 163 | /* Buffer for message to be processed, generated from MIDI layer */ |
139 | unsigned char *buffer_message; | 164 | unsigned char *buffer_message; |
140 | 165 | ||
141 | /* Length of message to be processed */ | 166 | /* Length of message to be processed, generated from MIDI layer */ |
142 | int message_length; | 167 | int message_length; |
143 | 168 | ||
169 | /* Circular buffer for non-MIDI control messages */ | ||
170 | struct { | ||
171 | struct mutex read_lock; | ||
172 | wait_queue_head_t wait_queue; | ||
173 | unsigned int active:1; | ||
174 | STRUCT_KFIFO_REC_2(LINE6_BUFSIZE_LISTEN * LINE6_RAW_MESSAGES_MAXCOUNT) | ||
175 | fifo; | ||
176 | } messages; | ||
177 | |||
178 | /* If MIDI is supported, buffer_message contains the pre-processed data; | ||
179 | * otherwise the data is only in urb_listen (buffer_incoming). | ||
180 | */ | ||
144 | void (*process_message)(struct usb_line6 *); | 181 | void (*process_message)(struct usb_line6 *); |
145 | void (*disconnect)(struct usb_line6 *line6); | 182 | void (*disconnect)(struct usb_line6 *line6); |
146 | }; | 183 | }; |
diff --git a/sound/usb/line6/midi.c b/sound/usb/line6/midi.c index cebea9b7f769..d0fb2f205bd9 100644 --- a/sound/usb/line6/midi.c +++ b/sound/usb/line6/midi.c | |||
@@ -258,7 +258,7 @@ int line6_init_midi(struct usb_line6 *line6) | |||
258 | struct snd_rawmidi *rmidi; | 258 | struct snd_rawmidi *rmidi; |
259 | struct snd_line6_midi *line6midi; | 259 | struct snd_line6_midi *line6midi; |
260 | 260 | ||
261 | if (!(line6->properties->capabilities & LINE6_CAP_CONTROL)) { | 261 | if (!(line6->properties->capabilities & LINE6_CAP_CONTROL_MIDI)) { |
262 | /* skip MIDI initialization and report success */ | 262 | /* skip MIDI initialization and report success */ |
263 | return 0; | 263 | return 0; |
264 | } | 264 | } |
diff --git a/sound/usb/line6/pcm.c b/sound/usb/line6/pcm.c index 41aa3355e920..fab53f58d447 100644 --- a/sound/usb/line6/pcm.c +++ b/sound/usb/line6/pcm.c | |||
@@ -52,7 +52,7 @@ static int snd_line6_impulse_volume_put(struct snd_kcontrol *kcontrol, | |||
52 | 52 | ||
53 | line6pcm->impulse_volume = value; | 53 | line6pcm->impulse_volume = value; |
54 | if (value > 0) { | 54 | if (value > 0) { |
55 | err = line6_pcm_acquire(line6pcm, LINE6_STREAM_IMPULSE); | 55 | err = line6_pcm_acquire(line6pcm, LINE6_STREAM_IMPULSE, true); |
56 | if (err < 0) { | 56 | if (err < 0) { |
57 | line6pcm->impulse_volume = 0; | 57 | line6pcm->impulse_volume = 0; |
58 | return err; | 58 | return err; |
@@ -104,7 +104,7 @@ static void line6_unlink_audio_urbs(struct snd_line6_pcm *line6pcm, | |||
104 | { | 104 | { |
105 | int i; | 105 | int i; |
106 | 106 | ||
107 | for (i = 0; i < LINE6_ISO_BUFFERS; i++) { | 107 | for (i = 0; i < line6pcm->line6->iso_buffers; i++) { |
108 | if (test_bit(i, &pcms->active_urbs)) { | 108 | if (test_bit(i, &pcms->active_urbs)) { |
109 | if (!test_and_set_bit(i, &pcms->unlink_urbs)) | 109 | if (!test_and_set_bit(i, &pcms->unlink_urbs)) |
110 | usb_unlink_urb(pcms->urbs[i]); | 110 | usb_unlink_urb(pcms->urbs[i]); |
@@ -124,7 +124,7 @@ static void line6_wait_clear_audio_urbs(struct snd_line6_pcm *line6pcm, | |||
124 | 124 | ||
125 | do { | 125 | do { |
126 | alive = 0; | 126 | alive = 0; |
127 | for (i = 0; i < LINE6_ISO_BUFFERS; i++) { | 127 | for (i = 0; i < line6pcm->line6->iso_buffers; i++) { |
128 | if (test_bit(i, &pcms->active_urbs)) | 128 | if (test_bit(i, &pcms->active_urbs)) |
129 | alive++; | 129 | alive++; |
130 | } | 130 | } |
@@ -146,15 +146,20 @@ get_stream(struct snd_line6_pcm *line6pcm, int direction) | |||
146 | } | 146 | } |
147 | 147 | ||
148 | /* allocate a buffer if not opened yet; | 148 | /* allocate a buffer if not opened yet; |
149 | * call this in line6pcm.state_change mutex | 149 | * call this in line6pcm.state_mutex |
150 | */ | 150 | */ |
151 | static int line6_buffer_acquire(struct snd_line6_pcm *line6pcm, | 151 | static int line6_buffer_acquire(struct snd_line6_pcm *line6pcm, |
152 | struct line6_pcm_stream *pstr, int type) | 152 | struct line6_pcm_stream *pstr, int direction, int type) |
153 | { | 153 | { |
154 | const int pkt_size = | ||
155 | (direction == SNDRV_PCM_STREAM_PLAYBACK) ? | ||
156 | line6pcm->max_packet_size_out : | ||
157 | line6pcm->max_packet_size_in; | ||
158 | |||
154 | /* Invoked multiple times in a row so allocate once only */ | 159 | /* Invoked multiple times in a row so allocate once only */ |
155 | if (!test_and_set_bit(type, &pstr->opened) && !pstr->buffer) { | 160 | if (!test_and_set_bit(type, &pstr->opened) && !pstr->buffer) { |
156 | pstr->buffer = kmalloc(LINE6_ISO_BUFFERS * LINE6_ISO_PACKETS * | 161 | pstr->buffer = kmalloc(line6pcm->line6->iso_buffers * |
157 | line6pcm->max_packet_size, GFP_KERNEL); | 162 | LINE6_ISO_PACKETS * pkt_size, GFP_KERNEL); |
158 | if (!pstr->buffer) | 163 | if (!pstr->buffer) |
159 | return -ENOMEM; | 164 | return -ENOMEM; |
160 | } | 165 | } |
@@ -162,12 +167,11 @@ static int line6_buffer_acquire(struct snd_line6_pcm *line6pcm, | |||
162 | } | 167 | } |
163 | 168 | ||
164 | /* free a buffer if all streams are closed; | 169 | /* free a buffer if all streams are closed; |
165 | * call this in line6pcm.state_change mutex | 170 | * call this in line6pcm.state_mutex |
166 | */ | 171 | */ |
167 | static void line6_buffer_release(struct snd_line6_pcm *line6pcm, | 172 | static void line6_buffer_release(struct snd_line6_pcm *line6pcm, |
168 | struct line6_pcm_stream *pstr, int type) | 173 | struct line6_pcm_stream *pstr, int type) |
169 | { | 174 | { |
170 | |||
171 | clear_bit(type, &pstr->opened); | 175 | clear_bit(type, &pstr->opened); |
172 | if (!pstr->opened) { | 176 | if (!pstr->opened) { |
173 | line6_wait_clear_audio_urbs(line6pcm, pstr); | 177 | line6_wait_clear_audio_urbs(line6pcm, pstr); |
@@ -194,6 +198,7 @@ static int line6_stream_start(struct snd_line6_pcm *line6pcm, int direction, | |||
194 | else | 198 | else |
195 | ret = line6_submit_audio_in_all_urbs(line6pcm); | 199 | ret = line6_submit_audio_in_all_urbs(line6pcm); |
196 | } | 200 | } |
201 | |||
197 | if (ret < 0) | 202 | if (ret < 0) |
198 | clear_bit(type, &pstr->running); | 203 | clear_bit(type, &pstr->running); |
199 | spin_unlock_irqrestore(&pstr->lock, flags); | 204 | spin_unlock_irqrestore(&pstr->lock, flags); |
@@ -237,6 +242,14 @@ int snd_line6_trigger(struct snd_pcm_substream *substream, int cmd) | |||
237 | switch (cmd) { | 242 | switch (cmd) { |
238 | case SNDRV_PCM_TRIGGER_START: | 243 | case SNDRV_PCM_TRIGGER_START: |
239 | case SNDRV_PCM_TRIGGER_RESUME: | 244 | case SNDRV_PCM_TRIGGER_RESUME: |
245 | if (s->stream == SNDRV_PCM_STREAM_CAPTURE && | ||
246 | (line6pcm->line6->properties->capabilities & | ||
247 | LINE6_CAP_IN_NEEDS_OUT)) { | ||
248 | err = line6_stream_start(line6pcm, SNDRV_PCM_STREAM_PLAYBACK, | ||
249 | LINE6_STREAM_CAPTURE_HELPER); | ||
250 | if (err < 0) | ||
251 | return err; | ||
252 | } | ||
240 | err = line6_stream_start(line6pcm, s->stream, | 253 | err = line6_stream_start(line6pcm, s->stream, |
241 | LINE6_STREAM_PCM); | 254 | LINE6_STREAM_PCM); |
242 | if (err < 0) | 255 | if (err < 0) |
@@ -245,6 +258,12 @@ int snd_line6_trigger(struct snd_pcm_substream *substream, int cmd) | |||
245 | 258 | ||
246 | case SNDRV_PCM_TRIGGER_STOP: | 259 | case SNDRV_PCM_TRIGGER_STOP: |
247 | case SNDRV_PCM_TRIGGER_SUSPEND: | 260 | case SNDRV_PCM_TRIGGER_SUSPEND: |
261 | if (s->stream == SNDRV_PCM_STREAM_CAPTURE && | ||
262 | (line6pcm->line6->properties->capabilities & | ||
263 | LINE6_CAP_IN_NEEDS_OUT)) { | ||
264 | line6_stream_stop(line6pcm, SNDRV_PCM_STREAM_PLAYBACK, | ||
265 | LINE6_STREAM_CAPTURE_HELPER); | ||
266 | } | ||
248 | line6_stream_stop(line6pcm, s->stream, | 267 | line6_stream_stop(line6pcm, s->stream, |
249 | LINE6_STREAM_PCM); | 268 | LINE6_STREAM_PCM); |
250 | break; | 269 | break; |
@@ -278,27 +297,30 @@ snd_pcm_uframes_t snd_line6_pointer(struct snd_pcm_substream *substream) | |||
278 | return pstr->pos_done; | 297 | return pstr->pos_done; |
279 | } | 298 | } |
280 | 299 | ||
281 | /* Acquire and start duplex streams: | 300 | /* Acquire and optionally start duplex streams: |
282 | * type is either LINE6_STREAM_IMPULSE or LINE6_STREAM_MONITOR | 301 | * type is either LINE6_STREAM_IMPULSE or LINE6_STREAM_MONITOR |
283 | */ | 302 | */ |
284 | int line6_pcm_acquire(struct snd_line6_pcm *line6pcm, int type) | 303 | int line6_pcm_acquire(struct snd_line6_pcm *line6pcm, int type, bool start) |
285 | { | 304 | { |
286 | struct line6_pcm_stream *pstr; | 305 | struct line6_pcm_stream *pstr; |
287 | int ret = 0, dir; | 306 | int ret = 0, dir; |
288 | 307 | ||
308 | /* TODO: We should assert SNDRV_PCM_STREAM_PLAYBACK/CAPTURE == 0/1 */ | ||
289 | mutex_lock(&line6pcm->state_mutex); | 309 | mutex_lock(&line6pcm->state_mutex); |
290 | for (dir = 0; dir < 2; dir++) { | 310 | for (dir = 0; dir < 2; dir++) { |
291 | pstr = get_stream(line6pcm, dir); | 311 | pstr = get_stream(line6pcm, dir); |
292 | ret = line6_buffer_acquire(line6pcm, pstr, type); | 312 | ret = line6_buffer_acquire(line6pcm, pstr, dir, type); |
293 | if (ret < 0) | 313 | if (ret < 0) |
294 | goto error; | 314 | goto error; |
295 | if (!pstr->running) | 315 | if (!pstr->running) |
296 | line6_wait_clear_audio_urbs(line6pcm, pstr); | 316 | line6_wait_clear_audio_urbs(line6pcm, pstr); |
297 | } | 317 | } |
298 | for (dir = 0; dir < 2; dir++) { | 318 | if (start) { |
299 | ret = line6_stream_start(line6pcm, dir, type); | 319 | for (dir = 0; dir < 2; dir++) { |
300 | if (ret < 0) | 320 | ret = line6_stream_start(line6pcm, dir, type); |
301 | goto error; | 321 | if (ret < 0) |
322 | goto error; | ||
323 | } | ||
302 | } | 324 | } |
303 | error: | 325 | error: |
304 | mutex_unlock(&line6pcm->state_mutex); | 326 | mutex_unlock(&line6pcm->state_mutex); |
@@ -334,7 +356,8 @@ int snd_line6_hw_params(struct snd_pcm_substream *substream, | |||
334 | struct line6_pcm_stream *pstr = get_stream(line6pcm, substream->stream); | 356 | struct line6_pcm_stream *pstr = get_stream(line6pcm, substream->stream); |
335 | 357 | ||
336 | mutex_lock(&line6pcm->state_mutex); | 358 | mutex_lock(&line6pcm->state_mutex); |
337 | ret = line6_buffer_acquire(line6pcm, pstr, LINE6_STREAM_PCM); | 359 | ret = line6_buffer_acquire(line6pcm, pstr, substream->stream, |
360 | LINE6_STREAM_PCM); | ||
338 | if (ret < 0) | 361 | if (ret < 0) |
339 | goto error; | 362 | goto error; |
340 | 363 | ||
@@ -434,24 +457,30 @@ static struct snd_kcontrol_new line6_controls[] = { | |||
434 | /* | 457 | /* |
435 | Cleanup the PCM device. | 458 | Cleanup the PCM device. |
436 | */ | 459 | */ |
437 | static void cleanup_urbs(struct line6_pcm_stream *pcms) | 460 | static void cleanup_urbs(struct line6_pcm_stream *pcms, int iso_buffers) |
438 | { | 461 | { |
439 | int i; | 462 | int i; |
440 | 463 | ||
441 | for (i = 0; i < LINE6_ISO_BUFFERS; i++) { | 464 | /* Most likely impossible in current code... */ |
465 | if (pcms->urbs == NULL) | ||
466 | return; | ||
467 | |||
468 | for (i = 0; i < iso_buffers; i++) { | ||
442 | if (pcms->urbs[i]) { | 469 | if (pcms->urbs[i]) { |
443 | usb_kill_urb(pcms->urbs[i]); | 470 | usb_kill_urb(pcms->urbs[i]); |
444 | usb_free_urb(pcms->urbs[i]); | 471 | usb_free_urb(pcms->urbs[i]); |
445 | } | 472 | } |
446 | } | 473 | } |
474 | kfree(pcms->urbs); | ||
475 | pcms->urbs = NULL; | ||
447 | } | 476 | } |
448 | 477 | ||
449 | static void line6_cleanup_pcm(struct snd_pcm *pcm) | 478 | static void line6_cleanup_pcm(struct snd_pcm *pcm) |
450 | { | 479 | { |
451 | struct snd_line6_pcm *line6pcm = snd_pcm_chip(pcm); | 480 | struct snd_line6_pcm *line6pcm = snd_pcm_chip(pcm); |
452 | 481 | ||
453 | cleanup_urbs(&line6pcm->out); | 482 | cleanup_urbs(&line6pcm->out, line6pcm->line6->iso_buffers); |
454 | cleanup_urbs(&line6pcm->in); | 483 | cleanup_urbs(&line6pcm->in, line6pcm->line6->iso_buffers); |
455 | kfree(line6pcm); | 484 | kfree(line6pcm); |
456 | } | 485 | } |
457 | 486 | ||
@@ -523,12 +552,12 @@ int line6_init_pcm(struct usb_line6 *line6, | |||
523 | line6pcm->volume_monitor = 255; | 552 | line6pcm->volume_monitor = 255; |
524 | line6pcm->line6 = line6; | 553 | line6pcm->line6 = line6; |
525 | 554 | ||
526 | /* Read and write buffers are sized identically, so choose minimum */ | 555 | line6pcm->max_packet_size_in = |
527 | line6pcm->max_packet_size = min( | 556 | usb_maxpacket(line6->usbdev, |
528 | usb_maxpacket(line6->usbdev, | 557 | usb_rcvisocpipe(line6->usbdev, ep_read), 0); |
529 | usb_rcvisocpipe(line6->usbdev, ep_read), 0), | 558 | line6pcm->max_packet_size_out = |
530 | usb_maxpacket(line6->usbdev, | 559 | usb_maxpacket(line6->usbdev, |
531 | usb_sndisocpipe(line6->usbdev, ep_write), 1)); | 560 | usb_sndisocpipe(line6->usbdev, ep_write), 1); |
532 | 561 | ||
533 | spin_lock_init(&line6pcm->out.lock); | 562 | spin_lock_init(&line6pcm->out.lock); |
534 | spin_lock_init(&line6pcm->in.lock); | 563 | spin_lock_init(&line6pcm->in.lock); |
diff --git a/sound/usb/line6/pcm.h b/sound/usb/line6/pcm.h index 508410adbd51..bb0c9cbf2a78 100644 --- a/sound/usb/line6/pcm.h +++ b/sound/usb/line6/pcm.h | |||
@@ -20,9 +20,6 @@ | |||
20 | 20 | ||
21 | #include "driver.h" | 21 | #include "driver.h" |
22 | 22 | ||
23 | /* number of URBs */ | ||
24 | #define LINE6_ISO_BUFFERS 2 | ||
25 | |||
26 | /* | 23 | /* |
27 | number of USB frames per URB | 24 | number of USB frames per URB |
28 | The Line 6 Windows driver always transmits two frames per packet, but | 25 | The Line 6 Windows driver always transmits two frames per packet, but |
@@ -31,7 +28,9 @@ | |||
31 | */ | 28 | */ |
32 | #define LINE6_ISO_PACKETS 1 | 29 | #define LINE6_ISO_PACKETS 1 |
33 | 30 | ||
34 | /* in a "full speed" device (such as the PODxt Pro) this means 1ms */ | 31 | /* in a "full speed" device (such as the PODxt Pro) this means 1ms, |
32 | * for "high speed" it's 1/8ms | ||
33 | */ | ||
35 | #define LINE6_ISO_INTERVAL 1 | 34 | #define LINE6_ISO_INTERVAL 1 |
36 | 35 | ||
37 | #define LINE6_IMPULSE_DEFAULT_PERIOD 100 | 36 | #define LINE6_IMPULSE_DEFAULT_PERIOD 100 |
@@ -74,6 +73,7 @@ enum { | |||
74 | LINE6_STREAM_PCM, | 73 | LINE6_STREAM_PCM, |
75 | LINE6_STREAM_MONITOR, | 74 | LINE6_STREAM_MONITOR, |
76 | LINE6_STREAM_IMPULSE, | 75 | LINE6_STREAM_IMPULSE, |
76 | LINE6_STREAM_CAPTURE_HELPER, | ||
77 | }; | 77 | }; |
78 | 78 | ||
79 | /* misc bit flags for PCM operation */ | 79 | /* misc bit flags for PCM operation */ |
@@ -85,12 +85,12 @@ enum { | |||
85 | struct line6_pcm_properties { | 85 | struct line6_pcm_properties { |
86 | struct snd_pcm_hardware playback_hw, capture_hw; | 86 | struct snd_pcm_hardware playback_hw, capture_hw; |
87 | struct snd_pcm_hw_constraint_ratdens rates; | 87 | struct snd_pcm_hw_constraint_ratdens rates; |
88 | int bytes_per_frame; | 88 | int bytes_per_channel; |
89 | }; | 89 | }; |
90 | 90 | ||
91 | struct line6_pcm_stream { | 91 | struct line6_pcm_stream { |
92 | /* allocated URBs */ | 92 | /* allocated URBs */ |
93 | struct urb *urbs[LINE6_ISO_BUFFERS]; | 93 | struct urb **urbs; |
94 | 94 | ||
95 | /* Temporary buffer; | 95 | /* Temporary buffer; |
96 | * Since the packet size is not known in advance, this buffer is | 96 | * Since the packet size is not known in advance, this buffer is |
@@ -157,11 +157,12 @@ struct snd_line6_pcm { | |||
157 | /* Previously captured frame (for software monitoring) */ | 157 | /* Previously captured frame (for software monitoring) */ |
158 | unsigned char *prev_fbuf; | 158 | unsigned char *prev_fbuf; |
159 | 159 | ||
160 | /* Size of previously captured frame (for software monitoring) */ | 160 | /* Size of previously captured frame (for software monitoring/sync) */ |
161 | int prev_fsize; | 161 | int prev_fsize; |
162 | 162 | ||
163 | /* Maximum size of USB packet */ | 163 | /* Maximum size of USB packet */ |
164 | int max_packet_size; | 164 | int max_packet_size_in; |
165 | int max_packet_size_out; | ||
165 | 166 | ||
166 | /* PCM playback volume (left and right) */ | 167 | /* PCM playback volume (left and right) */ |
167 | int volume_playback[2]; | 168 | int volume_playback[2]; |
@@ -191,7 +192,8 @@ extern int snd_line6_hw_params(struct snd_pcm_substream *substream, | |||
191 | extern int snd_line6_hw_free(struct snd_pcm_substream *substream); | 192 | extern int snd_line6_hw_free(struct snd_pcm_substream *substream); |
192 | extern snd_pcm_uframes_t snd_line6_pointer(struct snd_pcm_substream *substream); | 193 | extern snd_pcm_uframes_t snd_line6_pointer(struct snd_pcm_substream *substream); |
193 | extern void line6_pcm_disconnect(struct snd_line6_pcm *line6pcm); | 194 | extern void line6_pcm_disconnect(struct snd_line6_pcm *line6pcm); |
194 | extern int line6_pcm_acquire(struct snd_line6_pcm *line6pcm, int type); | 195 | extern int line6_pcm_acquire(struct snd_line6_pcm *line6pcm, int type, |
196 | bool start); | ||
195 | extern void line6_pcm_release(struct snd_line6_pcm *line6pcm, int type); | 197 | extern void line6_pcm_release(struct snd_line6_pcm *line6pcm, int type); |
196 | 198 | ||
197 | #endif | 199 | #endif |
diff --git a/sound/usb/line6/playback.c b/sound/usb/line6/playback.c index 97ed593f6010..812d18191e01 100644 --- a/sound/usb/line6/playback.c +++ b/sound/usb/line6/playback.c | |||
@@ -146,18 +146,20 @@ static int submit_audio_out_urb(struct snd_line6_pcm *line6pcm) | |||
146 | int index; | 146 | int index; |
147 | int i, urb_size, urb_frames; | 147 | int i, urb_size, urb_frames; |
148 | int ret; | 148 | int ret; |
149 | const int bytes_per_frame = line6pcm->properties->bytes_per_frame; | 149 | const int bytes_per_frame = |
150 | line6pcm->properties->bytes_per_channel * | ||
151 | line6pcm->properties->playback_hw.channels_max; | ||
150 | const int frame_increment = | 152 | const int frame_increment = |
151 | line6pcm->properties->rates.rats[0].num_min; | 153 | line6pcm->properties->rates.rats[0].num_min; |
152 | const int frame_factor = | 154 | const int frame_factor = |
153 | line6pcm->properties->rates.rats[0].den * | 155 | line6pcm->properties->rates.rats[0].den * |
154 | (USB_INTERVALS_PER_SECOND / LINE6_ISO_INTERVAL); | 156 | (line6pcm->line6->intervals_per_second / LINE6_ISO_INTERVAL); |
155 | struct urb *urb_out; | 157 | struct urb *urb_out; |
156 | 158 | ||
157 | index = | 159 | index = find_first_zero_bit(&line6pcm->out.active_urbs, |
158 | find_first_zero_bit(&line6pcm->out.active_urbs, LINE6_ISO_BUFFERS); | 160 | line6pcm->line6->iso_buffers); |
159 | 161 | ||
160 | if (index < 0 || index >= LINE6_ISO_BUFFERS) { | 162 | if (index < 0 || index >= line6pcm->line6->iso_buffers) { |
161 | dev_err(line6pcm->line6->ifcdev, "no free URB found\n"); | 163 | dev_err(line6pcm->line6->ifcdev, "no free URB found\n"); |
162 | return -EINVAL; | 164 | return -EINVAL; |
163 | } | 165 | } |
@@ -165,6 +167,7 @@ static int submit_audio_out_urb(struct snd_line6_pcm *line6pcm) | |||
165 | urb_out = line6pcm->out.urbs[index]; | 167 | urb_out = line6pcm->out.urbs[index]; |
166 | urb_size = 0; | 168 | urb_size = 0; |
167 | 169 | ||
170 | /* TODO: this may not work for LINE6_ISO_PACKETS != 1 */ | ||
168 | for (i = 0; i < LINE6_ISO_PACKETS; ++i) { | 171 | for (i = 0; i < LINE6_ISO_PACKETS; ++i) { |
169 | /* compute frame size for given sampling rate */ | 172 | /* compute frame size for given sampling rate */ |
170 | int fsize = 0; | 173 | int fsize = 0; |
@@ -178,9 +181,11 @@ static int submit_audio_out_urb(struct snd_line6_pcm *line6pcm) | |||
178 | line6pcm->out.count += frame_increment; | 181 | line6pcm->out.count += frame_increment; |
179 | n = line6pcm->out.count / frame_factor; | 182 | n = line6pcm->out.count / frame_factor; |
180 | line6pcm->out.count -= n * frame_factor; | 183 | line6pcm->out.count -= n * frame_factor; |
181 | fsize = n * bytes_per_frame; | 184 | fsize = n; |
182 | } | 185 | } |
183 | 186 | ||
187 | fsize *= bytes_per_frame; | ||
188 | |||
184 | fout->offset = urb_size; | 189 | fout->offset = urb_size; |
185 | fout->length = fsize; | 190 | fout->length = fsize; |
186 | urb_size += fsize; | 191 | urb_size += fsize; |
@@ -195,7 +200,7 @@ static int submit_audio_out_urb(struct snd_line6_pcm *line6pcm) | |||
195 | urb_frames = urb_size / bytes_per_frame; | 200 | urb_frames = urb_size / bytes_per_frame; |
196 | urb_out->transfer_buffer = | 201 | urb_out->transfer_buffer = |
197 | line6pcm->out.buffer + | 202 | line6pcm->out.buffer + |
198 | index * LINE6_ISO_PACKETS * line6pcm->max_packet_size; | 203 | index * LINE6_ISO_PACKETS * line6pcm->max_packet_size_out; |
199 | urb_out->transfer_buffer_length = urb_size; | 204 | urb_out->transfer_buffer_length = urb_size; |
200 | urb_out->context = line6pcm; | 205 | urb_out->context = line6pcm; |
201 | 206 | ||
@@ -286,7 +291,7 @@ int line6_submit_audio_out_all_urbs(struct snd_line6_pcm *line6pcm) | |||
286 | { | 291 | { |
287 | int ret = 0, i; | 292 | int ret = 0, i; |
288 | 293 | ||
289 | for (i = 0; i < LINE6_ISO_BUFFERS; ++i) { | 294 | for (i = 0; i < line6pcm->line6->iso_buffers; ++i) { |
290 | ret = submit_audio_out_urb(line6pcm); | 295 | ret = submit_audio_out_urb(line6pcm); |
291 | if (ret < 0) | 296 | if (ret < 0) |
292 | break; | 297 | break; |
@@ -305,6 +310,9 @@ static void audio_out_callback(struct urb *urb) | |||
305 | struct snd_line6_pcm *line6pcm = (struct snd_line6_pcm *)urb->context; | 310 | struct snd_line6_pcm *line6pcm = (struct snd_line6_pcm *)urb->context; |
306 | struct snd_pcm_substream *substream = | 311 | struct snd_pcm_substream *substream = |
307 | get_substream(line6pcm, SNDRV_PCM_STREAM_PLAYBACK); | 312 | get_substream(line6pcm, SNDRV_PCM_STREAM_PLAYBACK); |
313 | const int bytes_per_frame = | ||
314 | line6pcm->properties->bytes_per_channel * | ||
315 | line6pcm->properties->playback_hw.channels_max; | ||
308 | 316 | ||
309 | #if USE_CLEAR_BUFFER_WORKAROUND | 317 | #if USE_CLEAR_BUFFER_WORKAROUND |
310 | memset(urb->transfer_buffer, 0, urb->transfer_buffer_length); | 318 | memset(urb->transfer_buffer, 0, urb->transfer_buffer_length); |
@@ -313,11 +321,11 @@ static void audio_out_callback(struct urb *urb) | |||
313 | line6pcm->out.last_frame = urb->start_frame; | 321 | line6pcm->out.last_frame = urb->start_frame; |
314 | 322 | ||
315 | /* find index of URB */ | 323 | /* find index of URB */ |
316 | for (index = 0; index < LINE6_ISO_BUFFERS; index++) | 324 | for (index = 0; index < line6pcm->line6->iso_buffers; index++) |
317 | if (urb == line6pcm->out.urbs[index]) | 325 | if (urb == line6pcm->out.urbs[index]) |
318 | break; | 326 | break; |
319 | 327 | ||
320 | if (index >= LINE6_ISO_BUFFERS) | 328 | if (index >= line6pcm->line6->iso_buffers) |
321 | return; /* URB has been unlinked asynchronously */ | 329 | return; /* URB has been unlinked asynchronously */ |
322 | 330 | ||
323 | for (i = 0; i < LINE6_ISO_PACKETS; i++) | 331 | for (i = 0; i < LINE6_ISO_PACKETS; i++) |
@@ -329,7 +337,7 @@ static void audio_out_callback(struct urb *urb) | |||
329 | struct snd_pcm_runtime *runtime = substream->runtime; | 337 | struct snd_pcm_runtime *runtime = substream->runtime; |
330 | 338 | ||
331 | line6pcm->out.pos_done += | 339 | line6pcm->out.pos_done += |
332 | length / line6pcm->properties->bytes_per_frame; | 340 | length / bytes_per_frame; |
333 | 341 | ||
334 | if (line6pcm->out.pos_done >= runtime->buffer_size) | 342 | if (line6pcm->out.pos_done >= runtime->buffer_size) |
335 | line6pcm->out.pos_done -= runtime->buffer_size; | 343 | line6pcm->out.pos_done -= runtime->buffer_size; |
@@ -401,8 +409,13 @@ int line6_create_audio_out_urbs(struct snd_line6_pcm *line6pcm) | |||
401 | struct usb_line6 *line6 = line6pcm->line6; | 409 | struct usb_line6 *line6 = line6pcm->line6; |
402 | int i; | 410 | int i; |
403 | 411 | ||
412 | line6pcm->out.urbs = kzalloc( | ||
413 | sizeof(struct urb *) * line6->iso_buffers, GFP_KERNEL); | ||
414 | if (line6pcm->out.urbs == NULL) | ||
415 | return -ENOMEM; | ||
416 | |||
404 | /* create audio URBs and fill in constant values: */ | 417 | /* create audio URBs and fill in constant values: */ |
405 | for (i = 0; i < LINE6_ISO_BUFFERS; ++i) { | 418 | for (i = 0; i < line6->iso_buffers; ++i) { |
406 | struct urb *urb; | 419 | struct urb *urb; |
407 | 420 | ||
408 | /* URB for audio out: */ | 421 | /* URB for audio out: */ |
diff --git a/sound/usb/line6/pod.c b/sound/usb/line6/pod.c index 45dd34874f43..17aa616e61f5 100644 --- a/sound/usb/line6/pod.c +++ b/sound/usb/line6/pod.c | |||
@@ -83,7 +83,6 @@ struct usb_line6_pod { | |||
83 | }; | 83 | }; |
84 | 84 | ||
85 | #define POD_SYSEX_CODE 3 | 85 | #define POD_SYSEX_CODE 3 |
86 | #define POD_BYTES_PER_FRAME 6 /* 24bit audio (stereo) */ | ||
87 | 86 | ||
88 | /* *INDENT-OFF* */ | 87 | /* *INDENT-OFF* */ |
89 | 88 | ||
@@ -167,7 +166,7 @@ static struct line6_pcm_properties pod_pcm_properties = { | |||
167 | .rates = { | 166 | .rates = { |
168 | .nrats = 1, | 167 | .nrats = 1, |
169 | .rats = &pod_ratden}, | 168 | .rats = &pod_ratden}, |
170 | .bytes_per_frame = POD_BYTES_PER_FRAME | 169 | .bytes_per_channel = 3 /* SNDRV_PCM_FMTBIT_S24_3LE */ |
171 | }; | 170 | }; |
172 | 171 | ||
173 | static const char pod_version_header[] = { | 172 | static const char pod_version_header[] = { |
@@ -476,6 +475,7 @@ static const struct line6_properties pod_properties_table[] = { | |||
476 | .id = "BassPODxt", | 475 | .id = "BassPODxt", |
477 | .name = "BassPODxt", | 476 | .name = "BassPODxt", |
478 | .capabilities = LINE6_CAP_CONTROL | 477 | .capabilities = LINE6_CAP_CONTROL |
478 | | LINE6_CAP_CONTROL_MIDI | ||
479 | | LINE6_CAP_PCM | 479 | | LINE6_CAP_PCM |
480 | | LINE6_CAP_HWMON, | 480 | | LINE6_CAP_HWMON, |
481 | .altsetting = 5, | 481 | .altsetting = 5, |
@@ -488,6 +488,7 @@ static const struct line6_properties pod_properties_table[] = { | |||
488 | .id = "BassPODxtLive", | 488 | .id = "BassPODxtLive", |
489 | .name = "BassPODxt Live", | 489 | .name = "BassPODxt Live", |
490 | .capabilities = LINE6_CAP_CONTROL | 490 | .capabilities = LINE6_CAP_CONTROL |
491 | | LINE6_CAP_CONTROL_MIDI | ||
491 | | LINE6_CAP_PCM | 492 | | LINE6_CAP_PCM |
492 | | LINE6_CAP_HWMON, | 493 | | LINE6_CAP_HWMON, |
493 | .altsetting = 1, | 494 | .altsetting = 1, |
@@ -500,6 +501,7 @@ static const struct line6_properties pod_properties_table[] = { | |||
500 | .id = "BassPODxtPro", | 501 | .id = "BassPODxtPro", |
501 | .name = "BassPODxt Pro", | 502 | .name = "BassPODxt Pro", |
502 | .capabilities = LINE6_CAP_CONTROL | 503 | .capabilities = LINE6_CAP_CONTROL |
504 | | LINE6_CAP_CONTROL_MIDI | ||
503 | | LINE6_CAP_PCM | 505 | | LINE6_CAP_PCM |
504 | | LINE6_CAP_HWMON, | 506 | | LINE6_CAP_HWMON, |
505 | .altsetting = 5, | 507 | .altsetting = 5, |
@@ -511,7 +513,8 @@ static const struct line6_properties pod_properties_table[] = { | |||
511 | [LINE6_POCKETPOD] = { | 513 | [LINE6_POCKETPOD] = { |
512 | .id = "PocketPOD", | 514 | .id = "PocketPOD", |
513 | .name = "Pocket POD", | 515 | .name = "Pocket POD", |
514 | .capabilities = LINE6_CAP_CONTROL, | 516 | .capabilities = LINE6_CAP_CONTROL |
517 | | LINE6_CAP_CONTROL_MIDI, | ||
515 | .altsetting = 0, | 518 | .altsetting = 0, |
516 | .ep_ctrl_r = 0x82, | 519 | .ep_ctrl_r = 0x82, |
517 | .ep_ctrl_w = 0x02, | 520 | .ep_ctrl_w = 0x02, |
@@ -521,6 +524,7 @@ static const struct line6_properties pod_properties_table[] = { | |||
521 | .id = "PODxt", | 524 | .id = "PODxt", |
522 | .name = "PODxt", | 525 | .name = "PODxt", |
523 | .capabilities = LINE6_CAP_CONTROL | 526 | .capabilities = LINE6_CAP_CONTROL |
527 | | LINE6_CAP_CONTROL_MIDI | ||
524 | | LINE6_CAP_PCM | 528 | | LINE6_CAP_PCM |
525 | | LINE6_CAP_HWMON, | 529 | | LINE6_CAP_HWMON, |
526 | .altsetting = 5, | 530 | .altsetting = 5, |
@@ -533,6 +537,7 @@ static const struct line6_properties pod_properties_table[] = { | |||
533 | .id = "PODxtLive", | 537 | .id = "PODxtLive", |
534 | .name = "PODxt Live", | 538 | .name = "PODxt Live", |
535 | .capabilities = LINE6_CAP_CONTROL | 539 | .capabilities = LINE6_CAP_CONTROL |
540 | | LINE6_CAP_CONTROL_MIDI | ||
536 | | LINE6_CAP_PCM | 541 | | LINE6_CAP_PCM |
537 | | LINE6_CAP_HWMON, | 542 | | LINE6_CAP_HWMON, |
538 | .altsetting = 1, | 543 | .altsetting = 1, |
@@ -545,6 +550,7 @@ static const struct line6_properties pod_properties_table[] = { | |||
545 | .id = "PODxtPro", | 550 | .id = "PODxtPro", |
546 | .name = "PODxt Pro", | 551 | .name = "PODxt Pro", |
547 | .capabilities = LINE6_CAP_CONTROL | 552 | .capabilities = LINE6_CAP_CONTROL |
553 | | LINE6_CAP_CONTROL_MIDI | ||
548 | | LINE6_CAP_PCM | 554 | | LINE6_CAP_PCM |
549 | | LINE6_CAP_HWMON, | 555 | | LINE6_CAP_HWMON, |
550 | .altsetting = 5, | 556 | .altsetting = 5, |
diff --git a/sound/usb/line6/podhd.c b/sound/usb/line6/podhd.c index 63dcaef41ac3..9352a44ae6e4 100644 --- a/sound/usb/line6/podhd.c +++ b/sound/usb/line6/podhd.c | |||
@@ -2,6 +2,7 @@ | |||
2 | * Line 6 Pod HD | 2 | * Line 6 Pod HD |
3 | * | 3 | * |
4 | * Copyright (C) 2011 Stefan Hajnoczi <stefanha@gmail.com> | 4 | * Copyright (C) 2011 Stefan Hajnoczi <stefanha@gmail.com> |
5 | * Copyright (C) 2015 Andrej Krutak <dev@andree.sk> | ||
5 | * | 6 | * |
6 | * This program is free software; you can redistribute it and/or | 7 | * This program is free software; you can redistribute it and/or |
7 | * modify it under the terms of the GNU General Public License as | 8 | * modify it under the terms of the GNU General Public License as |
@@ -18,14 +19,46 @@ | |||
18 | #include "driver.h" | 19 | #include "driver.h" |
19 | #include "pcm.h" | 20 | #include "pcm.h" |
20 | 21 | ||
22 | #define PODHD_STARTUP_DELAY 500 | ||
23 | |||
24 | /* | ||
25 | * Stages of POD startup procedure | ||
26 | */ | ||
27 | enum { | ||
28 | PODHD_STARTUP_INIT = 1, | ||
29 | PODHD_STARTUP_SCHEDULE_WORKQUEUE, | ||
30 | PODHD_STARTUP_SETUP, | ||
31 | PODHD_STARTUP_LAST = PODHD_STARTUP_SETUP - 1 | ||
32 | }; | ||
33 | |||
21 | enum { | 34 | enum { |
22 | LINE6_PODHD300, | 35 | LINE6_PODHD300, |
23 | LINE6_PODHD400, | 36 | LINE6_PODHD400, |
24 | LINE6_PODHD500_0, | 37 | LINE6_PODHD500_0, |
25 | LINE6_PODHD500_1, | 38 | LINE6_PODHD500_1, |
39 | LINE6_PODX3, | ||
40 | LINE6_PODX3LIVE | ||
26 | }; | 41 | }; |
27 | 42 | ||
28 | #define PODHD_BYTES_PER_FRAME 6 /* 24bit audio (stereo) */ | 43 | struct usb_line6_podhd { |
44 | /* Generic Line 6 USB data */ | ||
45 | struct usb_line6 line6; | ||
46 | |||
47 | /* Timer for device initialization */ | ||
48 | struct timer_list startup_timer; | ||
49 | |||
50 | /* Work handler for device initialization */ | ||
51 | struct work_struct startup_work; | ||
52 | |||
53 | /* Current progress in startup procedure */ | ||
54 | int startup_progress; | ||
55 | |||
56 | /* Serial number of device */ | ||
57 | u32 serial_number; | ||
58 | |||
59 | /* Firmware version */ | ||
60 | int firmware_version; | ||
61 | }; | ||
29 | 62 | ||
30 | static struct snd_ratden podhd_ratden = { | 63 | static struct snd_ratden podhd_ratden = { |
31 | .num_min = 48000, | 64 | .num_min = 48000, |
@@ -73,29 +106,233 @@ static struct line6_pcm_properties podhd_pcm_properties = { | |||
73 | .rates = { | 106 | .rates = { |
74 | .nrats = 1, | 107 | .nrats = 1, |
75 | .rats = &podhd_ratden}, | 108 | .rats = &podhd_ratden}, |
76 | .bytes_per_frame = PODHD_BYTES_PER_FRAME | 109 | .bytes_per_channel = 3 /* SNDRV_PCM_FMTBIT_S24_3LE */ |
110 | }; | ||
111 | |||
112 | static struct line6_pcm_properties podx3_pcm_properties = { | ||
113 | .playback_hw = { | ||
114 | .info = (SNDRV_PCM_INFO_MMAP | | ||
115 | SNDRV_PCM_INFO_INTERLEAVED | | ||
116 | SNDRV_PCM_INFO_BLOCK_TRANSFER | | ||
117 | SNDRV_PCM_INFO_MMAP_VALID | | ||
118 | SNDRV_PCM_INFO_PAUSE | | ||
119 | SNDRV_PCM_INFO_SYNC_START), | ||
120 | .formats = SNDRV_PCM_FMTBIT_S24_3LE, | ||
121 | .rates = SNDRV_PCM_RATE_48000, | ||
122 | .rate_min = 48000, | ||
123 | .rate_max = 48000, | ||
124 | .channels_min = 2, | ||
125 | .channels_max = 2, | ||
126 | .buffer_bytes_max = 60000, | ||
127 | .period_bytes_min = 64, | ||
128 | .period_bytes_max = 8192, | ||
129 | .periods_min = 1, | ||
130 | .periods_max = 1024}, | ||
131 | .capture_hw = { | ||
132 | .info = (SNDRV_PCM_INFO_MMAP | | ||
133 | SNDRV_PCM_INFO_INTERLEAVED | | ||
134 | SNDRV_PCM_INFO_BLOCK_TRANSFER | | ||
135 | SNDRV_PCM_INFO_MMAP_VALID | | ||
136 | SNDRV_PCM_INFO_SYNC_START), | ||
137 | .formats = SNDRV_PCM_FMTBIT_S24_3LE, | ||
138 | .rates = SNDRV_PCM_RATE_48000, | ||
139 | .rate_min = 48000, | ||
140 | .rate_max = 48000, | ||
141 | /* 1+2: Main signal (out), 3+4: Tone 1, | ||
142 | * 5+6: Tone 2, 7+8: raw | ||
143 | */ | ||
144 | .channels_min = 8, | ||
145 | .channels_max = 8, | ||
146 | .buffer_bytes_max = 60000, | ||
147 | .period_bytes_min = 64, | ||
148 | .period_bytes_max = 8192, | ||
149 | .periods_min = 1, | ||
150 | .periods_max = 1024}, | ||
151 | .rates = { | ||
152 | .nrats = 1, | ||
153 | .rats = &podhd_ratden}, | ||
154 | .bytes_per_channel = 3 /* SNDRV_PCM_FMTBIT_S24_3LE */ | ||
155 | }; | ||
156 | |||
157 | static void podhd_startup_start_workqueue(unsigned long data); | ||
158 | static void podhd_startup_workqueue(struct work_struct *work); | ||
159 | static int podhd_startup_finalize(struct usb_line6_podhd *pod); | ||
160 | |||
161 | static ssize_t serial_number_show(struct device *dev, | ||
162 | struct device_attribute *attr, char *buf) | ||
163 | { | ||
164 | struct snd_card *card = dev_to_snd_card(dev); | ||
165 | struct usb_line6_podhd *pod = card->private_data; | ||
166 | |||
167 | return sprintf(buf, "%u\n", pod->serial_number); | ||
168 | } | ||
169 | |||
170 | static ssize_t firmware_version_show(struct device *dev, | ||
171 | struct device_attribute *attr, char *buf) | ||
172 | { | ||
173 | struct snd_card *card = dev_to_snd_card(dev); | ||
174 | struct usb_line6_podhd *pod = card->private_data; | ||
175 | |||
176 | return sprintf(buf, "%06x\n", pod->firmware_version); | ||
177 | } | ||
178 | |||
179 | static DEVICE_ATTR_RO(firmware_version); | ||
180 | static DEVICE_ATTR_RO(serial_number); | ||
181 | |||
182 | static struct attribute *podhd_dev_attrs[] = { | ||
183 | &dev_attr_firmware_version.attr, | ||
184 | &dev_attr_serial_number.attr, | ||
185 | NULL | ||
186 | }; | ||
187 | |||
188 | static const struct attribute_group podhd_dev_attr_group = { | ||
189 | .name = "podhd", | ||
190 | .attrs = podhd_dev_attrs, | ||
77 | }; | 191 | }; |
78 | 192 | ||
79 | /* | 193 | /* |
194 | * POD X3 startup procedure. | ||
195 | * | ||
196 | * May be compatible with other POD HD's, since it's also similar to the | ||
197 | * previous POD setup. In any case, it doesn't seem to be required for the | ||
198 | * audio nor bulk interfaces to work. | ||
199 | */ | ||
200 | |||
201 | static void podhd_startup(struct usb_line6_podhd *pod) | ||
202 | { | ||
203 | CHECK_STARTUP_PROGRESS(pod->startup_progress, PODHD_STARTUP_INIT); | ||
204 | |||
205 | /* delay startup procedure: */ | ||
206 | line6_start_timer(&pod->startup_timer, PODHD_STARTUP_DELAY, | ||
207 | podhd_startup_start_workqueue, (unsigned long)pod); | ||
208 | } | ||
209 | |||
210 | static void podhd_startup_start_workqueue(unsigned long data) | ||
211 | { | ||
212 | struct usb_line6_podhd *pod = (struct usb_line6_podhd *)data; | ||
213 | |||
214 | CHECK_STARTUP_PROGRESS(pod->startup_progress, | ||
215 | PODHD_STARTUP_SCHEDULE_WORKQUEUE); | ||
216 | |||
217 | /* schedule work for global work queue: */ | ||
218 | schedule_work(&pod->startup_work); | ||
219 | } | ||
220 | |||
221 | static int podhd_dev_start(struct usb_line6_podhd *pod) | ||
222 | { | ||
223 | int ret; | ||
224 | u8 init_bytes[8]; | ||
225 | int i; | ||
226 | struct usb_device *usbdev = pod->line6.usbdev; | ||
227 | |||
228 | ret = usb_control_msg(usbdev, usb_sndctrlpipe(usbdev, 0), | ||
229 | 0x67, USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_OUT, | ||
230 | 0x11, 0, | ||
231 | NULL, 0, LINE6_TIMEOUT * HZ); | ||
232 | if (ret < 0) { | ||
233 | dev_err(pod->line6.ifcdev, "read request failed (error %d)\n", ret); | ||
234 | return ret; | ||
235 | } | ||
236 | |||
237 | /* NOTE: looks like some kind of ping message */ | ||
238 | ret = usb_control_msg(usbdev, usb_rcvctrlpipe(usbdev, 0), 0x67, | ||
239 | USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_IN, | ||
240 | 0x11, 0x0, | ||
241 | &init_bytes, 3, LINE6_TIMEOUT * HZ); | ||
242 | if (ret < 0) { | ||
243 | dev_err(pod->line6.ifcdev, | ||
244 | "receive length failed (error %d)\n", ret); | ||
245 | return ret; | ||
246 | } | ||
247 | |||
248 | pod->firmware_version = | ||
249 | (init_bytes[0] << 16) | (init_bytes[1] << 8) | (init_bytes[2] << 0); | ||
250 | |||
251 | for (i = 0; i <= 16; i++) { | ||
252 | ret = line6_read_data(&pod->line6, 0xf000 + 0x08 * i, init_bytes, 8); | ||
253 | if (ret < 0) | ||
254 | return ret; | ||
255 | } | ||
256 | |||
257 | ret = usb_control_msg(usbdev, usb_sndctrlpipe(usbdev, 0), | ||
258 | USB_REQ_SET_FEATURE, | ||
259 | USB_TYPE_STANDARD | USB_RECIP_DEVICE | USB_DIR_OUT, | ||
260 | 1, 0, | ||
261 | NULL, 0, LINE6_TIMEOUT * HZ); | ||
262 | if (ret < 0) | ||
263 | return ret; | ||
264 | |||
265 | return 0; | ||
266 | } | ||
267 | |||
268 | static void podhd_startup_workqueue(struct work_struct *work) | ||
269 | { | ||
270 | struct usb_line6_podhd *pod = | ||
271 | container_of(work, struct usb_line6_podhd, startup_work); | ||
272 | |||
273 | CHECK_STARTUP_PROGRESS(pod->startup_progress, PODHD_STARTUP_SETUP); | ||
274 | |||
275 | podhd_dev_start(pod); | ||
276 | line6_read_serial_number(&pod->line6, &pod->serial_number); | ||
277 | |||
278 | podhd_startup_finalize(pod); | ||
279 | } | ||
280 | |||
281 | static int podhd_startup_finalize(struct usb_line6_podhd *pod) | ||
282 | { | ||
283 | struct usb_line6 *line6 = &pod->line6; | ||
284 | |||
285 | /* ALSA audio interface: */ | ||
286 | return snd_card_register(line6->card); | ||
287 | } | ||
288 | |||
289 | static void podhd_disconnect(struct usb_line6 *line6) | ||
290 | { | ||
291 | struct usb_line6_podhd *pod = (struct usb_line6_podhd *)line6; | ||
292 | |||
293 | if (pod->line6.properties->capabilities & LINE6_CAP_CONTROL) { | ||
294 | del_timer_sync(&pod->startup_timer); | ||
295 | cancel_work_sync(&pod->startup_work); | ||
296 | } | ||
297 | } | ||
298 | |||
299 | /* | ||
80 | Try to init POD HD device. | 300 | Try to init POD HD device. |
81 | */ | 301 | */ |
82 | static int podhd_init(struct usb_line6 *line6, | 302 | static int podhd_init(struct usb_line6 *line6, |
83 | const struct usb_device_id *id) | 303 | const struct usb_device_id *id) |
84 | { | 304 | { |
85 | int err; | 305 | int err; |
306 | struct usb_line6_podhd *pod = (struct usb_line6_podhd *) line6; | ||
86 | 307 | ||
87 | /* initialize MIDI subsystem: */ | 308 | line6->disconnect = podhd_disconnect; |
88 | err = line6_init_midi(line6); | ||
89 | if (err < 0) | ||
90 | return err; | ||
91 | 309 | ||
92 | /* initialize PCM subsystem: */ | 310 | if (pod->line6.properties->capabilities & LINE6_CAP_CONTROL) { |
93 | err = line6_init_pcm(line6, &podhd_pcm_properties); | 311 | /* create sysfs entries: */ |
94 | if (err < 0) | 312 | err = snd_card_add_dev_attr(line6->card, &podhd_dev_attr_group); |
95 | return err; | 313 | if (err < 0) |
314 | return err; | ||
315 | } | ||
96 | 316 | ||
97 | /* register USB audio system: */ | 317 | if (pod->line6.properties->capabilities & LINE6_CAP_PCM) { |
98 | return snd_card_register(line6->card); | 318 | /* initialize PCM subsystem: */ |
319 | err = line6_init_pcm(line6, | ||
320 | (id->driver_info == LINE6_PODX3) ? &podx3_pcm_properties : | ||
321 | &podhd_pcm_properties); | ||
322 | if (err < 0) | ||
323 | return err; | ||
324 | } | ||
325 | |||
326 | if (!(pod->line6.properties->capabilities & LINE6_CAP_CONTROL)) { | ||
327 | /* register USB audio system directly */ | ||
328 | return podhd_startup_finalize(pod); | ||
329 | } | ||
330 | |||
331 | /* init device and delay registering */ | ||
332 | init_timer(&pod->startup_timer); | ||
333 | INIT_WORK(&pod->startup_work, podhd_startup_workqueue); | ||
334 | podhd_startup(pod); | ||
335 | return 0; | ||
99 | } | 336 | } |
100 | 337 | ||
101 | #define LINE6_DEVICE(prod) USB_DEVICE(0x0e41, prod) | 338 | #define LINE6_DEVICE(prod) USB_DEVICE(0x0e41, prod) |
@@ -103,10 +340,13 @@ static int podhd_init(struct usb_line6 *line6, | |||
103 | 340 | ||
104 | /* table of devices that work with this driver */ | 341 | /* table of devices that work with this driver */ |
105 | static const struct usb_device_id podhd_id_table[] = { | 342 | static const struct usb_device_id podhd_id_table[] = { |
343 | /* TODO: no need to alloc data interfaces when only audio is used */ | ||
106 | { LINE6_DEVICE(0x5057), .driver_info = LINE6_PODHD300 }, | 344 | { LINE6_DEVICE(0x5057), .driver_info = LINE6_PODHD300 }, |
107 | { LINE6_DEVICE(0x5058), .driver_info = LINE6_PODHD400 }, | 345 | { LINE6_DEVICE(0x5058), .driver_info = LINE6_PODHD400 }, |
108 | { LINE6_IF_NUM(0x414D, 0), .driver_info = LINE6_PODHD500_0 }, | 346 | { LINE6_IF_NUM(0x414D, 0), .driver_info = LINE6_PODHD500_0 }, |
109 | { LINE6_IF_NUM(0x414D, 1), .driver_info = LINE6_PODHD500_1 }, | 347 | { LINE6_IF_NUM(0x414D, 1), .driver_info = LINE6_PODHD500_1 }, |
348 | { LINE6_IF_NUM(0x414A, 0), .driver_info = LINE6_PODX3 }, | ||
349 | { LINE6_IF_NUM(0x414B, 0), .driver_info = LINE6_PODX3LIVE }, | ||
110 | {} | 350 | {} |
111 | }; | 351 | }; |
112 | 352 | ||
@@ -116,8 +356,7 @@ static const struct line6_properties podhd_properties_table[] = { | |||
116 | [LINE6_PODHD300] = { | 356 | [LINE6_PODHD300] = { |
117 | .id = "PODHD300", | 357 | .id = "PODHD300", |
118 | .name = "POD HD300", | 358 | .name = "POD HD300", |
119 | .capabilities = LINE6_CAP_CONTROL | 359 | .capabilities = LINE6_CAP_PCM |
120 | | LINE6_CAP_PCM | ||
121 | | LINE6_CAP_HWMON, | 360 | | LINE6_CAP_HWMON, |
122 | .altsetting = 5, | 361 | .altsetting = 5, |
123 | .ep_ctrl_r = 0x84, | 362 | .ep_ctrl_r = 0x84, |
@@ -128,8 +367,7 @@ static const struct line6_properties podhd_properties_table[] = { | |||
128 | [LINE6_PODHD400] = { | 367 | [LINE6_PODHD400] = { |
129 | .id = "PODHD400", | 368 | .id = "PODHD400", |
130 | .name = "POD HD400", | 369 | .name = "POD HD400", |
131 | .capabilities = LINE6_CAP_CONTROL | 370 | .capabilities = LINE6_CAP_PCM |
132 | | LINE6_CAP_PCM | ||
133 | | LINE6_CAP_HWMON, | 371 | | LINE6_CAP_HWMON, |
134 | .altsetting = 5, | 372 | .altsetting = 5, |
135 | .ep_ctrl_r = 0x84, | 373 | .ep_ctrl_r = 0x84, |
@@ -140,8 +378,7 @@ static const struct line6_properties podhd_properties_table[] = { | |||
140 | [LINE6_PODHD500_0] = { | 378 | [LINE6_PODHD500_0] = { |
141 | .id = "PODHD500", | 379 | .id = "PODHD500", |
142 | .name = "POD HD500", | 380 | .name = "POD HD500", |
143 | .capabilities = LINE6_CAP_CONTROL | 381 | .capabilities = LINE6_CAP_PCM |
144 | | LINE6_CAP_PCM | ||
145 | | LINE6_CAP_HWMON, | 382 | | LINE6_CAP_HWMON, |
146 | .altsetting = 1, | 383 | .altsetting = 1, |
147 | .ep_ctrl_r = 0x81, | 384 | .ep_ctrl_r = 0x81, |
@@ -152,8 +389,7 @@ static const struct line6_properties podhd_properties_table[] = { | |||
152 | [LINE6_PODHD500_1] = { | 389 | [LINE6_PODHD500_1] = { |
153 | .id = "PODHD500", | 390 | .id = "PODHD500", |
154 | .name = "POD HD500", | 391 | .name = "POD HD500", |
155 | .capabilities = LINE6_CAP_CONTROL | 392 | .capabilities = LINE6_CAP_PCM |
156 | | LINE6_CAP_PCM | ||
157 | | LINE6_CAP_HWMON, | 393 | | LINE6_CAP_HWMON, |
158 | .altsetting = 1, | 394 | .altsetting = 1, |
159 | .ep_ctrl_r = 0x81, | 395 | .ep_ctrl_r = 0x81, |
@@ -161,6 +397,28 @@ static const struct line6_properties podhd_properties_table[] = { | |||
161 | .ep_audio_r = 0x86, | 397 | .ep_audio_r = 0x86, |
162 | .ep_audio_w = 0x02, | 398 | .ep_audio_w = 0x02, |
163 | }, | 399 | }, |
400 | [LINE6_PODX3] = { | ||
401 | .id = "PODX3", | ||
402 | .name = "POD X3", | ||
403 | .capabilities = LINE6_CAP_CONTROL | ||
404 | | LINE6_CAP_PCM | LINE6_CAP_HWMON | LINE6_CAP_IN_NEEDS_OUT, | ||
405 | .altsetting = 1, | ||
406 | .ep_ctrl_r = 0x81, | ||
407 | .ep_ctrl_w = 0x01, | ||
408 | .ep_audio_r = 0x86, | ||
409 | .ep_audio_w = 0x02, | ||
410 | }, | ||
411 | [LINE6_PODX3LIVE] = { | ||
412 | .id = "PODX3LIVE", | ||
413 | .name = "POD X3 LIVE", | ||
414 | .capabilities = LINE6_CAP_CONTROL | ||
415 | | LINE6_CAP_PCM | LINE6_CAP_HWMON | LINE6_CAP_IN_NEEDS_OUT, | ||
416 | .altsetting = 1, | ||
417 | .ep_ctrl_r = 0x81, | ||
418 | .ep_ctrl_w = 0x01, | ||
419 | .ep_audio_r = 0x86, | ||
420 | .ep_audio_w = 0x02, | ||
421 | }, | ||
164 | }; | 422 | }; |
165 | 423 | ||
166 | /* | 424 | /* |
@@ -171,7 +429,7 @@ static int podhd_probe(struct usb_interface *interface, | |||
171 | { | 429 | { |
172 | return line6_probe(interface, id, "Line6-PODHD", | 430 | return line6_probe(interface, id, "Line6-PODHD", |
173 | &podhd_properties_table[id->driver_info], | 431 | &podhd_properties_table[id->driver_info], |
174 | podhd_init, sizeof(struct usb_line6)); | 432 | podhd_init, sizeof(struct usb_line6_podhd)); |
175 | } | 433 | } |
176 | 434 | ||
177 | static struct usb_driver podhd_driver = { | 435 | static struct usb_driver podhd_driver = { |
diff --git a/sound/usb/line6/toneport.c b/sound/usb/line6/toneport.c index 6d4c50c9b17d..8e22f430d700 100644 --- a/sound/usb/line6/toneport.c +++ b/sound/usb/line6/toneport.c | |||
@@ -114,7 +114,7 @@ static struct line6_pcm_properties toneport_pcm_properties = { | |||
114 | .rates = { | 114 | .rates = { |
115 | .nrats = 1, | 115 | .nrats = 1, |
116 | .rats = &toneport_ratden}, | 116 | .rats = &toneport_ratden}, |
117 | .bytes_per_frame = 4 | 117 | .bytes_per_channel = 2 |
118 | }; | 118 | }; |
119 | 119 | ||
120 | static const struct { | 120 | static const struct { |
@@ -177,7 +177,7 @@ static int snd_toneport_monitor_put(struct snd_kcontrol *kcontrol, | |||
177 | line6pcm->volume_monitor = ucontrol->value.integer.value[0]; | 177 | line6pcm->volume_monitor = ucontrol->value.integer.value[0]; |
178 | 178 | ||
179 | if (line6pcm->volume_monitor > 0) { | 179 | if (line6pcm->volume_monitor > 0) { |
180 | err = line6_pcm_acquire(line6pcm, LINE6_STREAM_MONITOR); | 180 | err = line6_pcm_acquire(line6pcm, LINE6_STREAM_MONITOR, true); |
181 | if (err < 0) { | 181 | if (err < 0) { |
182 | line6pcm->volume_monitor = 0; | 182 | line6pcm->volume_monitor = 0; |
183 | line6_pcm_release(line6pcm, LINE6_STREAM_MONITOR); | 183 | line6_pcm_release(line6pcm, LINE6_STREAM_MONITOR); |
@@ -246,7 +246,7 @@ static void toneport_start_pcm(unsigned long arg) | |||
246 | struct usb_line6_toneport *toneport = (struct usb_line6_toneport *)arg; | 246 | struct usb_line6_toneport *toneport = (struct usb_line6_toneport *)arg; |
247 | struct usb_line6 *line6 = &toneport->line6; | 247 | struct usb_line6 *line6 = &toneport->line6; |
248 | 248 | ||
249 | line6_pcm_acquire(line6->line6pcm, LINE6_STREAM_MONITOR); | 249 | line6_pcm_acquire(line6->line6pcm, LINE6_STREAM_MONITOR, true); |
250 | } | 250 | } |
251 | 251 | ||
252 | /* control definition */ | 252 | /* control definition */ |
diff --git a/sound/usb/line6/variax.c b/sound/usb/line6/variax.c index ddc23ddf0750..0c4512d0382e 100644 --- a/sound/usb/line6/variax.c +++ b/sound/usb/line6/variax.c | |||
@@ -259,7 +259,8 @@ static const struct line6_properties variax_properties_table[] = { | |||
259 | [LINE6_PODXTLIVE_VARIAX] = { | 259 | [LINE6_PODXTLIVE_VARIAX] = { |
260 | .id = "PODxtLive", | 260 | .id = "PODxtLive", |
261 | .name = "PODxt Live", | 261 | .name = "PODxt Live", |
262 | .capabilities = LINE6_CAP_CONTROL, | 262 | .capabilities = LINE6_CAP_CONTROL |
263 | | LINE6_CAP_CONTROL_MIDI, | ||
263 | .altsetting = 1, | 264 | .altsetting = 1, |
264 | .ep_ctrl_r = 0x86, | 265 | .ep_ctrl_r = 0x86, |
265 | .ep_ctrl_w = 0x05, | 266 | .ep_ctrl_w = 0x05, |
@@ -269,7 +270,8 @@ static const struct line6_properties variax_properties_table[] = { | |||
269 | [LINE6_VARIAX] = { | 270 | [LINE6_VARIAX] = { |
270 | .id = "Variax", | 271 | .id = "Variax", |
271 | .name = "Variax Workbench", | 272 | .name = "Variax Workbench", |
272 | .capabilities = LINE6_CAP_CONTROL, | 273 | .capabilities = LINE6_CAP_CONTROL |
274 | | LINE6_CAP_CONTROL_MIDI, | ||
273 | .altsetting = 1, | 275 | .altsetting = 1, |
274 | .ep_ctrl_r = 0x82, | 276 | .ep_ctrl_r = 0x82, |
275 | .ep_ctrl_w = 0x01, | 277 | .ep_ctrl_w = 0x01, |
diff --git a/sound/usb/mixer_quirks.c b/sound/usb/mixer_quirks.c index f6c3bf79af9a..04991b009132 100644 --- a/sound/usb/mixer_quirks.c +++ b/sound/usb/mixer_quirks.c | |||
@@ -1831,6 +1831,7 @@ void snd_usb_mixer_rc_memory_change(struct usb_mixer_interface *mixer, | |||
1831 | } | 1831 | } |
1832 | 1832 | ||
1833 | static void snd_dragonfly_quirk_db_scale(struct usb_mixer_interface *mixer, | 1833 | static void snd_dragonfly_quirk_db_scale(struct usb_mixer_interface *mixer, |
1834 | struct usb_mixer_elem_info *cval, | ||
1834 | struct snd_kcontrol *kctl) | 1835 | struct snd_kcontrol *kctl) |
1835 | { | 1836 | { |
1836 | /* Approximation using 10 ranges based on output measurement on hw v1.2. | 1837 | /* Approximation using 10 ranges based on output measurement on hw v1.2. |
@@ -1848,10 +1849,19 @@ static void snd_dragonfly_quirk_db_scale(struct usb_mixer_interface *mixer, | |||
1848 | 41, 50, TLV_DB_MINMAX_ITEM(-441, 0), | 1849 | 41, 50, TLV_DB_MINMAX_ITEM(-441, 0), |
1849 | ); | 1850 | ); |
1850 | 1851 | ||
1851 | usb_audio_info(mixer->chip, "applying DragonFly dB scale quirk\n"); | 1852 | if (cval->min == 0 && cval->max == 50) { |
1852 | kctl->tlv.p = scale; | 1853 | usb_audio_info(mixer->chip, "applying DragonFly dB scale quirk (0-50 variant)\n"); |
1853 | kctl->vd[0].access |= SNDRV_CTL_ELEM_ACCESS_TLV_READ; | 1854 | kctl->tlv.p = scale; |
1854 | kctl->vd[0].access &= ~SNDRV_CTL_ELEM_ACCESS_TLV_CALLBACK; | 1855 | kctl->vd[0].access |= SNDRV_CTL_ELEM_ACCESS_TLV_READ; |
1856 | kctl->vd[0].access &= ~SNDRV_CTL_ELEM_ACCESS_TLV_CALLBACK; | ||
1857 | |||
1858 | } else if (cval->min == 0 && cval->max <= 1000) { | ||
1859 | /* Some other clearly broken DragonFly variant. | ||
1860 | * At least a 0..53 variant (hw v1.0) exists. | ||
1861 | */ | ||
1862 | usb_audio_info(mixer->chip, "ignoring too narrow dB range on a DragonFly device"); | ||
1863 | kctl->vd[0].access &= ~SNDRV_CTL_ELEM_ACCESS_TLV_CALLBACK; | ||
1864 | } | ||
1855 | } | 1865 | } |
1856 | 1866 | ||
1857 | void snd_usb_mixer_fu_apply_quirk(struct usb_mixer_interface *mixer, | 1867 | void snd_usb_mixer_fu_apply_quirk(struct usb_mixer_interface *mixer, |
@@ -1860,8 +1870,8 @@ void snd_usb_mixer_fu_apply_quirk(struct usb_mixer_interface *mixer, | |||
1860 | { | 1870 | { |
1861 | switch (mixer->chip->usb_id) { | 1871 | switch (mixer->chip->usb_id) { |
1862 | case USB_ID(0x21b4, 0x0081): /* AudioQuest DragonFly */ | 1872 | case USB_ID(0x21b4, 0x0081): /* AudioQuest DragonFly */ |
1863 | if (unitid == 7 && cval->min == 0 && cval->max == 50) | 1873 | if (unitid == 7 && cval->control == UAC_FU_VOLUME) |
1864 | snd_dragonfly_quirk_db_scale(mixer, kctl); | 1874 | snd_dragonfly_quirk_db_scale(mixer, cval, kctl); |
1865 | break; | 1875 | break; |
1866 | } | 1876 | } |
1867 | } | 1877 | } |
diff --git a/sound/usb/quirks.c b/sound/usb/quirks.c index 152292e5ee2b..2782155ae3ce 100644 --- a/sound/usb/quirks.c +++ b/sound/usb/quirks.c | |||
@@ -1217,6 +1217,12 @@ void snd_usb_endpoint_start_quirk(struct snd_usb_endpoint *ep) | |||
1217 | ep->chip->usb_id == USB_ID(0x0763, 0x2031)) && | 1217 | ep->chip->usb_id == USB_ID(0x0763, 0x2031)) && |
1218 | ep->type == SND_USB_ENDPOINT_TYPE_DATA) | 1218 | ep->type == SND_USB_ENDPOINT_TYPE_DATA) |
1219 | ep->skip_packets = 16; | 1219 | ep->skip_packets = 16; |
1220 | |||
1221 | /* Work around devices that report unreasonable feedback data */ | ||
1222 | if ((ep->chip->usb_id == USB_ID(0x0644, 0x8038) || /* TEAC UD-H01 */ | ||
1223 | ep->chip->usb_id == USB_ID(0x1852, 0x5034)) && /* T+A Dac8 */ | ||
1224 | ep->syncmaxsize == 4) | ||
1225 | ep->tenor_fb_quirk = 1; | ||
1220 | } | 1226 | } |
1221 | 1227 | ||
1222 | void snd_usb_set_interface_quirk(struct usb_device *dev) | 1228 | void snd_usb_set_interface_quirk(struct usb_device *dev) |