2424#define PLAYBACK_MIN_PERIOD_SIZE 128
2525#define CAPTURE_MIN_NUM_PERIODS 2
2626#define CAPTURE_MAX_NUM_PERIODS 8
27- #define CAPTURE_MAX_PERIOD_SIZE 4096
28- #define CAPTURE_MIN_PERIOD_SIZE 320
27+ #define CAPTURE_MAX_PERIOD_SIZE 65536
28+ #define CAPTURE_MIN_PERIOD_SIZE 6144
2929#define BUFFER_BYTES_MAX (PLAYBACK_MAX_NUM_PERIODS * PLAYBACK_MAX_PERIOD_SIZE)
3030#define BUFFER_BYTES_MIN (PLAYBACK_MIN_NUM_PERIODS * PLAYBACK_MIN_PERIOD_SIZE)
3131#define COMPR_PLAYBACK_MAX_FRAGMENT_SIZE (128 * 1024)
@@ -64,12 +64,12 @@ struct q6apm_dai_rtd {
6464 phys_addr_t phys ;
6565 unsigned int pcm_size ;
6666 unsigned int pcm_count ;
67- unsigned int pos ; /* Buffer position */
6867 unsigned int periods ;
6968 unsigned int bytes_sent ;
7069 unsigned int bytes_received ;
7170 unsigned int copied_total ;
7271 uint16_t bits_per_sample ;
72+ snd_pcm_uframes_t queue_ptr ;
7373 bool next_track ;
7474 enum stream_state state ;
7575 struct q6apm_graph * graph ;
@@ -123,25 +123,16 @@ static void event_handler(uint32_t opcode, uint32_t token, void *payload, void *
123123{
124124 struct q6apm_dai_rtd * prtd = priv ;
125125 struct snd_pcm_substream * substream = prtd -> substream ;
126- unsigned long flags ;
127126
128127 switch (opcode ) {
129128 case APM_CLIENT_EVENT_CMD_EOS_DONE :
130129 prtd -> state = Q6APM_STREAM_STOPPED ;
131130 break ;
132131 case APM_CLIENT_EVENT_DATA_WRITE_DONE :
133- spin_lock_irqsave (& prtd -> lock , flags );
134- prtd -> pos += prtd -> pcm_count ;
135- spin_unlock_irqrestore (& prtd -> lock , flags );
136132 snd_pcm_period_elapsed (substream );
137- if (prtd -> state == Q6APM_STREAM_RUNNING )
138- q6apm_write_async (prtd -> graph , prtd -> pcm_count , 0 , 0 , 0 );
139133
140134 break ;
141135 case APM_CLIENT_EVENT_DATA_READ_DONE :
142- spin_lock_irqsave (& prtd -> lock , flags );
143- prtd -> pos += prtd -> pcm_count ;
144- spin_unlock_irqrestore (& prtd -> lock , flags );
145136 snd_pcm_period_elapsed (substream );
146137 if (prtd -> state == Q6APM_STREAM_RUNNING )
147138 q6apm_read (prtd -> graph );
@@ -248,7 +239,6 @@ static int q6apm_dai_prepare(struct snd_soc_component *component,
248239 }
249240
250241 prtd -> pcm_count = snd_pcm_lib_period_bytes (substream );
251- prtd -> pos = 0 ;
252242 /* rate and channels are sent to audio driver */
253243 ret = q6apm_graph_media_format_shmem (prtd -> graph , & cfg );
254244 if (ret < 0 ) {
@@ -294,6 +284,27 @@ static int q6apm_dai_prepare(struct snd_soc_component *component,
294284 return 0 ;
295285}
296286
287+ static int q6apm_dai_ack (struct snd_soc_component * component , struct snd_pcm_substream * substream )
288+ {
289+ struct snd_pcm_runtime * runtime = substream -> runtime ;
290+ struct q6apm_dai_rtd * prtd = runtime -> private_data ;
291+ int i , ret = 0 , avail_periods ;
292+
293+ if (substream -> stream == SNDRV_PCM_STREAM_PLAYBACK ) {
294+ avail_periods = (runtime -> control -> appl_ptr - prtd -> queue_ptr )/runtime -> period_size ;
295+ for (i = 0 ; i < avail_periods ; i ++ ) {
296+ ret = q6apm_write_async (prtd -> graph , prtd -> pcm_count , 0 , 0 , NO_TIMESTAMP );
297+ if (ret < 0 ) {
298+ dev_err (component -> dev , "Error queuing playback buffer %d\n" , ret );
299+ return ret ;
300+ }
301+ prtd -> queue_ptr += runtime -> period_size ;
302+ }
303+ }
304+
305+ return ret ;
306+ }
307+
297308static int q6apm_dai_trigger (struct snd_soc_component * component ,
298309 struct snd_pcm_substream * substream , int cmd )
299310{
@@ -305,9 +316,6 @@ static int q6apm_dai_trigger(struct snd_soc_component *component,
305316 case SNDRV_PCM_TRIGGER_START :
306317 case SNDRV_PCM_TRIGGER_RESUME :
307318 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE :
308- /* start writing buffers for playback only as we already queued capture buffers */
309- if (substream -> stream == SNDRV_PCM_STREAM_PLAYBACK )
310- ret = q6apm_write_async (prtd -> graph , prtd -> pcm_count , 0 , 0 , 0 );
311319 break ;
312320 case SNDRV_PCM_TRIGGER_STOP :
313321 /* TODO support be handled via SoftPause Module */
@@ -377,13 +385,14 @@ static int q6apm_dai_open(struct snd_soc_component *component,
377385 }
378386 }
379387
380- ret = snd_pcm_hw_constraint_step (runtime , 0 , SNDRV_PCM_HW_PARAM_PERIOD_BYTES , 32 );
388+ /* setup 10ms latency to accommodate DSP restrictions */
389+ ret = snd_pcm_hw_constraint_step (runtime , 0 , SNDRV_PCM_HW_PARAM_PERIOD_SIZE , 480 );
381390 if (ret < 0 ) {
382391 dev_err (dev , "constraint for period bytes step ret = %d\n" , ret );
383392 goto err ;
384393 }
385394
386- ret = snd_pcm_hw_constraint_step (runtime , 0 , SNDRV_PCM_HW_PARAM_BUFFER_BYTES , 32 );
395+ ret = snd_pcm_hw_constraint_step (runtime , 0 , SNDRV_PCM_HW_PARAM_BUFFER_SIZE , 480 );
387396 if (ret < 0 ) {
388397 dev_err (dev , "constraint for buffer bytes step ret = %d\n" , ret );
389398 goto err ;
@@ -428,16 +437,12 @@ static snd_pcm_uframes_t q6apm_dai_pointer(struct snd_soc_component *component,
428437 struct snd_pcm_runtime * runtime = substream -> runtime ;
429438 struct q6apm_dai_rtd * prtd = runtime -> private_data ;
430439 snd_pcm_uframes_t ptr ;
431- unsigned long flags ;
432440
433- spin_lock_irqsave (& prtd -> lock , flags );
434- if (prtd -> pos == prtd -> pcm_size )
435- prtd -> pos = 0 ;
436-
437- ptr = bytes_to_frames (runtime , prtd -> pos );
438- spin_unlock_irqrestore (& prtd -> lock , flags );
441+ ptr = q6apm_get_hw_pointer (prtd -> graph , substream -> stream ) * runtime -> period_size ;
442+ if (ptr )
443+ return ptr - 1 ;
439444
440- return ptr ;
445+ return 0 ;
441446}
442447
443448static int q6apm_dai_hw_params (struct snd_soc_component * component ,
@@ -652,8 +657,6 @@ static int q6apm_dai_compr_set_params(struct snd_soc_component *component,
652657 prtd -> pcm_size = runtime -> fragments * runtime -> fragment_size ;
653658 prtd -> bits_per_sample = 16 ;
654659
655- prtd -> pos = 0 ;
656-
657660 if (prtd -> next_track != true) {
658661 memcpy (& prtd -> codec , codec , sizeof (* codec ));
659662
@@ -836,6 +839,7 @@ static const struct snd_soc_component_driver q6apm_fe_dai_component = {
836839 .hw_params = q6apm_dai_hw_params ,
837840 .pointer = q6apm_dai_pointer ,
838841 .trigger = q6apm_dai_trigger ,
842+ .ack = q6apm_dai_ack ,
839843 .compress_ops = & q6apm_dai_compress_ops ,
840844 .use_dai_pcm_id = true,
841845};
0 commit comments