aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKuninori Morimoto <kuninori.morimoto.gx@renesas.com>2017-10-10 21:37:23 -0400
committerMark Brown <broonie@kernel.org>2017-10-23 05:27:13 -0400
commitb8135864d4d33d0c35516ec758b9b73226935c5d (patch)
tree122b7d1061ef1e8423bee6b915e1bf5ff8b9401a
parent08e61d03b08c99f611227c6e94c70cf0029fdeb6 (diff)
ASoC: snd_soc_component_driver has snd_pcm_ops
Platform will be replaced into Component in the future. snd_soc_platform_driver has snd_pcm_ops, but snd_soc_component_driver doesn't have it. To prepare for replacing, this patch adds snd_pcm_ops on component driver. platform will be replaced into component, and its code will be removed. But during replacing, both platform and component process code exists. To keep compatibility, to avoid platform NULL access and to avoid platform/component duplicate operation during replacing process, this patch has such code. Some of this code will be removed when platform was removed. Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com> Signed-off-by: Mark Brown <broonie@kernel.org>
-rw-r--r--include/sound/soc.h2
-rw-r--r--sound/soc/soc-pcm.c367
2 files changed, 355 insertions, 14 deletions
diff --git a/include/sound/soc.h b/include/sound/soc.h
index eea3007a28f1..2acb56673bab 100644
--- a/include/sound/soc.h
+++ b/include/sound/soc.h
@@ -826,6 +826,8 @@ struct snd_soc_component_driver {
826 int (*set_bias_level)(struct snd_soc_component *component, 826 int (*set_bias_level)(struct snd_soc_component *component,
827 enum snd_soc_bias_level level); 827 enum snd_soc_bias_level level);
828 828
829 const struct snd_pcm_ops *ops;
830
829 /* probe ordering - for components with runtime dependencies */ 831 /* probe ordering - for components with runtime dependencies */
830 int probe_order; 832 int probe_order;
831 int remove_order; 833 int remove_order;
diff --git a/sound/soc/soc-pcm.c b/sound/soc/soc-pcm.c
index e5eb0cff790b..daaa670ee9b7 100644
--- a/sound/soc/soc-pcm.c
+++ b/sound/soc/soc-pcm.c
@@ -459,7 +459,7 @@ static int soc_pcm_open(struct snd_pcm_substream *substream)
459 struct snd_soc_dai *cpu_dai = rtd->cpu_dai; 459 struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
460 struct snd_soc_dai *codec_dai; 460 struct snd_soc_dai *codec_dai;
461 const char *codec_dai_name = "multicodec"; 461 const char *codec_dai_name = "multicodec";
462 int i, ret = 0; 462 int i, ret = 0, __ret;
463 463
464 pinctrl_pm_select_default_state(cpu_dai->dev); 464 pinctrl_pm_select_default_state(cpu_dai->dev);
465 for (i = 0; i < rtd->num_codecs; i++) 465 for (i = 0; i < rtd->num_codecs; i++)
@@ -483,7 +483,7 @@ static int soc_pcm_open(struct snd_pcm_substream *substream)
483 } 483 }
484 } 484 }
485 485
486 if (platform->driver->ops && platform->driver->ops->open) { 486 if (platform && platform->driver->ops && platform->driver->ops->open) {
487 ret = platform->driver->ops->open(substream); 487 ret = platform->driver->ops->open(substream);
488 if (ret < 0) { 488 if (ret < 0) {
489 dev_err(platform->dev, "ASoC: can't open platform" 489 dev_err(platform->dev, "ASoC: can't open platform"
@@ -492,6 +492,29 @@ static int soc_pcm_open(struct snd_pcm_substream *substream)
492 } 492 }
493 } 493 }
494 494
495 ret = 0;
496 for_each_rtdcom(rtd, rtdcom) {
497 component = rtdcom->component;
498
499 /* ignore duplication for now */
500 if (platform && (component == &platform->component))
501 continue;
502
503 if (!component->driver->ops ||
504 !component->driver->ops->open)
505 continue;
506
507 __ret = component->driver->ops->open(substream);
508 if (__ret < 0) {
509 dev_err(component->dev,
510 "ASoC: can't open component %s: %d\n",
511 component->name, ret);
512 ret = __ret;
513 }
514 }
515 if (ret < 0)
516 goto component_err;
517
495 for (i = 0; i < rtd->num_codecs; i++) { 518 for (i = 0; i < rtd->num_codecs; i++) {
496 codec_dai = rtd->codec_dais[i]; 519 codec_dai = rtd->codec_dais[i];
497 if (codec_dai->driver->ops->startup) { 520 if (codec_dai->driver->ops->startup) {
@@ -598,7 +621,22 @@ codec_dai_err:
598 codec_dai->driver->ops->shutdown(substream, codec_dai); 621 codec_dai->driver->ops->shutdown(substream, codec_dai);
599 } 622 }
600 623
601 if (platform->driver->ops && platform->driver->ops->close) 624component_err:
625 for_each_rtdcom(rtd, rtdcom) {
626 component = rtdcom->component;
627
628 /* ignore duplication for now */
629 if (platform && (component == &platform->component))
630 continue;
631
632 if (!component->driver->ops ||
633 !component->driver->ops->close)
634 continue;
635
636 component->driver->ops->close(substream);
637 }
638
639 if (platform && platform->driver->ops && platform->driver->ops->close)
602 platform->driver->ops->close(substream); 640 platform->driver->ops->close(substream);
603 641
604platform_err: 642platform_err:
@@ -695,9 +733,23 @@ static int soc_pcm_close(struct snd_pcm_substream *substream)
695 if (rtd->dai_link->ops->shutdown) 733 if (rtd->dai_link->ops->shutdown)
696 rtd->dai_link->ops->shutdown(substream); 734 rtd->dai_link->ops->shutdown(substream);
697 735
698 if (platform->driver->ops && platform->driver->ops->close) 736 if (platform && platform->driver->ops && platform->driver->ops->close)
699 platform->driver->ops->close(substream); 737 platform->driver->ops->close(substream);
700 738
739 for_each_rtdcom(rtd, rtdcom) {
740 component = rtdcom->component;
741
742 /* ignore duplication for now */
743 if (platform && (component == &platform->component))
744 continue;
745
746 if (!component->driver->ops ||
747 !component->driver->ops->close)
748 continue;
749
750 component->driver->ops->close(substream);
751 }
752
701 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { 753 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
702 if (snd_soc_runtime_ignore_pmdown_time(rtd)) { 754 if (snd_soc_runtime_ignore_pmdown_time(rtd)) {
703 /* powered down playback stream now */ 755 /* powered down playback stream now */
@@ -745,6 +797,8 @@ static int soc_pcm_prepare(struct snd_pcm_substream *substream)
745{ 797{
746 struct snd_soc_pcm_runtime *rtd = substream->private_data; 798 struct snd_soc_pcm_runtime *rtd = substream->private_data;
747 struct snd_soc_platform *platform = rtd->platform; 799 struct snd_soc_platform *platform = rtd->platform;
800 struct snd_soc_component *component;
801 struct snd_soc_rtdcom_list *rtdcom;
748 struct snd_soc_dai *cpu_dai = rtd->cpu_dai; 802 struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
749 struct snd_soc_dai *codec_dai; 803 struct snd_soc_dai *codec_dai;
750 int i, ret = 0; 804 int i, ret = 0;
@@ -760,7 +814,7 @@ static int soc_pcm_prepare(struct snd_pcm_substream *substream)
760 } 814 }
761 } 815 }
762 816
763 if (platform->driver->ops && platform->driver->ops->prepare) { 817 if (platform && platform->driver->ops && platform->driver->ops->prepare) {
764 ret = platform->driver->ops->prepare(substream); 818 ret = platform->driver->ops->prepare(substream);
765 if (ret < 0) { 819 if (ret < 0) {
766 dev_err(platform->dev, "ASoC: platform prepare error:" 820 dev_err(platform->dev, "ASoC: platform prepare error:"
@@ -769,6 +823,25 @@ static int soc_pcm_prepare(struct snd_pcm_substream *substream)
769 } 823 }
770 } 824 }
771 825
826 for_each_rtdcom(rtd, rtdcom) {
827 component = rtdcom->component;
828
829 /* ignore duplication for now */
830 if (platform && (component == &platform->component))
831 continue;
832
833 if (!component->driver->ops ||
834 !component->driver->ops->prepare)
835 continue;
836
837 ret = component->driver->ops->prepare(substream);
838 if (ret < 0) {
839 dev_err(component->dev,
840 "ASoC: platform prepare error: %d\n", ret);
841 goto out;
842 }
843 }
844
772 for (i = 0; i < rtd->num_codecs; i++) { 845 for (i = 0; i < rtd->num_codecs; i++) {
773 codec_dai = rtd->codec_dais[i]; 846 codec_dai = rtd->codec_dais[i];
774 if (codec_dai->driver->ops->prepare) { 847 if (codec_dai->driver->ops->prepare) {
@@ -851,8 +924,10 @@ static int soc_pcm_hw_params(struct snd_pcm_substream *substream,
851{ 924{
852 struct snd_soc_pcm_runtime *rtd = substream->private_data; 925 struct snd_soc_pcm_runtime *rtd = substream->private_data;
853 struct snd_soc_platform *platform = rtd->platform; 926 struct snd_soc_platform *platform = rtd->platform;
927 struct snd_soc_component *component;
928 struct snd_soc_rtdcom_list *rtdcom;
854 struct snd_soc_dai *cpu_dai = rtd->cpu_dai; 929 struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
855 int i, ret = 0; 930 int i, ret = 0, __ret;
856 931
857 mutex_lock_nested(&rtd->pcm_mutex, rtd->pcm_subclass); 932 mutex_lock_nested(&rtd->pcm_mutex, rtd->pcm_subclass);
858 if (rtd->dai_link->ops->hw_params) { 933 if (rtd->dai_link->ops->hw_params) {
@@ -910,7 +985,7 @@ static int soc_pcm_hw_params(struct snd_pcm_substream *substream,
910 if (ret < 0) 985 if (ret < 0)
911 goto interface_err; 986 goto interface_err;
912 987
913 if (platform->driver->ops && platform->driver->ops->hw_params) { 988 if (platform && platform->driver->ops && platform->driver->ops->hw_params) {
914 ret = platform->driver->ops->hw_params(substream, params); 989 ret = platform->driver->ops->hw_params(substream, params);
915 if (ret < 0) { 990 if (ret < 0) {
916 dev_err(platform->dev, "ASoC: %s hw params failed: %d\n", 991 dev_err(platform->dev, "ASoC: %s hw params failed: %d\n",
@@ -919,20 +994,60 @@ static int soc_pcm_hw_params(struct snd_pcm_substream *substream,
919 } 994 }
920 } 995 }
921 996
997 ret = 0;
998 for_each_rtdcom(rtd, rtdcom) {
999 component = rtdcom->component;
1000
1001 /* ignore duplication for now */
1002 if (platform && (component == &platform->component))
1003 continue;
1004
1005 if (!component->driver->ops ||
1006 !component->driver->ops->hw_params)
1007 continue;
1008
1009 __ret = component->driver->ops->hw_params(substream, params);
1010 if (__ret < 0) {
1011 dev_err(component->dev,
1012 "ASoC: %s hw params failed: %d\n",
1013 component->name, ret);
1014 ret = __ret;
1015 }
1016 }
1017 if (ret < 0)
1018 goto component_err;
1019
922 /* store the parameters for each DAIs */ 1020 /* store the parameters for each DAIs */
923 cpu_dai->rate = params_rate(params); 1021 cpu_dai->rate = params_rate(params);
924 cpu_dai->channels = params_channels(params); 1022 cpu_dai->channels = params_channels(params);
925 cpu_dai->sample_bits = 1023 cpu_dai->sample_bits =
926 snd_pcm_format_physical_width(params_format(params)); 1024 snd_pcm_format_physical_width(params_format(params));
927 1025
928
929 ret = soc_pcm_params_symmetry(substream, params); 1026 ret = soc_pcm_params_symmetry(substream, params);
930 if (ret) 1027 if (ret)
931 goto platform_err; 1028 goto component_err;
932out: 1029out:
933 mutex_unlock(&rtd->pcm_mutex); 1030 mutex_unlock(&rtd->pcm_mutex);
934 return ret; 1031 return ret;
935 1032
1033component_err:
1034 for_each_rtdcom(rtd, rtdcom) {
1035 component = rtdcom->component;
1036
1037 /* ignore duplication */
1038 if (platform && (component == &platform->component))
1039 continue;
1040
1041 if (!component->driver->ops ||
1042 !component->driver->ops->hw_free)
1043 continue;
1044
1045 component->driver->ops->hw_free(substream);
1046 }
1047
1048 if (platform && platform->driver->ops && platform->driver->ops->hw_free)
1049 platform->driver->ops->hw_free(substream);
1050
936platform_err: 1051platform_err:
937 if (cpu_dai->driver->ops->hw_free) 1052 if (cpu_dai->driver->ops->hw_free)
938 cpu_dai->driver->ops->hw_free(substream, cpu_dai); 1053 cpu_dai->driver->ops->hw_free(substream, cpu_dai);
@@ -962,6 +1077,8 @@ static int soc_pcm_hw_free(struct snd_pcm_substream *substream)
962{ 1077{
963 struct snd_soc_pcm_runtime *rtd = substream->private_data; 1078 struct snd_soc_pcm_runtime *rtd = substream->private_data;
964 struct snd_soc_platform *platform = rtd->platform; 1079 struct snd_soc_platform *platform = rtd->platform;
1080 struct snd_soc_component *component;
1081 struct snd_soc_rtdcom_list *rtdcom;
965 struct snd_soc_dai *cpu_dai = rtd->cpu_dai; 1082 struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
966 struct snd_soc_dai *codec_dai; 1083 struct snd_soc_dai *codec_dai;
967 bool playback = substream->stream == SNDRV_PCM_STREAM_PLAYBACK; 1084 bool playback = substream->stream == SNDRV_PCM_STREAM_PLAYBACK;
@@ -998,9 +1115,24 @@ static int soc_pcm_hw_free(struct snd_pcm_substream *substream)
998 rtd->dai_link->ops->hw_free(substream); 1115 rtd->dai_link->ops->hw_free(substream);
999 1116
1000 /* free any DMA resources */ 1117 /* free any DMA resources */
1001 if (platform->driver->ops && platform->driver->ops->hw_free) 1118 if (platform && platform->driver->ops && platform->driver->ops->hw_free)
1002 platform->driver->ops->hw_free(substream); 1119 platform->driver->ops->hw_free(substream);
1003 1120
1121 /* free any component resources */
1122 for_each_rtdcom(rtd, rtdcom) {
1123 component = rtdcom->component;
1124
1125 /* ignore duplication for now */
1126 if (platform && (component == &platform->component))
1127 continue;
1128
1129 if (!component->driver->ops ||
1130 !component->driver->ops->hw_free)
1131 continue;
1132
1133 component->driver->ops->hw_free(substream);
1134 }
1135
1004 /* now free hw params for the DAIs */ 1136 /* now free hw params for the DAIs */
1005 for (i = 0; i < rtd->num_codecs; i++) { 1137 for (i = 0; i < rtd->num_codecs; i++) {
1006 codec_dai = rtd->codec_dais[i]; 1138 codec_dai = rtd->codec_dais[i];
@@ -1019,6 +1151,8 @@ static int soc_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
1019{ 1151{
1020 struct snd_soc_pcm_runtime *rtd = substream->private_data; 1152 struct snd_soc_pcm_runtime *rtd = substream->private_data;
1021 struct snd_soc_platform *platform = rtd->platform; 1153 struct snd_soc_platform *platform = rtd->platform;
1154 struct snd_soc_component *component;
1155 struct snd_soc_rtdcom_list *rtdcom;
1022 struct snd_soc_dai *cpu_dai = rtd->cpu_dai; 1156 struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
1023 struct snd_soc_dai *codec_dai; 1157 struct snd_soc_dai *codec_dai;
1024 int i, ret; 1158 int i, ret;
@@ -1033,12 +1167,28 @@ static int soc_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
1033 } 1167 }
1034 } 1168 }
1035 1169
1036 if (platform->driver->ops && platform->driver->ops->trigger) { 1170 if (platform && platform->driver->ops && platform->driver->ops->trigger) {
1037 ret = platform->driver->ops->trigger(substream, cmd); 1171 ret = platform->driver->ops->trigger(substream, cmd);
1038 if (ret < 0) 1172 if (ret < 0)
1039 return ret; 1173 return ret;
1040 } 1174 }
1041 1175
1176 for_each_rtdcom(rtd, rtdcom) {
1177 component = rtdcom->component;
1178
1179 /* ignore duplication for now */
1180 if (platform && (component == &platform->component))
1181 continue;
1182
1183 if (!component->driver->ops ||
1184 !component->driver->ops->trigger)
1185 continue;
1186
1187 ret = component->driver->ops->trigger(substream, cmd);
1188 if (ret < 0)
1189 return ret;
1190 }
1191
1042 if (cpu_dai->driver->ops->trigger) { 1192 if (cpu_dai->driver->ops->trigger) {
1043 ret = cpu_dai->driver->ops->trigger(substream, cmd, cpu_dai); 1193 ret = cpu_dai->driver->ops->trigger(substream, cmd, cpu_dai);
1044 if (ret < 0) 1194 if (ret < 0)
@@ -1088,6 +1238,8 @@ static snd_pcm_uframes_t soc_pcm_pointer(struct snd_pcm_substream *substream)
1088{ 1238{
1089 struct snd_soc_pcm_runtime *rtd = substream->private_data; 1239 struct snd_soc_pcm_runtime *rtd = substream->private_data;
1090 struct snd_soc_platform *platform = rtd->platform; 1240 struct snd_soc_platform *platform = rtd->platform;
1241 struct snd_soc_component *component;
1242 struct snd_soc_rtdcom_list *rtdcom;
1091 struct snd_soc_dai *cpu_dai = rtd->cpu_dai; 1243 struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
1092 struct snd_soc_dai *codec_dai; 1244 struct snd_soc_dai *codec_dai;
1093 struct snd_pcm_runtime *runtime = substream->runtime; 1245 struct snd_pcm_runtime *runtime = substream->runtime;
@@ -1096,9 +1248,25 @@ static snd_pcm_uframes_t soc_pcm_pointer(struct snd_pcm_substream *substream)
1096 snd_pcm_sframes_t codec_delay = 0; 1248 snd_pcm_sframes_t codec_delay = 0;
1097 int i; 1249 int i;
1098 1250
1099 if (platform->driver->ops && platform->driver->ops->pointer) 1251 if (platform && platform->driver->ops && platform->driver->ops->pointer)
1100 offset = platform->driver->ops->pointer(substream); 1252 offset = platform->driver->ops->pointer(substream);
1101 1253
1254 for_each_rtdcom(rtd, rtdcom) {
1255 component = rtdcom->component;
1256
1257 /* ignore duplication for now */
1258 if (platform && (component == &platform->component))
1259 continue;
1260
1261 if (!component->driver->ops ||
1262 !component->driver->ops->pointer)
1263 continue;
1264
1265 /* FIXME: use 1st pointer */
1266 offset = component->driver->ops->pointer(substream);
1267 break;
1268 }
1269
1102 if (cpu_dai->driver->ops->delay) 1270 if (cpu_dai->driver->ops->delay)
1103 delay += cpu_dai->driver->ops->delay(substream, cpu_dai); 1271 delay += cpu_dai->driver->ops->delay(substream, cpu_dai);
1104 1272
@@ -2283,9 +2451,27 @@ static int soc_pcm_ioctl(struct snd_pcm_substream *substream,
2283{ 2451{
2284 struct snd_soc_pcm_runtime *rtd = substream->private_data; 2452 struct snd_soc_pcm_runtime *rtd = substream->private_data;
2285 struct snd_soc_platform *platform = rtd->platform; 2453 struct snd_soc_platform *platform = rtd->platform;
2454 struct snd_soc_component *component;
2455 struct snd_soc_rtdcom_list *rtdcom;
2286 2456
2287 if (platform->driver->ops && platform->driver->ops->ioctl) 2457 if (platform && platform->driver->ops && platform->driver->ops->ioctl)
2288 return platform->driver->ops->ioctl(substream, cmd, arg); 2458 return platform->driver->ops->ioctl(substream, cmd, arg);
2459
2460 for_each_rtdcom(rtd, rtdcom) {
2461 component = rtdcom->component;
2462
2463 /* ignore duplication for now */
2464 if (platform && (component == &platform->component))
2465 continue;
2466
2467 if (!component->driver->ops ||
2468 !component->driver->ops->ioctl)
2469 continue;
2470
2471 /* FIXME: use 1st ioctl */
2472 return component->driver->ops->ioctl(substream, cmd, arg);
2473 }
2474
2289 return snd_pcm_lib_ioctl(substream, cmd, arg); 2475 return snd_pcm_lib_ioctl(substream, cmd, arg);
2290} 2476}
2291 2477
@@ -2647,6 +2833,138 @@ static void soc_pcm_private_free(struct snd_pcm *pcm)
2647 } 2833 }
2648} 2834}
2649 2835
2836static int soc_rtdcom_ack(struct snd_pcm_substream *substream)
2837{
2838 struct snd_soc_pcm_runtime *rtd = substream->private_data;
2839 struct snd_soc_rtdcom_list *rtdcom;
2840 struct snd_soc_component *component;
2841
2842 for_each_rtdcom(rtd, rtdcom) {
2843 component = rtdcom->component;
2844
2845 if (!component->driver->ops ||
2846 !component->driver->ops->ack)
2847 continue;
2848
2849 /* FIXME. it returns 1st ask now */
2850 return component->driver->ops->ack(substream);
2851 }
2852
2853 return -EINVAL;
2854}
2855
2856static int soc_rtdcom_copy_user(struct snd_pcm_substream *substream, int channel,
2857 unsigned long pos, void __user *buf,
2858 unsigned long bytes)
2859{
2860 struct snd_soc_pcm_runtime *rtd = substream->private_data;
2861 struct snd_soc_rtdcom_list *rtdcom;
2862 struct snd_soc_component *component;
2863
2864 for_each_rtdcom(rtd, rtdcom) {
2865 component = rtdcom->component;
2866
2867 if (!component->driver->ops ||
2868 !component->driver->ops->copy_user)
2869 continue;
2870
2871 /* FIXME. it returns 1st copy now */
2872 return component->driver->ops->copy_user(substream, channel,
2873 pos, buf, bytes);
2874 }
2875
2876 return -EINVAL;
2877}
2878
2879static int soc_rtdcom_copy_kernel(struct snd_pcm_substream *substream, int channel,
2880 unsigned long pos, void *buf, unsigned long bytes)
2881{
2882 struct snd_soc_pcm_runtime *rtd = substream->private_data;
2883 struct snd_soc_rtdcom_list *rtdcom;
2884 struct snd_soc_component *component;
2885
2886 for_each_rtdcom(rtd, rtdcom) {
2887 component = rtdcom->component;
2888
2889 if (!component->driver->ops ||
2890 !component->driver->ops->copy_kernel)
2891 continue;
2892
2893 /* FIXME. it returns 1st copy now */
2894 return component->driver->ops->copy_kernel(substream, channel,
2895 pos, buf, bytes);
2896 }
2897
2898 return -EINVAL;
2899}
2900
2901static int soc_rtdcom_fill_silence(struct snd_pcm_substream *substream, int channel,
2902 unsigned long pos, unsigned long bytes)
2903{
2904 struct snd_soc_pcm_runtime *rtd = substream->private_data;
2905 struct snd_soc_rtdcom_list *rtdcom;
2906 struct snd_soc_component *component;
2907
2908 for_each_rtdcom(rtd, rtdcom) {
2909 component = rtdcom->component;
2910
2911 if (!component->driver->ops ||
2912 !component->driver->ops->fill_silence)
2913 continue;
2914
2915 /* FIXME. it returns 1st silence now */
2916 return component->driver->ops->fill_silence(substream, channel,
2917 pos, bytes);
2918 }
2919
2920 return -EINVAL;
2921}
2922
2923static struct page *soc_rtdcom_page(struct snd_pcm_substream *substream,
2924 unsigned long offset)
2925{
2926 struct snd_soc_pcm_runtime *rtd = substream->private_data;
2927 struct snd_soc_rtdcom_list *rtdcom;
2928 struct snd_soc_component *component;
2929 struct page *page;
2930
2931 for_each_rtdcom(rtd, rtdcom) {
2932 component = rtdcom->component;
2933
2934 if (!component->driver->ops ||
2935 !component->driver->ops->page)
2936 continue;
2937
2938 /* FIXME. it returns 1st page now */
2939 page = component->driver->ops->page(substream, offset);
2940 if (page)
2941 return page;
2942 }
2943
2944 return NULL;
2945}
2946
2947static int soc_rtdcom_mmap(struct snd_pcm_substream *substream,
2948 struct vm_area_struct *vma)
2949{
2950 struct snd_soc_pcm_runtime *rtd = substream->private_data;
2951 struct snd_soc_rtdcom_list *rtdcom;
2952 struct snd_soc_component *component;
2953
2954 for_each_rtdcom(rtd, rtdcom) {
2955 component = rtdcom->component;
2956
2957 if (!component->driver->ops ||
2958 !component->driver->ops->mmap)
2959 continue;
2960
2961 /* FIXME. it returns 1st mmap now */
2962 return component->driver->ops->mmap(substream, vma);
2963 }
2964
2965 return -EINVAL;
2966}
2967
2650/* create a new pcm */ 2968/* create a new pcm */
2651int soc_new_pcm(struct snd_soc_pcm_runtime *rtd, int num) 2969int soc_new_pcm(struct snd_soc_pcm_runtime *rtd, int num)
2652{ 2970{
@@ -2749,7 +3067,28 @@ int soc_new_pcm(struct snd_soc_pcm_runtime *rtd, int num)
2749 rtd->ops.ioctl = soc_pcm_ioctl; 3067 rtd->ops.ioctl = soc_pcm_ioctl;
2750 } 3068 }
2751 3069
2752 if (platform->driver->ops) { 3070 for_each_rtdcom(rtd, rtdcom) {
3071 const struct snd_pcm_ops *ops = rtdcom->component->driver->ops;
3072
3073 if (!ops)
3074 continue;
3075
3076 if (ops->ack)
3077 rtd->ops.ack = soc_rtdcom_ack;
3078 if (ops->copy_user)
3079 rtd->ops.copy_user = soc_rtdcom_copy_user;
3080 if (ops->copy_kernel)
3081 rtd->ops.copy_kernel = soc_rtdcom_copy_kernel;
3082 if (ops->fill_silence)
3083 rtd->ops.fill_silence = soc_rtdcom_fill_silence;
3084 if (ops->page)
3085 rtd->ops.page = soc_rtdcom_page;
3086 if (ops->mmap)
3087 rtd->ops.mmap = soc_rtdcom_mmap;
3088 }
3089
3090 /* overwrite */
3091 if (platform && platform->driver->ops) {
2753 rtd->ops.ack = platform->driver->ops->ack; 3092 rtd->ops.ack = platform->driver->ops->ack;
2754 rtd->ops.copy_user = platform->driver->ops->copy_user; 3093 rtd->ops.copy_user = platform->driver->ops->copy_user;
2755 rtd->ops.copy_kernel = platform->driver->ops->copy_kernel; 3094 rtd->ops.copy_kernel = platform->driver->ops->copy_kernel;