aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMark Brown <broonie@kernel.org>2018-01-18 06:55:37 -0500
committerMark Brown <broonie@kernel.org>2018-01-18 06:55:37 -0500
commit078b3a0205cba12302d40ce04a24c0edaa6842ce (patch)
tree69d5b79691fd894866b89798329c42efc7c641b5
parent5f7a0ea9fe0e1874ff339ab42fdde89f0ccee411 (diff)
parent2ca69d73bc05a55edb95689d436ce87974a3162e (diff)
Merge remote-tracking branch 'asoc/topic/rcar' into asoc-next
-rw-r--r--Documentation/devicetree/bindings/sound/renesas,rsnd.txt15
-rw-r--r--include/sound/soc.h2
-rw-r--r--sound/soc/rockchip/rk3399_gru_sound.c3
-rw-r--r--sound/soc/sh/rcar/core.c143
-rw-r--r--sound/soc/sh/rcar/dma.c18
-rw-r--r--sound/soc/sh/rcar/rsnd.h15
-rw-r--r--sound/soc/sh/rcar/ssi.c163
-rw-r--r--sound/soc/soc-core.c10
8 files changed, 197 insertions, 172 deletions
diff --git a/Documentation/devicetree/bindings/sound/renesas,rsnd.txt b/Documentation/devicetree/bindings/sound/renesas,rsnd.txt
index 085bec364caf..5bed9a595772 100644
--- a/Documentation/devicetree/bindings/sound/renesas,rsnd.txt
+++ b/Documentation/devicetree/bindings/sound/renesas,rsnd.txt
@@ -4,7 +4,7 @@ Renesas R-Car sound
4* Modules 4* Modules
5============================================= 5=============================================
6 6
7Renesas R-Car sound is constructed from below modules 7Renesas R-Car and RZ/G sound is constructed from below modules
8(for Gen2 or later) 8(for Gen2 or later)
9 9
10 SCU : Sampling Rate Converter Unit 10 SCU : Sampling Rate Converter Unit
@@ -197,12 +197,17 @@ Ex)
197 [MEM] -> [SRC2] -> [CTU03] -+ 197 [MEM] -> [SRC2] -> [CTU03] -+
198 198
199 sound { 199 sound {
200 #address-cells = <1>;
201 #size-cells = <0>;
202
200 compatible = "simple-scu-audio-card"; 203 compatible = "simple-scu-audio-card";
201 ... 204 ...
202 simple-audio-card,cpu-0 { 205 simple-audio-card,cpu@0 {
206 reg = <0>;
203 sound-dai = <&rcar_sound 0>; 207 sound-dai = <&rcar_sound 0>;
204 }; 208 };
205 simple-audio-card,cpu-1 { 209 simple-audio-card,cpu@1 {
210 reg = <1>;
206 sound-dai = <&rcar_sound 1>; 211 sound-dai = <&rcar_sound 1>;
207 }; 212 };
208 simple-audio-card,codec { 213 simple-audio-card,codec {
@@ -334,9 +339,11 @@ Required properties:
334 339
335- compatible : "renesas,rcar_sound-<soctype>", fallbacks 340- compatible : "renesas,rcar_sound-<soctype>", fallbacks
336 "renesas,rcar_sound-gen1" if generation1, and 341 "renesas,rcar_sound-gen1" if generation1, and
337 "renesas,rcar_sound-gen2" if generation2 342 "renesas,rcar_sound-gen2" if generation2 (or RZ/G1)
338 "renesas,rcar_sound-gen3" if generation3 343 "renesas,rcar_sound-gen3" if generation3
339 Examples with soctypes are: 344 Examples with soctypes are:
345 - "renesas,rcar_sound-r8a7743" (RZ/G1M)
346 - "renesas,rcar_sound-r8a7745" (RZ/G1E)
340 - "renesas,rcar_sound-r8a7778" (R-Car M1A) 347 - "renesas,rcar_sound-r8a7778" (R-Car M1A)
341 - "renesas,rcar_sound-r8a7779" (R-Car H1) 348 - "renesas,rcar_sound-r8a7779" (R-Car H1)
342 - "renesas,rcar_sound-r8a7790" (R-Car H2) 349 - "renesas,rcar_sound-r8a7790" (R-Car H2)
diff --git a/include/sound/soc.h b/include/sound/soc.h
index 6e865c2bcffe..8fd59dadaf01 100644
--- a/include/sound/soc.h
+++ b/include/sound/soc.h
@@ -494,6 +494,8 @@ int soc_new_pcm(struct snd_soc_pcm_runtime *rtd, int num);
494int snd_soc_new_compress(struct snd_soc_pcm_runtime *rtd, int num); 494int snd_soc_new_compress(struct snd_soc_pcm_runtime *rtd, int num);
495#endif 495#endif
496 496
497void snd_soc_disconnect_sync(struct device *dev);
498
497struct snd_pcm_substream *snd_soc_get_dai_substream(struct snd_soc_card *card, 499struct snd_pcm_substream *snd_soc_get_dai_substream(struct snd_soc_card *card,
498 const char *dai_link, int stream); 500 const char *dai_link, int stream);
499struct snd_soc_pcm_runtime *snd_soc_get_pcm_runtime(struct snd_soc_card *card, 501struct snd_soc_pcm_runtime *snd_soc_get_pcm_runtime(struct snd_soc_card *card,
diff --git a/sound/soc/rockchip/rk3399_gru_sound.c b/sound/soc/rockchip/rk3399_gru_sound.c
index d64fbbd50544..fa6cd1de828b 100644
--- a/sound/soc/rockchip/rk3399_gru_sound.c
+++ b/sound/soc/rockchip/rk3399_gru_sound.c
@@ -206,7 +206,8 @@ static int rockchip_sound_da7219_init(struct snd_soc_pcm_runtime *rtd)
206 return ret; 206 return ret;
207 } 207 }
208 208
209 snd_jack_set_key(rockchip_sound_jack.jack, SND_JACK_BTN_0, KEY_MEDIA); 209 snd_jack_set_key(
210 rockchip_sound_jack.jack, SND_JACK_BTN_0, KEY_PLAYPAUSE);
210 snd_jack_set_key( 211 snd_jack_set_key(
211 rockchip_sound_jack.jack, SND_JACK_BTN_1, KEY_VOLUMEUP); 212 rockchip_sound_jack.jack, SND_JACK_BTN_1, KEY_VOLUMEUP);
212 snd_jack_set_key( 213 snd_jack_set_key(
diff --git a/sound/soc/sh/rcar/core.c b/sound/soc/sh/rcar/core.c
index f12a88a21dfa..64d5ecb86528 100644
--- a/sound/soc/sh/rcar/core.c
+++ b/sound/soc/sh/rcar/core.c
@@ -197,16 +197,27 @@ int rsnd_io_is_working(struct rsnd_dai_stream *io)
197 return 0; 197 return 0;
198} 198}
199 199
200int rsnd_runtime_channel_original(struct rsnd_dai_stream *io) 200int rsnd_runtime_channel_original_with_params(struct rsnd_dai_stream *io,
201 struct snd_pcm_hw_params *params)
201{ 202{
202 struct snd_pcm_runtime *runtime = rsnd_io_to_runtime(io); 203 struct snd_pcm_runtime *runtime = rsnd_io_to_runtime(io);
203 204
204 return runtime->channels; 205 /*
206 * params will be added when refine
207 * see
208 * __rsnd_soc_hw_rule_rate()
209 * __rsnd_soc_hw_rule_channels()
210 */
211 if (params)
212 return params_channels(params);
213 else
214 return runtime->channels;
205} 215}
206 216
207int rsnd_runtime_channel_after_ctu(struct rsnd_dai_stream *io) 217int rsnd_runtime_channel_after_ctu_with_params(struct rsnd_dai_stream *io,
218 struct snd_pcm_hw_params *params)
208{ 219{
209 int chan = rsnd_runtime_channel_original(io); 220 int chan = rsnd_runtime_channel_original_with_params(io, params);
210 struct rsnd_mod *ctu_mod = rsnd_io_to_mod_ctu(io); 221 struct rsnd_mod *ctu_mod = rsnd_io_to_mod_ctu(io);
211 222
212 if (ctu_mod) { 223 if (ctu_mod) {
@@ -219,12 +230,13 @@ int rsnd_runtime_channel_after_ctu(struct rsnd_dai_stream *io)
219 return chan; 230 return chan;
220} 231}
221 232
222int rsnd_runtime_channel_for_ssi(struct rsnd_dai_stream *io) 233int rsnd_runtime_channel_for_ssi_with_params(struct rsnd_dai_stream *io,
234 struct snd_pcm_hw_params *params)
223{ 235{
224 struct rsnd_dai *rdai = rsnd_io_to_rdai(io); 236 struct rsnd_dai *rdai = rsnd_io_to_rdai(io);
225 int chan = rsnd_io_is_play(io) ? 237 int chan = rsnd_io_is_play(io) ?
226 rsnd_runtime_channel_after_ctu(io) : 238 rsnd_runtime_channel_after_ctu_with_params(io, params) :
227 rsnd_runtime_channel_original(io); 239 rsnd_runtime_channel_original_with_params(io, params);
228 240
229 /* Use Multi SSI */ 241 /* Use Multi SSI */
230 if (rsnd_runtime_is_ssi_multi(io)) 242 if (rsnd_runtime_is_ssi_multi(io))
@@ -262,10 +274,10 @@ u32 rsnd_get_adinr_bit(struct rsnd_mod *mod, struct rsnd_dai_stream *io)
262 struct snd_pcm_runtime *runtime = rsnd_io_to_runtime(io); 274 struct snd_pcm_runtime *runtime = rsnd_io_to_runtime(io);
263 struct device *dev = rsnd_priv_to_dev(priv); 275 struct device *dev = rsnd_priv_to_dev(priv);
264 276
265 switch (runtime->sample_bits) { 277 switch (snd_pcm_format_width(runtime->format)) {
266 case 16: 278 case 16:
267 return 8 << 16; 279 return 8 << 16;
268 case 32: 280 case 24:
269 return 0 << 16; 281 return 0 << 16;
270 } 282 }
271 283
@@ -282,11 +294,12 @@ u32 rsnd_get_dalign(struct rsnd_mod *mod, struct rsnd_dai_stream *io)
282 struct rsnd_mod *ssiu = rsnd_io_to_mod_ssiu(io); 294 struct rsnd_mod *ssiu = rsnd_io_to_mod_ssiu(io);
283 struct rsnd_mod *target; 295 struct rsnd_mod *target;
284 struct snd_pcm_runtime *runtime = rsnd_io_to_runtime(io); 296 struct snd_pcm_runtime *runtime = rsnd_io_to_runtime(io);
285 u32 val = 0x76543210;
286 u32 mask = ~0;
287 297
288 /* 298 /*
289 * *Hardware* L/R and *Software* L/R are inverted. 299 * *Hardware* L/R and *Software* L/R are inverted for 16bit data.
300 * 31..16 15...0
301 * HW: [L ch] [R ch]
302 * SW: [R ch] [L ch]
290 * We need to care about inversion timing to control 303 * We need to care about inversion timing to control
291 * Playback/Capture correctly. 304 * Playback/Capture correctly.
292 * The point is [DVC] needs *Hardware* L/R, [MEM] needs *Software* L/R 305 * The point is [DVC] needs *Hardware* L/R, [MEM] needs *Software* L/R
@@ -313,27 +326,13 @@ u32 rsnd_get_dalign(struct rsnd_mod *mod, struct rsnd_dai_stream *io)
313 target = cmd ? cmd : ssiu; 326 target = cmd ? cmd : ssiu;
314 } 327 }
315 328
316 mask <<= runtime->channels * 4; 329 /* Non target mod or 24bit data needs normal DALIGN */
317 val = val & mask; 330 if ((snd_pcm_format_width(runtime->format) != 16) ||
318 331 (mod != target))
319 switch (runtime->sample_bits) {
320 case 16:
321 val |= 0x67452301 & ~mask;
322 break;
323 case 32:
324 val |= 0x76543210 & ~mask;
325 break;
326 }
327
328 /*
329 * exchange channeles on SRC if possible,
330 * otherwise, R/L volume settings on DVC
331 * changes inverted channels
332 */
333 if (mod == target)
334 return val;
335 else
336 return 0x76543210; 332 return 0x76543210;
333 /* Target mod needs inverted DALIGN when 16bit */
334 else
335 return 0x67452301;
337} 336}
338 337
339u32 rsnd_get_busif_shift(struct rsnd_dai_stream *io, struct rsnd_mod *mod) 338u32 rsnd_get_busif_shift(struct rsnd_dai_stream *io, struct rsnd_mod *mod)
@@ -363,12 +362,8 @@ u32 rsnd_get_busif_shift(struct rsnd_dai_stream *io, struct rsnd_mod *mod)
363 * HW 24bit data is located as 0x******00 362 * HW 24bit data is located as 0x******00
364 * 363 *
365 */ 364 */
366 switch (runtime->sample_bits) { 365 if (snd_pcm_format_width(runtime->format) == 16)
367 case 16:
368 return 0; 366 return 0;
369 case 32:
370 break;
371 }
372 367
373 for (i = 0; i < ARRAY_SIZE(playback_mods); i++) { 368 for (i = 0; i < ARRAY_SIZE(playback_mods); i++) {
374 tmod = rsnd_io_to_mod(io, mods[i]); 369 tmod = rsnd_io_to_mod(io, mods[i]);
@@ -616,8 +611,6 @@ static int rsnd_soc_dai_trigger(struct snd_pcm_substream *substream, int cmd,
616 switch (cmd) { 611 switch (cmd) {
617 case SNDRV_PCM_TRIGGER_START: 612 case SNDRV_PCM_TRIGGER_START:
618 case SNDRV_PCM_TRIGGER_RESUME: 613 case SNDRV_PCM_TRIGGER_RESUME:
619 rsnd_dai_stream_init(io, substream);
620
621 ret = rsnd_dai_call(init, io, priv); 614 ret = rsnd_dai_call(init, io, priv);
622 if (ret < 0) 615 if (ret < 0)
623 goto dai_trigger_end; 616 goto dai_trigger_end;
@@ -639,7 +632,6 @@ static int rsnd_soc_dai_trigger(struct snd_pcm_substream *substream, int cmd,
639 632
640 ret |= rsnd_dai_call(quit, io, priv); 633 ret |= rsnd_dai_call(quit, io, priv);
641 634
642 rsnd_dai_stream_quit(io);
643 break; 635 break;
644 default: 636 default:
645 ret = -EINVAL; 637 ret = -EINVAL;
@@ -784,8 +776,9 @@ static int rsnd_soc_hw_rule(struct rsnd_priv *priv,
784 return snd_interval_refine(iv, &p); 776 return snd_interval_refine(iv, &p);
785} 777}
786 778
787static int rsnd_soc_hw_rule_rate(struct snd_pcm_hw_params *params, 779static int __rsnd_soc_hw_rule_rate(struct snd_pcm_hw_params *params,
788 struct snd_pcm_hw_rule *rule) 780 struct snd_pcm_hw_rule *rule,
781 int is_play)
789{ 782{
790 struct snd_interval *ic_ = hw_param_interval(params, SNDRV_PCM_HW_PARAM_CHANNELS); 783 struct snd_interval *ic_ = hw_param_interval(params, SNDRV_PCM_HW_PARAM_CHANNELS);
791 struct snd_interval *ir = hw_param_interval(params, SNDRV_PCM_HW_PARAM_RATE); 784 struct snd_interval *ir = hw_param_interval(params, SNDRV_PCM_HW_PARAM_RATE);
@@ -793,25 +786,37 @@ static int rsnd_soc_hw_rule_rate(struct snd_pcm_hw_params *params,
793 struct snd_soc_dai *dai = rule->private; 786 struct snd_soc_dai *dai = rule->private;
794 struct rsnd_dai *rdai = rsnd_dai_to_rdai(dai); 787 struct rsnd_dai *rdai = rsnd_dai_to_rdai(dai);
795 struct rsnd_priv *priv = rsnd_rdai_to_priv(rdai); 788 struct rsnd_priv *priv = rsnd_rdai_to_priv(rdai);
789 struct rsnd_dai_stream *io = is_play ? &rdai->playback : &rdai->capture;
796 790
797 /* 791 /*
798 * possible sampling rate limitation is same as 792 * possible sampling rate limitation is same as
799 * 2ch if it supports multi ssi 793 * 2ch if it supports multi ssi
794 * and same as 8ch if TDM 6ch (see rsnd_ssi_config_init())
800 */ 795 */
801 ic = *ic_; 796 ic = *ic_;
802 if (1 < rsnd_rdai_ssi_lane_get(rdai)) { 797 ic.min =
803 ic.min = 2; 798 ic.max = rsnd_runtime_channel_for_ssi_with_params(io, params);
804 ic.max = 2;
805 }
806 799
807 return rsnd_soc_hw_rule(priv, rsnd_soc_hw_rate_list, 800 return rsnd_soc_hw_rule(priv, rsnd_soc_hw_rate_list,
808 ARRAY_SIZE(rsnd_soc_hw_rate_list), 801 ARRAY_SIZE(rsnd_soc_hw_rate_list),
809 &ic, ir); 802 &ic, ir);
810} 803}
811 804
805static int rsnd_soc_hw_rule_rate_playback(struct snd_pcm_hw_params *params,
806 struct snd_pcm_hw_rule *rule)
807{
808 return __rsnd_soc_hw_rule_rate(params, rule, 1);
809}
810
811static int rsnd_soc_hw_rule_rate_capture(struct snd_pcm_hw_params *params,
812 struct snd_pcm_hw_rule *rule)
813{
814 return __rsnd_soc_hw_rule_rate(params, rule, 0);
815}
812 816
813static int rsnd_soc_hw_rule_channels(struct snd_pcm_hw_params *params, 817static int __rsnd_soc_hw_rule_channels(struct snd_pcm_hw_params *params,
814 struct snd_pcm_hw_rule *rule) 818 struct snd_pcm_hw_rule *rule,
819 int is_play)
815{ 820{
816 struct snd_interval *ic_ = hw_param_interval(params, SNDRV_PCM_HW_PARAM_CHANNELS); 821 struct snd_interval *ic_ = hw_param_interval(params, SNDRV_PCM_HW_PARAM_CHANNELS);
817 struct snd_interval *ir = hw_param_interval(params, SNDRV_PCM_HW_PARAM_RATE); 822 struct snd_interval *ir = hw_param_interval(params, SNDRV_PCM_HW_PARAM_RATE);
@@ -819,22 +824,34 @@ static int rsnd_soc_hw_rule_channels(struct snd_pcm_hw_params *params,
819 struct snd_soc_dai *dai = rule->private; 824 struct snd_soc_dai *dai = rule->private;
820 struct rsnd_dai *rdai = rsnd_dai_to_rdai(dai); 825 struct rsnd_dai *rdai = rsnd_dai_to_rdai(dai);
821 struct rsnd_priv *priv = rsnd_rdai_to_priv(rdai); 826 struct rsnd_priv *priv = rsnd_rdai_to_priv(rdai);
827 struct rsnd_dai_stream *io = is_play ? &rdai->playback : &rdai->capture;
822 828
823 /* 829 /*
824 * possible sampling rate limitation is same as 830 * possible sampling rate limitation is same as
825 * 2ch if it supports multi ssi 831 * 2ch if it supports multi ssi
832 * and same as 8ch if TDM 6ch (see rsnd_ssi_config_init())
826 */ 833 */
827 ic = *ic_; 834 ic = *ic_;
828 if (1 < rsnd_rdai_ssi_lane_get(rdai)) { 835 ic.min =
829 ic.min = 2; 836 ic.max = rsnd_runtime_channel_for_ssi_with_params(io, params);
830 ic.max = 2;
831 }
832 837
833 return rsnd_soc_hw_rule(priv, rsnd_soc_hw_channels_list, 838 return rsnd_soc_hw_rule(priv, rsnd_soc_hw_channels_list,
834 ARRAY_SIZE(rsnd_soc_hw_channels_list), 839 ARRAY_SIZE(rsnd_soc_hw_channels_list),
835 ir, &ic); 840 ir, &ic);
836} 841}
837 842
843static int rsnd_soc_hw_rule_channels_playback(struct snd_pcm_hw_params *params,
844 struct snd_pcm_hw_rule *rule)
845{
846 return __rsnd_soc_hw_rule_channels(params, rule, 1);
847}
848
849static int rsnd_soc_hw_rule_channels_capture(struct snd_pcm_hw_params *params,
850 struct snd_pcm_hw_rule *rule)
851{
852 return __rsnd_soc_hw_rule_channels(params, rule, 0);
853}
854
838static const struct snd_pcm_hardware rsnd_pcm_hardware = { 855static const struct snd_pcm_hardware rsnd_pcm_hardware = {
839 .info = SNDRV_PCM_INFO_INTERLEAVED | 856 .info = SNDRV_PCM_INFO_INTERLEAVED |
840 SNDRV_PCM_INFO_MMAP | 857 SNDRV_PCM_INFO_MMAP |
@@ -859,6 +876,8 @@ static int rsnd_soc_dai_startup(struct snd_pcm_substream *substream,
859 int ret; 876 int ret;
860 int i; 877 int i;
861 878
879 rsnd_dai_stream_init(io, substream);
880
862 /* 881 /*
863 * Channel Limitation 882 * Channel Limitation
864 * It depends on Platform design 883 * It depends on Platform design
@@ -886,11 +905,17 @@ static int rsnd_soc_dai_startup(struct snd_pcm_substream *substream,
886 * It depends on Clock Master Mode 905 * It depends on Clock Master Mode
887 */ 906 */
888 if (rsnd_rdai_is_clk_master(rdai)) { 907 if (rsnd_rdai_is_clk_master(rdai)) {
908 int is_play = substream->stream == SNDRV_PCM_STREAM_PLAYBACK;
909
889 snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_RATE, 910 snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_RATE,
890 rsnd_soc_hw_rule_rate, dai, 911 is_play ? rsnd_soc_hw_rule_rate_playback :
912 rsnd_soc_hw_rule_rate_capture,
913 dai,
891 SNDRV_PCM_HW_PARAM_CHANNELS, -1); 914 SNDRV_PCM_HW_PARAM_CHANNELS, -1);
892 snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS, 915 snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS,
893 rsnd_soc_hw_rule_channels, dai, 916 is_play ? rsnd_soc_hw_rule_channels_playback :
917 rsnd_soc_hw_rule_channels_capture,
918 dai,
894 SNDRV_PCM_HW_PARAM_RATE, -1); 919 SNDRV_PCM_HW_PARAM_RATE, -1);
895 } 920 }
896 921
@@ -915,6 +940,8 @@ static void rsnd_soc_dai_shutdown(struct snd_pcm_substream *substream,
915 * call rsnd_dai_call without spinlock 940 * call rsnd_dai_call without spinlock
916 */ 941 */
917 rsnd_dai_call(nolock_stop, io, priv); 942 rsnd_dai_call(nolock_stop, io, priv);
943
944 rsnd_dai_stream_quit(io);
918} 945}
919 946
920static const struct snd_soc_dai_ops rsnd_soc_dai_ops = { 947static const struct snd_soc_dai_ops rsnd_soc_dai_ops = {
@@ -990,7 +1017,7 @@ of_node_compatible:
990 1017
991static void __rsnd_dai_probe(struct rsnd_priv *priv, 1018static void __rsnd_dai_probe(struct rsnd_priv *priv,
992 struct device_node *dai_np, 1019 struct device_node *dai_np,
993 int dai_i, int is_graph) 1020 int dai_i)
994{ 1021{
995 struct device_node *playback, *capture; 1022 struct device_node *playback, *capture;
996 struct rsnd_dai_stream *io_playback; 1023 struct rsnd_dai_stream *io_playback;
@@ -1089,13 +1116,13 @@ static int rsnd_dai_probe(struct rsnd_priv *priv)
1089 dai_i = 0; 1116 dai_i = 0;
1090 if (is_graph) { 1117 if (is_graph) {
1091 for_each_endpoint_of_node(dai_node, dai_np) { 1118 for_each_endpoint_of_node(dai_node, dai_np) {
1092 __rsnd_dai_probe(priv, dai_np, dai_i, is_graph); 1119 __rsnd_dai_probe(priv, dai_np, dai_i);
1093 rsnd_ssi_parse_hdmi_connection(priv, dai_np, dai_i); 1120 rsnd_ssi_parse_hdmi_connection(priv, dai_np, dai_i);
1094 dai_i++; 1121 dai_i++;
1095 } 1122 }
1096 } else { 1123 } else {
1097 for_each_child_of_node(dai_node, dai_np) 1124 for_each_child_of_node(dai_node, dai_np)
1098 __rsnd_dai_probe(priv, dai_np, dai_i++, is_graph); 1125 __rsnd_dai_probe(priv, dai_np, dai_i++);
1099 } 1126 }
1100 1127
1101 return 0; 1128 return 0;
@@ -1496,6 +1523,8 @@ static int rsnd_remove(struct platform_device *pdev)
1496 }; 1523 };
1497 int ret = 0, i; 1524 int ret = 0, i;
1498 1525
1526 snd_soc_disconnect_sync(&pdev->dev);
1527
1499 pm_runtime_disable(&pdev->dev); 1528 pm_runtime_disable(&pdev->dev);
1500 1529
1501 for_each_rsnd_dai(rdai, priv, i) { 1530 for_each_rsnd_dai(rdai, priv, i) {
diff --git a/sound/soc/sh/rcar/dma.c b/sound/soc/sh/rcar/dma.c
index 4d750bdf8e24..41de23417c4a 100644
--- a/sound/soc/sh/rcar/dma.c
+++ b/sound/soc/sh/rcar/dma.c
@@ -71,25 +71,7 @@ static struct rsnd_mod mem = {
71static void __rsnd_dmaen_complete(struct rsnd_mod *mod, 71static void __rsnd_dmaen_complete(struct rsnd_mod *mod,
72 struct rsnd_dai_stream *io) 72 struct rsnd_dai_stream *io)
73{ 73{
74 struct rsnd_priv *priv = rsnd_mod_to_priv(mod);
75 bool elapsed = false;
76 unsigned long flags;
77
78 /*
79 * Renesas sound Gen1 needs 1 DMAC,
80 * Gen2 needs 2 DMAC.
81 * In Gen2 case, it are Audio-DMAC, and Audio-DMAC-peri-peri.
82 * But, Audio-DMAC-peri-peri doesn't have interrupt,
83 * and this driver is assuming that here.
84 */
85 spin_lock_irqsave(&priv->lock, flags);
86
87 if (rsnd_io_is_working(io)) 74 if (rsnd_io_is_working(io))
88 elapsed = true;
89
90 spin_unlock_irqrestore(&priv->lock, flags);
91
92 if (elapsed)
93 rsnd_dai_period_elapsed(io); 75 rsnd_dai_period_elapsed(io);
94} 76}
95 77
diff --git a/sound/soc/sh/rcar/rsnd.h b/sound/soc/sh/rcar/rsnd.h
index 57cd2bc773c2..ad6523595b0a 100644
--- a/sound/soc/sh/rcar/rsnd.h
+++ b/sound/soc/sh/rcar/rsnd.h
@@ -399,9 +399,18 @@ void rsnd_parse_connect_common(struct rsnd_dai *rdai,
399 struct device_node *playback, 399 struct device_node *playback,
400 struct device_node *capture); 400 struct device_node *capture);
401 401
402int rsnd_runtime_channel_original(struct rsnd_dai_stream *io); 402#define rsnd_runtime_channel_original(io) \
403int rsnd_runtime_channel_after_ctu(struct rsnd_dai_stream *io); 403 rsnd_runtime_channel_original_with_params(io, NULL)
404int rsnd_runtime_channel_for_ssi(struct rsnd_dai_stream *io); 404int rsnd_runtime_channel_original_with_params(struct rsnd_dai_stream *io,
405 struct snd_pcm_hw_params *params);
406#define rsnd_runtime_channel_after_ctu(io) \
407 rsnd_runtime_channel_after_ctu_with_params(io, NULL)
408int rsnd_runtime_channel_after_ctu_with_params(struct rsnd_dai_stream *io,
409 struct snd_pcm_hw_params *params);
410#define rsnd_runtime_channel_for_ssi(io) \
411 rsnd_runtime_channel_for_ssi_with_params(io, NULL)
412int rsnd_runtime_channel_for_ssi_with_params(struct rsnd_dai_stream *io,
413 struct snd_pcm_hw_params *params);
405int rsnd_runtime_is_ssi_multi(struct rsnd_dai_stream *io); 414int rsnd_runtime_is_ssi_multi(struct rsnd_dai_stream *io);
406int rsnd_runtime_is_ssi_tdm(struct rsnd_dai_stream *io); 415int rsnd_runtime_is_ssi_tdm(struct rsnd_dai_stream *io);
407 416
diff --git a/sound/soc/sh/rcar/ssi.c b/sound/soc/sh/rcar/ssi.c
index cbf3bf312d23..97a9db892a8f 100644
--- a/sound/soc/sh/rcar/ssi.c
+++ b/sound/soc/sh/rcar/ssi.c
@@ -79,8 +79,8 @@ struct rsnd_ssi {
79 int irq; 79 int irq;
80 unsigned int usrcnt; 80 unsigned int usrcnt;
81 81
82 /* for PIO */
82 int byte_pos; 83 int byte_pos;
83 int period_pos;
84 int byte_per_period; 84 int byte_per_period;
85 int next_period_byte; 85 int next_period_byte;
86}; 86};
@@ -371,11 +371,11 @@ static void rsnd_ssi_config_init(struct rsnd_mod *mod,
371 if (rsnd_io_is_play(io)) 371 if (rsnd_io_is_play(io))
372 cr_own |= TRMD; 372 cr_own |= TRMD;
373 373
374 switch (runtime->sample_bits) { 374 switch (snd_pcm_format_width(runtime->format)) {
375 case 16: 375 case 16:
376 cr_own |= DWL_16; 376 cr_own |= DWL_16;
377 break; 377 break;
378 case 32: 378 case 24:
379 cr_own |= DWL_24; 379 cr_own |= DWL_24;
380 break; 380 break;
381 } 381 }
@@ -414,63 +414,6 @@ static void rsnd_ssi_register_setup(struct rsnd_mod *mod)
414 ssi->cr_en); 414 ssi->cr_en);
415} 415}
416 416
417static void rsnd_ssi_pointer_init(struct rsnd_mod *mod,
418 struct rsnd_dai_stream *io)
419{
420 struct rsnd_ssi *ssi = rsnd_mod_to_ssi(mod);
421 struct snd_pcm_runtime *runtime = rsnd_io_to_runtime(io);
422
423 ssi->byte_pos = 0;
424 ssi->period_pos = 0;
425 ssi->byte_per_period = runtime->period_size *
426 runtime->channels *
427 samples_to_bytes(runtime, 1);
428 ssi->next_period_byte = ssi->byte_per_period;
429}
430
431static int rsnd_ssi_pointer_offset(struct rsnd_mod *mod,
432 struct rsnd_dai_stream *io,
433 int additional)
434{
435 struct rsnd_ssi *ssi = rsnd_mod_to_ssi(mod);
436 struct snd_pcm_runtime *runtime = rsnd_io_to_runtime(io);
437 int pos = ssi->byte_pos + additional;
438
439 pos %= (runtime->periods * ssi->byte_per_period);
440
441 return pos;
442}
443
444static bool rsnd_ssi_pointer_update(struct rsnd_mod *mod,
445 struct rsnd_dai_stream *io,
446 int byte)
447{
448 struct rsnd_ssi *ssi = rsnd_mod_to_ssi(mod);
449 bool ret = false;
450 int byte_pos;
451
452 byte_pos = ssi->byte_pos + byte;
453
454 if (byte_pos >= ssi->next_period_byte) {
455 struct snd_pcm_runtime *runtime = rsnd_io_to_runtime(io);
456
457 ssi->period_pos++;
458 ssi->next_period_byte += ssi->byte_per_period;
459
460 if (ssi->period_pos >= runtime->periods) {
461 byte_pos = 0;
462 ssi->period_pos = 0;
463 ssi->next_period_byte = ssi->byte_per_period;
464 }
465
466 ret = true;
467 }
468
469 WRITE_ONCE(ssi->byte_pos, byte_pos);
470
471 return ret;
472}
473
474/* 417/*
475 * SSI mod common functions 418 * SSI mod common functions
476 */ 419 */
@@ -484,8 +427,6 @@ static int rsnd_ssi_init(struct rsnd_mod *mod,
484 if (!rsnd_ssi_is_run_mods(mod, io)) 427 if (!rsnd_ssi_is_run_mods(mod, io))
485 return 0; 428 return 0;
486 429
487 rsnd_ssi_pointer_init(mod, io);
488
489 ssi->usrcnt++; 430 ssi->usrcnt++;
490 431
491 rsnd_mod_power_on(mod); 432 rsnd_mod_power_on(mod);
@@ -656,6 +597,8 @@ static int rsnd_ssi_irq(struct rsnd_mod *mod,
656 return 0; 597 return 0;
657} 598}
658 599
600static bool rsnd_ssi_pio_interrupt(struct rsnd_mod *mod,
601 struct rsnd_dai_stream *io);
659static void __rsnd_ssi_interrupt(struct rsnd_mod *mod, 602static void __rsnd_ssi_interrupt(struct rsnd_mod *mod,
660 struct rsnd_dai_stream *io) 603 struct rsnd_dai_stream *io)
661{ 604{
@@ -674,30 +617,8 @@ static void __rsnd_ssi_interrupt(struct rsnd_mod *mod,
674 status = rsnd_ssi_status_get(mod); 617 status = rsnd_ssi_status_get(mod);
675 618
676 /* PIO only */ 619 /* PIO only */
677 if (!is_dma && (status & DIRQ)) { 620 if (!is_dma && (status & DIRQ))
678 struct snd_pcm_runtime *runtime = rsnd_io_to_runtime(io); 621 elapsed = rsnd_ssi_pio_interrupt(mod, io);
679 u32 *buf = (u32 *)(runtime->dma_area +
680 rsnd_ssi_pointer_offset(mod, io, 0));
681 int shift = 0;
682
683 switch (runtime->sample_bits) {
684 case 32:
685 shift = 8;
686 break;
687 }
688
689 /*
690 * 8/16/32 data can be assesse to TDR/RDR register
691 * directly as 32bit data
692 * see rsnd_ssi_init()
693 */
694 if (rsnd_io_is_play(io))
695 rsnd_mod_write(mod, SSITDR, (*buf) << shift);
696 else
697 *buf = (rsnd_mod_read(mod, SSIRDR) >> shift);
698
699 elapsed = rsnd_ssi_pointer_update(mod, io, sizeof(*buf));
700 }
701 622
702 /* DMA only */ 623 /* DMA only */
703 if (is_dma && (status & (UIRQ | OIRQ))) 624 if (is_dma && (status & (UIRQ | OIRQ)))
@@ -835,7 +756,71 @@ static int rsnd_ssi_common_remove(struct rsnd_mod *mod,
835 return 0; 756 return 0;
836} 757}
837 758
838static int rsnd_ssi_pointer(struct rsnd_mod *mod, 759/*
760 * SSI PIO functions
761 */
762static bool rsnd_ssi_pio_interrupt(struct rsnd_mod *mod,
763 struct rsnd_dai_stream *io)
764{
765 struct snd_pcm_runtime *runtime = rsnd_io_to_runtime(io);
766 struct rsnd_ssi *ssi = rsnd_mod_to_ssi(mod);
767 u32 *buf = (u32 *)(runtime->dma_area + ssi->byte_pos);
768 int shift = 0;
769 int byte_pos;
770 bool elapsed = false;
771
772 if (snd_pcm_format_width(runtime->format) == 24)
773 shift = 8;
774
775 /*
776 * 8/16/32 data can be assesse to TDR/RDR register
777 * directly as 32bit data
778 * see rsnd_ssi_init()
779 */
780 if (rsnd_io_is_play(io))
781 rsnd_mod_write(mod, SSITDR, (*buf) << shift);
782 else
783 *buf = (rsnd_mod_read(mod, SSIRDR) >> shift);
784
785 byte_pos = ssi->byte_pos + sizeof(*buf);
786
787 if (byte_pos >= ssi->next_period_byte) {
788 int period_pos = byte_pos / ssi->byte_per_period;
789
790 if (period_pos >= runtime->periods) {
791 byte_pos = 0;
792 period_pos = 0;
793 }
794
795 ssi->next_period_byte = (period_pos + 1) * ssi->byte_per_period;
796
797 elapsed = true;
798 }
799
800 WRITE_ONCE(ssi->byte_pos, byte_pos);
801
802 return elapsed;
803}
804
805static int rsnd_ssi_pio_init(struct rsnd_mod *mod,
806 struct rsnd_dai_stream *io,
807 struct rsnd_priv *priv)
808{
809 struct snd_pcm_runtime *runtime = rsnd_io_to_runtime(io);
810 struct rsnd_ssi *ssi = rsnd_mod_to_ssi(mod);
811
812 if (!rsnd_ssi_is_parent(mod, io)) {
813 ssi->byte_pos = 0;
814 ssi->byte_per_period = runtime->period_size *
815 runtime->channels *
816 samples_to_bytes(runtime, 1);
817 ssi->next_period_byte = ssi->byte_per_period;
818 }
819
820 return rsnd_ssi_init(mod, io, priv);
821}
822
823static int rsnd_ssi_pio_pointer(struct rsnd_mod *mod,
839 struct rsnd_dai_stream *io, 824 struct rsnd_dai_stream *io,
840 snd_pcm_uframes_t *pointer) 825 snd_pcm_uframes_t *pointer)
841{ 826{
@@ -851,12 +836,12 @@ static struct rsnd_mod_ops rsnd_ssi_pio_ops = {
851 .name = SSI_NAME, 836 .name = SSI_NAME,
852 .probe = rsnd_ssi_common_probe, 837 .probe = rsnd_ssi_common_probe,
853 .remove = rsnd_ssi_common_remove, 838 .remove = rsnd_ssi_common_remove,
854 .init = rsnd_ssi_init, 839 .init = rsnd_ssi_pio_init,
855 .quit = rsnd_ssi_quit, 840 .quit = rsnd_ssi_quit,
856 .start = rsnd_ssi_start, 841 .start = rsnd_ssi_start,
857 .stop = rsnd_ssi_stop, 842 .stop = rsnd_ssi_stop,
858 .irq = rsnd_ssi_irq, 843 .irq = rsnd_ssi_irq,
859 .pointer= rsnd_ssi_pointer, 844 .pointer = rsnd_ssi_pio_pointer,
860 .pcm_new = rsnd_ssi_pcm_new, 845 .pcm_new = rsnd_ssi_pcm_new,
861 .hw_params = rsnd_ssi_hw_params, 846 .hw_params = rsnd_ssi_hw_params,
862}; 847};
diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c
index 9b79c2199781..e018a2badfde 100644
--- a/sound/soc/soc-core.c
+++ b/sound/soc/soc-core.c
@@ -1393,6 +1393,16 @@ static int soc_init_dai_link(struct snd_soc_card *card,
1393 return 0; 1393 return 0;
1394} 1394}
1395 1395
1396void snd_soc_disconnect_sync(struct device *dev)
1397{
1398 struct snd_soc_component *component = snd_soc_lookup_component(dev, NULL);
1399
1400 if (!component || !component->card)
1401 return;
1402
1403 snd_card_disconnect_sync(component->card->snd_card);
1404}
1405
1396/** 1406/**
1397 * snd_soc_add_dai_link - Add a DAI link dynamically 1407 * snd_soc_add_dai_link - Add a DAI link dynamically
1398 * @card: The ASoC card to which the DAI link is added 1408 * @card: The ASoC card to which the DAI link is added