Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions src/audio/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ if(NOT BUILD_LIBRARY)
detect_test.c
)
endif()
add_subdirectory(pcm_converter)
return()
endif()

Expand Down
165 changes: 41 additions & 124 deletions src/audio/dai.c
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@

#include <sof/audio/buffer.h>
#include <sof/audio/component.h>
#include <sof/audio/format.h>
#include <sof/audio/pcm_converter.h>
#include <sof/audio/pipeline.h>
#include <sof/common.h>
#include <sof/debug/panic.h>
Expand Down Expand Up @@ -56,7 +58,7 @@ struct dai_data {

struct dai *dai;
struct dma *dma;
uint32_t frame_bytes;
enum sof_ipc_frame frame_fmt;
int xrun; /* true if we are doing xrun recovery */

/* processing function */
Expand All @@ -78,6 +80,7 @@ static void dai_dma_cb(void *data, uint32_t type, struct dma_cb_data *next)
struct comp_dev *dev = (struct comp_dev *)data;
struct dai_data *dd = comp_get_drvdata(dev);
uint32_t bytes = next->elem.size;
uint32_t samples = bytes / sample_bytes(dd->frame_fmt);
struct comp_buffer *local_buffer;
void *buffer_ptr;

Expand Down Expand Up @@ -108,16 +111,18 @@ static void dai_dma_cb(void *data, uint32_t type, struct dma_cb_data *next)
local_buffer = list_first_item(&dev->bsource_list,
struct comp_buffer, sink_list);

dma_buffer_copy_to(local_buffer, dd->dma_buffer, dd->process,
bytes);
dma_buffer_copy_to(local_buffer,
samples * comp_sample_bytes(dev),
dd->dma_buffer, bytes, dd->process, samples);

buffer_ptr = local_buffer->r_ptr;
} else {
local_buffer = list_first_item(&dev->bsink_list,
struct comp_buffer, source_list);

dma_buffer_copy_from(dd->dma_buffer, local_buffer, dd->process,
bytes);
dma_buffer_copy_from(dd->dma_buffer, bytes, local_buffer,
samples * comp_sample_bytes(dev),
dd->process, samples);

buffer_ptr = local_buffer->w_ptr;
}
Expand Down Expand Up @@ -225,10 +230,14 @@ static int dai_playback_params(struct comp_dev *dev, uint32_t period_bytes,
uint32_t fifo;
int err;

/* set processing function */
dd->process = pcm_get_conversion_function(dev->params.frame_fmt,
dd->frame_fmt);

/* set up DMA configuration */
config->direction = DMA_DIR_MEM_TO_DEV;
config->src_width = comp_sample_bytes(dev);
config->dest_width = comp_sample_bytes(dev);
config->src_width = sample_bytes(dd->frame_fmt);
config->dest_width = sample_bytes(dd->frame_fmt);
config->cyclic = 1;
config->irq_disabled = pipeline_is_timer_driven(dev->pipeline);
config->dest_dev = dai_get_handshake(dd->dai, dev->params.direction,
Expand Down Expand Up @@ -274,6 +283,10 @@ static int dai_capture_params(struct comp_dev *dev, uint32_t period_bytes,
uint32_t fifo;
int err;

/* set processing function */
dd->process = pcm_get_conversion_function(dd->frame_fmt,
dev->params.frame_fmt);

/* set up DMA configuration */
config->direction = DMA_DIR_DEV_TO_MEM;
config->cyclic = 1;
Expand All @@ -292,8 +305,8 @@ static int dai_capture_params(struct comp_dev *dev, uint32_t period_bytes,
config->src_width = 4;
config->dest_width = 4;
} else {
config->src_width = comp_sample_bytes(dev);
config->dest_width = comp_sample_bytes(dev);
config->src_width = sample_bytes(dd->frame_fmt);
config->dest_width = sample_bytes(dd->frame_fmt);
}

trace_dai_with_ids(dev, "dai_capture_params() "
Expand Down Expand Up @@ -328,8 +341,9 @@ static int dai_capture_params(struct comp_dev *dev, uint32_t period_bytes,

static int dai_params(struct comp_dev *dev)
{
struct dai_data *dd = comp_get_drvdata(dev);
struct sof_ipc_comp_config *dconfig = COMP_GET_CONFIG(dev);
struct dai_data *dd = comp_get_drvdata(dev);
uint32_t frame_size;
uint32_t period_count;
uint32_t period_bytes;
uint32_t buffer_size;
Expand All @@ -353,23 +367,6 @@ static int dai_params(struct comp_dev *dev)
return -EINVAL;
}

/* for DAI, we should configure its frame_fmt from topology */
dev->params.frame_fmt = dconfig->frame_fmt;

/* set processing function */
if (dev->params.frame_fmt == SOF_IPC_FRAME_S16_LE)
dd->process = buffer_copy_s16;
else
dd->process = buffer_copy_s32;

/* calculate period size based on config */
dd->frame_bytes = comp_frame_bytes(dev);
if (!dd->frame_bytes) {
trace_dai_error_with_ids(dev, "dai_params() error: "
"comp_frame_bytes() returned 0.");
return -EINVAL;
}

err = dma_get_attribute(dd->dma, DMA_ATTR_BUFFER_ADDRESS_ALIGNMENT,
&addr_align);
if (err < 0) {
Expand Down Expand Up @@ -397,7 +394,13 @@ static int dai_params(struct comp_dev *dev)
return -EINVAL;
}

period_bytes = dev->frames * dd->frame_bytes;
dd->frame_fmt = dconfig->frame_fmt;

/* calculate frame size */
frame_size = frame_bytes(dd->frame_fmt, dev->params.channels);

/* calculate period size */
period_bytes = dev->frames * frame_size;
if (!period_bytes) {
trace_dai_error_with_ids(dev, "dai_params() error: invalid "
"period_bytes.");
Expand Down Expand Up @@ -621,6 +624,8 @@ static int dai_copy(struct comp_dev *dev)
uint32_t avail_bytes = 0;
uint32_t free_bytes = 0;
uint32_t copy_bytes = 0;
uint32_t src_samples;
uint32_t sink_samples;
int ret = 0;

tracev_dai_with_ids(dev, "dai_copy()");
Expand All @@ -636,11 +641,17 @@ static int dai_copy(struct comp_dev *dev)
if (dev->params.direction == SOF_IPC_STREAM_PLAYBACK) {
local_buffer = list_first_item(&dev->bsource_list,
struct comp_buffer, sink_list);
copy_bytes = MIN(local_buffer->avail, free_bytes);
src_samples = local_buffer->avail / comp_sample_bytes(dev);
sink_samples = free_bytes / sample_bytes(dd->frame_fmt);
copy_bytes = MIN(src_samples, sink_samples) *
sample_bytes(dd->frame_fmt);
} else {
local_buffer = list_first_item(&dev->bsink_list,
struct comp_buffer, source_list);
copy_bytes = MIN(avail_bytes, local_buffer->free);
src_samples = avail_bytes / sample_bytes(dd->frame_fmt);
sink_samples = local_buffer->free / comp_sample_bytes(dev);
copy_bytes = MIN(src_samples, sink_samples) *
sample_bytes(dd->frame_fmt);
}

tracev_dai_with_ids(dev, "dai_copy(), copy_bytes = 0x%x", copy_bytes);
Expand Down Expand Up @@ -677,7 +688,6 @@ static int dai_config(struct comp_dev *dev, struct sof_ipc_dai_config *config)
struct dai_data *dd = comp_get_drvdata(dev);
struct sof_ipc_comp_dai *dai = (struct sof_ipc_comp_dai *)&dev->comp;
int channel = 0;
int i;
int handshake;

trace_dai_with_ids(dev, "config comp %d pipe %d dai %d type %d",
Expand All @@ -695,71 +705,21 @@ static int dai_config(struct comp_dev *dev, struct sof_ipc_dai_config *config)
case SOF_DAI_INTEL_SSP:
/* set dma burst elems to slot number */
dd->config.burst_elems = config->ssp.tdm_slots;

/* calc frame bytes */
switch (config->ssp.sample_valid_bits) {
case 16:
dd->frame_bytes = 2 * config->ssp.tdm_slots;
break;
case 17 ... 32:
dd->frame_bytes = 4 * config->ssp.tdm_slots;
break;
default:
break;
}
break;
case SOF_DAI_INTEL_DMIC:
/* The frame bytes setting follows only FIFO A setting in
* this DMIC driver version.
*/
trace_dai_with_ids(dev, "dai_config(), config->type = "
"SOF_DAI_INTEL_DMIC");

/* We can use always the largest burst length. */
dd->config.burst_elems = 8;

/* Set frame size in bytes to match the configuration. The
* actual width of FIFO appears in IPC always in fifo_bits_a
* for both FIFOs A and B.
*/
trace_dai_with_ids(dev, "dai_config(), "
"config->dmic.fifo_bits = %u; "
"config->dmic.num_pdm_active = %u;",
config->dmic.fifo_bits,
config->dmic.num_pdm_active);
dd->frame_bytes = 0;
for (i = 0; i < config->dmic.num_pdm_active; i++) {
trace_dai_with_ids(dev, "dai_config, "
"config->dmic.pdm[%u].enable_mic_a = %u; ",
config->dmic.pdm[i].id,
config->dmic.pdm[i].enable_mic_a);
trace_dai_with_ids(dev, "dai_config, "
"config->dmic.pdm[%u].enable_mic_b = %u; ",
config->dmic.pdm[i].id,
config->dmic.pdm[i].enable_mic_b);
dd->frame_bytes += (config->dmic.fifo_bits >> 3) *
(config->dmic.pdm[i].enable_mic_a +
config->dmic.pdm[i].enable_mic_b);
}

/* Packing of mono streams from several PDM controllers is not
* supported. In such cases the stream needs to be two
* channels.
*/
if (config->dmic.num_pdm_active > 1) {
dd->frame_bytes = 2 * config->dmic.num_pdm_active *
(config->dmic.fifo_bits >> 3);
}

trace_dai_with_ids(dev, "dai_config(), dd->frame_bytes = %u",
dd->frame_bytes);
break;
case SOF_DAI_INTEL_HDA:
/* set to some non-zero value to satisfy the condition below,
* it is recalculated in dai_params() later
* this is temp until dai/hda model is changed.
*/
dd->frame_bytes = 4;
channel = config->hda.link_dma_ch;
trace_dai_with_ids(dev, "dai_config(), channel = %d",
channel);
Expand All @@ -777,11 +737,6 @@ static int dai_config(struct comp_dev *dev, struct sof_ipc_dai_config *config)
}
break;
case SOF_DAI_INTEL_ALH:
/* set to some non-zero value to satisfy the condition below,
* it is recalculated in dai_params() later
*/
dd->frame_bytes = 4;

/* SDW HW FIFO always requires 32bit MSB aligned sample data for
* all formats, such as 8/16/24/32 bits.
*/
Expand All @@ -800,18 +755,6 @@ static int dai_config(struct comp_dev *dev, struct sof_ipc_dai_config *config)
dd->stream_id);
channel = EDMA_HS_GET_CHAN(handshake);

switch (dev->params.frame_fmt) {
case SOF_IPC_FRAME_S16_LE:
dd->frame_bytes = 2;
break;
case SOF_IPC_FRAME_S24_4LE:
case SOF_IPC_FRAME_S32_LE:
dd->frame_bytes = 4;
break;
default:
return -EINVAL;
}

dd->config.burst_elems =
dd->dai->plat_data.fifo[dai->direction].depth;
break;
Expand All @@ -820,26 +763,6 @@ static int dai_config(struct comp_dev *dev, struct sof_ipc_dai_config *config)
dd->stream_id);
channel = EDMA_HS_GET_CHAN(handshake);

switch (dev->params.frame_fmt) {
#if CONFIG_FORMAT_S16LE
case SOF_IPC_FRAME_S16_LE:
dd->frame_bytes = 2;
break;
#endif /* CONFIG_FORMAT_S16LE */
#if CONFIG_FORMAT_S24LE
case SOF_IPC_FRAME_S24_4LE:
dd->frame_bytes = 4;
break;
#endif /* CONFIG_FORMAT_S24LE */
#if CONFIG_FORMAT_S32LE
case SOF_IPC_FRAME_S32_LE:
dd->frame_bytes = 4;
break;
#endif /* CONFIG_FORMAT_S32LE */
default:
trace_dai_error_with_ids(dev, "dai_config() unsupported frame_fmt");
}

dd->config.burst_elems =
dd->dai->plat_data.fifo[dai->direction].depth;
break;
Expand All @@ -854,12 +777,6 @@ static int dai_config(struct comp_dev *dev, struct sof_ipc_dai_config *config)
break;
}

if (!dd->frame_bytes) {
trace_dai_error_with_ids(dev, "dai_config() error: "
"dd->frame_bytes == 0");
return -EINVAL;
}

if (channel != DMA_CHAN_INVALID) {
if (!dd->chan)
/* get dma channel at first config only */
Expand Down
26 changes: 4 additions & 22 deletions src/audio/eq_fir/eq_fir.c
Original file line number Diff line number Diff line change
Expand Up @@ -192,16 +192,7 @@ static void eq_fir_s16_passthrough(struct fir_state_32x16 fir[],
struct comp_buffer *sink,
int frames, int nch)
{
int16_t *x;
int16_t *y;
int i;
int n = frames * nch;

for (i = 0; i < n; i++) {
x = buffer_read_frag_s16(source, i);
y = buffer_write_frag_s16(sink, i);
*y = *x;
}
buffer_copy_s16(source, sink, frames * nch);
}
#endif /* CONFIG_FORMAT_S16LE */

Expand All @@ -211,16 +202,7 @@ static void eq_fir_s32_passthrough(struct fir_state_32x16 fir[],
struct comp_buffer *sink,
int frames, int nch)
{
int32_t *x;
int32_t *y;
int i;
int n = frames * nch;

for (i = 0; i < n; i++) {
x = buffer_read_frag_s32(source, i);
y = buffer_write_frag_s32(sink, i);
*y = *x;
}
buffer_copy_s32(source, sink, frames * nch);
}
#endif /* CONFIG_FORMAT_S24LE || CONFIG_FORMAT_S32LE */

Expand Down Expand Up @@ -784,10 +766,10 @@ static int eq_fir_prepare(struct comp_dev *dev)
struct comp_buffer, source_list);

/* get source data format */
cd->source_format = comp_frame_fmt(sourceb->source);
cd->source_format = sourceb->source->params.frame_fmt;

/* get sink data format and period bytes */
cd->sink_format = comp_frame_fmt(sinkb->sink);
cd->sink_format = sinkb->sink->params.frame_fmt;
sink_period_bytes = comp_period_bytes(sinkb->sink, dev->frames);

/* Rewrite params format for this component to match the host side. */
Expand Down
Loading