aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAngela Stegmaier2013-07-12 15:17:34 -0500
committerMisael Lopez Cruz2013-07-22 15:04:18 -0500
commitc46ee17381911655894b2f1d78f2e187f3db2c1e (patch)
treec70d616f006fa501640bdaaf58bde6876a3fa4f4
parent13b25a428ba2656d0d6ae2bd242a772e88850aba (diff)
downloadkernel-video-c46ee17381911655894b2f1d78f2e187f3db2c1e.tar.gz
kernel-video-c46ee17381911655894b2f1d78f2e187f3db2c1e.tar.xz
kernel-video-c46ee17381911655894b2f1d78f2e187f3db2c1e.zip
ASoC: davinci-mcasp: Add hw_rule for buffer_size when using AFIFO
The AFIFO threshold imposes a limiation on the buffer size. When the AFIFO is used, the buffer size (in samples) needs to be an integer multiple of the AFIFO threshold value (wnumevt, rnumevt). This patch adds a hw_rule to the McASP driver for version 4 of the McASP to account for the limitation on the buffer size. Change-Id: I3bd320130b10a55d3d84defd99572526ad6469fb Signed-off-by: Angela Stegmaier <angelabaker@ti.com>
-rw-r--r--sound/soc/davinci/davinci-mcasp.c81
1 files changed, 80 insertions, 1 deletions
diff --git a/sound/soc/davinci/davinci-mcasp.c b/sound/soc/davinci/davinci-mcasp.c
index da38efba721..ef30dbdd7ae 100644
--- a/sound/soc/davinci/davinci-mcasp.c
+++ b/sound/soc/davinci/davinci-mcasp.c
@@ -25,6 +25,7 @@
25#include <linux/of.h> 25#include <linux/of.h>
26#include <linux/of_platform.h> 26#include <linux/of_platform.h>
27#include <linux/of_device.h> 27#include <linux/of_device.h>
28#include <linux/lcm.h>
28 29
29#include <sound/core.h> 30#include <sound/core.h>
30#include <sound/pcm.h> 31#include <sound/pcm.h>
@@ -1042,14 +1043,92 @@ static int davinci_mcasp_trigger(struct snd_pcm_substream *substream,
1042 return ret; 1043 return ret;
1043} 1044}
1044 1045
1046static int davinci_mcasp_hwrule_buffersize(struct snd_pcm_hw_params *params,
1047 struct snd_pcm_hw_rule *rule,
1048 int stream)
1049{
1050 struct snd_interval *buffer_size = hw_param_interval(params,
1051 SNDRV_PCM_HW_PARAM_BUFFER_SIZE);
1052 int channels = params_channels(params);
1053 int periods = params_periods(params);
1054 struct davinci_audio_dev *dev = rule->private;
1055 int i;
1056 u8 slots = dev->tdm_slots;
1057 u8 max_active_serializers = (channels + slots - 1) / slots;
1058 u8 num_ser = 0;
1059 u8 num_evt = 0;
1060 unsigned long step = 1;
1061
1062 if (stream == SNDRV_PCM_STREAM_PLAYBACK) {
1063 for (i = 0; i < dev->num_serializer; i++) {
1064 if (dev->serial_dir[i] == TX_MODE &&
1065 num_ser < max_active_serializers)
1066 num_ser++;
1067 }
1068 num_evt = dev->txnumevt * num_ser;
1069 } else {
1070 for (i = 0; i < dev->num_serializer; i++) {
1071 if (dev->serial_dir[i] == RX_MODE &&
1072 num_ser < max_active_serializers)
1073 num_ser++;
1074 }
1075 num_evt = dev->rxnumevt * num_ser;
1076 }
1077
1078 /*
1079 * The buffersize (in samples), must be a multiple of num_evt. The
1080 * buffersize (in frames) is the product of the period_size and the
1081 * number of periods. Therefore, the buffersize should be a multiple
1082 * of the number of periods. The below finds the least common
1083 * multiple of num_evt and channels (since the number of samples
1084 * per frame is equal to the number of channels). It also makes sure
1085 * that the resulting step value (LCM / channels) is a multiple of the
1086 * number of periods.
1087 */
1088 step = lcm((lcm(num_evt, channels) / channels), periods);
1089
1090 return snd_interval_step(buffer_size, 0, step);
1091}
1092
1093static int davinci_mcasp_hwrule_txbuffersize(struct snd_pcm_hw_params *params,
1094 struct snd_pcm_hw_rule *rule)
1095{
1096 return davinci_mcasp_hwrule_buffersize(params, rule,
1097 SNDRV_PCM_STREAM_PLAYBACK);
1098}
1099
1100static int davinci_mcasp_hwrule_rxbuffersize(struct snd_pcm_hw_params *params,
1101 struct snd_pcm_hw_rule *rule)
1102{
1103 return davinci_mcasp_hwrule_buffersize(params, rule,
1104 SNDRV_PCM_STREAM_CAPTURE);
1105}
1106
1045static int davinci_mcasp_startup(struct snd_pcm_substream *substream, 1107static int davinci_mcasp_startup(struct snd_pcm_substream *substream,
1046 struct snd_soc_dai *dai) 1108 struct snd_soc_dai *dai)
1047{ 1109{
1048 struct davinci_audio_dev *dev = snd_soc_dai_get_drvdata(dai); 1110 struct davinci_audio_dev *dev = snd_soc_dai_get_drvdata(dai);
1049 1111
1050 if (dev->version == MCASP_VERSION_4) 1112
1113 if (dev->version == MCASP_VERSION_4) {
1051 snd_soc_dai_set_dma_data(dai, substream, 1114 snd_soc_dai_set_dma_data(dai, substream,
1052 dev->dma_params[substream->stream]); 1115 dev->dma_params[substream->stream]);
1116 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
1117 if (dev->txnumevt)
1118 snd_pcm_hw_rule_add(substream->runtime, 0,
1119 SNDRV_PCM_HW_PARAM_BUFFER_SIZE,
1120 davinci_mcasp_hwrule_txbuffersize,
1121 dev,
1122 SNDRV_PCM_HW_PARAM_BUFFER_SIZE, -1);
1123 } else if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) {
1124 if (dev->rxnumevt)
1125 snd_pcm_hw_rule_add(substream->runtime, 0,
1126 SNDRV_PCM_HW_PARAM_BUFFER_SIZE,
1127 davinci_mcasp_hwrule_rxbuffersize,
1128 dev,
1129 SNDRV_PCM_HW_PARAM_BUFFER_SIZE, -1);
1130 }
1131 }
1053 else 1132 else
1054 snd_soc_dai_set_dma_data(dai, substream, dev->dma_params); 1133 snd_soc_dai_set_dma_data(dai, substream, dev->dma_params);
1055 1134