*
* For nperiods < 4, the remaining BDs out of 4 are marked as invalid, so that
* the hardware skips those BDs in the loop.
+ *
+ * An exceptional setup is the case with nperiods=1. Since we have to update
+ * BDs after finishing one BD processing, we'd need at least two BDs, where
+ * both BDs point to the same content, the same address, the same size of the
+ * whole PCM buffer.
*/
#define AUD_BUF_ADDR(x) (AUD_BUF_A_ADDR + (x) * HAD_REG_WIDTH)
num_periods = runtime->periods;
intelhaddata->num_bds = min(num_periods, HAD_NUM_OF_RING_BUFS);
+ /* set the minimum 2 BDs for num_periods=1 */
+ intelhaddata->num_bds = max(intelhaddata->num_bds, 2U);
intelhaddata->period_bytes =
frames_to_bytes(runtime, runtime->period_size);
WARN_ON(intelhaddata->period_bytes & 0x3f);
intelhaddata->pcmbuf_filled = 0;
for (i = 0; i < HAD_NUM_OF_RING_BUFS; i++) {
- if (i < num_periods)
+ if (i < intelhaddata->num_bds)
had_prog_bd(substream, intelhaddata);
else /* invalidate the rest */
had_invalidate_bd(intelhaddata, i);
len = had_process_ringbuf(substream, intelhaddata);
if (len < 0)
return SNDRV_PCM_POS_XRUN;
- return bytes_to_frames(substream->runtime, len);
+ len = bytes_to_frames(substream->runtime, len);
+ /* wrapping may happen when periods=1 */
+ len %= substream->runtime->buffer_size;
+ return len;
}
/*
#define HAD_MAX_BUFFER ((1024 * 1024 - 1) & ~0x3f)
#define HAD_DEFAULT_BUFFER (600 * 1024) /* default prealloc size */
#define HAD_MAX_PERIODS 256 /* arbitrary, but should suffice */
-#define HAD_MIN_PERIODS 2
+#define HAD_MIN_PERIODS 1
#define HAD_MAX_PERIOD_BYTES ((HAD_MAX_BUFFER / HAD_MIN_PERIODS) & ~0x3f)
#define HAD_MIN_PERIOD_BYTES 1024 /* might be smaller */
#define HAD_FIFO_SIZE 0 /* fifo not being used */