We assume that there are always datas/spaces for playback/capture,
and then don't need to check the host side buffer pointers, here
remove these buffer check related code to save about 0.6KB to the
firmware binary size.
We also do code cleanup for host in this patch: remove superfluous
prefix 'host_' for host_data members, merge host_dma_cb_playback()
and host_dma_cb_capture() as they have most common code, and the
latter change can save about 0.25KB to firmware binary size.
Furthermore, we also fix the capture doesn't work issue at the
same time.
Signed-off-by: Keyon Jie <yang.jie@linux.intel.com>
Considering of capture pipeline, when doing .params(), we need
set params to each component's source buffer.
This patch implement that for host/volume component, as mixer is
only for playback ATM, and dai don't have source buffer for capture,
we don't need change them ATM.
Signed-off-by: Keyon Jie <yang.jie@linux.intel.com>
We met a variable uninitialized issue:
'ret' might be used uninitialized in this function.
host.c:606 | host_preload()
Here adding the initialized assignment to fix this issue.
Signed-off-by: Keyon Jie <yang.jie@linux.intel.com>
Preload entire pipeline and all components by walking the pipeline graph.
Signed-off-by: Liam Girdwood <liam.r.girdwood@linux.intel.com>
Modified-by: Keyon Jie <yang.jie@linux.intel.com>
The elements reset code may be shared by params() and stop(),
and the host side pointer resetting code may be used by both
reset() and stop().
Here create separate functions for those common codes, to make
code more clean.
Signed-off-by: Keyon Jie <yang.jie@linux.intel.com>
For command stop, excepting reset components, we may need reset
the buffer next to the component, otherwise, if the next start
command comes(without reset before it), the buffer pointers may
be disordered.
Signed-off-by: Keyon Jie <yang.jie@linux.intel.com>
After finished a transfer copy, check for reload channel:
1. if next.size is DMA_RELOAD_END, stop this dma copy;
2. if next.size > 0 but not DMA_RELOAD_LLI, use next
element for next copy;
3. if we are waiting for pause, pause it;
4. otherwise, reload lli.
Signed-off-by: Keyon Jie <yang.jie@linux.intel.com>
We should only copy when there is data, after copied the last bytes
or period, we will stop the dai and ssp, and trigger the pipeline
finish, which will notify host side the last read pointer and let
host side send trigger stop ipc.
Signed-off-by: Keyon Jie <yang.jie@linux.intel.com>
For the last bytes (< 1 period) copy, we need to remember this
for the size caculation at finished, here add dd->last_bytes for
this purpos.
Signed-off-by: Keyon Jie <yang.jie@linux.intel.com>
We should only copy when there is data, as we are using pulling
mode, should sink side should have free space always, we check
each source->avail and copy only some bytes when avail < period
size.
Signed-off-by: Keyon Jie <yang.jie@linux.intel.com>
As its sink won't be host/dai, it is alwasys internal component,
let's hard code it to STREAM_FORMAT_S32_LE ATM.
Signed-off-by: Keyon Jie <yang.jie@linux.intel.com>
We should only copy when there is data, as we are using pulling
mode, should sink side should have free space always, we check
source->avail only and copy only some bytes when avail < period
size.
Signed-off-by: Keyon Jie <yang.jie@linux.intel.com>
For component 'inactive, but ready' status, naming 'SETUP' may
be more understandable than 'STOPPED', and 'SETUP' is consistent
with ALSA.
new() params() start()
none ======> init =======> setup ======> running
<====== <======= <======
free() reset() stop()
If its sink is host, we need set it to 16bit(hard coded ATM);
if its sink is dai, we need set it to 32bit SSP format;
otherwise, for internal component, we uses STREAM_FORMAT_S32_LE.
Signed-off-by: Keyon Jie <yang.jie@linux.intel.com>
We don't copy when host_avail is 0(usually stream finished), at the
same time, we need wait until the dma copy is finished before we
can start next pulling copy.
Signed-off-by: Keyon Jie <yang.jie@linux.intel.com>
1. only pause at running stage;
2. resetting buffer pointers and local_elem for stopping, to let next
starting begin from original position;
3. adding processes for COMP_CMD_AVAIL_UPDATE.
Signed-off-by: Keyon Jie <yang.jie@linux.intel.com>
We need to clear those pointers at new(), and undo at reset()
those initialization what we did in set_params().
For new(), rzalloc() will help set host_data members to 0s and
NULLs.
Signed-off-by: Keyon Jie <yang.jie@linux.intel.com>
We need to wait until the last bytes/period is finished in dai,
before we can notify host side about that, otherwise, host side
will trigger stop too early, and we will miss rendering them.
Signed-off-by: Keyon Jie <yang.jie@linux.intel.com>
Here add R/W pointers check for playback, make sure the next
copy size is not bigger than the host avail bytes.
Signed-off-by: Keyon Jie <yang.jie@linux.intel.com>
This read pointer indicate how much we have read, we can use it
to inform host side to refill the free periods.
But as it doesn't really mean that we have rendered all of them
(there may be several periods in the pipeline buffer), and for
the last bytes/period, host side will trigger stop immediately
once it got this notification.
To avoid lost for last several periods issue, we postpone this
notification to the finish of last bytes/period copy in dai,
which will be add in the following patches.
Signed-off-by: Keyon Jie <yang.jie@linux.intel.com>
We use host_pos_blks to store the latest read pointer, and
report *host_pos to host side, here rename host_pos_blks to
host_pos_read to make it understandable.
Signed-off-by: Keyon Jie <yang.jie@linux.intel.com>
To implement host side buffer R/W pointer check, we need add
buffer update procedures at first, here we introduce host_avail
and host_free to indicate the buffer usuage status.
Signed-off-by: Keyon Jie <yang.jie@linux.intel.com>
It used IPC_INTEL_STR_PAUSE plus IPC_INTEL_STR_RESET to stop a
stream, but sometimes we application only intend to stop the
stream(e.g. speaker-test with large buffer size( > .wav file
size)), which means we only reset the buffer pointers but don't
need set params again(for reset, we need set params again).
Here add this stream operation IPC_INTEL_STR_STOP to handle
this case.
Signed-off-by: Keyon Jie <yang.jie@linux.intel.com>
We need the application buffer pointer(write pointer for playback)
update from the host side, to make the ALSA pcm buffer pointer
checking possible.
Here we introduce component command COMP_CMD_AVAIL_UPDATE for the
update event notification.
Signed-off-by: Keyon Jie <yang.jie@linux.intel.com>
The presentation_posn used for dai rendered bytes readback to
host side should be uint64_t type, according to the driver side
definition.
Signed-off-by: Keyon Jie <yang.jie@linux.intel.com>
We uses pull mode for running pipeline, that means, we
start each copy in pipeline_schedule_copy().
So here remove this superfluous one period copy.
Signed-off-by: Keyon Jie <yang.jie@linux.intel.com>
It reset dai_pos at prepare stage before, which will
make it wrong when the prepare is called more than
one time.
Here move the reset to MMAP_POS command handling,
which should happen at stream allocating stage only.
Signed-off-by: Keyon Jie <yang.jie@linux.intel.com>
We may meet src buffer bound, sink buffer bound, and
splitting may not finish at one time DMA copy, that
is, next_size < split_remaining, ...
This patch added to handle all of those cases, and
prepare for the buffer read/write pointer checking
in future.
Signed-off-by: Keyon Jie <yang.jie@linux.intel.com>
The Right channel was assigned with Left channel by mistake
in vol_s16_to_s32 and vol_s32_to_s32, here correct it.
Signed-off-by: Keyon Jie <yang.jie@linux.intel.com>
It will treat full buffer as empty one at current
comp_update_buffer(), as w_ptr is equal to r_ptr,
this will make us missing those datas or at least
the buffer->avail/free are not correct.
Here spit comp_update_buffer() into consuming one
and producing one, for consuming, 'r_ptr == w_ptr'
update means buffer is becoming empty, and for
producing, 'w_ptr == r_ptr' means buffer is becoming
full.
Signed-off-by: Keyon Jie <yang.jie@linux.intel.com>
The element frame_size in dai_config struct is actually
sample size for each channel, e.g. 24 for S24_4LE, so
rename it to sample_size to avoid confusion.
Signed-off-by: Keyon Jie <yang.jie@linux.intel.com>
As the normal static pipeline can work fine after the 1.33->1ms
buffer and 16->32 bits internal buffer transforming finished,
let's change back to use normal static pipeline by default.
Signed-off-by: Keyon Jie <yang.jie@linux.intel.com>
As we have changed internal buffer to 32 bits, to
avoid clamping, we need to change accumulator to
64 bits.
Signed-off-by: Keyon Jie <yang.jie@linux.intel.com>
As we are using 32 bits data in internal buffer, we need
24bit<==>32bit volume scaler for host<==>processing<==>dai
converting.
Signed-off-by: Keyon Jie <yang.jie@linux.intel.com>
When the host buffer is not 1ms aligned and splitting happens,
the increment is not period size, this wrong pointer will make
pcm data missed/clipped and sound noisy.
Changing to use the actual size last dma copy consumed,
local_elem->size, to fix the issue.
Signed-off-by: Keyon Jie <yang.jie@linux.intel.com>
Adding stream_format to indicate the stream format that the
dai buffer is using, which will be used for volume copy
functions mapping.
Signed-off-by: Keyon Jie <yang.jie@linux.intel.com>
Make the mixer compute two channels per loop iteration. This allows for
easier vectorisation. The loop is also more efficient if we update or
source/sink pointers after mixing has completed.
Signed-off-by: Liam Girdwood <liam.r.girdwood@linux.intel.com>
The conversion should up/down convert only if source/sink is host or dai.
Volume should be 32 bit at all other times
Signed-off-by: Liam Girdwood <liam.r.girdwood@linux.intel.com>
Use period frames instead of period size in bytes. This makes the pipeline
configuration less ambiguous and also allows for host, dai and internal frame
sizes to be defined.
Signed-off-by: Liam Girdwood <liam.r.girdwood@linux.intel.com>