diff options
-rw-r--r-- | include/sound/soc.h | 39 | ||||
-rw-r--r-- | sound/soc/davinci/davinci-mcasp.c | 167 | ||||
-rw-r--r-- | sound/soc/soc-pcm.c | 47 |
3 files changed, 153 insertions, 100 deletions
diff --git a/include/sound/soc.h b/include/sound/soc.h index 2314103985d4..f10f48fad5d5 100644 --- a/include/sound/soc.h +++ b/include/sound/soc.h | |||
@@ -970,6 +970,24 @@ struct snd_soc_dai_link { | |||
970 | 970 | ||
971 | enum snd_soc_dpcm_trigger trigger[2]; /* trigger type for DPCM */ | 971 | enum snd_soc_dpcm_trigger trigger[2]; /* trigger type for DPCM */ |
972 | 972 | ||
973 | /* codec/machine specific init - e.g. add machine controls */ | ||
974 | int (*init)(struct snd_soc_pcm_runtime *rtd); | ||
975 | |||
976 | /* optional hw_params re-writing for BE and FE sync */ | ||
977 | int (*be_hw_params_fixup)(struct snd_soc_pcm_runtime *rtd, | ||
978 | struct snd_pcm_hw_params *params); | ||
979 | |||
980 | /* machine stream operations */ | ||
981 | const struct snd_soc_ops *ops; | ||
982 | const struct snd_soc_compr_ops *compr_ops; | ||
983 | |||
984 | /* For unidirectional dai links */ | ||
985 | bool playback_only; | ||
986 | bool capture_only; | ||
987 | |||
988 | /* Mark this pcm with non atomic ops */ | ||
989 | bool nonatomic; | ||
990 | |||
973 | /* Keep DAI active over suspend */ | 991 | /* Keep DAI active over suspend */ |
974 | unsigned int ignore_suspend:1; | 992 | unsigned int ignore_suspend:1; |
975 | 993 | ||
@@ -978,9 +996,6 @@ struct snd_soc_dai_link { | |||
978 | unsigned int symmetric_channels:1; | 996 | unsigned int symmetric_channels:1; |
979 | unsigned int symmetric_samplebits:1; | 997 | unsigned int symmetric_samplebits:1; |
980 | 998 | ||
981 | /* Mark this pcm with non atomic ops */ | ||
982 | bool nonatomic; | ||
983 | |||
984 | /* Do not create a PCM for this DAI link (Backend link) */ | 999 | /* Do not create a PCM for this DAI link (Backend link) */ |
985 | unsigned int no_pcm:1; | 1000 | unsigned int no_pcm:1; |
986 | 1001 | ||
@@ -991,23 +1006,11 @@ struct snd_soc_dai_link { | |||
991 | unsigned int dpcm_capture:1; | 1006 | unsigned int dpcm_capture:1; |
992 | unsigned int dpcm_playback:1; | 1007 | unsigned int dpcm_playback:1; |
993 | 1008 | ||
1009 | /* DPCM used FE & BE merged format */ | ||
1010 | unsigned int dpcm_merged_format:1; | ||
1011 | |||
994 | /* pmdown_time is ignored at stop */ | 1012 | /* pmdown_time is ignored at stop */ |
995 | unsigned int ignore_pmdown_time:1; | 1013 | unsigned int ignore_pmdown_time:1; |
996 | |||
997 | /* codec/machine specific init - e.g. add machine controls */ | ||
998 | int (*init)(struct snd_soc_pcm_runtime *rtd); | ||
999 | |||
1000 | /* optional hw_params re-writing for BE and FE sync */ | ||
1001 | int (*be_hw_params_fixup)(struct snd_soc_pcm_runtime *rtd, | ||
1002 | struct snd_pcm_hw_params *params); | ||
1003 | |||
1004 | /* machine stream operations */ | ||
1005 | const struct snd_soc_ops *ops; | ||
1006 | const struct snd_soc_compr_ops *compr_ops; | ||
1007 | |||
1008 | /* For unidirectional dai links */ | ||
1009 | bool playback_only; | ||
1010 | bool capture_only; | ||
1011 | }; | 1014 | }; |
1012 | 1015 | ||
1013 | struct snd_soc_codec_conf { | 1016 | struct snd_soc_codec_conf { |
diff --git a/sound/soc/davinci/davinci-mcasp.c b/sound/soc/davinci/davinci-mcasp.c index 23c91fa65ab8..d79349434a9a 100644 --- a/sound/soc/davinci/davinci-mcasp.c +++ b/sound/soc/davinci/davinci-mcasp.c | |||
@@ -107,6 +107,7 @@ struct davinci_mcasp { | |||
107 | #endif | 107 | #endif |
108 | 108 | ||
109 | struct davinci_mcasp_ruledata ruledata[2]; | 109 | struct davinci_mcasp_ruledata ruledata[2]; |
110 | struct snd_pcm_hw_constraint_list chconstr[2]; | ||
110 | }; | 111 | }; |
111 | 112 | ||
112 | static inline void mcasp_set_bits(struct davinci_mcasp *mcasp, u32 offset, | 113 | static inline void mcasp_set_bits(struct davinci_mcasp *mcasp, u32 offset, |
@@ -915,15 +916,12 @@ static int davinci_mcasp_hw_params(struct snd_pcm_substream *substream, | |||
915 | * the machine driver, we need to calculate the ratio. | 916 | * the machine driver, we need to calculate the ratio. |
916 | */ | 917 | */ |
917 | if (mcasp->bclk_master && mcasp->bclk_div == 0 && mcasp->sysclk_freq) { | 918 | if (mcasp->bclk_master && mcasp->bclk_div == 0 && mcasp->sysclk_freq) { |
918 | int channels = params_channels(params); | 919 | int slots = mcasp->tdm_slots; |
919 | int rate = params_rate(params); | 920 | int rate = params_rate(params); |
920 | int sbits = params_width(params); | 921 | int sbits = params_width(params); |
921 | int ppm, div; | 922 | int ppm, div; |
922 | 923 | ||
923 | if (channels > mcasp->tdm_slots) | 924 | div = davinci_mcasp_calc_clk_div(mcasp, rate*sbits*slots, |
924 | channels = mcasp->tdm_slots; | ||
925 | |||
926 | div = davinci_mcasp_calc_clk_div(mcasp, rate*sbits*channels, | ||
927 | &ppm); | 925 | &ppm); |
928 | if (ppm) | 926 | if (ppm) |
929 | dev_info(mcasp->dev, "Sample-rate is off by %d PPM\n", | 927 | dev_info(mcasp->dev, "Sample-rate is off by %d PPM\n", |
@@ -1024,31 +1022,36 @@ static int davinci_mcasp_hw_rule_rate(struct snd_pcm_hw_params *params, | |||
1024 | struct snd_interval *ri = | 1022 | struct snd_interval *ri = |
1025 | hw_param_interval(params, SNDRV_PCM_HW_PARAM_RATE); | 1023 | hw_param_interval(params, SNDRV_PCM_HW_PARAM_RATE); |
1026 | int sbits = params_width(params); | 1024 | int sbits = params_width(params); |
1027 | int channels = params_channels(params); | 1025 | int slots = rd->mcasp->tdm_slots; |
1028 | unsigned int list[ARRAY_SIZE(davinci_mcasp_dai_rates)]; | 1026 | struct snd_interval range; |
1029 | int i, count = 0; | 1027 | int i; |
1030 | 1028 | ||
1031 | if (channels > rd->mcasp->tdm_slots) | 1029 | snd_interval_any(&range); |
1032 | channels = rd->mcasp->tdm_slots; | 1030 | range.empty = 1; |
1033 | 1031 | ||
1034 | for (i = 0; i < ARRAY_SIZE(davinci_mcasp_dai_rates); i++) { | 1032 | for (i = 0; i < ARRAY_SIZE(davinci_mcasp_dai_rates); i++) { |
1035 | if (ri->min <= davinci_mcasp_dai_rates[i] && | 1033 | if (snd_interval_test(ri, davinci_mcasp_dai_rates[i])) { |
1036 | ri->max >= davinci_mcasp_dai_rates[i]) { | 1034 | uint bclk_freq = sbits*slots* |
1037 | uint bclk_freq = sbits*channels* | ||
1038 | davinci_mcasp_dai_rates[i]; | 1035 | davinci_mcasp_dai_rates[i]; |
1039 | int ppm; | 1036 | int ppm; |
1040 | 1037 | ||
1041 | davinci_mcasp_calc_clk_div(rd->mcasp, bclk_freq, &ppm); | 1038 | davinci_mcasp_calc_clk_div(rd->mcasp, bclk_freq, &ppm); |
1042 | if (abs(ppm) < DAVINCI_MAX_RATE_ERROR_PPM) | 1039 | if (abs(ppm) < DAVINCI_MAX_RATE_ERROR_PPM) { |
1043 | list[count++] = davinci_mcasp_dai_rates[i]; | 1040 | if (range.empty) { |
1041 | range.min = davinci_mcasp_dai_rates[i]; | ||
1042 | range.empty = 0; | ||
1043 | } | ||
1044 | range.max = davinci_mcasp_dai_rates[i]; | ||
1045 | } | ||
1044 | } | 1046 | } |
1045 | } | 1047 | } |
1048 | |||
1046 | dev_dbg(rd->mcasp->dev, | 1049 | dev_dbg(rd->mcasp->dev, |
1047 | "%d frequencies (%d-%d) for %d sbits and %d channels\n", | 1050 | "Frequencies %d-%d -> %d-%d for %d sbits and %d tdm slots\n", |
1048 | count, ri->min, ri->max, sbits, channels); | 1051 | ri->min, ri->max, range.min, range.max, sbits, slots); |
1049 | 1052 | ||
1050 | return snd_interval_list(hw_param_interval(params, rule->var), | 1053 | return snd_interval_refine(hw_param_interval(params, rule->var), |
1051 | count, list, 0); | 1054 | &range); |
1052 | } | 1055 | } |
1053 | 1056 | ||
1054 | static int davinci_mcasp_hw_rule_format(struct snd_pcm_hw_params *params, | 1057 | static int davinci_mcasp_hw_rule_format(struct snd_pcm_hw_params *params, |
@@ -1058,17 +1061,14 @@ static int davinci_mcasp_hw_rule_format(struct snd_pcm_hw_params *params, | |||
1058 | struct snd_mask *fmt = hw_param_mask(params, SNDRV_PCM_HW_PARAM_FORMAT); | 1061 | struct snd_mask *fmt = hw_param_mask(params, SNDRV_PCM_HW_PARAM_FORMAT); |
1059 | struct snd_mask nfmt; | 1062 | struct snd_mask nfmt; |
1060 | int rate = params_rate(params); | 1063 | int rate = params_rate(params); |
1061 | int channels = params_channels(params); | 1064 | int slots = rd->mcasp->tdm_slots; |
1062 | int i, count = 0; | 1065 | int i, count = 0; |
1063 | 1066 | ||
1064 | snd_mask_none(&nfmt); | 1067 | snd_mask_none(&nfmt); |
1065 | 1068 | ||
1066 | if (channels > rd->mcasp->tdm_slots) | ||
1067 | channels = rd->mcasp->tdm_slots; | ||
1068 | |||
1069 | for (i = 0; i < SNDRV_PCM_FORMAT_LAST; i++) { | 1069 | for (i = 0; i < SNDRV_PCM_FORMAT_LAST; i++) { |
1070 | if (snd_mask_test(fmt, i)) { | 1070 | if (snd_mask_test(fmt, i)) { |
1071 | uint bclk_freq = snd_pcm_format_width(i)*channels*rate; | 1071 | uint bclk_freq = snd_pcm_format_width(i)*slots*rate; |
1072 | int ppm; | 1072 | int ppm; |
1073 | 1073 | ||
1074 | davinci_mcasp_calc_clk_div(rd->mcasp, bclk_freq, &ppm); | 1074 | davinci_mcasp_calc_clk_div(rd->mcasp, bclk_freq, &ppm); |
@@ -1079,51 +1079,12 @@ static int davinci_mcasp_hw_rule_format(struct snd_pcm_hw_params *params, | |||
1079 | } | 1079 | } |
1080 | } | 1080 | } |
1081 | dev_dbg(rd->mcasp->dev, | 1081 | dev_dbg(rd->mcasp->dev, |
1082 | "%d possible sample format for %d Hz and %d channels\n", | 1082 | "%d possible sample format for %d Hz and %d tdm slots\n", |
1083 | count, rate, channels); | 1083 | count, rate, slots); |
1084 | 1084 | ||
1085 | return snd_mask_refine(fmt, &nfmt); | 1085 | return snd_mask_refine(fmt, &nfmt); |
1086 | } | 1086 | } |
1087 | 1087 | ||
1088 | static int davinci_mcasp_hw_rule_channels(struct snd_pcm_hw_params *params, | ||
1089 | struct snd_pcm_hw_rule *rule) | ||
1090 | { | ||
1091 | struct davinci_mcasp_ruledata *rd = rule->private; | ||
1092 | struct snd_interval *ci = | ||
1093 | hw_param_interval(params, SNDRV_PCM_HW_PARAM_CHANNELS); | ||
1094 | int sbits = params_width(params); | ||
1095 | int rate = params_rate(params); | ||
1096 | int max_chan_per_wire = rd->mcasp->tdm_slots < ci->max ? | ||
1097 | rd->mcasp->tdm_slots : ci->max; | ||
1098 | unsigned int list[ci->max - ci->min + 1]; | ||
1099 | int c1, c, count = 0; | ||
1100 | |||
1101 | for (c1 = ci->min; c1 <= max_chan_per_wire; c1++) { | ||
1102 | uint bclk_freq = c1*sbits*rate; | ||
1103 | int ppm; | ||
1104 | |||
1105 | davinci_mcasp_calc_clk_div(rd->mcasp, bclk_freq, &ppm); | ||
1106 | if (abs(ppm) < DAVINCI_MAX_RATE_ERROR_PPM) { | ||
1107 | /* If we can use all tdm_slots, we can put any | ||
1108 | amount of channels to remaining wires as | ||
1109 | long as they fit in. */ | ||
1110 | if (c1 == rd->mcasp->tdm_slots) { | ||
1111 | for (c = c1; c <= rd->serializers*c1 && | ||
1112 | c <= ci->max; c++) | ||
1113 | list[count++] = c; | ||
1114 | } else { | ||
1115 | list[count++] = c1; | ||
1116 | } | ||
1117 | } | ||
1118 | } | ||
1119 | dev_dbg(rd->mcasp->dev, | ||
1120 | "%d possible channel counts (%d-%d) for %d Hz and %d sbits\n", | ||
1121 | count, ci->min, ci->max, rate, sbits); | ||
1122 | |||
1123 | return snd_interval_list(hw_param_interval(params, rule->var), | ||
1124 | count, list, 0); | ||
1125 | } | ||
1126 | |||
1127 | static int davinci_mcasp_startup(struct snd_pcm_substream *substream, | 1088 | static int davinci_mcasp_startup(struct snd_pcm_substream *substream, |
1128 | struct snd_soc_dai *cpu_dai) | 1089 | struct snd_soc_dai *cpu_dai) |
1129 | { | 1090 | { |
@@ -1167,6 +1128,11 @@ static int davinci_mcasp_startup(struct snd_pcm_substream *substream, | |||
1167 | SNDRV_PCM_HW_PARAM_CHANNELS, | 1128 | SNDRV_PCM_HW_PARAM_CHANNELS, |
1168 | 2, max_channels); | 1129 | 2, max_channels); |
1169 | 1130 | ||
1131 | if (mcasp->chconstr[substream->stream].count) | ||
1132 | snd_pcm_hw_constraint_list(substream->runtime, | ||
1133 | 0, SNDRV_PCM_HW_PARAM_CHANNELS, | ||
1134 | &mcasp->chconstr[substream->stream]); | ||
1135 | |||
1170 | /* | 1136 | /* |
1171 | * If we rely on implicit BCLK divider setting we should | 1137 | * If we rely on implicit BCLK divider setting we should |
1172 | * set constraints based on what we can provide. | 1138 | * set constraints based on what we can provide. |
@@ -1180,24 +1146,14 @@ static int davinci_mcasp_startup(struct snd_pcm_substream *substream, | |||
1180 | SNDRV_PCM_HW_PARAM_RATE, | 1146 | SNDRV_PCM_HW_PARAM_RATE, |
1181 | davinci_mcasp_hw_rule_rate, | 1147 | davinci_mcasp_hw_rule_rate, |
1182 | ruledata, | 1148 | ruledata, |
1183 | SNDRV_PCM_HW_PARAM_FORMAT, | 1149 | SNDRV_PCM_HW_PARAM_FORMAT, -1); |
1184 | SNDRV_PCM_HW_PARAM_CHANNELS, -1); | ||
1185 | if (ret) | 1150 | if (ret) |
1186 | return ret; | 1151 | return ret; |
1187 | ret = snd_pcm_hw_rule_add(substream->runtime, 0, | 1152 | ret = snd_pcm_hw_rule_add(substream->runtime, 0, |
1188 | SNDRV_PCM_HW_PARAM_FORMAT, | 1153 | SNDRV_PCM_HW_PARAM_FORMAT, |
1189 | davinci_mcasp_hw_rule_format, | 1154 | davinci_mcasp_hw_rule_format, |
1190 | ruledata, | 1155 | ruledata, |
1191 | SNDRV_PCM_HW_PARAM_RATE, | 1156 | SNDRV_PCM_HW_PARAM_RATE, -1); |
1192 | SNDRV_PCM_HW_PARAM_CHANNELS, -1); | ||
1193 | if (ret) | ||
1194 | return ret; | ||
1195 | ret = snd_pcm_hw_rule_add(substream->runtime, 0, | ||
1196 | SNDRV_PCM_HW_PARAM_CHANNELS, | ||
1197 | davinci_mcasp_hw_rule_channels, | ||
1198 | ruledata, | ||
1199 | SNDRV_PCM_HW_PARAM_RATE, | ||
1200 | SNDRV_PCM_HW_PARAM_FORMAT, -1); | ||
1201 | if (ret) | 1157 | if (ret) |
1202 | return ret; | 1158 | return ret; |
1203 | } | 1159 | } |
@@ -1556,6 +1512,59 @@ nodata: | |||
1556 | return pdata; | 1512 | return pdata; |
1557 | } | 1513 | } |
1558 | 1514 | ||
1515 | /* All serializers must have equal number of channels */ | ||
1516 | static int davinci_mcasp_ch_constraint(struct davinci_mcasp *mcasp, | ||
1517 | struct snd_pcm_hw_constraint_list *cl, | ||
1518 | int serializers) | ||
1519 | { | ||
1520 | unsigned int *list; | ||
1521 | int i, count = 0; | ||
1522 | |||
1523 | if (serializers <= 1) | ||
1524 | return 0; | ||
1525 | |||
1526 | list = devm_kzalloc(mcasp->dev, sizeof(unsigned int) * | ||
1527 | (mcasp->tdm_slots + serializers - 2), | ||
1528 | GFP_KERNEL); | ||
1529 | if (!list) | ||
1530 | return -ENOMEM; | ||
1531 | |||
1532 | for (i = 2; i <= mcasp->tdm_slots; i++) | ||
1533 | list[count++] = i; | ||
1534 | |||
1535 | for (i = 2; i <= serializers; i++) | ||
1536 | list[count++] = i*mcasp->tdm_slots; | ||
1537 | |||
1538 | cl->count = count; | ||
1539 | cl->list = list; | ||
1540 | |||
1541 | return 0; | ||
1542 | } | ||
1543 | |||
1544 | |||
1545 | static int davinci_mcasp_init_ch_constraints(struct davinci_mcasp *mcasp) | ||
1546 | { | ||
1547 | int rx_serializers = 0, tx_serializers = 0, ret, i; | ||
1548 | |||
1549 | for (i = 0; i < mcasp->num_serializer; i++) | ||
1550 | if (mcasp->serial_dir[i] == TX_MODE) | ||
1551 | tx_serializers++; | ||
1552 | else if (mcasp->serial_dir[i] == RX_MODE) | ||
1553 | rx_serializers++; | ||
1554 | |||
1555 | ret = davinci_mcasp_ch_constraint(mcasp, &mcasp->chconstr[ | ||
1556 | SNDRV_PCM_STREAM_PLAYBACK], | ||
1557 | tx_serializers); | ||
1558 | if (ret) | ||
1559 | return ret; | ||
1560 | |||
1561 | ret = davinci_mcasp_ch_constraint(mcasp, &mcasp->chconstr[ | ||
1562 | SNDRV_PCM_STREAM_CAPTURE], | ||
1563 | rx_serializers); | ||
1564 | |||
1565 | return ret; | ||
1566 | } | ||
1567 | |||
1559 | static int davinci_mcasp_probe(struct platform_device *pdev) | 1568 | static int davinci_mcasp_probe(struct platform_device *pdev) |
1560 | { | 1569 | { |
1561 | struct snd_dmaengine_dai_dma_data *dma_data; | 1570 | struct snd_dmaengine_dai_dma_data *dma_data; |
@@ -1739,6 +1748,10 @@ static int davinci_mcasp_probe(struct platform_device *pdev) | |||
1739 | mcasp->fifo_base = DAVINCI_MCASP_V3_AFIFO_BASE; | 1748 | mcasp->fifo_base = DAVINCI_MCASP_V3_AFIFO_BASE; |
1740 | } | 1749 | } |
1741 | 1750 | ||
1751 | ret = davinci_mcasp_init_ch_constraints(mcasp); | ||
1752 | if (ret) | ||
1753 | goto err; | ||
1754 | |||
1742 | dev_set_drvdata(&pdev->dev, mcasp); | 1755 | dev_set_drvdata(&pdev->dev, mcasp); |
1743 | 1756 | ||
1744 | mcasp_reparent_fck(pdev); | 1757 | mcasp_reparent_fck(pdev); |
diff --git a/sound/soc/soc-pcm.c b/sound/soc/soc-pcm.c index 35fe58f4fa86..256b9c91aa94 100644 --- a/sound/soc/soc-pcm.c +++ b/sound/soc/soc-pcm.c | |||
@@ -1485,30 +1485,67 @@ unwind: | |||
1485 | } | 1485 | } |
1486 | 1486 | ||
1487 | static void dpcm_init_runtime_hw(struct snd_pcm_runtime *runtime, | 1487 | static void dpcm_init_runtime_hw(struct snd_pcm_runtime *runtime, |
1488 | struct snd_soc_pcm_stream *stream) | 1488 | struct snd_soc_pcm_stream *stream, |
1489 | u64 formats) | ||
1489 | { | 1490 | { |
1490 | runtime->hw.rate_min = stream->rate_min; | 1491 | runtime->hw.rate_min = stream->rate_min; |
1491 | runtime->hw.rate_max = stream->rate_max; | 1492 | runtime->hw.rate_max = stream->rate_max; |
1492 | runtime->hw.channels_min = stream->channels_min; | 1493 | runtime->hw.channels_min = stream->channels_min; |
1493 | runtime->hw.channels_max = stream->channels_max; | 1494 | runtime->hw.channels_max = stream->channels_max; |
1494 | if (runtime->hw.formats) | 1495 | if (runtime->hw.formats) |
1495 | runtime->hw.formats &= stream->formats; | 1496 | runtime->hw.formats &= formats & stream->formats; |
1496 | else | 1497 | else |
1497 | runtime->hw.formats = stream->formats; | 1498 | runtime->hw.formats = formats & stream->formats; |
1498 | runtime->hw.rates = stream->rates; | 1499 | runtime->hw.rates = stream->rates; |
1499 | } | 1500 | } |
1500 | 1501 | ||
1502 | static u64 dpcm_runtime_base_format(struct snd_pcm_substream *substream) | ||
1503 | { | ||
1504 | struct snd_soc_pcm_runtime *fe = substream->private_data; | ||
1505 | struct snd_soc_dpcm *dpcm; | ||
1506 | u64 formats = ULLONG_MAX; | ||
1507 | int stream = substream->stream; | ||
1508 | |||
1509 | if (!fe->dai_link->dpcm_merged_format) | ||
1510 | return formats; | ||
1511 | |||
1512 | /* | ||
1513 | * It returns merged BE codec format | ||
1514 | * if FE want to use it (= dpcm_merged_format) | ||
1515 | */ | ||
1516 | |||
1517 | list_for_each_entry(dpcm, &fe->dpcm[stream].be_clients, list_be) { | ||
1518 | struct snd_soc_pcm_runtime *be = dpcm->be; | ||
1519 | struct snd_soc_dai_driver *codec_dai_drv; | ||
1520 | struct snd_soc_pcm_stream *codec_stream; | ||
1521 | int i; | ||
1522 | |||
1523 | for (i = 0; i < be->num_codecs; i++) { | ||
1524 | codec_dai_drv = be->codec_dais[i]->driver; | ||
1525 | if (stream == SNDRV_PCM_STREAM_PLAYBACK) | ||
1526 | codec_stream = &codec_dai_drv->playback; | ||
1527 | else | ||
1528 | codec_stream = &codec_dai_drv->capture; | ||
1529 | |||
1530 | formats &= codec_stream->formats; | ||
1531 | } | ||
1532 | } | ||
1533 | |||
1534 | return formats; | ||
1535 | } | ||
1536 | |||
1501 | static void dpcm_set_fe_runtime(struct snd_pcm_substream *substream) | 1537 | static void dpcm_set_fe_runtime(struct snd_pcm_substream *substream) |
1502 | { | 1538 | { |
1503 | struct snd_pcm_runtime *runtime = substream->runtime; | 1539 | struct snd_pcm_runtime *runtime = substream->runtime; |
1504 | struct snd_soc_pcm_runtime *rtd = substream->private_data; | 1540 | struct snd_soc_pcm_runtime *rtd = substream->private_data; |
1505 | struct snd_soc_dai *cpu_dai = rtd->cpu_dai; | 1541 | struct snd_soc_dai *cpu_dai = rtd->cpu_dai; |
1506 | struct snd_soc_dai_driver *cpu_dai_drv = cpu_dai->driver; | 1542 | struct snd_soc_dai_driver *cpu_dai_drv = cpu_dai->driver; |
1543 | u64 format = dpcm_runtime_base_format(substream); | ||
1507 | 1544 | ||
1508 | if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) | 1545 | if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) |
1509 | dpcm_init_runtime_hw(runtime, &cpu_dai_drv->playback); | 1546 | dpcm_init_runtime_hw(runtime, &cpu_dai_drv->playback, format); |
1510 | else | 1547 | else |
1511 | dpcm_init_runtime_hw(runtime, &cpu_dai_drv->capture); | 1548 | dpcm_init_runtime_hw(runtime, &cpu_dai_drv->capture, format); |
1512 | } | 1549 | } |
1513 | 1550 | ||
1514 | static int dpcm_fe_dai_do_trigger(struct snd_pcm_substream *substream, int cmd); | 1551 | static int dpcm_fe_dai_do_trigger(struct snd_pcm_substream *substream, int cmd); |