* [PATCH 1/5] ASoC: wm_adsp: Factor out stripping padding from ADSP data @ 2019-02-22 10:04 Charles Keepax 2019-02-22 10:04 ` [PATCH 2/5] ASoC: wm_adsp: Reorder some functions for improved clarity Charles Keepax ` (4 more replies) 0 siblings, 5 replies; 9+ messages in thread From: Charles Keepax @ 2019-02-22 10:04 UTC (permalink / raw) To: broonie; +Cc: stuarth, patches, alsa-devel, lgirdwood In preparation for more refactoring add a helper function to strip the padding from ADSP data. Signed-off-by: Charles Keepax <ckeepax@opensource.cirrus.com> --- sound/soc/codecs/wm_adsp.c | 27 +++++++++++++++++---------- 1 file changed, 17 insertions(+), 10 deletions(-) diff --git a/sound/soc/codecs/wm_adsp.c b/sound/soc/codecs/wm_adsp.c index 8d16a14cd2266..ae7e1f5d8d10a 100644 --- a/sound/soc/codecs/wm_adsp.c +++ b/sound/soc/codecs/wm_adsp.c @@ -3231,6 +3231,21 @@ static inline int wm_adsp_buffer_write(struct wm_adsp_compr_buf *buf, buf->host_buf_ptr + field_offset, data); } +static void wm_adsp_remove_padding(u32 *buf, int nwords, int data_word_size) +{ + u8 *pack_in = (u8 *)buf; + u8 *pack_out = (u8 *)buf; + int i, j; + + /* Remove the padding bytes from the data read from the DSP */ + for (i = 0; i < nwords; i++) { + for (j = 0; j < data_word_size; j++) + *pack_out++ = *pack_in++; + + pack_in += sizeof(*buf) - data_word_size; + } +} + static int wm_adsp_legacy_host_buf_addr(struct wm_adsp_compr_buf *buf) { struct wm_adsp_alg_region *alg_region; @@ -3670,11 +3685,9 @@ EXPORT_SYMBOL_GPL(wm_adsp_compr_pointer); static int wm_adsp_buffer_capture_block(struct wm_adsp_compr *compr, int target) { struct wm_adsp_compr_buf *buf = compr->buf; - u8 *pack_in = (u8 *)compr->raw_buf; - u8 *pack_out = (u8 *)compr->raw_buf; unsigned int adsp_addr; int mem_type, nwords, max_read; - int i, j, ret; + int i, ret; /* Calculate read parameters */ for (i = 0; i < wm_adsp_fw[buf->dsp->fw].caps->num_regions; ++i) @@ -3706,13 +3719,7 @@ static int wm_adsp_buffer_capture_block(struct wm_adsp_compr *compr, int target) if (ret < 0) return ret; - /* Remove the padding bytes from the data read from the DSP */ - for (i = 0; i < nwords; i++) { - for (j = 0; j < WM_ADSP_DATA_WORD_SIZE; j++) - *pack_out++ = *pack_in++; - - pack_in += sizeof(*(compr->raw_buf)) - WM_ADSP_DATA_WORD_SIZE; - } + wm_adsp_remove_padding(compr->raw_buf, nwords, WM_ADSP_DATA_WORD_SIZE); /* update read index to account for words read */ buf->read_index += nwords; -- 2.11.0 ^ permalink raw reply related [flat|nested] 9+ messages in thread
* [PATCH 2/5] ASoC: wm_adsp: Reorder some functions for improved clarity 2019-02-22 10:04 [PATCH 1/5] ASoC: wm_adsp: Factor out stripping padding from ADSP data Charles Keepax @ 2019-02-22 10:04 ` Charles Keepax 2019-02-26 12:06 ` Applied "ASoC: wm_adsp: Reorder some functions for improved clarity" to the asoc tree Mark Brown 2019-02-22 10:04 ` [PATCH 3/5] ASoC: wm_adsp: Refactor compress stream initialisation Charles Keepax ` (3 subsequent siblings) 4 siblings, 1 reply; 9+ messages in thread From: Charles Keepax @ 2019-02-22 10:04 UTC (permalink / raw) To: broonie; +Cc: stuarth, patches, alsa-devel, lgirdwood Signed-off-by: Charles Keepax <ckeepax@opensource.cirrus.com> --- sound/soc/codecs/wm_adsp.c | 81 +++++++++++++++++++++++----------------------- 1 file changed, 41 insertions(+), 40 deletions(-) diff --git a/sound/soc/codecs/wm_adsp.c b/sound/soc/codecs/wm_adsp.c index ae7e1f5d8d10a..d556ea7204167 100644 --- a/sound/soc/codecs/wm_adsp.c +++ b/sound/soc/codecs/wm_adsp.c @@ -3246,6 +3246,47 @@ static void wm_adsp_remove_padding(u32 *buf, int nwords, int data_word_size) } } +static int wm_adsp_buffer_populate(struct wm_adsp_compr_buf *buf) +{ + const struct wm_adsp_fw_caps *caps = wm_adsp_fw[buf->dsp->fw].caps; + struct wm_adsp_buffer_region *region; + u32 offset = 0; + int i, ret; + + for (i = 0; i < caps->num_regions; ++i) { + region = &buf->regions[i]; + + region->offset = offset; + region->mem_type = caps->region_defs[i].mem_type; + + ret = wm_adsp_buffer_read(buf, caps->region_defs[i].base_offset, + ®ion->base_addr); + if (ret < 0) + return ret; + + ret = wm_adsp_buffer_read(buf, caps->region_defs[i].size_offset, + &offset); + if (ret < 0) + return ret; + + region->cumulative_size = offset; + + adsp_dbg(buf->dsp, + "region=%d type=%d base=%08x off=%08x size=%08x\n", + i, region->mem_type, region->base_addr, + region->offset, region->cumulative_size); + } + + return 0; +} + +static void wm_adsp_buffer_clear(struct wm_adsp_compr_buf *buf) +{ + buf->irq_count = 0xFFFFFFFF; + buf->read_index = -1; + buf->avail = 0; +} + static int wm_adsp_legacy_host_buf_addr(struct wm_adsp_compr_buf *buf) { struct wm_adsp_alg_region *alg_region; @@ -3343,46 +3384,6 @@ static int wm_adsp_buffer_locate(struct wm_adsp_compr_buf *buf) return 0; } -static int wm_adsp_buffer_populate(struct wm_adsp_compr_buf *buf) -{ - const struct wm_adsp_fw_caps *caps = wm_adsp_fw[buf->dsp->fw].caps; - struct wm_adsp_buffer_region *region; - u32 offset = 0; - int i, ret; - - for (i = 0; i < caps->num_regions; ++i) { - region = &buf->regions[i]; - - region->offset = offset; - region->mem_type = caps->region_defs[i].mem_type; - - ret = wm_adsp_buffer_read(buf, caps->region_defs[i].base_offset, - ®ion->base_addr); - if (ret < 0) - return ret; - - ret = wm_adsp_buffer_read(buf, caps->region_defs[i].size_offset, - &offset); - if (ret < 0) - return ret; - - region->cumulative_size = offset; - - adsp_dbg(buf->dsp, - "region=%d type=%d base=%08x off=%08x size=%08x\n", - i, region->mem_type, region->base_addr, - region->offset, region->cumulative_size); - } - - return 0; -} - -static void wm_adsp_buffer_clear(struct wm_adsp_compr_buf *buf) -{ - buf->irq_count = 0xFFFFFFFF; - buf->read_index = -1; - buf->avail = 0; -} static int wm_adsp_buffer_init(struct wm_adsp *dsp) { -- 2.11.0 ^ permalink raw reply related [flat|nested] 9+ messages in thread
* Applied "ASoC: wm_adsp: Reorder some functions for improved clarity" to the asoc tree 2019-02-22 10:04 ` [PATCH 2/5] ASoC: wm_adsp: Reorder some functions for improved clarity Charles Keepax @ 2019-02-26 12:06 ` Mark Brown 0 siblings, 0 replies; 9+ messages in thread From: Mark Brown @ 2019-02-26 12:06 UTC (permalink / raw) To: Charles Keepax; +Cc: stuarth, patches, alsa-devel, broonie, lgirdwood The patch ASoC: wm_adsp: Reorder some functions for improved clarity has been applied to the asoc tree at https://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound.git All being well this means that it will be integrated into the linux-next tree (usually sometime in the next 24 hours) and sent to Linus during the next merge window (or sooner if it is a bug fix), however if problems are discovered then the patch may be dropped or reverted. You may get further e-mails resulting from automated or manual testing and review of the tree, please engage with people reporting problems and send followup patches addressing any issues that are reported if needed. If any updates are required or you are submitting further changes they should be sent as incremental updates against current git, existing patches will not be replaced. Please add any relevant lists and maintainers to the CCs when replying to this mail. Thanks, Mark >From 1e38f069c7d74109cfb5cff04e7fb7a24fea1ea6 Mon Sep 17 00:00:00 2001 From: Charles Keepax <ckeepax@opensource.cirrus.com> Date: Fri, 22 Feb 2019 10:04:18 +0000 Subject: [PATCH] ASoC: wm_adsp: Reorder some functions for improved clarity Signed-off-by: Charles Keepax <ckeepax@opensource.cirrus.com> Signed-off-by: Mark Brown <broonie@kernel.org> --- sound/soc/codecs/wm_adsp.c | 81 +++++++++++++++++++------------------- 1 file changed, 41 insertions(+), 40 deletions(-) diff --git a/sound/soc/codecs/wm_adsp.c b/sound/soc/codecs/wm_adsp.c index bd3241aacdb6..852ab3f70689 100644 --- a/sound/soc/codecs/wm_adsp.c +++ b/sound/soc/codecs/wm_adsp.c @@ -3246,6 +3246,47 @@ static void wm_adsp_remove_padding(u32 *buf, int nwords, int data_word_size) } } +static int wm_adsp_buffer_populate(struct wm_adsp_compr_buf *buf) +{ + const struct wm_adsp_fw_caps *caps = wm_adsp_fw[buf->dsp->fw].caps; + struct wm_adsp_buffer_region *region; + u32 offset = 0; + int i, ret; + + for (i = 0; i < caps->num_regions; ++i) { + region = &buf->regions[i]; + + region->offset = offset; + region->mem_type = caps->region_defs[i].mem_type; + + ret = wm_adsp_buffer_read(buf, caps->region_defs[i].base_offset, + ®ion->base_addr); + if (ret < 0) + return ret; + + ret = wm_adsp_buffer_read(buf, caps->region_defs[i].size_offset, + &offset); + if (ret < 0) + return ret; + + region->cumulative_size = offset; + + adsp_dbg(buf->dsp, + "region=%d type=%d base=%08x off=%08x size=%08x\n", + i, region->mem_type, region->base_addr, + region->offset, region->cumulative_size); + } + + return 0; +} + +static void wm_adsp_buffer_clear(struct wm_adsp_compr_buf *buf) +{ + buf->irq_count = 0xFFFFFFFF; + buf->read_index = -1; + buf->avail = 0; +} + static int wm_adsp_legacy_host_buf_addr(struct wm_adsp_compr_buf *buf) { struct wm_adsp_alg_region *alg_region; @@ -3343,46 +3384,6 @@ static int wm_adsp_buffer_locate(struct wm_adsp_compr_buf *buf) return 0; } -static int wm_adsp_buffer_populate(struct wm_adsp_compr_buf *buf) -{ - const struct wm_adsp_fw_caps *caps = wm_adsp_fw[buf->dsp->fw].caps; - struct wm_adsp_buffer_region *region; - u32 offset = 0; - int i, ret; - - for (i = 0; i < caps->num_regions; ++i) { - region = &buf->regions[i]; - - region->offset = offset; - region->mem_type = caps->region_defs[i].mem_type; - - ret = wm_adsp_buffer_read(buf, caps->region_defs[i].base_offset, - ®ion->base_addr); - if (ret < 0) - return ret; - - ret = wm_adsp_buffer_read(buf, caps->region_defs[i].size_offset, - &offset); - if (ret < 0) - return ret; - - region->cumulative_size = offset; - - adsp_dbg(buf->dsp, - "region=%d type=%d base=%08x off=%08x size=%08x\n", - i, region->mem_type, region->base_addr, - region->offset, region->cumulative_size); - } - - return 0; -} - -static void wm_adsp_buffer_clear(struct wm_adsp_compr_buf *buf) -{ - buf->irq_count = 0xFFFFFFFF; - buf->read_index = -1; - buf->avail = 0; -} static int wm_adsp_buffer_init(struct wm_adsp *dsp) { -- 2.20.1 ^ permalink raw reply related [flat|nested] 9+ messages in thread
* [PATCH 3/5] ASoC: wm_adsp: Refactor compress stream initialisation 2019-02-22 10:04 [PATCH 1/5] ASoC: wm_adsp: Factor out stripping padding from ADSP data Charles Keepax 2019-02-22 10:04 ` [PATCH 2/5] ASoC: wm_adsp: Reorder some functions for improved clarity Charles Keepax @ 2019-02-22 10:04 ` Charles Keepax 2019-02-26 12:06 ` Applied "ASoC: wm_adsp: Refactor compress stream initialisation" to the asoc tree Mark Brown 2019-02-22 10:04 ` [PATCH 4/5] ASoC: wm_adsp: Add support for multiple compressed buffers Charles Keepax ` (2 subsequent siblings) 4 siblings, 1 reply; 9+ messages in thread From: Charles Keepax @ 2019-02-22 10:04 UTC (permalink / raw) To: broonie; +Cc: stuarth, patches, alsa-devel, lgirdwood Make the code slightly clearer and prepare things for the addition of multiple compressed streams on a single DSP core. Signed-off-by: Charles Keepax <ckeepax@opensource.cirrus.com> --- sound/soc/codecs/wm_adsp.c | 139 ++++++++++++++++++++++++--------------------- 1 file changed, 74 insertions(+), 65 deletions(-) diff --git a/sound/soc/codecs/wm_adsp.c b/sound/soc/codecs/wm_adsp.c index d556ea7204167..d5b0d969dddf7 100644 --- a/sound/soc/codecs/wm_adsp.c +++ b/sound/soc/codecs/wm_adsp.c @@ -3253,6 +3253,11 @@ static int wm_adsp_buffer_populate(struct wm_adsp_compr_buf *buf) u32 offset = 0; int i, ret; + buf->regions = kcalloc(caps->num_regions, sizeof(*buf->regions), + GFP_KERNEL); + if (!buf->regions) + return -ENOMEM; + for (i = 0; i < caps->num_regions; ++i) { region = &buf->regions[i]; @@ -3287,13 +3292,34 @@ static void wm_adsp_buffer_clear(struct wm_adsp_compr_buf *buf) buf->avail = 0; } -static int wm_adsp_legacy_host_buf_addr(struct wm_adsp_compr_buf *buf) +static struct wm_adsp_compr_buf *wm_adsp_buffer_alloc(struct wm_adsp *dsp) +{ + struct wm_adsp_compr_buf *buf; + + buf = kzalloc(sizeof(*buf), GFP_KERNEL); + if (!buf) + return NULL; + + buf->dsp = dsp; + + wm_adsp_buffer_clear(buf); + + dsp->buffer = buf; + + return buf; +} + +static int wm_adsp_buffer_parse_legacy(struct wm_adsp *dsp) { struct wm_adsp_alg_region *alg_region; - struct wm_adsp *dsp = buf->dsp; + struct wm_adsp_compr_buf *buf; u32 xmalg, addr, magic; int i, ret; + buf = wm_adsp_buffer_alloc(dsp); + if (!buf) + return -ENOMEM; + alg_region = wm_adsp_find_alg_region(dsp, WMFW_ADSP2_XM, dsp->fw_id); xmalg = sizeof(struct wm_adsp_system_config_xm_hdr) / sizeof(__be32); @@ -3303,7 +3329,7 @@ static int wm_adsp_legacy_host_buf_addr(struct wm_adsp_compr_buf *buf) return ret; if (magic != WM_ADSP_ALG_XM_STRUCT_MAGIC) - return -EINVAL; + return -ENODEV; addr = alg_region->base + xmalg + ALG_XM_FIELD(host_buf_ptr); for (i = 0; i < 5; ++i) { @@ -3323,49 +3349,27 @@ static int wm_adsp_legacy_host_buf_addr(struct wm_adsp_compr_buf *buf) buf->host_buf_mem_type = WMFW_ADSP2_XM; - adsp_dbg(dsp, "host_buf_ptr=%x\n", buf->host_buf_ptr); - - return 0; -} - -static struct wm_coeff_ctl * -wm_adsp_find_host_buffer_ctrl(struct wm_adsp_compr_buf *buf) -{ - struct wm_adsp *dsp = buf->dsp; - struct wm_coeff_ctl *ctl; - - list_for_each_entry(ctl, &dsp->ctl_list, list) { - if (ctl->type != WMFW_CTL_TYPE_HOST_BUFFER) - continue; - - if (!ctl->enabled) - continue; + ret = wm_adsp_buffer_populate(buf); + if (ret < 0) + return ret; - buf->host_buf_mem_type = ctl->alg_region.type; - return ctl; - } + adsp_dbg(dsp, "legacy host_buf_ptr=%x\n", buf->host_buf_ptr); - return NULL; + return 0; } -static int wm_adsp_buffer_locate(struct wm_adsp_compr_buf *buf) +static int wm_adsp_buffer_parse_coeff(struct wm_coeff_ctl *ctl) { - struct wm_adsp *dsp = buf->dsp; - struct wm_coeff_ctl *ctl; - unsigned int reg; - u32 val; - int i, ret; - - ctl = wm_adsp_find_host_buffer_ctrl(buf); - if (!ctl) - return wm_adsp_legacy_host_buf_addr(buf); + struct wm_adsp_compr_buf *buf; + unsigned int val, reg; + int ret, i; ret = wm_coeff_base_reg(ctl, ®); if (ret) return ret; for (i = 0; i < 5; ++i) { - ret = regmap_raw_read(dsp->regmap, reg, &val, sizeof(val)); + ret = regmap_raw_read(ctl->dsp->regmap, reg, &val, sizeof(val)); if (ret < 0) return ret; @@ -3375,56 +3379,61 @@ static int wm_adsp_buffer_locate(struct wm_adsp_compr_buf *buf) usleep_range(1000, 2000); } - if (!val) + if (!val) { + adsp_err(ctl->dsp, "Failed to acquire host buffer\n"); return -EIO; + } + + buf = wm_adsp_buffer_alloc(ctl->dsp); + if (!buf) + return -ENOMEM; + buf->host_buf_mem_type = ctl->alg_region.type; buf->host_buf_ptr = be32_to_cpu(val); - adsp_dbg(dsp, "host_buf_ptr=%x\n", buf->host_buf_ptr); + + ret = wm_adsp_buffer_populate(buf); + if (ret < 0) + return ret; + + adsp_dbg(ctl->dsp, "host_buf_ptr=%x\n", buf->host_buf_ptr); return 0; } - static int wm_adsp_buffer_init(struct wm_adsp *dsp) { - struct wm_adsp_compr_buf *buf; + struct wm_coeff_ctl *ctl; int ret; - buf = kzalloc(sizeof(*buf), GFP_KERNEL); - if (!buf) - return -ENOMEM; - - buf->dsp = dsp; + list_for_each_entry(ctl, &dsp->ctl_list, list) { + if (ctl->type != WMFW_CTL_TYPE_HOST_BUFFER) + continue; - wm_adsp_buffer_clear(buf); + if (!ctl->enabled) + continue; - ret = wm_adsp_buffer_locate(buf); - if (ret < 0) { - adsp_err(dsp, "Failed to acquire host buffer: %d\n", ret); - goto err_buffer; - } + ret = wm_adsp_buffer_parse_coeff(ctl); + if (ret < 0) { + adsp_err(dsp, "Failed to parse coeff: %d\n", ret); + goto error; + } - buf->regions = kcalloc(wm_adsp_fw[dsp->fw].caps->num_regions, - sizeof(*buf->regions), GFP_KERNEL); - if (!buf->regions) { - ret = -ENOMEM; - goto err_buffer; + return 0; } - ret = wm_adsp_buffer_populate(buf); - if (ret < 0) { - adsp_err(dsp, "Failed to populate host buffer: %d\n", ret); - goto err_regions; + if (!dsp->buffer) { + /* Fall back to legacy support */ + ret = wm_adsp_buffer_parse_legacy(dsp); + if (ret) { + adsp_err(dsp, "Failed to parse legacy: %d\n", ret); + goto error; + } } - dsp->buffer = buf; - return 0; -err_regions: - kfree(buf->regions); -err_buffer: - kfree(buf); +error: + wm_adsp_buffer_free(dsp); return ret; } -- 2.11.0 ^ permalink raw reply related [flat|nested] 9+ messages in thread
* Applied "ASoC: wm_adsp: Refactor compress stream initialisation" to the asoc tree 2019-02-22 10:04 ` [PATCH 3/5] ASoC: wm_adsp: Refactor compress stream initialisation Charles Keepax @ 2019-02-26 12:06 ` Mark Brown 0 siblings, 0 replies; 9+ messages in thread From: Mark Brown @ 2019-02-26 12:06 UTC (permalink / raw) To: Charles Keepax; +Cc: stuarth, patches, alsa-devel, broonie, lgirdwood The patch ASoC: wm_adsp: Refactor compress stream initialisation has been applied to the asoc tree at https://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound.git All being well this means that it will be integrated into the linux-next tree (usually sometime in the next 24 hours) and sent to Linus during the next merge window (or sooner if it is a bug fix), however if problems are discovered then the patch may be dropped or reverted. You may get further e-mails resulting from automated or manual testing and review of the tree, please engage with people reporting problems and send followup patches addressing any issues that are reported if needed. If any updates are required or you are submitting further changes they should be sent as incremental updates against current git, existing patches will not be replaced. Please add any relevant lists and maintainers to the CCs when replying to this mail. Thanks, Mark >From a792af69b08fd7f89b156c8cba1dfc2088522582 Mon Sep 17 00:00:00 2001 From: Charles Keepax <ckeepax@opensource.cirrus.com> Date: Fri, 22 Feb 2019 10:04:19 +0000 Subject: [PATCH] ASoC: wm_adsp: Refactor compress stream initialisation Make the code slightly clearer and prepare things for the addition of multiple compressed streams on a single DSP core. Signed-off-by: Charles Keepax <ckeepax@opensource.cirrus.com> Signed-off-by: Mark Brown <broonie@kernel.org> --- sound/soc/codecs/wm_adsp.c | 139 ++++++++++++++++++++----------------- 1 file changed, 74 insertions(+), 65 deletions(-) diff --git a/sound/soc/codecs/wm_adsp.c b/sound/soc/codecs/wm_adsp.c index 852ab3f70689..4fdcef3f0ecc 100644 --- a/sound/soc/codecs/wm_adsp.c +++ b/sound/soc/codecs/wm_adsp.c @@ -3253,6 +3253,11 @@ static int wm_adsp_buffer_populate(struct wm_adsp_compr_buf *buf) u32 offset = 0; int i, ret; + buf->regions = kcalloc(caps->num_regions, sizeof(*buf->regions), + GFP_KERNEL); + if (!buf->regions) + return -ENOMEM; + for (i = 0; i < caps->num_regions; ++i) { region = &buf->regions[i]; @@ -3287,13 +3292,34 @@ static void wm_adsp_buffer_clear(struct wm_adsp_compr_buf *buf) buf->avail = 0; } -static int wm_adsp_legacy_host_buf_addr(struct wm_adsp_compr_buf *buf) +static struct wm_adsp_compr_buf *wm_adsp_buffer_alloc(struct wm_adsp *dsp) +{ + struct wm_adsp_compr_buf *buf; + + buf = kzalloc(sizeof(*buf), GFP_KERNEL); + if (!buf) + return NULL; + + buf->dsp = dsp; + + wm_adsp_buffer_clear(buf); + + dsp->buffer = buf; + + return buf; +} + +static int wm_adsp_buffer_parse_legacy(struct wm_adsp *dsp) { struct wm_adsp_alg_region *alg_region; - struct wm_adsp *dsp = buf->dsp; + struct wm_adsp_compr_buf *buf; u32 xmalg, addr, magic; int i, ret; + buf = wm_adsp_buffer_alloc(dsp); + if (!buf) + return -ENOMEM; + alg_region = wm_adsp_find_alg_region(dsp, WMFW_ADSP2_XM, dsp->fw_id); xmalg = sizeof(struct wm_adsp_system_config_xm_hdr) / sizeof(__be32); @@ -3303,7 +3329,7 @@ static int wm_adsp_legacy_host_buf_addr(struct wm_adsp_compr_buf *buf) return ret; if (magic != WM_ADSP_ALG_XM_STRUCT_MAGIC) - return -EINVAL; + return -ENODEV; addr = alg_region->base + xmalg + ALG_XM_FIELD(host_buf_ptr); for (i = 0; i < 5; ++i) { @@ -3323,49 +3349,27 @@ static int wm_adsp_legacy_host_buf_addr(struct wm_adsp_compr_buf *buf) buf->host_buf_mem_type = WMFW_ADSP2_XM; - adsp_dbg(dsp, "host_buf_ptr=%x\n", buf->host_buf_ptr); - - return 0; -} - -static struct wm_coeff_ctl * -wm_adsp_find_host_buffer_ctrl(struct wm_adsp_compr_buf *buf) -{ - struct wm_adsp *dsp = buf->dsp; - struct wm_coeff_ctl *ctl; - - list_for_each_entry(ctl, &dsp->ctl_list, list) { - if (ctl->type != WMFW_CTL_TYPE_HOST_BUFFER) - continue; - - if (!ctl->enabled) - continue; + ret = wm_adsp_buffer_populate(buf); + if (ret < 0) + return ret; - buf->host_buf_mem_type = ctl->alg_region.type; - return ctl; - } + adsp_dbg(dsp, "legacy host_buf_ptr=%x\n", buf->host_buf_ptr); - return NULL; + return 0; } -static int wm_adsp_buffer_locate(struct wm_adsp_compr_buf *buf) +static int wm_adsp_buffer_parse_coeff(struct wm_coeff_ctl *ctl) { - struct wm_adsp *dsp = buf->dsp; - struct wm_coeff_ctl *ctl; - unsigned int reg; - u32 val; - int i, ret; - - ctl = wm_adsp_find_host_buffer_ctrl(buf); - if (!ctl) - return wm_adsp_legacy_host_buf_addr(buf); + struct wm_adsp_compr_buf *buf; + unsigned int val, reg; + int ret, i; ret = wm_coeff_base_reg(ctl, ®); if (ret) return ret; for (i = 0; i < 5; ++i) { - ret = regmap_raw_read(dsp->regmap, reg, &val, sizeof(val)); + ret = regmap_raw_read(ctl->dsp->regmap, reg, &val, sizeof(val)); if (ret < 0) return ret; @@ -3375,56 +3379,61 @@ static int wm_adsp_buffer_locate(struct wm_adsp_compr_buf *buf) usleep_range(1000, 2000); } - if (!val) + if (!val) { + adsp_err(ctl->dsp, "Failed to acquire host buffer\n"); return -EIO; + } + + buf = wm_adsp_buffer_alloc(ctl->dsp); + if (!buf) + return -ENOMEM; + buf->host_buf_mem_type = ctl->alg_region.type; buf->host_buf_ptr = be32_to_cpu(val); - adsp_dbg(dsp, "host_buf_ptr=%x\n", buf->host_buf_ptr); + + ret = wm_adsp_buffer_populate(buf); + if (ret < 0) + return ret; + + adsp_dbg(ctl->dsp, "host_buf_ptr=%x\n", buf->host_buf_ptr); return 0; } - static int wm_adsp_buffer_init(struct wm_adsp *dsp) { - struct wm_adsp_compr_buf *buf; + struct wm_coeff_ctl *ctl; int ret; - buf = kzalloc(sizeof(*buf), GFP_KERNEL); - if (!buf) - return -ENOMEM; - - buf->dsp = dsp; + list_for_each_entry(ctl, &dsp->ctl_list, list) { + if (ctl->type != WMFW_CTL_TYPE_HOST_BUFFER) + continue; - wm_adsp_buffer_clear(buf); + if (!ctl->enabled) + continue; - ret = wm_adsp_buffer_locate(buf); - if (ret < 0) { - adsp_err(dsp, "Failed to acquire host buffer: %d\n", ret); - goto err_buffer; - } + ret = wm_adsp_buffer_parse_coeff(ctl); + if (ret < 0) { + adsp_err(dsp, "Failed to parse coeff: %d\n", ret); + goto error; + } - buf->regions = kcalloc(wm_adsp_fw[dsp->fw].caps->num_regions, - sizeof(*buf->regions), GFP_KERNEL); - if (!buf->regions) { - ret = -ENOMEM; - goto err_buffer; + return 0; } - ret = wm_adsp_buffer_populate(buf); - if (ret < 0) { - adsp_err(dsp, "Failed to populate host buffer: %d\n", ret); - goto err_regions; + if (!dsp->buffer) { + /* Fall back to legacy support */ + ret = wm_adsp_buffer_parse_legacy(dsp); + if (ret) { + adsp_err(dsp, "Failed to parse legacy: %d\n", ret); + goto error; + } } - dsp->buffer = buf; - return 0; -err_regions: - kfree(buf->regions); -err_buffer: - kfree(buf); +error: + wm_adsp_buffer_free(dsp); return ret; } -- 2.20.1 ^ permalink raw reply related [flat|nested] 9+ messages in thread
* [PATCH 4/5] ASoC: wm_adsp: Add support for multiple compressed buffers 2019-02-22 10:04 [PATCH 1/5] ASoC: wm_adsp: Factor out stripping padding from ADSP data Charles Keepax 2019-02-22 10:04 ` [PATCH 2/5] ASoC: wm_adsp: Reorder some functions for improved clarity Charles Keepax 2019-02-22 10:04 ` [PATCH 3/5] ASoC: wm_adsp: Refactor compress stream initialisation Charles Keepax @ 2019-02-22 10:04 ` Charles Keepax 2019-02-26 12:06 ` Applied "ASoC: wm_adsp: Add support for multiple compressed buffers" to the asoc tree Mark Brown 2019-02-22 10:04 ` [PATCH 5/5] ASoC: wm_adsp: Improve logging messages Charles Keepax 2019-02-26 12:06 ` Applied "ASoC: wm_adsp: Factor out stripping padding from ADSP data" to the asoc tree Mark Brown 4 siblings, 1 reply; 9+ messages in thread From: Charles Keepax @ 2019-02-22 10:04 UTC (permalink / raw) To: broonie; +Cc: stuarth, patches, alsa-devel, lgirdwood From: Stuart Henderson <stuarth@opensource.cirrus.com> Currently, only a single compressed stream is supported per firmware. Add support for multiple compressed streams on a single firmware, this allows additional features like completely independent trigger words or separate debug capture streams to be implemented. Signed-off-by: Stuart Henderson <stuarth@opensource.cirrus.com> Signed-off-by: Charles Keepax <ckeepax@opensource.cirrus.com> --- sound/soc/codecs/wm_adsp.c | 166 ++++++++++++++++++++++++++++++++------------- sound/soc/codecs/wm_adsp.h | 4 +- 2 files changed, 119 insertions(+), 51 deletions(-) diff --git a/sound/soc/codecs/wm_adsp.c b/sound/soc/codecs/wm_adsp.c index d5b0d969dddf7..5edaed3320407 100644 --- a/sound/soc/codecs/wm_adsp.c +++ b/sound/soc/codecs/wm_adsp.c @@ -310,6 +310,12 @@ struct wm_adsp_alg_xm_struct { __be64 smoothed_power; }; +struct wm_adsp_host_buf_coeff_v1 { + __be32 host_buf_ptr; /* Host buffer pointer */ + __be32 versions; /* Version numbers */ + __be32 name[4]; /* The buffer name */ +}; + struct wm_adsp_buffer { __be32 buf1_base; /* Base addr of first buffer area */ __be32 buf1_size; /* Size of buf1 area in DSP words */ @@ -334,6 +340,7 @@ struct wm_adsp_buffer { struct wm_adsp_compr; struct wm_adsp_compr_buf { + struct list_head list; struct wm_adsp *dsp; struct wm_adsp_compr *compr; @@ -345,9 +352,12 @@ struct wm_adsp_compr_buf { int read_index; int avail; int host_buf_mem_type; + + char *name; }; struct wm_adsp_compr { + struct list_head list; struct wm_adsp *dsp; struct wm_adsp_compr_buf *buf; @@ -358,6 +368,8 @@ struct wm_adsp_compr { unsigned int copied_total; unsigned int sample_rate; + + const char *name; }; #define WM_ADSP_DATA_WORD_SIZE 3 @@ -375,6 +387,11 @@ struct wm_adsp_compr { #define ALG_XM_FIELD(field) \ (offsetof(struct wm_adsp_alg_xm_struct, field) / sizeof(__be32)) +#define HOST_BUF_COEFF_SUPPORTED_COMPAT_VER 1 + +#define HOST_BUF_COEFF_COMPAT_VER_MASK 0xFF00 +#define HOST_BUF_COEFF_COMPAT_VER_SHIFT 8 + static int wm_adsp_buffer_init(struct wm_adsp *dsp); static int wm_adsp_buffer_free(struct wm_adsp *dsp); @@ -708,7 +725,7 @@ int wm_adsp_fw_put(struct snd_kcontrol *kcontrol, mutex_lock(&dsp[e->shift_l].pwr_lock); - if (dsp[e->shift_l].booted || dsp[e->shift_l].compr) + if (dsp[e->shift_l].booted || !list_empty(&dsp[e->shift_l].compr_list)) ret = -EBUSY; else dsp[e->shift_l].fw = ucontrol->value.enumerated.item[0]; @@ -2430,6 +2447,8 @@ static int wm_adsp_common_init(struct wm_adsp *dsp) INIT_LIST_HEAD(&dsp->alg_regions); INIT_LIST_HEAD(&dsp->ctl_list); + INIT_LIST_HEAD(&dsp->compr_list); + INIT_LIST_HEAD(&dsp->buffer_list); mutex_init(&dsp->pwr_lock); @@ -2972,14 +2991,19 @@ static inline int wm_adsp_compr_attached(struct wm_adsp_compr *compr) static int wm_adsp_compr_attach(struct wm_adsp_compr *compr) { - /* - * Note this will be more complex once each DSP can support multiple - * streams - */ - if (!compr->dsp->buffer) + struct wm_adsp_compr_buf *buf = NULL, *tmp; + + list_for_each_entry(tmp, &compr->dsp->buffer_list, list) { + if (!tmp->name || !strcmp(compr->name, tmp->name)) { + buf = tmp; + break; + } + } + + if (!buf) return -EINVAL; - compr->buf = compr->dsp->buffer; + compr->buf = buf; compr->buf->compr = compr; return 0; @@ -3002,7 +3026,8 @@ static void wm_adsp_compr_detach(struct wm_adsp_compr *compr) int wm_adsp_compr_open(struct wm_adsp *dsp, struct snd_compr_stream *stream) { - struct wm_adsp_compr *compr; + struct wm_adsp_compr *compr, *tmp; + struct snd_soc_pcm_runtime *rtd = stream->private_data; int ret = 0; mutex_lock(&dsp->pwr_lock); @@ -3019,11 +3044,12 @@ int wm_adsp_compr_open(struct wm_adsp *dsp, struct snd_compr_stream *stream) goto out; } - if (dsp->compr) { - /* It is expect this limitation will be removed in future */ - adsp_err(dsp, "Only a single stream supported per DSP\n"); - ret = -EBUSY; - goto out; + list_for_each_entry(tmp, &dsp->compr_list, list) { + if (!strcmp(tmp->name, rtd->codec_dai->name)) { + adsp_err(dsp, "Only a single stream supported per dai\n"); + ret = -EBUSY; + goto out; + } } compr = kzalloc(sizeof(*compr), GFP_KERNEL); @@ -3034,8 +3060,9 @@ int wm_adsp_compr_open(struct wm_adsp *dsp, struct snd_compr_stream *stream) compr->dsp = dsp; compr->stream = stream; + compr->name = rtd->codec_dai->name; - dsp->compr = compr; + list_add_tail(&compr->list, &dsp->compr_list); stream->runtime->private_data = compr; @@ -3054,7 +3081,7 @@ int wm_adsp_compr_free(struct snd_compr_stream *stream) mutex_lock(&dsp->pwr_lock); wm_adsp_compr_detach(compr); - dsp->compr = NULL; + list_del(&compr->list); kfree(compr->raw_buf); kfree(compr); @@ -3304,7 +3331,7 @@ static struct wm_adsp_compr_buf *wm_adsp_buffer_alloc(struct wm_adsp *dsp) wm_adsp_buffer_clear(buf); - dsp->buffer = buf; + list_add_tail(&buf->list, &dsp->buffer_list); return buf; } @@ -3360,6 +3387,7 @@ static int wm_adsp_buffer_parse_legacy(struct wm_adsp *dsp) static int wm_adsp_buffer_parse_coeff(struct wm_coeff_ctl *ctl) { + struct wm_adsp_host_buf_coeff_v1 coeff_v1; struct wm_adsp_compr_buf *buf; unsigned int val, reg; int ret, i; @@ -3395,9 +3423,45 @@ static int wm_adsp_buffer_parse_coeff(struct wm_coeff_ctl *ctl) if (ret < 0) return ret; - adsp_dbg(ctl->dsp, "host_buf_ptr=%x\n", buf->host_buf_ptr); + /* + * v0 host_buffer coefficients didn't have versioning, so if the + * control is one word, assume version 0. + */ + if (ctl->len == 4) { + adsp_dbg(ctl->dsp, "host_buf_ptr=%x\n", buf->host_buf_ptr); + return 0; + } + + ret = regmap_raw_read(ctl->dsp->regmap, reg, &coeff_v1, + sizeof(coeff_v1)); + if (ret < 0) + return ret; + + coeff_v1.versions = be32_to_cpu(coeff_v1.versions); + val = coeff_v1.versions & HOST_BUF_COEFF_COMPAT_VER_MASK; + val >>= HOST_BUF_COEFF_COMPAT_VER_SHIFT; - return 0; + if (val > HOST_BUF_COEFF_SUPPORTED_COMPAT_VER) { + adsp_err(ctl->dsp, + "Host buffer coeff ver %u > supported version %u\n", + val, HOST_BUF_COEFF_SUPPORTED_COMPAT_VER); + return -EINVAL; + } + + for (i = 0; i < ARRAY_SIZE(coeff_v1.name); i++) + coeff_v1.name[i] = be32_to_cpu(coeff_v1.name[i]); + + wm_adsp_remove_padding((u32 *)&coeff_v1.name, + ARRAY_SIZE(coeff_v1.name), + WM_ADSP_DATA_WORD_SIZE); + + buf->name = kasprintf(GFP_KERNEL, "%s-dsp-%s", ctl->dsp->part, + (char *)&coeff_v1.name); + + adsp_dbg(ctl->dsp, "host_buf_ptr=%x coeff version %u\n", + buf->host_buf_ptr, val); + + return val; } static int wm_adsp_buffer_init(struct wm_adsp *dsp) @@ -3416,12 +3480,13 @@ static int wm_adsp_buffer_init(struct wm_adsp *dsp) if (ret < 0) { adsp_err(dsp, "Failed to parse coeff: %d\n", ret); goto error; + } else if (ret == 0) { + /* Only one buffer supported for version 0 */ + return 0; } - - return 0; } - if (!dsp->buffer) { + if (list_empty(&dsp->buffer_list)) { /* Fall back to legacy support */ ret = wm_adsp_buffer_parse_legacy(dsp); if (ret) { @@ -3439,13 +3504,16 @@ static int wm_adsp_buffer_init(struct wm_adsp *dsp) static int wm_adsp_buffer_free(struct wm_adsp *dsp) { - if (dsp->buffer) { - wm_adsp_compr_detach(dsp->buffer->compr); + struct wm_adsp_compr_buf *buf, *tmp; - kfree(dsp->buffer->regions); - kfree(dsp->buffer); + list_for_each_entry_safe(buf, tmp, &dsp->buffer_list, list) { + if (buf->compr) + wm_adsp_compr_detach(buf->compr); - dsp->buffer = NULL; + kfree(buf->name); + kfree(buf->regions); + list_del(&buf->list); + kfree(buf); } return 0; @@ -3576,39 +3644,39 @@ int wm_adsp_compr_handle_irq(struct wm_adsp *dsp) mutex_lock(&dsp->pwr_lock); - buf = dsp->buffer; - compr = dsp->compr; - - if (!buf) { + if (list_empty(&dsp->buffer_list)) { ret = -ENODEV; goto out; } - adsp_dbg(dsp, "Handling buffer IRQ\n"); - ret = wm_adsp_buffer_get_error(buf); - if (ret < 0) - goto out_notify; /* Wake poll to report error */ + list_for_each_entry(buf, &dsp->buffer_list, list) { + compr = buf->compr; - ret = wm_adsp_buffer_read(buf, HOST_BUFFER_FIELD(irq_count), - &buf->irq_count); - if (ret < 0) { - adsp_err(dsp, "Failed to get irq_count: %d\n", ret); - goto out; - } + ret = wm_adsp_buffer_get_error(buf); + if (ret < 0) + goto out_notify; /* Wake poll to report error */ - ret = wm_adsp_buffer_update_avail(buf); - if (ret < 0) { - adsp_err(dsp, "Error reading avail: %d\n", ret); - goto out; - } + ret = wm_adsp_buffer_read(buf, HOST_BUFFER_FIELD(irq_count), + &buf->irq_count); + if (ret < 0) { + adsp_err(dsp, "Failed to get irq_count: %d\n", ret); + goto out; + } - if (wm_adsp_fw[dsp->fw].voice_trigger && buf->irq_count == 2) - ret = WM_ADSP_COMPR_VOICE_TRIGGER; + ret = wm_adsp_buffer_update_avail(buf); + if (ret < 0) { + adsp_err(dsp, "Error reading avail: %d\n", ret); + goto out; + } + + if (wm_adsp_fw[dsp->fw].voice_trigger && buf->irq_count == 2) + ret = WM_ADSP_COMPR_VOICE_TRIGGER; out_notify: - if (compr && compr->stream) - snd_compr_fragment_elapsed(compr->stream); + if (compr && compr->stream) + snd_compr_fragment_elapsed(compr->stream); + } out: mutex_unlock(&dsp->pwr_lock); diff --git a/sound/soc/codecs/wm_adsp.h b/sound/soc/codecs/wm_adsp.h index 4b8778b0b06cd..59e07ad163296 100644 --- a/sound/soc/codecs/wm_adsp.h +++ b/sound/soc/codecs/wm_adsp.h @@ -90,8 +90,8 @@ struct wm_adsp { struct work_struct boot_work; - struct wm_adsp_compr *compr; - struct wm_adsp_compr_buf *buffer; + struct list_head compr_list; + struct list_head buffer_list; struct mutex pwr_lock; -- 2.11.0 ^ permalink raw reply related [flat|nested] 9+ messages in thread
* Applied "ASoC: wm_adsp: Add support for multiple compressed buffers" to the asoc tree 2019-02-22 10:04 ` [PATCH 4/5] ASoC: wm_adsp: Add support for multiple compressed buffers Charles Keepax @ 2019-02-26 12:06 ` Mark Brown 0 siblings, 0 replies; 9+ messages in thread From: Mark Brown @ 2019-02-26 12:06 UTC (permalink / raw) Cc: alsa-devel, Charles Keepax, patches, lgirdwood, stuarth, broonie The patch ASoC: wm_adsp: Add support for multiple compressed buffers has been applied to the asoc tree at https://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound.git All being well this means that it will be integrated into the linux-next tree (usually sometime in the next 24 hours) and sent to Linus during the next merge window (or sooner if it is a bug fix), however if problems are discovered then the patch may be dropped or reverted. You may get further e-mails resulting from automated or manual testing and review of the tree, please engage with people reporting problems and send followup patches addressing any issues that are reported if needed. If any updates are required or you are submitting further changes they should be sent as incremental updates against current git, existing patches will not be replaced. Please add any relevant lists and maintainers to the CCs when replying to this mail. Thanks, Mark >From 4f2d4eabf57718875b97363a3bd35de490f354c5 Mon Sep 17 00:00:00 2001 From: Stuart Henderson <stuarth@opensource.cirrus.com> Date: Fri, 22 Feb 2019 10:04:20 +0000 Subject: [PATCH] ASoC: wm_adsp: Add support for multiple compressed buffers Currently, only a single compressed stream is supported per firmware. Add support for multiple compressed streams on a single firmware, this allows additional features like completely independent trigger words or separate debug capture streams to be implemented. Signed-off-by: Stuart Henderson <stuarth@opensource.cirrus.com> Signed-off-by: Charles Keepax <ckeepax@opensource.cirrus.com> Signed-off-by: Mark Brown <broonie@kernel.org> --- sound/soc/codecs/wm_adsp.c | 166 ++++++++++++++++++++++++++----------- sound/soc/codecs/wm_adsp.h | 4 +- 2 files changed, 119 insertions(+), 51 deletions(-) diff --git a/sound/soc/codecs/wm_adsp.c b/sound/soc/codecs/wm_adsp.c index 4fdcef3f0ecc..fe802fc331c5 100644 --- a/sound/soc/codecs/wm_adsp.c +++ b/sound/soc/codecs/wm_adsp.c @@ -310,6 +310,12 @@ struct wm_adsp_alg_xm_struct { __be64 smoothed_power; }; +struct wm_adsp_host_buf_coeff_v1 { + __be32 host_buf_ptr; /* Host buffer pointer */ + __be32 versions; /* Version numbers */ + __be32 name[4]; /* The buffer name */ +}; + struct wm_adsp_buffer { __be32 buf1_base; /* Base addr of first buffer area */ __be32 buf1_size; /* Size of buf1 area in DSP words */ @@ -334,6 +340,7 @@ struct wm_adsp_buffer { struct wm_adsp_compr; struct wm_adsp_compr_buf { + struct list_head list; struct wm_adsp *dsp; struct wm_adsp_compr *compr; @@ -345,9 +352,12 @@ struct wm_adsp_compr_buf { int read_index; int avail; int host_buf_mem_type; + + char *name; }; struct wm_adsp_compr { + struct list_head list; struct wm_adsp *dsp; struct wm_adsp_compr_buf *buf; @@ -358,6 +368,8 @@ struct wm_adsp_compr { unsigned int copied_total; unsigned int sample_rate; + + const char *name; }; #define WM_ADSP_DATA_WORD_SIZE 3 @@ -375,6 +387,11 @@ struct wm_adsp_compr { #define ALG_XM_FIELD(field) \ (offsetof(struct wm_adsp_alg_xm_struct, field) / sizeof(__be32)) +#define HOST_BUF_COEFF_SUPPORTED_COMPAT_VER 1 + +#define HOST_BUF_COEFF_COMPAT_VER_MASK 0xFF00 +#define HOST_BUF_COEFF_COMPAT_VER_SHIFT 8 + static int wm_adsp_buffer_init(struct wm_adsp *dsp); static int wm_adsp_buffer_free(struct wm_adsp *dsp); @@ -708,7 +725,7 @@ int wm_adsp_fw_put(struct snd_kcontrol *kcontrol, mutex_lock(&dsp[e->shift_l].pwr_lock); - if (dsp[e->shift_l].booted || dsp[e->shift_l].compr) + if (dsp[e->shift_l].booted || !list_empty(&dsp[e->shift_l].compr_list)) ret = -EBUSY; else dsp[e->shift_l].fw = ucontrol->value.enumerated.item[0]; @@ -2430,6 +2447,8 @@ static int wm_adsp_common_init(struct wm_adsp *dsp) INIT_LIST_HEAD(&dsp->alg_regions); INIT_LIST_HEAD(&dsp->ctl_list); + INIT_LIST_HEAD(&dsp->compr_list); + INIT_LIST_HEAD(&dsp->buffer_list); mutex_init(&dsp->pwr_lock); @@ -2972,14 +2991,19 @@ static inline int wm_adsp_compr_attached(struct wm_adsp_compr *compr) static int wm_adsp_compr_attach(struct wm_adsp_compr *compr) { - /* - * Note this will be more complex once each DSP can support multiple - * streams - */ - if (!compr->dsp->buffer) + struct wm_adsp_compr_buf *buf = NULL, *tmp; + + list_for_each_entry(tmp, &compr->dsp->buffer_list, list) { + if (!tmp->name || !strcmp(compr->name, tmp->name)) { + buf = tmp; + break; + } + } + + if (!buf) return -EINVAL; - compr->buf = compr->dsp->buffer; + compr->buf = buf; compr->buf->compr = compr; return 0; @@ -3002,7 +3026,8 @@ static void wm_adsp_compr_detach(struct wm_adsp_compr *compr) int wm_adsp_compr_open(struct wm_adsp *dsp, struct snd_compr_stream *stream) { - struct wm_adsp_compr *compr; + struct wm_adsp_compr *compr, *tmp; + struct snd_soc_pcm_runtime *rtd = stream->private_data; int ret = 0; mutex_lock(&dsp->pwr_lock); @@ -3019,11 +3044,12 @@ int wm_adsp_compr_open(struct wm_adsp *dsp, struct snd_compr_stream *stream) goto out; } - if (dsp->compr) { - /* It is expect this limitation will be removed in future */ - adsp_err(dsp, "Only a single stream supported per DSP\n"); - ret = -EBUSY; - goto out; + list_for_each_entry(tmp, &dsp->compr_list, list) { + if (!strcmp(tmp->name, rtd->codec_dai->name)) { + adsp_err(dsp, "Only a single stream supported per dai\n"); + ret = -EBUSY; + goto out; + } } compr = kzalloc(sizeof(*compr), GFP_KERNEL); @@ -3034,8 +3060,9 @@ int wm_adsp_compr_open(struct wm_adsp *dsp, struct snd_compr_stream *stream) compr->dsp = dsp; compr->stream = stream; + compr->name = rtd->codec_dai->name; - dsp->compr = compr; + list_add_tail(&compr->list, &dsp->compr_list); stream->runtime->private_data = compr; @@ -3054,7 +3081,7 @@ int wm_adsp_compr_free(struct snd_compr_stream *stream) mutex_lock(&dsp->pwr_lock); wm_adsp_compr_detach(compr); - dsp->compr = NULL; + list_del(&compr->list); kfree(compr->raw_buf); kfree(compr); @@ -3304,7 +3331,7 @@ static struct wm_adsp_compr_buf *wm_adsp_buffer_alloc(struct wm_adsp *dsp) wm_adsp_buffer_clear(buf); - dsp->buffer = buf; + list_add_tail(&buf->list, &dsp->buffer_list); return buf; } @@ -3360,6 +3387,7 @@ static int wm_adsp_buffer_parse_legacy(struct wm_adsp *dsp) static int wm_adsp_buffer_parse_coeff(struct wm_coeff_ctl *ctl) { + struct wm_adsp_host_buf_coeff_v1 coeff_v1; struct wm_adsp_compr_buf *buf; unsigned int val, reg; int ret, i; @@ -3395,9 +3423,45 @@ static int wm_adsp_buffer_parse_coeff(struct wm_coeff_ctl *ctl) if (ret < 0) return ret; - adsp_dbg(ctl->dsp, "host_buf_ptr=%x\n", buf->host_buf_ptr); + /* + * v0 host_buffer coefficients didn't have versioning, so if the + * control is one word, assume version 0. + */ + if (ctl->len == 4) { + adsp_dbg(ctl->dsp, "host_buf_ptr=%x\n", buf->host_buf_ptr); + return 0; + } + + ret = regmap_raw_read(ctl->dsp->regmap, reg, &coeff_v1, + sizeof(coeff_v1)); + if (ret < 0) + return ret; + + coeff_v1.versions = be32_to_cpu(coeff_v1.versions); + val = coeff_v1.versions & HOST_BUF_COEFF_COMPAT_VER_MASK; + val >>= HOST_BUF_COEFF_COMPAT_VER_SHIFT; - return 0; + if (val > HOST_BUF_COEFF_SUPPORTED_COMPAT_VER) { + adsp_err(ctl->dsp, + "Host buffer coeff ver %u > supported version %u\n", + val, HOST_BUF_COEFF_SUPPORTED_COMPAT_VER); + return -EINVAL; + } + + for (i = 0; i < ARRAY_SIZE(coeff_v1.name); i++) + coeff_v1.name[i] = be32_to_cpu(coeff_v1.name[i]); + + wm_adsp_remove_padding((u32 *)&coeff_v1.name, + ARRAY_SIZE(coeff_v1.name), + WM_ADSP_DATA_WORD_SIZE); + + buf->name = kasprintf(GFP_KERNEL, "%s-dsp-%s", ctl->dsp->part, + (char *)&coeff_v1.name); + + adsp_dbg(ctl->dsp, "host_buf_ptr=%x coeff version %u\n", + buf->host_buf_ptr, val); + + return val; } static int wm_adsp_buffer_init(struct wm_adsp *dsp) @@ -3416,12 +3480,13 @@ static int wm_adsp_buffer_init(struct wm_adsp *dsp) if (ret < 0) { adsp_err(dsp, "Failed to parse coeff: %d\n", ret); goto error; + } else if (ret == 0) { + /* Only one buffer supported for version 0 */ + return 0; } - - return 0; } - if (!dsp->buffer) { + if (list_empty(&dsp->buffer_list)) { /* Fall back to legacy support */ ret = wm_adsp_buffer_parse_legacy(dsp); if (ret) { @@ -3439,13 +3504,16 @@ static int wm_adsp_buffer_init(struct wm_adsp *dsp) static int wm_adsp_buffer_free(struct wm_adsp *dsp) { - if (dsp->buffer) { - wm_adsp_compr_detach(dsp->buffer->compr); + struct wm_adsp_compr_buf *buf, *tmp; - kfree(dsp->buffer->regions); - kfree(dsp->buffer); + list_for_each_entry_safe(buf, tmp, &dsp->buffer_list, list) { + if (buf->compr) + wm_adsp_compr_detach(buf->compr); - dsp->buffer = NULL; + kfree(buf->name); + kfree(buf->regions); + list_del(&buf->list); + kfree(buf); } return 0; @@ -3572,39 +3640,39 @@ int wm_adsp_compr_handle_irq(struct wm_adsp *dsp) mutex_lock(&dsp->pwr_lock); - buf = dsp->buffer; - compr = dsp->compr; - - if (!buf) { + if (list_empty(&dsp->buffer_list)) { ret = -ENODEV; goto out; } - adsp_dbg(dsp, "Handling buffer IRQ\n"); - ret = wm_adsp_buffer_get_error(buf); - if (ret < 0) - goto out_notify; /* Wake poll to report error */ + list_for_each_entry(buf, &dsp->buffer_list, list) { + compr = buf->compr; - ret = wm_adsp_buffer_read(buf, HOST_BUFFER_FIELD(irq_count), - &buf->irq_count); - if (ret < 0) { - adsp_err(dsp, "Failed to get irq_count: %d\n", ret); - goto out; - } + ret = wm_adsp_buffer_get_error(buf); + if (ret < 0) + goto out_notify; /* Wake poll to report error */ - ret = wm_adsp_buffer_update_avail(buf); - if (ret < 0) { - adsp_err(dsp, "Error reading avail: %d\n", ret); - goto out; - } + ret = wm_adsp_buffer_read(buf, HOST_BUFFER_FIELD(irq_count), + &buf->irq_count); + if (ret < 0) { + adsp_err(dsp, "Failed to get irq_count: %d\n", ret); + goto out; + } - if (wm_adsp_fw[dsp->fw].voice_trigger && buf->irq_count == 2) - ret = WM_ADSP_COMPR_VOICE_TRIGGER; + ret = wm_adsp_buffer_update_avail(buf); + if (ret < 0) { + adsp_err(dsp, "Error reading avail: %d\n", ret); + goto out; + } + + if (wm_adsp_fw[dsp->fw].voice_trigger && buf->irq_count == 2) + ret = WM_ADSP_COMPR_VOICE_TRIGGER; out_notify: - if (compr && compr->stream) - snd_compr_fragment_elapsed(compr->stream); + if (compr && compr->stream) + snd_compr_fragment_elapsed(compr->stream); + } out: mutex_unlock(&dsp->pwr_lock); diff --git a/sound/soc/codecs/wm_adsp.h b/sound/soc/codecs/wm_adsp.h index 4b8778b0b06c..59e07ad16329 100644 --- a/sound/soc/codecs/wm_adsp.h +++ b/sound/soc/codecs/wm_adsp.h @@ -90,8 +90,8 @@ struct wm_adsp { struct work_struct boot_work; - struct wm_adsp_compr *compr; - struct wm_adsp_compr_buf *buffer; + struct list_head compr_list; + struct list_head buffer_list; struct mutex pwr_lock; -- 2.20.1 ^ permalink raw reply related [flat|nested] 9+ messages in thread
* [PATCH 5/5] ASoC: wm_adsp: Improve logging messages 2019-02-22 10:04 [PATCH 1/5] ASoC: wm_adsp: Factor out stripping padding from ADSP data Charles Keepax ` (2 preceding siblings ...) 2019-02-22 10:04 ` [PATCH 4/5] ASoC: wm_adsp: Add support for multiple compressed buffers Charles Keepax @ 2019-02-22 10:04 ` Charles Keepax 2019-02-26 12:06 ` Applied "ASoC: wm_adsp: Factor out stripping padding from ADSP data" to the asoc tree Mark Brown 4 siblings, 0 replies; 9+ messages in thread From: Charles Keepax @ 2019-02-22 10:04 UTC (permalink / raw) To: broonie; +Cc: stuarth, patches, alsa-devel, lgirdwood As the compressed stream implementation has acquired support for multiple DAI links and compressed streams it has become harder to interpret messages in the kernel log. Add additional macros to include the compressed DAI name in the log messages, allowing different streams to be easily disambiguated. Signed-off-by: Charles Keepax <ckeepax@opensource.cirrus.com> --- sound/soc/codecs/wm_adsp.c | 97 +++++++++++++++++++++++++--------------------- 1 file changed, 53 insertions(+), 44 deletions(-) diff --git a/sound/soc/codecs/wm_adsp.c b/sound/soc/codecs/wm_adsp.c index 5edaed3320407..d9d74c099d001 100644 --- a/sound/soc/codecs/wm_adsp.c +++ b/sound/soc/codecs/wm_adsp.c @@ -46,6 +46,13 @@ #define adsp_dbg(_dsp, fmt, ...) \ dev_dbg(_dsp->dev, "%s: " fmt, _dsp->name, ##__VA_ARGS__) +#define compr_err(_obj, fmt, ...) \ + adsp_err(_obj->dsp, "%s: " fmt, _obj->name ? _obj->name : "legacy", \ + ##__VA_ARGS__) +#define compr_dbg(_obj, fmt, ...) \ + adsp_dbg(_obj->dsp, "%s: " fmt, _obj->name ? _obj->name : "legacy", \ + ##__VA_ARGS__) + #define ADSP1_CONTROL_1 0x00 #define ADSP1_CONTROL_2 0x02 #define ADSP1_CONTROL_3 0x03 @@ -3033,20 +3040,23 @@ int wm_adsp_compr_open(struct wm_adsp *dsp, struct snd_compr_stream *stream) mutex_lock(&dsp->pwr_lock); if (wm_adsp_fw[dsp->fw].num_caps == 0) { - adsp_err(dsp, "Firmware does not support compressed API\n"); + adsp_err(dsp, "%s: Firmware does not support compressed API\n", + rtd->codec_dai->name); ret = -ENXIO; goto out; } if (wm_adsp_fw[dsp->fw].compr_direction != stream->direction) { - adsp_err(dsp, "Firmware does not support stream direction\n"); + adsp_err(dsp, "%s: Firmware does not support stream direction\n", + rtd->codec_dai->name); ret = -EINVAL; goto out; } list_for_each_entry(tmp, &dsp->compr_list, list) { if (!strcmp(tmp->name, rtd->codec_dai->name)) { - adsp_err(dsp, "Only a single stream supported per dai\n"); + adsp_err(dsp, "%s: Only a single stream supported per dai\n", + rtd->codec_dai->name); ret = -EBUSY; goto out; } @@ -3106,9 +3116,9 @@ static int wm_adsp_compr_check_params(struct snd_compr_stream *stream, params->buffer.fragments < WM_ADSP_MIN_FRAGMENTS || params->buffer.fragments > WM_ADSP_MAX_FRAGMENTS || params->buffer.fragment_size % WM_ADSP_DATA_WORD_SIZE) { - adsp_err(dsp, "Invalid buffer fragsize=%d fragments=%d\n", - params->buffer.fragment_size, - params->buffer.fragments); + compr_err(compr, "Invalid buffer fragsize=%d fragments=%d\n", + params->buffer.fragment_size, + params->buffer.fragments); return -EINVAL; } @@ -3136,9 +3146,9 @@ static int wm_adsp_compr_check_params(struct snd_compr_stream *stream, return 0; } - adsp_err(dsp, "Invalid params id=%u ch=%u,%u rate=%u fmt=%u\n", - params->codec.id, params->codec.ch_in, params->codec.ch_out, - params->codec.sample_rate, params->codec.format); + compr_err(compr, "Invalid params id=%u ch=%u,%u rate=%u fmt=%u\n", + params->codec.id, params->codec.ch_in, params->codec.ch_out, + params->codec.sample_rate, params->codec.format); return -EINVAL; } @@ -3160,8 +3170,8 @@ int wm_adsp_compr_set_params(struct snd_compr_stream *stream, compr->size = params->buffer; - adsp_dbg(compr->dsp, "fragment_size=%d fragments=%d\n", - compr->size.fragment_size, compr->size.fragments); + compr_dbg(compr, "fragment_size=%d fragments=%d\n", + compr->size.fragment_size, compr->size.fragments); size = wm_adsp_compr_frag_words(compr) * sizeof(*compr->raw_buf); compr->raw_buf = kmalloc(size, GFP_DMA | GFP_KERNEL); @@ -3303,10 +3313,10 @@ static int wm_adsp_buffer_populate(struct wm_adsp_compr_buf *buf) region->cumulative_size = offset; - adsp_dbg(buf->dsp, - "region=%d type=%d base=%08x off=%08x size=%08x\n", - i, region->mem_type, region->base_addr, - region->offset, region->cumulative_size); + compr_dbg(buf, + "region=%d type=%d base=%08x off=%08x size=%08x\n", + i, region->mem_type, region->base_addr, + region->offset, region->cumulative_size); } return 0; @@ -3380,7 +3390,7 @@ static int wm_adsp_buffer_parse_legacy(struct wm_adsp *dsp) if (ret < 0) return ret; - adsp_dbg(dsp, "legacy host_buf_ptr=%x\n", buf->host_buf_ptr); + compr_dbg(buf, "legacy host_buf_ptr=%x\n", buf->host_buf_ptr); return 0; } @@ -3428,7 +3438,7 @@ static int wm_adsp_buffer_parse_coeff(struct wm_coeff_ctl *ctl) * control is one word, assume version 0. */ if (ctl->len == 4) { - adsp_dbg(ctl->dsp, "host_buf_ptr=%x\n", buf->host_buf_ptr); + compr_dbg(buf, "host_buf_ptr=%x\n", buf->host_buf_ptr); return 0; } @@ -3458,8 +3468,8 @@ static int wm_adsp_buffer_parse_coeff(struct wm_coeff_ctl *ctl) buf->name = kasprintf(GFP_KERNEL, "%s-dsp-%s", ctl->dsp->part, (char *)&coeff_v1.name); - adsp_dbg(ctl->dsp, "host_buf_ptr=%x coeff version %u\n", - buf->host_buf_ptr, val); + compr_dbg(buf, "host_buf_ptr=%x coeff version %u\n", + buf->host_buf_ptr, val); return val; } @@ -3525,11 +3535,11 @@ static int wm_adsp_buffer_get_error(struct wm_adsp_compr_buf *buf) ret = wm_adsp_buffer_read(buf, HOST_BUFFER_FIELD(error), &buf->error); if (ret < 0) { - adsp_err(buf->dsp, "Failed to check buffer error: %d\n", ret); + compr_err(buf, "Failed to check buffer error: %d\n", ret); return ret; } if (buf->error != 0) { - adsp_err(buf->dsp, "Buffer error occurred: %d\n", buf->error); + compr_err(buf, "Buffer error occurred: %d\n", buf->error); return -EIO; } @@ -3542,7 +3552,7 @@ int wm_adsp_compr_trigger(struct snd_compr_stream *stream, int cmd) struct wm_adsp *dsp = compr->dsp; int ret = 0; - adsp_dbg(dsp, "Trigger: %d\n", cmd); + compr_dbg(compr, "Trigger: %d\n", cmd); mutex_lock(&dsp->pwr_lock); @@ -3551,8 +3561,8 @@ int wm_adsp_compr_trigger(struct snd_compr_stream *stream, int cmd) if (!wm_adsp_compr_attached(compr)) { ret = wm_adsp_compr_attach(compr); if (ret < 0) { - adsp_err(dsp, "Failed to link buffer and stream: %d\n", - ret); + compr_err(compr, "Failed to link buffer and stream: %d\n", + ret); break; } } @@ -3568,8 +3578,8 @@ int wm_adsp_compr_trigger(struct snd_compr_stream *stream, int cmd) HOST_BUFFER_FIELD(high_water_mark), wm_adsp_compr_frag_words(compr)); if (ret < 0) { - adsp_err(dsp, "Failed to set high water mark: %d\n", - ret); + compr_err(compr, "Failed to set high water mark: %d\n", + ret); break; } break; @@ -3610,7 +3620,7 @@ static int wm_adsp_buffer_update_avail(struct wm_adsp_compr_buf *buf) read_index = sign_extend32(next_read_index, 23); if (read_index < 0) { - adsp_dbg(buf->dsp, "Avail check on unstarted stream\n"); + compr_dbg(buf, "Avail check on unstarted stream\n"); return 0; } @@ -3628,8 +3638,8 @@ static int wm_adsp_buffer_update_avail(struct wm_adsp_compr_buf *buf) if (avail < 0) avail += wm_adsp_buffer_size(buf); - adsp_dbg(buf->dsp, "readindex=0x%x, writeindex=0x%x, avail=%d\n", - buf->read_index, write_index, avail * WM_ADSP_DATA_WORD_SIZE); + compr_dbg(buf, "readindex=0x%x, writeindex=0x%x, avail=%d\n", + buf->read_index, write_index, avail * WM_ADSP_DATA_WORD_SIZE); buf->avail = avail; @@ -3648,6 +3658,7 @@ int wm_adsp_compr_handle_irq(struct wm_adsp *dsp) ret = -ENODEV; goto out; } + adsp_dbg(dsp, "Handling buffer IRQ\n"); list_for_each_entry(buf, &dsp->buffer_list, list) { @@ -3660,13 +3671,13 @@ int wm_adsp_compr_handle_irq(struct wm_adsp *dsp) ret = wm_adsp_buffer_read(buf, HOST_BUFFER_FIELD(irq_count), &buf->irq_count); if (ret < 0) { - adsp_err(dsp, "Failed to get irq_count: %d\n", ret); + compr_err(buf, "Failed to get irq_count: %d\n", ret); goto out; } ret = wm_adsp_buffer_update_avail(buf); if (ret < 0) { - adsp_err(dsp, "Error reading avail: %d\n", ret); + compr_err(buf, "Error reading avail: %d\n", ret); goto out; } @@ -3690,8 +3701,7 @@ static int wm_adsp_buffer_reenable_irq(struct wm_adsp_compr_buf *buf) if (buf->irq_count & 0x01) return 0; - adsp_dbg(buf->dsp, "Enable IRQ(0x%x) for next fragment\n", - buf->irq_count); + compr_dbg(buf, "Enable IRQ(0x%x) for next fragment\n", buf->irq_count); buf->irq_count |= 0x01; @@ -3707,7 +3717,7 @@ int wm_adsp_compr_pointer(struct snd_compr_stream *stream, struct wm_adsp_compr_buf *buf; int ret = 0; - adsp_dbg(dsp, "Pointer request\n"); + compr_dbg(compr, "Pointer request\n"); mutex_lock(&dsp->pwr_lock); @@ -3722,7 +3732,7 @@ int wm_adsp_compr_pointer(struct snd_compr_stream *stream, if (buf->avail < wm_adsp_compr_frag_words(compr)) { ret = wm_adsp_buffer_update_avail(buf); if (ret < 0) { - adsp_err(dsp, "Error reading avail: %d\n", ret); + compr_err(compr, "Error reading avail: %d\n", ret); goto out; } @@ -3741,9 +3751,8 @@ int wm_adsp_compr_pointer(struct snd_compr_stream *stream, ret = wm_adsp_buffer_reenable_irq(buf); if (ret < 0) { - adsp_err(dsp, - "Failed to re-enable buffer IRQ: %d\n", - ret); + compr_err(compr, "Failed to re-enable buffer IRQ: %d\n", + ret); goto out; } } @@ -3818,11 +3827,10 @@ static int wm_adsp_buffer_capture_block(struct wm_adsp_compr *compr, int target) static int wm_adsp_compr_read(struct wm_adsp_compr *compr, char __user *buf, size_t count) { - struct wm_adsp *dsp = compr->dsp; int ntotal = 0; int nwords, nbytes; - adsp_dbg(dsp, "Requested read of %zu bytes\n", count); + compr_dbg(compr, "Requested read of %zu bytes\n", count); if (!compr->buf || compr->buf->error) { snd_compr_stop_error(compr->stream, SNDRV_PCM_STATE_XRUN); @@ -3834,17 +3842,18 @@ static int wm_adsp_compr_read(struct wm_adsp_compr *compr, do { nwords = wm_adsp_buffer_capture_block(compr, count); if (nwords < 0) { - adsp_err(dsp, "Failed to capture block: %d\n", nwords); + compr_err(compr, "Failed to capture block: %d\n", + nwords); return nwords; } nbytes = nwords * WM_ADSP_DATA_WORD_SIZE; - adsp_dbg(dsp, "Read %d bytes\n", nbytes); + compr_dbg(compr, "Read %d bytes\n", nbytes); if (copy_to_user(buf + ntotal, compr->raw_buf, nbytes)) { - adsp_err(dsp, "Failed to copy data to user: %d, %d\n", - ntotal, nbytes); + compr_err(compr, "Failed to copy data to user: %d, %d\n", + ntotal, nbytes); return -EFAULT; } -- 2.11.0 ^ permalink raw reply related [flat|nested] 9+ messages in thread
* Applied "ASoC: wm_adsp: Factor out stripping padding from ADSP data" to the asoc tree 2019-02-22 10:04 [PATCH 1/5] ASoC: wm_adsp: Factor out stripping padding from ADSP data Charles Keepax ` (3 preceding siblings ...) 2019-02-22 10:04 ` [PATCH 5/5] ASoC: wm_adsp: Improve logging messages Charles Keepax @ 2019-02-26 12:06 ` Mark Brown 4 siblings, 0 replies; 9+ messages in thread From: Mark Brown @ 2019-02-26 12:06 UTC (permalink / raw) To: Charles Keepax; +Cc: stuarth, patches, alsa-devel, broonie, lgirdwood The patch ASoC: wm_adsp: Factor out stripping padding from ADSP data has been applied to the asoc tree at https://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound.git All being well this means that it will be integrated into the linux-next tree (usually sometime in the next 24 hours) and sent to Linus during the next merge window (or sooner if it is a bug fix), however if problems are discovered then the patch may be dropped or reverted. You may get further e-mails resulting from automated or manual testing and review of the tree, please engage with people reporting problems and send followup patches addressing any issues that are reported if needed. If any updates are required or you are submitting further changes they should be sent as incremental updates against current git, existing patches will not be replaced. Please add any relevant lists and maintainers to the CCs when replying to this mail. Thanks, Mark >From cc7d6ce90216d101ae16f330fe05bd38e0e64cde Mon Sep 17 00:00:00 2001 From: Charles Keepax <ckeepax@opensource.cirrus.com> Date: Fri, 22 Feb 2019 10:04:17 +0000 Subject: [PATCH] ASoC: wm_adsp: Factor out stripping padding from ADSP data In preparation for more refactoring add a helper function to strip the padding from ADSP data. Signed-off-by: Charles Keepax <ckeepax@opensource.cirrus.com> Signed-off-by: Mark Brown <broonie@kernel.org> --- sound/soc/codecs/wm_adsp.c | 27 +++++++++++++++++---------- 1 file changed, 17 insertions(+), 10 deletions(-) diff --git a/sound/soc/codecs/wm_adsp.c b/sound/soc/codecs/wm_adsp.c index 12ef85e85c29..bd3241aacdb6 100644 --- a/sound/soc/codecs/wm_adsp.c +++ b/sound/soc/codecs/wm_adsp.c @@ -3231,6 +3231,21 @@ static inline int wm_adsp_buffer_write(struct wm_adsp_compr_buf *buf, buf->host_buf_ptr + field_offset, data); } +static void wm_adsp_remove_padding(u32 *buf, int nwords, int data_word_size) +{ + u8 *pack_in = (u8 *)buf; + u8 *pack_out = (u8 *)buf; + int i, j; + + /* Remove the padding bytes from the data read from the DSP */ + for (i = 0; i < nwords; i++) { + for (j = 0; j < data_word_size; j++) + *pack_out++ = *pack_in++; + + pack_in += sizeof(*buf) - data_word_size; + } +} + static int wm_adsp_legacy_host_buf_addr(struct wm_adsp_compr_buf *buf) { struct wm_adsp_alg_region *alg_region; @@ -3666,11 +3681,9 @@ EXPORT_SYMBOL_GPL(wm_adsp_compr_pointer); static int wm_adsp_buffer_capture_block(struct wm_adsp_compr *compr, int target) { struct wm_adsp_compr_buf *buf = compr->buf; - u8 *pack_in = (u8 *)compr->raw_buf; - u8 *pack_out = (u8 *)compr->raw_buf; unsigned int adsp_addr; int mem_type, nwords, max_read; - int i, j, ret; + int i, ret; /* Calculate read parameters */ for (i = 0; i < wm_adsp_fw[buf->dsp->fw].caps->num_regions; ++i) @@ -3702,13 +3715,7 @@ static int wm_adsp_buffer_capture_block(struct wm_adsp_compr *compr, int target) if (ret < 0) return ret; - /* Remove the padding bytes from the data read from the DSP */ - for (i = 0; i < nwords; i++) { - for (j = 0; j < WM_ADSP_DATA_WORD_SIZE; j++) - *pack_out++ = *pack_in++; - - pack_in += sizeof(*(compr->raw_buf)) - WM_ADSP_DATA_WORD_SIZE; - } + wm_adsp_remove_padding(compr->raw_buf, nwords, WM_ADSP_DATA_WORD_SIZE); /* update read index to account for words read */ buf->read_index += nwords; -- 2.20.1 ^ permalink raw reply related [flat|nested] 9+ messages in thread
end of thread, other threads:[~2019-02-26 12:06 UTC | newest] Thread overview: 9+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2019-02-22 10:04 [PATCH 1/5] ASoC: wm_adsp: Factor out stripping padding from ADSP data Charles Keepax 2019-02-22 10:04 ` [PATCH 2/5] ASoC: wm_adsp: Reorder some functions for improved clarity Charles Keepax 2019-02-26 12:06 ` Applied "ASoC: wm_adsp: Reorder some functions for improved clarity" to the asoc tree Mark Brown 2019-02-22 10:04 ` [PATCH 3/5] ASoC: wm_adsp: Refactor compress stream initialisation Charles Keepax 2019-02-26 12:06 ` Applied "ASoC: wm_adsp: Refactor compress stream initialisation" to the asoc tree Mark Brown 2019-02-22 10:04 ` [PATCH 4/5] ASoC: wm_adsp: Add support for multiple compressed buffers Charles Keepax 2019-02-26 12:06 ` Applied "ASoC: wm_adsp: Add support for multiple compressed buffers" to the asoc tree Mark Brown 2019-02-22 10:04 ` [PATCH 5/5] ASoC: wm_adsp: Improve logging messages Charles Keepax 2019-02-26 12:06 ` Applied "ASoC: wm_adsp: Factor out stripping padding from ADSP data" to the asoc tree Mark Brown
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for NNTP newsgroup(s).