[PATCH 00/16] add driver to support firmware loading on Cirrus Logic DSPs
This series of patches gradually separates the ASoC specific wm_adsp code from that required to manage firmware in Cirrus Logic DSPs.
The series starts with renaming, progresses to splitting the functionality before finally moving the independent functionality into drivers/firmware so that it can be used by both the existing ASoC wm_adsp and new non-audio parts.
Charles Keepax (3): ASoC: wm_adsp: Move check for control existence ASoC: wm_adsp: Switch to using wm_coeff_read_ctrl for compressed buffers ASoC: wm_adsp: Move sys_config_size to wm_adsp
Simon Trimmer (13): ASoC: wm_adsp: Remove use of snd_ctl_elem_type_t ASoC: wm_adsp: Cancel ongoing work when removing controls ASoC: wm_adsp: Rename generic DSP support ASoC: wm_adsp: Introduce cs_dsp logging macros ASoC: wm_adsp: Separate some ASoC and generic functions ASoC: wm_adsp: Split DSP power operations into helper functions ASoC: wm_adsp: Separate generic cs_dsp_coeff_ctl handling ASoC: wm_adsp: Move check of dsp->running to better place ASoC: wm_adsp: Pass firmware names as parameters when starting DSP core ASoC: wm_adsp: move firmware loading to client ASoC: wm_adsp: Split out struct cs_dsp from struct wm_adsp ASoC: wm_adsp: Separate wm_adsp specifics in cs_dsp_client_ops firmware: cs_dsp: add driver to support firmware loading on Cirrus Logic DSPs
MAINTAINERS | 11 + drivers/firmware/Kconfig | 1 + drivers/firmware/Makefile | 1 + drivers/firmware/cirrus/Kconfig | 5 + drivers/firmware/cirrus/Makefile | 3 + drivers/firmware/cirrus/cs_dsp.c | 3109 ++++++++++++++++ include/linux/firmware/cirrus/cs_dsp.h | 242 ++ .../linux/firmware/cirrus}/wmfw.h | 8 +- sound/soc/codecs/Kconfig | 1 + sound/soc/codecs/cs47l15.c | 22 +- sound/soc/codecs/cs47l24.c | 20 +- sound/soc/codecs/cs47l35.c | 24 +- sound/soc/codecs/cs47l85.c | 32 +- sound/soc/codecs/cs47l90.c | 34 +- sound/soc/codecs/cs47l92.c | 20 +- sound/soc/codecs/madera.c | 18 +- sound/soc/codecs/wm2200.c | 30 +- sound/soc/codecs/wm5102.c | 16 +- sound/soc/codecs/wm5110.c | 24 +- sound/soc/codecs/wm_adsp.c | 3188 ++--------------- sound/soc/codecs/wm_adsp.h | 105 +- 21 files changed, 3794 insertions(+), 3120 deletions(-) create mode 100644 drivers/firmware/cirrus/Kconfig create mode 100644 drivers/firmware/cirrus/Makefile create mode 100644 drivers/firmware/cirrus/cs_dsp.c create mode 100644 include/linux/firmware/cirrus/cs_dsp.h rename {sound/soc/codecs => include/linux/firmware/cirrus}/wmfw.h (91%)
In preparation for moving the generic DSP support out of ASoC, remove the use of the ALSA specific types for the control type. The use of an ALSA type was unnecessary, the simplified code is easier to read and avoids Sparse warnings.
Signed-off-by: Simon Trimmer simont@opensource.cirrus.com Signed-off-by: Charles Keepax ckeepax@opensource.cirrus.com --- sound/soc/codecs/wm_adsp.c | 24 +++++++++++------------- sound/soc/codecs/wmfw.h | 8 +++++--- 2 files changed, 16 insertions(+), 16 deletions(-)
diff --git a/sound/soc/codecs/wm_adsp.c b/sound/soc/codecs/wm_adsp.c index f7c800927cb2..f5db6e3b9f60 100644 --- a/sound/soc/codecs/wm_adsp.c +++ b/sound/soc/codecs/wm_adsp.c @@ -612,7 +612,7 @@ struct wm_coeff_ctl { unsigned int set:1; struct soc_bytes_ext bytes_ext; unsigned int flags; - snd_ctl_elem_type_t type; + unsigned int type; };
static const char *wm_adsp_mem_region_name(unsigned int type) @@ -1414,7 +1414,7 @@ static int wm_adsp_create_control(struct wm_adsp *dsp, const struct wm_adsp_alg_region *alg_region, unsigned int offset, unsigned int len, const char *subname, unsigned int subname_len, - unsigned int flags, snd_ctl_elem_type_t type) + unsigned int flags, unsigned int type) { struct wm_coeff_ctl *ctl; struct wmfw_ctl_work *ctl_work; @@ -1546,7 +1546,7 @@ struct wm_coeff_parsed_coeff { int mem_type; const u8 *name; int name_len; - snd_ctl_elem_type_t ctl_type; + unsigned int ctl_type; int flags; int len; }; @@ -1641,7 +1641,7 @@ static inline void wm_coeff_parse_coeff(struct wm_adsp *dsp, const u8 **data, blk->mem_type = le16_to_cpu(raw->hdr.type); blk->name = raw->name; blk->name_len = strlen(raw->name); - blk->ctl_type = (__force snd_ctl_elem_type_t)le16_to_cpu(raw->ctl_type); + blk->ctl_type = le16_to_cpu(raw->ctl_type); blk->flags = le16_to_cpu(raw->flags); blk->len = le32_to_cpu(raw->len); break; @@ -1654,9 +1654,7 @@ static inline void wm_coeff_parse_coeff(struct wm_adsp *dsp, const u8 **data, &blk->name); wm_coeff_parse_string(sizeof(u8), &tmp, NULL); wm_coeff_parse_string(sizeof(u16), &tmp, NULL); - blk->ctl_type = - (__force snd_ctl_elem_type_t)wm_coeff_parse_int(sizeof(raw->ctl_type), - &tmp); + blk->ctl_type = wm_coeff_parse_int(sizeof(raw->ctl_type), &tmp); blk->flags = wm_coeff_parse_int(sizeof(raw->flags), &tmp); blk->len = wm_coeff_parse_int(sizeof(raw->len), &tmp);
@@ -1701,7 +1699,7 @@ static int wm_adsp_parse_coeff(struct wm_adsp *dsp, wm_coeff_parse_coeff(dsp, &data, &coeff_blk);
switch (coeff_blk.ctl_type) { - case SNDRV_CTL_ELEM_TYPE_BYTES: + case WMFW_CTL_TYPE_BYTES: break; case WMFW_CTL_TYPE_ACKED: if (coeff_blk.flags & WMFW_CTL_FLAG_SYS) @@ -2322,7 +2320,7 @@ static int wm_adsp1_setup_algs(struct wm_adsp *dsp) len *= 4; wm_adsp_create_control(dsp, alg_region, 0, len, NULL, 0, 0, - SNDRV_CTL_ELEM_TYPE_BYTES); + WMFW_CTL_TYPE_BYTES); } else { adsp_warn(dsp, "Missing length info for region DM with ID %x\n", be32_to_cpu(adsp1_alg[i].alg.id)); @@ -2343,7 +2341,7 @@ static int wm_adsp1_setup_algs(struct wm_adsp *dsp) len *= 4; wm_adsp_create_control(dsp, alg_region, 0, len, NULL, 0, 0, - SNDRV_CTL_ELEM_TYPE_BYTES); + WMFW_CTL_TYPE_BYTES); } else { adsp_warn(dsp, "Missing length info for region ZM with ID %x\n", be32_to_cpu(adsp1_alg[i].alg.id)); @@ -2430,7 +2428,7 @@ static int wm_adsp2_setup_algs(struct wm_adsp *dsp) len *= 4; wm_adsp_create_control(dsp, alg_region, 0, len, NULL, 0, 0, - SNDRV_CTL_ELEM_TYPE_BYTES); + WMFW_CTL_TYPE_BYTES); } else { adsp_warn(dsp, "Missing length info for region XM with ID %x\n", be32_to_cpu(adsp2_alg[i].alg.id)); @@ -2451,7 +2449,7 @@ static int wm_adsp2_setup_algs(struct wm_adsp *dsp) len *= 4; wm_adsp_create_control(dsp, alg_region, 0, len, NULL, 0, 0, - SNDRV_CTL_ELEM_TYPE_BYTES); + WMFW_CTL_TYPE_BYTES); } else { adsp_warn(dsp, "Missing length info for region YM with ID %x\n", be32_to_cpu(adsp2_alg[i].alg.id)); @@ -2472,7 +2470,7 @@ static int wm_adsp2_setup_algs(struct wm_adsp *dsp) len *= 4; wm_adsp_create_control(dsp, alg_region, 0, len, NULL, 0, 0, - SNDRV_CTL_ELEM_TYPE_BYTES); + WMFW_CTL_TYPE_BYTES); } else { adsp_warn(dsp, "Missing length info for region ZM with ID %x\n", be32_to_cpu(adsp2_alg[i].alg.id)); diff --git a/sound/soc/codecs/wmfw.h b/sound/soc/codecs/wmfw.h index f3d51602f85c..a19bf7c6fc8b 100644 --- a/sound/soc/codecs/wmfw.h +++ b/sound/soc/codecs/wmfw.h @@ -23,10 +23,12 @@ #define WMFW_CTL_FLAG_WRITEABLE 0x0002 #define WMFW_CTL_FLAG_READABLE 0x0001
+#define WMFW_CTL_TYPE_BYTES 0x0004 /* byte control */ + /* Non-ALSA coefficient types start at 0x1000 */ -#define WMFW_CTL_TYPE_ACKED ((__force snd_ctl_elem_type_t)0x1000) /* acked control */ -#define WMFW_CTL_TYPE_HOSTEVENT ((__force snd_ctl_elem_type_t)0x1001) /* event control */ -#define WMFW_CTL_TYPE_HOST_BUFFER ((__force snd_ctl_elem_type_t)0x1002) /* host buffer pointer */ +#define WMFW_CTL_TYPE_ACKED 0x1000 /* acked control */ +#define WMFW_CTL_TYPE_HOSTEVENT 0x1001 /* event control */ +#define WMFW_CTL_TYPE_HOST_BUFFER 0x1002 /* host buffer pointer */
struct wmfw_header { char magic[4];
From: Charles Keepax ckeepax@opensource.cirrus.com
Checking earlier in the function if a control already exists avoids superfluous string construction and also prepares for future refactoring.
Signed-off-by: Charles Keepax ckeepax@opensource.cirrus.com Signed-off-by: Simon Trimmer simont@opensource.cirrus.com --- sound/soc/codecs/wm_adsp.c | 21 +++++++++++++-------- 1 file changed, 13 insertions(+), 8 deletions(-)
diff --git a/sound/soc/codecs/wm_adsp.c b/sound/soc/codecs/wm_adsp.c index f5db6e3b9f60..b300af6fdd41 100644 --- a/sound/soc/codecs/wm_adsp.c +++ b/sound/soc/codecs/wm_adsp.c @@ -1422,6 +1422,19 @@ static int wm_adsp_create_control(struct wm_adsp *dsp, const char *region_name; int ret;
+ list_for_each_entry(ctl, &dsp->ctl_list, list) { + if (ctl->fw_name == wm_adsp_fw_text[dsp->fw] && + ctl->alg_region.alg == alg_region->alg && + ctl->alg_region.type == alg_region->type) { + if ((!subname && !ctl->subname) || + (subname && !strncmp(ctl->subname, subname, ctl->subname_len))) { + if (!ctl->enabled) + ctl->enabled = 1; + return 0; + } + } + } + region_name = wm_adsp_mem_region_name(alg_region->type); if (!region_name) { adsp_err(dsp, "Unknown region type: %d\n", alg_region->type); @@ -1462,14 +1475,6 @@ static int wm_adsp_create_control(struct wm_adsp *dsp, " %.*s", subname_len - skip, subname + skip); }
- list_for_each_entry(ctl, &dsp->ctl_list, list) { - if (!strcmp(ctl->name, name)) { - if (!ctl->enabled) - ctl->enabled = 1; - return 0; - } - } - ctl = kzalloc(sizeof(*ctl), GFP_KERNEL); if (!ctl) return -ENOMEM;
From: Charles Keepax ckeepax@opensource.cirrus.com
When parsing a compressed buffer from the firmware the driver currently open codes reading the firmware coefficient containing the buffer description. Improve this slightly by using the coefficient read functions already provided by the wm_adsp driver. It is worth noting this change requires the running variable to be set before wm_adsp_buffer_init is called, however this is safe, since its all still under the power lock and nothing in the compressed code gates itself on running.
Signed-off-by: Charles Keepax ckeepax@opensource.cirrus.com Signed-off-by: Simon Trimmer simont@opensource.cirrus.com --- sound/soc/codecs/wm_adsp.c | 24 +++++++----------------- 1 file changed, 7 insertions(+), 17 deletions(-)
diff --git a/sound/soc/codecs/wm_adsp.c b/sound/soc/codecs/wm_adsp.c index b300af6fdd41..9c3d4b96fd7c 100644 --- a/sound/soc/codecs/wm_adsp.c +++ b/sound/soc/codecs/wm_adsp.c @@ -3277,14 +3277,14 @@ int wm_adsp_event(struct snd_soc_dapm_widget *w, goto err; }
+ dsp->running = true; + if (wm_adsp_fw[dsp->fw].num_caps != 0) { ret = wm_adsp_buffer_init(dsp); if (ret < 0) goto err; }
- dsp->running = true; - mutex_unlock(&dsp->pwr_lock); break;
@@ -3869,26 +3869,21 @@ 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 reg, version; - __be32 bufp; + unsigned int version; int ret, i;
- ret = wm_coeff_base_reg(ctl, ®); - if (ret) - return ret; - for (i = 0; i < 5; ++i) { - ret = regmap_raw_read(ctl->dsp->regmap, reg, &bufp, sizeof(bufp)); + ret = wm_coeff_read_ctrl(ctl, &coeff_v1, sizeof(coeff_v1)); if (ret < 0) return ret;
- if (bufp) + if (coeff_v1.host_buf_ptr) break;
usleep_range(1000, 2000); }
- if (!bufp) { + if (!coeff_v1.host_buf_ptr) { adsp_err(ctl->dsp, "Failed to acquire host buffer\n"); return -EIO; } @@ -3898,7 +3893,7 @@ static int wm_adsp_buffer_parse_coeff(struct wm_coeff_ctl *ctl) return -ENOMEM;
buf->host_buf_mem_type = ctl->alg_region.type; - buf->host_buf_ptr = be32_to_cpu(bufp); + buf->host_buf_ptr = be32_to_cpu(coeff_v1.host_buf_ptr);
ret = wm_adsp_buffer_populate(buf); if (ret < 0) @@ -3913,11 +3908,6 @@ static int wm_adsp_buffer_parse_coeff(struct wm_coeff_ctl *ctl) return 0; }
- ret = regmap_raw_read(ctl->dsp->regmap, reg, &coeff_v1, - sizeof(coeff_v1)); - if (ret < 0) - return ret; - version = be32_to_cpu(coeff_v1.versions) & HOST_BUF_COEFF_COMPAT_VER_MASK; version >>= HOST_BUF_COEFF_COMPAT_VER_SHIFT;
Removes wm_adsp_ctl_work and integrates the work_struct into wm_coeff_ctl so it may be referenced.
Signed-off-by: Simon Trimmer simont@opensource.cirrus.com --- sound/soc/codecs/wm_adsp.c | 34 +++++++++------------------------- 1 file changed, 9 insertions(+), 25 deletions(-)
diff --git a/sound/soc/codecs/wm_adsp.c b/sound/soc/codecs/wm_adsp.c index 9c3d4b96fd7c..c1b5ea3b5718 100644 --- a/sound/soc/codecs/wm_adsp.c +++ b/sound/soc/codecs/wm_adsp.c @@ -613,6 +613,7 @@ struct wm_coeff_ctl { struct soc_bytes_ext bytes_ext; unsigned int flags; unsigned int type; + struct work_struct work; };
static const char *wm_adsp_mem_region_name(unsigned int type) @@ -1240,12 +1241,6 @@ static int wm_coeff_get_acked(struct snd_kcontrol *kcontrol, return 0; }
-struct wmfw_ctl_work { - struct wm_adsp *dsp; - struct wm_coeff_ctl *ctl; - struct work_struct work; -}; - static unsigned int wmfw_convert_flags(unsigned int in, unsigned int len) { unsigned int out, rd, wr, vol; @@ -1394,16 +1389,17 @@ static void wm_adsp_signal_event_controls(struct wm_adsp *dsp,
static void wm_adsp_ctl_work(struct work_struct *work) { - struct wmfw_ctl_work *ctl_work = container_of(work, - struct wmfw_ctl_work, - work); + struct wm_coeff_ctl *ctl = container_of(work, + struct wm_coeff_ctl, + work);
- wmfw_add_ctl(ctl_work->dsp, ctl_work->ctl); - kfree(ctl_work); + wmfw_add_ctl(ctl->dsp, ctl); }
static void wm_adsp_free_ctl_blk(struct wm_coeff_ctl *ctl) { + cancel_work_sync(&ctl->work); + kfree(ctl->cache); kfree(ctl->name); kfree(ctl->subname); @@ -1417,7 +1413,6 @@ static int wm_adsp_create_control(struct wm_adsp *dsp, unsigned int flags, unsigned int type) { struct wm_coeff_ctl *ctl; - struct wmfw_ctl_work *ctl_work; char name[SNDRV_CTL_ELEM_ID_NAME_MAXLEN]; const char *region_name; int ret; @@ -1513,22 +1508,11 @@ static int wm_adsp_create_control(struct wm_adsp *dsp, if (flags & WMFW_CTL_FLAG_SYS) return 0;
- ctl_work = kzalloc(sizeof(*ctl_work), GFP_KERNEL); - if (!ctl_work) { - ret = -ENOMEM; - goto err_list_del; - } - - ctl_work->dsp = dsp; - ctl_work->ctl = ctl; - INIT_WORK(&ctl_work->work, wm_adsp_ctl_work); - schedule_work(&ctl_work->work); + INIT_WORK(&ctl->work, wm_adsp_ctl_work); + schedule_work(&ctl->work);
return 0;
-err_list_del: - list_del(&ctl->list); - kfree(ctl->cache); err_ctl_subname: kfree(ctl->subname); err_ctl_name:
This rename is preparation for moving the generic DSP support out of ASoC, generic code named wm_* will be renamed to cs_*.
Signed-off-by: Simon Trimmer simont@opensource.cirrus.com Signed-off-by: Charles Keepax ckeepax@opensource.cirrus.com --- sound/soc/codecs/cs47l15.c | 4 +- sound/soc/codecs/cs47l24.c | 6 +- sound/soc/codecs/cs47l35.c | 8 +- sound/soc/codecs/cs47l85.c | 16 +- sound/soc/codecs/cs47l90.c | 18 +- sound/soc/codecs/cs47l92.c | 4 +- sound/soc/codecs/wm2200.c | 4 +- sound/soc/codecs/wm5102.c | 2 +- sound/soc/codecs/wm5110.c | 10 +- sound/soc/codecs/wm_adsp.c | 826 ++++++++++++++++++------------------- sound/soc/codecs/wm_adsp.h | 46 +-- 11 files changed, 472 insertions(+), 472 deletions(-)
diff --git a/sound/soc/codecs/cs47l15.c b/sound/soc/codecs/cs47l15.c index 1ee83160b83f..07388701f89f 100644 --- a/sound/soc/codecs/cs47l15.c +++ b/sound/soc/codecs/cs47l15.c @@ -45,7 +45,7 @@ struct cs47l15 { bool in1_lp_mode; };
-static const struct wm_adsp_region cs47l15_dsp1_regions[] = { +static const struct cs_dsp_region cs47l15_dsp1_regions[] = { { .type = WMFW_ADSP2_PM, .base = 0x080000 }, { .type = WMFW_ADSP2_ZM, .base = 0x0e0000 }, { .type = WMFW_ADSP2_XM, .base = 0x0a0000 }, @@ -1413,7 +1413,7 @@ static int cs47l15_probe(struct platform_device *pdev) cs47l15->core.adsp[0].num_mems = ARRAY_SIZE(cs47l15_dsp1_regions);
cs47l15->core.adsp[0].lock_regions = - WM_ADSP2_REGION_1 | WM_ADSP2_REGION_2 | WM_ADSP2_REGION_3; + CS_ADSP2_REGION_1 | CS_ADSP2_REGION_2 | CS_ADSP2_REGION_3;
ret = wm_adsp2_init(&cs47l15->core.adsp[0]); if (ret != 0) diff --git a/sound/soc/codecs/cs47l24.c b/sound/soc/codecs/cs47l24.c index 6b6d08816024..be81094dbf1e 100644 --- a/sound/soc/codecs/cs47l24.c +++ b/sound/soc/codecs/cs47l24.c @@ -37,21 +37,21 @@ struct cs47l24_priv { struct arizona_fll fll[2]; };
-static const struct wm_adsp_region cs47l24_dsp2_regions[] = { +static const struct cs_dsp_region cs47l24_dsp2_regions[] = { { .type = WMFW_ADSP2_PM, .base = 0x200000 }, { .type = WMFW_ADSP2_ZM, .base = 0x280000 }, { .type = WMFW_ADSP2_XM, .base = 0x290000 }, { .type = WMFW_ADSP2_YM, .base = 0x2a8000 }, };
-static const struct wm_adsp_region cs47l24_dsp3_regions[] = { +static const struct cs_dsp_region cs47l24_dsp3_regions[] = { { .type = WMFW_ADSP2_PM, .base = 0x300000 }, { .type = WMFW_ADSP2_ZM, .base = 0x380000 }, { .type = WMFW_ADSP2_XM, .base = 0x390000 }, { .type = WMFW_ADSP2_YM, .base = 0x3a8000 }, };
-static const struct wm_adsp_region *cs47l24_dsp_regions[] = { +static const struct cs_dsp_region *cs47l24_dsp_regions[] = { cs47l24_dsp2_regions, cs47l24_dsp3_regions, }; diff --git a/sound/soc/codecs/cs47l35.c b/sound/soc/codecs/cs47l35.c index 3f04a2a74521..b8d594bf4d13 100644 --- a/sound/soc/codecs/cs47l35.c +++ b/sound/soc/codecs/cs47l35.c @@ -37,28 +37,28 @@ struct cs47l35 { struct madera_fll fll; };
-static const struct wm_adsp_region cs47l35_dsp1_regions[] = { +static const struct cs_dsp_region cs47l35_dsp1_regions[] = { { .type = WMFW_ADSP2_PM, .base = 0x080000 }, { .type = WMFW_ADSP2_ZM, .base = 0x0e0000 }, { .type = WMFW_ADSP2_XM, .base = 0x0a0000 }, { .type = WMFW_ADSP2_YM, .base = 0x0c0000 }, };
-static const struct wm_adsp_region cs47l35_dsp2_regions[] = { +static const struct cs_dsp_region cs47l35_dsp2_regions[] = { { .type = WMFW_ADSP2_PM, .base = 0x100000 }, { .type = WMFW_ADSP2_ZM, .base = 0x160000 }, { .type = WMFW_ADSP2_XM, .base = 0x120000 }, { .type = WMFW_ADSP2_YM, .base = 0x140000 }, };
-static const struct wm_adsp_region cs47l35_dsp3_regions[] = { +static const struct cs_dsp_region cs47l35_dsp3_regions[] = { { .type = WMFW_ADSP2_PM, .base = 0x180000 }, { .type = WMFW_ADSP2_ZM, .base = 0x1e0000 }, { .type = WMFW_ADSP2_XM, .base = 0x1a0000 }, { .type = WMFW_ADSP2_YM, .base = 0x1c0000 }, };
-static const struct wm_adsp_region *cs47l35_dsp_regions[] = { +static const struct cs_dsp_region *cs47l35_dsp_regions[] = { cs47l35_dsp1_regions, cs47l35_dsp2_regions, cs47l35_dsp3_regions, diff --git a/sound/soc/codecs/cs47l85.c b/sound/soc/codecs/cs47l85.c index 748a180870bc..7ba08ca75c4f 100644 --- a/sound/soc/codecs/cs47l85.c +++ b/sound/soc/codecs/cs47l85.c @@ -37,56 +37,56 @@ struct cs47l85 { struct madera_fll fll[3]; };
-static const struct wm_adsp_region cs47l85_dsp1_regions[] = { +static const struct cs_dsp_region cs47l85_dsp1_regions[] = { { .type = WMFW_ADSP2_PM, .base = 0x080000 }, { .type = WMFW_ADSP2_ZM, .base = 0x0e0000 }, { .type = WMFW_ADSP2_XM, .base = 0x0a0000 }, { .type = WMFW_ADSP2_YM, .base = 0x0c0000 }, };
-static const struct wm_adsp_region cs47l85_dsp2_regions[] = { +static const struct cs_dsp_region cs47l85_dsp2_regions[] = { { .type = WMFW_ADSP2_PM, .base = 0x100000 }, { .type = WMFW_ADSP2_ZM, .base = 0x160000 }, { .type = WMFW_ADSP2_XM, .base = 0x120000 }, { .type = WMFW_ADSP2_YM, .base = 0x140000 }, };
-static const struct wm_adsp_region cs47l85_dsp3_regions[] = { +static const struct cs_dsp_region cs47l85_dsp3_regions[] = { { .type = WMFW_ADSP2_PM, .base = 0x180000 }, { .type = WMFW_ADSP2_ZM, .base = 0x1e0000 }, { .type = WMFW_ADSP2_XM, .base = 0x1a0000 }, { .type = WMFW_ADSP2_YM, .base = 0x1c0000 }, };
-static const struct wm_adsp_region cs47l85_dsp4_regions[] = { +static const struct cs_dsp_region cs47l85_dsp4_regions[] = { { .type = WMFW_ADSP2_PM, .base = 0x200000 }, { .type = WMFW_ADSP2_ZM, .base = 0x260000 }, { .type = WMFW_ADSP2_XM, .base = 0x220000 }, { .type = WMFW_ADSP2_YM, .base = 0x240000 }, };
-static const struct wm_adsp_region cs47l85_dsp5_regions[] = { +static const struct cs_dsp_region cs47l85_dsp5_regions[] = { { .type = WMFW_ADSP2_PM, .base = 0x280000 }, { .type = WMFW_ADSP2_ZM, .base = 0x2e0000 }, { .type = WMFW_ADSP2_XM, .base = 0x2a0000 }, { .type = WMFW_ADSP2_YM, .base = 0x2c0000 }, };
-static const struct wm_adsp_region cs47l85_dsp6_regions[] = { +static const struct cs_dsp_region cs47l85_dsp6_regions[] = { { .type = WMFW_ADSP2_PM, .base = 0x300000 }, { .type = WMFW_ADSP2_ZM, .base = 0x360000 }, { .type = WMFW_ADSP2_XM, .base = 0x320000 }, { .type = WMFW_ADSP2_YM, .base = 0x340000 }, };
-static const struct wm_adsp_region cs47l85_dsp7_regions[] = { +static const struct cs_dsp_region cs47l85_dsp7_regions[] = { { .type = WMFW_ADSP2_PM, .base = 0x380000 }, { .type = WMFW_ADSP2_ZM, .base = 0x3e0000 }, { .type = WMFW_ADSP2_XM, .base = 0x3a0000 }, { .type = WMFW_ADSP2_YM, .base = 0x3c0000 }, };
-static const struct wm_adsp_region *cs47l85_dsp_regions[] = { +static const struct cs_dsp_region *cs47l85_dsp_regions[] = { cs47l85_dsp1_regions, cs47l85_dsp2_regions, cs47l85_dsp3_regions, diff --git a/sound/soc/codecs/cs47l90.c b/sound/soc/codecs/cs47l90.c index d2911c014b86..01d75c32d81e 100644 --- a/sound/soc/codecs/cs47l90.c +++ b/sound/soc/codecs/cs47l90.c @@ -37,56 +37,56 @@ struct cs47l90 { struct madera_fll fll[3]; };
-static const struct wm_adsp_region cs47l90_dsp1_regions[] = { +static const struct cs_dsp_region cs47l90_dsp1_regions[] = { { .type = WMFW_ADSP2_PM, .base = 0x080000 }, { .type = WMFW_ADSP2_ZM, .base = 0x0e0000 }, { .type = WMFW_ADSP2_XM, .base = 0x0a0000 }, { .type = WMFW_ADSP2_YM, .base = 0x0c0000 }, };
-static const struct wm_adsp_region cs47l90_dsp2_regions[] = { +static const struct cs_dsp_region cs47l90_dsp2_regions[] = { { .type = WMFW_ADSP2_PM, .base = 0x100000 }, { .type = WMFW_ADSP2_ZM, .base = 0x160000 }, { .type = WMFW_ADSP2_XM, .base = 0x120000 }, { .type = WMFW_ADSP2_YM, .base = 0x140000 }, };
-static const struct wm_adsp_region cs47l90_dsp3_regions[] = { +static const struct cs_dsp_region cs47l90_dsp3_regions[] = { { .type = WMFW_ADSP2_PM, .base = 0x180000 }, { .type = WMFW_ADSP2_ZM, .base = 0x1e0000 }, { .type = WMFW_ADSP2_XM, .base = 0x1a0000 }, { .type = WMFW_ADSP2_YM, .base = 0x1c0000 }, };
-static const struct wm_adsp_region cs47l90_dsp4_regions[] = { +static const struct cs_dsp_region cs47l90_dsp4_regions[] = { { .type = WMFW_ADSP2_PM, .base = 0x200000 }, { .type = WMFW_ADSP2_ZM, .base = 0x260000 }, { .type = WMFW_ADSP2_XM, .base = 0x220000 }, { .type = WMFW_ADSP2_YM, .base = 0x240000 }, };
-static const struct wm_adsp_region cs47l90_dsp5_regions[] = { +static const struct cs_dsp_region cs47l90_dsp5_regions[] = { { .type = WMFW_ADSP2_PM, .base = 0x280000 }, { .type = WMFW_ADSP2_ZM, .base = 0x2e0000 }, { .type = WMFW_ADSP2_XM, .base = 0x2a0000 }, { .type = WMFW_ADSP2_YM, .base = 0x2c0000 }, };
-static const struct wm_adsp_region cs47l90_dsp6_regions[] = { +static const struct cs_dsp_region cs47l90_dsp6_regions[] = { { .type = WMFW_ADSP2_PM, .base = 0x300000 }, { .type = WMFW_ADSP2_ZM, .base = 0x360000 }, { .type = WMFW_ADSP2_XM, .base = 0x320000 }, { .type = WMFW_ADSP2_YM, .base = 0x340000 }, };
-static const struct wm_adsp_region cs47l90_dsp7_regions[] = { +static const struct cs_dsp_region cs47l90_dsp7_regions[] = { { .type = WMFW_ADSP2_PM, .base = 0x380000 }, { .type = WMFW_ADSP2_ZM, .base = 0x3e0000 }, { .type = WMFW_ADSP2_XM, .base = 0x3a0000 }, { .type = WMFW_ADSP2_YM, .base = 0x3c0000 }, };
-static const struct wm_adsp_region *cs47l90_dsp_regions[] = { +static const struct cs_dsp_region *cs47l90_dsp_regions[] = { cs47l90_dsp1_regions, cs47l90_dsp2_regions, cs47l90_dsp3_regions, @@ -2554,7 +2554,7 @@ static int cs47l90_probe(struct platform_device *pdev) cs47l90->core.adsp[i].num_mems = ARRAY_SIZE(cs47l90_dsp1_regions);
- cs47l90->core.adsp[i].lock_regions = WM_ADSP2_REGION_1_9; + cs47l90->core.adsp[i].lock_regions = CS_ADSP2_REGION_1_9;
ret = wm_adsp2_init(&cs47l90->core.adsp[i]);
diff --git a/sound/soc/codecs/cs47l92.c b/sound/soc/codecs/cs47l92.c index 1a0280416d92..05087cc9c44b 100644 --- a/sound/soc/codecs/cs47l92.c +++ b/sound/soc/codecs/cs47l92.c @@ -37,7 +37,7 @@ struct cs47l92 { struct madera_fll fll[2]; };
-static const struct wm_adsp_region cs47l92_dsp1_regions[] = { +static const struct cs_dsp_region cs47l92_dsp1_regions[] = { { .type = WMFW_ADSP2_PM, .base = 0x080000 }, { .type = WMFW_ADSP2_ZM, .base = 0x0e0000 }, { .type = WMFW_ADSP2_XM, .base = 0x0a0000 }, @@ -2012,7 +2012,7 @@ static int cs47l92_probe(struct platform_device *pdev) cs47l92->core.adsp[0].mem = cs47l92_dsp1_regions; cs47l92->core.adsp[0].num_mems = ARRAY_SIZE(cs47l92_dsp1_regions);
- cs47l92->core.adsp[0].lock_regions = WM_ADSP2_REGION_1_9; + cs47l92->core.adsp[0].lock_regions = CS_ADSP2_REGION_1_9;
ret = wm_adsp2_init(&cs47l92->core.adsp[0]); if (ret != 0) diff --git a/sound/soc/codecs/wm2200.c b/sound/soc/codecs/wm2200.c index c35673e7f420..68355188eb55 100644 --- a/sound/soc/codecs/wm2200.c +++ b/sound/soc/codecs/wm2200.c @@ -145,13 +145,13 @@ static const struct regmap_range_cfg wm2200_ranges[] = { .window_start = WM2200_DSP2_ZM_0, .window_len = 1024, }, };
-static const struct wm_adsp_region wm2200_dsp1_regions[] = { +static const struct cs_dsp_region wm2200_dsp1_regions[] = { { .type = WMFW_ADSP1_PM, .base = WM2200_DSP1_PM_BASE }, { .type = WMFW_ADSP1_DM, .base = WM2200_DSP1_DM_BASE }, { .type = WMFW_ADSP1_ZM, .base = WM2200_DSP1_ZM_BASE }, };
-static const struct wm_adsp_region wm2200_dsp2_regions[] = { +static const struct cs_dsp_region wm2200_dsp2_regions[] = { { .type = WMFW_ADSP1_PM, .base = WM2200_DSP2_PM_BASE }, { .type = WMFW_ADSP1_DM, .base = WM2200_DSP2_DM_BASE }, { .type = WMFW_ADSP1_ZM, .base = WM2200_DSP2_ZM_BASE }, diff --git a/sound/soc/codecs/wm5102.c b/sound/soc/codecs/wm5102.c index 621598608bf0..26e87c6be35b 100644 --- a/sound/soc/codecs/wm5102.c +++ b/sound/soc/codecs/wm5102.c @@ -44,7 +44,7 @@ static DECLARE_TLV_DB_SCALE(digital_tlv, -6400, 50, 0); static DECLARE_TLV_DB_SCALE(noise_tlv, -13200, 600, 0); static DECLARE_TLV_DB_SCALE(ng_tlv, -10200, 600, 0);
-static const struct wm_adsp_region wm5102_dsp1_regions[] = { +static const struct cs_dsp_region wm5102_dsp1_regions[] = { { .type = WMFW_ADSP2_PM, .base = 0x100000 }, { .type = WMFW_ADSP2_ZM, .base = 0x180000 }, { .type = WMFW_ADSP2_XM, .base = 0x190000 }, diff --git a/sound/soc/codecs/wm5110.c b/sound/soc/codecs/wm5110.c index 5c2d45d05c97..e13e66b0ee52 100644 --- a/sound/soc/codecs/wm5110.c +++ b/sound/soc/codecs/wm5110.c @@ -45,35 +45,35 @@ struct wm5110_priv { unsigned int in_pga_cache[6]; };
-static const struct wm_adsp_region wm5110_dsp1_regions[] = { +static const struct cs_dsp_region wm5110_dsp1_regions[] = { { .type = WMFW_ADSP2_PM, .base = 0x100000 }, { .type = WMFW_ADSP2_ZM, .base = 0x180000 }, { .type = WMFW_ADSP2_XM, .base = 0x190000 }, { .type = WMFW_ADSP2_YM, .base = 0x1a8000 }, };
-static const struct wm_adsp_region wm5110_dsp2_regions[] = { +static const struct cs_dsp_region wm5110_dsp2_regions[] = { { .type = WMFW_ADSP2_PM, .base = 0x200000 }, { .type = WMFW_ADSP2_ZM, .base = 0x280000 }, { .type = WMFW_ADSP2_XM, .base = 0x290000 }, { .type = WMFW_ADSP2_YM, .base = 0x2a8000 }, };
-static const struct wm_adsp_region wm5110_dsp3_regions[] = { +static const struct cs_dsp_region wm5110_dsp3_regions[] = { { .type = WMFW_ADSP2_PM, .base = 0x300000 }, { .type = WMFW_ADSP2_ZM, .base = 0x380000 }, { .type = WMFW_ADSP2_XM, .base = 0x390000 }, { .type = WMFW_ADSP2_YM, .base = 0x3a8000 }, };
-static const struct wm_adsp_region wm5110_dsp4_regions[] = { +static const struct cs_dsp_region wm5110_dsp4_regions[] = { { .type = WMFW_ADSP2_PM, .base = 0x400000 }, { .type = WMFW_ADSP2_ZM, .base = 0x480000 }, { .type = WMFW_ADSP2_XM, .base = 0x490000 }, { .type = WMFW_ADSP2_YM, .base = 0x4a8000 }, };
-static const struct wm_adsp_region *wm5110_dsp_regions[] = { +static const struct cs_dsp_region *wm5110_dsp_regions[] = { wm5110_dsp1_regions, wm5110_dsp2_regions, wm5110_dsp3_regions, diff --git a/sound/soc/codecs/wm_adsp.c b/sound/soc/codecs/wm_adsp.c index c1b5ea3b5718..a039c137a3cb 100644 --- a/sound/soc/codecs/wm_adsp.c +++ b/sound/soc/codecs/wm_adsp.c @@ -214,15 +214,15 @@
#define ADSP_MAX_STD_CTRL_SIZE 512
-#define WM_ADSP_ACKED_CTL_TIMEOUT_MS 100 -#define WM_ADSP_ACKED_CTL_N_QUICKPOLLS 10 -#define WM_ADSP_ACKED_CTL_MIN_VALUE 0 -#define WM_ADSP_ACKED_CTL_MAX_VALUE 0xFFFFFF +#define CS_DSP_ACKED_CTL_TIMEOUT_MS 100 +#define CS_DSP_ACKED_CTL_N_QUICKPOLLS 10 +#define CS_DSP_ACKED_CTL_MIN_VALUE 0 +#define CS_DSP_ACKED_CTL_MAX_VALUE 0xFFFFFF
/* * Event control messages */ -#define WM_ADSP_FW_EVENT_SHUTDOWN 0x000001 +#define CS_DSP_FW_EVENT_SHUTDOWN 0x000001
/* * HALO system info @@ -304,19 +304,19 @@ #define HALO_MPU_VIO_ERR_SRC_MASK 0x00007fff #define HALO_MPU_VIO_ERR_SRC_SHIFT 0
-static const struct wm_adsp_ops wm_adsp1_ops; -static const struct wm_adsp_ops wm_adsp2_ops[]; -static const struct wm_adsp_ops wm_halo_ops; +static const struct cs_dsp_ops cs_dsp_adsp1_ops; +static const struct cs_dsp_ops cs_dsp_adsp2_ops[]; +static const struct cs_dsp_ops cs_dsp_halo_ops;
-struct wm_adsp_buf { +struct cs_dsp_buf { struct list_head list; void *buf; };
-static struct wm_adsp_buf *wm_adsp_buf_alloc(const void *src, size_t len, - struct list_head *list) +static struct cs_dsp_buf *cs_dsp_buf_alloc(const void *src, size_t len, + struct list_head *list) { - struct wm_adsp_buf *buf = kzalloc(sizeof(*buf), GFP_KERNEL); + struct cs_dsp_buf *buf = kzalloc(sizeof(*buf), GFP_KERNEL);
if (buf == NULL) return NULL; @@ -334,12 +334,12 @@ static struct wm_adsp_buf *wm_adsp_buf_alloc(const void *src, size_t len, return buf; }
-static void wm_adsp_buf_free(struct list_head *list) +static void cs_dsp_buf_free(struct list_head *list) { while (!list_empty(list)) { - struct wm_adsp_buf *buf = list_first_entry(list, - struct wm_adsp_buf, - list); + struct cs_dsp_buf *buf = list_first_entry(list, + struct cs_dsp_buf, + list); list_del(&buf->list); vfree(buf->buf); kfree(buf); @@ -470,12 +470,12 @@ struct wm_adsp_compr { const char *name; };
-#define WM_ADSP_DATA_WORD_SIZE 3 +#define CS_DSP_DATA_WORD_SIZE 3
#define WM_ADSP_MIN_FRAGMENTS 1 #define WM_ADSP_MAX_FRAGMENTS 256 -#define WM_ADSP_MIN_FRAGMENT_SIZE (64 * WM_ADSP_DATA_WORD_SIZE) -#define WM_ADSP_MAX_FRAGMENT_SIZE (4096 * WM_ADSP_DATA_WORD_SIZE) +#define WM_ADSP_MIN_FRAGMENT_SIZE (64 * CS_DSP_DATA_WORD_SIZE) +#define WM_ADSP_MAX_FRAGMENT_SIZE (4096 * CS_DSP_DATA_WORD_SIZE)
#define WM_ADSP_ALG_XM_STRUCT_MAGIC 0x49aec7
@@ -602,7 +602,7 @@ struct wm_coeff_ctl { /* Subname is needed to match with firmware */ const char *subname; unsigned int subname_len; - struct wm_adsp_alg_region alg_region; + struct cs_dsp_alg_region alg_region; struct wm_adsp *dsp; unsigned int enabled:1; struct list_head list; @@ -616,7 +616,7 @@ struct wm_coeff_ctl { struct work_struct work; };
-static const char *wm_adsp_mem_region_name(unsigned int type) +static const char *cs_dsp_mem_region_name(unsigned int type) { switch (type) { case WMFW_ADSP1_PM: @@ -641,7 +641,7 @@ static const char *wm_adsp_mem_region_name(unsigned int type) }
#ifdef CONFIG_DEBUG_FS -static void wm_adsp_debugfs_save_wmfwname(struct wm_adsp *dsp, const char *s) +static void cs_dsp_debugfs_save_wmfwname(struct wm_adsp *dsp, const char *s) { char *tmp = kasprintf(GFP_KERNEL, "%s\n", s);
@@ -649,7 +649,7 @@ static void wm_adsp_debugfs_save_wmfwname(struct wm_adsp *dsp, const char *s) dsp->wmfw_file_name = tmp; }
-static void wm_adsp_debugfs_save_binname(struct wm_adsp *dsp, const char *s) +static void cs_dsp_debugfs_save_binname(struct wm_adsp *dsp, const char *s) { char *tmp = kasprintf(GFP_KERNEL, "%s\n", s);
@@ -657,7 +657,7 @@ static void wm_adsp_debugfs_save_binname(struct wm_adsp *dsp, const char *s) dsp->bin_file_name = tmp; }
-static void wm_adsp_debugfs_clear(struct wm_adsp *dsp) +static void cs_dsp_debugfs_clear(struct wm_adsp *dsp) { kfree(dsp->wmfw_file_name); kfree(dsp->bin_file_name); @@ -665,9 +665,9 @@ static void wm_adsp_debugfs_clear(struct wm_adsp *dsp) dsp->bin_file_name = NULL; }
-static ssize_t wm_adsp_debugfs_wmfw_read(struct file *file, - char __user *user_buf, - size_t count, loff_t *ppos) +static ssize_t cs_dsp_debugfs_wmfw_read(struct file *file, + char __user *user_buf, + size_t count, loff_t *ppos) { struct wm_adsp *dsp = file->private_data; ssize_t ret; @@ -685,9 +685,9 @@ static ssize_t wm_adsp_debugfs_wmfw_read(struct file *file, return ret; }
-static ssize_t wm_adsp_debugfs_bin_read(struct file *file, - char __user *user_buf, - size_t count, loff_t *ppos) +static ssize_t cs_dsp_debugfs_bin_read(struct file *file, + char __user *user_buf, + size_t count, loff_t *ppos) { struct wm_adsp *dsp = file->private_data; ssize_t ret; @@ -708,25 +708,25 @@ static ssize_t wm_adsp_debugfs_bin_read(struct file *file, static const struct { const char *name; const struct file_operations fops; -} wm_adsp_debugfs_fops[] = { +} cs_dsp_debugfs_fops[] = { { .name = "wmfw_file_name", .fops = { .open = simple_open, - .read = wm_adsp_debugfs_wmfw_read, + .read = cs_dsp_debugfs_wmfw_read, }, }, { .name = "bin_file_name", .fops = { .open = simple_open, - .read = wm_adsp_debugfs_bin_read, + .read = cs_dsp_debugfs_bin_read, }, }, };
-static void wm_adsp2_init_debugfs(struct wm_adsp *dsp, - struct snd_soc_component *component) +static void cs_dsp_init_debugfs(struct wm_adsp *dsp, + struct snd_soc_component *component) { struct dentry *root = NULL; int i; @@ -738,40 +738,40 @@ static void wm_adsp2_init_debugfs(struct wm_adsp *dsp, debugfs_create_x32("fw_id", 0444, root, &dsp->fw_id); debugfs_create_x32("fw_version", 0444, root, &dsp->fw_id_version);
- for (i = 0; i < ARRAY_SIZE(wm_adsp_debugfs_fops); ++i) - debugfs_create_file(wm_adsp_debugfs_fops[i].name, 0444, root, - dsp, &wm_adsp_debugfs_fops[i].fops); + for (i = 0; i < ARRAY_SIZE(cs_dsp_debugfs_fops); ++i) + debugfs_create_file(cs_dsp_debugfs_fops[i].name, 0444, root, + dsp, &cs_dsp_debugfs_fops[i].fops);
dsp->debugfs_root = root; }
-static void wm_adsp2_cleanup_debugfs(struct wm_adsp *dsp) +static void cs_dsp_cleanup_debugfs(struct wm_adsp *dsp) { - wm_adsp_debugfs_clear(dsp); + cs_dsp_debugfs_clear(dsp); debugfs_remove_recursive(dsp->debugfs_root); dsp->debugfs_root = NULL; } #else -static inline void wm_adsp2_init_debugfs(struct wm_adsp *dsp, - struct snd_soc_component *component) +static inline void cs_dsp_init_debugfs(struct wm_adsp *dsp, + struct snd_soc_component *component) { }
-static inline void wm_adsp2_cleanup_debugfs(struct wm_adsp *dsp) +static inline void cs_dsp_cleanup_debugfs(struct wm_adsp *dsp) { }
-static inline void wm_adsp_debugfs_save_wmfwname(struct wm_adsp *dsp, +static inline void cs_dsp_debugfs_save_wmfwname(struct wm_adsp *dsp, const char *s) { }
-static inline void wm_adsp_debugfs_save_binname(struct wm_adsp *dsp, +static inline void cs_dsp_debugfs_save_binname(struct wm_adsp *dsp, const char *s) { }
-static inline void wm_adsp_debugfs_clear(struct wm_adsp *dsp) +static inline void cs_dsp_debugfs_clear(struct wm_adsp *dsp) { } #endif @@ -827,8 +827,8 @@ const struct soc_enum wm_adsp_fw_enum[] = { }; EXPORT_SYMBOL_GPL(wm_adsp_fw_enum);
-static const struct wm_adsp_region *wm_adsp_find_region(struct wm_adsp *dsp, - int type) +static const struct cs_dsp_region *cs_dsp_find_region(struct wm_adsp *dsp, + int type) { int i;
@@ -839,8 +839,8 @@ static const struct wm_adsp_region *wm_adsp_find_region(struct wm_adsp *dsp, return NULL; }
-static unsigned int wm_adsp_region_to_reg(struct wm_adsp_region const *mem, - unsigned int offset) +static unsigned int cs_dsp_region_to_reg(struct cs_dsp_region const *mem, + unsigned int offset) { switch (mem->type) { case WMFW_ADSP1_PM: @@ -856,8 +856,8 @@ static unsigned int wm_adsp_region_to_reg(struct wm_adsp_region const *mem, } }
-static unsigned int wm_halo_region_to_reg(struct wm_adsp_region const *mem, - unsigned int offset) +static unsigned int cs_dsp_halo_region_to_reg(struct cs_dsp_region const *mem, + unsigned int offset) { switch (mem->type) { case WMFW_ADSP2_XM: @@ -874,8 +874,8 @@ static unsigned int wm_halo_region_to_reg(struct wm_adsp_region const *mem, } }
-static void wm_adsp_read_fw_status(struct wm_adsp *dsp, - int noffs, unsigned int *offs) +static void cs_dsp_read_fw_status(struct wm_adsp *dsp, + int noffs, unsigned int *offs) { unsigned int i; int ret; @@ -889,36 +889,36 @@ static void wm_adsp_read_fw_status(struct wm_adsp *dsp, } }
-static void wm_adsp2_show_fw_status(struct wm_adsp *dsp) +static void cs_dsp_adsp2_show_fw_status(struct wm_adsp *dsp) { unsigned int offs[] = { ADSP2_SCRATCH0, ADSP2_SCRATCH1, ADSP2_SCRATCH2, ADSP2_SCRATCH3, };
- wm_adsp_read_fw_status(dsp, ARRAY_SIZE(offs), offs); + cs_dsp_read_fw_status(dsp, ARRAY_SIZE(offs), offs);
adsp_dbg(dsp, "FW SCRATCH 0:0x%x 1:0x%x 2:0x%x 3:0x%x\n", offs[0], offs[1], offs[2], offs[3]); }
-static void wm_adsp2v2_show_fw_status(struct wm_adsp *dsp) +static void cs_dsp_adsp2v2_show_fw_status(struct wm_adsp *dsp) { unsigned int offs[] = { ADSP2V2_SCRATCH0_1, ADSP2V2_SCRATCH2_3 };
- wm_adsp_read_fw_status(dsp, ARRAY_SIZE(offs), offs); + cs_dsp_read_fw_status(dsp, ARRAY_SIZE(offs), offs);
adsp_dbg(dsp, "FW SCRATCH 0:0x%x 1:0x%x 2:0x%x 3:0x%x\n", offs[0] & 0xFFFF, offs[0] >> 16, offs[1] & 0xFFFF, offs[1] >> 16); }
-static void wm_halo_show_fw_status(struct wm_adsp *dsp) +static void cs_dsp_halo_show_fw_status(struct wm_adsp *dsp) { unsigned int offs[] = { HALO_SCRATCH1, HALO_SCRATCH2, HALO_SCRATCH3, HALO_SCRATCH4, };
- wm_adsp_read_fw_status(dsp, ARRAY_SIZE(offs), offs); + cs_dsp_read_fw_status(dsp, ARRAY_SIZE(offs), offs);
adsp_dbg(dsp, "FW SCRATCH 0:0x%x 1:0x%x 2:0x%x 3:0x%x\n", offs[0], offs[1], offs[2], offs[3]); @@ -929,13 +929,13 @@ static inline struct wm_coeff_ctl *bytes_ext_to_ctl(struct soc_bytes_ext *ext) return container_of(ext, struct wm_coeff_ctl, bytes_ext); }
-static int wm_coeff_base_reg(struct wm_coeff_ctl *ctl, unsigned int *reg) +static int cs_dsp_coeff_base_reg(struct wm_coeff_ctl *ctl, unsigned int *reg) { - const struct wm_adsp_alg_region *alg_region = &ctl->alg_region; + const struct cs_dsp_alg_region *alg_region = &ctl->alg_region; struct wm_adsp *dsp = ctl->dsp; - const struct wm_adsp_region *mem; + const struct cs_dsp_region *mem;
- mem = wm_adsp_find_region(dsp, alg_region->type); + mem = cs_dsp_find_region(dsp, alg_region->type); if (!mem) { adsp_err(dsp, "No base for region %x\n", alg_region->type); @@ -957,8 +957,8 @@ static int wm_coeff_info(struct snd_kcontrol *kctl, switch (ctl->type) { case WMFW_CTL_TYPE_ACKED: uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; - uinfo->value.integer.min = WM_ADSP_ACKED_CTL_MIN_VALUE; - uinfo->value.integer.max = WM_ADSP_ACKED_CTL_MAX_VALUE; + uinfo->value.integer.min = CS_DSP_ACKED_CTL_MIN_VALUE; + uinfo->value.integer.max = CS_DSP_ACKED_CTL_MAX_VALUE; uinfo->value.integer.step = 1; uinfo->count = 1; break; @@ -971,21 +971,21 @@ static int wm_coeff_info(struct snd_kcontrol *kctl, return 0; }
-static int wm_coeff_write_acked_control(struct wm_coeff_ctl *ctl, - unsigned int event_id) +static int cs_dsp_coeff_write_acked_control(struct wm_coeff_ctl *ctl, + unsigned int event_id) { struct wm_adsp *dsp = ctl->dsp; __be32 val = cpu_to_be32(event_id); unsigned int reg; int i, ret;
- ret = wm_coeff_base_reg(ctl, ®); + ret = cs_dsp_coeff_base_reg(ctl, ®); if (ret) return ret;
adsp_dbg(dsp, "Sending 0x%x to acked control alg 0x%x %s:0x%x\n", event_id, ctl->alg_region.alg, - wm_adsp_mem_region_name(ctl->alg_region.type), ctl->offset); + cs_dsp_mem_region_name(ctl->alg_region.type), ctl->offset);
ret = regmap_raw_write(dsp->regmap, reg, &val, sizeof(val)); if (ret) { @@ -999,9 +999,9 @@ static int wm_coeff_write_acked_control(struct wm_coeff_ctl *ctl, * to ack instantly so we do the first 1ms delay before reading the * control to avoid a pointless bus transaction */ - for (i = 0; i < WM_ADSP_ACKED_CTL_TIMEOUT_MS;) { + for (i = 0; i < CS_DSP_ACKED_CTL_TIMEOUT_MS;) { switch (i) { - case 0 ... WM_ADSP_ACKED_CTL_N_QUICKPOLLS - 1: + case 0 ... CS_DSP_ACKED_CTL_N_QUICKPOLLS - 1: usleep_range(1000, 2000); i++; break; @@ -1025,21 +1025,21 @@ static int wm_coeff_write_acked_control(struct wm_coeff_ctl *ctl,
adsp_warn(dsp, "Acked control @0x%x alg:0x%x %s:0x%x timed out\n", reg, ctl->alg_region.alg, - wm_adsp_mem_region_name(ctl->alg_region.type), + cs_dsp_mem_region_name(ctl->alg_region.type), ctl->offset);
return -ETIMEDOUT; }
-static int wm_coeff_write_ctrl_raw(struct wm_coeff_ctl *ctl, - const void *buf, size_t len) +static int cs_dsp_coeff_write_ctrl_raw(struct wm_coeff_ctl *ctl, + const void *buf, size_t len) { struct wm_adsp *dsp = ctl->dsp; void *scratch; int ret; unsigned int reg;
- ret = wm_coeff_base_reg(ctl, ®); + ret = cs_dsp_coeff_base_reg(ctl, ®); if (ret) return ret;
@@ -1062,8 +1062,8 @@ static int wm_coeff_write_ctrl_raw(struct wm_coeff_ctl *ctl, return 0; }
-static int wm_coeff_write_ctrl(struct wm_coeff_ctl *ctl, - const void *buf, size_t len) +static int cs_dsp_coeff_write_ctrl(struct wm_coeff_ctl *ctl, + const void *buf, size_t len) { int ret = 0;
@@ -1074,7 +1074,7 @@ static int wm_coeff_write_ctrl(struct wm_coeff_ctl *ctl,
ctl->set = 1; if (ctl->enabled && ctl->dsp->running) - ret = wm_coeff_write_ctrl_raw(ctl, buf, len); + ret = cs_dsp_coeff_write_ctrl_raw(ctl, buf, len);
return ret; } @@ -1089,7 +1089,7 @@ static int wm_coeff_put(struct snd_kcontrol *kctl, int ret = 0;
mutex_lock(&ctl->dsp->pwr_lock); - ret = wm_coeff_write_ctrl(ctl, p, ctl->len); + ret = cs_dsp_coeff_write_ctrl(ctl, p, ctl->len); mutex_unlock(&ctl->dsp->pwr_lock);
return ret; @@ -1108,7 +1108,7 @@ static int wm_coeff_tlv_put(struct snd_kcontrol *kctl, if (copy_from_user(ctl->cache, bytes, size)) ret = -EFAULT; else - ret = wm_coeff_write_ctrl(ctl, ctl->cache, size); + ret = cs_dsp_coeff_write_ctrl(ctl, ctl->cache, size);
mutex_unlock(&ctl->dsp->pwr_lock);
@@ -1130,7 +1130,7 @@ static int wm_coeff_put_acked(struct snd_kcontrol *kctl, mutex_lock(&ctl->dsp->pwr_lock);
if (ctl->enabled && ctl->dsp->running) - ret = wm_coeff_write_acked_control(ctl, val); + ret = cs_dsp_coeff_write_acked_control(ctl, val); else ret = -EPERM;
@@ -1139,15 +1139,15 @@ static int wm_coeff_put_acked(struct snd_kcontrol *kctl, return ret; }
-static int wm_coeff_read_ctrl_raw(struct wm_coeff_ctl *ctl, - void *buf, size_t len) +static int cs_dsp_coeff_read_ctrl_raw(struct wm_coeff_ctl *ctl, + void *buf, size_t len) { struct wm_adsp *dsp = ctl->dsp; void *scratch; int ret; unsigned int reg;
- ret = wm_coeff_base_reg(ctl, ®); + ret = cs_dsp_coeff_base_reg(ctl, ®); if (ret) return ret;
@@ -1170,18 +1170,18 @@ static int wm_coeff_read_ctrl_raw(struct wm_coeff_ctl *ctl, return 0; }
-static int wm_coeff_read_ctrl(struct wm_coeff_ctl *ctl, void *buf, size_t len) +static int cs_dsp_coeff_read_ctrl(struct wm_coeff_ctl *ctl, void *buf, size_t len) { int ret = 0;
if (ctl->flags & WMFW_CTL_FLAG_VOLATILE) { if (ctl->enabled && ctl->dsp->running) - return wm_coeff_read_ctrl_raw(ctl, buf, len); + return cs_dsp_coeff_read_ctrl_raw(ctl, buf, len); else return -EPERM; } else { if (!ctl->flags && ctl->enabled && ctl->dsp->running) - ret = wm_coeff_read_ctrl_raw(ctl, ctl->cache, ctl->len); + ret = cs_dsp_coeff_read_ctrl_raw(ctl, ctl->cache, ctl->len);
if (buf != ctl->cache) memcpy(buf, ctl->cache, len); @@ -1200,7 +1200,7 @@ static int wm_coeff_get(struct snd_kcontrol *kctl, int ret;
mutex_lock(&ctl->dsp->pwr_lock); - ret = wm_coeff_read_ctrl(ctl, p, ctl->len); + ret = cs_dsp_coeff_read_ctrl(ctl, p, ctl->len); mutex_unlock(&ctl->dsp->pwr_lock);
return ret; @@ -1216,7 +1216,7 @@ static int wm_coeff_tlv_get(struct snd_kcontrol *kctl,
mutex_lock(&ctl->dsp->pwr_lock);
- ret = wm_coeff_read_ctrl(ctl, ctl->cache, size); + ret = cs_dsp_coeff_read_ctrl(ctl, ctl->cache, size);
if (!ret && copy_to_user(bytes, ctl->cache, size)) ret = -EFAULT; @@ -1321,7 +1321,7 @@ static int wmfw_add_ctl(struct wm_adsp *dsp, struct wm_coeff_ctl *ctl) return ret; }
-static int wm_coeff_init_control_caches(struct wm_adsp *dsp) +static int cs_dsp_coeff_init_control_caches(struct wm_adsp *dsp) { struct wm_coeff_ctl *ctl; int ret; @@ -1338,7 +1338,7 @@ static int wm_coeff_init_control_caches(struct wm_adsp *dsp) * created so we don't need to do anything. */ if (!ctl->flags || (ctl->flags & WMFW_CTL_FLAG_READABLE)) { - ret = wm_coeff_read_ctrl_raw(ctl, ctl->cache, ctl->len); + ret = cs_dsp_coeff_read_ctrl_raw(ctl, ctl->cache, ctl->len); if (ret < 0) return ret; } @@ -1347,7 +1347,7 @@ static int wm_coeff_init_control_caches(struct wm_adsp *dsp) return 0; }
-static int wm_coeff_sync_controls(struct wm_adsp *dsp) +static int cs_dsp_coeff_sync_controls(struct wm_adsp *dsp) { struct wm_coeff_ctl *ctl; int ret; @@ -1356,8 +1356,8 @@ static int wm_coeff_sync_controls(struct wm_adsp *dsp) if (!ctl->enabled) continue; if (ctl->set && !(ctl->flags & WMFW_CTL_FLAG_VOLATILE)) { - ret = wm_coeff_write_ctrl_raw(ctl, ctl->cache, - ctl->len); + ret = cs_dsp_coeff_write_ctrl_raw(ctl, ctl->cache, + ctl->len); if (ret < 0) return ret; } @@ -1366,7 +1366,7 @@ static int wm_coeff_sync_controls(struct wm_adsp *dsp) return 0; }
-static void wm_adsp_signal_event_controls(struct wm_adsp *dsp, +static void cs_dsp_signal_event_controls(struct wm_adsp *dsp, unsigned int event) { struct wm_coeff_ctl *ctl; @@ -1379,7 +1379,7 @@ static void wm_adsp_signal_event_controls(struct wm_adsp *dsp, if (!ctl->enabled) continue;
- ret = wm_coeff_write_acked_control(ctl, event); + ret = cs_dsp_coeff_write_acked_control(ctl, event); if (ret) adsp_warn(dsp, "Failed to send 0x%x event to alg 0x%x (%d)\n", @@ -1396,7 +1396,7 @@ static void wm_adsp_ctl_work(struct work_struct *work) wmfw_add_ctl(ctl->dsp, ctl); }
-static void wm_adsp_free_ctl_blk(struct wm_coeff_ctl *ctl) +static void cs_dsp_free_ctl_blk(struct wm_coeff_ctl *ctl) { cancel_work_sync(&ctl->work);
@@ -1406,11 +1406,11 @@ static void wm_adsp_free_ctl_blk(struct wm_coeff_ctl *ctl) kfree(ctl); }
-static int wm_adsp_create_control(struct wm_adsp *dsp, - const struct wm_adsp_alg_region *alg_region, - unsigned int offset, unsigned int len, - const char *subname, unsigned int subname_len, - unsigned int flags, unsigned int type) +static int cs_dsp_create_control(struct wm_adsp *dsp, + const struct cs_dsp_alg_region *alg_region, + unsigned int offset, unsigned int len, + const char *subname, unsigned int subname_len, + unsigned int flags, unsigned int type) { struct wm_coeff_ctl *ctl; char name[SNDRV_CTL_ELEM_ID_NAME_MAXLEN]; @@ -1430,7 +1430,7 @@ static int wm_adsp_create_control(struct wm_adsp *dsp, } }
- region_name = wm_adsp_mem_region_name(alg_region->type); + region_name = cs_dsp_mem_region_name(alg_region->type); if (!region_name) { adsp_err(dsp, "Unknown region type: %d\n", alg_region->type); return -EINVAL; @@ -1523,14 +1523,14 @@ static int wm_adsp_create_control(struct wm_adsp *dsp, return ret; }
-struct wm_coeff_parsed_alg { +struct cs_dsp_coeff_parsed_alg { int id; const u8 *name; int name_len; int ncoeff; };
-struct wm_coeff_parsed_coeff { +struct cs_dsp_coeff_parsed_coeff { int offset; int mem_type; const u8 *name; @@ -1540,7 +1540,7 @@ struct wm_coeff_parsed_coeff { int len; };
-static int wm_coeff_parse_string(int bytes, const u8 **pos, const u8 **str) +static int cs_dsp_coeff_parse_string(int bytes, const u8 **pos, const u8 **str) { int length;
@@ -1563,7 +1563,7 @@ static int wm_coeff_parse_string(int bytes, const u8 **pos, const u8 **str) return length; }
-static int wm_coeff_parse_int(int bytes, const u8 **pos) +static int cs_dsp_coeff_parse_int(int bytes, const u8 **pos) { int val = 0;
@@ -1583,8 +1583,8 @@ static int wm_coeff_parse_int(int bytes, const u8 **pos) return val; }
-static inline void wm_coeff_parse_alg(struct wm_adsp *dsp, const u8 **data, - struct wm_coeff_parsed_alg *blk) +static inline void cs_dsp_coeff_parse_alg(struct wm_adsp *dsp, const u8 **data, + struct cs_dsp_coeff_parsed_alg *blk) { const struct wmfw_adsp_alg_data *raw;
@@ -1600,11 +1600,11 @@ static inline void wm_coeff_parse_alg(struct wm_adsp *dsp, const u8 **data, blk->ncoeff = le32_to_cpu(raw->ncoeff); break; default: - blk->id = wm_coeff_parse_int(sizeof(raw->id), data); - blk->name_len = wm_coeff_parse_string(sizeof(u8), data, - &blk->name); - wm_coeff_parse_string(sizeof(u16), data, NULL); - blk->ncoeff = wm_coeff_parse_int(sizeof(raw->ncoeff), data); + blk->id = cs_dsp_coeff_parse_int(sizeof(raw->id), data); + blk->name_len = cs_dsp_coeff_parse_string(sizeof(u8), data, + &blk->name); + cs_dsp_coeff_parse_string(sizeof(u16), data, NULL); + blk->ncoeff = cs_dsp_coeff_parse_int(sizeof(raw->ncoeff), data); break; }
@@ -1613,8 +1613,8 @@ static inline void wm_coeff_parse_alg(struct wm_adsp *dsp, const u8 **data, adsp_dbg(dsp, "# of coefficient descriptors: %#x\n", blk->ncoeff); }
-static inline void wm_coeff_parse_coeff(struct wm_adsp *dsp, const u8 **data, - struct wm_coeff_parsed_coeff *blk) +static inline void cs_dsp_coeff_parse_coeff(struct wm_adsp *dsp, const u8 **data, + struct cs_dsp_coeff_parsed_coeff *blk) { const struct wmfw_adsp_coeff_data *raw; const u8 *tmp; @@ -1636,16 +1636,16 @@ static inline void wm_coeff_parse_coeff(struct wm_adsp *dsp, const u8 **data, break; default: tmp = *data; - blk->offset = wm_coeff_parse_int(sizeof(raw->hdr.offset), &tmp); - blk->mem_type = wm_coeff_parse_int(sizeof(raw->hdr.type), &tmp); - length = wm_coeff_parse_int(sizeof(raw->hdr.size), &tmp); - blk->name_len = wm_coeff_parse_string(sizeof(u8), &tmp, - &blk->name); - wm_coeff_parse_string(sizeof(u8), &tmp, NULL); - wm_coeff_parse_string(sizeof(u16), &tmp, NULL); - blk->ctl_type = wm_coeff_parse_int(sizeof(raw->ctl_type), &tmp); - blk->flags = wm_coeff_parse_int(sizeof(raw->flags), &tmp); - blk->len = wm_coeff_parse_int(sizeof(raw->len), &tmp); + blk->offset = cs_dsp_coeff_parse_int(sizeof(raw->hdr.offset), &tmp); + blk->mem_type = cs_dsp_coeff_parse_int(sizeof(raw->hdr.type), &tmp); + length = cs_dsp_coeff_parse_int(sizeof(raw->hdr.size), &tmp); + blk->name_len = cs_dsp_coeff_parse_string(sizeof(u8), &tmp, + &blk->name); + cs_dsp_coeff_parse_string(sizeof(u8), &tmp, NULL); + cs_dsp_coeff_parse_string(sizeof(u16), &tmp, NULL); + blk->ctl_type = cs_dsp_coeff_parse_int(sizeof(raw->ctl_type), &tmp); + blk->flags = cs_dsp_coeff_parse_int(sizeof(raw->flags), &tmp); + blk->len = cs_dsp_coeff_parse_int(sizeof(raw->len), &tmp);
*data = *data + sizeof(raw->hdr) + length; break; @@ -1659,10 +1659,10 @@ static inline void wm_coeff_parse_coeff(struct wm_adsp *dsp, const u8 **data, adsp_dbg(dsp, "\tALSA control len: %#x\n", blk->len); }
-static int wm_adsp_check_coeff_flags(struct wm_adsp *dsp, - const struct wm_coeff_parsed_coeff *coeff_blk, - unsigned int f_required, - unsigned int f_illegal) +static int cs_dsp_check_coeff_flags(struct wm_adsp *dsp, + const struct cs_dsp_coeff_parsed_coeff *coeff_blk, + unsigned int f_required, + unsigned int f_illegal) { if ((coeff_blk->flags & f_illegal) || ((coeff_blk->flags & f_required) != f_required)) { @@ -1674,18 +1674,18 @@ static int wm_adsp_check_coeff_flags(struct wm_adsp *dsp, return 0; }
-static int wm_adsp_parse_coeff(struct wm_adsp *dsp, - const struct wmfw_region *region) +static int cs_dsp_parse_coeff(struct wm_adsp *dsp, + const struct wmfw_region *region) { - struct wm_adsp_alg_region alg_region = {}; - struct wm_coeff_parsed_alg alg_blk; - struct wm_coeff_parsed_coeff coeff_blk; + struct cs_dsp_alg_region alg_region = {}; + struct cs_dsp_coeff_parsed_alg alg_blk; + struct cs_dsp_coeff_parsed_coeff coeff_blk; const u8 *data = region->data; int i, ret;
- wm_coeff_parse_alg(dsp, &data, &alg_blk); + cs_dsp_coeff_parse_alg(dsp, &data, &alg_blk); for (i = 0; i < alg_blk.ncoeff; i++) { - wm_coeff_parse_coeff(dsp, &data, &coeff_blk); + cs_dsp_coeff_parse_coeff(dsp, &data, &coeff_blk);
switch (coeff_blk.ctl_type) { case WMFW_CTL_TYPE_BYTES: @@ -1694,30 +1694,30 @@ static int wm_adsp_parse_coeff(struct wm_adsp *dsp, if (coeff_blk.flags & WMFW_CTL_FLAG_SYS) continue; /* ignore */
- ret = wm_adsp_check_coeff_flags(dsp, &coeff_blk, - WMFW_CTL_FLAG_VOLATILE | - WMFW_CTL_FLAG_WRITEABLE | - WMFW_CTL_FLAG_READABLE, - 0); + ret = cs_dsp_check_coeff_flags(dsp, &coeff_blk, + WMFW_CTL_FLAG_VOLATILE | + WMFW_CTL_FLAG_WRITEABLE | + WMFW_CTL_FLAG_READABLE, + 0); if (ret) return -EINVAL; break; case WMFW_CTL_TYPE_HOSTEVENT: - ret = wm_adsp_check_coeff_flags(dsp, &coeff_blk, - WMFW_CTL_FLAG_SYS | - WMFW_CTL_FLAG_VOLATILE | - WMFW_CTL_FLAG_WRITEABLE | - WMFW_CTL_FLAG_READABLE, - 0); + ret = cs_dsp_check_coeff_flags(dsp, &coeff_blk, + WMFW_CTL_FLAG_SYS | + WMFW_CTL_FLAG_VOLATILE | + WMFW_CTL_FLAG_WRITEABLE | + WMFW_CTL_FLAG_READABLE, + 0); if (ret) return -EINVAL; break; case WMFW_CTL_TYPE_HOST_BUFFER: - ret = wm_adsp_check_coeff_flags(dsp, &coeff_blk, - WMFW_CTL_FLAG_SYS | - WMFW_CTL_FLAG_VOLATILE | - WMFW_CTL_FLAG_READABLE, - 0); + ret = cs_dsp_check_coeff_flags(dsp, &coeff_blk, + WMFW_CTL_FLAG_SYS | + WMFW_CTL_FLAG_VOLATILE | + WMFW_CTL_FLAG_READABLE, + 0); if (ret) return -EINVAL; break; @@ -1730,13 +1730,13 @@ static int wm_adsp_parse_coeff(struct wm_adsp *dsp, alg_region.type = coeff_blk.mem_type; alg_region.alg = alg_blk.id;
- ret = wm_adsp_create_control(dsp, &alg_region, - coeff_blk.offset, - coeff_blk.len, - coeff_blk.name, - coeff_blk.name_len, - coeff_blk.flags, - coeff_blk.ctl_type); + ret = cs_dsp_create_control(dsp, &alg_region, + coeff_blk.offset, + coeff_blk.len, + coeff_blk.name, + coeff_blk.name_len, + coeff_blk.flags, + coeff_blk.ctl_type); if (ret < 0) adsp_err(dsp, "Failed to create control: %.*s, %d\n", coeff_blk.name_len, coeff_blk.name, ret); @@ -1745,10 +1745,10 @@ static int wm_adsp_parse_coeff(struct wm_adsp *dsp, return 0; }
-static unsigned int wm_adsp1_parse_sizes(struct wm_adsp *dsp, - const char * const file, - unsigned int pos, - const struct firmware *firmware) +static unsigned int cs_dsp_adsp1_parse_sizes(struct wm_adsp *dsp, + const char * const file, + unsigned int pos, + const struct firmware *firmware) { const struct wmfw_adsp1_sizes *adsp1_sizes;
@@ -1761,10 +1761,10 @@ static unsigned int wm_adsp1_parse_sizes(struct wm_adsp *dsp, return pos + sizeof(*adsp1_sizes); }
-static unsigned int wm_adsp2_parse_sizes(struct wm_adsp *dsp, - const char * const file, - unsigned int pos, - const struct firmware *firmware) +static unsigned int cs_dsp_adsp2_parse_sizes(struct wm_adsp *dsp, + const char * const file, + unsigned int pos, + const struct firmware *firmware) { const struct wmfw_adsp2_sizes *adsp2_sizes;
@@ -1777,7 +1777,7 @@ static unsigned int wm_adsp2_parse_sizes(struct wm_adsp *dsp, return pos + sizeof(*adsp2_sizes); }
-static bool wm_adsp_validate_version(struct wm_adsp *dsp, unsigned int version) +static bool cs_dsp_validate_version(struct wm_adsp *dsp, unsigned int version) { switch (version) { case 0: @@ -1791,7 +1791,7 @@ static bool wm_adsp_validate_version(struct wm_adsp *dsp, unsigned int version) } }
-static bool wm_halo_validate_version(struct wm_adsp *dsp, unsigned int version) +static bool cs_dsp_halo_validate_version(struct wm_adsp *dsp, unsigned int version) { switch (version) { case 3: @@ -1801,7 +1801,7 @@ static bool wm_halo_validate_version(struct wm_adsp *dsp, unsigned int version) } }
-static int wm_adsp_load(struct wm_adsp *dsp) +static int cs_dsp_load(struct wm_adsp *dsp) { LIST_HEAD(buf_list); const struct firmware *firmware; @@ -1811,10 +1811,10 @@ static int wm_adsp_load(struct wm_adsp *dsp) const struct wmfw_adsp1_sizes *adsp1_sizes; const struct wmfw_footer *footer; const struct wmfw_region *region; - const struct wm_adsp_region *mem; + const struct cs_dsp_region *mem; const char *region_name; char *file, *text = NULL; - struct wm_adsp_buf *buf; + struct cs_dsp_buf *buf; unsigned int reg; int regions = 0; int ret, offset, type; @@ -1895,7 +1895,7 @@ static int wm_adsp_load(struct wm_adsp *dsp) break; case WMFW_ALGORITHM_DATA: region_name = "Algorithm"; - ret = wm_adsp_parse_coeff(dsp, region); + ret = cs_dsp_parse_coeff(dsp, region); if (ret != 0) goto out_fw; break; @@ -1916,14 +1916,14 @@ static int wm_adsp_load(struct wm_adsp *dsp) case WMFW_HALO_PM_PACKED: case WMFW_HALO_XM_PACKED: case WMFW_HALO_YM_PACKED: - mem = wm_adsp_find_region(dsp, type); + mem = cs_dsp_find_region(dsp, type); if (!mem) { adsp_err(dsp, "No region of type: %x\n", type); ret = -EINVAL; goto out_fw; }
- region_name = wm_adsp_mem_region_name(type); + region_name = cs_dsp_mem_region_name(type); reg = dsp->ops->region_to_reg(mem, offset); break; default: @@ -1955,9 +1955,9 @@ static int wm_adsp_load(struct wm_adsp *dsp) }
if (reg) { - buf = wm_adsp_buf_alloc(region->data, - le32_to_cpu(region->len), - &buf_list); + buf = cs_dsp_buf_alloc(region->data, + le32_to_cpu(region->len), + &buf_list); if (!buf) { adsp_err(dsp, "Out of memory\n"); ret = -ENOMEM; @@ -1990,11 +1990,11 @@ static int wm_adsp_load(struct wm_adsp *dsp) adsp_warn(dsp, "%s.%d: %zu bytes at end of file\n", file, regions, pos - firmware->size);
- wm_adsp_debugfs_save_wmfwname(dsp, file); + cs_dsp_debugfs_save_wmfwname(dsp, file);
out_fw: regmap_async_complete(regmap); - wm_adsp_buf_free(&buf_list); + cs_dsp_buf_free(&buf_list); release_firmware(firmware); kfree(text); out: @@ -2007,9 +2007,9 @@ static int wm_adsp_load(struct wm_adsp *dsp) * Find wm_coeff_ctl with input name as its subname * If not found, return NULL */ -static struct wm_coeff_ctl *wm_adsp_get_ctl(struct wm_adsp *dsp, - const char *name, int type, - unsigned int alg) +static struct wm_coeff_ctl *cs_dsp_get_ctl(struct wm_adsp *dsp, + const char *name, int type, + unsigned int alg) { struct wm_coeff_ctl *pos, *rslt = NULL; const char *fw_txt = wm_adsp_fw_text[dsp->fw]; @@ -2037,14 +2037,14 @@ int wm_adsp_write_ctl(struct wm_adsp *dsp, const char *name, int type, char ctl_name[SNDRV_CTL_ELEM_ID_NAME_MAXLEN]; int ret;
- ctl = wm_adsp_get_ctl(dsp, name, type, alg); + ctl = cs_dsp_get_ctl(dsp, name, type, alg); if (!ctl) return -EINVAL;
if (len > ctl->len) return -EINVAL;
- ret = wm_coeff_write_ctrl(ctl, buf, len); + ret = cs_dsp_coeff_write_ctrl(ctl, buf, len); if (ret) return ret;
@@ -2076,19 +2076,19 @@ int wm_adsp_read_ctl(struct wm_adsp *dsp, const char *name, int type, { struct wm_coeff_ctl *ctl;
- ctl = wm_adsp_get_ctl(dsp, name, type, alg); + ctl = cs_dsp_get_ctl(dsp, name, type, alg); if (!ctl) return -EINVAL;
if (len > ctl->len) return -EINVAL;
- return wm_coeff_read_ctrl(ctl, buf, len); + return cs_dsp_coeff_read_ctrl(ctl, buf, len); } EXPORT_SYMBOL_GPL(wm_adsp_read_ctl);
-static void wm_adsp_ctl_fixup_base(struct wm_adsp *dsp, - const struct wm_adsp_alg_region *alg_region) +static void cs_dsp_ctl_fixup_base(struct wm_adsp *dsp, + const struct cs_dsp_alg_region *alg_region) { struct wm_coeff_ctl *ctl;
@@ -2101,9 +2101,9 @@ static void wm_adsp_ctl_fixup_base(struct wm_adsp *dsp, } }
-static void *wm_adsp_read_algs(struct wm_adsp *dsp, size_t n_algs, - const struct wm_adsp_region *mem, - unsigned int pos, unsigned int len) +static void *cs_dsp_read_algs(struct wm_adsp *dsp, size_t n_algs, + const struct cs_dsp_region *mem, + unsigned int pos, unsigned int len) { void *alg; unsigned int reg; @@ -2153,10 +2153,10 @@ static void *wm_adsp_read_algs(struct wm_adsp *dsp, size_t n_algs, return alg; }
-static struct wm_adsp_alg_region * - wm_adsp_find_alg_region(struct wm_adsp *dsp, int type, unsigned int id) +static struct cs_dsp_alg_region * + cs_dsp_find_alg_region(struct wm_adsp *dsp, int type, unsigned int id) { - struct wm_adsp_alg_region *alg_region; + struct cs_dsp_alg_region *alg_region;
list_for_each_entry(alg_region, &dsp->alg_regions, list) { if (id == alg_region->alg && type == alg_region->type) @@ -2166,11 +2166,11 @@ static struct wm_adsp_alg_region * return NULL; }
-static struct wm_adsp_alg_region *wm_adsp_create_region(struct wm_adsp *dsp, - int type, __be32 id, - __be32 base) +static struct cs_dsp_alg_region *cs_dsp_create_region(struct wm_adsp *dsp, + int type, __be32 id, + __be32 base) { - struct wm_adsp_alg_region *alg_region; + struct cs_dsp_alg_region *alg_region;
alg_region = kzalloc(sizeof(*alg_region), GFP_KERNEL); if (!alg_region) @@ -2183,26 +2183,26 @@ static struct wm_adsp_alg_region *wm_adsp_create_region(struct wm_adsp *dsp, list_add_tail(&alg_region->list, &dsp->alg_regions);
if (dsp->fw_ver > 0) - wm_adsp_ctl_fixup_base(dsp, alg_region); + cs_dsp_ctl_fixup_base(dsp, alg_region);
return alg_region; }
-static void wm_adsp_free_alg_regions(struct wm_adsp *dsp) +static void cs_dsp_free_alg_regions(struct wm_adsp *dsp) { - struct wm_adsp_alg_region *alg_region; + struct cs_dsp_alg_region *alg_region;
while (!list_empty(&dsp->alg_regions)) { alg_region = list_first_entry(&dsp->alg_regions, - struct wm_adsp_alg_region, + struct cs_dsp_alg_region, list); list_del(&alg_region->list); kfree(alg_region); } }
-static void wmfw_parse_id_header(struct wm_adsp *dsp, - struct wmfw_id_hdr *fw, int nalgs) +static void cs_dsp_parse_wmfw_id_header(struct wm_adsp *dsp, + struct wmfw_id_hdr *fw, int nalgs) { dsp->fw_id = be32_to_cpu(fw->id); dsp->fw_id_version = be32_to_cpu(fw->ver); @@ -2213,8 +2213,8 @@ static void wmfw_parse_id_header(struct wm_adsp *dsp, nalgs); }
-static void wmfw_v3_parse_id_header(struct wm_adsp *dsp, - struct wmfw_v3_id_hdr *fw, int nalgs) +static void cs_dsp_parse_wmfw_v3_id_header(struct wm_adsp *dsp, + struct wmfw_v3_id_hdr *fw, int nalgs) { dsp->fw_id = be32_to_cpu(fw->id); dsp->fw_id_version = be32_to_cpu(fw->ver); @@ -2227,14 +2227,14 @@ static void wmfw_v3_parse_id_header(struct wm_adsp *dsp, nalgs); }
-static int wm_adsp_create_regions(struct wm_adsp *dsp, __be32 id, int nregions, - const int *type, __be32 *base) +static int cs_dsp_create_regions(struct wm_adsp *dsp, __be32 id, int nregions, + const int *type, __be32 *base) { - struct wm_adsp_alg_region *alg_region; + struct cs_dsp_alg_region *alg_region; int i;
for (i = 0; i < nregions; i++) { - alg_region = wm_adsp_create_region(dsp, type[i], id, base[i]); + alg_region = cs_dsp_create_region(dsp, type[i], id, base[i]); if (IS_ERR(alg_region)) return PTR_ERR(alg_region); } @@ -2242,17 +2242,17 @@ static int wm_adsp_create_regions(struct wm_adsp *dsp, __be32 id, int nregions, return 0; }
-static int wm_adsp1_setup_algs(struct wm_adsp *dsp) +static int cs_dsp_adsp1_setup_algs(struct wm_adsp *dsp) { struct wmfw_adsp1_id_hdr adsp1_id; struct wmfw_adsp1_alg_hdr *adsp1_alg; - struct wm_adsp_alg_region *alg_region; - const struct wm_adsp_region *mem; + struct cs_dsp_alg_region *alg_region; + const struct cs_dsp_region *mem; unsigned int pos, len; size_t n_algs; int i, ret;
- mem = wm_adsp_find_region(dsp, WMFW_ADSP1_DM); + mem = cs_dsp_find_region(dsp, WMFW_ADSP1_DM); if (WARN_ON(!mem)) return -EINVAL;
@@ -2266,15 +2266,15 @@ static int wm_adsp1_setup_algs(struct wm_adsp *dsp)
n_algs = be32_to_cpu(adsp1_id.n_algs);
- wmfw_parse_id_header(dsp, &adsp1_id.fw, n_algs); + cs_dsp_parse_wmfw_id_header(dsp, &adsp1_id.fw, n_algs);
- alg_region = wm_adsp_create_region(dsp, WMFW_ADSP1_ZM, - adsp1_id.fw.id, adsp1_id.zm); + alg_region = cs_dsp_create_region(dsp, WMFW_ADSP1_ZM, + adsp1_id.fw.id, adsp1_id.zm); if (IS_ERR(alg_region)) return PTR_ERR(alg_region);
- alg_region = wm_adsp_create_region(dsp, WMFW_ADSP1_DM, - adsp1_id.fw.id, adsp1_id.dm); + alg_region = cs_dsp_create_region(dsp, WMFW_ADSP1_DM, + adsp1_id.fw.id, adsp1_id.dm); if (IS_ERR(alg_region)) return PTR_ERR(alg_region);
@@ -2282,7 +2282,7 @@ static int wm_adsp1_setup_algs(struct wm_adsp *dsp) pos = sizeof(adsp1_id) / sizeof(u32); len = (sizeof(*adsp1_alg) * n_algs) / sizeof(u32);
- adsp1_alg = wm_adsp_read_algs(dsp, n_algs, mem, pos, len); + adsp1_alg = cs_dsp_read_algs(dsp, n_algs, mem, pos, len); if (IS_ERR(adsp1_alg)) return PTR_ERR(adsp1_alg);
@@ -2295,9 +2295,9 @@ static int wm_adsp1_setup_algs(struct wm_adsp *dsp) be32_to_cpu(adsp1_alg[i].dm), be32_to_cpu(adsp1_alg[i].zm));
- alg_region = wm_adsp_create_region(dsp, WMFW_ADSP1_DM, - adsp1_alg[i].alg.id, - adsp1_alg[i].dm); + alg_region = cs_dsp_create_region(dsp, WMFW_ADSP1_DM, + adsp1_alg[i].alg.id, + adsp1_alg[i].dm); if (IS_ERR(alg_region)) { ret = PTR_ERR(alg_region); goto out; @@ -2307,18 +2307,18 @@ static int wm_adsp1_setup_algs(struct wm_adsp *dsp) len = be32_to_cpu(adsp1_alg[i + 1].dm); len -= be32_to_cpu(adsp1_alg[i].dm); len *= 4; - wm_adsp_create_control(dsp, alg_region, 0, - len, NULL, 0, 0, - WMFW_CTL_TYPE_BYTES); + cs_dsp_create_control(dsp, alg_region, 0, + len, NULL, 0, 0, + WMFW_CTL_TYPE_BYTES); } else { adsp_warn(dsp, "Missing length info for region DM with ID %x\n", be32_to_cpu(adsp1_alg[i].alg.id)); } }
- alg_region = wm_adsp_create_region(dsp, WMFW_ADSP1_ZM, - adsp1_alg[i].alg.id, - adsp1_alg[i].zm); + alg_region = cs_dsp_create_region(dsp, WMFW_ADSP1_ZM, + adsp1_alg[i].alg.id, + adsp1_alg[i].zm); if (IS_ERR(alg_region)) { ret = PTR_ERR(alg_region); goto out; @@ -2328,9 +2328,9 @@ static int wm_adsp1_setup_algs(struct wm_adsp *dsp) len = be32_to_cpu(adsp1_alg[i + 1].zm); len -= be32_to_cpu(adsp1_alg[i].zm); len *= 4; - wm_adsp_create_control(dsp, alg_region, 0, - len, NULL, 0, 0, - WMFW_CTL_TYPE_BYTES); + cs_dsp_create_control(dsp, alg_region, 0, + len, NULL, 0, 0, + WMFW_CTL_TYPE_BYTES); } else { adsp_warn(dsp, "Missing length info for region ZM with ID %x\n", be32_to_cpu(adsp1_alg[i].alg.id)); @@ -2343,17 +2343,17 @@ static int wm_adsp1_setup_algs(struct wm_adsp *dsp) return ret; }
-static int wm_adsp2_setup_algs(struct wm_adsp *dsp) +static int cs_dsp_adsp2_setup_algs(struct wm_adsp *dsp) { struct wmfw_adsp2_id_hdr adsp2_id; struct wmfw_adsp2_alg_hdr *adsp2_alg; - struct wm_adsp_alg_region *alg_region; - const struct wm_adsp_region *mem; + struct cs_dsp_alg_region *alg_region; + const struct cs_dsp_region *mem; unsigned int pos, len; size_t n_algs; int i, ret;
- mem = wm_adsp_find_region(dsp, WMFW_ADSP2_XM); + mem = cs_dsp_find_region(dsp, WMFW_ADSP2_XM); if (WARN_ON(!mem)) return -EINVAL;
@@ -2367,20 +2367,20 @@ static int wm_adsp2_setup_algs(struct wm_adsp *dsp)
n_algs = be32_to_cpu(adsp2_id.n_algs);
- wmfw_parse_id_header(dsp, &adsp2_id.fw, n_algs); + cs_dsp_parse_wmfw_id_header(dsp, &adsp2_id.fw, n_algs);
- alg_region = wm_adsp_create_region(dsp, WMFW_ADSP2_XM, - adsp2_id.fw.id, adsp2_id.xm); + alg_region = cs_dsp_create_region(dsp, WMFW_ADSP2_XM, + adsp2_id.fw.id, adsp2_id.xm); if (IS_ERR(alg_region)) return PTR_ERR(alg_region);
- alg_region = wm_adsp_create_region(dsp, WMFW_ADSP2_YM, - adsp2_id.fw.id, adsp2_id.ym); + alg_region = cs_dsp_create_region(dsp, WMFW_ADSP2_YM, + adsp2_id.fw.id, adsp2_id.ym); if (IS_ERR(alg_region)) return PTR_ERR(alg_region);
- alg_region = wm_adsp_create_region(dsp, WMFW_ADSP2_ZM, - adsp2_id.fw.id, adsp2_id.zm); + alg_region = cs_dsp_create_region(dsp, WMFW_ADSP2_ZM, + adsp2_id.fw.id, adsp2_id.zm); if (IS_ERR(alg_region)) return PTR_ERR(alg_region);
@@ -2388,7 +2388,7 @@ static int wm_adsp2_setup_algs(struct wm_adsp *dsp) pos = sizeof(adsp2_id) / sizeof(u32); len = (sizeof(*adsp2_alg) * n_algs) / sizeof(u32);
- adsp2_alg = wm_adsp_read_algs(dsp, n_algs, mem, pos, len); + adsp2_alg = cs_dsp_read_algs(dsp, n_algs, mem, pos, len); if (IS_ERR(adsp2_alg)) return PTR_ERR(adsp2_alg);
@@ -2403,9 +2403,9 @@ static int wm_adsp2_setup_algs(struct wm_adsp *dsp) be32_to_cpu(adsp2_alg[i].ym), be32_to_cpu(adsp2_alg[i].zm));
- alg_region = wm_adsp_create_region(dsp, WMFW_ADSP2_XM, - adsp2_alg[i].alg.id, - adsp2_alg[i].xm); + alg_region = cs_dsp_create_region(dsp, WMFW_ADSP2_XM, + adsp2_alg[i].alg.id, + adsp2_alg[i].xm); if (IS_ERR(alg_region)) { ret = PTR_ERR(alg_region); goto out; @@ -2415,18 +2415,18 @@ static int wm_adsp2_setup_algs(struct wm_adsp *dsp) len = be32_to_cpu(adsp2_alg[i + 1].xm); len -= be32_to_cpu(adsp2_alg[i].xm); len *= 4; - wm_adsp_create_control(dsp, alg_region, 0, - len, NULL, 0, 0, - WMFW_CTL_TYPE_BYTES); + cs_dsp_create_control(dsp, alg_region, 0, + len, NULL, 0, 0, + WMFW_CTL_TYPE_BYTES); } else { adsp_warn(dsp, "Missing length info for region XM with ID %x\n", be32_to_cpu(adsp2_alg[i].alg.id)); } }
- alg_region = wm_adsp_create_region(dsp, WMFW_ADSP2_YM, - adsp2_alg[i].alg.id, - adsp2_alg[i].ym); + alg_region = cs_dsp_create_region(dsp, WMFW_ADSP2_YM, + adsp2_alg[i].alg.id, + adsp2_alg[i].ym); if (IS_ERR(alg_region)) { ret = PTR_ERR(alg_region); goto out; @@ -2436,18 +2436,18 @@ static int wm_adsp2_setup_algs(struct wm_adsp *dsp) len = be32_to_cpu(adsp2_alg[i + 1].ym); len -= be32_to_cpu(adsp2_alg[i].ym); len *= 4; - wm_adsp_create_control(dsp, alg_region, 0, - len, NULL, 0, 0, - WMFW_CTL_TYPE_BYTES); + cs_dsp_create_control(dsp, alg_region, 0, + len, NULL, 0, 0, + WMFW_CTL_TYPE_BYTES); } else { adsp_warn(dsp, "Missing length info for region YM with ID %x\n", be32_to_cpu(adsp2_alg[i].alg.id)); } }
- alg_region = wm_adsp_create_region(dsp, WMFW_ADSP2_ZM, - adsp2_alg[i].alg.id, - adsp2_alg[i].zm); + alg_region = cs_dsp_create_region(dsp, WMFW_ADSP2_ZM, + adsp2_alg[i].alg.id, + adsp2_alg[i].zm); if (IS_ERR(alg_region)) { ret = PTR_ERR(alg_region); goto out; @@ -2457,9 +2457,9 @@ static int wm_adsp2_setup_algs(struct wm_adsp *dsp) len = be32_to_cpu(adsp2_alg[i + 1].zm); len -= be32_to_cpu(adsp2_alg[i].zm); len *= 4; - wm_adsp_create_control(dsp, alg_region, 0, - len, NULL, 0, 0, - WMFW_CTL_TYPE_BYTES); + cs_dsp_create_control(dsp, alg_region, 0, + len, NULL, 0, 0, + WMFW_CTL_TYPE_BYTES); } else { adsp_warn(dsp, "Missing length info for region ZM with ID %x\n", be32_to_cpu(adsp2_alg[i].alg.id)); @@ -2472,8 +2472,8 @@ static int wm_adsp2_setup_algs(struct wm_adsp *dsp) return ret; }
-static int wm_halo_create_regions(struct wm_adsp *dsp, __be32 id, - __be32 xm_base, __be32 ym_base) +static int cs_dsp_halo_create_regions(struct wm_adsp *dsp, __be32 id, + __be32 xm_base, __be32 ym_base) { static const int types[] = { WMFW_ADSP2_XM, WMFW_HALO_XM_PACKED, @@ -2481,19 +2481,19 @@ static int wm_halo_create_regions(struct wm_adsp *dsp, __be32 id, }; __be32 bases[] = { xm_base, xm_base, ym_base, ym_base };
- return wm_adsp_create_regions(dsp, id, ARRAY_SIZE(types), types, bases); + return cs_dsp_create_regions(dsp, id, ARRAY_SIZE(types), types, bases); }
-static int wm_halo_setup_algs(struct wm_adsp *dsp) +static int cs_dsp_halo_setup_algs(struct wm_adsp *dsp) { struct wmfw_halo_id_hdr halo_id; struct wmfw_halo_alg_hdr *halo_alg; - const struct wm_adsp_region *mem; + const struct cs_dsp_region *mem; unsigned int pos, len; size_t n_algs; int i, ret;
- mem = wm_adsp_find_region(dsp, WMFW_ADSP2_XM); + mem = cs_dsp_find_region(dsp, WMFW_ADSP2_XM); if (WARN_ON(!mem)) return -EINVAL;
@@ -2507,10 +2507,10 @@ static int wm_halo_setup_algs(struct wm_adsp *dsp)
n_algs = be32_to_cpu(halo_id.n_algs);
- wmfw_v3_parse_id_header(dsp, &halo_id.fw, n_algs); + cs_dsp_parse_wmfw_v3_id_header(dsp, &halo_id.fw, n_algs);
- ret = wm_halo_create_regions(dsp, halo_id.fw.id, - halo_id.xm_base, halo_id.ym_base); + ret = cs_dsp_halo_create_regions(dsp, halo_id.fw.id, + halo_id.xm_base, halo_id.ym_base); if (ret) return ret;
@@ -2518,7 +2518,7 @@ static int wm_halo_setup_algs(struct wm_adsp *dsp) pos = sizeof(halo_id) / sizeof(u32); len = (sizeof(*halo_alg) * n_algs) / sizeof(u32);
- halo_alg = wm_adsp_read_algs(dsp, n_algs, mem, pos, len); + halo_alg = cs_dsp_read_algs(dsp, n_algs, mem, pos, len); if (IS_ERR(halo_alg)) return PTR_ERR(halo_alg);
@@ -2532,9 +2532,9 @@ static int wm_halo_setup_algs(struct wm_adsp *dsp) be32_to_cpu(halo_alg[i].xm_base), be32_to_cpu(halo_alg[i].ym_base));
- ret = wm_halo_create_regions(dsp, halo_alg[i].alg.id, - halo_alg[i].xm_base, - halo_alg[i].ym_base); + ret = cs_dsp_halo_create_regions(dsp, halo_alg[i].alg.id, + halo_alg[i].xm_base, + halo_alg[i].ym_base); if (ret) goto out; } @@ -2544,19 +2544,19 @@ static int wm_halo_setup_algs(struct wm_adsp *dsp) return ret; }
-static int wm_adsp_load_coeff(struct wm_adsp *dsp) +static int cs_dsp_load_coeff(struct wm_adsp *dsp) { LIST_HEAD(buf_list); struct regmap *regmap = dsp->regmap; struct wmfw_coeff_hdr *hdr; struct wmfw_coeff_item *blk; const struct firmware *firmware; - const struct wm_adsp_region *mem; - struct wm_adsp_alg_region *alg_region; + const struct cs_dsp_region *mem; + struct cs_dsp_alg_region *alg_region; const char *region_name; int ret, pos, blocks, type, offset, reg; char *file; - struct wm_adsp_buf *buf; + struct cs_dsp_buf *buf;
file = kzalloc(PAGE_SIZE, GFP_KERNEL); if (file == NULL) @@ -2634,7 +2634,7 @@ static int wm_adsp_load_coeff(struct wm_adsp *dsp) if (le32_to_cpu(blk->id) == dsp->fw_id && offset == 0) { region_name = "global coefficients"; - mem = wm_adsp_find_region(dsp, type); + mem = cs_dsp_find_region(dsp, type); if (!mem) { adsp_err(dsp, "No ZM\n"); break; @@ -2658,14 +2658,14 @@ static int wm_adsp_load_coeff(struct wm_adsp *dsp) file, blocks, le32_to_cpu(blk->len), type, le32_to_cpu(blk->id));
- mem = wm_adsp_find_region(dsp, type); + mem = cs_dsp_find_region(dsp, type); if (!mem) { adsp_err(dsp, "No base for region %x\n", type); break; }
- alg_region = wm_adsp_find_alg_region(dsp, type, - le32_to_cpu(blk->id)); + alg_region = cs_dsp_find_alg_region(dsp, type, + le32_to_cpu(blk->id)); if (alg_region) { reg = alg_region->base; reg = dsp->ops->region_to_reg(mem, reg); @@ -2694,9 +2694,9 @@ static int wm_adsp_load_coeff(struct wm_adsp *dsp) goto out_fw; }
- buf = wm_adsp_buf_alloc(blk->data, - le32_to_cpu(blk->len), - &buf_list); + buf = cs_dsp_buf_alloc(blk->data, + le32_to_cpu(blk->len), + &buf_list); if (!buf) { adsp_err(dsp, "Out of memory\n"); ret = -ENOMEM; @@ -2727,18 +2727,18 @@ static int wm_adsp_load_coeff(struct wm_adsp *dsp) adsp_warn(dsp, "%s.%d: %zu bytes at end of file\n", file, blocks, pos - firmware->size);
- wm_adsp_debugfs_save_binname(dsp, file); + cs_dsp_debugfs_save_binname(dsp, file);
out_fw: regmap_async_complete(regmap); release_firmware(firmware); - wm_adsp_buf_free(&buf_list); + cs_dsp_buf_free(&buf_list); out: kfree(file); return ret; }
-static int wm_adsp_create_name(struct wm_adsp *dsp) +static int cs_dsp_create_name(struct wm_adsp *dsp) { char *p;
@@ -2766,7 +2766,7 @@ static int wm_adsp_common_init(struct wm_adsp *dsp) { int ret;
- ret = wm_adsp_create_name(dsp); + ret = cs_dsp_create_name(dsp); if (ret) return ret;
@@ -2782,7 +2782,7 @@ static int wm_adsp_common_init(struct wm_adsp *dsp)
int wm_adsp1_init(struct wm_adsp *dsp) { - dsp->ops = &wm_adsp1_ops; + dsp->ops = &cs_dsp_adsp1_ops;
return wm_adsp_common_init(dsp); } @@ -2832,25 +2832,25 @@ int wm_adsp1_event(struct snd_soc_dapm_widget *w, } }
- ret = wm_adsp_load(dsp); + ret = cs_dsp_load(dsp); if (ret != 0) goto err_ena;
- ret = wm_adsp1_setup_algs(dsp); + ret = cs_dsp_adsp1_setup_algs(dsp); if (ret != 0) goto err_ena;
- ret = wm_adsp_load_coeff(dsp); + ret = cs_dsp_load_coeff(dsp); if (ret != 0) goto err_ena;
/* Initialize caches for enabled and unset controls */ - ret = wm_coeff_init_control_caches(dsp); + ret = cs_dsp_coeff_init_control_caches(dsp); if (ret != 0) goto err_ena;
/* Sync set controls */ - ret = wm_coeff_sync_controls(dsp); + ret = cs_dsp_coeff_sync_controls(dsp); if (ret != 0) goto err_ena;
@@ -2882,7 +2882,7 @@ int wm_adsp1_event(struct snd_soc_dapm_widget *w, ctl->enabled = 0;
- wm_adsp_free_alg_regions(dsp); + cs_dsp_free_alg_regions(dsp); break;
default: @@ -2903,7 +2903,7 @@ int wm_adsp1_event(struct snd_soc_dapm_widget *w, } EXPORT_SYMBOL_GPL(wm_adsp1_event);
-static int wm_adsp2v2_enable_core(struct wm_adsp *dsp) +static int cs_dsp_adsp2v2_enable_core(struct wm_adsp *dsp) { unsigned int val; int ret, count; @@ -2930,7 +2930,7 @@ static int wm_adsp2v2_enable_core(struct wm_adsp *dsp) return 0; }
-static int wm_adsp2_enable_core(struct wm_adsp *dsp) +static int cs_dsp_adsp2_enable_core(struct wm_adsp *dsp) { int ret;
@@ -2939,18 +2939,18 @@ static int wm_adsp2_enable_core(struct wm_adsp *dsp) if (ret != 0) return ret;
- return wm_adsp2v2_enable_core(dsp); + return cs_dsp_adsp2v2_enable_core(dsp); }
-static int wm_adsp2_lock(struct wm_adsp *dsp, unsigned int lock_regions) +static int cs_dsp_adsp2_lock(struct wm_adsp *dsp, unsigned int lock_regions) { struct regmap *regmap = dsp->regmap; unsigned int code0, code1, lock_reg;
- if (!(lock_regions & WM_ADSP2_REGION_ALL)) + if (!(lock_regions & CS_ADSP2_REGION_ALL)) return 0;
- lock_regions &= WM_ADSP2_REGION_ALL; + lock_regions &= CS_ADSP2_REGION_ALL; lock_reg = dsp->base + ADSP2_LOCK_REGION_1_LOCK_REGION_0;
while (lock_regions) { @@ -2972,19 +2972,19 @@ static int wm_adsp2_lock(struct wm_adsp *dsp, unsigned int lock_regions) return 0; }
-static int wm_adsp2_enable_memory(struct wm_adsp *dsp) +static int cs_dsp_adsp2_enable_memory(struct wm_adsp *dsp) { return regmap_update_bits(dsp->regmap, dsp->base + ADSP2_CONTROL, ADSP2_MEM_ENA, ADSP2_MEM_ENA); }
-static void wm_adsp2_disable_memory(struct wm_adsp *dsp) +static void cs_dsp_adsp2_disable_memory(struct wm_adsp *dsp) { regmap_update_bits(dsp->regmap, dsp->base + ADSP2_CONTROL, ADSP2_MEM_ENA, 0); }
-static void wm_adsp2_disable_core(struct wm_adsp *dsp) +static void cs_dsp_adsp2_disable_core(struct wm_adsp *dsp) { regmap_write(dsp->regmap, dsp->base + ADSP2_RDMA_CONFIG_1, 0); regmap_write(dsp->regmap, dsp->base + ADSP2_WDMA_CONFIG_1, 0); @@ -2994,7 +2994,7 @@ static void wm_adsp2_disable_core(struct wm_adsp *dsp) ADSP2_SYS_ENA, 0); }
-static void wm_adsp2v2_disable_core(struct wm_adsp *dsp) +static void cs_dsp_adsp2v2_disable_core(struct wm_adsp *dsp) { regmap_write(dsp->regmap, dsp->base + ADSP2_RDMA_CONFIG_1, 0); regmap_write(dsp->regmap, dsp->base + ADSP2_WDMA_CONFIG_1, 0); @@ -3022,7 +3022,7 @@ static void wm_adsp_boot_work(struct work_struct *work) goto err_mem; }
- ret = wm_adsp_load(dsp); + ret = cs_dsp_load(dsp); if (ret != 0) goto err_ena;
@@ -3030,12 +3030,12 @@ static void wm_adsp_boot_work(struct work_struct *work) if (ret != 0) goto err_ena;
- ret = wm_adsp_load_coeff(dsp); + ret = cs_dsp_load_coeff(dsp); if (ret != 0) goto err_ena;
/* Initialize caches for enabled and unset controls */ - ret = wm_coeff_init_control_caches(dsp); + ret = cs_dsp_coeff_init_control_caches(dsp); if (ret != 0) goto err_ena;
@@ -3058,7 +3058,7 @@ static void wm_adsp_boot_work(struct work_struct *work) mutex_unlock(&dsp->pwr_lock); }
-static int wm_halo_configure_mpu(struct wm_adsp *dsp, unsigned int lock_regions) +static int cs_dsp_halo_configure_mpu(struct wm_adsp *dsp, unsigned int lock_regions) { struct reg_sequence config[] = { { dsp->base + HALO_MPU_LOCK_CONFIG, 0x5555 }, @@ -3149,13 +3149,13 @@ int wm_adsp2_preloader_put(struct snd_kcontrol *kcontrol, } EXPORT_SYMBOL_GPL(wm_adsp2_preloader_put);
-static void wm_adsp_stop_watchdog(struct wm_adsp *dsp) +static void cs_dsp_stop_watchdog(struct wm_adsp *dsp) { regmap_update_bits(dsp->regmap, dsp->base + ADSP2_WATCHDOG, ADSP2_WDT_ENA_MASK, 0); }
-static void wm_halo_stop_watchdog(struct wm_adsp *dsp) +static void cs_dsp_halo_stop_watchdog(struct wm_adsp *dsp) { regmap_update_bits(dsp->regmap, dsp->base + HALO_WDT_CONTROL, HALO_WDT_EN_MASK, 0); @@ -3176,7 +3176,7 @@ int wm_adsp_early_event(struct snd_soc_dapm_widget *w, case SND_SOC_DAPM_PRE_PMD: mutex_lock(&dsp->pwr_lock);
- wm_adsp_debugfs_clear(dsp); + cs_dsp_debugfs_clear(dsp);
dsp->fw_id = 0; dsp->fw_id_version = 0; @@ -3189,7 +3189,7 @@ int wm_adsp_early_event(struct snd_soc_dapm_widget *w, list_for_each_entry(ctl, &dsp->ctl_list, list) ctl->enabled = 0;
- wm_adsp_free_alg_regions(dsp); + cs_dsp_free_alg_regions(dsp);
mutex_unlock(&dsp->pwr_lock);
@@ -3203,14 +3203,14 @@ int wm_adsp_early_event(struct snd_soc_dapm_widget *w, } EXPORT_SYMBOL_GPL(wm_adsp_early_event);
-static int wm_adsp2_start_core(struct wm_adsp *dsp) +static int cs_dsp_adsp2_start_core(struct wm_adsp *dsp) { return regmap_update_bits(dsp->regmap, dsp->base + ADSP2_CONTROL, ADSP2_CORE_ENA | ADSP2_START, ADSP2_CORE_ENA | ADSP2_START); }
-static void wm_adsp2_stop_core(struct wm_adsp *dsp) +static void cs_dsp_adsp2_stop_core(struct wm_adsp *dsp) { regmap_update_bits(dsp->regmap, dsp->base + ADSP2_CONTROL, ADSP2_CORE_ENA | ADSP2_START, 0); @@ -3242,7 +3242,7 @@ int wm_adsp_event(struct snd_soc_dapm_widget *w, }
/* Sync set controls */ - ret = wm_coeff_sync_controls(dsp); + ret = cs_dsp_coeff_sync_controls(dsp); if (ret != 0) goto err;
@@ -3274,7 +3274,7 @@ int wm_adsp_event(struct snd_soc_dapm_widget *w,
case SND_SOC_DAPM_PRE_PMD: /* Tell the firmware to cleanup */ - wm_adsp_signal_event_controls(dsp, WM_ADSP_FW_EVENT_SHUTDOWN); + cs_dsp_signal_event_controls(dsp, CS_DSP_FW_EVENT_SHUTDOWN);
if (dsp->ops->stop_watchdog) dsp->ops->stop_watchdog(dsp); @@ -3317,7 +3317,7 @@ int wm_adsp_event(struct snd_soc_dapm_widget *w, } EXPORT_SYMBOL_GPL(wm_adsp_event);
-static int wm_halo_start_core(struct wm_adsp *dsp) +static int cs_dsp_halo_start_core(struct wm_adsp *dsp) { return regmap_update_bits(dsp->regmap, dsp->base + HALO_CCM_CORE_CONTROL, @@ -3325,7 +3325,7 @@ static int wm_halo_start_core(struct wm_adsp *dsp) HALO_CORE_RESET | HALO_CORE_EN); }
-static void wm_halo_stop_core(struct wm_adsp *dsp) +static void cs_dsp_halo_stop_core(struct wm_adsp *dsp) { regmap_update_bits(dsp->regmap, dsp->base + HALO_CCM_CORE_CONTROL, HALO_CORE_EN, 0); @@ -3342,7 +3342,7 @@ int wm_adsp2_component_probe(struct wm_adsp *dsp, struct snd_soc_component *comp snprintf(preload, ARRAY_SIZE(preload), "%s Preload", dsp->name); snd_soc_component_disable_pin(component, preload);
- wm_adsp2_init_debugfs(dsp, component); + cs_dsp_init_debugfs(dsp, component);
dsp->component = component;
@@ -3352,7 +3352,7 @@ EXPORT_SYMBOL_GPL(wm_adsp2_component_probe);
int wm_adsp2_component_remove(struct wm_adsp *dsp, struct snd_soc_component *component) { - wm_adsp2_cleanup_debugfs(dsp); + cs_dsp_cleanup_debugfs(dsp);
return 0; } @@ -3380,13 +3380,13 @@ int wm_adsp2_init(struct wm_adsp *dsp) return ret; }
- dsp->ops = &wm_adsp2_ops[0]; + dsp->ops = &cs_dsp_adsp2_ops[0]; break; case 1: - dsp->ops = &wm_adsp2_ops[1]; + dsp->ops = &cs_dsp_adsp2_ops[1]; break; default: - dsp->ops = &wm_adsp2_ops[2]; + dsp->ops = &cs_dsp_adsp2_ops[2]; break; }
@@ -3404,7 +3404,7 @@ int wm_halo_init(struct wm_adsp *dsp) if (ret) return ret;
- dsp->ops = &wm_halo_ops; + dsp->ops = &cs_dsp_halo_ops;
INIT_WORK(&dsp->boot_work, wm_adsp_boot_work);
@@ -3420,7 +3420,7 @@ void wm_adsp2_remove(struct wm_adsp *dsp) ctl = list_first_entry(&dsp->ctl_list, struct wm_coeff_ctl, list); list_del(&ctl->list); - wm_adsp_free_ctl_blk(ctl); + cs_dsp_free_ctl_blk(ctl); } } EXPORT_SYMBOL_GPL(wm_adsp2_remove); @@ -3553,7 +3553,7 @@ static int wm_adsp_compr_check_params(struct snd_compr_stream *stream, params->buffer.fragment_size > WM_ADSP_MAX_FRAGMENT_SIZE || params->buffer.fragments < WM_ADSP_MIN_FRAGMENTS || params->buffer.fragments > WM_ADSP_MAX_FRAGMENTS || - params->buffer.fragment_size % WM_ADSP_DATA_WORD_SIZE) { + params->buffer.fragment_size % CS_DSP_DATA_WORD_SIZE) { compr_err(compr, "Invalid buffer fragsize=%d fragments=%d\n", params->buffer.fragment_size, params->buffer.fragments); @@ -3592,7 +3592,7 @@ static int wm_adsp_compr_check_params(struct snd_compr_stream *stream,
static inline unsigned int wm_adsp_compr_frag_words(struct wm_adsp_compr *compr) { - return compr->size.fragment_size / WM_ADSP_DATA_WORD_SIZE; + return compr->size.fragment_size / CS_DSP_DATA_WORD_SIZE; }
int wm_adsp_compr_set_params(struct snd_soc_component *component, @@ -3648,11 +3648,11 @@ int wm_adsp_compr_get_caps(struct snd_soc_component *component, } EXPORT_SYMBOL_GPL(wm_adsp_compr_get_caps);
-static int wm_adsp_read_raw_data_block(struct wm_adsp *dsp, int mem_type, - unsigned int mem_addr, - unsigned int num_words, __be32 *data) +static int cs_dsp_read_raw_data_block(struct wm_adsp *dsp, int mem_type, + unsigned int mem_addr, + unsigned int num_words, __be32 *data) { - struct wm_adsp_region const *mem = wm_adsp_find_region(dsp, mem_type); + struct cs_dsp_region const *mem = cs_dsp_find_region(dsp, mem_type); unsigned int reg; int ret;
@@ -3669,13 +3669,13 @@ static int wm_adsp_read_raw_data_block(struct wm_adsp *dsp, int mem_type, return 0; }
-static inline int wm_adsp_read_data_word(struct wm_adsp *dsp, int mem_type, - unsigned int mem_addr, u32 *data) +static inline int cs_dsp_read_data_word(struct wm_adsp *dsp, int mem_type, + unsigned int mem_addr, u32 *data) { __be32 raw; int ret;
- ret = wm_adsp_read_raw_data_block(dsp, mem_type, mem_addr, 1, &raw); + ret = cs_dsp_read_raw_data_block(dsp, mem_type, mem_addr, 1, &raw); if (ret < 0) return ret;
@@ -3684,10 +3684,10 @@ static inline int wm_adsp_read_data_word(struct wm_adsp *dsp, int mem_type, return 0; }
-static int wm_adsp_write_data_word(struct wm_adsp *dsp, int mem_type, - unsigned int mem_addr, u32 data) +static int cs_dsp_write_data_word(struct wm_adsp *dsp, int mem_type, + unsigned int mem_addr, u32 data) { - struct wm_adsp_region const *mem = wm_adsp_find_region(dsp, mem_type); + struct cs_dsp_region const *mem = cs_dsp_find_region(dsp, mem_type); __be32 val = cpu_to_be32(data & 0x00ffffffu); unsigned int reg;
@@ -3702,18 +3702,18 @@ static int wm_adsp_write_data_word(struct wm_adsp *dsp, int mem_type, static inline int wm_adsp_buffer_read(struct wm_adsp_compr_buf *buf, unsigned int field_offset, u32 *data) { - return wm_adsp_read_data_word(buf->dsp, buf->host_buf_mem_type, - buf->host_buf_ptr + field_offset, data); + return cs_dsp_read_data_word(buf->dsp, buf->host_buf_mem_type, + buf->host_buf_ptr + field_offset, data); }
static inline int wm_adsp_buffer_write(struct wm_adsp_compr_buf *buf, unsigned int field_offset, u32 data) { - return wm_adsp_write_data_word(buf->dsp, buf->host_buf_mem_type, - buf->host_buf_ptr + field_offset, data); + return cs_dsp_write_data_word(buf->dsp, buf->host_buf_mem_type, + buf->host_buf_ptr + field_offset, data); }
-static void wm_adsp_remove_padding(u32 *buf, int nwords) +static void cs_dsp_remove_padding(u32 *buf, int nwords) { const __be32 *pack_in = (__be32 *)buf; u8 *pack_out = (u8 *)buf; @@ -3797,12 +3797,12 @@ static struct wm_adsp_compr_buf *wm_adsp_buffer_alloc(struct wm_adsp *dsp)
static int wm_adsp_buffer_parse_legacy(struct wm_adsp *dsp) { - struct wm_adsp_alg_region *alg_region; + struct cs_dsp_alg_region *alg_region; struct wm_adsp_compr_buf *buf; u32 xmalg, addr, magic; int i, ret;
- alg_region = wm_adsp_find_alg_region(dsp, WMFW_ADSP2_XM, dsp->fw_id); + alg_region = cs_dsp_find_alg_region(dsp, WMFW_ADSP2_XM, dsp->fw_id); if (!alg_region) { adsp_err(dsp, "No algorithm region found\n"); return -EINVAL; @@ -3815,7 +3815,7 @@ static int wm_adsp_buffer_parse_legacy(struct wm_adsp *dsp) xmalg = dsp->ops->sys_config_size / sizeof(__be32);
addr = alg_region->base + xmalg + ALG_XM_FIELD(magic); - ret = wm_adsp_read_data_word(dsp, WMFW_ADSP2_XM, addr, &magic); + ret = cs_dsp_read_data_word(dsp, WMFW_ADSP2_XM, addr, &magic); if (ret < 0) return ret;
@@ -3824,8 +3824,8 @@ static int wm_adsp_buffer_parse_legacy(struct wm_adsp *dsp)
addr = alg_region->base + xmalg + ALG_XM_FIELD(host_buf_ptr); for (i = 0; i < 5; ++i) { - ret = wm_adsp_read_data_word(dsp, WMFW_ADSP2_XM, addr, - &buf->host_buf_ptr); + ret = cs_dsp_read_data_word(dsp, WMFW_ADSP2_XM, addr, + &buf->host_buf_ptr); if (ret < 0) return ret;
@@ -3857,7 +3857,7 @@ static int wm_adsp_buffer_parse_coeff(struct wm_coeff_ctl *ctl) int ret, i;
for (i = 0; i < 5; ++i) { - ret = wm_coeff_read_ctrl(ctl, &coeff_v1, sizeof(coeff_v1)); + ret = cs_dsp_coeff_read_ctrl(ctl, &coeff_v1, sizeof(coeff_v1)); if (ret < 0) return ret;
@@ -3902,7 +3902,7 @@ static int wm_adsp_buffer_parse_coeff(struct wm_coeff_ctl *ctl) return -EINVAL; }
- wm_adsp_remove_padding((u32 *)&coeff_v1.name, ARRAY_SIZE(coeff_v1.name)); + cs_dsp_remove_padding((u32 *)&coeff_v1.name, ARRAY_SIZE(coeff_v1.name));
buf->name = kasprintf(GFP_KERNEL, "%s-dsp-%s", ctl->dsp->part, (char *)&coeff_v1.name); @@ -4078,7 +4078,7 @@ static int wm_adsp_buffer_update_avail(struct wm_adsp_compr_buf *buf) avail += wm_adsp_buffer_size(buf);
compr_dbg(buf, "readindex=0x%x, writeindex=0x%x, avail=%d\n", - buf->read_index, write_index, avail * WM_ADSP_DATA_WORD_SIZE); + buf->read_index, write_index, avail * CS_DSP_DATA_WORD_SIZE);
buf->avail = avail;
@@ -4199,7 +4199,7 @@ int wm_adsp_compr_pointer(struct snd_soc_component *component, }
tstamp->copied_total = compr->copied_total; - tstamp->copied_total += buf->avail * WM_ADSP_DATA_WORD_SIZE; + tstamp->copied_total += buf->avail * CS_DSP_DATA_WORD_SIZE; tstamp->sampling_rate = compr->sample_rate;
out: @@ -4241,12 +4241,12 @@ static int wm_adsp_buffer_capture_block(struct wm_adsp_compr *compr, int target) return 0;
/* Read data from DSP */ - ret = wm_adsp_read_raw_data_block(buf->dsp, mem_type, adsp_addr, - nwords, (__be32 *)compr->raw_buf); + ret = cs_dsp_read_raw_data_block(buf->dsp, mem_type, adsp_addr, + nwords, (__be32 *)compr->raw_buf); if (ret < 0) return ret;
- wm_adsp_remove_padding(compr->raw_buf, nwords); + cs_dsp_remove_padding(compr->raw_buf, nwords);
/* update read index to account for words read */ buf->read_index += nwords; @@ -4278,7 +4278,7 @@ static int wm_adsp_compr_read(struct wm_adsp_compr *compr, return -EIO; }
- count /= WM_ADSP_DATA_WORD_SIZE; + count /= CS_DSP_DATA_WORD_SIZE;
do { nwords = wm_adsp_buffer_capture_block(compr, count); @@ -4288,7 +4288,7 @@ static int wm_adsp_compr_read(struct wm_adsp_compr *compr, return nwords; }
- nbytes = nwords * WM_ADSP_DATA_WORD_SIZE; + nbytes = nwords * CS_DSP_DATA_WORD_SIZE;
compr_dbg(compr, "Read %d bytes\n", nbytes);
@@ -4479,87 +4479,87 @@ irqreturn_t wm_halo_wdt_expire(int irq, void *data) } EXPORT_SYMBOL_GPL(wm_halo_wdt_expire);
-static const struct wm_adsp_ops wm_adsp1_ops = { - .validate_version = wm_adsp_validate_version, - .parse_sizes = wm_adsp1_parse_sizes, - .region_to_reg = wm_adsp_region_to_reg, +static const struct cs_dsp_ops cs_dsp_adsp1_ops = { + .validate_version = cs_dsp_validate_version, + .parse_sizes = cs_dsp_adsp1_parse_sizes, + .region_to_reg = cs_dsp_region_to_reg, };
-static const struct wm_adsp_ops wm_adsp2_ops[] = { +static const struct cs_dsp_ops cs_dsp_adsp2_ops[] = { { .sys_config_size = sizeof(struct wm_adsp_system_config_xm_hdr), - .parse_sizes = wm_adsp2_parse_sizes, - .validate_version = wm_adsp_validate_version, - .setup_algs = wm_adsp2_setup_algs, - .region_to_reg = wm_adsp_region_to_reg, + .parse_sizes = cs_dsp_adsp2_parse_sizes, + .validate_version = cs_dsp_validate_version, + .setup_algs = cs_dsp_adsp2_setup_algs, + .region_to_reg = cs_dsp_region_to_reg,
- .show_fw_status = wm_adsp2_show_fw_status, + .show_fw_status = cs_dsp_adsp2_show_fw_status,
- .enable_memory = wm_adsp2_enable_memory, - .disable_memory = wm_adsp2_disable_memory, + .enable_memory = cs_dsp_adsp2_enable_memory, + .disable_memory = cs_dsp_adsp2_disable_memory,
- .enable_core = wm_adsp2_enable_core, - .disable_core = wm_adsp2_disable_core, + .enable_core = cs_dsp_adsp2_enable_core, + .disable_core = cs_dsp_adsp2_disable_core,
- .start_core = wm_adsp2_start_core, - .stop_core = wm_adsp2_stop_core, + .start_core = cs_dsp_adsp2_start_core, + .stop_core = cs_dsp_adsp2_stop_core,
}, { .sys_config_size = sizeof(struct wm_adsp_system_config_xm_hdr), - .parse_sizes = wm_adsp2_parse_sizes, - .validate_version = wm_adsp_validate_version, - .setup_algs = wm_adsp2_setup_algs, - .region_to_reg = wm_adsp_region_to_reg, + .parse_sizes = cs_dsp_adsp2_parse_sizes, + .validate_version = cs_dsp_validate_version, + .setup_algs = cs_dsp_adsp2_setup_algs, + .region_to_reg = cs_dsp_region_to_reg,
- .show_fw_status = wm_adsp2v2_show_fw_status, + .show_fw_status = cs_dsp_adsp2v2_show_fw_status,
- .enable_memory = wm_adsp2_enable_memory, - .disable_memory = wm_adsp2_disable_memory, - .lock_memory = wm_adsp2_lock, + .enable_memory = cs_dsp_adsp2_enable_memory, + .disable_memory = cs_dsp_adsp2_disable_memory, + .lock_memory = cs_dsp_adsp2_lock,
- .enable_core = wm_adsp2v2_enable_core, - .disable_core = wm_adsp2v2_disable_core, + .enable_core = cs_dsp_adsp2v2_enable_core, + .disable_core = cs_dsp_adsp2v2_disable_core,
- .start_core = wm_adsp2_start_core, - .stop_core = wm_adsp2_stop_core, + .start_core = cs_dsp_adsp2_start_core, + .stop_core = cs_dsp_adsp2_stop_core, }, { .sys_config_size = sizeof(struct wm_adsp_system_config_xm_hdr), - .parse_sizes = wm_adsp2_parse_sizes, - .validate_version = wm_adsp_validate_version, - .setup_algs = wm_adsp2_setup_algs, - .region_to_reg = wm_adsp_region_to_reg, + .parse_sizes = cs_dsp_adsp2_parse_sizes, + .validate_version = cs_dsp_validate_version, + .setup_algs = cs_dsp_adsp2_setup_algs, + .region_to_reg = cs_dsp_region_to_reg,
- .show_fw_status = wm_adsp2v2_show_fw_status, - .stop_watchdog = wm_adsp_stop_watchdog, + .show_fw_status = cs_dsp_adsp2v2_show_fw_status, + .stop_watchdog = cs_dsp_stop_watchdog,
- .enable_memory = wm_adsp2_enable_memory, - .disable_memory = wm_adsp2_disable_memory, - .lock_memory = wm_adsp2_lock, + .enable_memory = cs_dsp_adsp2_enable_memory, + .disable_memory = cs_dsp_adsp2_disable_memory, + .lock_memory = cs_dsp_adsp2_lock,
- .enable_core = wm_adsp2v2_enable_core, - .disable_core = wm_adsp2v2_disable_core, + .enable_core = cs_dsp_adsp2v2_enable_core, + .disable_core = cs_dsp_adsp2v2_disable_core,
- .start_core = wm_adsp2_start_core, - .stop_core = wm_adsp2_stop_core, + .start_core = cs_dsp_adsp2_start_core, + .stop_core = cs_dsp_adsp2_stop_core, }, };
-static const struct wm_adsp_ops wm_halo_ops = { +static const struct cs_dsp_ops cs_dsp_halo_ops = { .sys_config_size = sizeof(struct wm_halo_system_config_xm_hdr), - .parse_sizes = wm_adsp2_parse_sizes, - .validate_version = wm_halo_validate_version, - .setup_algs = wm_halo_setup_algs, - .region_to_reg = wm_halo_region_to_reg, + .parse_sizes = cs_dsp_adsp2_parse_sizes, + .validate_version = cs_dsp_halo_validate_version, + .setup_algs = cs_dsp_halo_setup_algs, + .region_to_reg = cs_dsp_halo_region_to_reg,
- .show_fw_status = wm_halo_show_fw_status, - .stop_watchdog = wm_halo_stop_watchdog, + .show_fw_status = cs_dsp_halo_show_fw_status, + .stop_watchdog = cs_dsp_halo_stop_watchdog,
- .lock_memory = wm_halo_configure_mpu, + .lock_memory = cs_dsp_halo_configure_mpu,
- .start_core = wm_halo_start_core, - .stop_core = wm_halo_stop_core, + .start_core = cs_dsp_halo_start_core, + .stop_core = cs_dsp_halo_stop_core, };
MODULE_LICENSE("GPL v2"); diff --git a/sound/soc/codecs/wm_adsp.h b/sound/soc/codecs/wm_adsp.h index f22131d9cc29..114bc41981ef 100644 --- a/sound/soc/codecs/wm_adsp.h +++ b/sound/soc/codecs/wm_adsp.h @@ -20,29 +20,29 @@ #define WM_ADSP_COMPR_OK 0 #define WM_ADSP_COMPR_VOICE_TRIGGER 1
-#define WM_ADSP2_REGION_0 BIT(0) -#define WM_ADSP2_REGION_1 BIT(1) -#define WM_ADSP2_REGION_2 BIT(2) -#define WM_ADSP2_REGION_3 BIT(3) -#define WM_ADSP2_REGION_4 BIT(4) -#define WM_ADSP2_REGION_5 BIT(5) -#define WM_ADSP2_REGION_6 BIT(6) -#define WM_ADSP2_REGION_7 BIT(7) -#define WM_ADSP2_REGION_8 BIT(8) -#define WM_ADSP2_REGION_9 BIT(9) -#define WM_ADSP2_REGION_1_9 (WM_ADSP2_REGION_1 | \ - WM_ADSP2_REGION_2 | WM_ADSP2_REGION_3 | \ - WM_ADSP2_REGION_4 | WM_ADSP2_REGION_5 | \ - WM_ADSP2_REGION_6 | WM_ADSP2_REGION_7 | \ - WM_ADSP2_REGION_8 | WM_ADSP2_REGION_9) -#define WM_ADSP2_REGION_ALL (WM_ADSP2_REGION_0 | WM_ADSP2_REGION_1_9) +#define CS_ADSP2_REGION_0 BIT(0) +#define CS_ADSP2_REGION_1 BIT(1) +#define CS_ADSP2_REGION_2 BIT(2) +#define CS_ADSP2_REGION_3 BIT(3) +#define CS_ADSP2_REGION_4 BIT(4) +#define CS_ADSP2_REGION_5 BIT(5) +#define CS_ADSP2_REGION_6 BIT(6) +#define CS_ADSP2_REGION_7 BIT(7) +#define CS_ADSP2_REGION_8 BIT(8) +#define CS_ADSP2_REGION_9 BIT(9) +#define CS_ADSP2_REGION_1_9 (CS_ADSP2_REGION_1 | \ + CS_ADSP2_REGION_2 | CS_ADSP2_REGION_3 | \ + CS_ADSP2_REGION_4 | CS_ADSP2_REGION_5 | \ + CS_ADSP2_REGION_6 | CS_ADSP2_REGION_7 | \ + CS_ADSP2_REGION_8 | CS_ADSP2_REGION_9) +#define CS_ADSP2_REGION_ALL (CS_ADSP2_REGION_0 | CS_ADSP2_REGION_1_9)
-struct wm_adsp_region { +struct cs_dsp_region { int type; unsigned int base; };
-struct wm_adsp_alg_region { +struct cs_dsp_alg_region { struct list_head list; unsigned int alg; int type; @@ -51,7 +51,7 @@ struct wm_adsp_alg_region {
struct wm_adsp_compr; struct wm_adsp_compr_buf; -struct wm_adsp_ops; +struct cs_dsp_ops;
struct wm_adsp { const char *part; @@ -64,7 +64,7 @@ struct wm_adsp { struct regmap *regmap; struct snd_soc_component *component;
- const struct wm_adsp_ops *ops; + const struct cs_dsp_ops *ops;
unsigned int base; unsigned int base_sysinfo; @@ -78,7 +78,7 @@ struct wm_adsp { unsigned int fw_id_version; unsigned int fw_vendor_id;
- const struct wm_adsp_region *mem; + const struct cs_dsp_region *mem; int num_mems;
int fw; @@ -108,7 +108,7 @@ struct wm_adsp {
};
-struct wm_adsp_ops { +struct cs_dsp_ops { unsigned int sys_config_size;
bool (*validate_version)(struct wm_adsp *dsp, unsigned int version); @@ -117,7 +117,7 @@ struct wm_adsp_ops { unsigned int pos, const struct firmware *firmware); int (*setup_algs)(struct wm_adsp *dsp); - unsigned int (*region_to_reg)(struct wm_adsp_region const *mem, + unsigned int (*region_to_reg)(struct cs_dsp_region const *mem, unsigned int offset);
void (*show_fw_status)(struct wm_adsp *dsp);
In preparation for moving the generic DSP support out of ASoC, add some new logging macros that will be used from the generic code.
Signed-off-by: Simon Trimmer simont@opensource.cirrus.com Signed-off-by: Charles Keepax ckeepax@opensource.cirrus.com --- sound/soc/codecs/wm_adsp.c | 461 +++++++++++++++++++------------------ 1 file changed, 234 insertions(+), 227 deletions(-)
diff --git a/sound/soc/codecs/wm_adsp.c b/sound/soc/codecs/wm_adsp.c index a039c137a3cb..cfa8f1476c00 100644 --- a/sound/soc/codecs/wm_adsp.c +++ b/sound/soc/codecs/wm_adsp.c @@ -43,6 +43,15 @@ #define adsp_dbg(_dsp, fmt, ...) \ dev_dbg(_dsp->dev, "%s: " fmt, _dsp->name, ##__VA_ARGS__)
+#define cs_dsp_err(_dsp, fmt, ...) \ + dev_err(_dsp->dev, "%s: " fmt, _dsp->name, ##__VA_ARGS__) +#define cs_dsp_warn(_dsp, fmt, ...) \ + dev_warn(_dsp->dev, "%s: " fmt, _dsp->name, ##__VA_ARGS__) +#define cs_dsp_info(_dsp, fmt, ...) \ + dev_info(_dsp->dev, "%s: " fmt, _dsp->name, ##__VA_ARGS__) +#define cs_dsp_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__) @@ -883,7 +892,7 @@ static void cs_dsp_read_fw_status(struct wm_adsp *dsp, for (i = 0; i < noffs; ++i) { ret = regmap_read(dsp->regmap, dsp->base + offs[i], &offs[i]); if (ret) { - adsp_err(dsp, "Failed to read SCRATCH%u: %d\n", i, ret); + cs_dsp_err(dsp, "Failed to read SCRATCH%u: %d\n", i, ret); return; } } @@ -897,8 +906,8 @@ static void cs_dsp_adsp2_show_fw_status(struct wm_adsp *dsp)
cs_dsp_read_fw_status(dsp, ARRAY_SIZE(offs), offs);
- adsp_dbg(dsp, "FW SCRATCH 0:0x%x 1:0x%x 2:0x%x 3:0x%x\n", - offs[0], offs[1], offs[2], offs[3]); + cs_dsp_dbg(dsp, "FW SCRATCH 0:0x%x 1:0x%x 2:0x%x 3:0x%x\n", + offs[0], offs[1], offs[2], offs[3]); }
static void cs_dsp_adsp2v2_show_fw_status(struct wm_adsp *dsp) @@ -907,9 +916,9 @@ static void cs_dsp_adsp2v2_show_fw_status(struct wm_adsp *dsp)
cs_dsp_read_fw_status(dsp, ARRAY_SIZE(offs), offs);
- adsp_dbg(dsp, "FW SCRATCH 0:0x%x 1:0x%x 2:0x%x 3:0x%x\n", - offs[0] & 0xFFFF, offs[0] >> 16, - offs[1] & 0xFFFF, offs[1] >> 16); + cs_dsp_dbg(dsp, "FW SCRATCH 0:0x%x 1:0x%x 2:0x%x 3:0x%x\n", + offs[0] & 0xFFFF, offs[0] >> 16, + offs[1] & 0xFFFF, offs[1] >> 16); }
static void cs_dsp_halo_show_fw_status(struct wm_adsp *dsp) @@ -920,8 +929,8 @@ static void cs_dsp_halo_show_fw_status(struct wm_adsp *dsp)
cs_dsp_read_fw_status(dsp, ARRAY_SIZE(offs), offs);
- adsp_dbg(dsp, "FW SCRATCH 0:0x%x 1:0x%x 2:0x%x 3:0x%x\n", - offs[0], offs[1], offs[2], offs[3]); + cs_dsp_dbg(dsp, "FW SCRATCH 0:0x%x 1:0x%x 2:0x%x 3:0x%x\n", + offs[0], offs[1], offs[2], offs[3]); }
static inline struct wm_coeff_ctl *bytes_ext_to_ctl(struct soc_bytes_ext *ext) @@ -937,8 +946,8 @@ static int cs_dsp_coeff_base_reg(struct wm_coeff_ctl *ctl, unsigned int *reg)
mem = cs_dsp_find_region(dsp, alg_region->type); if (!mem) { - adsp_err(dsp, "No base for region %x\n", - alg_region->type); + cs_dsp_err(dsp, "No base for region %x\n", + alg_region->type); return -EINVAL; }
@@ -983,13 +992,13 @@ static int cs_dsp_coeff_write_acked_control(struct wm_coeff_ctl *ctl, if (ret) return ret;
- adsp_dbg(dsp, "Sending 0x%x to acked control alg 0x%x %s:0x%x\n", - event_id, ctl->alg_region.alg, - cs_dsp_mem_region_name(ctl->alg_region.type), ctl->offset); + cs_dsp_dbg(dsp, "Sending 0x%x to acked control alg 0x%x %s:0x%x\n", + event_id, ctl->alg_region.alg, + cs_dsp_mem_region_name(ctl->alg_region.type), ctl->offset);
ret = regmap_raw_write(dsp->regmap, reg, &val, sizeof(val)); if (ret) { - adsp_err(dsp, "Failed to write %x: %d\n", reg, ret); + cs_dsp_err(dsp, "Failed to write %x: %d\n", reg, ret); return ret; }
@@ -1013,20 +1022,20 @@ static int cs_dsp_coeff_write_acked_control(struct wm_coeff_ctl *ctl,
ret = regmap_raw_read(dsp->regmap, reg, &val, sizeof(val)); if (ret) { - adsp_err(dsp, "Failed to read %x: %d\n", reg, ret); + cs_dsp_err(dsp, "Failed to read %x: %d\n", reg, ret); return ret; }
if (val == 0) { - adsp_dbg(dsp, "Acked control ACKED at poll %u\n", i); + cs_dsp_dbg(dsp, "Acked control ACKED at poll %u\n", i); return 0; } }
- adsp_warn(dsp, "Acked control @0x%x alg:0x%x %s:0x%x timed out\n", - reg, ctl->alg_region.alg, - cs_dsp_mem_region_name(ctl->alg_region.type), - ctl->offset); + cs_dsp_warn(dsp, "Acked control @0x%x alg:0x%x %s:0x%x timed out\n", + reg, ctl->alg_region.alg, + cs_dsp_mem_region_name(ctl->alg_region.type), + ctl->offset);
return -ETIMEDOUT; } @@ -1050,12 +1059,12 @@ static int cs_dsp_coeff_write_ctrl_raw(struct wm_coeff_ctl *ctl, ret = regmap_raw_write(dsp->regmap, reg, scratch, len); if (ret) { - adsp_err(dsp, "Failed to write %zu bytes to %x: %d\n", - len, reg, ret); + cs_dsp_err(dsp, "Failed to write %zu bytes to %x: %d\n", + len, reg, ret); kfree(scratch); return ret; } - adsp_dbg(dsp, "Wrote %zu bytes to %x\n", len, reg); + cs_dsp_dbg(dsp, "Wrote %zu bytes to %x\n", len, reg);
kfree(scratch);
@@ -1157,12 +1166,12 @@ static int cs_dsp_coeff_read_ctrl_raw(struct wm_coeff_ctl *ctl,
ret = regmap_raw_read(dsp->regmap, reg, scratch, len); if (ret) { - adsp_err(dsp, "Failed to read %zu bytes from %x: %d\n", - len, reg, ret); + cs_dsp_err(dsp, "Failed to read %zu bytes from %x: %d\n", + len, reg, ret); kfree(scratch); return ret; } - adsp_dbg(dsp, "Read %zu bytes from %x\n", len, reg); + cs_dsp_dbg(dsp, "Read %zu bytes from %x\n", len, reg);
memcpy(buf, scratch, len); kfree(scratch); @@ -1381,9 +1390,9 @@ static void cs_dsp_signal_event_controls(struct wm_adsp *dsp,
ret = cs_dsp_coeff_write_acked_control(ctl, event); if (ret) - adsp_warn(dsp, - "Failed to send 0x%x event to alg 0x%x (%d)\n", - event, ctl->alg_region.alg, ret); + cs_dsp_warn(dsp, + "Failed to send 0x%x event to alg 0x%x (%d)\n", + event, ctl->alg_region.alg, ret); } }
@@ -1432,7 +1441,7 @@ static int cs_dsp_create_control(struct wm_adsp *dsp,
region_name = cs_dsp_mem_region_name(alg_region->type); if (!region_name) { - adsp_err(dsp, "Unknown region type: %d\n", alg_region->type); + cs_dsp_err(dsp, "Unknown region type: %d\n", alg_region->type); return -EINVAL; }
@@ -1608,9 +1617,9 @@ static inline void cs_dsp_coeff_parse_alg(struct wm_adsp *dsp, const u8 **data, break; }
- adsp_dbg(dsp, "Algorithm ID: %#x\n", blk->id); - adsp_dbg(dsp, "Algorithm name: %.*s\n", blk->name_len, blk->name); - adsp_dbg(dsp, "# of coefficient descriptors: %#x\n", blk->ncoeff); + cs_dsp_dbg(dsp, "Algorithm ID: %#x\n", blk->id); + cs_dsp_dbg(dsp, "Algorithm name: %.*s\n", blk->name_len, blk->name); + cs_dsp_dbg(dsp, "# of coefficient descriptors: %#x\n", blk->ncoeff); }
static inline void cs_dsp_coeff_parse_coeff(struct wm_adsp *dsp, const u8 **data, @@ -1651,12 +1660,12 @@ static inline void cs_dsp_coeff_parse_coeff(struct wm_adsp *dsp, const u8 **data break; }
- adsp_dbg(dsp, "\tCoefficient type: %#x\n", blk->mem_type); - adsp_dbg(dsp, "\tCoefficient offset: %#x\n", blk->offset); - adsp_dbg(dsp, "\tCoefficient name: %.*s\n", blk->name_len, blk->name); - adsp_dbg(dsp, "\tCoefficient flags: %#x\n", blk->flags); - adsp_dbg(dsp, "\tALSA control type: %#x\n", blk->ctl_type); - adsp_dbg(dsp, "\tALSA control len: %#x\n", blk->len); + cs_dsp_dbg(dsp, "\tCoefficient type: %#x\n", blk->mem_type); + cs_dsp_dbg(dsp, "\tCoefficient offset: %#x\n", blk->offset); + cs_dsp_dbg(dsp, "\tCoefficient name: %.*s\n", blk->name_len, blk->name); + cs_dsp_dbg(dsp, "\tCoefficient flags: %#x\n", blk->flags); + cs_dsp_dbg(dsp, "\tALSA control type: %#x\n", blk->ctl_type); + cs_dsp_dbg(dsp, "\tALSA control len: %#x\n", blk->len); }
static int cs_dsp_check_coeff_flags(struct wm_adsp *dsp, @@ -1666,8 +1675,8 @@ static int cs_dsp_check_coeff_flags(struct wm_adsp *dsp, { if ((coeff_blk->flags & f_illegal) || ((coeff_blk->flags & f_required) != f_required)) { - adsp_err(dsp, "Illegal flags 0x%x for control type 0x%x\n", - coeff_blk->flags, coeff_blk->ctl_type); + cs_dsp_err(dsp, "Illegal flags 0x%x for control type 0x%x\n", + coeff_blk->flags, coeff_blk->ctl_type); return -EINVAL; }
@@ -1722,8 +1731,8 @@ static int cs_dsp_parse_coeff(struct wm_adsp *dsp, return -EINVAL; break; default: - adsp_err(dsp, "Unknown control type: %d\n", - coeff_blk.ctl_type); + cs_dsp_err(dsp, "Unknown control type: %d\n", + coeff_blk.ctl_type); return -EINVAL; }
@@ -1738,8 +1747,8 @@ static int cs_dsp_parse_coeff(struct wm_adsp *dsp, coeff_blk.flags, coeff_blk.ctl_type); if (ret < 0) - adsp_err(dsp, "Failed to create control: %.*s, %d\n", - coeff_blk.name_len, coeff_blk.name, ret); + cs_dsp_err(dsp, "Failed to create control: %.*s, %d\n", + coeff_blk.name_len, coeff_blk.name, ret); }
return 0; @@ -1754,9 +1763,9 @@ static unsigned int cs_dsp_adsp1_parse_sizes(struct wm_adsp *dsp,
adsp1_sizes = (void *)&firmware->data[pos];
- adsp_dbg(dsp, "%s: %d DM, %d PM, %d ZM\n", file, - le32_to_cpu(adsp1_sizes->dm), le32_to_cpu(adsp1_sizes->pm), - le32_to_cpu(adsp1_sizes->zm)); + cs_dsp_dbg(dsp, "%s: %d DM, %d PM, %d ZM\n", file, + le32_to_cpu(adsp1_sizes->dm), le32_to_cpu(adsp1_sizes->pm), + le32_to_cpu(adsp1_sizes->zm));
return pos + sizeof(*adsp1_sizes); } @@ -1770,9 +1779,9 @@ static unsigned int cs_dsp_adsp2_parse_sizes(struct wm_adsp *dsp,
adsp2_sizes = (void *)&firmware->data[pos];
- adsp_dbg(dsp, "%s: %d XM, %d YM %d PM, %d ZM\n", file, - le32_to_cpu(adsp2_sizes->xm), le32_to_cpu(adsp2_sizes->ym), - le32_to_cpu(adsp2_sizes->pm), le32_to_cpu(adsp2_sizes->zm)); + cs_dsp_dbg(dsp, "%s: %d XM, %d YM %d PM, %d ZM\n", file, + le32_to_cpu(adsp2_sizes->xm), le32_to_cpu(adsp2_sizes->ym), + le32_to_cpu(adsp2_sizes->pm), le32_to_cpu(adsp2_sizes->zm));
return pos + sizeof(*adsp2_sizes); } @@ -1781,7 +1790,7 @@ static bool cs_dsp_validate_version(struct wm_adsp *dsp, unsigned int version) { switch (version) { case 0: - adsp_warn(dsp, "Deprecated file format %d\n", version); + cs_dsp_warn(dsp, "Deprecated file format %d\n", version); return true; case 1: case 2: @@ -1829,37 +1838,37 @@ static int cs_dsp_load(struct wm_adsp *dsp)
ret = request_firmware(&firmware, file, dsp->dev); if (ret != 0) { - adsp_err(dsp, "Failed to request '%s'\n", file); + cs_dsp_err(dsp, "Failed to request '%s'\n", file); goto out; } ret = -EINVAL;
pos = sizeof(*header) + sizeof(*adsp1_sizes) + sizeof(*footer); if (pos >= firmware->size) { - adsp_err(dsp, "%s: file too short, %zu bytes\n", - file, firmware->size); + cs_dsp_err(dsp, "%s: file too short, %zu bytes\n", + file, firmware->size); goto out_fw; }
header = (void *)&firmware->data[0];
if (memcmp(&header->magic[0], "WMFW", 4) != 0) { - adsp_err(dsp, "%s: invalid magic\n", file); + cs_dsp_err(dsp, "%s: invalid magic\n", file); goto out_fw; }
if (!dsp->ops->validate_version(dsp, header->ver)) { - adsp_err(dsp, "%s: unknown file format %d\n", - file, header->ver); + cs_dsp_err(dsp, "%s: unknown file format %d\n", + file, header->ver); goto out_fw; }
- adsp_info(dsp, "Firmware version: %d\n", header->ver); + cs_dsp_info(dsp, "Firmware version: %d\n", header->ver); dsp->fw_ver = header->ver;
if (header->core != dsp->type) { - adsp_err(dsp, "%s: invalid core %d != %d\n", - file, header->core, dsp->type); + cs_dsp_err(dsp, "%s: invalid core %d != %d\n", + file, header->core, dsp->type); goto out_fw; }
@@ -1870,13 +1879,13 @@ static int cs_dsp_load(struct wm_adsp *dsp) pos += sizeof(*footer);
if (le32_to_cpu(header->len) != pos) { - adsp_err(dsp, "%s: unexpected header length %d\n", - file, le32_to_cpu(header->len)); + cs_dsp_err(dsp, "%s: unexpected header length %d\n", + file, le32_to_cpu(header->len)); goto out_fw; }
- adsp_dbg(dsp, "%s: timestamp %llu\n", file, - le64_to_cpu(footer->timestamp)); + cs_dsp_dbg(dsp, "%s: timestamp %llu\n", file, + le64_to_cpu(footer->timestamp));
while (pos < firmware->size && sizeof(*region) < firmware->size - pos) { @@ -1918,7 +1927,7 @@ static int cs_dsp_load(struct wm_adsp *dsp) case WMFW_HALO_YM_PACKED: mem = cs_dsp_find_region(dsp, type); if (!mem) { - adsp_err(dsp, "No region of type: %x\n", type); + cs_dsp_err(dsp, "No region of type: %x\n", type); ret = -EINVAL; goto out_fw; } @@ -1927,29 +1936,29 @@ static int cs_dsp_load(struct wm_adsp *dsp) reg = dsp->ops->region_to_reg(mem, offset); break; default: - adsp_warn(dsp, - "%s.%d: Unknown region type %x at %d(%x)\n", - file, regions, type, pos, pos); + cs_dsp_warn(dsp, + "%s.%d: Unknown region type %x at %d(%x)\n", + file, regions, type, pos, pos); break; }
- adsp_dbg(dsp, "%s.%d: %d bytes at %d in %s\n", file, - regions, le32_to_cpu(region->len), offset, - region_name); + cs_dsp_dbg(dsp, "%s.%d: %d bytes at %d in %s\n", file, + regions, le32_to_cpu(region->len), offset, + region_name);
if (le32_to_cpu(region->len) > firmware->size - pos - sizeof(*region)) { - adsp_err(dsp, - "%s.%d: %s region len %d bytes exceeds file length %zu\n", - file, regions, region_name, - le32_to_cpu(region->len), firmware->size); + cs_dsp_err(dsp, + "%s.%d: %s region len %d bytes exceeds file length %zu\n", + file, regions, region_name, + le32_to_cpu(region->len), firmware->size); ret = -EINVAL; goto out_fw; }
if (text) { memcpy(text, region->data, le32_to_cpu(region->len)); - adsp_info(dsp, "%s: %s\n", file, text); + cs_dsp_info(dsp, "%s: %s\n", file, text); kfree(text); text = NULL; } @@ -1959,7 +1968,7 @@ static int cs_dsp_load(struct wm_adsp *dsp) le32_to_cpu(region->len), &buf_list); if (!buf) { - adsp_err(dsp, "Out of memory\n"); + cs_dsp_err(dsp, "Out of memory\n"); ret = -ENOMEM; goto out_fw; } @@ -1967,11 +1976,11 @@ static int cs_dsp_load(struct wm_adsp *dsp) ret = regmap_raw_write_async(regmap, reg, buf->buf, le32_to_cpu(region->len)); if (ret != 0) { - adsp_err(dsp, - "%s.%d: Failed to write %d bytes at %d in %s: %d\n", - file, regions, - le32_to_cpu(region->len), offset, - region_name, ret); + cs_dsp_err(dsp, + "%s.%d: Failed to write %d bytes at %d in %s: %d\n", + file, regions, + le32_to_cpu(region->len), offset, + region_name, ret); goto out_fw; } } @@ -1982,13 +1991,13 @@ static int cs_dsp_load(struct wm_adsp *dsp)
ret = regmap_async_complete(regmap); if (ret != 0) { - adsp_err(dsp, "Failed to complete async write: %d\n", ret); + cs_dsp_err(dsp, "Failed to complete async write: %d\n", ret); goto out_fw; }
if (pos > firmware->size) - adsp_warn(dsp, "%s.%d: %zu bytes at end of file\n", - file, regions, pos - firmware->size); + cs_dsp_warn(dsp, "%s.%d: %zu bytes at end of file\n", + file, regions, pos - firmware->size);
cs_dsp_debugfs_save_wmfwname(dsp, file);
@@ -2111,12 +2120,12 @@ static void *cs_dsp_read_algs(struct wm_adsp *dsp, size_t n_algs, __be32 val;
if (n_algs == 0) { - adsp_err(dsp, "No algorithms\n"); + cs_dsp_err(dsp, "No algorithms\n"); return ERR_PTR(-EINVAL); }
if (n_algs > 1024) { - adsp_err(dsp, "Algorithm count %zx excessive\n", n_algs); + cs_dsp_err(dsp, "Algorithm count %zx excessive\n", n_algs); return ERR_PTR(-EINVAL); }
@@ -2125,14 +2134,14 @@ static void *cs_dsp_read_algs(struct wm_adsp *dsp, size_t n_algs,
ret = regmap_raw_read(dsp->regmap, reg, &val, sizeof(val)); if (ret != 0) { - adsp_err(dsp, "Failed to read algorithm list end: %d\n", - ret); + cs_dsp_err(dsp, "Failed to read algorithm list end: %d\n", + ret); return ERR_PTR(ret); }
if (be32_to_cpu(val) != 0xbedead) - adsp_warn(dsp, "Algorithm list end %x 0x%x != 0xbedead\n", - reg, be32_to_cpu(val)); + cs_dsp_warn(dsp, "Algorithm list end %x 0x%x != 0xbedead\n", + reg, be32_to_cpu(val));
/* Convert length from DSP words to bytes */ len *= sizeof(u32); @@ -2145,7 +2154,7 @@ static void *cs_dsp_read_algs(struct wm_adsp *dsp, size_t n_algs,
ret = regmap_raw_read(dsp->regmap, reg, alg, len); if (ret != 0) { - adsp_err(dsp, "Failed to read algorithm list: %d\n", ret); + cs_dsp_err(dsp, "Failed to read algorithm list: %d\n", ret); kfree(alg); return ERR_PTR(ret); } @@ -2207,10 +2216,10 @@ static void cs_dsp_parse_wmfw_id_header(struct wm_adsp *dsp, dsp->fw_id = be32_to_cpu(fw->id); dsp->fw_id_version = be32_to_cpu(fw->ver);
- adsp_info(dsp, "Firmware: %x v%d.%d.%d, %d algorithms\n", - dsp->fw_id, (dsp->fw_id_version & 0xff0000) >> 16, - (dsp->fw_id_version & 0xff00) >> 8, dsp->fw_id_version & 0xff, - nalgs); + cs_dsp_info(dsp, "Firmware: %x v%d.%d.%d, %d algorithms\n", + dsp->fw_id, (dsp->fw_id_version & 0xff0000) >> 16, + (dsp->fw_id_version & 0xff00) >> 8, dsp->fw_id_version & 0xff, + nalgs); }
static void cs_dsp_parse_wmfw_v3_id_header(struct wm_adsp *dsp, @@ -2220,11 +2229,11 @@ static void cs_dsp_parse_wmfw_v3_id_header(struct wm_adsp *dsp, dsp->fw_id_version = be32_to_cpu(fw->ver); dsp->fw_vendor_id = be32_to_cpu(fw->vendor_id);
- adsp_info(dsp, "Firmware: %x vendor: 0x%x v%d.%d.%d, %d algorithms\n", - dsp->fw_id, dsp->fw_vendor_id, - (dsp->fw_id_version & 0xff0000) >> 16, - (dsp->fw_id_version & 0xff00) >> 8, dsp->fw_id_version & 0xff, - nalgs); + cs_dsp_info(dsp, "Firmware: %x vendor: 0x%x v%d.%d.%d, %d algorithms\n", + dsp->fw_id, dsp->fw_vendor_id, + (dsp->fw_id_version & 0xff0000) >> 16, + (dsp->fw_id_version & 0xff00) >> 8, dsp->fw_id_version & 0xff, + nalgs); }
static int cs_dsp_create_regions(struct wm_adsp *dsp, __be32 id, int nregions, @@ -2259,8 +2268,8 @@ static int cs_dsp_adsp1_setup_algs(struct wm_adsp *dsp) ret = regmap_raw_read(dsp->regmap, mem->base, &adsp1_id, sizeof(adsp1_id)); if (ret != 0) { - adsp_err(dsp, "Failed to read algorithm info: %d\n", - ret); + cs_dsp_err(dsp, "Failed to read algorithm info: %d\n", + ret); return ret; }
@@ -2287,13 +2296,13 @@ static int cs_dsp_adsp1_setup_algs(struct wm_adsp *dsp) return PTR_ERR(adsp1_alg);
for (i = 0; i < n_algs; i++) { - adsp_info(dsp, "%d: ID %x v%d.%d.%d DM@%x ZM@%x\n", - i, be32_to_cpu(adsp1_alg[i].alg.id), - (be32_to_cpu(adsp1_alg[i].alg.ver) & 0xff0000) >> 16, - (be32_to_cpu(adsp1_alg[i].alg.ver) & 0xff00) >> 8, - be32_to_cpu(adsp1_alg[i].alg.ver) & 0xff, - be32_to_cpu(adsp1_alg[i].dm), - be32_to_cpu(adsp1_alg[i].zm)); + cs_dsp_info(dsp, "%d: ID %x v%d.%d.%d DM@%x ZM@%x\n", + i, be32_to_cpu(adsp1_alg[i].alg.id), + (be32_to_cpu(adsp1_alg[i].alg.ver) & 0xff0000) >> 16, + (be32_to_cpu(adsp1_alg[i].alg.ver) & 0xff00) >> 8, + be32_to_cpu(adsp1_alg[i].alg.ver) & 0xff, + be32_to_cpu(adsp1_alg[i].dm), + be32_to_cpu(adsp1_alg[i].zm));
alg_region = cs_dsp_create_region(dsp, WMFW_ADSP1_DM, adsp1_alg[i].alg.id, @@ -2311,8 +2320,8 @@ static int cs_dsp_adsp1_setup_algs(struct wm_adsp *dsp) len, NULL, 0, 0, WMFW_CTL_TYPE_BYTES); } else { - adsp_warn(dsp, "Missing length info for region DM with ID %x\n", - be32_to_cpu(adsp1_alg[i].alg.id)); + cs_dsp_warn(dsp, "Missing length info for region DM with ID %x\n", + be32_to_cpu(adsp1_alg[i].alg.id)); } }
@@ -2332,8 +2341,8 @@ static int cs_dsp_adsp1_setup_algs(struct wm_adsp *dsp) len, NULL, 0, 0, WMFW_CTL_TYPE_BYTES); } else { - adsp_warn(dsp, "Missing length info for region ZM with ID %x\n", - be32_to_cpu(adsp1_alg[i].alg.id)); + cs_dsp_warn(dsp, "Missing length info for region ZM with ID %x\n", + be32_to_cpu(adsp1_alg[i].alg.id)); } } } @@ -2360,8 +2369,8 @@ static int cs_dsp_adsp2_setup_algs(struct wm_adsp *dsp) ret = regmap_raw_read(dsp->regmap, mem->base, &adsp2_id, sizeof(adsp2_id)); if (ret != 0) { - adsp_err(dsp, "Failed to read algorithm info: %d\n", - ret); + cs_dsp_err(dsp, "Failed to read algorithm info: %d\n", + ret); return ret; }
@@ -2393,15 +2402,15 @@ static int cs_dsp_adsp2_setup_algs(struct wm_adsp *dsp) return PTR_ERR(adsp2_alg);
for (i = 0; i < n_algs; i++) { - adsp_info(dsp, - "%d: ID %x v%d.%d.%d XM@%x YM@%x ZM@%x\n", - i, be32_to_cpu(adsp2_alg[i].alg.id), - (be32_to_cpu(adsp2_alg[i].alg.ver) & 0xff0000) >> 16, - (be32_to_cpu(adsp2_alg[i].alg.ver) & 0xff00) >> 8, - be32_to_cpu(adsp2_alg[i].alg.ver) & 0xff, - be32_to_cpu(adsp2_alg[i].xm), - be32_to_cpu(adsp2_alg[i].ym), - be32_to_cpu(adsp2_alg[i].zm)); + cs_dsp_info(dsp, + "%d: ID %x v%d.%d.%d XM@%x YM@%x ZM@%x\n", + i, be32_to_cpu(adsp2_alg[i].alg.id), + (be32_to_cpu(adsp2_alg[i].alg.ver) & 0xff0000) >> 16, + (be32_to_cpu(adsp2_alg[i].alg.ver) & 0xff00) >> 8, + be32_to_cpu(adsp2_alg[i].alg.ver) & 0xff, + be32_to_cpu(adsp2_alg[i].xm), + be32_to_cpu(adsp2_alg[i].ym), + be32_to_cpu(adsp2_alg[i].zm));
alg_region = cs_dsp_create_region(dsp, WMFW_ADSP2_XM, adsp2_alg[i].alg.id, @@ -2419,8 +2428,8 @@ static int cs_dsp_adsp2_setup_algs(struct wm_adsp *dsp) len, NULL, 0, 0, WMFW_CTL_TYPE_BYTES); } else { - adsp_warn(dsp, "Missing length info for region XM with ID %x\n", - be32_to_cpu(adsp2_alg[i].alg.id)); + cs_dsp_warn(dsp, "Missing length info for region XM with ID %x\n", + be32_to_cpu(adsp2_alg[i].alg.id)); } }
@@ -2440,8 +2449,8 @@ static int cs_dsp_adsp2_setup_algs(struct wm_adsp *dsp) len, NULL, 0, 0, WMFW_CTL_TYPE_BYTES); } else { - adsp_warn(dsp, "Missing length info for region YM with ID %x\n", - be32_to_cpu(adsp2_alg[i].alg.id)); + cs_dsp_warn(dsp, "Missing length info for region YM with ID %x\n", + be32_to_cpu(adsp2_alg[i].alg.id)); } }
@@ -2461,8 +2470,8 @@ static int cs_dsp_adsp2_setup_algs(struct wm_adsp *dsp) len, NULL, 0, 0, WMFW_CTL_TYPE_BYTES); } else { - adsp_warn(dsp, "Missing length info for region ZM with ID %x\n", - be32_to_cpu(adsp2_alg[i].alg.id)); + cs_dsp_warn(dsp, "Missing length info for region ZM with ID %x\n", + be32_to_cpu(adsp2_alg[i].alg.id)); } } } @@ -2500,8 +2509,8 @@ static int cs_dsp_halo_setup_algs(struct wm_adsp *dsp) ret = regmap_raw_read(dsp->regmap, mem->base, &halo_id, sizeof(halo_id)); if (ret != 0) { - adsp_err(dsp, "Failed to read algorithm info: %d\n", - ret); + cs_dsp_err(dsp, "Failed to read algorithm info: %d\n", + ret); return ret; }
@@ -2523,14 +2532,14 @@ static int cs_dsp_halo_setup_algs(struct wm_adsp *dsp) return PTR_ERR(halo_alg);
for (i = 0; i < n_algs; i++) { - adsp_info(dsp, - "%d: ID %x v%d.%d.%d XM@%x YM@%x\n", - i, be32_to_cpu(halo_alg[i].alg.id), - (be32_to_cpu(halo_alg[i].alg.ver) & 0xff0000) >> 16, - (be32_to_cpu(halo_alg[i].alg.ver) & 0xff00) >> 8, - be32_to_cpu(halo_alg[i].alg.ver) & 0xff, - be32_to_cpu(halo_alg[i].xm_base), - be32_to_cpu(halo_alg[i].ym_base)); + cs_dsp_info(dsp, + "%d: ID %x v%d.%d.%d XM@%x YM@%x\n", + i, be32_to_cpu(halo_alg[i].alg.id), + (be32_to_cpu(halo_alg[i].alg.ver) & 0xff0000) >> 16, + (be32_to_cpu(halo_alg[i].alg.ver) & 0xff00) >> 8, + be32_to_cpu(halo_alg[i].alg.ver) & 0xff, + be32_to_cpu(halo_alg[i].xm_base), + be32_to_cpu(halo_alg[i].ym_base));
ret = cs_dsp_halo_create_regions(dsp, halo_alg[i].alg.id, halo_alg[i].xm_base, @@ -2568,21 +2577,21 @@ static int cs_dsp_load_coeff(struct wm_adsp *dsp)
ret = request_firmware(&firmware, file, dsp->dev); if (ret != 0) { - adsp_warn(dsp, "Failed to request '%s'\n", file); + cs_dsp_warn(dsp, "Failed to request '%s'\n", file); ret = 0; goto out; } ret = -EINVAL;
if (sizeof(*hdr) >= firmware->size) { - adsp_err(dsp, "%s: file too short, %zu bytes\n", - file, firmware->size); + cs_dsp_err(dsp, "%s: file too short, %zu bytes\n", + file, firmware->size); goto out_fw; }
hdr = (void *)&firmware->data[0]; if (memcmp(hdr->magic, "WMDR", 4) != 0) { - adsp_err(dsp, "%s: invalid magic\n", file); + cs_dsp_err(dsp, "%s: invalid magic\n", file); goto out_fw; }
@@ -2590,16 +2599,16 @@ static int cs_dsp_load_coeff(struct wm_adsp *dsp) case 1: break; default: - adsp_err(dsp, "%s: Unsupported coefficient file format %d\n", - file, be32_to_cpu(hdr->rev) & 0xff); + cs_dsp_err(dsp, "%s: Unsupported coefficient file format %d\n", + file, be32_to_cpu(hdr->rev) & 0xff); ret = -EINVAL; goto out_fw; }
- adsp_dbg(dsp, "%s: v%d.%d.%d\n", file, - (le32_to_cpu(hdr->ver) >> 16) & 0xff, - (le32_to_cpu(hdr->ver) >> 8) & 0xff, - le32_to_cpu(hdr->ver) & 0xff); + cs_dsp_dbg(dsp, "%s: v%d.%d.%d\n", file, + (le32_to_cpu(hdr->ver) >> 16) & 0xff, + (le32_to_cpu(hdr->ver) >> 8) & 0xff, + le32_to_cpu(hdr->ver) & 0xff);
pos = le32_to_cpu(hdr->len);
@@ -2611,13 +2620,13 @@ static int cs_dsp_load_coeff(struct wm_adsp *dsp) type = le16_to_cpu(blk->type); offset = le16_to_cpu(blk->offset);
- adsp_dbg(dsp, "%s.%d: %x v%d.%d.%d\n", - file, blocks, le32_to_cpu(blk->id), - (le32_to_cpu(blk->ver) >> 16) & 0xff, - (le32_to_cpu(blk->ver) >> 8) & 0xff, - le32_to_cpu(blk->ver) & 0xff); - adsp_dbg(dsp, "%s.%d: %d bytes at 0x%x in %x\n", - file, blocks, le32_to_cpu(blk->len), offset, type); + cs_dsp_dbg(dsp, "%s.%d: %x v%d.%d.%d\n", + file, blocks, le32_to_cpu(blk->id), + (le32_to_cpu(blk->ver) >> 16) & 0xff, + (le32_to_cpu(blk->ver) >> 8) & 0xff, + le32_to_cpu(blk->ver) & 0xff); + cs_dsp_dbg(dsp, "%s.%d: %d bytes at 0x%x in %x\n", + file, blocks, le32_to_cpu(blk->len), offset, type);
reg = 0; region_name = "Unknown"; @@ -2636,7 +2645,7 @@ static int cs_dsp_load_coeff(struct wm_adsp *dsp) region_name = "global coefficients"; mem = cs_dsp_find_region(dsp, type); if (!mem) { - adsp_err(dsp, "No ZM\n"); + cs_dsp_err(dsp, "No ZM\n"); break; } reg = dsp->ops->region_to_reg(mem, 0); @@ -2654,13 +2663,13 @@ static int cs_dsp_load_coeff(struct wm_adsp *dsp) case WMFW_HALO_XM_PACKED: case WMFW_HALO_YM_PACKED: case WMFW_HALO_PM_PACKED: - adsp_dbg(dsp, "%s.%d: %d bytes in %x for %x\n", - file, blocks, le32_to_cpu(blk->len), - type, le32_to_cpu(blk->id)); + cs_dsp_dbg(dsp, "%s.%d: %d bytes in %x for %x\n", + file, blocks, le32_to_cpu(blk->len), + type, le32_to_cpu(blk->id));
mem = cs_dsp_find_region(dsp, type); if (!mem) { - adsp_err(dsp, "No base for region %x\n", type); + cs_dsp_err(dsp, "No base for region %x\n", type); break; }
@@ -2671,25 +2680,25 @@ static int cs_dsp_load_coeff(struct wm_adsp *dsp) reg = dsp->ops->region_to_reg(mem, reg); reg += offset; } else { - adsp_err(dsp, "No %x for algorithm %x\n", - type, le32_to_cpu(blk->id)); + cs_dsp_err(dsp, "No %x for algorithm %x\n", + type, le32_to_cpu(blk->id)); } break;
default: - adsp_err(dsp, "%s.%d: Unknown region type %x at %d\n", - file, blocks, type, pos); + cs_dsp_err(dsp, "%s.%d: Unknown region type %x at %d\n", + file, blocks, type, pos); break; }
if (reg) { if (le32_to_cpu(blk->len) > firmware->size - pos - sizeof(*blk)) { - adsp_err(dsp, - "%s.%d: %s region len %d bytes exceeds file length %zu\n", - file, blocks, region_name, - le32_to_cpu(blk->len), - firmware->size); + cs_dsp_err(dsp, + "%s.%d: %s region len %d bytes exceeds file length %zu\n", + file, blocks, region_name, + le32_to_cpu(blk->len), + firmware->size); ret = -EINVAL; goto out_fw; } @@ -2698,20 +2707,20 @@ static int cs_dsp_load_coeff(struct wm_adsp *dsp) le32_to_cpu(blk->len), &buf_list); if (!buf) { - adsp_err(dsp, "Out of memory\n"); + cs_dsp_err(dsp, "Out of memory\n"); ret = -ENOMEM; goto out_fw; }
- adsp_dbg(dsp, "%s.%d: Writing %d bytes at %x\n", - file, blocks, le32_to_cpu(blk->len), - reg); + cs_dsp_dbg(dsp, "%s.%d: Writing %d bytes at %x\n", + file, blocks, le32_to_cpu(blk->len), + reg); ret = regmap_raw_write_async(regmap, reg, buf->buf, le32_to_cpu(blk->len)); if (ret != 0) { - adsp_err(dsp, - "%s.%d: Failed to write to %x in %s: %d\n", - file, blocks, reg, region_name, ret); + cs_dsp_err(dsp, + "%s.%d: Failed to write to %x in %s: %d\n", + file, blocks, reg, region_name, ret); } }
@@ -2721,11 +2730,11 @@ static int cs_dsp_load_coeff(struct wm_adsp *dsp)
ret = regmap_async_complete(regmap); if (ret != 0) - adsp_err(dsp, "Failed to complete async write: %d\n", ret); + cs_dsp_err(dsp, "Failed to complete async write: %d\n", ret);
if (pos > firmware->size) - adsp_warn(dsp, "%s.%d: %zu bytes at end of file\n", - file, blocks, pos - firmware->size); + cs_dsp_warn(dsp, "%s.%d: %zu bytes at end of file\n", + file, blocks, pos - firmware->size);
cs_dsp_debugfs_save_binname(dsp, file);
@@ -2815,8 +2824,7 @@ int wm_adsp1_event(struct snd_soc_dapm_widget *w, if (dsp->sysclk_reg) { ret = regmap_read(dsp->regmap, dsp->sysclk_reg, &val); if (ret != 0) { - adsp_err(dsp, "Failed to read SYSCLK state: %d\n", - ret); + cs_dsp_err(dsp, "Failed to read SYSCLK state: %d\n", ret); goto err_mutex; }
@@ -2826,8 +2834,7 @@ int wm_adsp1_event(struct snd_soc_dapm_widget *w, dsp->base + ADSP1_CONTROL_31, ADSP1_CLK_SEL_MASK, val); if (ret != 0) { - adsp_err(dsp, "Failed to set clock rate: %d\n", - ret); + cs_dsp_err(dsp, "Failed to set clock rate: %d\n", ret); goto err_mutex; } } @@ -2921,11 +2928,11 @@ static int cs_dsp_adsp2v2_enable_core(struct wm_adsp *dsp) }
if (!(val & ADSP2_RAM_RDY)) { - adsp_err(dsp, "Failed to start DSP RAM\n"); + cs_dsp_err(dsp, "Failed to start DSP RAM\n"); return -EBUSY; }
- adsp_dbg(dsp, "RAM ready after %d polls\n", count); + cs_dsp_dbg(dsp, "RAM ready after %d polls\n", count);
return 0; } @@ -3100,7 +3107,7 @@ int wm_adsp2_set_dspclk(struct snd_soc_dapm_widget *w, unsigned int freq) ADSP2_CLK_SEL_MASK, freq << ADSP2_CLK_SEL_SHIFT); if (ret) - adsp_err(dsp, "Failed to set clock rate: %d\n", ret); + cs_dsp_err(dsp, "Failed to set clock rate: %d\n", ret);
return ret; } @@ -3193,7 +3200,7 @@ int wm_adsp_early_event(struct snd_soc_dapm_widget *w,
mutex_unlock(&dsp->pwr_lock);
- adsp_dbg(dsp, "Shutdown complete\n"); + cs_dsp_dbg(dsp, "Shutdown complete\n"); break; default: break; @@ -3249,8 +3256,7 @@ int wm_adsp_event(struct snd_soc_dapm_widget *w, if (dsp->ops->lock_memory) { ret = dsp->ops->lock_memory(dsp, dsp->lock_regions); if (ret != 0) { - adsp_err(dsp, "Error configuring MPU: %d\n", - ret); + cs_dsp_err(dsp, "Error configuring MPU: %d\n", ret); goto err; } } @@ -3299,7 +3305,7 @@ int wm_adsp_event(struct snd_soc_dapm_widget *w,
mutex_unlock(&dsp->pwr_lock);
- adsp_dbg(dsp, "Execution stopped\n"); + cs_dsp_dbg(dsp, "Execution stopped\n"); break;
default: @@ -3375,8 +3381,8 @@ int wm_adsp2_init(struct wm_adsp *dsp) ret = regmap_update_bits(dsp->regmap, dsp->base + ADSP2_CONTROL, ADSP2_MEM_ENA, 0); if (ret) { - adsp_err(dsp, - "Failed to clear memory retention: %d\n", ret); + cs_dsp_err(dsp, + "Failed to clear memory retention: %d\n", ret); return ret; }
@@ -4351,49 +4357,49 @@ irqreturn_t wm_adsp2_bus_error(int irq, void *data)
ret = regmap_read(regmap, dsp->base + ADSP2_LOCK_REGION_CTRL, &val); if (ret) { - adsp_err(dsp, - "Failed to read Region Lock Ctrl register: %d\n", ret); + cs_dsp_err(dsp, + "Failed to read Region Lock Ctrl register: %d\n", ret); goto error; }
if (val & ADSP2_WDT_TIMEOUT_STS_MASK) { - adsp_err(dsp, "watchdog timeout error\n"); + cs_dsp_err(dsp, "watchdog timeout error\n"); dsp->ops->stop_watchdog(dsp); wm_adsp_fatal_error(dsp); }
if (val & (ADSP2_ADDR_ERR_MASK | ADSP2_REGION_LOCK_ERR_MASK)) { if (val & ADSP2_ADDR_ERR_MASK) - adsp_err(dsp, "bus error: address error\n"); + cs_dsp_err(dsp, "bus error: address error\n"); else - adsp_err(dsp, "bus error: region lock error\n"); + cs_dsp_err(dsp, "bus error: region lock error\n");
ret = regmap_read(regmap, dsp->base + ADSP2_BUS_ERR_ADDR, &val); if (ret) { - adsp_err(dsp, - "Failed to read Bus Err Addr register: %d\n", - ret); + cs_dsp_err(dsp, + "Failed to read Bus Err Addr register: %d\n", + ret); goto error; }
- adsp_err(dsp, "bus error address = 0x%x\n", - val & ADSP2_BUS_ERR_ADDR_MASK); + cs_dsp_err(dsp, "bus error address = 0x%x\n", + val & ADSP2_BUS_ERR_ADDR_MASK);
ret = regmap_read(regmap, dsp->base + ADSP2_PMEM_ERR_ADDR_XMEM_ERR_ADDR, &val); if (ret) { - adsp_err(dsp, - "Failed to read Pmem Xmem Err Addr register: %d\n", - ret); + cs_dsp_err(dsp, + "Failed to read Pmem Xmem Err Addr register: %d\n", + ret); goto error; }
- adsp_err(dsp, "xmem error address = 0x%x\n", - val & ADSP2_XMEM_ERR_ADDR_MASK); - adsp_err(dsp, "pmem error address = 0x%x\n", - (val & ADSP2_PMEM_ERR_ADDR_MASK) >> - ADSP2_PMEM_ERR_ADDR_SHIFT); + cs_dsp_err(dsp, "xmem error address = 0x%x\n", + val & ADSP2_XMEM_ERR_ADDR_MASK); + cs_dsp_err(dsp, "pmem error address = 0x%x\n", + (val & ADSP2_PMEM_ERR_ADDR_MASK) >> + ADSP2_PMEM_ERR_ADDR_SHIFT); }
regmap_update_bits(regmap, dsp->base + ADSP2_LOCK_REGION_CTRL, @@ -4423,38 +4429,38 @@ irqreturn_t wm_halo_bus_error(int irq, void *data) ret = regmap_read(regmap, dsp->base_sysinfo + HALO_AHBM_WINDOW_DEBUG_1, fault); if (ret) { - adsp_warn(dsp, "Failed to read AHB DEBUG_1: %d\n", ret); + cs_dsp_warn(dsp, "Failed to read AHB DEBUG_1: %d\n", ret); goto exit_unlock; }
- adsp_warn(dsp, "AHB: STATUS: 0x%x ADDR: 0x%x\n", - *fault & HALO_AHBM_FLAGS_ERR_MASK, - (*fault & HALO_AHBM_CORE_ERR_ADDR_MASK) >> - HALO_AHBM_CORE_ERR_ADDR_SHIFT); + cs_dsp_warn(dsp, "AHB: STATUS: 0x%x ADDR: 0x%x\n", + *fault & HALO_AHBM_FLAGS_ERR_MASK, + (*fault & HALO_AHBM_CORE_ERR_ADDR_MASK) >> + HALO_AHBM_CORE_ERR_ADDR_SHIFT);
ret = regmap_read(regmap, dsp->base_sysinfo + HALO_AHBM_WINDOW_DEBUG_0, fault); if (ret) { - adsp_warn(dsp, "Failed to read AHB DEBUG_0: %d\n", ret); + cs_dsp_warn(dsp, "Failed to read AHB DEBUG_0: %d\n", ret); goto exit_unlock; }
- adsp_warn(dsp, "AHB: SYS_ADDR: 0x%x\n", *fault); + cs_dsp_warn(dsp, "AHB: SYS_ADDR: 0x%x\n", *fault);
ret = regmap_bulk_read(regmap, dsp->base + HALO_MPU_XM_VIO_ADDR, fault, ARRAY_SIZE(fault)); if (ret) { - adsp_warn(dsp, "Failed to read MPU fault info: %d\n", ret); + cs_dsp_warn(dsp, "Failed to read MPU fault info: %d\n", ret); goto exit_unlock; }
- adsp_warn(dsp, "XM: STATUS:0x%x ADDR:0x%x\n", fault[1], fault[0]); - adsp_warn(dsp, "YM: STATUS:0x%x ADDR:0x%x\n", fault[3], fault[2]); - adsp_warn(dsp, "PM: STATUS:0x%x ADDR:0x%x\n", fault[5], fault[4]); + cs_dsp_warn(dsp, "XM: STATUS:0x%x ADDR:0x%x\n", fault[1], fault[0]); + cs_dsp_warn(dsp, "YM: STATUS:0x%x ADDR:0x%x\n", fault[3], fault[2]); + cs_dsp_warn(dsp, "PM: STATUS:0x%x ADDR:0x%x\n", fault[5], fault[4]);
ret = regmap_multi_reg_write(dsp->regmap, clear, ARRAY_SIZE(clear)); if (ret) - adsp_warn(dsp, "Failed to clear MPU status: %d\n", ret); + cs_dsp_warn(dsp, "Failed to clear MPU status: %d\n", ret);
exit_unlock: mutex_unlock(&dsp->pwr_lock); @@ -4469,7 +4475,8 @@ irqreturn_t wm_halo_wdt_expire(int irq, void *data)
mutex_lock(&dsp->pwr_lock);
- adsp_warn(dsp, "WDT Expiry Fault\n"); + cs_dsp_warn(dsp, "WDT Expiry Fault\n"); + dsp->ops->stop_watchdog(dsp); wm_adsp_fatal_error(dsp);
Split some functions into ASoC and generic portions so that existing interfaces can be retained whilst allowing the implementation to be moved out of ASoC.
Signed-off-by: Simon Trimmer simont@opensource.cirrus.com Signed-off-by: Charles Keepax ckeepax@opensource.cirrus.com --- sound/soc/codecs/wm_adsp.c | 109 ++++++++++++++++++++++++++----------- 1 file changed, 76 insertions(+), 33 deletions(-)
diff --git a/sound/soc/codecs/wm_adsp.c b/sound/soc/codecs/wm_adsp.c index cfa8f1476c00..c0ca46e04418 100644 --- a/sound/soc/codecs/wm_adsp.c +++ b/sound/soc/codecs/wm_adsp.c @@ -2771,7 +2771,7 @@ static int cs_dsp_create_name(struct wm_adsp *dsp) return 0; }
-static int wm_adsp_common_init(struct wm_adsp *dsp) +static int cs_dsp_common_init(struct wm_adsp *dsp) { int ret;
@@ -2781,19 +2781,30 @@ static int wm_adsp_common_init(struct wm_adsp *dsp)
INIT_LIST_HEAD(&dsp->alg_regions); INIT_LIST_HEAD(&dsp->ctl_list); + + mutex_init(&dsp->pwr_lock); + + return 0; +} + +static void wm_adsp_common_init(struct wm_adsp *dsp) +{ INIT_LIST_HEAD(&dsp->compr_list); INIT_LIST_HEAD(&dsp->buffer_list); - - mutex_init(&dsp->pwr_lock); - - return 0; }
-int wm_adsp1_init(struct wm_adsp *dsp) +static int cs_dsp_adsp1_init(struct wm_adsp *dsp) { dsp->ops = &cs_dsp_adsp1_ops;
- return wm_adsp_common_init(dsp); + return cs_dsp_common_init(dsp); +} + +int wm_adsp1_init(struct wm_adsp *dsp) +{ + wm_adsp_common_init(dsp); + + return cs_dsp_adsp1_init(dsp); } EXPORT_SYMBOL_GPL(wm_adsp1_init);
@@ -3096,11 +3107,8 @@ static int cs_dsp_halo_configure_mpu(struct wm_adsp *dsp, unsigned int lock_regi return regmap_multi_reg_write(dsp->regmap, config, ARRAY_SIZE(config)); }
-int wm_adsp2_set_dspclk(struct snd_soc_dapm_widget *w, unsigned int freq) +static int cs_dsp_set_dspclk(struct wm_adsp *dsp, unsigned int freq) { - struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm); - struct wm_adsp *dsps = snd_soc_component_get_drvdata(component); - struct wm_adsp *dsp = &dsps[w->shift]; int ret;
ret = regmap_update_bits(dsp->regmap, dsp->base + ADSP2_CLOCKING, @@ -3111,6 +3119,15 @@ int wm_adsp2_set_dspclk(struct snd_soc_dapm_widget *w, unsigned int freq)
return ret; } + +int wm_adsp2_set_dspclk(struct snd_soc_dapm_widget *w, unsigned int freq) +{ + struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm); + struct wm_adsp *dsps = snd_soc_component_get_drvdata(component); + struct wm_adsp *dsp = &dsps[w->shift]; + + return cs_dsp_set_dspclk(dsp, freq); +} EXPORT_SYMBOL_GPL(wm_adsp2_set_dspclk);
int wm_adsp2_preloader_get(struct snd_kcontrol *kcontrol, @@ -3364,14 +3381,10 @@ int wm_adsp2_component_remove(struct wm_adsp *dsp, struct snd_soc_component *com } EXPORT_SYMBOL_GPL(wm_adsp2_component_remove);
-int wm_adsp2_init(struct wm_adsp *dsp) +static int cs_dsp_adsp2_init(struct wm_adsp *dsp) { int ret;
- ret = wm_adsp_common_init(dsp); - if (ret) - return ret; - switch (dsp->rev) { case 0: /* @@ -3396,29 +3409,37 @@ int wm_adsp2_init(struct wm_adsp *dsp) break; }
+ return cs_dsp_common_init(dsp); +} + +int wm_adsp2_init(struct wm_adsp *dsp) +{ INIT_WORK(&dsp->boot_work, wm_adsp_boot_work);
- return 0; + wm_adsp_common_init(dsp); + + return cs_dsp_adsp2_init(dsp); } EXPORT_SYMBOL_GPL(wm_adsp2_init);
-int wm_halo_init(struct wm_adsp *dsp) +static int cs_dsp_halo_init(struct wm_adsp *dsp) { - int ret; - - ret = wm_adsp_common_init(dsp); - if (ret) - return ret; - dsp->ops = &cs_dsp_halo_ops;
+ return cs_dsp_common_init(dsp); +} + +int wm_halo_init(struct wm_adsp *dsp) +{ INIT_WORK(&dsp->boot_work, wm_adsp_boot_work);
- return 0; + wm_adsp_common_init(dsp); + + return cs_dsp_halo_init(dsp); } EXPORT_SYMBOL_GPL(wm_halo_init);
-void wm_adsp2_remove(struct wm_adsp *dsp) +static void cs_dsp_remove(struct wm_adsp *dsp) { struct wm_coeff_ctl *ctl;
@@ -3429,6 +3450,11 @@ void wm_adsp2_remove(struct wm_adsp *dsp) cs_dsp_free_ctl_blk(ctl); } } + +void wm_adsp2_remove(struct wm_adsp *dsp) +{ + cs_dsp_remove(dsp); +} EXPORT_SYMBOL_GPL(wm_adsp2_remove);
static inline int wm_adsp_compr_attached(struct wm_adsp_compr *compr) @@ -4346,9 +4372,8 @@ static void wm_adsp_fatal_error(struct wm_adsp *dsp) } }
-irqreturn_t wm_adsp2_bus_error(int irq, void *data) +static void cs_dsp_adsp2_bus_error(struct wm_adsp *dsp) { - struct wm_adsp *dsp = (struct wm_adsp *)data; unsigned int val; struct regmap *regmap = dsp->regmap; int ret = 0; @@ -4407,14 +4432,20 @@ irqreturn_t wm_adsp2_bus_error(int irq, void *data)
error: mutex_unlock(&dsp->pwr_lock); +} + +irqreturn_t wm_adsp2_bus_error(int irq, void *data) +{ + struct wm_adsp *dsp = (struct wm_adsp *)data; + + cs_dsp_adsp2_bus_error(dsp);
return IRQ_HANDLED; } EXPORT_SYMBOL_GPL(wm_adsp2_bus_error);
-irqreturn_t wm_halo_bus_error(int irq, void *data) +static void cs_dsp_halo_bus_error(struct wm_adsp *dsp) { - struct wm_adsp *dsp = (struct wm_adsp *)data; struct regmap *regmap = dsp->regmap; unsigned int fault[6]; struct reg_sequence clear[] = { @@ -4464,15 +4495,20 @@ irqreturn_t wm_halo_bus_error(int irq, void *data)
exit_unlock: mutex_unlock(&dsp->pwr_lock); +} + +irqreturn_t wm_halo_bus_error(int irq, void *data) +{ + struct wm_adsp *dsp = (struct wm_adsp *)data; + + cs_dsp_halo_bus_error(dsp);
return IRQ_HANDLED; } EXPORT_SYMBOL_GPL(wm_halo_bus_error);
-irqreturn_t wm_halo_wdt_expire(int irq, void *data) +static void cs_dsp_halo_wdt_expire(struct wm_adsp *dsp) { - struct wm_adsp *dsp = data; - mutex_lock(&dsp->pwr_lock);
cs_dsp_warn(dsp, "WDT Expiry Fault\n"); @@ -4481,6 +4517,13 @@ irqreturn_t wm_halo_wdt_expire(int irq, void *data) wm_adsp_fatal_error(dsp);
mutex_unlock(&dsp->pwr_lock); +} + +irqreturn_t wm_halo_wdt_expire(int irq, void *data) +{ + struct wm_adsp *dsp = data; + + cs_dsp_halo_wdt_expire(dsp);
return IRQ_HANDLED; }
This is preparation for moving the generic DSP support out of ASoC. This change separates the generic handling of power and state transitions from the DAPM API wrapper.
Signed-off-by: Simon Trimmer simont@opensource.cirrus.com Signed-off-by: Charles Keepax ckeepax@opensource.cirrus.com --- sound/soc/codecs/wm_adsp.c | 545 ++++++++++++++++++++----------------- 1 file changed, 298 insertions(+), 247 deletions(-)
diff --git a/sound/soc/codecs/wm_adsp.c b/sound/soc/codecs/wm_adsp.c index c0ca46e04418..1bca3922a6b8 100644 --- a/sound/soc/codecs/wm_adsp.c +++ b/sound/soc/codecs/wm_adsp.c @@ -2808,6 +2808,108 @@ int wm_adsp1_init(struct wm_adsp *dsp) } EXPORT_SYMBOL_GPL(wm_adsp1_init);
+static int cs_dsp_adsp1_power_up(struct wm_adsp *dsp) +{ + unsigned int val; + int ret; + + mutex_lock(&dsp->pwr_lock); + + regmap_update_bits(dsp->regmap, dsp->base + ADSP1_CONTROL_30, + ADSP1_SYS_ENA, ADSP1_SYS_ENA); + + /* + * For simplicity set the DSP clock rate to be the + * SYSCLK rate rather than making it configurable. + */ + if (dsp->sysclk_reg) { + ret = regmap_read(dsp->regmap, dsp->sysclk_reg, &val); + if (ret != 0) { + cs_dsp_err(dsp, "Failed to read SYSCLK state: %d\n", ret); + goto err_mutex; + } + + val = (val & dsp->sysclk_mask) >> dsp->sysclk_shift; + + ret = regmap_update_bits(dsp->regmap, + dsp->base + ADSP1_CONTROL_31, + ADSP1_CLK_SEL_MASK, val); + if (ret != 0) { + cs_dsp_err(dsp, "Failed to set clock rate: %d\n", ret); + goto err_mutex; + } + } + + ret = cs_dsp_load(dsp); + if (ret != 0) + goto err_ena; + + ret = cs_dsp_adsp1_setup_algs(dsp); + if (ret != 0) + goto err_ena; + + ret = cs_dsp_load_coeff(dsp); + if (ret != 0) + goto err_ena; + + /* Initialize caches for enabled and unset controls */ + ret = cs_dsp_coeff_init_control_caches(dsp); + if (ret != 0) + goto err_ena; + + /* Sync set controls */ + ret = cs_dsp_coeff_sync_controls(dsp); + if (ret != 0) + goto err_ena; + + dsp->booted = true; + + /* Start the core running */ + regmap_update_bits(dsp->regmap, dsp->base + ADSP1_CONTROL_30, + ADSP1_CORE_ENA | ADSP1_START, + ADSP1_CORE_ENA | ADSP1_START); + + dsp->running = true; + + mutex_unlock(&dsp->pwr_lock); + + return 0; + +err_ena: + regmap_update_bits(dsp->regmap, dsp->base + ADSP1_CONTROL_30, + ADSP1_SYS_ENA, 0); +err_mutex: + mutex_unlock(&dsp->pwr_lock); + return ret; +} + +static void cs_dsp_adsp1_power_down(struct wm_adsp *dsp) +{ + struct wm_coeff_ctl *ctl; + + mutex_lock(&dsp->pwr_lock); + + dsp->running = false; + dsp->booted = false; + + /* Halt the core */ + regmap_update_bits(dsp->regmap, dsp->base + ADSP1_CONTROL_30, + ADSP1_CORE_ENA | ADSP1_START, 0); + + regmap_update_bits(dsp->regmap, dsp->base + ADSP1_CONTROL_19, + ADSP1_WDMA_BUFFER_LENGTH_MASK, 0); + + regmap_update_bits(dsp->regmap, dsp->base + ADSP1_CONTROL_30, + ADSP1_SYS_ENA, 0); + + list_for_each_entry(ctl, &dsp->ctl_list, list) + ctl->enabled = 0; + + cs_dsp_free_alg_regions(dsp); + + mutex_unlock(&dsp->pwr_lock); +} + int wm_adsp1_event(struct snd_soc_dapm_widget *w, struct snd_kcontrol *kcontrol, int event) @@ -2815,108 +2917,21 @@ int wm_adsp1_event(struct snd_soc_dapm_widget *w, struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm); struct wm_adsp *dsps = snd_soc_component_get_drvdata(component); struct wm_adsp *dsp = &dsps[w->shift]; - struct wm_coeff_ctl *ctl; - int ret; - unsigned int val; + int ret = 0;
dsp->component = component;
- mutex_lock(&dsp->pwr_lock); - switch (event) { case SND_SOC_DAPM_POST_PMU: - regmap_update_bits(dsp->regmap, dsp->base + ADSP1_CONTROL_30, - ADSP1_SYS_ENA, ADSP1_SYS_ENA); - - /* - * For simplicity set the DSP clock rate to be the - * SYSCLK rate rather than making it configurable. - */ - if (dsp->sysclk_reg) { - ret = regmap_read(dsp->regmap, dsp->sysclk_reg, &val); - if (ret != 0) { - cs_dsp_err(dsp, "Failed to read SYSCLK state: %d\n", ret); - goto err_mutex; - } - - val = (val & dsp->sysclk_mask) >> dsp->sysclk_shift; - - ret = regmap_update_bits(dsp->regmap, - dsp->base + ADSP1_CONTROL_31, - ADSP1_CLK_SEL_MASK, val); - if (ret != 0) { - cs_dsp_err(dsp, "Failed to set clock rate: %d\n", ret); - goto err_mutex; - } - } - - ret = cs_dsp_load(dsp); - if (ret != 0) - goto err_ena; - - ret = cs_dsp_adsp1_setup_algs(dsp); - if (ret != 0) - goto err_ena; - - ret = cs_dsp_load_coeff(dsp); - if (ret != 0) - goto err_ena; - - /* Initialize caches for enabled and unset controls */ - ret = cs_dsp_coeff_init_control_caches(dsp); - if (ret != 0) - goto err_ena; - - /* Sync set controls */ - ret = cs_dsp_coeff_sync_controls(dsp); - if (ret != 0) - goto err_ena; - - dsp->booted = true; - - /* Start the core running */ - regmap_update_bits(dsp->regmap, dsp->base + ADSP1_CONTROL_30, - ADSP1_CORE_ENA | ADSP1_START, - ADSP1_CORE_ENA | ADSP1_START); - - dsp->running = true; + ret = cs_dsp_adsp1_power_up(dsp); break; - case SND_SOC_DAPM_PRE_PMD: - dsp->running = false; - dsp->booted = false; - - /* Halt the core */ - regmap_update_bits(dsp->regmap, dsp->base + ADSP1_CONTROL_30, - ADSP1_CORE_ENA | ADSP1_START, 0); - - regmap_update_bits(dsp->regmap, dsp->base + ADSP1_CONTROL_19, - ADSP1_WDMA_BUFFER_LENGTH_MASK, 0); - - regmap_update_bits(dsp->regmap, dsp->base + ADSP1_CONTROL_30, - ADSP1_SYS_ENA, 0); - - list_for_each_entry(ctl, &dsp->ctl_list, list) - ctl->enabled = 0; - - - cs_dsp_free_alg_regions(dsp); + cs_dsp_adsp1_power_down(dsp); break; - default: break; }
- mutex_unlock(&dsp->pwr_lock); - - return 0; - -err_ena: - regmap_update_bits(dsp->regmap, dsp->base + ADSP1_CONTROL_30, - ADSP1_SYS_ENA, 0); -err_mutex: - mutex_unlock(&dsp->pwr_lock); - return ret; } EXPORT_SYMBOL_GPL(wm_adsp1_event); @@ -3019,63 +3034,6 @@ static void cs_dsp_adsp2v2_disable_core(struct wm_adsp *dsp) regmap_write(dsp->regmap, dsp->base + ADSP2V2_WDMA_CONFIG_2, 0); }
-static void wm_adsp_boot_work(struct work_struct *work) -{ - struct wm_adsp *dsp = container_of(work, - struct wm_adsp, - boot_work); - int ret; - - mutex_lock(&dsp->pwr_lock); - - if (dsp->ops->enable_memory) { - ret = dsp->ops->enable_memory(dsp); - if (ret != 0) - goto err_mutex; - } - - if (dsp->ops->enable_core) { - ret = dsp->ops->enable_core(dsp); - if (ret != 0) - goto err_mem; - } - - ret = cs_dsp_load(dsp); - if (ret != 0) - goto err_ena; - - ret = dsp->ops->setup_algs(dsp); - if (ret != 0) - goto err_ena; - - ret = cs_dsp_load_coeff(dsp); - if (ret != 0) - goto err_ena; - - /* Initialize caches for enabled and unset controls */ - ret = cs_dsp_coeff_init_control_caches(dsp); - if (ret != 0) - goto err_ena; - - if (dsp->ops->disable_core) - dsp->ops->disable_core(dsp); - - dsp->booted = true; - - mutex_unlock(&dsp->pwr_lock); - - return; - -err_ena: - if (dsp->ops->disable_core) - dsp->ops->disable_core(dsp); -err_mem: - if (dsp->ops->disable_memory) - dsp->ops->disable_memory(dsp); -err_mutex: - mutex_unlock(&dsp->pwr_lock); -} - static int cs_dsp_halo_configure_mpu(struct wm_adsp *dsp, unsigned int lock_regions) { struct reg_sequence config[] = { @@ -3185,39 +3143,108 @@ static void cs_dsp_halo_stop_watchdog(struct wm_adsp *dsp) HALO_WDT_EN_MASK, 0); }
+static void cs_dsp_power_up(struct wm_adsp *dsp) +{ + int ret; + + mutex_lock(&dsp->pwr_lock); + + if (dsp->ops->enable_memory) { + ret = dsp->ops->enable_memory(dsp); + if (ret != 0) + goto err_mutex; + } + + if (dsp->ops->enable_core) { + ret = dsp->ops->enable_core(dsp); + if (ret != 0) + goto err_mem; + } + + ret = cs_dsp_load(dsp); + if (ret != 0) + goto err_ena; + + ret = dsp->ops->setup_algs(dsp); + if (ret != 0) + goto err_ena; + + ret = cs_dsp_load_coeff(dsp); + if (ret != 0) + goto err_ena; + + /* Initialize caches for enabled and unset controls */ + ret = cs_dsp_coeff_init_control_caches(dsp); + if (ret != 0) + goto err_ena; + + if (dsp->ops->disable_core) + dsp->ops->disable_core(dsp); + + dsp->booted = true; + + mutex_unlock(&dsp->pwr_lock); + + return; + +err_ena: + if (dsp->ops->disable_core) + dsp->ops->disable_core(dsp); +err_mem: + if (dsp->ops->disable_memory) + dsp->ops->disable_memory(dsp); +err_mutex: + mutex_unlock(&dsp->pwr_lock); +} + +static void cs_dsp_power_down(struct wm_adsp *dsp) +{ + struct wm_coeff_ctl *ctl; + + mutex_lock(&dsp->pwr_lock); + + cs_dsp_debugfs_clear(dsp); + + dsp->fw_id = 0; + dsp->fw_id_version = 0; + + dsp->booted = false; + + if (dsp->ops->disable_memory) + dsp->ops->disable_memory(dsp); + + list_for_each_entry(ctl, &dsp->ctl_list, list) + ctl->enabled = 0; + + cs_dsp_free_alg_regions(dsp); + + mutex_unlock(&dsp->pwr_lock); + + cs_dsp_dbg(dsp, "Shutdown complete\n"); +} + +static void wm_adsp_boot_work(struct work_struct *work) +{ + struct wm_adsp *dsp = container_of(work, + struct wm_adsp, + boot_work); + + cs_dsp_power_up(dsp); +} + int wm_adsp_early_event(struct snd_soc_dapm_widget *w, struct snd_kcontrol *kcontrol, int event) { struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm); struct wm_adsp *dsps = snd_soc_component_get_drvdata(component); struct wm_adsp *dsp = &dsps[w->shift]; - struct wm_coeff_ctl *ctl;
switch (event) { case SND_SOC_DAPM_PRE_PMU: queue_work(system_unbound_wq, &dsp->boot_work); break; case SND_SOC_DAPM_PRE_PMD: - mutex_lock(&dsp->pwr_lock); - - cs_dsp_debugfs_clear(dsp); - - dsp->fw_id = 0; - dsp->fw_id_version = 0; - - dsp->booted = false; - - if (dsp->ops->disable_memory) - dsp->ops->disable_memory(dsp); - - list_for_each_entry(ctl, &dsp->ctl_list, list) - ctl->enabled = 0; - - cs_dsp_free_alg_regions(dsp); - - mutex_unlock(&dsp->pwr_lock); - - cs_dsp_dbg(dsp, "Shutdown complete\n"); + cs_dsp_power_down(dsp); break; default: break; @@ -3240,102 +3267,126 @@ static void cs_dsp_adsp2_stop_core(struct wm_adsp *dsp) ADSP2_CORE_ENA | ADSP2_START, 0); }
+static int wm_adsp_event_post_run(struct wm_adsp *dsp) +{ + if (wm_adsp_fw[dsp->fw].num_caps != 0) + return wm_adsp_buffer_init(dsp); + + return 0; +} + +static void wm_adsp_event_post_stop(struct wm_adsp *dsp) +{ + if (wm_adsp_fw[dsp->fw].num_caps != 0) + wm_adsp_buffer_free(dsp); + + dsp->fatal_error = false; +} + +static int cs_dsp_run(struct wm_adsp *dsp) +{ + int ret; + + mutex_lock(&dsp->pwr_lock); + + if (!dsp->booted) { + ret = -EIO; + goto err; + } + + if (dsp->ops->enable_core) { + ret = dsp->ops->enable_core(dsp); + if (ret != 0) + goto err; + } + + /* Sync set controls */ + ret = cs_dsp_coeff_sync_controls(dsp); + if (ret != 0) + goto err; + + if (dsp->ops->lock_memory) { + ret = dsp->ops->lock_memory(dsp, dsp->lock_regions); + if (ret != 0) { + cs_dsp_err(dsp, "Error configuring MPU: %d\n", ret); + goto err; + } + } + + if (dsp->ops->start_core) { + ret = dsp->ops->start_core(dsp); + if (ret != 0) + goto err; + } + + dsp->running = true; + + ret = wm_adsp_event_post_run(dsp); + if (ret < 0) + goto err; + + mutex_unlock(&dsp->pwr_lock); + + return 0; + +err: + if (dsp->ops->stop_core) + dsp->ops->stop_core(dsp); + if (dsp->ops->disable_core) + dsp->ops->disable_core(dsp); + mutex_unlock(&dsp->pwr_lock); + + return ret; +} + +static void cs_dsp_stop(struct wm_adsp *dsp) +{ + /* Tell the firmware to cleanup */ + cs_dsp_signal_event_controls(dsp, CS_DSP_FW_EVENT_SHUTDOWN); + + if (dsp->ops->stop_watchdog) + dsp->ops->stop_watchdog(dsp); + + /* Log firmware state, it can be useful for analysis */ + if (dsp->ops->show_fw_status) + dsp->ops->show_fw_status(dsp); + + mutex_lock(&dsp->pwr_lock); + + dsp->running = false; + + if (dsp->ops->stop_core) + dsp->ops->stop_core(dsp); + if (dsp->ops->disable_core) + dsp->ops->disable_core(dsp); + + wm_adsp_event_post_stop(dsp); + + mutex_unlock(&dsp->pwr_lock); + + cs_dsp_dbg(dsp, "Execution stopped\n"); +} + int wm_adsp_event(struct snd_soc_dapm_widget *w, struct snd_kcontrol *kcontrol, int event) { struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm); struct wm_adsp *dsps = snd_soc_component_get_drvdata(component); struct wm_adsp *dsp = &dsps[w->shift]; - int ret; + int ret = 0;
switch (event) { case SND_SOC_DAPM_POST_PMU: flush_work(&dsp->boot_work); - - mutex_lock(&dsp->pwr_lock); - - if (!dsp->booted) { - ret = -EIO; - goto err; - } - - if (dsp->ops->enable_core) { - ret = dsp->ops->enable_core(dsp); - if (ret != 0) - goto err; - } - - /* Sync set controls */ - ret = cs_dsp_coeff_sync_controls(dsp); - if (ret != 0) - goto err; - - if (dsp->ops->lock_memory) { - ret = dsp->ops->lock_memory(dsp, dsp->lock_regions); - if (ret != 0) { - cs_dsp_err(dsp, "Error configuring MPU: %d\n", ret); - goto err; - } - } - - if (dsp->ops->start_core) { - ret = dsp->ops->start_core(dsp); - if (ret != 0) - goto err; - } - - dsp->running = true; - - if (wm_adsp_fw[dsp->fw].num_caps != 0) { - ret = wm_adsp_buffer_init(dsp); - if (ret < 0) - goto err; - } - - mutex_unlock(&dsp->pwr_lock); + ret = cs_dsp_run(dsp); break; - case SND_SOC_DAPM_PRE_PMD: - /* Tell the firmware to cleanup */ - cs_dsp_signal_event_controls(dsp, CS_DSP_FW_EVENT_SHUTDOWN); - - if (dsp->ops->stop_watchdog) - dsp->ops->stop_watchdog(dsp); - - /* Log firmware state, it can be useful for analysis */ - if (dsp->ops->show_fw_status) - dsp->ops->show_fw_status(dsp); - - mutex_lock(&dsp->pwr_lock); - - dsp->running = false; - - if (dsp->ops->stop_core) - dsp->ops->stop_core(dsp); - if (dsp->ops->disable_core) - dsp->ops->disable_core(dsp); - - if (wm_adsp_fw[dsp->fw].num_caps != 0) - wm_adsp_buffer_free(dsp); - - dsp->fatal_error = false; - - mutex_unlock(&dsp->pwr_lock); - - cs_dsp_dbg(dsp, "Execution stopped\n"); + cs_dsp_stop(dsp); break; - default: break; }
- return 0; -err: - if (dsp->ops->stop_core) - dsp->ops->stop_core(dsp); - if (dsp->ops->disable_core) - dsp->ops->disable_core(dsp); - mutex_unlock(&dsp->pwr_lock); return ret; } EXPORT_SYMBOL_GPL(wm_adsp_event);
From: Charles Keepax ckeepax@opensource.cirrus.com
sys_config_size is part of the compressed stream support, move it from what will become generic DSP code so that it remains in ASoC.
Signed-off-by: Charles Keepax ckeepax@opensource.cirrus.com Signed-off-by: Simon Trimmer simont@opensource.cirrus.com --- sound/soc/codecs/wm_adsp.c | 10 +++++----- sound/soc/codecs/wm_adsp.h | 4 ++-- 2 files changed, 7 insertions(+), 7 deletions(-)
diff --git a/sound/soc/codecs/wm_adsp.c b/sound/soc/codecs/wm_adsp.c index 1bca3922a6b8..82038cac4286 100644 --- a/sound/soc/codecs/wm_adsp.c +++ b/sound/soc/codecs/wm_adsp.c @@ -3467,6 +3467,8 @@ int wm_adsp2_init(struct wm_adsp *dsp) { INIT_WORK(&dsp->boot_work, wm_adsp_boot_work);
+ dsp->sys_config_size = sizeof(struct wm_adsp_system_config_xm_hdr); + wm_adsp_common_init(dsp);
return cs_dsp_adsp2_init(dsp); @@ -3484,6 +3486,8 @@ int wm_halo_init(struct wm_adsp *dsp) { INIT_WORK(&dsp->boot_work, wm_adsp_boot_work);
+ dsp->sys_config_size = sizeof(struct wm_halo_system_config_xm_hdr); + wm_adsp_common_init(dsp);
return cs_dsp_halo_init(dsp); @@ -3895,7 +3899,7 @@ static int wm_adsp_buffer_parse_legacy(struct wm_adsp *dsp) if (!buf) return -ENOMEM;
- xmalg = dsp->ops->sys_config_size / sizeof(__be32); + xmalg = dsp->sys_config_size / sizeof(__be32);
addr = alg_region->base + xmalg + ALG_XM_FIELD(magic); ret = cs_dsp_read_data_word(dsp, WMFW_ADSP2_XM, addr, &magic); @@ -4588,7 +4592,6 @@ static const struct cs_dsp_ops cs_dsp_adsp1_ops = {
static const struct cs_dsp_ops cs_dsp_adsp2_ops[] = { { - .sys_config_size = sizeof(struct wm_adsp_system_config_xm_hdr), .parse_sizes = cs_dsp_adsp2_parse_sizes, .validate_version = cs_dsp_validate_version, .setup_algs = cs_dsp_adsp2_setup_algs, @@ -4607,7 +4610,6 @@ static const struct cs_dsp_ops cs_dsp_adsp2_ops[] = {
}, { - .sys_config_size = sizeof(struct wm_adsp_system_config_xm_hdr), .parse_sizes = cs_dsp_adsp2_parse_sizes, .validate_version = cs_dsp_validate_version, .setup_algs = cs_dsp_adsp2_setup_algs, @@ -4626,7 +4628,6 @@ static const struct cs_dsp_ops cs_dsp_adsp2_ops[] = { .stop_core = cs_dsp_adsp2_stop_core, }, { - .sys_config_size = sizeof(struct wm_adsp_system_config_xm_hdr), .parse_sizes = cs_dsp_adsp2_parse_sizes, .validate_version = cs_dsp_validate_version, .setup_algs = cs_dsp_adsp2_setup_algs, @@ -4648,7 +4649,6 @@ static const struct cs_dsp_ops cs_dsp_adsp2_ops[] = { };
static const struct cs_dsp_ops cs_dsp_halo_ops = { - .sys_config_size = sizeof(struct wm_halo_system_config_xm_hdr), .parse_sizes = cs_dsp_adsp2_parse_sizes, .validate_version = cs_dsp_halo_validate_version, .setup_algs = cs_dsp_halo_setup_algs, diff --git a/sound/soc/codecs/wm_adsp.h b/sound/soc/codecs/wm_adsp.h index 114bc41981ef..98b12b485916 100644 --- a/sound/soc/codecs/wm_adsp.h +++ b/sound/soc/codecs/wm_adsp.h @@ -81,6 +81,8 @@ struct wm_adsp { const struct cs_dsp_region *mem; int num_mems;
+ unsigned int sys_config_size; + int fw; int fw_ver;
@@ -109,8 +111,6 @@ struct wm_adsp { };
struct cs_dsp_ops { - unsigned int sys_config_size; - bool (*validate_version)(struct wm_adsp *dsp, unsigned int version); unsigned int (*parse_sizes)(struct wm_adsp *dsp, const char * const file,
This is preparation for moving the generic DSP support out of ASoC. The majority of the handling of firmware controls is generic and this change separates the generic and ASoC specific details into separate structures and functions and renames the generic code named wm_* to cs_*.
Signed-off-by: Simon Trimmer simont@opensource.cirrus.com Signed-off-by: Charles Keepax ckeepax@opensource.cirrus.com --- sound/soc/codecs/wm_adsp.c | 283 ++++++++++++++++++++----------------- sound/soc/codecs/wm_adsp.h | 20 +++ 2 files changed, 176 insertions(+), 127 deletions(-)
diff --git a/sound/soc/codecs/wm_adsp.c b/sound/soc/codecs/wm_adsp.c index 82038cac4286..bd335e4240e5 100644 --- a/sound/soc/codecs/wm_adsp.c +++ b/sound/soc/codecs/wm_adsp.c @@ -607,21 +607,8 @@ static const struct {
struct wm_coeff_ctl { const char *name; - const char *fw_name; - /* Subname is needed to match with firmware */ - const char *subname; - unsigned int subname_len; - struct cs_dsp_alg_region alg_region; - struct wm_adsp *dsp; - unsigned int enabled:1; - struct list_head list; - void *cache; - unsigned int offset; - size_t len; - unsigned int set:1; + struct cs_dsp_coeff_ctl *cs_ctl; struct soc_bytes_ext bytes_ext; - unsigned int flags; - unsigned int type; struct work_struct work; };
@@ -938,7 +925,7 @@ static inline struct wm_coeff_ctl *bytes_ext_to_ctl(struct soc_bytes_ext *ext) return container_of(ext, struct wm_coeff_ctl, bytes_ext); }
-static int cs_dsp_coeff_base_reg(struct wm_coeff_ctl *ctl, unsigned int *reg) +static int cs_dsp_coeff_base_reg(struct cs_dsp_coeff_ctl *ctl, unsigned int *reg) { const struct cs_dsp_alg_region *alg_region = &ctl->alg_region; struct wm_adsp *dsp = ctl->dsp; @@ -962,8 +949,9 @@ static int wm_coeff_info(struct snd_kcontrol *kctl, struct soc_bytes_ext *bytes_ext = (struct soc_bytes_ext *)kctl->private_value; struct wm_coeff_ctl *ctl = bytes_ext_to_ctl(bytes_ext); + struct cs_dsp_coeff_ctl *cs_ctl = ctl->cs_ctl;
- switch (ctl->type) { + switch (cs_ctl->type) { case WMFW_CTL_TYPE_ACKED: uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; uinfo->value.integer.min = CS_DSP_ACKED_CTL_MIN_VALUE; @@ -973,14 +961,14 @@ static int wm_coeff_info(struct snd_kcontrol *kctl, break; default: uinfo->type = SNDRV_CTL_ELEM_TYPE_BYTES; - uinfo->count = ctl->len; + uinfo->count = cs_ctl->len; break; }
return 0; }
-static int cs_dsp_coeff_write_acked_control(struct wm_coeff_ctl *ctl, +static int cs_dsp_coeff_write_acked_control(struct cs_dsp_coeff_ctl *ctl, unsigned int event_id) { struct wm_adsp *dsp = ctl->dsp; @@ -1040,7 +1028,7 @@ static int cs_dsp_coeff_write_acked_control(struct wm_coeff_ctl *ctl, return -ETIMEDOUT; }
-static int cs_dsp_coeff_write_ctrl_raw(struct wm_coeff_ctl *ctl, +static int cs_dsp_coeff_write_ctrl_raw(struct cs_dsp_coeff_ctl *ctl, const void *buf, size_t len) { struct wm_adsp *dsp = ctl->dsp; @@ -1071,7 +1059,7 @@ static int cs_dsp_coeff_write_ctrl_raw(struct wm_coeff_ctl *ctl, return 0; }
-static int cs_dsp_coeff_write_ctrl(struct wm_coeff_ctl *ctl, +static int cs_dsp_coeff_write_ctrl(struct cs_dsp_coeff_ctl *ctl, const void *buf, size_t len) { int ret = 0; @@ -1094,12 +1082,13 @@ static int wm_coeff_put(struct snd_kcontrol *kctl, struct soc_bytes_ext *bytes_ext = (struct soc_bytes_ext *)kctl->private_value; struct wm_coeff_ctl *ctl = bytes_ext_to_ctl(bytes_ext); + struct cs_dsp_coeff_ctl *cs_ctl = ctl->cs_ctl; char *p = ucontrol->value.bytes.data; int ret = 0;
- mutex_lock(&ctl->dsp->pwr_lock); - ret = cs_dsp_coeff_write_ctrl(ctl, p, ctl->len); - mutex_unlock(&ctl->dsp->pwr_lock); + mutex_lock(&cs_ctl->dsp->pwr_lock); + ret = cs_dsp_coeff_write_ctrl(cs_ctl, p, cs_ctl->len); + mutex_unlock(&cs_ctl->dsp->pwr_lock);
return ret; } @@ -1110,16 +1099,17 @@ static int wm_coeff_tlv_put(struct snd_kcontrol *kctl, struct soc_bytes_ext *bytes_ext = (struct soc_bytes_ext *)kctl->private_value; struct wm_coeff_ctl *ctl = bytes_ext_to_ctl(bytes_ext); + struct cs_dsp_coeff_ctl *cs_ctl = ctl->cs_ctl; int ret = 0;
- mutex_lock(&ctl->dsp->pwr_lock); + mutex_lock(&cs_ctl->dsp->pwr_lock);
- if (copy_from_user(ctl->cache, bytes, size)) + if (copy_from_user(cs_ctl->cache, bytes, size)) ret = -EFAULT; else - ret = cs_dsp_coeff_write_ctrl(ctl, ctl->cache, size); + ret = cs_dsp_coeff_write_ctrl(cs_ctl, cs_ctl->cache, size);
- mutex_unlock(&ctl->dsp->pwr_lock); + mutex_unlock(&cs_ctl->dsp->pwr_lock);
return ret; } @@ -1130,25 +1120,26 @@ static int wm_coeff_put_acked(struct snd_kcontrol *kctl, struct soc_bytes_ext *bytes_ext = (struct soc_bytes_ext *)kctl->private_value; struct wm_coeff_ctl *ctl = bytes_ext_to_ctl(bytes_ext); + struct cs_dsp_coeff_ctl *cs_ctl = ctl->cs_ctl; unsigned int val = ucontrol->value.integer.value[0]; int ret;
if (val == 0) return 0; /* 0 means no event */
- mutex_lock(&ctl->dsp->pwr_lock); + mutex_lock(&cs_ctl->dsp->pwr_lock);
- if (ctl->enabled && ctl->dsp->running) - ret = cs_dsp_coeff_write_acked_control(ctl, val); + if (cs_ctl->enabled && cs_ctl->dsp->running) + ret = cs_dsp_coeff_write_acked_control(cs_ctl, val); else ret = -EPERM;
- mutex_unlock(&ctl->dsp->pwr_lock); + mutex_unlock(&cs_ctl->dsp->pwr_lock);
return ret; }
-static int cs_dsp_coeff_read_ctrl_raw(struct wm_coeff_ctl *ctl, +static int cs_dsp_coeff_read_ctrl_raw(struct cs_dsp_coeff_ctl *ctl, void *buf, size_t len) { struct wm_adsp *dsp = ctl->dsp; @@ -1179,7 +1170,7 @@ static int cs_dsp_coeff_read_ctrl_raw(struct wm_coeff_ctl *ctl, return 0; }
-static int cs_dsp_coeff_read_ctrl(struct wm_coeff_ctl *ctl, void *buf, size_t len) +static int cs_dsp_coeff_read_ctrl(struct cs_dsp_coeff_ctl *ctl, void *buf, size_t len) { int ret = 0;
@@ -1205,12 +1196,13 @@ static int wm_coeff_get(struct snd_kcontrol *kctl, struct soc_bytes_ext *bytes_ext = (struct soc_bytes_ext *)kctl->private_value; struct wm_coeff_ctl *ctl = bytes_ext_to_ctl(bytes_ext); + struct cs_dsp_coeff_ctl *cs_ctl = ctl->cs_ctl; char *p = ucontrol->value.bytes.data; int ret;
- mutex_lock(&ctl->dsp->pwr_lock); - ret = cs_dsp_coeff_read_ctrl(ctl, p, ctl->len); - mutex_unlock(&ctl->dsp->pwr_lock); + mutex_lock(&cs_ctl->dsp->pwr_lock); + ret = cs_dsp_coeff_read_ctrl(cs_ctl, p, cs_ctl->len); + mutex_unlock(&cs_ctl->dsp->pwr_lock);
return ret; } @@ -1221,16 +1213,17 @@ static int wm_coeff_tlv_get(struct snd_kcontrol *kctl, struct soc_bytes_ext *bytes_ext = (struct soc_bytes_ext *)kctl->private_value; struct wm_coeff_ctl *ctl = bytes_ext_to_ctl(bytes_ext); + struct cs_dsp_coeff_ctl *cs_ctl = ctl->cs_ctl; int ret = 0;
- mutex_lock(&ctl->dsp->pwr_lock); + mutex_lock(&cs_ctl->dsp->pwr_lock);
- ret = cs_dsp_coeff_read_ctrl(ctl, ctl->cache, size); + ret = cs_dsp_coeff_read_ctrl(cs_ctl, cs_ctl->cache, size);
- if (!ret && copy_to_user(bytes, ctl->cache, size)) + if (!ret && copy_to_user(bytes, cs_ctl->cache, size)) ret = -EFAULT;
- mutex_unlock(&ctl->dsp->pwr_lock); + mutex_unlock(&cs_ctl->dsp->pwr_lock);
return ret; } @@ -1283,12 +1276,10 @@ static unsigned int wmfw_convert_flags(unsigned int in, unsigned int len)
static int wmfw_add_ctl(struct wm_adsp *dsp, struct wm_coeff_ctl *ctl) { + struct cs_dsp_coeff_ctl *cs_ctl = ctl->cs_ctl; struct snd_kcontrol_new *kcontrol; int ret;
- if (!ctl || !ctl->name) - return -EINVAL; - kcontrol = kzalloc(sizeof(*kcontrol), GFP_KERNEL); if (!kcontrol) return -ENOMEM; @@ -1298,16 +1289,16 @@ static int wmfw_add_ctl(struct wm_adsp *dsp, struct wm_coeff_ctl *ctl) kcontrol->iface = SNDRV_CTL_ELEM_IFACE_MIXER; kcontrol->tlv.c = snd_soc_bytes_tlv_callback; kcontrol->private_value = (unsigned long)&ctl->bytes_ext; - kcontrol->access = wmfw_convert_flags(ctl->flags, ctl->len); + kcontrol->access = wmfw_convert_flags(cs_ctl->flags, cs_ctl->len);
- switch (ctl->type) { + switch (cs_ctl->type) { case WMFW_CTL_TYPE_ACKED: kcontrol->get = wm_coeff_get_acked; kcontrol->put = wm_coeff_put_acked; break; default: if (kcontrol->access & SNDRV_CTL_ELEM_ACCESS_TLV_CALLBACK) { - ctl->bytes_ext.max = ctl->len; + ctl->bytes_ext.max = cs_ctl->len; ctl->bytes_ext.get = wm_coeff_tlv_get; ctl->bytes_ext.put = wm_coeff_tlv_put; } else { @@ -1332,7 +1323,7 @@ static int wmfw_add_ctl(struct wm_adsp *dsp, struct wm_coeff_ctl *ctl)
static int cs_dsp_coeff_init_control_caches(struct wm_adsp *dsp) { - struct wm_coeff_ctl *ctl; + struct cs_dsp_coeff_ctl *ctl; int ret;
list_for_each_entry(ctl, &dsp->ctl_list, list) { @@ -1358,7 +1349,7 @@ static int cs_dsp_coeff_init_control_caches(struct wm_adsp *dsp)
static int cs_dsp_coeff_sync_controls(struct wm_adsp *dsp) { - struct wm_coeff_ctl *ctl; + struct cs_dsp_coeff_ctl *ctl; int ret;
list_for_each_entry(ctl, &dsp->ctl_list, list) { @@ -1378,7 +1369,7 @@ static int cs_dsp_coeff_sync_controls(struct wm_adsp *dsp) static void cs_dsp_signal_event_controls(struct wm_adsp *dsp, unsigned int event) { - struct wm_coeff_ctl *ctl; + struct cs_dsp_coeff_ctl *ctl; int ret;
list_for_each_entry(ctl, &dsp->ctl_list, list) { @@ -1401,47 +1392,30 @@ static void wm_adsp_ctl_work(struct work_struct *work) struct wm_coeff_ctl *ctl = container_of(work, struct wm_coeff_ctl, work); - - wmfw_add_ctl(ctl->dsp, ctl); + wmfw_add_ctl(ctl->cs_ctl->dsp, ctl); }
-static void cs_dsp_free_ctl_blk(struct wm_coeff_ctl *ctl) +static void cs_dsp_free_ctl_blk(struct cs_dsp_coeff_ctl *ctl) { - cancel_work_sync(&ctl->work); - kfree(ctl->cache); - kfree(ctl->name); kfree(ctl->subname); kfree(ctl); }
-static int cs_dsp_create_control(struct wm_adsp *dsp, - const struct cs_dsp_alg_region *alg_region, - unsigned int offset, unsigned int len, - const char *subname, unsigned int subname_len, - unsigned int flags, unsigned int type) +static int wm_adsp_control_add(struct cs_dsp_coeff_ctl *cs_ctl) { + struct wm_adsp *dsp = cs_ctl->dsp; struct wm_coeff_ctl *ctl; char name[SNDRV_CTL_ELEM_ID_NAME_MAXLEN]; const char *region_name; int ret;
- list_for_each_entry(ctl, &dsp->ctl_list, list) { - if (ctl->fw_name == wm_adsp_fw_text[dsp->fw] && - ctl->alg_region.alg == alg_region->alg && - ctl->alg_region.type == alg_region->type) { - if ((!subname && !ctl->subname) || - (subname && !strncmp(ctl->subname, subname, ctl->subname_len))) { - if (!ctl->enabled) - ctl->enabled = 1; - return 0; - } - } - } + if (cs_ctl->flags & WMFW_CTL_FLAG_SYS) + return 0;
- region_name = cs_dsp_mem_region_name(alg_region->type); + region_name = cs_dsp_mem_region_name(cs_ctl->alg_region.type); if (!region_name) { - cs_dsp_err(dsp, "Unknown region type: %d\n", alg_region->type); + adsp_err(dsp, "Unknown region type: %d\n", cs_ctl->alg_region.type); return -EINVAL; }
@@ -1449,22 +1423,21 @@ static int cs_dsp_create_control(struct wm_adsp *dsp, case 0: case 1: snprintf(name, SNDRV_CTL_ELEM_ID_NAME_MAXLEN, "%s %s %x", - dsp->name, region_name, alg_region->alg); - subname = NULL; /* don't append subname */ + dsp->name, region_name, cs_ctl->alg_region.alg); break; case 2: ret = scnprintf(name, SNDRV_CTL_ELEM_ID_NAME_MAXLEN, "%s%c %.12s %x", dsp->name, *region_name, - wm_adsp_fw_text[dsp->fw], alg_region->alg); + wm_adsp_fw_text[dsp->fw], cs_ctl->alg_region.alg); break; default: ret = scnprintf(name, SNDRV_CTL_ELEM_ID_NAME_MAXLEN, "%s %.12s %x", dsp->name, - wm_adsp_fw_text[dsp->fw], alg_region->alg); + wm_adsp_fw_text[dsp->fw], cs_ctl->alg_region.alg); break; }
- if (subname) { + if (cs_ctl->subname) { int avail = SNDRV_CTL_ELEM_ID_NAME_MAXLEN - ret - 2; int skip = 0;
@@ -1472,30 +1445,81 @@ static int cs_dsp_create_control(struct wm_adsp *dsp, avail -= strlen(dsp->component->name_prefix) + 1;
/* Truncate the subname from the start if it is too long */ - if (subname_len > avail) - skip = subname_len - avail; + if (cs_ctl->subname_len > avail) + skip = cs_ctl->subname_len - avail;
snprintf(name + ret, SNDRV_CTL_ELEM_ID_NAME_MAXLEN - ret, - " %.*s", subname_len - skip, subname + skip); + " %.*s", cs_ctl->subname_len - skip, cs_ctl->subname + skip); }
ctl = kzalloc(sizeof(*ctl), GFP_KERNEL); if (!ctl) return -ENOMEM; - ctl->fw_name = wm_adsp_fw_text[dsp->fw]; - ctl->alg_region = *alg_region; + ctl->cs_ctl = cs_ctl; + ctl->name = kmemdup(name, strlen(name) + 1, GFP_KERNEL); if (!ctl->name) { ret = -ENOMEM; goto err_ctl; } - if (subname) { + + cs_ctl->priv = ctl; + + INIT_WORK(&ctl->work, wm_adsp_ctl_work); + schedule_work(&ctl->work); + + return 0; + +err_ctl: + kfree(ctl); + + return ret; +} + +static void wm_adsp_control_remove(struct cs_dsp_coeff_ctl *cs_ctl) +{ + struct wm_coeff_ctl *ctl = cs_ctl->priv; + + cancel_work_sync(&ctl->work); + + kfree(ctl->name); + kfree(ctl); +} + +static int cs_dsp_create_control(struct wm_adsp *dsp, + const struct cs_dsp_alg_region *alg_region, + unsigned int offset, unsigned int len, + const char *subname, unsigned int subname_len, + unsigned int flags, unsigned int type) +{ + struct cs_dsp_coeff_ctl *ctl; + int ret; + + list_for_each_entry(ctl, &dsp->ctl_list, list) { + if (ctl->fw_name == wm_adsp_fw_text[dsp->fw] && + ctl->alg_region.alg == alg_region->alg && + ctl->alg_region.type == alg_region->type) { + if ((!subname && !ctl->subname) || + (subname && !strncmp(ctl->subname, subname, ctl->subname_len))) { + if (!ctl->enabled) + ctl->enabled = 1; + return 0; + } + } + } + + ctl = kzalloc(sizeof(*ctl), GFP_KERNEL); + if (!ctl) + return -ENOMEM; + ctl->fw_name = wm_adsp_fw_text[dsp->fw]; + ctl->alg_region = *alg_region; + if (subname && dsp->fw_ver >= 2) { ctl->subname_len = subname_len; ctl->subname = kmemdup(subname, strlen(subname) + 1, GFP_KERNEL); if (!ctl->subname) { ret = -ENOMEM; - goto err_ctl_name; + goto err_ctl; } } ctl->enabled = 1; @@ -1514,18 +1538,17 @@ static int cs_dsp_create_control(struct wm_adsp *dsp,
list_add(&ctl->list, &dsp->ctl_list);
- if (flags & WMFW_CTL_FLAG_SYS) - return 0; - - INIT_WORK(&ctl->work, wm_adsp_ctl_work); - schedule_work(&ctl->work); + ret = wm_adsp_control_add(ctl); + if (ret) + goto err_list_del;
return 0;
+err_list_del: + list_del(&ctl->list); + kfree(ctl->cache); err_ctl_subname: kfree(ctl->subname); -err_ctl_name: - kfree(ctl->name); err_ctl: kfree(ctl);
@@ -2013,14 +2036,14 @@ static int cs_dsp_load(struct wm_adsp *dsp) }
/* - * Find wm_coeff_ctl with input name as its subname + * Find cs_dsp_coeff_ctl with input name as its subname * If not found, return NULL */ -static struct wm_coeff_ctl *cs_dsp_get_ctl(struct wm_adsp *dsp, - const char *name, int type, - unsigned int alg) +static struct cs_dsp_coeff_ctl *cs_dsp_get_ctl(struct wm_adsp *dsp, + const char *name, int type, + unsigned int alg) { - struct wm_coeff_ctl *pos, *rslt = NULL; + struct cs_dsp_coeff_ctl *pos, *rslt = NULL; const char *fw_txt = wm_adsp_fw_text[dsp->fw];
list_for_each_entry(pos, &dsp->ctl_list, list) { @@ -2041,23 +2064,26 @@ static struct wm_coeff_ctl *cs_dsp_get_ctl(struct wm_adsp *dsp, int wm_adsp_write_ctl(struct wm_adsp *dsp, const char *name, int type, unsigned int alg, void *buf, size_t len) { + struct cs_dsp_coeff_ctl *cs_ctl; struct wm_coeff_ctl *ctl; struct snd_kcontrol *kcontrol; char ctl_name[SNDRV_CTL_ELEM_ID_NAME_MAXLEN]; int ret;
- ctl = cs_dsp_get_ctl(dsp, name, type, alg); - if (!ctl) + cs_ctl = cs_dsp_get_ctl(dsp, name, type, alg); + if (!cs_ctl) return -EINVAL;
- if (len > ctl->len) + ctl = cs_ctl->priv; + + if (len > cs_ctl->len) return -EINVAL;
- ret = cs_dsp_coeff_write_ctrl(ctl, buf, len); + ret = cs_dsp_coeff_write_ctrl(cs_ctl, buf, len); if (ret) return ret;
- if (ctl->flags & WMFW_CTL_FLAG_SYS) + if (cs_ctl->flags & WMFW_CTL_FLAG_SYS) return 0;
if (dsp->component->name_prefix) @@ -2083,23 +2109,23 @@ EXPORT_SYMBOL_GPL(wm_adsp_write_ctl); int wm_adsp_read_ctl(struct wm_adsp *dsp, const char *name, int type, unsigned int alg, void *buf, size_t len) { - struct wm_coeff_ctl *ctl; + struct cs_dsp_coeff_ctl *cs_ctl;
- ctl = cs_dsp_get_ctl(dsp, name, type, alg); - if (!ctl) + cs_ctl = cs_dsp_get_ctl(dsp, name, type, alg); + if (!cs_ctl) return -EINVAL;
- if (len > ctl->len) + if (len > cs_ctl->len) return -EINVAL;
- return cs_dsp_coeff_read_ctrl(ctl, buf, len); + return cs_dsp_coeff_read_ctrl(cs_ctl, buf, len); } EXPORT_SYMBOL_GPL(wm_adsp_read_ctl);
static void cs_dsp_ctl_fixup_base(struct wm_adsp *dsp, const struct cs_dsp_alg_region *alg_region) { - struct wm_coeff_ctl *ctl; + struct cs_dsp_coeff_ctl *ctl;
list_for_each_entry(ctl, &dsp->ctl_list, list) { if (ctl->fw_name == wm_adsp_fw_text[dsp->fw] && @@ -2885,7 +2911,7 @@ static int cs_dsp_adsp1_power_up(struct wm_adsp *dsp)
static void cs_dsp_adsp1_power_down(struct wm_adsp *dsp) { - struct wm_coeff_ctl *ctl; + struct cs_dsp_coeff_ctl *ctl;
mutex_lock(&dsp->pwr_lock);
@@ -3199,7 +3225,7 @@ static void cs_dsp_power_up(struct wm_adsp *dsp)
static void cs_dsp_power_down(struct wm_adsp *dsp) { - struct wm_coeff_ctl *ctl; + struct cs_dsp_coeff_ctl *ctl;
mutex_lock(&dsp->pwr_lock);
@@ -3496,11 +3522,13 @@ EXPORT_SYMBOL_GPL(wm_halo_init);
static void cs_dsp_remove(struct wm_adsp *dsp) { - struct wm_coeff_ctl *ctl; + struct cs_dsp_coeff_ctl *ctl;
while (!list_empty(&dsp->ctl_list)) { - ctl = list_first_entry(&dsp->ctl_list, struct wm_coeff_ctl, - list); + ctl = list_first_entry(&dsp->ctl_list, struct cs_dsp_coeff_ctl, list); + + wm_adsp_control_remove(ctl); + list_del(&ctl->list); cs_dsp_free_ctl_blk(ctl); } @@ -3936,15 +3964,16 @@ static int wm_adsp_buffer_parse_legacy(struct wm_adsp *dsp) return 0; }
-static int wm_adsp_buffer_parse_coeff(struct wm_coeff_ctl *ctl) +static int wm_adsp_buffer_parse_coeff(struct cs_dsp_coeff_ctl *cs_ctl) { struct wm_adsp_host_buf_coeff_v1 coeff_v1; struct wm_adsp_compr_buf *buf; + struct wm_adsp *dsp = cs_ctl->dsp; unsigned int version; int ret, i;
for (i = 0; i < 5; ++i) { - ret = cs_dsp_coeff_read_ctrl(ctl, &coeff_v1, sizeof(coeff_v1)); + ret = cs_dsp_coeff_read_ctrl(cs_ctl, &coeff_v1, sizeof(coeff_v1)); if (ret < 0) return ret;
@@ -3955,15 +3984,15 @@ static int wm_adsp_buffer_parse_coeff(struct wm_coeff_ctl *ctl) }
if (!coeff_v1.host_buf_ptr) { - adsp_err(ctl->dsp, "Failed to acquire host buffer\n"); + adsp_err(dsp, "Failed to acquire host buffer\n"); return -EIO; }
- buf = wm_adsp_buffer_alloc(ctl->dsp); + buf = wm_adsp_buffer_alloc(dsp); if (!buf) return -ENOMEM;
- buf->host_buf_mem_type = ctl->alg_region.type; + buf->host_buf_mem_type = cs_ctl->alg_region.type; buf->host_buf_ptr = be32_to_cpu(coeff_v1.host_buf_ptr);
ret = wm_adsp_buffer_populate(buf); @@ -3974,7 +4003,7 @@ static int wm_adsp_buffer_parse_coeff(struct wm_coeff_ctl *ctl) * v0 host_buffer coefficients didn't have versioning, so if the * control is one word, assume version 0. */ - if (ctl->len == 4) { + if (cs_ctl->len == 4) { compr_dbg(buf, "host_buf_ptr=%x\n", buf->host_buf_ptr); return 0; } @@ -3983,7 +4012,7 @@ static int wm_adsp_buffer_parse_coeff(struct wm_coeff_ctl *ctl) version >>= HOST_BUF_COEFF_COMPAT_VER_SHIFT;
if (version > HOST_BUF_COEFF_SUPPORTED_COMPAT_VER) { - adsp_err(ctl->dsp, + adsp_err(dsp, "Host buffer coeff ver %u > supported version %u\n", version, HOST_BUF_COEFF_SUPPORTED_COMPAT_VER); return -EINVAL; @@ -3991,7 +4020,7 @@ static int wm_adsp_buffer_parse_coeff(struct wm_coeff_ctl *ctl)
cs_dsp_remove_padding((u32 *)&coeff_v1.name, ARRAY_SIZE(coeff_v1.name));
- buf->name = kasprintf(GFP_KERNEL, "%s-dsp-%s", ctl->dsp->part, + buf->name = kasprintf(GFP_KERNEL, "%s-dsp-%s", dsp->part, (char *)&coeff_v1.name);
compr_dbg(buf, "host_buf_ptr=%x coeff version %u\n", @@ -4002,17 +4031,17 @@ static int wm_adsp_buffer_parse_coeff(struct wm_coeff_ctl *ctl)
static int wm_adsp_buffer_init(struct wm_adsp *dsp) { - struct wm_coeff_ctl *ctl; + struct cs_dsp_coeff_ctl *cs_ctl; int ret;
- list_for_each_entry(ctl, &dsp->ctl_list, list) { - if (ctl->type != WMFW_CTL_TYPE_HOST_BUFFER) + list_for_each_entry(cs_ctl, &dsp->ctl_list, list) { + if (cs_ctl->type != WMFW_CTL_TYPE_HOST_BUFFER) continue;
- if (!ctl->enabled) + if (!cs_ctl->enabled) continue;
- ret = wm_adsp_buffer_parse_coeff(ctl); + ret = wm_adsp_buffer_parse_coeff(cs_ctl); if (ret < 0) { adsp_err(dsp, "Failed to parse coeff: %d\n", ret); goto error; diff --git a/sound/soc/codecs/wm_adsp.h b/sound/soc/codecs/wm_adsp.h index 98b12b485916..eee298e94946 100644 --- a/sound/soc/codecs/wm_adsp.h +++ b/sound/soc/codecs/wm_adsp.h @@ -49,10 +49,30 @@ struct cs_dsp_alg_region { unsigned int base; };
+struct wm_adsp; struct wm_adsp_compr; struct wm_adsp_compr_buf; struct cs_dsp_ops;
+struct cs_dsp_coeff_ctl { + const char *fw_name; + /* Subname is needed to match with firmware */ + const char *subname; + unsigned int subname_len; + struct cs_dsp_alg_region alg_region; + struct wm_adsp *dsp; + unsigned int enabled:1; + struct list_head list; + void *cache; + unsigned int offset; + size_t len; + unsigned int set:1; + unsigned int flags; + unsigned int type; + + void *priv; +}; + struct wm_adsp { const char *part; const char *name;
In preparation for moving the generic DSP support out of ASoC, move the check of dsp->running to a more appropriate place that will move to the generic code.
Signed-off-by: Simon Trimmer simont@opensource.cirrus.com Signed-off-by: Charles Keepax ckeepax@opensource.cirrus.com --- sound/soc/codecs/wm_adsp.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/sound/soc/codecs/wm_adsp.c b/sound/soc/codecs/wm_adsp.c index bd335e4240e5..1c8bf818dab9 100644 --- a/sound/soc/codecs/wm_adsp.c +++ b/sound/soc/codecs/wm_adsp.c @@ -976,6 +976,9 @@ static int cs_dsp_coeff_write_acked_control(struct cs_dsp_coeff_ctl *ctl, unsigned int reg; int i, ret;
+ if (!dsp->running) + return -EPERM; + ret = cs_dsp_coeff_base_reg(ctl, ®); if (ret) return ret; @@ -1129,7 +1132,7 @@ static int wm_coeff_put_acked(struct snd_kcontrol *kctl,
mutex_lock(&cs_ctl->dsp->pwr_lock);
- if (cs_ctl->enabled && cs_ctl->dsp->running) + if (cs_ctl->enabled) ret = cs_dsp_coeff_write_acked_control(cs_ctl, val); else ret = -EPERM;
As preparation for moving the generic DSP support out of ASoC pass the firmware names used when loading files as parameters as the generic code can't refer directly to the array specific to wm_adsp. The code remaining in wm_adsp.c doesn't need to change, it can continue to use the string arrays directly.
Signed-off-by: Simon Trimmer simont@opensource.cirrus.com Signed-off-by: Charles Keepax ckeepax@opensource.cirrus.com --- sound/soc/codecs/wm_adsp.c | 43 +++++++++++++++++++++++--------------- sound/soc/codecs/wm_adsp.h | 1 + 2 files changed, 27 insertions(+), 17 deletions(-)
diff --git a/sound/soc/codecs/wm_adsp.c b/sound/soc/codecs/wm_adsp.c index 1c8bf818dab9..c2e1eb8ff357 100644 --- a/sound/soc/codecs/wm_adsp.c +++ b/sound/soc/codecs/wm_adsp.c @@ -1499,7 +1499,7 @@ static int cs_dsp_create_control(struct wm_adsp *dsp, int ret;
list_for_each_entry(ctl, &dsp->ctl_list, list) { - if (ctl->fw_name == wm_adsp_fw_text[dsp->fw] && + if (ctl->fw_name == dsp->fw_name && ctl->alg_region.alg == alg_region->alg && ctl->alg_region.type == alg_region->type) { if ((!subname && !ctl->subname) || @@ -1514,7 +1514,8 @@ static int cs_dsp_create_control(struct wm_adsp *dsp, ctl = kzalloc(sizeof(*ctl), GFP_KERNEL); if (!ctl) return -ENOMEM; - ctl->fw_name = wm_adsp_fw_text[dsp->fw]; + + ctl->fw_name = dsp->fw_name; ctl->alg_region = *alg_region; if (subname && dsp->fw_ver >= 2) { ctl->subname_len = subname_len; @@ -1836,7 +1837,7 @@ static bool cs_dsp_halo_validate_version(struct wm_adsp *dsp, unsigned int versi } }
-static int cs_dsp_load(struct wm_adsp *dsp) +static int cs_dsp_load(struct wm_adsp *dsp, const char *fw_file_name) { LIST_HEAD(buf_list); const struct firmware *firmware; @@ -1859,7 +1860,7 @@ static int cs_dsp_load(struct wm_adsp *dsp) return -ENOMEM;
snprintf(file, PAGE_SIZE, "%s-%s-%s.wmfw", dsp->part, dsp->fwf_name, - wm_adsp_fw[dsp->fw].file); + fw_file_name); file[PAGE_SIZE - 1] = '\0';
ret = request_firmware(&firmware, file, dsp->dev); @@ -2047,13 +2048,12 @@ static struct cs_dsp_coeff_ctl *cs_dsp_get_ctl(struct wm_adsp *dsp, unsigned int alg) { struct cs_dsp_coeff_ctl *pos, *rslt = NULL; - const char *fw_txt = wm_adsp_fw_text[dsp->fw];
list_for_each_entry(pos, &dsp->ctl_list, list) { if (!pos->subname) continue; if (strncmp(pos->subname, name, pos->subname_len) == 0 && - pos->fw_name == fw_txt && + pos->fw_name == dsp->fw_name && pos->alg_region.alg == alg && pos->alg_region.type == type) { rslt = pos; @@ -2131,7 +2131,7 @@ static void cs_dsp_ctl_fixup_base(struct wm_adsp *dsp, struct cs_dsp_coeff_ctl *ctl;
list_for_each_entry(ctl, &dsp->ctl_list, list) { - if (ctl->fw_name == wm_adsp_fw_text[dsp->fw] && + if (ctl->fw_name == dsp->fw_name && alg_region->alg == ctl->alg_region.alg && alg_region->type == ctl->alg_region.type) { ctl->alg_region.base = alg_region->base; @@ -2582,7 +2582,7 @@ static int cs_dsp_halo_setup_algs(struct wm_adsp *dsp) return ret; }
-static int cs_dsp_load_coeff(struct wm_adsp *dsp) +static int cs_dsp_load_coeff(struct wm_adsp *dsp, const char *fw_file_name) { LIST_HEAD(buf_list); struct regmap *regmap = dsp->regmap; @@ -2601,7 +2601,7 @@ static int cs_dsp_load_coeff(struct wm_adsp *dsp) return -ENOMEM;
snprintf(file, PAGE_SIZE, "%s-%s-%s.bin", dsp->part, dsp->fwf_name, - wm_adsp_fw[dsp->fw].file); + fw_file_name); file[PAGE_SIZE - 1] = '\0';
ret = request_firmware(&firmware, file, dsp->dev); @@ -2837,13 +2837,15 @@ int wm_adsp1_init(struct wm_adsp *dsp) } EXPORT_SYMBOL_GPL(wm_adsp1_init);
-static int cs_dsp_adsp1_power_up(struct wm_adsp *dsp) +static int cs_dsp_adsp1_power_up(struct wm_adsp *dsp, const char *fw_file_name, const char *fw_name) { unsigned int val; int ret;
mutex_lock(&dsp->pwr_lock);
+ dsp->fw_name = fw_name; + regmap_update_bits(dsp->regmap, dsp->base + ADSP1_CONTROL_30, ADSP1_SYS_ENA, ADSP1_SYS_ENA);
@@ -2869,7 +2871,7 @@ static int cs_dsp_adsp1_power_up(struct wm_adsp *dsp) } }
- ret = cs_dsp_load(dsp); + ret = cs_dsp_load(dsp, fw_file_name); if (ret != 0) goto err_ena;
@@ -2877,7 +2879,7 @@ static int cs_dsp_adsp1_power_up(struct wm_adsp *dsp) if (ret != 0) goto err_ena;
- ret = cs_dsp_load_coeff(dsp); + ret = cs_dsp_load_coeff(dsp, fw_file_name); if (ret != 0) goto err_ena;
@@ -2952,7 +2954,9 @@ int wm_adsp1_event(struct snd_soc_dapm_widget *w,
switch (event) { case SND_SOC_DAPM_POST_PMU: - ret = cs_dsp_adsp1_power_up(dsp); + ret = cs_dsp_adsp1_power_up(dsp, + wm_adsp_fw[dsp->fw].file, + wm_adsp_fw_text[dsp->fw]); break; case SND_SOC_DAPM_PRE_PMD: cs_dsp_adsp1_power_down(dsp); @@ -3172,12 +3176,15 @@ static void cs_dsp_halo_stop_watchdog(struct wm_adsp *dsp) HALO_WDT_EN_MASK, 0); }
-static void cs_dsp_power_up(struct wm_adsp *dsp) +static void cs_dsp_power_up(struct wm_adsp *dsp, const char *fw_file_name, + const char *fw_name) { int ret;
mutex_lock(&dsp->pwr_lock);
+ dsp->fw_name = fw_name; + if (dsp->ops->enable_memory) { ret = dsp->ops->enable_memory(dsp); if (ret != 0) @@ -3190,7 +3197,7 @@ static void cs_dsp_power_up(struct wm_adsp *dsp) goto err_mem; }
- ret = cs_dsp_load(dsp); + ret = cs_dsp_load(dsp, fw_file_name); if (ret != 0) goto err_ena;
@@ -3198,7 +3205,7 @@ static void cs_dsp_power_up(struct wm_adsp *dsp) if (ret != 0) goto err_ena;
- ret = cs_dsp_load_coeff(dsp); + ret = cs_dsp_load_coeff(dsp, fw_file_name); if (ret != 0) goto err_ena;
@@ -3258,7 +3265,9 @@ static void wm_adsp_boot_work(struct work_struct *work) struct wm_adsp, boot_work);
- cs_dsp_power_up(dsp); + cs_dsp_power_up(dsp, + wm_adsp_fw[dsp->fw].file, + wm_adsp_fw_text[dsp->fw]); }
int wm_adsp_early_event(struct snd_soc_dapm_widget *w, diff --git a/sound/soc/codecs/wm_adsp.h b/sound/soc/codecs/wm_adsp.h index eee298e94946..3bad022c4bb1 100644 --- a/sound/soc/codecs/wm_adsp.h +++ b/sound/soc/codecs/wm_adsp.h @@ -94,6 +94,7 @@ struct wm_adsp {
struct list_head alg_regions;
+ const char *fw_name; unsigned int fw_id; unsigned int fw_id_version; unsigned int fw_vendor_id;
This is preparation for moving the generic DSP support out of ASoC. Passing the firmware as parameters into the power_up functions simplifies the generic code that will be moved out of wm_adsp.
Signed-off-by: Simon Trimmer simont@opensource.cirrus.com --- sound/soc/codecs/wm_adsp.c | 163 +++++++++++++++++++++++++------------ 1 file changed, 112 insertions(+), 51 deletions(-)
diff --git a/sound/soc/codecs/wm_adsp.c b/sound/soc/codecs/wm_adsp.c index c2e1eb8ff357..3b5b0cce7b35 100644 --- a/sound/soc/codecs/wm_adsp.c +++ b/sound/soc/codecs/wm_adsp.c @@ -29,6 +29,7 @@ #include <sound/jack.h> #include <sound/initval.h> #include <sound/tlv.h> +#include <linux/firmware.h>
#include "wm_adsp.h"
@@ -1797,6 +1798,60 @@ static unsigned int cs_dsp_adsp1_parse_sizes(struct wm_adsp *dsp, return pos + sizeof(*adsp1_sizes); }
+static void wm_adsp_release_firmware_files(struct wm_adsp *dsp, + const struct firmware *wmfw_firmware, + char *wmfw_filename, + const struct firmware *coeff_firmware, + char *coeff_filename) +{ + if (wmfw_firmware) + release_firmware(wmfw_firmware); + kfree(wmfw_filename); + + if (coeff_firmware) + release_firmware(coeff_firmware); + kfree(coeff_filename); +} + +static int wm_adsp_request_firmware_file(struct wm_adsp *dsp, + const struct firmware **firmware, + char **filename, + char *suffix) +{ + int ret = 0; + + *filename = kasprintf(GFP_KERNEL, "%s-%s-%s.%s", dsp->part, dsp->fwf_name, + wm_adsp_fw[dsp->fw].file, suffix); + if (*filename == NULL) + return -ENOMEM; + + ret = request_firmware(firmware, *filename, dsp->dev); + if (ret != 0) { + adsp_err(dsp, "Failed to request '%s'\n", *filename); + kfree(*filename); + *filename = NULL; + } + + return ret; +} + +static int wm_adsp_request_firmware_files(struct wm_adsp *dsp, + const struct firmware **wmfw_firmware, + char **wmfw_filename, + const struct firmware **coeff_firmware, + char **coeff_filename) +{ + int ret = 0; + + ret = wm_adsp_request_firmware_file(dsp, wmfw_firmware, wmfw_filename, "wmfw"); + if (ret != 0) + return ret; + + wm_adsp_request_firmware_file(dsp, coeff_firmware, coeff_filename, "bin"); + + return 0; +} + static unsigned int cs_dsp_adsp2_parse_sizes(struct wm_adsp *dsp, const char * const file, unsigned int pos, @@ -1837,10 +1892,10 @@ static bool cs_dsp_halo_validate_version(struct wm_adsp *dsp, unsigned int versi } }
-static int cs_dsp_load(struct wm_adsp *dsp, const char *fw_file_name) +static int cs_dsp_load(struct wm_adsp *dsp, const struct firmware *firmware, + const char *file) { LIST_HEAD(buf_list); - const struct firmware *firmware; struct regmap *regmap = dsp->regmap; unsigned int pos = 0; const struct wmfw_header *header; @@ -1849,25 +1904,12 @@ static int cs_dsp_load(struct wm_adsp *dsp, const char *fw_file_name) const struct wmfw_region *region; const struct cs_dsp_region *mem; const char *region_name; - char *file, *text = NULL; + char *text = NULL; struct cs_dsp_buf *buf; unsigned int reg; int regions = 0; int ret, offset, type;
- file = kzalloc(PAGE_SIZE, GFP_KERNEL); - if (file == NULL) - return -ENOMEM; - - snprintf(file, PAGE_SIZE, "%s-%s-%s.wmfw", dsp->part, dsp->fwf_name, - fw_file_name); - file[PAGE_SIZE - 1] = '\0'; - - ret = request_firmware(&firmware, file, dsp->dev); - if (ret != 0) { - cs_dsp_err(dsp, "Failed to request '%s'\n", file); - goto out; - } ret = -EINVAL;
pos = sizeof(*header) + sizeof(*adsp1_sizes) + sizeof(*footer); @@ -2031,10 +2073,7 @@ static int cs_dsp_load(struct wm_adsp *dsp, const char *fw_file_name) out_fw: regmap_async_complete(regmap); cs_dsp_buf_free(&buf_list); - release_firmware(firmware); kfree(text); -out: - kfree(file);
return ret; } @@ -2582,45 +2621,33 @@ static int cs_dsp_halo_setup_algs(struct wm_adsp *dsp) return ret; }
-static int cs_dsp_load_coeff(struct wm_adsp *dsp, const char *fw_file_name) +static int cs_dsp_load_coeff(struct wm_adsp *dsp, const struct firmware *firmware, + const char *file) { LIST_HEAD(buf_list); struct regmap *regmap = dsp->regmap; struct wmfw_coeff_hdr *hdr; struct wmfw_coeff_item *blk; - const struct firmware *firmware; const struct cs_dsp_region *mem; struct cs_dsp_alg_region *alg_region; const char *region_name; int ret, pos, blocks, type, offset, reg; - char *file; struct cs_dsp_buf *buf;
- file = kzalloc(PAGE_SIZE, GFP_KERNEL); - if (file == NULL) - return -ENOMEM; + if (!firmware) + return 0;
- snprintf(file, PAGE_SIZE, "%s-%s-%s.bin", dsp->part, dsp->fwf_name, - fw_file_name); - file[PAGE_SIZE - 1] = '\0'; - - ret = request_firmware(&firmware, file, dsp->dev); - if (ret != 0) { - cs_dsp_warn(dsp, "Failed to request '%s'\n", file); - ret = 0; - goto out; - } ret = -EINVAL;
if (sizeof(*hdr) >= firmware->size) { - cs_dsp_err(dsp, "%s: file too short, %zu bytes\n", + cs_dsp_err(dsp, "%s: coefficient file too short, %zu bytes\n", file, firmware->size); goto out_fw; }
hdr = (void *)&firmware->data[0]; if (memcmp(hdr->magic, "WMDR", 4) != 0) { - cs_dsp_err(dsp, "%s: invalid magic\n", file); + cs_dsp_err(dsp, "%s: invalid coefficient magic\n", file); goto out_fw; }
@@ -2769,10 +2796,7 @@ static int cs_dsp_load_coeff(struct wm_adsp *dsp, const char *fw_file_name)
out_fw: regmap_async_complete(regmap); - release_firmware(firmware); cs_dsp_buf_free(&buf_list); -out: - kfree(file); return ret; }
@@ -2837,7 +2861,10 @@ int wm_adsp1_init(struct wm_adsp *dsp) } EXPORT_SYMBOL_GPL(wm_adsp1_init);
-static int cs_dsp_adsp1_power_up(struct wm_adsp *dsp, const char *fw_file_name, const char *fw_name) +static int cs_dsp_adsp1_power_up(struct wm_adsp *dsp, + const struct firmware *wmfw_firmware, char *wmfw_filename, + const struct firmware *coeff_firmware, char *coeff_filename, + const char *fw_name) { unsigned int val; int ret; @@ -2871,7 +2898,7 @@ static int cs_dsp_adsp1_power_up(struct wm_adsp *dsp, const char *fw_file_name, } }
- ret = cs_dsp_load(dsp, fw_file_name); + ret = cs_dsp_load(dsp, wmfw_firmware, wmfw_filename); if (ret != 0) goto err_ena;
@@ -2879,7 +2906,7 @@ static int cs_dsp_adsp1_power_up(struct wm_adsp *dsp, const char *fw_file_name, if (ret != 0) goto err_ena;
- ret = cs_dsp_load_coeff(dsp, fw_file_name); + ret = cs_dsp_load_coeff(dsp, coeff_firmware, coeff_filename); if (ret != 0) goto err_ena;
@@ -2949,14 +2976,29 @@ int wm_adsp1_event(struct snd_soc_dapm_widget *w, struct wm_adsp *dsps = snd_soc_component_get_drvdata(component); struct wm_adsp *dsp = &dsps[w->shift]; int ret = 0; + char *wmfw_filename = NULL; + const struct firmware *wmfw_firmware = NULL; + char *coeff_filename = NULL; + const struct firmware *coeff_firmware = NULL;
dsp->component = component;
switch (event) { case SND_SOC_DAPM_POST_PMU: + ret = wm_adsp_request_firmware_files(dsp, + &wmfw_firmware, &wmfw_filename, + &coeff_firmware, &coeff_filename); + if (ret) + break; + ret = cs_dsp_adsp1_power_up(dsp, - wm_adsp_fw[dsp->fw].file, + wmfw_firmware, wmfw_filename, + coeff_firmware, coeff_filename, wm_adsp_fw_text[dsp->fw]); + + wm_adsp_release_firmware_files(dsp, + wmfw_firmware, wmfw_filename, + coeff_firmware, coeff_filename); break; case SND_SOC_DAPM_PRE_PMD: cs_dsp_adsp1_power_down(dsp); @@ -3176,8 +3218,10 @@ static void cs_dsp_halo_stop_watchdog(struct wm_adsp *dsp) HALO_WDT_EN_MASK, 0); }
-static void cs_dsp_power_up(struct wm_adsp *dsp, const char *fw_file_name, - const char *fw_name) +static int cs_dsp_power_up(struct wm_adsp *dsp, + const struct firmware *wmfw_firmware, char *wmfw_filename, + const struct firmware *coeff_firmware, char *coeff_filename, + const char *fw_name) { int ret;
@@ -3197,7 +3241,7 @@ static void cs_dsp_power_up(struct wm_adsp *dsp, const char *fw_file_name, goto err_mem; }
- ret = cs_dsp_load(dsp, fw_file_name); + ret = cs_dsp_load(dsp, wmfw_firmware, wmfw_filename); if (ret != 0) goto err_ena;
@@ -3205,7 +3249,7 @@ static void cs_dsp_power_up(struct wm_adsp *dsp, const char *fw_file_name, if (ret != 0) goto err_ena;
- ret = cs_dsp_load_coeff(dsp, fw_file_name); + ret = cs_dsp_load_coeff(dsp, coeff_firmware, coeff_filename); if (ret != 0) goto err_ena;
@@ -3221,8 +3265,7 @@ static void cs_dsp_power_up(struct wm_adsp *dsp, const char *fw_file_name,
mutex_unlock(&dsp->pwr_lock);
- return; - + return 0; err_ena: if (dsp->ops->disable_core) dsp->ops->disable_core(dsp); @@ -3231,6 +3274,8 @@ static void cs_dsp_power_up(struct wm_adsp *dsp, const char *fw_file_name, dsp->ops->disable_memory(dsp); err_mutex: mutex_unlock(&dsp->pwr_lock); + + return ret; }
static void cs_dsp_power_down(struct wm_adsp *dsp) @@ -3264,10 +3309,26 @@ static void wm_adsp_boot_work(struct work_struct *work) struct wm_adsp *dsp = container_of(work, struct wm_adsp, boot_work); + int ret = 0; + char *wmfw_filename = NULL; + const struct firmware *wmfw_firmware = NULL; + char *coeff_filename = NULL; + const struct firmware *coeff_firmware = NULL; + + ret = wm_adsp_request_firmware_files(dsp, + &wmfw_firmware, &wmfw_filename, + &coeff_firmware, &coeff_filename); + if (ret) + return;
cs_dsp_power_up(dsp, - wm_adsp_fw[dsp->fw].file, + wmfw_firmware, wmfw_filename, + coeff_firmware, coeff_filename, wm_adsp_fw_text[dsp->fw]); + + wm_adsp_release_firmware_files(dsp, + wmfw_firmware, wmfw_filename, + coeff_firmware, coeff_filename); }
int wm_adsp_early_event(struct snd_soc_dapm_widget *w,
In preparation for moving the generic DSP support out of ASoC split struct wm_adsp into two parts, one will form the structure for the new generic DSP code and embed that one into wm_adsp.
Signed-off-by: Simon Trimmer simont@opensource.cirrus.com Signed-off-by: Charles Keepax ckeepax@opensource.cirrus.com --- sound/soc/codecs/cs47l15.c | 18 +- sound/soc/codecs/cs47l24.c | 14 +- sound/soc/codecs/cs47l35.c | 16 +- sound/soc/codecs/cs47l85.c | 16 +- sound/soc/codecs/cs47l90.c | 18 +- sound/soc/codecs/cs47l92.c | 18 +- sound/soc/codecs/madera.c | 18 +- sound/soc/codecs/wm2200.c | 26 +-- sound/soc/codecs/wm5102.c | 14 +- sound/soc/codecs/wm5110.c | 14 +- sound/soc/codecs/wm_adsp.c | 356 ++++++++++++++++++++----------------- sound/soc/codecs/wm_adsp.h | 60 ++++--- 12 files changed, 309 insertions(+), 279 deletions(-)
diff --git a/sound/soc/codecs/cs47l15.c b/sound/soc/codecs/cs47l15.c index 07388701f89f..391fd7da331f 100644 --- a/sound/soc/codecs/cs47l15.c +++ b/sound/soc/codecs/cs47l15.c @@ -1402,17 +1402,17 @@ static int cs47l15_probe(struct platform_device *pdev) dev_warn(&pdev->dev, "Failed to set DSP IRQ wake: %d\n", ret);
cs47l15->core.adsp[0].part = "cs47l15"; - cs47l15->core.adsp[0].num = 1; - cs47l15->core.adsp[0].type = WMFW_ADSP2; - cs47l15->core.adsp[0].rev = 2; - cs47l15->core.adsp[0].dev = madera->dev; - cs47l15->core.adsp[0].regmap = madera->regmap_32bit; + cs47l15->core.adsp[0].cs_dsp.num = 1; + cs47l15->core.adsp[0].cs_dsp.type = WMFW_ADSP2; + cs47l15->core.adsp[0].cs_dsp.rev = 2; + cs47l15->core.adsp[0].cs_dsp.dev = madera->dev; + cs47l15->core.adsp[0].cs_dsp.regmap = madera->regmap_32bit;
- cs47l15->core.adsp[0].base = MADERA_DSP1_CONFIG_1; - cs47l15->core.adsp[0].mem = cs47l15_dsp1_regions; - cs47l15->core.adsp[0].num_mems = ARRAY_SIZE(cs47l15_dsp1_regions); + cs47l15->core.adsp[0].cs_dsp.base = MADERA_DSP1_CONFIG_1; + cs47l15->core.adsp[0].cs_dsp.mem = cs47l15_dsp1_regions; + cs47l15->core.adsp[0].cs_dsp.num_mems = ARRAY_SIZE(cs47l15_dsp1_regions);
- cs47l15->core.adsp[0].lock_regions = + cs47l15->core.adsp[0].cs_dsp.lock_regions = CS_ADSP2_REGION_1 | CS_ADSP2_REGION_2 | CS_ADSP2_REGION_3;
ret = wm_adsp2_init(&cs47l15->core.adsp[0]); diff --git a/sound/soc/codecs/cs47l24.c b/sound/soc/codecs/cs47l24.c index be81094dbf1e..6356f81aafc5 100644 --- a/sound/soc/codecs/cs47l24.c +++ b/sound/soc/codecs/cs47l24.c @@ -1234,15 +1234,15 @@ static int cs47l24_probe(struct platform_device *pdev)
for (i = 1; i <= 2; i++) { cs47l24->core.adsp[i].part = "cs47l24"; - cs47l24->core.adsp[i].num = i + 1; - cs47l24->core.adsp[i].type = WMFW_ADSP2; - cs47l24->core.adsp[i].dev = arizona->dev; - cs47l24->core.adsp[i].regmap = arizona->regmap; + cs47l24->core.adsp[i].cs_dsp.num = i + 1; + cs47l24->core.adsp[i].cs_dsp.type = WMFW_ADSP2; + cs47l24->core.adsp[i].cs_dsp.dev = arizona->dev; + cs47l24->core.adsp[i].cs_dsp.regmap = arizona->regmap;
- cs47l24->core.adsp[i].base = ARIZONA_DSP1_CONTROL_1 + + cs47l24->core.adsp[i].cs_dsp.base = ARIZONA_DSP1_CONTROL_1 + (0x100 * i); - cs47l24->core.adsp[i].mem = cs47l24_dsp_regions[i - 1]; - cs47l24->core.adsp[i].num_mems = + cs47l24->core.adsp[i].cs_dsp.mem = cs47l24_dsp_regions[i - 1]; + cs47l24->core.adsp[i].cs_dsp.num_mems = ARRAY_SIZE(cs47l24_dsp2_regions);
ret = wm_adsp2_init(&cs47l24->core.adsp[i]); diff --git a/sound/soc/codecs/cs47l35.c b/sound/soc/codecs/cs47l35.c index b8d594bf4d13..db2f844b8b17 100644 --- a/sound/soc/codecs/cs47l35.c +++ b/sound/soc/codecs/cs47l35.c @@ -1686,15 +1686,15 @@ static int cs47l35_probe(struct platform_device *pdev)
for (i = 0; i < CS47L35_NUM_ADSP; i++) { cs47l35->core.adsp[i].part = "cs47l35"; - cs47l35->core.adsp[i].num = i + 1; - cs47l35->core.adsp[i].type = WMFW_ADSP2; - cs47l35->core.adsp[i].rev = 1; - cs47l35->core.adsp[i].dev = madera->dev; - cs47l35->core.adsp[i].regmap = madera->regmap_32bit; + cs47l35->core.adsp[i].cs_dsp.num = i + 1; + cs47l35->core.adsp[i].cs_dsp.type = WMFW_ADSP2; + cs47l35->core.adsp[i].cs_dsp.rev = 1; + cs47l35->core.adsp[i].cs_dsp.dev = madera->dev; + cs47l35->core.adsp[i].cs_dsp.regmap = madera->regmap_32bit;
- cs47l35->core.adsp[i].base = wm_adsp2_control_bases[i]; - cs47l35->core.adsp[i].mem = cs47l35_dsp_regions[i]; - cs47l35->core.adsp[i].num_mems = + cs47l35->core.adsp[i].cs_dsp.base = wm_adsp2_control_bases[i]; + cs47l35->core.adsp[i].cs_dsp.mem = cs47l35_dsp_regions[i]; + cs47l35->core.adsp[i].cs_dsp.num_mems = ARRAY_SIZE(cs47l35_dsp1_regions);
ret = wm_adsp2_init(&cs47l35->core.adsp[i]); diff --git a/sound/soc/codecs/cs47l85.c b/sound/soc/codecs/cs47l85.c index 7ba08ca75c4f..d4fedc5ad516 100644 --- a/sound/soc/codecs/cs47l85.c +++ b/sound/soc/codecs/cs47l85.c @@ -2632,15 +2632,15 @@ static int cs47l85_probe(struct platform_device *pdev)
for (i = 0; i < CS47L85_NUM_ADSP; i++) { cs47l85->core.adsp[i].part = "cs47l85"; - cs47l85->core.adsp[i].num = i + 1; - cs47l85->core.adsp[i].type = WMFW_ADSP2; - cs47l85->core.adsp[i].rev = 1; - cs47l85->core.adsp[i].dev = madera->dev; - cs47l85->core.adsp[i].regmap = madera->regmap_32bit; + cs47l85->core.adsp[i].cs_dsp.num = i + 1; + cs47l85->core.adsp[i].cs_dsp.type = WMFW_ADSP2; + cs47l85->core.adsp[i].cs_dsp.rev = 1; + cs47l85->core.adsp[i].cs_dsp.dev = madera->dev; + cs47l85->core.adsp[i].cs_dsp.regmap = madera->regmap_32bit;
- cs47l85->core.adsp[i].base = wm_adsp2_control_bases[i]; - cs47l85->core.adsp[i].mem = cs47l85_dsp_regions[i]; - cs47l85->core.adsp[i].num_mems = + cs47l85->core.adsp[i].cs_dsp.base = wm_adsp2_control_bases[i]; + cs47l85->core.adsp[i].cs_dsp.mem = cs47l85_dsp_regions[i]; + cs47l85->core.adsp[i].cs_dsp.num_mems = ARRAY_SIZE(cs47l85_dsp1_regions);
ret = wm_adsp2_init(&cs47l85->core.adsp[i]); diff --git a/sound/soc/codecs/cs47l90.c b/sound/soc/codecs/cs47l90.c index 01d75c32d81e..5aec937a2462 100644 --- a/sound/soc/codecs/cs47l90.c +++ b/sound/soc/codecs/cs47l90.c @@ -2543,18 +2543,18 @@ static int cs47l90_probe(struct platform_device *pdev)
for (i = 0; i < CS47L90_NUM_ADSP; i++) { cs47l90->core.adsp[i].part = "cs47l90"; - cs47l90->core.adsp[i].num = i + 1; - cs47l90->core.adsp[i].type = WMFW_ADSP2; - cs47l90->core.adsp[i].rev = 2; - cs47l90->core.adsp[i].dev = madera->dev; - cs47l90->core.adsp[i].regmap = madera->regmap_32bit; + cs47l90->core.adsp[i].cs_dsp.num = i + 1; + cs47l90->core.adsp[i].cs_dsp.type = WMFW_ADSP2; + cs47l90->core.adsp[i].cs_dsp.rev = 2; + cs47l90->core.adsp[i].cs_dsp.dev = madera->dev; + cs47l90->core.adsp[i].cs_dsp.regmap = madera->regmap_32bit;
- cs47l90->core.adsp[i].base = cs47l90_dsp_control_bases[i]; - cs47l90->core.adsp[i].mem = cs47l90_dsp_regions[i]; - cs47l90->core.adsp[i].num_mems = + cs47l90->core.adsp[i].cs_dsp.base = cs47l90_dsp_control_bases[i]; + cs47l90->core.adsp[i].cs_dsp.mem = cs47l90_dsp_regions[i]; + cs47l90->core.adsp[i].cs_dsp.num_mems = ARRAY_SIZE(cs47l90_dsp1_regions);
- cs47l90->core.adsp[i].lock_regions = CS_ADSP2_REGION_1_9; + cs47l90->core.adsp[i].cs_dsp.lock_regions = CS_ADSP2_REGION_1_9;
ret = wm_adsp2_init(&cs47l90->core.adsp[i]);
diff --git a/sound/soc/codecs/cs47l92.c b/sound/soc/codecs/cs47l92.c index 05087cc9c44b..a1b8dcdb9f7b 100644 --- a/sound/soc/codecs/cs47l92.c +++ b/sound/soc/codecs/cs47l92.c @@ -2002,17 +2002,17 @@ static int cs47l92_probe(struct platform_device *pdev) dev_warn(&pdev->dev, "Failed to set DSP IRQ wake: %d\n", ret);
cs47l92->core.adsp[0].part = "cs47l92"; - cs47l92->core.adsp[0].num = 1; - cs47l92->core.adsp[0].type = WMFW_ADSP2; - cs47l92->core.adsp[0].rev = 2; - cs47l92->core.adsp[0].dev = madera->dev; - cs47l92->core.adsp[0].regmap = madera->regmap_32bit; + cs47l92->core.adsp[0].cs_dsp.num = 1; + cs47l92->core.adsp[0].cs_dsp.type = WMFW_ADSP2; + cs47l92->core.adsp[0].cs_dsp.rev = 2; + cs47l92->core.adsp[0].cs_dsp.dev = madera->dev; + cs47l92->core.adsp[0].cs_dsp.regmap = madera->regmap_32bit;
- cs47l92->core.adsp[0].base = MADERA_DSP1_CONFIG_1; - cs47l92->core.adsp[0].mem = cs47l92_dsp1_regions; - cs47l92->core.adsp[0].num_mems = ARRAY_SIZE(cs47l92_dsp1_regions); + cs47l92->core.adsp[0].cs_dsp.base = MADERA_DSP1_CONFIG_1; + cs47l92->core.adsp[0].cs_dsp.mem = cs47l92_dsp1_regions; + cs47l92->core.adsp[0].cs_dsp.num_mems = ARRAY_SIZE(cs47l92_dsp1_regions);
- cs47l92->core.adsp[0].lock_regions = CS_ADSP2_REGION_1_9; + cs47l92->core.adsp[0].cs_dsp.lock_regions = CS_ADSP2_REGION_1_9;
ret = wm_adsp2_init(&cs47l92->core.adsp[0]); if (ret != 0) diff --git a/sound/soc/codecs/madera.c b/sound/soc/codecs/madera.c index f4ed7e04673f..272041c6236a 100644 --- a/sound/soc/codecs/madera.c +++ b/sound/soc/codecs/madera.c @@ -905,7 +905,7 @@ static int madera_adsp_rate_put(struct snd_kcontrol *kcontrol, */ mutex_lock(&priv->rate_lock);
- if (!madera_can_change_grp_rate(priv, priv->adsp[adsp_num].base)) { + if (!madera_can_change_grp_rate(priv, priv->adsp[adsp_num].cs_dsp.base)) { dev_warn(priv->madera->dev, "Cannot change '%s' while in use by active audio paths\n", kcontrol->id.name); @@ -964,7 +964,7 @@ static int madera_write_adsp_clk_setting(struct madera_priv *priv, unsigned int mask = MADERA_DSP_RATE_MASK; int ret;
- val = priv->adsp_rate_cache[dsp->num - 1] << MADERA_DSP_RATE_SHIFT; + val = priv->adsp_rate_cache[dsp->cs_dsp.num - 1] << MADERA_DSP_RATE_SHIFT;
switch (priv->madera->type) { case CS47L35: @@ -978,15 +978,15 @@ static int madera_write_adsp_clk_setting(struct madera_priv *priv, /* Configure exact dsp frequency */ dev_dbg(priv->madera->dev, "Set DSP frequency to 0x%x\n", freq);
- ret = regmap_write(dsp->regmap, - dsp->base + MADERA_DSP_CONFIG_2_OFFS, freq); + ret = regmap_write(dsp->cs_dsp.regmap, + dsp->cs_dsp.base + MADERA_DSP_CONFIG_2_OFFS, freq); if (ret) goto err; break; }
- ret = regmap_update_bits(dsp->regmap, - dsp->base + MADERA_DSP_CONFIG_1_OFFS, + ret = regmap_update_bits(dsp->cs_dsp.regmap, + dsp->cs_dsp.base + MADERA_DSP_CONFIG_1_OFFS, mask, val); if (ret) goto err; @@ -996,7 +996,7 @@ static int madera_write_adsp_clk_setting(struct madera_priv *priv, return 0;
err: - dev_err(dsp->dev, "Failed to set DSP%d clock: %d\n", dsp->num, ret); + dev_err(dsp->cs_dsp.dev, "Failed to set DSP%d clock: %d\n", dsp->cs_dsp.num, ret);
return ret; } @@ -1018,7 +1018,7 @@ int madera_set_adsp_clk(struct madera_priv *priv, int dsp_num, * changes are locked out by the domain_group_ref reference count. */
- ret = regmap_read(dsp->regmap, dsp->base, &cur); + ret = regmap_read(dsp->cs_dsp.regmap, dsp->cs_dsp.base, &cur); if (ret) { dev_err(madera->dev, "Failed to read current DSP rate: %d\n", ret); @@ -1027,7 +1027,7 @@ int madera_set_adsp_clk(struct madera_priv *priv, int dsp_num,
cur &= MADERA_DSP_RATE_MASK;
- new = priv->adsp_rate_cache[dsp->num - 1] << MADERA_DSP_RATE_SHIFT; + new = priv->adsp_rate_cache[dsp->cs_dsp.num - 1] << MADERA_DSP_RATE_SHIFT;
if (new == cur) { dev_dbg(madera->dev, "DSP rate not changed\n"); diff --git a/sound/soc/codecs/wm2200.c b/sound/soc/codecs/wm2200.c index 68355188eb55..8863b533f9c4 100644 --- a/sound/soc/codecs/wm2200.c +++ b/sound/soc/codecs/wm2200.c @@ -2202,23 +2202,23 @@ static int wm2200_i2c_probe(struct i2c_client *i2c, }
for (i = 0; i < 2; i++) { - wm2200->dsp[i].type = WMFW_ADSP1; + wm2200->dsp[i].cs_dsp.type = WMFW_ADSP1; wm2200->dsp[i].part = "wm2200"; - wm2200->dsp[i].num = i + 1; - wm2200->dsp[i].dev = &i2c->dev; - wm2200->dsp[i].regmap = wm2200->regmap; - wm2200->dsp[i].sysclk_reg = WM2200_CLOCKING_3; - wm2200->dsp[i].sysclk_mask = WM2200_SYSCLK_FREQ_MASK; - wm2200->dsp[i].sysclk_shift = WM2200_SYSCLK_FREQ_SHIFT; + wm2200->dsp[i].cs_dsp.num = i + 1; + wm2200->dsp[i].cs_dsp.dev = &i2c->dev; + wm2200->dsp[i].cs_dsp.regmap = wm2200->regmap; + wm2200->dsp[i].cs_dsp.sysclk_reg = WM2200_CLOCKING_3; + wm2200->dsp[i].cs_dsp.sysclk_mask = WM2200_SYSCLK_FREQ_MASK; + wm2200->dsp[i].cs_dsp.sysclk_shift = WM2200_SYSCLK_FREQ_SHIFT; }
- wm2200->dsp[0].base = WM2200_DSP1_CONTROL_1; - wm2200->dsp[0].mem = wm2200_dsp1_regions; - wm2200->dsp[0].num_mems = ARRAY_SIZE(wm2200_dsp1_regions); + wm2200->dsp[0].cs_dsp.base = WM2200_DSP1_CONTROL_1; + wm2200->dsp[0].cs_dsp.mem = wm2200_dsp1_regions; + wm2200->dsp[0].cs_dsp.num_mems = ARRAY_SIZE(wm2200_dsp1_regions);
- wm2200->dsp[1].base = WM2200_DSP2_CONTROL_1; - wm2200->dsp[1].mem = wm2200_dsp2_regions; - wm2200->dsp[1].num_mems = ARRAY_SIZE(wm2200_dsp2_regions); + wm2200->dsp[1].cs_dsp.base = WM2200_DSP2_CONTROL_1; + wm2200->dsp[1].cs_dsp.mem = wm2200_dsp2_regions; + wm2200->dsp[1].cs_dsp.num_mems = ARRAY_SIZE(wm2200_dsp2_regions);
for (i = 0; i < ARRAY_SIZE(wm2200->dsp); i++) wm_adsp1_init(&wm2200->dsp[i]); diff --git a/sound/soc/codecs/wm5102.c b/sound/soc/codecs/wm5102.c index 26e87c6be35b..da2f8998df87 100644 --- a/sound/soc/codecs/wm5102.c +++ b/sound/soc/codecs/wm5102.c @@ -2046,13 +2046,13 @@ static int wm5102_probe(struct platform_device *pdev) arizona_init_dvfs(&wm5102->core);
wm5102->core.adsp[0].part = "wm5102"; - wm5102->core.adsp[0].num = 1; - wm5102->core.adsp[0].type = WMFW_ADSP2; - wm5102->core.adsp[0].base = ARIZONA_DSP1_CONTROL_1; - wm5102->core.adsp[0].dev = arizona->dev; - wm5102->core.adsp[0].regmap = arizona->regmap; - wm5102->core.adsp[0].mem = wm5102_dsp1_regions; - wm5102->core.adsp[0].num_mems = ARRAY_SIZE(wm5102_dsp1_regions); + wm5102->core.adsp[0].cs_dsp.num = 1; + wm5102->core.adsp[0].cs_dsp.type = WMFW_ADSP2; + wm5102->core.adsp[0].cs_dsp.base = ARIZONA_DSP1_CONTROL_1; + wm5102->core.adsp[0].cs_dsp.dev = arizona->dev; + wm5102->core.adsp[0].cs_dsp.regmap = arizona->regmap; + wm5102->core.adsp[0].cs_dsp.mem = wm5102_dsp1_regions; + wm5102->core.adsp[0].cs_dsp.num_mems = ARRAY_SIZE(wm5102_dsp1_regions);
ret = wm_adsp2_init(&wm5102->core.adsp[0]); if (ret != 0) diff --git a/sound/soc/codecs/wm5110.c b/sound/soc/codecs/wm5110.c index e13e66b0ee52..4973ba1ed779 100644 --- a/sound/soc/codecs/wm5110.c +++ b/sound/soc/codecs/wm5110.c @@ -2409,15 +2409,15 @@ static int wm5110_probe(struct platform_device *pdev)
for (i = 0; i < WM5110_NUM_ADSP; i++) { wm5110->core.adsp[i].part = "wm5110"; - wm5110->core.adsp[i].num = i + 1; - wm5110->core.adsp[i].type = WMFW_ADSP2; - wm5110->core.adsp[i].dev = arizona->dev; - wm5110->core.adsp[i].regmap = arizona->regmap; + wm5110->core.adsp[i].cs_dsp.num = i + 1; + wm5110->core.adsp[i].cs_dsp.type = WMFW_ADSP2; + wm5110->core.adsp[i].cs_dsp.dev = arizona->dev; + wm5110->core.adsp[i].cs_dsp.regmap = arizona->regmap;
- wm5110->core.adsp[i].base = ARIZONA_DSP1_CONTROL_1 + wm5110->core.adsp[i].cs_dsp.base = ARIZONA_DSP1_CONTROL_1 + (0x100 * i); - wm5110->core.adsp[i].mem = wm5110_dsp_regions[i]; - wm5110->core.adsp[i].num_mems + wm5110->core.adsp[i].cs_dsp.mem = wm5110_dsp_regions[i]; + wm5110->core.adsp[i].cs_dsp.num_mems = ARRAY_SIZE(wm5110_dsp1_regions);
ret = wm_adsp2_init(&wm5110->core.adsp[i]); diff --git a/sound/soc/codecs/wm_adsp.c b/sound/soc/codecs/wm_adsp.c index 3b5b0cce7b35..092df446ff2f 100644 --- a/sound/soc/codecs/wm_adsp.c +++ b/sound/soc/codecs/wm_adsp.c @@ -34,15 +34,15 @@ #include "wm_adsp.h"
#define adsp_crit(_dsp, fmt, ...) \ - dev_crit(_dsp->dev, "%s: " fmt, _dsp->name, ##__VA_ARGS__) + dev_crit(_dsp->cs_dsp.dev, "%s: " fmt, _dsp->cs_dsp.name, ##__VA_ARGS__) #define adsp_err(_dsp, fmt, ...) \ - dev_err(_dsp->dev, "%s: " fmt, _dsp->name, ##__VA_ARGS__) + dev_err(_dsp->cs_dsp.dev, "%s: " fmt, _dsp->cs_dsp.name, ##__VA_ARGS__) #define adsp_warn(_dsp, fmt, ...) \ - dev_warn(_dsp->dev, "%s: " fmt, _dsp->name, ##__VA_ARGS__) + dev_warn(_dsp->cs_dsp.dev, "%s: " fmt, _dsp->cs_dsp.name, ##__VA_ARGS__) #define adsp_info(_dsp, fmt, ...) \ - dev_info(_dsp->dev, "%s: " fmt, _dsp->name, ##__VA_ARGS__) + dev_info(_dsp->cs_dsp.dev, "%s: " fmt, _dsp->cs_dsp.name, ##__VA_ARGS__) #define adsp_dbg(_dsp, fmt, ...) \ - dev_dbg(_dsp->dev, "%s: " fmt, _dsp->name, ##__VA_ARGS__) + dev_dbg(_dsp->cs_dsp.dev, "%s: " fmt, _dsp->cs_dsp.name, ##__VA_ARGS__)
#define cs_dsp_err(_dsp, fmt, ...) \ dev_err(_dsp->dev, "%s: " fmt, _dsp->name, ##__VA_ARGS__) @@ -638,7 +638,7 @@ static const char *cs_dsp_mem_region_name(unsigned int type) }
#ifdef CONFIG_DEBUG_FS -static void cs_dsp_debugfs_save_wmfwname(struct wm_adsp *dsp, const char *s) +static void cs_dsp_debugfs_save_wmfwname(struct cs_dsp *dsp, const char *s) { char *tmp = kasprintf(GFP_KERNEL, "%s\n", s);
@@ -646,7 +646,7 @@ static void cs_dsp_debugfs_save_wmfwname(struct wm_adsp *dsp, const char *s) dsp->wmfw_file_name = tmp; }
-static void cs_dsp_debugfs_save_binname(struct wm_adsp *dsp, const char *s) +static void cs_dsp_debugfs_save_binname(struct cs_dsp *dsp, const char *s) { char *tmp = kasprintf(GFP_KERNEL, "%s\n", s);
@@ -654,7 +654,7 @@ static void cs_dsp_debugfs_save_binname(struct wm_adsp *dsp, const char *s) dsp->bin_file_name = tmp; }
-static void cs_dsp_debugfs_clear(struct wm_adsp *dsp) +static void cs_dsp_debugfs_clear(struct cs_dsp *dsp) { kfree(dsp->wmfw_file_name); kfree(dsp->bin_file_name); @@ -666,7 +666,7 @@ static ssize_t cs_dsp_debugfs_wmfw_read(struct file *file, char __user *user_buf, size_t count, loff_t *ppos) { - struct wm_adsp *dsp = file->private_data; + struct cs_dsp *dsp = file->private_data; ssize_t ret;
mutex_lock(&dsp->pwr_lock); @@ -686,7 +686,7 @@ static ssize_t cs_dsp_debugfs_bin_read(struct file *file, char __user *user_buf, size_t count, loff_t *ppos) { - struct wm_adsp *dsp = file->private_data; + struct cs_dsp *dsp = file->private_data; ssize_t ret;
mutex_lock(&dsp->pwr_lock); @@ -722,13 +722,13 @@ static const struct { }, };
-static void cs_dsp_init_debugfs(struct wm_adsp *dsp, - struct snd_soc_component *component) +static void cs_dsp_init_debugfs(struct cs_dsp *dsp, + struct dentry *debugfs_root) { struct dentry *root = NULL; int i;
- root = debugfs_create_dir(dsp->name, component->debugfs_root); + root = debugfs_create_dir(dsp->name, debugfs_root);
debugfs_create_bool("booted", 0444, root, &dsp->booted); debugfs_create_bool("running", 0444, root, &dsp->running); @@ -742,33 +742,33 @@ static void cs_dsp_init_debugfs(struct wm_adsp *dsp, dsp->debugfs_root = root; }
-static void cs_dsp_cleanup_debugfs(struct wm_adsp *dsp) +static void cs_dsp_cleanup_debugfs(struct cs_dsp *dsp) { cs_dsp_debugfs_clear(dsp); debugfs_remove_recursive(dsp->debugfs_root); dsp->debugfs_root = NULL; } #else -static inline void cs_dsp_init_debugfs(struct wm_adsp *dsp, - struct snd_soc_component *component) +static inline void cs_dsp_init_debugfs(struct cs_dsp *dsp, + struct dentry *debugfs_root) { }
-static inline void cs_dsp_cleanup_debugfs(struct wm_adsp *dsp) +static inline void cs_dsp_cleanup_debugfs(struct cs_dsp *dsp) { }
-static inline void cs_dsp_debugfs_save_wmfwname(struct wm_adsp *dsp, - const char *s) -{ -} - -static inline void cs_dsp_debugfs_save_binname(struct wm_adsp *dsp, +static inline void cs_dsp_debugfs_save_wmfwname(struct cs_dsp *dsp, const char *s) { }
-static inline void cs_dsp_debugfs_clear(struct wm_adsp *dsp) +static inline void cs_dsp_debugfs_save_binname(struct cs_dsp *dsp, + const char *s) +{ +} + +static inline void cs_dsp_debugfs_clear(struct cs_dsp *dsp) { } #endif @@ -800,14 +800,14 @@ int wm_adsp_fw_put(struct snd_kcontrol *kcontrol, if (ucontrol->value.enumerated.item[0] >= WM_ADSP_NUM_FW) return -EINVAL;
- mutex_lock(&dsp[e->shift_l].pwr_lock); + mutex_lock(&dsp[e->shift_l].cs_dsp.pwr_lock);
- if (dsp[e->shift_l].booted || !list_empty(&dsp[e->shift_l].compr_list)) + if (dsp[e->shift_l].cs_dsp.booted || !list_empty(&dsp[e->shift_l].compr_list)) ret = -EBUSY; else dsp[e->shift_l].fw = ucontrol->value.enumerated.item[0];
- mutex_unlock(&dsp[e->shift_l].pwr_lock); + mutex_unlock(&dsp[e->shift_l].cs_dsp.pwr_lock);
return ret; } @@ -824,7 +824,7 @@ const struct soc_enum wm_adsp_fw_enum[] = { }; EXPORT_SYMBOL_GPL(wm_adsp_fw_enum);
-static const struct cs_dsp_region *cs_dsp_find_region(struct wm_adsp *dsp, +static const struct cs_dsp_region *cs_dsp_find_region(struct cs_dsp *dsp, int type) { int i; @@ -871,7 +871,7 @@ static unsigned int cs_dsp_halo_region_to_reg(struct cs_dsp_region const *mem, } }
-static void cs_dsp_read_fw_status(struct wm_adsp *dsp, +static void cs_dsp_read_fw_status(struct cs_dsp *dsp, int noffs, unsigned int *offs) { unsigned int i; @@ -886,7 +886,7 @@ static void cs_dsp_read_fw_status(struct wm_adsp *dsp, } }
-static void cs_dsp_adsp2_show_fw_status(struct wm_adsp *dsp) +static void cs_dsp_adsp2_show_fw_status(struct cs_dsp *dsp) { unsigned int offs[] = { ADSP2_SCRATCH0, ADSP2_SCRATCH1, ADSP2_SCRATCH2, ADSP2_SCRATCH3, @@ -898,7 +898,7 @@ static void cs_dsp_adsp2_show_fw_status(struct wm_adsp *dsp) offs[0], offs[1], offs[2], offs[3]); }
-static void cs_dsp_adsp2v2_show_fw_status(struct wm_adsp *dsp) +static void cs_dsp_adsp2v2_show_fw_status(struct cs_dsp *dsp) { unsigned int offs[] = { ADSP2V2_SCRATCH0_1, ADSP2V2_SCRATCH2_3 };
@@ -909,7 +909,7 @@ static void cs_dsp_adsp2v2_show_fw_status(struct wm_adsp *dsp) offs[1] & 0xFFFF, offs[1] >> 16); }
-static void cs_dsp_halo_show_fw_status(struct wm_adsp *dsp) +static void cs_dsp_halo_show_fw_status(struct cs_dsp *dsp) { unsigned int offs[] = { HALO_SCRATCH1, HALO_SCRATCH2, HALO_SCRATCH3, HALO_SCRATCH4, @@ -929,7 +929,7 @@ static inline struct wm_coeff_ctl *bytes_ext_to_ctl(struct soc_bytes_ext *ext) static int cs_dsp_coeff_base_reg(struct cs_dsp_coeff_ctl *ctl, unsigned int *reg) { const struct cs_dsp_alg_region *alg_region = &ctl->alg_region; - struct wm_adsp *dsp = ctl->dsp; + struct cs_dsp *dsp = ctl->dsp; const struct cs_dsp_region *mem;
mem = cs_dsp_find_region(dsp, alg_region->type); @@ -972,7 +972,7 @@ static int wm_coeff_info(struct snd_kcontrol *kctl, static int cs_dsp_coeff_write_acked_control(struct cs_dsp_coeff_ctl *ctl, unsigned int event_id) { - struct wm_adsp *dsp = ctl->dsp; + struct cs_dsp *dsp = ctl->dsp; __be32 val = cpu_to_be32(event_id); unsigned int reg; int i, ret; @@ -1035,7 +1035,7 @@ static int cs_dsp_coeff_write_acked_control(struct cs_dsp_coeff_ctl *ctl, static int cs_dsp_coeff_write_ctrl_raw(struct cs_dsp_coeff_ctl *ctl, const void *buf, size_t len) { - struct wm_adsp *dsp = ctl->dsp; + struct cs_dsp *dsp = ctl->dsp; void *scratch; int ret; unsigned int reg; @@ -1146,7 +1146,7 @@ static int wm_coeff_put_acked(struct snd_kcontrol *kctl, static int cs_dsp_coeff_read_ctrl_raw(struct cs_dsp_coeff_ctl *ctl, void *buf, size_t len) { - struct wm_adsp *dsp = ctl->dsp; + struct cs_dsp *dsp = ctl->dsp; void *scratch; int ret; unsigned int reg; @@ -1325,7 +1325,7 @@ static int wmfw_add_ctl(struct wm_adsp *dsp, struct wm_coeff_ctl *ctl) return ret; }
-static int cs_dsp_coeff_init_control_caches(struct wm_adsp *dsp) +static int cs_dsp_coeff_init_control_caches(struct cs_dsp *dsp) { struct cs_dsp_coeff_ctl *ctl; int ret; @@ -1351,7 +1351,7 @@ static int cs_dsp_coeff_init_control_caches(struct wm_adsp *dsp) return 0; }
-static int cs_dsp_coeff_sync_controls(struct wm_adsp *dsp) +static int cs_dsp_coeff_sync_controls(struct cs_dsp *dsp) { struct cs_dsp_coeff_ctl *ctl; int ret; @@ -1370,8 +1370,8 @@ static int cs_dsp_coeff_sync_controls(struct wm_adsp *dsp) return 0; }
-static void cs_dsp_signal_event_controls(struct wm_adsp *dsp, - unsigned int event) +static void cs_dsp_signal_event_controls(struct cs_dsp *dsp, + unsigned int event) { struct cs_dsp_coeff_ctl *ctl; int ret; @@ -1396,7 +1396,11 @@ static void wm_adsp_ctl_work(struct work_struct *work) struct wm_coeff_ctl *ctl = container_of(work, struct wm_coeff_ctl, work); - wmfw_add_ctl(ctl->cs_ctl->dsp, ctl); + struct wm_adsp *dsp = container_of(ctl->cs_ctl->dsp, + struct wm_adsp, + cs_dsp); + + wmfw_add_ctl(dsp, ctl); }
static void cs_dsp_free_ctl_blk(struct cs_dsp_coeff_ctl *ctl) @@ -1408,7 +1412,8 @@ static void cs_dsp_free_ctl_blk(struct cs_dsp_coeff_ctl *ctl)
static int wm_adsp_control_add(struct cs_dsp_coeff_ctl *cs_ctl) { - struct wm_adsp *dsp = cs_ctl->dsp; + struct wm_adsp *dsp = container_of(cs_ctl->dsp, struct wm_adsp, cs_dsp); + struct cs_dsp *cs_dsp = &dsp->cs_dsp; struct wm_coeff_ctl *ctl; char name[SNDRV_CTL_ELEM_ID_NAME_MAXLEN]; const char *region_name; @@ -1423,20 +1428,20 @@ static int wm_adsp_control_add(struct cs_dsp_coeff_ctl *cs_ctl) return -EINVAL; }
- switch (dsp->fw_ver) { + switch (cs_dsp->fw_ver) { case 0: case 1: snprintf(name, SNDRV_CTL_ELEM_ID_NAME_MAXLEN, "%s %s %x", - dsp->name, region_name, cs_ctl->alg_region.alg); + cs_dsp->name, region_name, cs_ctl->alg_region.alg); break; case 2: ret = scnprintf(name, SNDRV_CTL_ELEM_ID_NAME_MAXLEN, - "%s%c %.12s %x", dsp->name, *region_name, + "%s%c %.12s %x", cs_dsp->name, *region_name, wm_adsp_fw_text[dsp->fw], cs_ctl->alg_region.alg); break; default: ret = scnprintf(name, SNDRV_CTL_ELEM_ID_NAME_MAXLEN, - "%s %.12s %x", dsp->name, + "%s %.12s %x", cs_dsp->name, wm_adsp_fw_text[dsp->fw], cs_ctl->alg_region.alg); break; } @@ -1490,7 +1495,7 @@ static void wm_adsp_control_remove(struct cs_dsp_coeff_ctl *cs_ctl) kfree(ctl); }
-static int cs_dsp_create_control(struct wm_adsp *dsp, +static int cs_dsp_create_control(struct cs_dsp *dsp, const struct cs_dsp_alg_region *alg_region, unsigned int offset, unsigned int len, const char *subname, unsigned int subname_len, @@ -1620,7 +1625,7 @@ static int cs_dsp_coeff_parse_int(int bytes, const u8 **pos) return val; }
-static inline void cs_dsp_coeff_parse_alg(struct wm_adsp *dsp, const u8 **data, +static inline void cs_dsp_coeff_parse_alg(struct cs_dsp *dsp, const u8 **data, struct cs_dsp_coeff_parsed_alg *blk) { const struct wmfw_adsp_alg_data *raw; @@ -1650,7 +1655,7 @@ static inline void cs_dsp_coeff_parse_alg(struct wm_adsp *dsp, const u8 **data, cs_dsp_dbg(dsp, "# of coefficient descriptors: %#x\n", blk->ncoeff); }
-static inline void cs_dsp_coeff_parse_coeff(struct wm_adsp *dsp, const u8 **data, +static inline void cs_dsp_coeff_parse_coeff(struct cs_dsp *dsp, const u8 **data, struct cs_dsp_coeff_parsed_coeff *blk) { const struct wmfw_adsp_coeff_data *raw; @@ -1696,7 +1701,7 @@ static inline void cs_dsp_coeff_parse_coeff(struct wm_adsp *dsp, const u8 **data cs_dsp_dbg(dsp, "\tALSA control len: %#x\n", blk->len); }
-static int cs_dsp_check_coeff_flags(struct wm_adsp *dsp, +static int cs_dsp_check_coeff_flags(struct cs_dsp *dsp, const struct cs_dsp_coeff_parsed_coeff *coeff_blk, unsigned int f_required, unsigned int f_illegal) @@ -1711,7 +1716,7 @@ static int cs_dsp_check_coeff_flags(struct wm_adsp *dsp, return 0; }
-static int cs_dsp_parse_coeff(struct wm_adsp *dsp, +static int cs_dsp_parse_coeff(struct cs_dsp *dsp, const struct wmfw_region *region) { struct cs_dsp_alg_region alg_region = {}; @@ -1782,7 +1787,7 @@ static int cs_dsp_parse_coeff(struct wm_adsp *dsp, return 0; }
-static unsigned int cs_dsp_adsp1_parse_sizes(struct wm_adsp *dsp, +static unsigned int cs_dsp_adsp1_parse_sizes(struct cs_dsp *dsp, const char * const file, unsigned int pos, const struct firmware *firmware) @@ -1818,6 +1823,7 @@ static int wm_adsp_request_firmware_file(struct wm_adsp *dsp, char **filename, char *suffix) { + struct cs_dsp *cs_dsp = &dsp->cs_dsp; int ret = 0;
*filename = kasprintf(GFP_KERNEL, "%s-%s-%s.%s", dsp->part, dsp->fwf_name, @@ -1825,7 +1831,7 @@ static int wm_adsp_request_firmware_file(struct wm_adsp *dsp, if (*filename == NULL) return -ENOMEM;
- ret = request_firmware(firmware, *filename, dsp->dev); + ret = request_firmware(firmware, *filename, cs_dsp->dev); if (ret != 0) { adsp_err(dsp, "Failed to request '%s'\n", *filename); kfree(*filename); @@ -1852,7 +1858,7 @@ static int wm_adsp_request_firmware_files(struct wm_adsp *dsp, return 0; }
-static unsigned int cs_dsp_adsp2_parse_sizes(struct wm_adsp *dsp, +static unsigned int cs_dsp_adsp2_parse_sizes(struct cs_dsp *dsp, const char * const file, unsigned int pos, const struct firmware *firmware) @@ -1868,7 +1874,7 @@ static unsigned int cs_dsp_adsp2_parse_sizes(struct wm_adsp *dsp, return pos + sizeof(*adsp2_sizes); }
-static bool cs_dsp_validate_version(struct wm_adsp *dsp, unsigned int version) +static bool cs_dsp_validate_version(struct cs_dsp *dsp, unsigned int version) { switch (version) { case 0: @@ -1882,7 +1888,7 @@ static bool cs_dsp_validate_version(struct wm_adsp *dsp, unsigned int version) } }
-static bool cs_dsp_halo_validate_version(struct wm_adsp *dsp, unsigned int version) +static bool cs_dsp_halo_validate_version(struct cs_dsp *dsp, unsigned int version) { switch (version) { case 3: @@ -1892,7 +1898,7 @@ static bool cs_dsp_halo_validate_version(struct wm_adsp *dsp, unsigned int versi } }
-static int cs_dsp_load(struct wm_adsp *dsp, const struct firmware *firmware, +static int cs_dsp_load(struct cs_dsp *dsp, const struct firmware *firmware, const char *file) { LIST_HEAD(buf_list); @@ -2082,7 +2088,7 @@ static int cs_dsp_load(struct wm_adsp *dsp, const struct firmware *firmware, * Find cs_dsp_coeff_ctl with input name as its subname * If not found, return NULL */ -static struct cs_dsp_coeff_ctl *cs_dsp_get_ctl(struct wm_adsp *dsp, +static struct cs_dsp_coeff_ctl *cs_dsp_get_ctl(struct cs_dsp *dsp, const char *name, int type, unsigned int alg) { @@ -2112,7 +2118,7 @@ int wm_adsp_write_ctl(struct wm_adsp *dsp, const char *name, int type, char ctl_name[SNDRV_CTL_ELEM_ID_NAME_MAXLEN]; int ret;
- cs_ctl = cs_dsp_get_ctl(dsp, name, type, alg); + cs_ctl = cs_dsp_get_ctl(&dsp->cs_dsp, name, type, alg); if (!cs_ctl) return -EINVAL;
@@ -2153,7 +2159,7 @@ int wm_adsp_read_ctl(struct wm_adsp *dsp, const char *name, int type, { struct cs_dsp_coeff_ctl *cs_ctl;
- cs_ctl = cs_dsp_get_ctl(dsp, name, type, alg); + cs_ctl = cs_dsp_get_ctl(&dsp->cs_dsp, name, type, alg); if (!cs_ctl) return -EINVAL;
@@ -2164,7 +2170,7 @@ int wm_adsp_read_ctl(struct wm_adsp *dsp, const char *name, int type, } EXPORT_SYMBOL_GPL(wm_adsp_read_ctl);
-static void cs_dsp_ctl_fixup_base(struct wm_adsp *dsp, +static void cs_dsp_ctl_fixup_base(struct cs_dsp *dsp, const struct cs_dsp_alg_region *alg_region) { struct cs_dsp_coeff_ctl *ctl; @@ -2178,7 +2184,7 @@ static void cs_dsp_ctl_fixup_base(struct wm_adsp *dsp, } }
-static void *cs_dsp_read_algs(struct wm_adsp *dsp, size_t n_algs, +static void *cs_dsp_read_algs(struct cs_dsp *dsp, size_t n_algs, const struct cs_dsp_region *mem, unsigned int pos, unsigned int len) { @@ -2231,7 +2237,7 @@ static void *cs_dsp_read_algs(struct wm_adsp *dsp, size_t n_algs, }
static struct cs_dsp_alg_region * - cs_dsp_find_alg_region(struct wm_adsp *dsp, int type, unsigned int id) + cs_dsp_find_alg_region(struct cs_dsp *dsp, int type, unsigned int id) { struct cs_dsp_alg_region *alg_region;
@@ -2243,7 +2249,7 @@ static struct cs_dsp_alg_region * return NULL; }
-static struct cs_dsp_alg_region *cs_dsp_create_region(struct wm_adsp *dsp, +static struct cs_dsp_alg_region *cs_dsp_create_region(struct cs_dsp *dsp, int type, __be32 id, __be32 base) { @@ -2265,7 +2271,7 @@ static struct cs_dsp_alg_region *cs_dsp_create_region(struct wm_adsp *dsp, return alg_region; }
-static void cs_dsp_free_alg_regions(struct wm_adsp *dsp) +static void cs_dsp_free_alg_regions(struct cs_dsp *dsp) { struct cs_dsp_alg_region *alg_region;
@@ -2278,7 +2284,7 @@ static void cs_dsp_free_alg_regions(struct wm_adsp *dsp) } }
-static void cs_dsp_parse_wmfw_id_header(struct wm_adsp *dsp, +static void cs_dsp_parse_wmfw_id_header(struct cs_dsp *dsp, struct wmfw_id_hdr *fw, int nalgs) { dsp->fw_id = be32_to_cpu(fw->id); @@ -2290,7 +2296,7 @@ static void cs_dsp_parse_wmfw_id_header(struct wm_adsp *dsp, nalgs); }
-static void cs_dsp_parse_wmfw_v3_id_header(struct wm_adsp *dsp, +static void cs_dsp_parse_wmfw_v3_id_header(struct cs_dsp *dsp, struct wmfw_v3_id_hdr *fw, int nalgs) { dsp->fw_id = be32_to_cpu(fw->id); @@ -2304,7 +2310,7 @@ static void cs_dsp_parse_wmfw_v3_id_header(struct wm_adsp *dsp, nalgs); }
-static int cs_dsp_create_regions(struct wm_adsp *dsp, __be32 id, int nregions, +static int cs_dsp_create_regions(struct cs_dsp *dsp, __be32 id, int nregions, const int *type, __be32 *base) { struct cs_dsp_alg_region *alg_region; @@ -2319,7 +2325,7 @@ static int cs_dsp_create_regions(struct wm_adsp *dsp, __be32 id, int nregions, return 0; }
-static int cs_dsp_adsp1_setup_algs(struct wm_adsp *dsp) +static int cs_dsp_adsp1_setup_algs(struct cs_dsp *dsp) { struct wmfw_adsp1_id_hdr adsp1_id; struct wmfw_adsp1_alg_hdr *adsp1_alg; @@ -2420,7 +2426,7 @@ static int cs_dsp_adsp1_setup_algs(struct wm_adsp *dsp) return ret; }
-static int cs_dsp_adsp2_setup_algs(struct wm_adsp *dsp) +static int cs_dsp_adsp2_setup_algs(struct cs_dsp *dsp) { struct wmfw_adsp2_id_hdr adsp2_id; struct wmfw_adsp2_alg_hdr *adsp2_alg; @@ -2549,7 +2555,7 @@ static int cs_dsp_adsp2_setup_algs(struct wm_adsp *dsp) return ret; }
-static int cs_dsp_halo_create_regions(struct wm_adsp *dsp, __be32 id, +static int cs_dsp_halo_create_regions(struct cs_dsp *dsp, __be32 id, __be32 xm_base, __be32 ym_base) { static const int types[] = { @@ -2561,7 +2567,7 @@ static int cs_dsp_halo_create_regions(struct wm_adsp *dsp, __be32 id, return cs_dsp_create_regions(dsp, id, ARRAY_SIZE(types), types, bases); }
-static int cs_dsp_halo_setup_algs(struct wm_adsp *dsp) +static int cs_dsp_halo_setup_algs(struct cs_dsp *dsp) { struct wmfw_halo_id_hdr halo_id; struct wmfw_halo_alg_hdr *halo_alg; @@ -2621,7 +2627,7 @@ static int cs_dsp_halo_setup_algs(struct wm_adsp *dsp) return ret; }
-static int cs_dsp_load_coeff(struct wm_adsp *dsp, const struct firmware *firmware, +static int cs_dsp_load_coeff(struct cs_dsp *dsp, const struct firmware *firmware, const char *file) { LIST_HEAD(buf_list); @@ -2800,10 +2806,8 @@ static int cs_dsp_load_coeff(struct wm_adsp *dsp, const struct firmware *firmwar return ret; }
-static int cs_dsp_create_name(struct wm_adsp *dsp) +static int cs_dsp_create_name(struct cs_dsp *dsp) { - char *p; - if (!dsp->name) { dsp->name = devm_kasprintf(dsp->dev, GFP_KERNEL, "DSP%d", dsp->num); @@ -2811,20 +2815,10 @@ static int cs_dsp_create_name(struct wm_adsp *dsp) return -ENOMEM; }
- if (!dsp->fwf_name) { - p = devm_kstrdup(dsp->dev, dsp->name, GFP_KERNEL); - if (!p) - return -ENOMEM; - - dsp->fwf_name = p; - for (; *p != 0; ++p) - *p = tolower(*p); - } - return 0; }
-static int cs_dsp_common_init(struct wm_adsp *dsp) +static int cs_dsp_common_init(struct cs_dsp *dsp) { int ret;
@@ -2840,13 +2834,27 @@ static int cs_dsp_common_init(struct wm_adsp *dsp) return 0; }
-static void wm_adsp_common_init(struct wm_adsp *dsp) +static int wm_adsp_common_init(struct wm_adsp *dsp) { + char *p; + INIT_LIST_HEAD(&dsp->compr_list); INIT_LIST_HEAD(&dsp->buffer_list); + + if (!dsp->fwf_name) { + p = devm_kstrdup(dsp->cs_dsp.dev, dsp->cs_dsp.name, GFP_KERNEL); + if (!p) + return -ENOMEM; + + dsp->fwf_name = p; + for (; *p != 0; ++p) + *p = tolower(*p); + } + + return 0; }
-static int cs_dsp_adsp1_init(struct wm_adsp *dsp) +static int cs_dsp_adsp1_init(struct cs_dsp *dsp) { dsp->ops = &cs_dsp_adsp1_ops;
@@ -2855,13 +2863,17 @@ static int cs_dsp_adsp1_init(struct wm_adsp *dsp)
int wm_adsp1_init(struct wm_adsp *dsp) { - wm_adsp_common_init(dsp); + int ret;
- return cs_dsp_adsp1_init(dsp); + ret = cs_dsp_adsp1_init(&dsp->cs_dsp); + if (ret) + return ret; + + return wm_adsp_common_init(dsp); } EXPORT_SYMBOL_GPL(wm_adsp1_init);
-static int cs_dsp_adsp1_power_up(struct wm_adsp *dsp, +static int cs_dsp_adsp1_power_up(struct cs_dsp *dsp, const struct firmware *wmfw_firmware, char *wmfw_filename, const struct firmware *coeff_firmware, char *coeff_filename, const char *fw_name) @@ -2941,7 +2953,7 @@ static int cs_dsp_adsp1_power_up(struct wm_adsp *dsp, return ret; }
-static void cs_dsp_adsp1_power_down(struct wm_adsp *dsp) +static void cs_dsp_adsp1_power_down(struct cs_dsp *dsp) { struct cs_dsp_coeff_ctl *ctl;
@@ -2991,7 +3003,7 @@ int wm_adsp1_event(struct snd_soc_dapm_widget *w, if (ret) break;
- ret = cs_dsp_adsp1_power_up(dsp, + ret = cs_dsp_adsp1_power_up(&dsp->cs_dsp, wmfw_firmware, wmfw_filename, coeff_firmware, coeff_filename, wm_adsp_fw_text[dsp->fw]); @@ -3001,7 +3013,7 @@ int wm_adsp1_event(struct snd_soc_dapm_widget *w, coeff_firmware, coeff_filename); break; case SND_SOC_DAPM_PRE_PMD: - cs_dsp_adsp1_power_down(dsp); + cs_dsp_adsp1_power_down(&dsp->cs_dsp); break; default: break; @@ -3011,7 +3023,7 @@ int wm_adsp1_event(struct snd_soc_dapm_widget *w, } EXPORT_SYMBOL_GPL(wm_adsp1_event);
-static int cs_dsp_adsp2v2_enable_core(struct wm_adsp *dsp) +static int cs_dsp_adsp2v2_enable_core(struct cs_dsp *dsp) { unsigned int val; int ret, count; @@ -3038,7 +3050,7 @@ static int cs_dsp_adsp2v2_enable_core(struct wm_adsp *dsp) return 0; }
-static int cs_dsp_adsp2_enable_core(struct wm_adsp *dsp) +static int cs_dsp_adsp2_enable_core(struct cs_dsp *dsp) { int ret;
@@ -3050,7 +3062,7 @@ static int cs_dsp_adsp2_enable_core(struct wm_adsp *dsp) return cs_dsp_adsp2v2_enable_core(dsp); }
-static int cs_dsp_adsp2_lock(struct wm_adsp *dsp, unsigned int lock_regions) +static int cs_dsp_adsp2_lock(struct cs_dsp *dsp, unsigned int lock_regions) { struct regmap *regmap = dsp->regmap; unsigned int code0, code1, lock_reg; @@ -3080,19 +3092,19 @@ static int cs_dsp_adsp2_lock(struct wm_adsp *dsp, unsigned int lock_regions) return 0; }
-static int cs_dsp_adsp2_enable_memory(struct wm_adsp *dsp) +static int cs_dsp_adsp2_enable_memory(struct cs_dsp *dsp) { return regmap_update_bits(dsp->regmap, dsp->base + ADSP2_CONTROL, ADSP2_MEM_ENA, ADSP2_MEM_ENA); }
-static void cs_dsp_adsp2_disable_memory(struct wm_adsp *dsp) +static void cs_dsp_adsp2_disable_memory(struct cs_dsp *dsp) { regmap_update_bits(dsp->regmap, dsp->base + ADSP2_CONTROL, ADSP2_MEM_ENA, 0); }
-static void cs_dsp_adsp2_disable_core(struct wm_adsp *dsp) +static void cs_dsp_adsp2_disable_core(struct cs_dsp *dsp) { regmap_write(dsp->regmap, dsp->base + ADSP2_RDMA_CONFIG_1, 0); regmap_write(dsp->regmap, dsp->base + ADSP2_WDMA_CONFIG_1, 0); @@ -3102,14 +3114,14 @@ static void cs_dsp_adsp2_disable_core(struct wm_adsp *dsp) ADSP2_SYS_ENA, 0); }
-static void cs_dsp_adsp2v2_disable_core(struct wm_adsp *dsp) +static void cs_dsp_adsp2v2_disable_core(struct cs_dsp *dsp) { regmap_write(dsp->regmap, dsp->base + ADSP2_RDMA_CONFIG_1, 0); regmap_write(dsp->regmap, dsp->base + ADSP2_WDMA_CONFIG_1, 0); regmap_write(dsp->regmap, dsp->base + ADSP2V2_WDMA_CONFIG_2, 0); }
-static int cs_dsp_halo_configure_mpu(struct wm_adsp *dsp, unsigned int lock_regions) +static int cs_dsp_halo_configure_mpu(struct cs_dsp *dsp, unsigned int lock_regions) { struct reg_sequence config[] = { { dsp->base + HALO_MPU_LOCK_CONFIG, 0x5555 }, @@ -3140,7 +3152,7 @@ static int cs_dsp_halo_configure_mpu(struct wm_adsp *dsp, unsigned int lock_regi return regmap_multi_reg_write(dsp->regmap, config, ARRAY_SIZE(config)); }
-static int cs_dsp_set_dspclk(struct wm_adsp *dsp, unsigned int freq) +static int cs_dsp_set_dspclk(struct cs_dsp *dsp, unsigned int freq) { int ret;
@@ -3159,7 +3171,7 @@ int wm_adsp2_set_dspclk(struct snd_soc_dapm_widget *w, unsigned int freq) struct wm_adsp *dsps = snd_soc_component_get_drvdata(component); struct wm_adsp *dsp = &dsps[w->shift];
- return cs_dsp_set_dspclk(dsp, freq); + return cs_dsp_set_dspclk(&dsp->cs_dsp, freq); } EXPORT_SYMBOL_GPL(wm_adsp2_set_dspclk);
@@ -3189,7 +3201,7 @@ int wm_adsp2_preloader_put(struct snd_kcontrol *kcontrol, struct wm_adsp *dsp = &dsps[mc->shift - 1]; char preload[32];
- snprintf(preload, ARRAY_SIZE(preload), "%s Preload", dsp->name); + snprintf(preload, ARRAY_SIZE(preload), "%s Preload", dsp->cs_dsp.name);
dsp->preloaded = ucontrol->value.integer.value[0];
@@ -3206,19 +3218,19 @@ int wm_adsp2_preloader_put(struct snd_kcontrol *kcontrol, } EXPORT_SYMBOL_GPL(wm_adsp2_preloader_put);
-static void cs_dsp_stop_watchdog(struct wm_adsp *dsp) +static void cs_dsp_stop_watchdog(struct cs_dsp *dsp) { regmap_update_bits(dsp->regmap, dsp->base + ADSP2_WATCHDOG, ADSP2_WDT_ENA_MASK, 0); }
-static void cs_dsp_halo_stop_watchdog(struct wm_adsp *dsp) +static void cs_dsp_halo_stop_watchdog(struct cs_dsp *dsp) { regmap_update_bits(dsp->regmap, dsp->base + HALO_WDT_CONTROL, HALO_WDT_EN_MASK, 0); }
-static int cs_dsp_power_up(struct wm_adsp *dsp, +static int cs_dsp_power_up(struct cs_dsp *dsp, const struct firmware *wmfw_firmware, char *wmfw_filename, const struct firmware *coeff_firmware, char *coeff_filename, const char *fw_name) @@ -3278,7 +3290,7 @@ static int cs_dsp_power_up(struct wm_adsp *dsp, return ret; }
-static void cs_dsp_power_down(struct wm_adsp *dsp) +static void cs_dsp_power_down(struct cs_dsp *dsp) { struct cs_dsp_coeff_ctl *ctl;
@@ -3321,7 +3333,7 @@ static void wm_adsp_boot_work(struct work_struct *work) if (ret) return;
- cs_dsp_power_up(dsp, + cs_dsp_power_up(&dsp->cs_dsp, wmfw_firmware, wmfw_filename, coeff_firmware, coeff_filename, wm_adsp_fw_text[dsp->fw]); @@ -3343,7 +3355,7 @@ int wm_adsp_early_event(struct snd_soc_dapm_widget *w, queue_work(system_unbound_wq, &dsp->boot_work); break; case SND_SOC_DAPM_PRE_PMD: - cs_dsp_power_down(dsp); + cs_dsp_power_down(&dsp->cs_dsp); break; default: break; @@ -3353,36 +3365,40 @@ int wm_adsp_early_event(struct snd_soc_dapm_widget *w, } EXPORT_SYMBOL_GPL(wm_adsp_early_event);
-static int cs_dsp_adsp2_start_core(struct wm_adsp *dsp) +static int cs_dsp_adsp2_start_core(struct cs_dsp *dsp) { return regmap_update_bits(dsp->regmap, dsp->base + ADSP2_CONTROL, ADSP2_CORE_ENA | ADSP2_START, ADSP2_CORE_ENA | ADSP2_START); }
-static void cs_dsp_adsp2_stop_core(struct wm_adsp *dsp) +static void cs_dsp_adsp2_stop_core(struct cs_dsp *dsp) { regmap_update_bits(dsp->regmap, dsp->base + ADSP2_CONTROL, ADSP2_CORE_ENA | ADSP2_START, 0); }
-static int wm_adsp_event_post_run(struct wm_adsp *dsp) +static int wm_adsp_event_post_run(struct cs_dsp *cs_dsp) { + struct wm_adsp *dsp = container_of(cs_dsp, struct wm_adsp, cs_dsp); + if (wm_adsp_fw[dsp->fw].num_caps != 0) return wm_adsp_buffer_init(dsp);
return 0; }
-static void wm_adsp_event_post_stop(struct wm_adsp *dsp) +static void wm_adsp_event_post_stop(struct cs_dsp *cs_dsp) { + struct wm_adsp *dsp = container_of(cs_dsp, struct wm_adsp, cs_dsp); + if (wm_adsp_fw[dsp->fw].num_caps != 0) wm_adsp_buffer_free(dsp);
dsp->fatal_error = false; }
-static int cs_dsp_run(struct wm_adsp *dsp) +static int cs_dsp_run(struct cs_dsp *dsp) { int ret;
@@ -3438,7 +3454,7 @@ static int cs_dsp_run(struct wm_adsp *dsp) return ret; }
-static void cs_dsp_stop(struct wm_adsp *dsp) +static void cs_dsp_stop(struct cs_dsp *dsp) { /* Tell the firmware to cleanup */ cs_dsp_signal_event_controls(dsp, CS_DSP_FW_EVENT_SHUTDOWN); @@ -3477,10 +3493,10 @@ int wm_adsp_event(struct snd_soc_dapm_widget *w, switch (event) { case SND_SOC_DAPM_POST_PMU: flush_work(&dsp->boot_work); - ret = cs_dsp_run(dsp); + ret = cs_dsp_run(&dsp->cs_dsp); break; case SND_SOC_DAPM_PRE_PMD: - cs_dsp_stop(dsp); + cs_dsp_stop(&dsp->cs_dsp); break; default: break; @@ -3490,7 +3506,7 @@ int wm_adsp_event(struct snd_soc_dapm_widget *w, } EXPORT_SYMBOL_GPL(wm_adsp_event);
-static int cs_dsp_halo_start_core(struct wm_adsp *dsp) +static int cs_dsp_halo_start_core(struct cs_dsp *dsp) { return regmap_update_bits(dsp->regmap, dsp->base + HALO_CCM_CORE_CONTROL, @@ -3498,7 +3514,7 @@ static int cs_dsp_halo_start_core(struct wm_adsp *dsp) HALO_CORE_RESET | HALO_CORE_EN); }
-static void cs_dsp_halo_stop_core(struct wm_adsp *dsp) +static void cs_dsp_halo_stop_core(struct cs_dsp *dsp) { regmap_update_bits(dsp->regmap, dsp->base + HALO_CCM_CORE_CONTROL, HALO_CORE_EN, 0); @@ -3512,10 +3528,10 @@ int wm_adsp2_component_probe(struct wm_adsp *dsp, struct snd_soc_component *comp { char preload[32];
- snprintf(preload, ARRAY_SIZE(preload), "%s Preload", dsp->name); + snprintf(preload, ARRAY_SIZE(preload), "%s Preload", dsp->cs_dsp.name); snd_soc_component_disable_pin(component, preload);
- cs_dsp_init_debugfs(dsp, component); + cs_dsp_init_debugfs(&dsp->cs_dsp, component->debugfs_root);
dsp->component = component;
@@ -3525,13 +3541,13 @@ EXPORT_SYMBOL_GPL(wm_adsp2_component_probe);
int wm_adsp2_component_remove(struct wm_adsp *dsp, struct snd_soc_component *component) { - cs_dsp_cleanup_debugfs(dsp); + cs_dsp_cleanup_debugfs(&dsp->cs_dsp);
return 0; } EXPORT_SYMBOL_GPL(wm_adsp2_component_remove);
-static int cs_dsp_adsp2_init(struct wm_adsp *dsp) +static int cs_dsp_adsp2_init(struct cs_dsp *dsp) { int ret;
@@ -3564,17 +3580,21 @@ static int cs_dsp_adsp2_init(struct wm_adsp *dsp)
int wm_adsp2_init(struct wm_adsp *dsp) { + int ret; + INIT_WORK(&dsp->boot_work, wm_adsp_boot_work);
dsp->sys_config_size = sizeof(struct wm_adsp_system_config_xm_hdr);
- wm_adsp_common_init(dsp); + ret = cs_dsp_adsp2_init(&dsp->cs_dsp); + if (ret) + return ret;
- return cs_dsp_adsp2_init(dsp); + return wm_adsp_common_init(dsp); } EXPORT_SYMBOL_GPL(wm_adsp2_init);
-static int cs_dsp_halo_init(struct wm_adsp *dsp) +static int cs_dsp_halo_init(struct cs_dsp *dsp) { dsp->ops = &cs_dsp_halo_ops;
@@ -3583,17 +3603,21 @@ static int cs_dsp_halo_init(struct wm_adsp *dsp)
int wm_halo_init(struct wm_adsp *dsp) { + int ret; + INIT_WORK(&dsp->boot_work, wm_adsp_boot_work);
dsp->sys_config_size = sizeof(struct wm_halo_system_config_xm_hdr);
- wm_adsp_common_init(dsp); + ret = cs_dsp_halo_init(&dsp->cs_dsp); + if (ret) + return ret;
- return cs_dsp_halo_init(dsp); + return wm_adsp_common_init(dsp); } EXPORT_SYMBOL_GPL(wm_halo_init);
-static void cs_dsp_remove(struct wm_adsp *dsp) +static void cs_dsp_remove(struct cs_dsp *dsp) { struct cs_dsp_coeff_ctl *ctl;
@@ -3609,7 +3633,7 @@ static void cs_dsp_remove(struct wm_adsp *dsp)
void wm_adsp2_remove(struct wm_adsp *dsp) { - cs_dsp_remove(dsp); + cs_dsp_remove(&dsp->cs_dsp); } EXPORT_SYMBOL_GPL(wm_adsp2_remove);
@@ -3662,7 +3686,7 @@ int wm_adsp_compr_open(struct wm_adsp *dsp, struct snd_compr_stream *stream) struct snd_soc_pcm_runtime *rtd = stream->private_data; int ret = 0;
- mutex_lock(&dsp->pwr_lock); + mutex_lock(&dsp->cs_dsp.pwr_lock);
if (wm_adsp_fw[dsp->fw].num_caps == 0) { adsp_err(dsp, "%s: Firmware does not support compressed API\n", @@ -3702,7 +3726,7 @@ int wm_adsp_compr_open(struct wm_adsp *dsp, struct snd_compr_stream *stream) stream->runtime->private_data = compr;
out: - mutex_unlock(&dsp->pwr_lock); + mutex_unlock(&dsp->cs_dsp.pwr_lock);
return ret; } @@ -3714,7 +3738,7 @@ int wm_adsp_compr_free(struct snd_soc_component *component, struct wm_adsp_compr *compr = stream->runtime->private_data; struct wm_adsp *dsp = compr->dsp;
- mutex_lock(&dsp->pwr_lock); + mutex_lock(&dsp->cs_dsp.pwr_lock);
wm_adsp_compr_detach(compr); list_del(&compr->list); @@ -3722,7 +3746,7 @@ int wm_adsp_compr_free(struct snd_soc_component *component, kfree(compr->raw_buf); kfree(compr);
- mutex_unlock(&dsp->pwr_lock); + mutex_unlock(&dsp->cs_dsp.pwr_lock);
return 0; } @@ -3836,7 +3860,7 @@ int wm_adsp_compr_get_caps(struct snd_soc_component *component, } EXPORT_SYMBOL_GPL(wm_adsp_compr_get_caps);
-static int cs_dsp_read_raw_data_block(struct wm_adsp *dsp, int mem_type, +static int cs_dsp_read_raw_data_block(struct cs_dsp *dsp, int mem_type, unsigned int mem_addr, unsigned int num_words, __be32 *data) { @@ -3857,8 +3881,8 @@ static int cs_dsp_read_raw_data_block(struct wm_adsp *dsp, int mem_type, return 0; }
-static inline int cs_dsp_read_data_word(struct wm_adsp *dsp, int mem_type, - unsigned int mem_addr, u32 *data) +static int cs_dsp_read_data_word(struct cs_dsp *dsp, int mem_type, + unsigned int mem_addr, u32 *data) { __be32 raw; int ret; @@ -3872,7 +3896,7 @@ static inline int cs_dsp_read_data_word(struct wm_adsp *dsp, int mem_type, return 0; }
-static int cs_dsp_write_data_word(struct wm_adsp *dsp, int mem_type, +static int cs_dsp_write_data_word(struct cs_dsp *dsp, int mem_type, unsigned int mem_addr, u32 data) { struct cs_dsp_region const *mem = cs_dsp_find_region(dsp, mem_type); @@ -3890,15 +3914,16 @@ static int cs_dsp_write_data_word(struct wm_adsp *dsp, int mem_type, static inline int wm_adsp_buffer_read(struct wm_adsp_compr_buf *buf, unsigned int field_offset, u32 *data) { - return cs_dsp_read_data_word(buf->dsp, buf->host_buf_mem_type, + return cs_dsp_read_data_word(&buf->dsp->cs_dsp, buf->host_buf_mem_type, buf->host_buf_ptr + field_offset, data); }
static inline int wm_adsp_buffer_write(struct wm_adsp_compr_buf *buf, unsigned int field_offset, u32 data) { - return cs_dsp_write_data_word(buf->dsp, buf->host_buf_mem_type, - buf->host_buf_ptr + field_offset, data); + return cs_dsp_write_data_word(&buf->dsp->cs_dsp, buf->host_buf_mem_type, + buf->host_buf_ptr + field_offset, + data); }
static void cs_dsp_remove_padding(u32 *buf, int nwords) @@ -3990,7 +4015,7 @@ static int wm_adsp_buffer_parse_legacy(struct wm_adsp *dsp) u32 xmalg, addr, magic; int i, ret;
- alg_region = cs_dsp_find_alg_region(dsp, WMFW_ADSP2_XM, dsp->fw_id); + alg_region = cs_dsp_find_alg_region(&dsp->cs_dsp, WMFW_ADSP2_XM, dsp->cs_dsp.fw_id); if (!alg_region) { adsp_err(dsp, "No algorithm region found\n"); return -EINVAL; @@ -4003,7 +4028,7 @@ static int wm_adsp_buffer_parse_legacy(struct wm_adsp *dsp) xmalg = dsp->sys_config_size / sizeof(__be32);
addr = alg_region->base + xmalg + ALG_XM_FIELD(magic); - ret = cs_dsp_read_data_word(dsp, WMFW_ADSP2_XM, addr, &magic); + ret = cs_dsp_read_data_word(&dsp->cs_dsp, WMFW_ADSP2_XM, addr, &magic); if (ret < 0) return ret;
@@ -4012,7 +4037,7 @@ static int wm_adsp_buffer_parse_legacy(struct wm_adsp *dsp)
addr = alg_region->base + xmalg + ALG_XM_FIELD(host_buf_ptr); for (i = 0; i < 5; ++i) { - ret = cs_dsp_read_data_word(dsp, WMFW_ADSP2_XM, addr, + ret = cs_dsp_read_data_word(&dsp->cs_dsp, WMFW_ADSP2_XM, addr, &buf->host_buf_ptr); if (ret < 0) return ret; @@ -4041,7 +4066,7 @@ static int wm_adsp_buffer_parse_coeff(struct cs_dsp_coeff_ctl *cs_ctl) { struct wm_adsp_host_buf_coeff_v1 coeff_v1; struct wm_adsp_compr_buf *buf; - struct wm_adsp *dsp = cs_ctl->dsp; + struct wm_adsp *dsp = container_of(cs_ctl->dsp, struct wm_adsp, cs_dsp); unsigned int version; int ret, i;
@@ -4107,7 +4132,7 @@ static int wm_adsp_buffer_init(struct wm_adsp *dsp) struct cs_dsp_coeff_ctl *cs_ctl; int ret;
- list_for_each_entry(cs_ctl, &dsp->ctl_list, list) { + list_for_each_entry(cs_ctl, &dsp->cs_dsp.ctl_list, list) { if (cs_ctl->type != WMFW_CTL_TYPE_HOST_BUFFER) continue;
@@ -4182,7 +4207,7 @@ int wm_adsp_compr_trigger(struct snd_soc_component *component,
compr_dbg(compr, "Trigger: %d\n", cmd);
- mutex_lock(&dsp->pwr_lock); + mutex_lock(&dsp->cs_dsp.pwr_lock);
switch (cmd) { case SNDRV_PCM_TRIGGER_START: @@ -4218,7 +4243,7 @@ int wm_adsp_compr_trigger(struct snd_soc_component *component, break; }
- mutex_unlock(&dsp->pwr_lock); + mutex_unlock(&dsp->cs_dsp.pwr_lock);
return ret; } @@ -4280,7 +4305,7 @@ int wm_adsp_compr_handle_irq(struct wm_adsp *dsp) struct wm_adsp_compr *compr; int ret = 0;
- mutex_lock(&dsp->pwr_lock); + mutex_lock(&dsp->cs_dsp.pwr_lock);
if (list_empty(&dsp->buffer_list)) { ret = -ENODEV; @@ -4318,7 +4343,7 @@ int wm_adsp_compr_handle_irq(struct wm_adsp *dsp) }
out: - mutex_unlock(&dsp->pwr_lock); + mutex_unlock(&dsp->cs_dsp.pwr_lock);
return ret; } @@ -4348,7 +4373,7 @@ int wm_adsp_compr_pointer(struct snd_soc_component *component,
compr_dbg(compr, "Pointer request\n");
- mutex_lock(&dsp->pwr_lock); + mutex_lock(&dsp->cs_dsp.pwr_lock);
buf = compr->buf;
@@ -4392,7 +4417,7 @@ int wm_adsp_compr_pointer(struct snd_soc_component *component, tstamp->sampling_rate = compr->sample_rate;
out: - mutex_unlock(&dsp->pwr_lock); + mutex_unlock(&dsp->cs_dsp.pwr_lock);
return ret; } @@ -4430,7 +4455,7 @@ static int wm_adsp_buffer_capture_block(struct wm_adsp_compr *compr, int target) return 0;
/* Read data from DSP */ - ret = cs_dsp_read_raw_data_block(buf->dsp, mem_type, adsp_addr, + ret = cs_dsp_read_raw_data_block(&buf->dsp->cs_dsp, mem_type, adsp_addr, nwords, (__be32 *)compr->raw_buf); if (ret < 0) return ret; @@ -4504,21 +4529,22 @@ int wm_adsp_compr_copy(struct snd_soc_component *component, struct wm_adsp *dsp = compr->dsp; int ret;
- mutex_lock(&dsp->pwr_lock); + mutex_lock(&dsp->cs_dsp.pwr_lock);
if (stream->direction == SND_COMPRESS_CAPTURE) ret = wm_adsp_compr_read(compr, buf, count); else ret = -ENOTSUPP;
- mutex_unlock(&dsp->pwr_lock); + mutex_unlock(&dsp->cs_dsp.pwr_lock);
return ret; } EXPORT_SYMBOL_GPL(wm_adsp_compr_copy);
-static void wm_adsp_fatal_error(struct wm_adsp *dsp) +static void wm_adsp_fatal_error(struct cs_dsp *cs_dsp) { + struct wm_adsp *dsp = container_of(cs_dsp, struct wm_adsp, cs_dsp); struct wm_adsp_compr *compr;
dsp->fatal_error = true; @@ -4529,7 +4555,7 @@ static void wm_adsp_fatal_error(struct wm_adsp *dsp) } }
-static void cs_dsp_adsp2_bus_error(struct wm_adsp *dsp) +static void cs_dsp_adsp2_bus_error(struct cs_dsp *dsp) { unsigned int val; struct regmap *regmap = dsp->regmap; @@ -4595,13 +4621,13 @@ irqreturn_t wm_adsp2_bus_error(int irq, void *data) { struct wm_adsp *dsp = (struct wm_adsp *)data;
- cs_dsp_adsp2_bus_error(dsp); + cs_dsp_adsp2_bus_error(&dsp->cs_dsp);
return IRQ_HANDLED; } EXPORT_SYMBOL_GPL(wm_adsp2_bus_error);
-static void cs_dsp_halo_bus_error(struct wm_adsp *dsp) +static void cs_dsp_halo_bus_error(struct cs_dsp *dsp) { struct regmap *regmap = dsp->regmap; unsigned int fault[6]; @@ -4658,13 +4684,13 @@ irqreturn_t wm_halo_bus_error(int irq, void *data) { struct wm_adsp *dsp = (struct wm_adsp *)data;
- cs_dsp_halo_bus_error(dsp); + cs_dsp_halo_bus_error(&dsp->cs_dsp);
return IRQ_HANDLED; } EXPORT_SYMBOL_GPL(wm_halo_bus_error);
-static void cs_dsp_halo_wdt_expire(struct wm_adsp *dsp) +static void cs_dsp_halo_wdt_expire(struct cs_dsp *dsp) { mutex_lock(&dsp->pwr_lock);
@@ -4680,7 +4706,7 @@ irqreturn_t wm_halo_wdt_expire(int irq, void *data) { struct wm_adsp *dsp = data;
- cs_dsp_halo_wdt_expire(dsp); + cs_dsp_halo_wdt_expire(&dsp->cs_dsp);
return IRQ_HANDLED; } diff --git a/sound/soc/codecs/wm_adsp.h b/sound/soc/codecs/wm_adsp.h index 3bad022c4bb1..5a70b6679fa3 100644 --- a/sound/soc/codecs/wm_adsp.h +++ b/sound/soc/codecs/wm_adsp.h @@ -49,7 +49,6 @@ struct cs_dsp_alg_region { unsigned int base; };
-struct wm_adsp; struct wm_adsp_compr; struct wm_adsp_compr_buf; struct cs_dsp_ops; @@ -60,7 +59,7 @@ struct cs_dsp_coeff_ctl { const char *subname; unsigned int subname_len; struct cs_dsp_alg_region alg_region; - struct wm_adsp *dsp; + struct cs_dsp *dsp; unsigned int enabled:1; struct list_head list; void *cache; @@ -73,16 +72,13 @@ struct cs_dsp_coeff_ctl { void *priv; };
-struct wm_adsp { - const char *part; +struct cs_dsp { const char *name; - const char *fwf_name; int rev; int num; int type; struct device *dev; struct regmap *regmap; - struct snd_soc_component *component;
const struct cs_dsp_ops *ops;
@@ -102,23 +98,13 @@ struct wm_adsp { const struct cs_dsp_region *mem; int num_mems;
- unsigned int sys_config_size; - - int fw; int fw_ver;
- bool preloaded; bool booted; bool running; - bool fatal_error;
struct list_head ctl_list;
- struct work_struct boot_work; - - struct list_head compr_list; - struct list_head buffer_list; - struct mutex pwr_lock;
unsigned int lock_regions; @@ -128,31 +114,49 @@ struct wm_adsp { char *wmfw_file_name; char *bin_file_name; #endif +};
+struct wm_adsp { + struct cs_dsp cs_dsp; + const char *part; + const char *fwf_name; + struct snd_soc_component *component; + + unsigned int sys_config_size; + + int fw; + + struct work_struct boot_work; + + bool preloaded; + bool fatal_error; + + struct list_head compr_list; + struct list_head buffer_list; };
struct cs_dsp_ops { - bool (*validate_version)(struct wm_adsp *dsp, unsigned int version); - unsigned int (*parse_sizes)(struct wm_adsp *dsp, + bool (*validate_version)(struct cs_dsp *dsp, unsigned int version); + unsigned int (*parse_sizes)(struct cs_dsp *dsp, const char * const file, unsigned int pos, const struct firmware *firmware); - int (*setup_algs)(struct wm_adsp *dsp); + int (*setup_algs)(struct cs_dsp *dsp); unsigned int (*region_to_reg)(struct cs_dsp_region const *mem, unsigned int offset);
- void (*show_fw_status)(struct wm_adsp *dsp); - void (*stop_watchdog)(struct wm_adsp *dsp); + void (*show_fw_status)(struct cs_dsp *dsp); + void (*stop_watchdog)(struct cs_dsp *dsp);
- int (*enable_memory)(struct wm_adsp *dsp); - void (*disable_memory)(struct wm_adsp *dsp); - int (*lock_memory)(struct wm_adsp *dsp, unsigned int lock_regions); + int (*enable_memory)(struct cs_dsp *dsp); + void (*disable_memory)(struct cs_dsp *dsp); + int (*lock_memory)(struct cs_dsp *dsp, unsigned int lock_regions);
- int (*enable_core)(struct wm_adsp *dsp); - void (*disable_core)(struct wm_adsp *dsp); + int (*enable_core)(struct cs_dsp *dsp); + void (*disable_core)(struct cs_dsp *dsp);
- int (*start_core)(struct wm_adsp *dsp); - void (*stop_core)(struct wm_adsp *dsp); + int (*start_core)(struct cs_dsp *dsp); + void (*stop_core)(struct cs_dsp *dsp); };
#define WM_ADSP1(wname, num) \
This is preparation for moving the generic DSP support out of ASoC. The event callbacks let the client add custom handling of events.
Signed-off-by: Simon Trimmer simont@opensource.cirrus.com Signed-off-by: Charles Keepax ckeepax@opensource.cirrus.com --- sound/soc/codecs/wm_adsp.c | 48 ++++++++++++++++++++++++++++++-------- sound/soc/codecs/wm_adsp.h | 10 ++++++++ 2 files changed, 48 insertions(+), 10 deletions(-)
diff --git a/sound/soc/codecs/wm_adsp.c b/sound/soc/codecs/wm_adsp.c index 092df446ff2f..6c5d55b3b311 100644 --- a/sound/soc/codecs/wm_adsp.c +++ b/sound/soc/codecs/wm_adsp.c @@ -318,6 +318,9 @@ static const struct cs_dsp_ops cs_dsp_adsp1_ops; static const struct cs_dsp_ops cs_dsp_adsp2_ops[]; static const struct cs_dsp_ops cs_dsp_halo_ops;
+static const struct cs_dsp_client_ops wm_adsp1_client_ops; +static const struct cs_dsp_client_ops wm_adsp2_client_ops; + struct cs_dsp_buf { struct list_head list; void *buf; @@ -1548,9 +1551,11 @@ static int cs_dsp_create_control(struct cs_dsp *dsp,
list_add(&ctl->list, &dsp->ctl_list);
- ret = wm_adsp_control_add(ctl); - if (ret) - goto err_list_del; + if (dsp->client_ops->control_add) { + ret = dsp->client_ops->control_add(ctl); + if (ret) + goto err_list_del; + }
return 0;
@@ -2865,6 +2870,8 @@ int wm_adsp1_init(struct wm_adsp *dsp) { int ret;
+ dsp->cs_dsp.client_ops = &wm_adsp1_client_ops; + ret = cs_dsp_adsp1_init(&dsp->cs_dsp); if (ret) return ret; @@ -3436,9 +3443,11 @@ static int cs_dsp_run(struct cs_dsp *dsp)
dsp->running = true;
- ret = wm_adsp_event_post_run(dsp); - if (ret < 0) - goto err; + if (dsp->client_ops->post_run) { + ret = dsp->client_ops->post_run(dsp); + if (ret) + goto err; + }
mutex_unlock(&dsp->pwr_lock);
@@ -3475,7 +3484,8 @@ static void cs_dsp_stop(struct cs_dsp *dsp) if (dsp->ops->disable_core) dsp->ops->disable_core(dsp);
- wm_adsp_event_post_stop(dsp); + if (dsp->client_ops->post_stop) + dsp->client_ops->post_stop(dsp);
mutex_unlock(&dsp->pwr_lock);
@@ -3585,6 +3595,7 @@ int wm_adsp2_init(struct wm_adsp *dsp) INIT_WORK(&dsp->boot_work, wm_adsp_boot_work);
dsp->sys_config_size = sizeof(struct wm_adsp_system_config_xm_hdr); + dsp->cs_dsp.client_ops = &wm_adsp2_client_ops;
ret = cs_dsp_adsp2_init(&dsp->cs_dsp); if (ret) @@ -3608,6 +3619,7 @@ int wm_halo_init(struct wm_adsp *dsp) INIT_WORK(&dsp->boot_work, wm_adsp_boot_work);
dsp->sys_config_size = sizeof(struct wm_halo_system_config_xm_hdr); + dsp->cs_dsp.client_ops = &wm_adsp2_client_ops;
ret = cs_dsp_halo_init(&dsp->cs_dsp); if (ret) @@ -3624,7 +3636,8 @@ static void cs_dsp_remove(struct cs_dsp *dsp) while (!list_empty(&dsp->ctl_list)) { ctl = list_first_entry(&dsp->ctl_list, struct cs_dsp_coeff_ctl, list);
- wm_adsp_control_remove(ctl); + if (dsp->client_ops->control_remove) + dsp->client_ops->control_remove(ctl);
list_del(&ctl->list); cs_dsp_free_ctl_blk(ctl); @@ -4573,7 +4586,8 @@ static void cs_dsp_adsp2_bus_error(struct cs_dsp *dsp) if (val & ADSP2_WDT_TIMEOUT_STS_MASK) { cs_dsp_err(dsp, "watchdog timeout error\n"); dsp->ops->stop_watchdog(dsp); - wm_adsp_fatal_error(dsp); + if (dsp->client_ops->watchdog_expired) + dsp->client_ops->watchdog_expired(dsp); }
if (val & (ADSP2_ADDR_ERR_MASK | ADSP2_REGION_LOCK_ERR_MASK)) { @@ -4697,7 +4711,8 @@ static void cs_dsp_halo_wdt_expire(struct cs_dsp *dsp) cs_dsp_warn(dsp, "WDT Expiry Fault\n");
dsp->ops->stop_watchdog(dsp); - wm_adsp_fatal_error(dsp); + if (dsp->client_ops->watchdog_expired) + dsp->client_ops->watchdog_expired(dsp);
mutex_unlock(&dsp->pwr_lock); } @@ -4718,6 +4733,11 @@ static const struct cs_dsp_ops cs_dsp_adsp1_ops = { .region_to_reg = cs_dsp_region_to_reg, };
+static const struct cs_dsp_client_ops wm_adsp1_client_ops = { + .control_add = wm_adsp_control_add, + .control_remove = wm_adsp_control_remove, +}; + static const struct cs_dsp_ops cs_dsp_adsp2_ops[] = { { .parse_sizes = cs_dsp_adsp2_parse_sizes, @@ -4791,4 +4811,12 @@ static const struct cs_dsp_ops cs_dsp_halo_ops = { .stop_core = cs_dsp_halo_stop_core, };
+static const struct cs_dsp_client_ops wm_adsp2_client_ops = { + .control_add = wm_adsp_control_add, + .control_remove = wm_adsp_control_remove, + .post_run = wm_adsp_event_post_run, + .post_stop = wm_adsp_event_post_stop, + .watchdog_expired = wm_adsp_fatal_error, +}; + MODULE_LICENSE("GPL v2"); diff --git a/sound/soc/codecs/wm_adsp.h b/sound/soc/codecs/wm_adsp.h index 5a70b6679fa3..25aaef74654c 100644 --- a/sound/soc/codecs/wm_adsp.h +++ b/sound/soc/codecs/wm_adsp.h @@ -52,6 +52,7 @@ struct cs_dsp_alg_region { struct wm_adsp_compr; struct wm_adsp_compr_buf; struct cs_dsp_ops; +struct cs_dsp_client_ops;
struct cs_dsp_coeff_ctl { const char *fw_name; @@ -81,6 +82,7 @@ struct cs_dsp { struct regmap *regmap;
const struct cs_dsp_ops *ops; + const struct cs_dsp_client_ops *client_ops;
unsigned int base; unsigned int base_sysinfo; @@ -237,4 +239,12 @@ int wm_adsp_write_ctl(struct wm_adsp *dsp, const char *name, int type, int wm_adsp_read_ctl(struct wm_adsp *dsp, const char *name, int type, unsigned int alg, void *buf, size_t len);
+struct cs_dsp_client_ops { + int (*control_add)(struct cs_dsp_coeff_ctl *ctl); + void (*control_remove)(struct cs_dsp_coeff_ctl *ctl); + int (*post_run)(struct cs_dsp *dsp); + void (*post_stop)(struct cs_dsp *dsp); + void (*watchdog_expired)(struct cs_dsp *dsp); +}; + #endif
wm_adsp originally provided firmware loading on some audio DSP and was implemented as an ASoC codec driver. However, the firmware loading now covers a wider range of DSP cores and peripherals containing them, beyond just audio. So it needs to be available to non-audio drivers. All the core firmware loading support has been moved into a new driver cs_dsp, leaving only the ASoC-specific parts in wm_adsp.
Signed-off-by: Simon Trimmer simont@opensource.cirrus.com Signed-off-by: Charles Keepax ckeepax@opensource.cirrus.com --- MAINTAINERS | 11 + drivers/firmware/Kconfig | 1 + drivers/firmware/Makefile | 1 + drivers/firmware/cirrus/Kconfig | 5 + drivers/firmware/cirrus/Makefile | 3 + drivers/firmware/cirrus/cs_dsp.c | 3109 +++++++++++++++++ include/linux/firmware/cirrus/cs_dsp.h | 242 ++ .../linux/firmware/cirrus}/wmfw.h | 0 sound/soc/codecs/Kconfig | 1 + sound/soc/codecs/wm_adsp.c | 2920 +--------------- sound/soc/codecs/wm_adsp.h | 132 +- 11 files changed, 3414 insertions(+), 3011 deletions(-) create mode 100644 drivers/firmware/cirrus/Kconfig create mode 100644 drivers/firmware/cirrus/Makefile create mode 100644 drivers/firmware/cirrus/cs_dsp.c create mode 100644 include/linux/firmware/cirrus/cs_dsp.h rename {sound/soc/codecs => include/linux/firmware/cirrus}/wmfw.h (100%)
diff --git a/MAINTAINERS b/MAINTAINERS index f555bfad3ca0..dd3ed0f809a3 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -4445,6 +4445,17 @@ L: patches@opensource.cirrus.com S: Maintained F: sound/soc/codecs/cs*
+CIRRUS LOGIC DSP FIRMWARE DRIVER +M: Simon Trimmer simont@opensource.cirrus.com +M: Charles Keepax ckeepax@opensource.cirrus.com +M: Richard Fitzgerald rf@opensource.cirrus.com +L: patches@opensource.cirrus.com +S: Supported +W: https://github.com/CirrusLogic/linux-drivers/wiki +T: git https://github.com/CirrusLogic/linux-drivers.git +F: drivers/firmware/cirrus/* +F: include/linux/firmware/cirrus/* + CIRRUS LOGIC EP93XX ETHERNET DRIVER M: Hartley Sweeten hsweeten@visionengravers.com L: netdev@vger.kernel.org diff --git a/drivers/firmware/Kconfig b/drivers/firmware/Kconfig index 220a58cf0a44..fd2a5f68acab 100644 --- a/drivers/firmware/Kconfig +++ b/drivers/firmware/Kconfig @@ -298,6 +298,7 @@ config TURRIS_MOX_RWTM
source "drivers/firmware/arm_ffa/Kconfig" source "drivers/firmware/broadcom/Kconfig" +source "drivers/firmware/cirrus/Kconfig" source "drivers/firmware/google/Kconfig" source "drivers/firmware/efi/Kconfig" source "drivers/firmware/imx/Kconfig" diff --git a/drivers/firmware/Makefile b/drivers/firmware/Makefile index 5ced0673d94b..4e58cb474a68 100644 --- a/drivers/firmware/Makefile +++ b/drivers/firmware/Makefile @@ -28,6 +28,7 @@ obj-$(CONFIG_TURRIS_MOX_RWTM) += turris-mox-rwtm.o obj-y += arm_ffa/ obj-y += arm_scmi/ obj-y += broadcom/ +obj-y += cirrus/ obj-y += meson/ obj-$(CONFIG_GOOGLE_FIRMWARE) += google/ obj-$(CONFIG_EFI) += efi/ diff --git a/drivers/firmware/cirrus/Kconfig b/drivers/firmware/cirrus/Kconfig new file mode 100644 index 000000000000..f9503cb481d2 --- /dev/null +++ b/drivers/firmware/cirrus/Kconfig @@ -0,0 +1,5 @@ +# SPDX-License-Identifier: GPL-2.0-only + +config CS_DSP + tristate + default n diff --git a/drivers/firmware/cirrus/Makefile b/drivers/firmware/cirrus/Makefile new file mode 100644 index 000000000000..f074e2638c9c --- /dev/null +++ b/drivers/firmware/cirrus/Makefile @@ -0,0 +1,3 @@ +# SPDX-License-Identifier: GPL-2.0 +# +obj-$(CONFIG_CS_DSP) += cs_dsp.o diff --git a/drivers/firmware/cirrus/cs_dsp.c b/drivers/firmware/cirrus/cs_dsp.c new file mode 100644 index 000000000000..948dd8382686 --- /dev/null +++ b/drivers/firmware/cirrus/cs_dsp.c @@ -0,0 +1,3109 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * cs_dsp.c -- Cirrus Logic DSP firmware support + * + * Based on sound/soc/codecs/wm_adsp.c + * + * Copyright 2012 Wolfson Microelectronics plc + * Copyright (C) 2015-2021 Cirrus Logic, Inc. and + * Cirrus Logic International Semiconductor Ltd. + */ + +#include <linux/ctype.h> +#include <linux/debugfs.h> +#include <linux/delay.h> +#include <linux/device.h> +#include <linux/firmware.h> +#include <linux/interrupt.h> +#include <linux/list.h> +#include <linux/module.h> +#include <linux/moduleparam.h> +#include <linux/regmap.h> +#include <linux/slab.h> +#include <linux/vmalloc.h> +#include <linux/workqueue.h> + +#include <linux/firmware/cirrus/cs_dsp.h> +#include <linux/firmware/cirrus/wmfw.h> + +#define cs_dsp_err(_dsp, fmt, ...) \ + dev_err(_dsp->dev, "%s: " fmt, _dsp->name, ##__VA_ARGS__) +#define cs_dsp_warn(_dsp, fmt, ...) \ + dev_warn(_dsp->dev, "%s: " fmt, _dsp->name, ##__VA_ARGS__) +#define cs_dsp_info(_dsp, fmt, ...) \ + dev_info(_dsp->dev, "%s: " fmt, _dsp->name, ##__VA_ARGS__) +#define cs_dsp_dbg(_dsp, fmt, ...) \ + dev_dbg(_dsp->dev, "%s: " fmt, _dsp->name, ##__VA_ARGS__) + +#define ADSP1_CONTROL_1 0x00 +#define ADSP1_CONTROL_2 0x02 +#define ADSP1_CONTROL_3 0x03 +#define ADSP1_CONTROL_4 0x04 +#define ADSP1_CONTROL_5 0x06 +#define ADSP1_CONTROL_6 0x07 +#define ADSP1_CONTROL_7 0x08 +#define ADSP1_CONTROL_8 0x09 +#define ADSP1_CONTROL_9 0x0A +#define ADSP1_CONTROL_10 0x0B +#define ADSP1_CONTROL_11 0x0C +#define ADSP1_CONTROL_12 0x0D +#define ADSP1_CONTROL_13 0x0F +#define ADSP1_CONTROL_14 0x10 +#define ADSP1_CONTROL_15 0x11 +#define ADSP1_CONTROL_16 0x12 +#define ADSP1_CONTROL_17 0x13 +#define ADSP1_CONTROL_18 0x14 +#define ADSP1_CONTROL_19 0x16 +#define ADSP1_CONTROL_20 0x17 +#define ADSP1_CONTROL_21 0x18 +#define ADSP1_CONTROL_22 0x1A +#define ADSP1_CONTROL_23 0x1B +#define ADSP1_CONTROL_24 0x1C +#define ADSP1_CONTROL_25 0x1E +#define ADSP1_CONTROL_26 0x20 +#define ADSP1_CONTROL_27 0x21 +#define ADSP1_CONTROL_28 0x22 +#define ADSP1_CONTROL_29 0x23 +#define ADSP1_CONTROL_30 0x24 +#define ADSP1_CONTROL_31 0x26 + +/* + * ADSP1 Control 19 + */ +#define ADSP1_WDMA_BUFFER_LENGTH_MASK 0x00FF /* DSP1_WDMA_BUFFER_LENGTH - [7:0] */ +#define ADSP1_WDMA_BUFFER_LENGTH_SHIFT 0 /* DSP1_WDMA_BUFFER_LENGTH - [7:0] */ +#define ADSP1_WDMA_BUFFER_LENGTH_WIDTH 8 /* DSP1_WDMA_BUFFER_LENGTH - [7:0] */ + +/* + * ADSP1 Control 30 + */ +#define ADSP1_DBG_CLK_ENA 0x0008 /* DSP1_DBG_CLK_ENA */ +#define ADSP1_DBG_CLK_ENA_MASK 0x0008 /* DSP1_DBG_CLK_ENA */ +#define ADSP1_DBG_CLK_ENA_SHIFT 3 /* DSP1_DBG_CLK_ENA */ +#define ADSP1_DBG_CLK_ENA_WIDTH 1 /* DSP1_DBG_CLK_ENA */ +#define ADSP1_SYS_ENA 0x0004 /* DSP1_SYS_ENA */ +#define ADSP1_SYS_ENA_MASK 0x0004 /* DSP1_SYS_ENA */ +#define ADSP1_SYS_ENA_SHIFT 2 /* DSP1_SYS_ENA */ +#define ADSP1_SYS_ENA_WIDTH 1 /* DSP1_SYS_ENA */ +#define ADSP1_CORE_ENA 0x0002 /* DSP1_CORE_ENA */ +#define ADSP1_CORE_ENA_MASK 0x0002 /* DSP1_CORE_ENA */ +#define ADSP1_CORE_ENA_SHIFT 1 /* DSP1_CORE_ENA */ +#define ADSP1_CORE_ENA_WIDTH 1 /* DSP1_CORE_ENA */ +#define ADSP1_START 0x0001 /* DSP1_START */ +#define ADSP1_START_MASK 0x0001 /* DSP1_START */ +#define ADSP1_START_SHIFT 0 /* DSP1_START */ +#define ADSP1_START_WIDTH 1 /* DSP1_START */ + +/* + * ADSP1 Control 31 + */ +#define ADSP1_CLK_SEL_MASK 0x0007 /* CLK_SEL_ENA */ +#define ADSP1_CLK_SEL_SHIFT 0 /* CLK_SEL_ENA */ +#define ADSP1_CLK_SEL_WIDTH 3 /* CLK_SEL_ENA */ + +#define ADSP2_CONTROL 0x0 +#define ADSP2_CLOCKING 0x1 +#define ADSP2V2_CLOCKING 0x2 +#define ADSP2_STATUS1 0x4 +#define ADSP2_WDMA_CONFIG_1 0x30 +#define ADSP2_WDMA_CONFIG_2 0x31 +#define ADSP2V2_WDMA_CONFIG_2 0x32 +#define ADSP2_RDMA_CONFIG_1 0x34 + +#define ADSP2_SCRATCH0 0x40 +#define ADSP2_SCRATCH1 0x41 +#define ADSP2_SCRATCH2 0x42 +#define ADSP2_SCRATCH3 0x43 + +#define ADSP2V2_SCRATCH0_1 0x40 +#define ADSP2V2_SCRATCH2_3 0x42 + +/* + * ADSP2 Control + */ +#define ADSP2_MEM_ENA 0x0010 /* DSP1_MEM_ENA */ +#define ADSP2_MEM_ENA_MASK 0x0010 /* DSP1_MEM_ENA */ +#define ADSP2_MEM_ENA_SHIFT 4 /* DSP1_MEM_ENA */ +#define ADSP2_MEM_ENA_WIDTH 1 /* DSP1_MEM_ENA */ +#define ADSP2_SYS_ENA 0x0004 /* DSP1_SYS_ENA */ +#define ADSP2_SYS_ENA_MASK 0x0004 /* DSP1_SYS_ENA */ +#define ADSP2_SYS_ENA_SHIFT 2 /* DSP1_SYS_ENA */ +#define ADSP2_SYS_ENA_WIDTH 1 /* DSP1_SYS_ENA */ +#define ADSP2_CORE_ENA 0x0002 /* DSP1_CORE_ENA */ +#define ADSP2_CORE_ENA_MASK 0x0002 /* DSP1_CORE_ENA */ +#define ADSP2_CORE_ENA_SHIFT 1 /* DSP1_CORE_ENA */ +#define ADSP2_CORE_ENA_WIDTH 1 /* DSP1_CORE_ENA */ +#define ADSP2_START 0x0001 /* DSP1_START */ +#define ADSP2_START_MASK 0x0001 /* DSP1_START */ +#define ADSP2_START_SHIFT 0 /* DSP1_START */ +#define ADSP2_START_WIDTH 1 /* DSP1_START */ + +/* + * ADSP2 clocking + */ +#define ADSP2_CLK_SEL_MASK 0x0007 /* CLK_SEL_ENA */ +#define ADSP2_CLK_SEL_SHIFT 0 /* CLK_SEL_ENA */ +#define ADSP2_CLK_SEL_WIDTH 3 /* CLK_SEL_ENA */ + +/* + * ADSP2V2 clocking + */ +#define ADSP2V2_CLK_SEL_MASK 0x70000 /* CLK_SEL_ENA */ +#define ADSP2V2_CLK_SEL_SHIFT 16 /* CLK_SEL_ENA */ +#define ADSP2V2_CLK_SEL_WIDTH 3 /* CLK_SEL_ENA */ + +#define ADSP2V2_RATE_MASK 0x7800 /* DSP_RATE */ +#define ADSP2V2_RATE_SHIFT 11 /* DSP_RATE */ +#define ADSP2V2_RATE_WIDTH 4 /* DSP_RATE */ + +/* + * ADSP2 Status 1 + */ +#define ADSP2_RAM_RDY 0x0001 +#define ADSP2_RAM_RDY_MASK 0x0001 +#define ADSP2_RAM_RDY_SHIFT 0 +#define ADSP2_RAM_RDY_WIDTH 1 + +/* + * ADSP2 Lock support + */ +#define ADSP2_LOCK_CODE_0 0x5555 +#define ADSP2_LOCK_CODE_1 0xAAAA + +#define ADSP2_WATCHDOG 0x0A +#define ADSP2_BUS_ERR_ADDR 0x52 +#define ADSP2_REGION_LOCK_STATUS 0x64 +#define ADSP2_LOCK_REGION_1_LOCK_REGION_0 0x66 +#define ADSP2_LOCK_REGION_3_LOCK_REGION_2 0x68 +#define ADSP2_LOCK_REGION_5_LOCK_REGION_4 0x6A +#define ADSP2_LOCK_REGION_7_LOCK_REGION_6 0x6C +#define ADSP2_LOCK_REGION_9_LOCK_REGION_8 0x6E +#define ADSP2_LOCK_REGION_CTRL 0x7A +#define ADSP2_PMEM_ERR_ADDR_XMEM_ERR_ADDR 0x7C + +#define ADSP2_REGION_LOCK_ERR_MASK 0x8000 +#define ADSP2_ADDR_ERR_MASK 0x4000 +#define ADSP2_WDT_TIMEOUT_STS_MASK 0x2000 +#define ADSP2_CTRL_ERR_PAUSE_ENA 0x0002 +#define ADSP2_CTRL_ERR_EINT 0x0001 + +#define ADSP2_BUS_ERR_ADDR_MASK 0x00FFFFFF +#define ADSP2_XMEM_ERR_ADDR_MASK 0x0000FFFF +#define ADSP2_PMEM_ERR_ADDR_MASK 0x7FFF0000 +#define ADSP2_PMEM_ERR_ADDR_SHIFT 16 +#define ADSP2_WDT_ENA_MASK 0xFFFFFFFD + +#define ADSP2_LOCK_REGION_SHIFT 16 + +/* + * Event control messages + */ +#define CS_DSP_FW_EVENT_SHUTDOWN 0x000001 + +/* + * HALO system info + */ +#define HALO_AHBM_WINDOW_DEBUG_0 0x02040 +#define HALO_AHBM_WINDOW_DEBUG_1 0x02044 + +/* + * HALO core + */ +#define HALO_SCRATCH1 0x005c0 +#define HALO_SCRATCH2 0x005c8 +#define HALO_SCRATCH3 0x005d0 +#define HALO_SCRATCH4 0x005d8 +#define HALO_CCM_CORE_CONTROL 0x41000 +#define HALO_CORE_SOFT_RESET 0x00010 +#define HALO_WDT_CONTROL 0x47000 + +/* + * HALO MPU banks + */ +#define HALO_MPU_XMEM_ACCESS_0 0x43000 +#define HALO_MPU_YMEM_ACCESS_0 0x43004 +#define HALO_MPU_WINDOW_ACCESS_0 0x43008 +#define HALO_MPU_XREG_ACCESS_0 0x4300C +#define HALO_MPU_YREG_ACCESS_0 0x43014 +#define HALO_MPU_XMEM_ACCESS_1 0x43018 +#define HALO_MPU_YMEM_ACCESS_1 0x4301C +#define HALO_MPU_WINDOW_ACCESS_1 0x43020 +#define HALO_MPU_XREG_ACCESS_1 0x43024 +#define HALO_MPU_YREG_ACCESS_1 0x4302C +#define HALO_MPU_XMEM_ACCESS_2 0x43030 +#define HALO_MPU_YMEM_ACCESS_2 0x43034 +#define HALO_MPU_WINDOW_ACCESS_2 0x43038 +#define HALO_MPU_XREG_ACCESS_2 0x4303C +#define HALO_MPU_YREG_ACCESS_2 0x43044 +#define HALO_MPU_XMEM_ACCESS_3 0x43048 +#define HALO_MPU_YMEM_ACCESS_3 0x4304C +#define HALO_MPU_WINDOW_ACCESS_3 0x43050 +#define HALO_MPU_XREG_ACCESS_3 0x43054 +#define HALO_MPU_YREG_ACCESS_3 0x4305C +#define HALO_MPU_XM_VIO_ADDR 0x43100 +#define HALO_MPU_XM_VIO_STATUS 0x43104 +#define HALO_MPU_YM_VIO_ADDR 0x43108 +#define HALO_MPU_YM_VIO_STATUS 0x4310C +#define HALO_MPU_PM_VIO_ADDR 0x43110 +#define HALO_MPU_PM_VIO_STATUS 0x43114 +#define HALO_MPU_LOCK_CONFIG 0x43140 + +/* + * HALO_AHBM_WINDOW_DEBUG_1 + */ +#define HALO_AHBM_CORE_ERR_ADDR_MASK 0x0fffff00 +#define HALO_AHBM_CORE_ERR_ADDR_SHIFT 8 +#define HALO_AHBM_FLAGS_ERR_MASK 0x000000ff + +/* + * HALO_CCM_CORE_CONTROL + */ +#define HALO_CORE_RESET 0x00000200 +#define HALO_CORE_EN 0x00000001 + +/* + * HALO_CORE_SOFT_RESET + */ +#define HALO_CORE_SOFT_RESET_MASK 0x00000001 + +/* + * HALO_WDT_CONTROL + */ +#define HALO_WDT_EN_MASK 0x00000001 + +/* + * HALO_MPU_?M_VIO_STATUS + */ +#define HALO_MPU_VIO_STS_MASK 0x007e0000 +#define HALO_MPU_VIO_STS_SHIFT 17 +#define HALO_MPU_VIO_ERR_WR_MASK 0x00008000 +#define HALO_MPU_VIO_ERR_SRC_MASK 0x00007fff +#define HALO_MPU_VIO_ERR_SRC_SHIFT 0 + +struct cs_dsp_ops { + bool (*validate_version)(struct cs_dsp *dsp, unsigned int version); + unsigned int (*parse_sizes)(struct cs_dsp *dsp, + const char * const file, + unsigned int pos, + const struct firmware *firmware); + int (*setup_algs)(struct cs_dsp *dsp); + unsigned int (*region_to_reg)(struct cs_dsp_region const *mem, + unsigned int offset); + + void (*show_fw_status)(struct cs_dsp *dsp); + void (*stop_watchdog)(struct cs_dsp *dsp); + + int (*enable_memory)(struct cs_dsp *dsp); + void (*disable_memory)(struct cs_dsp *dsp); + int (*lock_memory)(struct cs_dsp *dsp, unsigned int lock_regions); + + int (*enable_core)(struct cs_dsp *dsp); + void (*disable_core)(struct cs_dsp *dsp); + + int (*start_core)(struct cs_dsp *dsp); + void (*stop_core)(struct cs_dsp *dsp); +}; + +static const struct cs_dsp_ops cs_dsp_adsp1_ops; +static const struct cs_dsp_ops cs_dsp_adsp2_ops[]; +static const struct cs_dsp_ops cs_dsp_halo_ops; + +struct cs_dsp_buf { + struct list_head list; + void *buf; +}; + +static struct cs_dsp_buf *cs_dsp_buf_alloc(const void *src, size_t len, + struct list_head *list) +{ + struct cs_dsp_buf *buf = kzalloc(sizeof(*buf), GFP_KERNEL); + + if (buf == NULL) + return NULL; + + buf->buf = vmalloc(len); + if (!buf->buf) { + kfree(buf); + return NULL; + } + memcpy(buf->buf, src, len); + + if (list) + list_add_tail(&buf->list, list); + + return buf; +} + +static void cs_dsp_buf_free(struct list_head *list) +{ + while (!list_empty(list)) { + struct cs_dsp_buf *buf = list_first_entry(list, + struct cs_dsp_buf, + list); + list_del(&buf->list); + vfree(buf->buf); + kfree(buf); + } +} + +/** + * cs_dsp_mem_region_name() - Return a name string for a memory type + * @type: the memory type to match + * + * Return: A const string identifying the memory region. + */ +const char *cs_dsp_mem_region_name(unsigned int type) +{ + switch (type) { + case WMFW_ADSP1_PM: + return "PM"; + case WMFW_HALO_PM_PACKED: + return "PM_PACKED"; + case WMFW_ADSP1_DM: + return "DM"; + case WMFW_ADSP2_XM: + return "XM"; + case WMFW_HALO_XM_PACKED: + return "XM_PACKED"; + case WMFW_ADSP2_YM: + return "YM"; + case WMFW_HALO_YM_PACKED: + return "YM_PACKED"; + case WMFW_ADSP1_ZM: + return "ZM"; + default: + return NULL; + } +} +EXPORT_SYMBOL_GPL(cs_dsp_mem_region_name); + +#ifdef CONFIG_DEBUG_FS +static void cs_dsp_debugfs_save_wmfwname(struct cs_dsp *dsp, const char *s) +{ + char *tmp = kasprintf(GFP_KERNEL, "%s\n", s); + + kfree(dsp->wmfw_file_name); + dsp->wmfw_file_name = tmp; +} + +static void cs_dsp_debugfs_save_binname(struct cs_dsp *dsp, const char *s) +{ + char *tmp = kasprintf(GFP_KERNEL, "%s\n", s); + + kfree(dsp->bin_file_name); + dsp->bin_file_name = tmp; +} + +static void cs_dsp_debugfs_clear(struct cs_dsp *dsp) +{ + kfree(dsp->wmfw_file_name); + kfree(dsp->bin_file_name); + dsp->wmfw_file_name = NULL; + dsp->bin_file_name = NULL; +} + +static ssize_t cs_dsp_debugfs_wmfw_read(struct file *file, + char __user *user_buf, + size_t count, loff_t *ppos) +{ + struct cs_dsp *dsp = file->private_data; + ssize_t ret; + + mutex_lock(&dsp->pwr_lock); + + if (!dsp->wmfw_file_name || !dsp->booted) + ret = 0; + else + ret = simple_read_from_buffer(user_buf, count, ppos, + dsp->wmfw_file_name, + strlen(dsp->wmfw_file_name)); + + mutex_unlock(&dsp->pwr_lock); + return ret; +} + +static ssize_t cs_dsp_debugfs_bin_read(struct file *file, + char __user *user_buf, + size_t count, loff_t *ppos) +{ + struct cs_dsp *dsp = file->private_data; + ssize_t ret; + + mutex_lock(&dsp->pwr_lock); + + if (!dsp->bin_file_name || !dsp->booted) + ret = 0; + else + ret = simple_read_from_buffer(user_buf, count, ppos, + dsp->bin_file_name, + strlen(dsp->bin_file_name)); + + mutex_unlock(&dsp->pwr_lock); + return ret; +} + +static const struct { + const char *name; + const struct file_operations fops; +} cs_dsp_debugfs_fops[] = { + { + .name = "wmfw_file_name", + .fops = { + .open = simple_open, + .read = cs_dsp_debugfs_wmfw_read, + }, + }, + { + .name = "bin_file_name", + .fops = { + .open = simple_open, + .read = cs_dsp_debugfs_bin_read, + }, + }, +}; + +/** + * cs_dsp_init_debugfs() - Create and populate DSP representation in debugfs + * @dsp: pointer to DSP structure + * @debugfs_root: pointer to debugfs directory in which to create this DSP + * representation + */ +void cs_dsp_init_debugfs(struct cs_dsp *dsp, struct dentry *debugfs_root) +{ + struct dentry *root = NULL; + int i; + + root = debugfs_create_dir(dsp->name, debugfs_root); + + debugfs_create_bool("booted", 0444, root, &dsp->booted); + debugfs_create_bool("running", 0444, root, &dsp->running); + debugfs_create_x32("fw_id", 0444, root, &dsp->fw_id); + debugfs_create_x32("fw_version", 0444, root, &dsp->fw_id_version); + + for (i = 0; i < ARRAY_SIZE(cs_dsp_debugfs_fops); ++i) + debugfs_create_file(cs_dsp_debugfs_fops[i].name, 0444, root, + dsp, &cs_dsp_debugfs_fops[i].fops); + + dsp->debugfs_root = root; +} +EXPORT_SYMBOL_GPL(cs_dsp_init_debugfs); + +/** + * cs_dsp_cleanup_debugfs() - Removes DSP representation from debugfs + * @dsp: pointer to DSP structure + */ +void cs_dsp_cleanup_debugfs(struct cs_dsp *dsp) +{ + cs_dsp_debugfs_clear(dsp); + debugfs_remove_recursive(dsp->debugfs_root); + dsp->debugfs_root = NULL; +} +EXPORT_SYMBOL_GPL(cs_dsp_cleanup_debugfs); +#else +void cs_dsp_init_debugfs(struct cs_dsp *dsp, struct dentry *debugfs_root) +{ +} +EXPORT_SYMBOL_GPL(cs_dsp_init_debugfs); + +void cs_dsp_cleanup_debugfs(struct cs_dsp *dsp) +{ +} +EXPORT_SYMBOL_GPL(cs_dsp_cleanup_debugfs); + +static inline void cs_dsp_debugfs_save_wmfwname(struct cs_dsp *dsp, + const char *s) +{ +} + +static inline void cs_dsp_debugfs_save_binname(struct cs_dsp *dsp, + const char *s) +{ +} + +static inline void cs_dsp_debugfs_clear(struct cs_dsp *dsp) +{ +} +#endif + +static const struct cs_dsp_region *cs_dsp_find_region(struct cs_dsp *dsp, + int type) +{ + int i; + + for (i = 0; i < dsp->num_mems; i++) + if (dsp->mem[i].type == type) + return &dsp->mem[i]; + + return NULL; +} + +static unsigned int cs_dsp_region_to_reg(struct cs_dsp_region const *mem, + unsigned int offset) +{ + switch (mem->type) { + case WMFW_ADSP1_PM: + return mem->base + (offset * 3); + case WMFW_ADSP1_DM: + case WMFW_ADSP2_XM: + case WMFW_ADSP2_YM: + case WMFW_ADSP1_ZM: + return mem->base + (offset * 2); + default: + WARN(1, "Unknown memory region type"); + return offset; + } +} + +static unsigned int cs_dsp_halo_region_to_reg(struct cs_dsp_region const *mem, + unsigned int offset) +{ + switch (mem->type) { + case WMFW_ADSP2_XM: + case WMFW_ADSP2_YM: + return mem->base + (offset * 4); + case WMFW_HALO_XM_PACKED: + case WMFW_HALO_YM_PACKED: + return (mem->base + (offset * 3)) & ~0x3; + case WMFW_HALO_PM_PACKED: + return mem->base + (offset * 5); + default: + WARN(1, "Unknown memory region type"); + return offset; + } +} + +static void cs_dsp_read_fw_status(struct cs_dsp *dsp, + int noffs, unsigned int *offs) +{ + unsigned int i; + int ret; + + for (i = 0; i < noffs; ++i) { + ret = regmap_read(dsp->regmap, dsp->base + offs[i], &offs[i]); + if (ret) { + cs_dsp_err(dsp, "Failed to read SCRATCH%u: %d\n", i, ret); + return; + } + } +} + +static void cs_dsp_adsp2_show_fw_status(struct cs_dsp *dsp) +{ + unsigned int offs[] = { + ADSP2_SCRATCH0, ADSP2_SCRATCH1, ADSP2_SCRATCH2, ADSP2_SCRATCH3, + }; + + cs_dsp_read_fw_status(dsp, ARRAY_SIZE(offs), offs); + + cs_dsp_dbg(dsp, "FW SCRATCH 0:0x%x 1:0x%x 2:0x%x 3:0x%x\n", + offs[0], offs[1], offs[2], offs[3]); +} + +static void cs_dsp_adsp2v2_show_fw_status(struct cs_dsp *dsp) +{ + unsigned int offs[] = { ADSP2V2_SCRATCH0_1, ADSP2V2_SCRATCH2_3 }; + + cs_dsp_read_fw_status(dsp, ARRAY_SIZE(offs), offs); + + cs_dsp_dbg(dsp, "FW SCRATCH 0:0x%x 1:0x%x 2:0x%x 3:0x%x\n", + offs[0] & 0xFFFF, offs[0] >> 16, + offs[1] & 0xFFFF, offs[1] >> 16); +} + +static void cs_dsp_halo_show_fw_status(struct cs_dsp *dsp) +{ + unsigned int offs[] = { + HALO_SCRATCH1, HALO_SCRATCH2, HALO_SCRATCH3, HALO_SCRATCH4, + }; + + cs_dsp_read_fw_status(dsp, ARRAY_SIZE(offs), offs); + + cs_dsp_dbg(dsp, "FW SCRATCH 0:0x%x 1:0x%x 2:0x%x 3:0x%x\n", + offs[0], offs[1], offs[2], offs[3]); +} + +static int cs_dsp_coeff_base_reg(struct cs_dsp_coeff_ctl *ctl, unsigned int *reg) +{ + const struct cs_dsp_alg_region *alg_region = &ctl->alg_region; + struct cs_dsp *dsp = ctl->dsp; + const struct cs_dsp_region *mem; + + mem = cs_dsp_find_region(dsp, alg_region->type); + if (!mem) { + cs_dsp_err(dsp, "No base for region %x\n", + alg_region->type); + return -EINVAL; + } + + *reg = dsp->ops->region_to_reg(mem, ctl->alg_region.base + ctl->offset); + + return 0; +} + +/** + * cs_dsp_coeff_write_acked_control() - Sends event_id to the acked control + * @ctl: pointer to acked coefficient control + * @event_id: the value to write to the given acked control + * + * Once the value has been written to the control the function shall block + * until the running firmware acknowledges the write or timeout is exceeded. + * + * Must be called with pwr_lock held. + * + * Return: Zero for success, a negative number on error. + */ +int cs_dsp_coeff_write_acked_control(struct cs_dsp_coeff_ctl *ctl, unsigned int event_id) +{ + struct cs_dsp *dsp = ctl->dsp; + __be32 val = cpu_to_be32(event_id); + unsigned int reg; + int i, ret; + + if (!dsp->running) + return -EPERM; + + ret = cs_dsp_coeff_base_reg(ctl, ®); + if (ret) + return ret; + + cs_dsp_dbg(dsp, "Sending 0x%x to acked control alg 0x%x %s:0x%x\n", + event_id, ctl->alg_region.alg, + cs_dsp_mem_region_name(ctl->alg_region.type), ctl->offset); + + ret = regmap_raw_write(dsp->regmap, reg, &val, sizeof(val)); + if (ret) { + cs_dsp_err(dsp, "Failed to write %x: %d\n", reg, ret); + return ret; + } + + /* + * Poll for ack, we initially poll at ~1ms intervals for firmwares + * that respond quickly, then go to ~10ms polls. A firmware is unlikely + * to ack instantly so we do the first 1ms delay before reading the + * control to avoid a pointless bus transaction + */ + for (i = 0; i < CS_DSP_ACKED_CTL_TIMEOUT_MS;) { + switch (i) { + case 0 ... CS_DSP_ACKED_CTL_N_QUICKPOLLS - 1: + usleep_range(1000, 2000); + i++; + break; + default: + usleep_range(10000, 20000); + i += 10; + break; + } + + ret = regmap_raw_read(dsp->regmap, reg, &val, sizeof(val)); + if (ret) { + cs_dsp_err(dsp, "Failed to read %x: %d\n", reg, ret); + return ret; + } + + if (val == 0) { + cs_dsp_dbg(dsp, "Acked control ACKED at poll %u\n", i); + return 0; + } + } + + cs_dsp_warn(dsp, "Acked control @0x%x alg:0x%x %s:0x%x timed out\n", + reg, ctl->alg_region.alg, + cs_dsp_mem_region_name(ctl->alg_region.type), + ctl->offset); + + return -ETIMEDOUT; +} +EXPORT_SYMBOL_GPL(cs_dsp_coeff_write_acked_control); + +static int cs_dsp_coeff_write_ctrl_raw(struct cs_dsp_coeff_ctl *ctl, + const void *buf, size_t len) +{ + struct cs_dsp *dsp = ctl->dsp; + void *scratch; + int ret; + unsigned int reg; + + ret = cs_dsp_coeff_base_reg(ctl, ®); + if (ret) + return ret; + + scratch = kmemdup(buf, len, GFP_KERNEL | GFP_DMA); + if (!scratch) + return -ENOMEM; + + ret = regmap_raw_write(dsp->regmap, reg, scratch, + len); + if (ret) { + cs_dsp_err(dsp, "Failed to write %zu bytes to %x: %d\n", + len, reg, ret); + kfree(scratch); + return ret; + } + cs_dsp_dbg(dsp, "Wrote %zu bytes to %x\n", len, reg); + + kfree(scratch); + + return 0; +} + +/** + * cs_dsp_coeff_write_ctrl() - Writes the given buffer to the given coefficient control + * @ctl: pointer to coefficient control + * @buf: the buffer to write to the given control + * @len: the length of the buffer + * + * Must be called with pwr_lock held. + * + * Return: Zero for success, a negative number on error. + */ +int cs_dsp_coeff_write_ctrl(struct cs_dsp_coeff_ctl *ctl, const void *buf, size_t len) +{ + int ret = 0; + + if (ctl->flags & WMFW_CTL_FLAG_VOLATILE) + ret = -EPERM; + else if (buf != ctl->cache) + memcpy(ctl->cache, buf, len); + + ctl->set = 1; + if (ctl->enabled && ctl->dsp->running) + ret = cs_dsp_coeff_write_ctrl_raw(ctl, buf, len); + + return ret; +} +EXPORT_SYMBOL_GPL(cs_dsp_coeff_write_ctrl); + +static int cs_dsp_coeff_read_ctrl_raw(struct cs_dsp_coeff_ctl *ctl, void *buf, size_t len) +{ + struct cs_dsp *dsp = ctl->dsp; + void *scratch; + int ret; + unsigned int reg; + + ret = cs_dsp_coeff_base_reg(ctl, ®); + if (ret) + return ret; + + scratch = kmalloc(len, GFP_KERNEL | GFP_DMA); + if (!scratch) + return -ENOMEM; + + ret = regmap_raw_read(dsp->regmap, reg, scratch, len); + if (ret) { + cs_dsp_err(dsp, "Failed to read %zu bytes from %x: %d\n", + len, reg, ret); + kfree(scratch); + return ret; + } + cs_dsp_dbg(dsp, "Read %zu bytes from %x\n", len, reg); + + memcpy(buf, scratch, len); + kfree(scratch); + + return 0; +} + +/** + * cs_dsp_coeff_read_ctrl() - Reads the given coefficient control into the given buffer + * @ctl: pointer to coefficient control + * @buf: the buffer to store to the given control + * @len: the length of the buffer + * + * Must be called with pwr_lock held. + * + * Return: Zero for success, a negative number on error. + */ +int cs_dsp_coeff_read_ctrl(struct cs_dsp_coeff_ctl *ctl, void *buf, size_t len) +{ + int ret = 0; + + if (ctl->flags & WMFW_CTL_FLAG_VOLATILE) { + if (ctl->enabled && ctl->dsp->running) + return cs_dsp_coeff_read_ctrl_raw(ctl, buf, len); + else + return -EPERM; + } else { + if (!ctl->flags && ctl->enabled && ctl->dsp->running) + ret = cs_dsp_coeff_read_ctrl_raw(ctl, ctl->cache, ctl->len); + + if (buf != ctl->cache) + memcpy(buf, ctl->cache, len); + } + + return ret; +} +EXPORT_SYMBOL_GPL(cs_dsp_coeff_read_ctrl); + +static int cs_dsp_coeff_init_control_caches(struct cs_dsp *dsp) +{ + struct cs_dsp_coeff_ctl *ctl; + int ret; + + list_for_each_entry(ctl, &dsp->ctl_list, list) { + if (!ctl->enabled || ctl->set) + continue; + if (ctl->flags & WMFW_CTL_FLAG_VOLATILE) + continue; + + /* + * For readable controls populate the cache from the DSP memory. + * For non-readable controls the cache was zero-filled when + * created so we don't need to do anything. + */ + if (!ctl->flags || (ctl->flags & WMFW_CTL_FLAG_READABLE)) { + ret = cs_dsp_coeff_read_ctrl_raw(ctl, ctl->cache, ctl->len); + if (ret < 0) + return ret; + } + } + + return 0; +} + +static int cs_dsp_coeff_sync_controls(struct cs_dsp *dsp) +{ + struct cs_dsp_coeff_ctl *ctl; + int ret; + + list_for_each_entry(ctl, &dsp->ctl_list, list) { + if (!ctl->enabled) + continue; + if (ctl->set && !(ctl->flags & WMFW_CTL_FLAG_VOLATILE)) { + ret = cs_dsp_coeff_write_ctrl_raw(ctl, ctl->cache, + ctl->len); + if (ret < 0) + return ret; + } + } + + return 0; +} + +static void cs_dsp_signal_event_controls(struct cs_dsp *dsp, + unsigned int event) +{ + struct cs_dsp_coeff_ctl *ctl; + int ret; + + list_for_each_entry(ctl, &dsp->ctl_list, list) { + if (ctl->type != WMFW_CTL_TYPE_HOSTEVENT) + continue; + + if (!ctl->enabled) + continue; + + ret = cs_dsp_coeff_write_acked_control(ctl, event); + if (ret) + cs_dsp_warn(dsp, + "Failed to send 0x%x event to alg 0x%x (%d)\n", + event, ctl->alg_region.alg, ret); + } +} + +static void cs_dsp_free_ctl_blk(struct cs_dsp_coeff_ctl *ctl) +{ + kfree(ctl->cache); + kfree(ctl->subname); + kfree(ctl); +} + +static int cs_dsp_create_control(struct cs_dsp *dsp, + const struct cs_dsp_alg_region *alg_region, + unsigned int offset, unsigned int len, + const char *subname, unsigned int subname_len, + unsigned int flags, unsigned int type) +{ + struct cs_dsp_coeff_ctl *ctl; + int ret; + + list_for_each_entry(ctl, &dsp->ctl_list, list) { + if (ctl->fw_name == dsp->fw_name && + ctl->alg_region.alg == alg_region->alg && + ctl->alg_region.type == alg_region->type) { + if ((!subname && !ctl->subname) || + (subname && !strncmp(ctl->subname, subname, ctl->subname_len))) { + if (!ctl->enabled) + ctl->enabled = 1; + return 0; + } + } + } + + ctl = kzalloc(sizeof(*ctl), GFP_KERNEL); + if (!ctl) + return -ENOMEM; + + ctl->fw_name = dsp->fw_name; + ctl->alg_region = *alg_region; + if (subname && dsp->fw_ver >= 2) { + ctl->subname_len = subname_len; + ctl->subname = kmemdup(subname, + strlen(subname) + 1, GFP_KERNEL); + if (!ctl->subname) { + ret = -ENOMEM; + goto err_ctl; + } + } + ctl->enabled = 1; + ctl->set = 0; + ctl->dsp = dsp; + + ctl->flags = flags; + ctl->type = type; + ctl->offset = offset; + ctl->len = len; + ctl->cache = kzalloc(ctl->len, GFP_KERNEL); + if (!ctl->cache) { + ret = -ENOMEM; + goto err_ctl_subname; + } + + list_add(&ctl->list, &dsp->ctl_list); + + if (dsp->client_ops->control_add) { + ret = dsp->client_ops->control_add(ctl); + if (ret) + goto err_list_del; + } + + return 0; + +err_list_del: + list_del(&ctl->list); + kfree(ctl->cache); +err_ctl_subname: + kfree(ctl->subname); +err_ctl: + kfree(ctl); + + return ret; +} + +struct cs_dsp_coeff_parsed_alg { + int id; + const u8 *name; + int name_len; + int ncoeff; +}; + +struct cs_dsp_coeff_parsed_coeff { + int offset; + int mem_type; + const u8 *name; + int name_len; + unsigned int ctl_type; + int flags; + int len; +}; + +static int cs_dsp_coeff_parse_string(int bytes, const u8 **pos, const u8 **str) +{ + int length; + + switch (bytes) { + case 1: + length = **pos; + break; + case 2: + length = le16_to_cpu(*((__le16 *)*pos)); + break; + default: + return 0; + } + + if (str) + *str = *pos + bytes; + + *pos += ((length + bytes) + 3) & ~0x03; + + return length; +} + +static int cs_dsp_coeff_parse_int(int bytes, const u8 **pos) +{ + int val = 0; + + switch (bytes) { + case 2: + val = le16_to_cpu(*((__le16 *)*pos)); + break; + case 4: + val = le32_to_cpu(*((__le32 *)*pos)); + break; + default: + break; + } + + *pos += bytes; + + return val; +} + +static inline void cs_dsp_coeff_parse_alg(struct cs_dsp *dsp, const u8 **data, + struct cs_dsp_coeff_parsed_alg *blk) +{ + const struct wmfw_adsp_alg_data *raw; + + switch (dsp->fw_ver) { + case 0: + case 1: + raw = (const struct wmfw_adsp_alg_data *)*data; + *data = raw->data; + + blk->id = le32_to_cpu(raw->id); + blk->name = raw->name; + blk->name_len = strlen(raw->name); + blk->ncoeff = le32_to_cpu(raw->ncoeff); + break; + default: + blk->id = cs_dsp_coeff_parse_int(sizeof(raw->id), data); + blk->name_len = cs_dsp_coeff_parse_string(sizeof(u8), data, + &blk->name); + cs_dsp_coeff_parse_string(sizeof(u16), data, NULL); + blk->ncoeff = cs_dsp_coeff_parse_int(sizeof(raw->ncoeff), data); + break; + } + + cs_dsp_dbg(dsp, "Algorithm ID: %#x\n", blk->id); + cs_dsp_dbg(dsp, "Algorithm name: %.*s\n", blk->name_len, blk->name); + cs_dsp_dbg(dsp, "# of coefficient descriptors: %#x\n", blk->ncoeff); +} + +static inline void cs_dsp_coeff_parse_coeff(struct cs_dsp *dsp, const u8 **data, + struct cs_dsp_coeff_parsed_coeff *blk) +{ + const struct wmfw_adsp_coeff_data *raw; + const u8 *tmp; + int length; + + switch (dsp->fw_ver) { + case 0: + case 1: + raw = (const struct wmfw_adsp_coeff_data *)*data; + *data = *data + sizeof(raw->hdr) + le32_to_cpu(raw->hdr.size); + + blk->offset = le16_to_cpu(raw->hdr.offset); + blk->mem_type = le16_to_cpu(raw->hdr.type); + blk->name = raw->name; + blk->name_len = strlen(raw->name); + blk->ctl_type = le16_to_cpu(raw->ctl_type); + blk->flags = le16_to_cpu(raw->flags); + blk->len = le32_to_cpu(raw->len); + break; + default: + tmp = *data; + blk->offset = cs_dsp_coeff_parse_int(sizeof(raw->hdr.offset), &tmp); + blk->mem_type = cs_dsp_coeff_parse_int(sizeof(raw->hdr.type), &tmp); + length = cs_dsp_coeff_parse_int(sizeof(raw->hdr.size), &tmp); + blk->name_len = cs_dsp_coeff_parse_string(sizeof(u8), &tmp, + &blk->name); + cs_dsp_coeff_parse_string(sizeof(u8), &tmp, NULL); + cs_dsp_coeff_parse_string(sizeof(u16), &tmp, NULL); + blk->ctl_type = cs_dsp_coeff_parse_int(sizeof(raw->ctl_type), &tmp); + blk->flags = cs_dsp_coeff_parse_int(sizeof(raw->flags), &tmp); + blk->len = cs_dsp_coeff_parse_int(sizeof(raw->len), &tmp); + + *data = *data + sizeof(raw->hdr) + length; + break; + } + + cs_dsp_dbg(dsp, "\tCoefficient type: %#x\n", blk->mem_type); + cs_dsp_dbg(dsp, "\tCoefficient offset: %#x\n", blk->offset); + cs_dsp_dbg(dsp, "\tCoefficient name: %.*s\n", blk->name_len, blk->name); + cs_dsp_dbg(dsp, "\tCoefficient flags: %#x\n", blk->flags); + cs_dsp_dbg(dsp, "\tALSA control type: %#x\n", blk->ctl_type); + cs_dsp_dbg(dsp, "\tALSA control len: %#x\n", blk->len); +} + +static int cs_dsp_check_coeff_flags(struct cs_dsp *dsp, + const struct cs_dsp_coeff_parsed_coeff *coeff_blk, + unsigned int f_required, + unsigned int f_illegal) +{ + if ((coeff_blk->flags & f_illegal) || + ((coeff_blk->flags & f_required) != f_required)) { + cs_dsp_err(dsp, "Illegal flags 0x%x for control type 0x%x\n", + coeff_blk->flags, coeff_blk->ctl_type); + return -EINVAL; + } + + return 0; +} + +static int cs_dsp_parse_coeff(struct cs_dsp *dsp, + const struct wmfw_region *region) +{ + struct cs_dsp_alg_region alg_region = {}; + struct cs_dsp_coeff_parsed_alg alg_blk; + struct cs_dsp_coeff_parsed_coeff coeff_blk; + const u8 *data = region->data; + int i, ret; + + cs_dsp_coeff_parse_alg(dsp, &data, &alg_blk); + for (i = 0; i < alg_blk.ncoeff; i++) { + cs_dsp_coeff_parse_coeff(dsp, &data, &coeff_blk); + + switch (coeff_blk.ctl_type) { + case WMFW_CTL_TYPE_BYTES: + break; + case WMFW_CTL_TYPE_ACKED: + if (coeff_blk.flags & WMFW_CTL_FLAG_SYS) + continue; /* ignore */ + + ret = cs_dsp_check_coeff_flags(dsp, &coeff_blk, + WMFW_CTL_FLAG_VOLATILE | + WMFW_CTL_FLAG_WRITEABLE | + WMFW_CTL_FLAG_READABLE, + 0); + if (ret) + return -EINVAL; + break; + case WMFW_CTL_TYPE_HOSTEVENT: + ret = cs_dsp_check_coeff_flags(dsp, &coeff_blk, + WMFW_CTL_FLAG_SYS | + WMFW_CTL_FLAG_VOLATILE | + WMFW_CTL_FLAG_WRITEABLE | + WMFW_CTL_FLAG_READABLE, + 0); + if (ret) + return -EINVAL; + break; + case WMFW_CTL_TYPE_HOST_BUFFER: + ret = cs_dsp_check_coeff_flags(dsp, &coeff_blk, + WMFW_CTL_FLAG_SYS | + WMFW_CTL_FLAG_VOLATILE | + WMFW_CTL_FLAG_READABLE, + 0); + if (ret) + return -EINVAL; + break; + default: + cs_dsp_err(dsp, "Unknown control type: %d\n", + coeff_blk.ctl_type); + return -EINVAL; + } + + alg_region.type = coeff_blk.mem_type; + alg_region.alg = alg_blk.id; + + ret = cs_dsp_create_control(dsp, &alg_region, + coeff_blk.offset, + coeff_blk.len, + coeff_blk.name, + coeff_blk.name_len, + coeff_blk.flags, + coeff_blk.ctl_type); + if (ret < 0) + cs_dsp_err(dsp, "Failed to create control: %.*s, %d\n", + coeff_blk.name_len, coeff_blk.name, ret); + } + + return 0; +} + +static unsigned int cs_dsp_adsp1_parse_sizes(struct cs_dsp *dsp, + const char * const file, + unsigned int pos, + const struct firmware *firmware) +{ + const struct wmfw_adsp1_sizes *adsp1_sizes; + + adsp1_sizes = (void *)&firmware->data[pos]; + + cs_dsp_dbg(dsp, "%s: %d DM, %d PM, %d ZM\n", file, + le32_to_cpu(adsp1_sizes->dm), le32_to_cpu(adsp1_sizes->pm), + le32_to_cpu(adsp1_sizes->zm)); + + return pos + sizeof(*adsp1_sizes); +} + +static unsigned int cs_dsp_adsp2_parse_sizes(struct cs_dsp *dsp, + const char * const file, + unsigned int pos, + const struct firmware *firmware) +{ + const struct wmfw_adsp2_sizes *adsp2_sizes; + + adsp2_sizes = (void *)&firmware->data[pos]; + + cs_dsp_dbg(dsp, "%s: %d XM, %d YM %d PM, %d ZM\n", file, + le32_to_cpu(adsp2_sizes->xm), le32_to_cpu(adsp2_sizes->ym), + le32_to_cpu(adsp2_sizes->pm), le32_to_cpu(adsp2_sizes->zm)); + + return pos + sizeof(*adsp2_sizes); +} + +static bool cs_dsp_validate_version(struct cs_dsp *dsp, unsigned int version) +{ + switch (version) { + case 0: + cs_dsp_warn(dsp, "Deprecated file format %d\n", version); + return true; + case 1: + case 2: + return true; + default: + return false; + } +} + +static bool cs_dsp_halo_validate_version(struct cs_dsp *dsp, unsigned int version) +{ + switch (version) { + case 3: + return true; + default: + return false; + } +} + +static int cs_dsp_load(struct cs_dsp *dsp, const struct firmware *firmware, + const char *file) +{ + LIST_HEAD(buf_list); + struct regmap *regmap = dsp->regmap; + unsigned int pos = 0; + const struct wmfw_header *header; + const struct wmfw_adsp1_sizes *adsp1_sizes; + const struct wmfw_footer *footer; + const struct wmfw_region *region; + const struct cs_dsp_region *mem; + const char *region_name; + char *text = NULL; + struct cs_dsp_buf *buf; + unsigned int reg; + int regions = 0; + int ret, offset, type; + + ret = -EINVAL; + + pos = sizeof(*header) + sizeof(*adsp1_sizes) + sizeof(*footer); + if (pos >= firmware->size) { + cs_dsp_err(dsp, "%s: file too short, %zu bytes\n", + file, firmware->size); + goto out_fw; + } + + header = (void *)&firmware->data[0]; + + if (memcmp(&header->magic[0], "WMFW", 4) != 0) { + cs_dsp_err(dsp, "%s: invalid magic\n", file); + goto out_fw; + } + + if (!dsp->ops->validate_version(dsp, header->ver)) { + cs_dsp_err(dsp, "%s: unknown file format %d\n", + file, header->ver); + goto out_fw; + } + + cs_dsp_info(dsp, "Firmware version: %d\n", header->ver); + dsp->fw_ver = header->ver; + + if (header->core != dsp->type) { + cs_dsp_err(dsp, "%s: invalid core %d != %d\n", + file, header->core, dsp->type); + goto out_fw; + } + + pos = sizeof(*header); + pos = dsp->ops->parse_sizes(dsp, file, pos, firmware); + + footer = (void *)&firmware->data[pos]; + pos += sizeof(*footer); + + if (le32_to_cpu(header->len) != pos) { + cs_dsp_err(dsp, "%s: unexpected header length %d\n", + file, le32_to_cpu(header->len)); + goto out_fw; + } + + cs_dsp_dbg(dsp, "%s: timestamp %llu\n", file, + le64_to_cpu(footer->timestamp)); + + while (pos < firmware->size && + sizeof(*region) < firmware->size - pos) { + region = (void *)&(firmware->data[pos]); + region_name = "Unknown"; + reg = 0; + text = NULL; + offset = le32_to_cpu(region->offset) & 0xffffff; + type = be32_to_cpu(region->type) & 0xff; + + switch (type) { + case WMFW_NAME_TEXT: + region_name = "Firmware name"; + text = kzalloc(le32_to_cpu(region->len) + 1, + GFP_KERNEL); + break; + case WMFW_ALGORITHM_DATA: + region_name = "Algorithm"; + ret = cs_dsp_parse_coeff(dsp, region); + if (ret != 0) + goto out_fw; + break; + case WMFW_INFO_TEXT: + region_name = "Information"; + text = kzalloc(le32_to_cpu(region->len) + 1, + GFP_KERNEL); + break; + case WMFW_ABSOLUTE: + region_name = "Absolute"; + reg = offset; + break; + case WMFW_ADSP1_PM: + case WMFW_ADSP1_DM: + case WMFW_ADSP2_XM: + case WMFW_ADSP2_YM: + case WMFW_ADSP1_ZM: + case WMFW_HALO_PM_PACKED: + case WMFW_HALO_XM_PACKED: + case WMFW_HALO_YM_PACKED: + mem = cs_dsp_find_region(dsp, type); + if (!mem) { + cs_dsp_err(dsp, "No region of type: %x\n", type); + ret = -EINVAL; + goto out_fw; + } + + region_name = cs_dsp_mem_region_name(type); + reg = dsp->ops->region_to_reg(mem, offset); + break; + default: + cs_dsp_warn(dsp, + "%s.%d: Unknown region type %x at %d(%x)\n", + file, regions, type, pos, pos); + break; + } + + cs_dsp_dbg(dsp, "%s.%d: %d bytes at %d in %s\n", file, + regions, le32_to_cpu(region->len), offset, + region_name); + + if (le32_to_cpu(region->len) > + firmware->size - pos - sizeof(*region)) { + cs_dsp_err(dsp, + "%s.%d: %s region len %d bytes exceeds file length %zu\n", + file, regions, region_name, + le32_to_cpu(region->len), firmware->size); + ret = -EINVAL; + goto out_fw; + } + + if (text) { + memcpy(text, region->data, le32_to_cpu(region->len)); + cs_dsp_info(dsp, "%s: %s\n", file, text); + kfree(text); + text = NULL; + } + + if (reg) { + buf = cs_dsp_buf_alloc(region->data, + le32_to_cpu(region->len), + &buf_list); + if (!buf) { + cs_dsp_err(dsp, "Out of memory\n"); + ret = -ENOMEM; + goto out_fw; + } + + ret = regmap_raw_write_async(regmap, reg, buf->buf, + le32_to_cpu(region->len)); + if (ret != 0) { + cs_dsp_err(dsp, + "%s.%d: Failed to write %d bytes at %d in %s: %d\n", + file, regions, + le32_to_cpu(region->len), offset, + region_name, ret); + goto out_fw; + } + } + + pos += le32_to_cpu(region->len) + sizeof(*region); + regions++; + } + + ret = regmap_async_complete(regmap); + if (ret != 0) { + cs_dsp_err(dsp, "Failed to complete async write: %d\n", ret); + goto out_fw; + } + + if (pos > firmware->size) + cs_dsp_warn(dsp, "%s.%d: %zu bytes at end of file\n", + file, regions, pos - firmware->size); + + cs_dsp_debugfs_save_wmfwname(dsp, file); + +out_fw: + regmap_async_complete(regmap); + cs_dsp_buf_free(&buf_list); + kfree(text); + + return ret; +} + +/** + * cs_dsp_get_ctl() - Finds a matching coefficient control + * @dsp: pointer to DSP structure + * @name: pointer to string to match with a control's subname + * @type: the algorithm type to match + * @alg: the algorithm id to match + * + * Find cs_dsp_coeff_ctl with input name as its subname + * + * Return: pointer to the control on success, NULL if not found + */ +struct cs_dsp_coeff_ctl *cs_dsp_get_ctl(struct cs_dsp *dsp, const char *name, int type, + unsigned int alg) +{ + struct cs_dsp_coeff_ctl *pos, *rslt = NULL; + + list_for_each_entry(pos, &dsp->ctl_list, list) { + if (!pos->subname) + continue; + if (strncmp(pos->subname, name, pos->subname_len) == 0 && + pos->fw_name == dsp->fw_name && + pos->alg_region.alg == alg && + pos->alg_region.type == type) { + rslt = pos; + break; + } + } + + return rslt; +} +EXPORT_SYMBOL_GPL(cs_dsp_get_ctl); + +static void cs_dsp_ctl_fixup_base(struct cs_dsp *dsp, + const struct cs_dsp_alg_region *alg_region) +{ + struct cs_dsp_coeff_ctl *ctl; + + list_for_each_entry(ctl, &dsp->ctl_list, list) { + if (ctl->fw_name == dsp->fw_name && + alg_region->alg == ctl->alg_region.alg && + alg_region->type == ctl->alg_region.type) { + ctl->alg_region.base = alg_region->base; + } + } +} + +static void *cs_dsp_read_algs(struct cs_dsp *dsp, size_t n_algs, + const struct cs_dsp_region *mem, + unsigned int pos, unsigned int len) +{ + void *alg; + unsigned int reg; + int ret; + __be32 val; + + if (n_algs == 0) { + cs_dsp_err(dsp, "No algorithms\n"); + return ERR_PTR(-EINVAL); + } + + if (n_algs > 1024) { + cs_dsp_err(dsp, "Algorithm count %zx excessive\n", n_algs); + return ERR_PTR(-EINVAL); + } + + /* Read the terminator first to validate the length */ + reg = dsp->ops->region_to_reg(mem, pos + len); + + ret = regmap_raw_read(dsp->regmap, reg, &val, sizeof(val)); + if (ret != 0) { + cs_dsp_err(dsp, "Failed to read algorithm list end: %d\n", + ret); + return ERR_PTR(ret); + } + + if (be32_to_cpu(val) != 0xbedead) + cs_dsp_warn(dsp, "Algorithm list end %x 0x%x != 0xbedead\n", + reg, be32_to_cpu(val)); + + /* Convert length from DSP words to bytes */ + len *= sizeof(u32); + + alg = kzalloc(len, GFP_KERNEL | GFP_DMA); + if (!alg) + return ERR_PTR(-ENOMEM); + + reg = dsp->ops->region_to_reg(mem, pos); + + ret = regmap_raw_read(dsp->regmap, reg, alg, len); + if (ret != 0) { + cs_dsp_err(dsp, "Failed to read algorithm list: %d\n", ret); + kfree(alg); + return ERR_PTR(ret); + } + + return alg; +} + +/** + * cs_dsp_find_alg_region() - Finds a matching algorithm region + * @dsp: pointer to DSP structure + * @type: the algorithm type to match + * @id: the algorithm id to match + * + * Return: Pointer to matching algorithm region, or NULL if not found. + */ +struct cs_dsp_alg_region *cs_dsp_find_alg_region(struct cs_dsp *dsp, + int type, unsigned int id) +{ + struct cs_dsp_alg_region *alg_region; + + list_for_each_entry(alg_region, &dsp->alg_regions, list) { + if (id == alg_region->alg && type == alg_region->type) + return alg_region; + } + + return NULL; +} +EXPORT_SYMBOL_GPL(cs_dsp_find_alg_region); + +static struct cs_dsp_alg_region *cs_dsp_create_region(struct cs_dsp *dsp, + int type, __be32 id, + __be32 base) +{ + struct cs_dsp_alg_region *alg_region; + + alg_region = kzalloc(sizeof(*alg_region), GFP_KERNEL); + if (!alg_region) + return ERR_PTR(-ENOMEM); + + alg_region->type = type; + alg_region->alg = be32_to_cpu(id); + alg_region->base = be32_to_cpu(base); + + list_add_tail(&alg_region->list, &dsp->alg_regions); + + if (dsp->fw_ver > 0) + cs_dsp_ctl_fixup_base(dsp, alg_region); + + return alg_region; +} + +static void cs_dsp_free_alg_regions(struct cs_dsp *dsp) +{ + struct cs_dsp_alg_region *alg_region; + + while (!list_empty(&dsp->alg_regions)) { + alg_region = list_first_entry(&dsp->alg_regions, + struct cs_dsp_alg_region, + list); + list_del(&alg_region->list); + kfree(alg_region); + } +} + +static void cs_dsp_parse_wmfw_id_header(struct cs_dsp *dsp, + struct wmfw_id_hdr *fw, int nalgs) +{ + dsp->fw_id = be32_to_cpu(fw->id); + dsp->fw_id_version = be32_to_cpu(fw->ver); + + cs_dsp_info(dsp, "Firmware: %x v%d.%d.%d, %d algorithms\n", + dsp->fw_id, (dsp->fw_id_version & 0xff0000) >> 16, + (dsp->fw_id_version & 0xff00) >> 8, dsp->fw_id_version & 0xff, + nalgs); +} + +static void cs_dsp_parse_wmfw_v3_id_header(struct cs_dsp *dsp, + struct wmfw_v3_id_hdr *fw, int nalgs) +{ + dsp->fw_id = be32_to_cpu(fw->id); + dsp->fw_id_version = be32_to_cpu(fw->ver); + dsp->fw_vendor_id = be32_to_cpu(fw->vendor_id); + + cs_dsp_info(dsp, "Firmware: %x vendor: 0x%x v%d.%d.%d, %d algorithms\n", + dsp->fw_id, dsp->fw_vendor_id, + (dsp->fw_id_version & 0xff0000) >> 16, + (dsp->fw_id_version & 0xff00) >> 8, dsp->fw_id_version & 0xff, + nalgs); +} + +static int cs_dsp_create_regions(struct cs_dsp *dsp, __be32 id, int nregions, + const int *type, __be32 *base) +{ + struct cs_dsp_alg_region *alg_region; + int i; + + for (i = 0; i < nregions; i++) { + alg_region = cs_dsp_create_region(dsp, type[i], id, base[i]); + if (IS_ERR(alg_region)) + return PTR_ERR(alg_region); + } + + return 0; +} + +static int cs_dsp_adsp1_setup_algs(struct cs_dsp *dsp) +{ + struct wmfw_adsp1_id_hdr adsp1_id; + struct wmfw_adsp1_alg_hdr *adsp1_alg; + struct cs_dsp_alg_region *alg_region; + const struct cs_dsp_region *mem; + unsigned int pos, len; + size_t n_algs; + int i, ret; + + mem = cs_dsp_find_region(dsp, WMFW_ADSP1_DM); + if (WARN_ON(!mem)) + return -EINVAL; + + ret = regmap_raw_read(dsp->regmap, mem->base, &adsp1_id, + sizeof(adsp1_id)); + if (ret != 0) { + cs_dsp_err(dsp, "Failed to read algorithm info: %d\n", + ret); + return ret; + } + + n_algs = be32_to_cpu(adsp1_id.n_algs); + + cs_dsp_parse_wmfw_id_header(dsp, &adsp1_id.fw, n_algs); + + alg_region = cs_dsp_create_region(dsp, WMFW_ADSP1_ZM, + adsp1_id.fw.id, adsp1_id.zm); + if (IS_ERR(alg_region)) + return PTR_ERR(alg_region); + + alg_region = cs_dsp_create_region(dsp, WMFW_ADSP1_DM, + adsp1_id.fw.id, adsp1_id.dm); + if (IS_ERR(alg_region)) + return PTR_ERR(alg_region); + + /* Calculate offset and length in DSP words */ + pos = sizeof(adsp1_id) / sizeof(u32); + len = (sizeof(*adsp1_alg) * n_algs) / sizeof(u32); + + adsp1_alg = cs_dsp_read_algs(dsp, n_algs, mem, pos, len); + if (IS_ERR(adsp1_alg)) + return PTR_ERR(adsp1_alg); + + for (i = 0; i < n_algs; i++) { + cs_dsp_info(dsp, "%d: ID %x v%d.%d.%d DM@%x ZM@%x\n", + i, be32_to_cpu(adsp1_alg[i].alg.id), + (be32_to_cpu(adsp1_alg[i].alg.ver) & 0xff0000) >> 16, + (be32_to_cpu(adsp1_alg[i].alg.ver) & 0xff00) >> 8, + be32_to_cpu(adsp1_alg[i].alg.ver) & 0xff, + be32_to_cpu(adsp1_alg[i].dm), + be32_to_cpu(adsp1_alg[i].zm)); + + alg_region = cs_dsp_create_region(dsp, WMFW_ADSP1_DM, + adsp1_alg[i].alg.id, + adsp1_alg[i].dm); + if (IS_ERR(alg_region)) { + ret = PTR_ERR(alg_region); + goto out; + } + if (dsp->fw_ver == 0) { + if (i + 1 < n_algs) { + len = be32_to_cpu(adsp1_alg[i + 1].dm); + len -= be32_to_cpu(adsp1_alg[i].dm); + len *= 4; + cs_dsp_create_control(dsp, alg_region, 0, + len, NULL, 0, 0, + WMFW_CTL_TYPE_BYTES); + } else { + cs_dsp_warn(dsp, "Missing length info for region DM with ID %x\n", + be32_to_cpu(adsp1_alg[i].alg.id)); + } + } + + alg_region = cs_dsp_create_region(dsp, WMFW_ADSP1_ZM, + adsp1_alg[i].alg.id, + adsp1_alg[i].zm); + if (IS_ERR(alg_region)) { + ret = PTR_ERR(alg_region); + goto out; + } + if (dsp->fw_ver == 0) { + if (i + 1 < n_algs) { + len = be32_to_cpu(adsp1_alg[i + 1].zm); + len -= be32_to_cpu(adsp1_alg[i].zm); + len *= 4; + cs_dsp_create_control(dsp, alg_region, 0, + len, NULL, 0, 0, + WMFW_CTL_TYPE_BYTES); + } else { + cs_dsp_warn(dsp, "Missing length info for region ZM with ID %x\n", + be32_to_cpu(adsp1_alg[i].alg.id)); + } + } + } + +out: + kfree(adsp1_alg); + return ret; +} + +static int cs_dsp_adsp2_setup_algs(struct cs_dsp *dsp) +{ + struct wmfw_adsp2_id_hdr adsp2_id; + struct wmfw_adsp2_alg_hdr *adsp2_alg; + struct cs_dsp_alg_region *alg_region; + const struct cs_dsp_region *mem; + unsigned int pos, len; + size_t n_algs; + int i, ret; + + mem = cs_dsp_find_region(dsp, WMFW_ADSP2_XM); + if (WARN_ON(!mem)) + return -EINVAL; + + ret = regmap_raw_read(dsp->regmap, mem->base, &adsp2_id, + sizeof(adsp2_id)); + if (ret != 0) { + cs_dsp_err(dsp, "Failed to read algorithm info: %d\n", + ret); + return ret; + } + + n_algs = be32_to_cpu(adsp2_id.n_algs); + + cs_dsp_parse_wmfw_id_header(dsp, &adsp2_id.fw, n_algs); + + alg_region = cs_dsp_create_region(dsp, WMFW_ADSP2_XM, + adsp2_id.fw.id, adsp2_id.xm); + if (IS_ERR(alg_region)) + return PTR_ERR(alg_region); + + alg_region = cs_dsp_create_region(dsp, WMFW_ADSP2_YM, + adsp2_id.fw.id, adsp2_id.ym); + if (IS_ERR(alg_region)) + return PTR_ERR(alg_region); + + alg_region = cs_dsp_create_region(dsp, WMFW_ADSP2_ZM, + adsp2_id.fw.id, adsp2_id.zm); + if (IS_ERR(alg_region)) + return PTR_ERR(alg_region); + + /* Calculate offset and length in DSP words */ + pos = sizeof(adsp2_id) / sizeof(u32); + len = (sizeof(*adsp2_alg) * n_algs) / sizeof(u32); + + adsp2_alg = cs_dsp_read_algs(dsp, n_algs, mem, pos, len); + if (IS_ERR(adsp2_alg)) + return PTR_ERR(adsp2_alg); + + for (i = 0; i < n_algs; i++) { + cs_dsp_info(dsp, + "%d: ID %x v%d.%d.%d XM@%x YM@%x ZM@%x\n", + i, be32_to_cpu(adsp2_alg[i].alg.id), + (be32_to_cpu(adsp2_alg[i].alg.ver) & 0xff0000) >> 16, + (be32_to_cpu(adsp2_alg[i].alg.ver) & 0xff00) >> 8, + be32_to_cpu(adsp2_alg[i].alg.ver) & 0xff, + be32_to_cpu(adsp2_alg[i].xm), + be32_to_cpu(adsp2_alg[i].ym), + be32_to_cpu(adsp2_alg[i].zm)); + + alg_region = cs_dsp_create_region(dsp, WMFW_ADSP2_XM, + adsp2_alg[i].alg.id, + adsp2_alg[i].xm); + if (IS_ERR(alg_region)) { + ret = PTR_ERR(alg_region); + goto out; + } + if (dsp->fw_ver == 0) { + if (i + 1 < n_algs) { + len = be32_to_cpu(adsp2_alg[i + 1].xm); + len -= be32_to_cpu(adsp2_alg[i].xm); + len *= 4; + cs_dsp_create_control(dsp, alg_region, 0, + len, NULL, 0, 0, + WMFW_CTL_TYPE_BYTES); + } else { + cs_dsp_warn(dsp, "Missing length info for region XM with ID %x\n", + be32_to_cpu(adsp2_alg[i].alg.id)); + } + } + + alg_region = cs_dsp_create_region(dsp, WMFW_ADSP2_YM, + adsp2_alg[i].alg.id, + adsp2_alg[i].ym); + if (IS_ERR(alg_region)) { + ret = PTR_ERR(alg_region); + goto out; + } + if (dsp->fw_ver == 0) { + if (i + 1 < n_algs) { + len = be32_to_cpu(adsp2_alg[i + 1].ym); + len -= be32_to_cpu(adsp2_alg[i].ym); + len *= 4; + cs_dsp_create_control(dsp, alg_region, 0, + len, NULL, 0, 0, + WMFW_CTL_TYPE_BYTES); + } else { + cs_dsp_warn(dsp, "Missing length info for region YM with ID %x\n", + be32_to_cpu(adsp2_alg[i].alg.id)); + } + } + + alg_region = cs_dsp_create_region(dsp, WMFW_ADSP2_ZM, + adsp2_alg[i].alg.id, + adsp2_alg[i].zm); + if (IS_ERR(alg_region)) { + ret = PTR_ERR(alg_region); + goto out; + } + if (dsp->fw_ver == 0) { + if (i + 1 < n_algs) { + len = be32_to_cpu(adsp2_alg[i + 1].zm); + len -= be32_to_cpu(adsp2_alg[i].zm); + len *= 4; + cs_dsp_create_control(dsp, alg_region, 0, + len, NULL, 0, 0, + WMFW_CTL_TYPE_BYTES); + } else { + cs_dsp_warn(dsp, "Missing length info for region ZM with ID %x\n", + be32_to_cpu(adsp2_alg[i].alg.id)); + } + } + } + +out: + kfree(adsp2_alg); + return ret; +} + +static int cs_dsp_halo_create_regions(struct cs_dsp *dsp, __be32 id, + __be32 xm_base, __be32 ym_base) +{ + static const int types[] = { + WMFW_ADSP2_XM, WMFW_HALO_XM_PACKED, + WMFW_ADSP2_YM, WMFW_HALO_YM_PACKED + }; + __be32 bases[] = { xm_base, xm_base, ym_base, ym_base }; + + return cs_dsp_create_regions(dsp, id, ARRAY_SIZE(types), types, bases); +} + +static int cs_dsp_halo_setup_algs(struct cs_dsp *dsp) +{ + struct wmfw_halo_id_hdr halo_id; + struct wmfw_halo_alg_hdr *halo_alg; + const struct cs_dsp_region *mem; + unsigned int pos, len; + size_t n_algs; + int i, ret; + + mem = cs_dsp_find_region(dsp, WMFW_ADSP2_XM); + if (WARN_ON(!mem)) + return -EINVAL; + + ret = regmap_raw_read(dsp->regmap, mem->base, &halo_id, + sizeof(halo_id)); + if (ret != 0) { + cs_dsp_err(dsp, "Failed to read algorithm info: %d\n", + ret); + return ret; + } + + n_algs = be32_to_cpu(halo_id.n_algs); + + cs_dsp_parse_wmfw_v3_id_header(dsp, &halo_id.fw, n_algs); + + ret = cs_dsp_halo_create_regions(dsp, halo_id.fw.id, + halo_id.xm_base, halo_id.ym_base); + if (ret) + return ret; + + /* Calculate offset and length in DSP words */ + pos = sizeof(halo_id) / sizeof(u32); + len = (sizeof(*halo_alg) * n_algs) / sizeof(u32); + + halo_alg = cs_dsp_read_algs(dsp, n_algs, mem, pos, len); + if (IS_ERR(halo_alg)) + return PTR_ERR(halo_alg); + + for (i = 0; i < n_algs; i++) { + cs_dsp_info(dsp, + "%d: ID %x v%d.%d.%d XM@%x YM@%x\n", + i, be32_to_cpu(halo_alg[i].alg.id), + (be32_to_cpu(halo_alg[i].alg.ver) & 0xff0000) >> 16, + (be32_to_cpu(halo_alg[i].alg.ver) & 0xff00) >> 8, + be32_to_cpu(halo_alg[i].alg.ver) & 0xff, + be32_to_cpu(halo_alg[i].xm_base), + be32_to_cpu(halo_alg[i].ym_base)); + + ret = cs_dsp_halo_create_regions(dsp, halo_alg[i].alg.id, + halo_alg[i].xm_base, + halo_alg[i].ym_base); + if (ret) + goto out; + } + +out: + kfree(halo_alg); + return ret; +} + +static int cs_dsp_load_coeff(struct cs_dsp *dsp, const struct firmware *firmware, + const char *file) +{ + LIST_HEAD(buf_list); + struct regmap *regmap = dsp->regmap; + struct wmfw_coeff_hdr *hdr; + struct wmfw_coeff_item *blk; + const struct cs_dsp_region *mem; + struct cs_dsp_alg_region *alg_region; + const char *region_name; + int ret, pos, blocks, type, offset, reg; + struct cs_dsp_buf *buf; + + if (!firmware) + return 0; + + ret = -EINVAL; + + if (sizeof(*hdr) >= firmware->size) { + cs_dsp_err(dsp, "%s: coefficient file too short, %zu bytes\n", + file, firmware->size); + goto out_fw; + } + + hdr = (void *)&firmware->data[0]; + if (memcmp(hdr->magic, "WMDR", 4) != 0) { + cs_dsp_err(dsp, "%s: invalid coefficient magic\n", file); + goto out_fw; + } + + switch (be32_to_cpu(hdr->rev) & 0xff) { + case 1: + break; + default: + cs_dsp_err(dsp, "%s: Unsupported coefficient file format %d\n", + file, be32_to_cpu(hdr->rev) & 0xff); + ret = -EINVAL; + goto out_fw; + } + + cs_dsp_dbg(dsp, "%s: v%d.%d.%d\n", file, + (le32_to_cpu(hdr->ver) >> 16) & 0xff, + (le32_to_cpu(hdr->ver) >> 8) & 0xff, + le32_to_cpu(hdr->ver) & 0xff); + + pos = le32_to_cpu(hdr->len); + + blocks = 0; + while (pos < firmware->size && + sizeof(*blk) < firmware->size - pos) { + blk = (void *)(&firmware->data[pos]); + + type = le16_to_cpu(blk->type); + offset = le16_to_cpu(blk->offset); + + cs_dsp_dbg(dsp, "%s.%d: %x v%d.%d.%d\n", + file, blocks, le32_to_cpu(blk->id), + (le32_to_cpu(blk->ver) >> 16) & 0xff, + (le32_to_cpu(blk->ver) >> 8) & 0xff, + le32_to_cpu(blk->ver) & 0xff); + cs_dsp_dbg(dsp, "%s.%d: %d bytes at 0x%x in %x\n", + file, blocks, le32_to_cpu(blk->len), offset, type); + + reg = 0; + region_name = "Unknown"; + switch (type) { + case (WMFW_NAME_TEXT << 8): + case (WMFW_INFO_TEXT << 8): + case (WMFW_METADATA << 8): + break; + case (WMFW_ABSOLUTE << 8): + /* + * Old files may use this for global + * coefficients. + */ + if (le32_to_cpu(blk->id) == dsp->fw_id && + offset == 0) { + region_name = "global coefficients"; + mem = cs_dsp_find_region(dsp, type); + if (!mem) { + cs_dsp_err(dsp, "No ZM\n"); + break; + } + reg = dsp->ops->region_to_reg(mem, 0); + + } else { + region_name = "register"; + reg = offset; + } + break; + + case WMFW_ADSP1_DM: + case WMFW_ADSP1_ZM: + case WMFW_ADSP2_XM: + case WMFW_ADSP2_YM: + case WMFW_HALO_XM_PACKED: + case WMFW_HALO_YM_PACKED: + case WMFW_HALO_PM_PACKED: + cs_dsp_dbg(dsp, "%s.%d: %d bytes in %x for %x\n", + file, blocks, le32_to_cpu(blk->len), + type, le32_to_cpu(blk->id)); + + mem = cs_dsp_find_region(dsp, type); + if (!mem) { + cs_dsp_err(dsp, "No base for region %x\n", type); + break; + } + + alg_region = cs_dsp_find_alg_region(dsp, type, + le32_to_cpu(blk->id)); + if (alg_region) { + reg = alg_region->base; + reg = dsp->ops->region_to_reg(mem, reg); + reg += offset; + } else { + cs_dsp_err(dsp, "No %x for algorithm %x\n", + type, le32_to_cpu(blk->id)); + } + break; + + default: + cs_dsp_err(dsp, "%s.%d: Unknown region type %x at %d\n", + file, blocks, type, pos); + break; + } + + if (reg) { + if (le32_to_cpu(blk->len) > + firmware->size - pos - sizeof(*blk)) { + cs_dsp_err(dsp, + "%s.%d: %s region len %d bytes exceeds file length %zu\n", + file, blocks, region_name, + le32_to_cpu(blk->len), + firmware->size); + ret = -EINVAL; + goto out_fw; + } + + buf = cs_dsp_buf_alloc(blk->data, + le32_to_cpu(blk->len), + &buf_list); + if (!buf) { + cs_dsp_err(dsp, "Out of memory\n"); + ret = -ENOMEM; + goto out_fw; + } + + cs_dsp_dbg(dsp, "%s.%d: Writing %d bytes at %x\n", + file, blocks, le32_to_cpu(blk->len), + reg); + ret = regmap_raw_write_async(regmap, reg, buf->buf, + le32_to_cpu(blk->len)); + if (ret != 0) { + cs_dsp_err(dsp, + "%s.%d: Failed to write to %x in %s: %d\n", + file, blocks, reg, region_name, ret); + } + } + + pos += (le32_to_cpu(blk->len) + sizeof(*blk) + 3) & ~0x03; + blocks++; + } + + ret = regmap_async_complete(regmap); + if (ret != 0) + cs_dsp_err(dsp, "Failed to complete async write: %d\n", ret); + + if (pos > firmware->size) + cs_dsp_warn(dsp, "%s.%d: %zu bytes at end of file\n", + file, blocks, pos - firmware->size); + + cs_dsp_debugfs_save_binname(dsp, file); + +out_fw: + regmap_async_complete(regmap); + cs_dsp_buf_free(&buf_list); + return ret; +} + +static int cs_dsp_create_name(struct cs_dsp *dsp) +{ + if (!dsp->name) { + dsp->name = devm_kasprintf(dsp->dev, GFP_KERNEL, "DSP%d", + dsp->num); + if (!dsp->name) + return -ENOMEM; + } + + return 0; +} + +static int cs_dsp_common_init(struct cs_dsp *dsp) +{ + int ret; + + ret = cs_dsp_create_name(dsp); + if (ret) + return ret; + + INIT_LIST_HEAD(&dsp->alg_regions); + INIT_LIST_HEAD(&dsp->ctl_list); + + mutex_init(&dsp->pwr_lock); + + return 0; +} + +/** + * cs_dsp_adsp1_init() - Initialise a cs_dsp structure representing a ADSP1 device + * @dsp: pointer to DSP structure + * + * Return: Zero for success, a negative number on error. + */ +int cs_dsp_adsp1_init(struct cs_dsp *dsp) +{ + dsp->ops = &cs_dsp_adsp1_ops; + + return cs_dsp_common_init(dsp); +} +EXPORT_SYMBOL_GPL(cs_dsp_adsp1_init); + +/** + * cs_dsp_adsp1_power_up() - Load and start the named firmware + * @dsp: pointer to DSP structure + * @wmfw_firmware: the firmware to be sent + * @wmfw_filename: file name of firmware to be sent + * @coeff_firmware: the coefficient data to be sent + * @coeff_filename: file name of coefficient to data be sent + * @fw_name: the user-friendly firmware name + * + * Return: Zero for success, a negative number on error. + */ +int cs_dsp_adsp1_power_up(struct cs_dsp *dsp, + const struct firmware *wmfw_firmware, char *wmfw_filename, + const struct firmware *coeff_firmware, char *coeff_filename, + const char *fw_name) +{ + unsigned int val; + int ret; + + mutex_lock(&dsp->pwr_lock); + + dsp->fw_name = fw_name; + + regmap_update_bits(dsp->regmap, dsp->base + ADSP1_CONTROL_30, + ADSP1_SYS_ENA, ADSP1_SYS_ENA); + + /* + * For simplicity set the DSP clock rate to be the + * SYSCLK rate rather than making it configurable. + */ + if (dsp->sysclk_reg) { + ret = regmap_read(dsp->regmap, dsp->sysclk_reg, &val); + if (ret != 0) { + cs_dsp_err(dsp, "Failed to read SYSCLK state: %d\n", ret); + goto err_mutex; + } + + val = (val & dsp->sysclk_mask) >> dsp->sysclk_shift; + + ret = regmap_update_bits(dsp->regmap, + dsp->base + ADSP1_CONTROL_31, + ADSP1_CLK_SEL_MASK, val); + if (ret != 0) { + cs_dsp_err(dsp, "Failed to set clock rate: %d\n", ret); + goto err_mutex; + } + } + + ret = cs_dsp_load(dsp, wmfw_firmware, wmfw_filename); + if (ret != 0) + goto err_ena; + + ret = cs_dsp_adsp1_setup_algs(dsp); + if (ret != 0) + goto err_ena; + + ret = cs_dsp_load_coeff(dsp, coeff_firmware, coeff_filename); + if (ret != 0) + goto err_ena; + + /* Initialize caches for enabled and unset controls */ + ret = cs_dsp_coeff_init_control_caches(dsp); + if (ret != 0) + goto err_ena; + + /* Sync set controls */ + ret = cs_dsp_coeff_sync_controls(dsp); + if (ret != 0) + goto err_ena; + + dsp->booted = true; + + /* Start the core running */ + regmap_update_bits(dsp->regmap, dsp->base + ADSP1_CONTROL_30, + ADSP1_CORE_ENA | ADSP1_START, + ADSP1_CORE_ENA | ADSP1_START); + + dsp->running = true; + + mutex_unlock(&dsp->pwr_lock); + + return 0; + +err_ena: + regmap_update_bits(dsp->regmap, dsp->base + ADSP1_CONTROL_30, + ADSP1_SYS_ENA, 0); +err_mutex: + mutex_unlock(&dsp->pwr_lock); + return ret; +} +EXPORT_SYMBOL_GPL(cs_dsp_adsp1_power_up); + +/** + * cs_dsp_adsp1_power_down() - Halts the DSP + * @dsp: pointer to DSP structure + */ +void cs_dsp_adsp1_power_down(struct cs_dsp *dsp) +{ + struct cs_dsp_coeff_ctl *ctl; + + mutex_lock(&dsp->pwr_lock); + + dsp->running = false; + dsp->booted = false; + + /* Halt the core */ + regmap_update_bits(dsp->regmap, dsp->base + ADSP1_CONTROL_30, + ADSP1_CORE_ENA | ADSP1_START, 0); + + regmap_update_bits(dsp->regmap, dsp->base + ADSP1_CONTROL_19, + ADSP1_WDMA_BUFFER_LENGTH_MASK, 0); + + regmap_update_bits(dsp->regmap, dsp->base + ADSP1_CONTROL_30, + ADSP1_SYS_ENA, 0); + + list_for_each_entry(ctl, &dsp->ctl_list, list) + ctl->enabled = 0; + + cs_dsp_free_alg_regions(dsp); + + mutex_unlock(&dsp->pwr_lock); +} +EXPORT_SYMBOL_GPL(cs_dsp_adsp1_power_down); + +static int cs_dsp_adsp2v2_enable_core(struct cs_dsp *dsp) +{ + unsigned int val; + int ret, count; + + /* Wait for the RAM to start, should be near instantaneous */ + for (count = 0; count < 10; ++count) { + ret = regmap_read(dsp->regmap, dsp->base + ADSP2_STATUS1, &val); + if (ret != 0) + return ret; + + if (val & ADSP2_RAM_RDY) + break; + + usleep_range(250, 500); + } + + if (!(val & ADSP2_RAM_RDY)) { + cs_dsp_err(dsp, "Failed to start DSP RAM\n"); + return -EBUSY; + } + + cs_dsp_dbg(dsp, "RAM ready after %d polls\n", count); + + return 0; +} + +static int cs_dsp_adsp2_enable_core(struct cs_dsp *dsp) +{ + int ret; + + ret = regmap_update_bits_async(dsp->regmap, dsp->base + ADSP2_CONTROL, + ADSP2_SYS_ENA, ADSP2_SYS_ENA); + if (ret != 0) + return ret; + + return cs_dsp_adsp2v2_enable_core(dsp); +} + +static int cs_dsp_adsp2_lock(struct cs_dsp *dsp, unsigned int lock_regions) +{ + struct regmap *regmap = dsp->regmap; + unsigned int code0, code1, lock_reg; + + if (!(lock_regions & CS_ADSP2_REGION_ALL)) + return 0; + + lock_regions &= CS_ADSP2_REGION_ALL; + lock_reg = dsp->base + ADSP2_LOCK_REGION_1_LOCK_REGION_0; + + while (lock_regions) { + code0 = code1 = 0; + if (lock_regions & BIT(0)) { + code0 = ADSP2_LOCK_CODE_0; + code1 = ADSP2_LOCK_CODE_1; + } + if (lock_regions & BIT(1)) { + code0 |= ADSP2_LOCK_CODE_0 << ADSP2_LOCK_REGION_SHIFT; + code1 |= ADSP2_LOCK_CODE_1 << ADSP2_LOCK_REGION_SHIFT; + } + regmap_write(regmap, lock_reg, code0); + regmap_write(regmap, lock_reg, code1); + lock_regions >>= 2; + lock_reg += 2; + } + + return 0; +} + +static int cs_dsp_adsp2_enable_memory(struct cs_dsp *dsp) +{ + return regmap_update_bits(dsp->regmap, dsp->base + ADSP2_CONTROL, + ADSP2_MEM_ENA, ADSP2_MEM_ENA); +} + +static void cs_dsp_adsp2_disable_memory(struct cs_dsp *dsp) +{ + regmap_update_bits(dsp->regmap, dsp->base + ADSP2_CONTROL, + ADSP2_MEM_ENA, 0); +} + +static void cs_dsp_adsp2_disable_core(struct cs_dsp *dsp) +{ + regmap_write(dsp->regmap, dsp->base + ADSP2_RDMA_CONFIG_1, 0); + regmap_write(dsp->regmap, dsp->base + ADSP2_WDMA_CONFIG_1, 0); + regmap_write(dsp->regmap, dsp->base + ADSP2_WDMA_CONFIG_2, 0); + + regmap_update_bits(dsp->regmap, dsp->base + ADSP2_CONTROL, + ADSP2_SYS_ENA, 0); +} + +static void cs_dsp_adsp2v2_disable_core(struct cs_dsp *dsp) +{ + regmap_write(dsp->regmap, dsp->base + ADSP2_RDMA_CONFIG_1, 0); + regmap_write(dsp->regmap, dsp->base + ADSP2_WDMA_CONFIG_1, 0); + regmap_write(dsp->regmap, dsp->base + ADSP2V2_WDMA_CONFIG_2, 0); +} + +static int cs_dsp_halo_configure_mpu(struct cs_dsp *dsp, unsigned int lock_regions) +{ + struct reg_sequence config[] = { + { dsp->base + HALO_MPU_LOCK_CONFIG, 0x5555 }, + { dsp->base + HALO_MPU_LOCK_CONFIG, 0xAAAA }, + { dsp->base + HALO_MPU_XMEM_ACCESS_0, 0xFFFFFFFF }, + { dsp->base + HALO_MPU_YMEM_ACCESS_0, 0xFFFFFFFF }, + { dsp->base + HALO_MPU_WINDOW_ACCESS_0, lock_regions }, + { dsp->base + HALO_MPU_XREG_ACCESS_0, lock_regions }, + { dsp->base + HALO_MPU_YREG_ACCESS_0, lock_regions }, + { dsp->base + HALO_MPU_XMEM_ACCESS_1, 0xFFFFFFFF }, + { dsp->base + HALO_MPU_YMEM_ACCESS_1, 0xFFFFFFFF }, + { dsp->base + HALO_MPU_WINDOW_ACCESS_1, lock_regions }, + { dsp->base + HALO_MPU_XREG_ACCESS_1, lock_regions }, + { dsp->base + HALO_MPU_YREG_ACCESS_1, lock_regions }, + { dsp->base + HALO_MPU_XMEM_ACCESS_2, 0xFFFFFFFF }, + { dsp->base + HALO_MPU_YMEM_ACCESS_2, 0xFFFFFFFF }, + { dsp->base + HALO_MPU_WINDOW_ACCESS_2, lock_regions }, + { dsp->base + HALO_MPU_XREG_ACCESS_2, lock_regions }, + { dsp->base + HALO_MPU_YREG_ACCESS_2, lock_regions }, + { dsp->base + HALO_MPU_XMEM_ACCESS_3, 0xFFFFFFFF }, + { dsp->base + HALO_MPU_YMEM_ACCESS_3, 0xFFFFFFFF }, + { dsp->base + HALO_MPU_WINDOW_ACCESS_3, lock_regions }, + { dsp->base + HALO_MPU_XREG_ACCESS_3, lock_regions }, + { dsp->base + HALO_MPU_YREG_ACCESS_3, lock_regions }, + { dsp->base + HALO_MPU_LOCK_CONFIG, 0 }, + }; + + return regmap_multi_reg_write(dsp->regmap, config, ARRAY_SIZE(config)); +} + +/** + * cs_dsp_set_dspclk() - Applies the given frequency to the given cs_dsp + * @dsp: pointer to DSP structure + * @freq: clock rate to set + * + * This is only for use on ADSP2 cores. + * + * Return: Zero for success, a negative number on error. + */ +int cs_dsp_set_dspclk(struct cs_dsp *dsp, unsigned int freq) +{ + int ret; + + ret = regmap_update_bits(dsp->regmap, dsp->base + ADSP2_CLOCKING, + ADSP2_CLK_SEL_MASK, + freq << ADSP2_CLK_SEL_SHIFT); + if (ret) + cs_dsp_err(dsp, "Failed to set clock rate: %d\n", ret); + + return ret; +} +EXPORT_SYMBOL_GPL(cs_dsp_set_dspclk); + +static void cs_dsp_stop_watchdog(struct cs_dsp *dsp) +{ + regmap_update_bits(dsp->regmap, dsp->base + ADSP2_WATCHDOG, + ADSP2_WDT_ENA_MASK, 0); +} + +static void cs_dsp_halo_stop_watchdog(struct cs_dsp *dsp) +{ + regmap_update_bits(dsp->regmap, dsp->base + HALO_WDT_CONTROL, + HALO_WDT_EN_MASK, 0); +} + +/** + * cs_dsp_power_up() - Downloads firmware to the DSP + * @dsp: pointer to DSP structure + * @wmfw_firmware: the firmware to be sent + * @wmfw_filename: file name of firmware to be sent + * @coeff_firmware: the coefficient data to be sent + * @coeff_filename: file name of coefficient to data be sent + * @fw_name: the user-friendly firmware name + * + * This function is used on ADSP2 and Halo DSP cores, it powers-up the DSP core + * and downloads the firmware but does not start the firmware running. The + * cs_dsp booted flag will be set once completed and if the core has a low-power + * memory retention mode it will be put into this state after the firmware is + * downloaded. + * + * Return: Zero for success, a negative number on error. + */ +int cs_dsp_power_up(struct cs_dsp *dsp, + const struct firmware *wmfw_firmware, char *wmfw_filename, + const struct firmware *coeff_firmware, char *coeff_filename, + const char *fw_name) +{ + int ret; + + mutex_lock(&dsp->pwr_lock); + + dsp->fw_name = fw_name; + + if (dsp->ops->enable_memory) { + ret = dsp->ops->enable_memory(dsp); + if (ret != 0) + goto err_mutex; + } + + if (dsp->ops->enable_core) { + ret = dsp->ops->enable_core(dsp); + if (ret != 0) + goto err_mem; + } + + ret = cs_dsp_load(dsp, wmfw_firmware, wmfw_filename); + if (ret != 0) + goto err_ena; + + ret = dsp->ops->setup_algs(dsp); + if (ret != 0) + goto err_ena; + + ret = cs_dsp_load_coeff(dsp, coeff_firmware, coeff_filename); + if (ret != 0) + goto err_ena; + + /* Initialize caches for enabled and unset controls */ + ret = cs_dsp_coeff_init_control_caches(dsp); + if (ret != 0) + goto err_ena; + + if (dsp->ops->disable_core) + dsp->ops->disable_core(dsp); + + dsp->booted = true; + + mutex_unlock(&dsp->pwr_lock); + + return 0; +err_ena: + if (dsp->ops->disable_core) + dsp->ops->disable_core(dsp); +err_mem: + if (dsp->ops->disable_memory) + dsp->ops->disable_memory(dsp); +err_mutex: + mutex_unlock(&dsp->pwr_lock); + + return ret; +} +EXPORT_SYMBOL_GPL(cs_dsp_power_up); + +/** + * cs_dsp_power_down() - Powers-down the DSP + * @dsp: pointer to DSP structure + * + * cs_dsp_stop() must have been called before this function. The core will be + * fully powered down and so the memory will not be retained. + */ +void cs_dsp_power_down(struct cs_dsp *dsp) +{ + struct cs_dsp_coeff_ctl *ctl; + + mutex_lock(&dsp->pwr_lock); + + cs_dsp_debugfs_clear(dsp); + + dsp->fw_id = 0; + dsp->fw_id_version = 0; + + dsp->booted = false; + + if (dsp->ops->disable_memory) + dsp->ops->disable_memory(dsp); + + list_for_each_entry(ctl, &dsp->ctl_list, list) + ctl->enabled = 0; + + cs_dsp_free_alg_regions(dsp); + + mutex_unlock(&dsp->pwr_lock); + + cs_dsp_dbg(dsp, "Shutdown complete\n"); +} +EXPORT_SYMBOL_GPL(cs_dsp_power_down); + +static int cs_dsp_adsp2_start_core(struct cs_dsp *dsp) +{ + return regmap_update_bits(dsp->regmap, dsp->base + ADSP2_CONTROL, + ADSP2_CORE_ENA | ADSP2_START, + ADSP2_CORE_ENA | ADSP2_START); +} + +static void cs_dsp_adsp2_stop_core(struct cs_dsp *dsp) +{ + regmap_update_bits(dsp->regmap, dsp->base + ADSP2_CONTROL, + ADSP2_CORE_ENA | ADSP2_START, 0); +} + +/** + * cs_dsp_run() - Starts the firmware running + * @dsp: pointer to DSP structure + * + * cs_dsp_power_up() must have previously been called successfully. + * + * Return: Zero for success, a negative number on error. + */ +int cs_dsp_run(struct cs_dsp *dsp) +{ + int ret; + + mutex_lock(&dsp->pwr_lock); + + if (!dsp->booted) { + ret = -EIO; + goto err; + } + + if (dsp->ops->enable_core) { + ret = dsp->ops->enable_core(dsp); + if (ret != 0) + goto err; + } + + /* Sync set controls */ + ret = cs_dsp_coeff_sync_controls(dsp); + if (ret != 0) + goto err; + + if (dsp->ops->lock_memory) { + ret = dsp->ops->lock_memory(dsp, dsp->lock_regions); + if (ret != 0) { + cs_dsp_err(dsp, "Error configuring MPU: %d\n", ret); + goto err; + } + } + + if (dsp->ops->start_core) { + ret = dsp->ops->start_core(dsp); + if (ret != 0) + goto err; + } + + dsp->running = true; + + if (dsp->client_ops->post_run) { + ret = dsp->client_ops->post_run(dsp); + if (ret) + goto err; + } + + mutex_unlock(&dsp->pwr_lock); + + return 0; + +err: + if (dsp->ops->stop_core) + dsp->ops->stop_core(dsp); + if (dsp->ops->disable_core) + dsp->ops->disable_core(dsp); + mutex_unlock(&dsp->pwr_lock); + + return ret; +} +EXPORT_SYMBOL_GPL(cs_dsp_run); + +/** + * cs_dsp_stop() - Stops the firmware + * @dsp: pointer to DSP structure + * + * Memory will not be disabled so firmware will remain loaded. + */ +void cs_dsp_stop(struct cs_dsp *dsp) +{ + /* Tell the firmware to cleanup */ + cs_dsp_signal_event_controls(dsp, CS_DSP_FW_EVENT_SHUTDOWN); + + if (dsp->ops->stop_watchdog) + dsp->ops->stop_watchdog(dsp); + + /* Log firmware state, it can be useful for analysis */ + if (dsp->ops->show_fw_status) + dsp->ops->show_fw_status(dsp); + + mutex_lock(&dsp->pwr_lock); + + dsp->running = false; + + if (dsp->ops->stop_core) + dsp->ops->stop_core(dsp); + if (dsp->ops->disable_core) + dsp->ops->disable_core(dsp); + + if (dsp->client_ops->post_stop) + dsp->client_ops->post_stop(dsp); + + mutex_unlock(&dsp->pwr_lock); + + cs_dsp_dbg(dsp, "Execution stopped\n"); +} +EXPORT_SYMBOL_GPL(cs_dsp_stop); + +static int cs_dsp_halo_start_core(struct cs_dsp *dsp) +{ + return regmap_update_bits(dsp->regmap, + dsp->base + HALO_CCM_CORE_CONTROL, + HALO_CORE_RESET | HALO_CORE_EN, + HALO_CORE_RESET | HALO_CORE_EN); +} + +static void cs_dsp_halo_stop_core(struct cs_dsp *dsp) +{ + regmap_update_bits(dsp->regmap, dsp->base + HALO_CCM_CORE_CONTROL, + HALO_CORE_EN, 0); + + /* reset halo core with CORE_SOFT_RESET */ + regmap_update_bits(dsp->regmap, dsp->base + HALO_CORE_SOFT_RESET, + HALO_CORE_SOFT_RESET_MASK, 1); +} + +/** + * cs_dsp_adsp2_init() - Initialise a cs_dsp structure representing a ADSP2 core + * @dsp: pointer to DSP structure + * + * Return: Zero for success, a negative number on error. + */ +int cs_dsp_adsp2_init(struct cs_dsp *dsp) +{ + int ret; + + switch (dsp->rev) { + case 0: + /* + * Disable the DSP memory by default when in reset for a small + * power saving. + */ + ret = regmap_update_bits(dsp->regmap, dsp->base + ADSP2_CONTROL, + ADSP2_MEM_ENA, 0); + if (ret) { + cs_dsp_err(dsp, + "Failed to clear memory retention: %d\n", ret); + return ret; + } + + dsp->ops = &cs_dsp_adsp2_ops[0]; + break; + case 1: + dsp->ops = &cs_dsp_adsp2_ops[1]; + break; + default: + dsp->ops = &cs_dsp_adsp2_ops[2]; + break; + } + + return cs_dsp_common_init(dsp); +} +EXPORT_SYMBOL_GPL(cs_dsp_adsp2_init); + +/** + * cs_dsp_halo_init() - Initialise a cs_dsp structure representing a HALO Core DSP + * @dsp: pointer to DSP structure + * + * Return: Zero for success, a negative number on error. + */ +int cs_dsp_halo_init(struct cs_dsp *dsp) +{ + dsp->ops = &cs_dsp_halo_ops; + + return cs_dsp_common_init(dsp); +} +EXPORT_SYMBOL_GPL(cs_dsp_halo_init); + +/** + * cs_dsp_remove() - Clean a cs_dsp before deletion + * @dsp: pointer to DSP structure + */ +void cs_dsp_remove(struct cs_dsp *dsp) +{ + struct cs_dsp_coeff_ctl *ctl; + + while (!list_empty(&dsp->ctl_list)) { + ctl = list_first_entry(&dsp->ctl_list, struct cs_dsp_coeff_ctl, list); + + if (dsp->client_ops->control_remove) + dsp->client_ops->control_remove(ctl); + + list_del(&ctl->list); + cs_dsp_free_ctl_blk(ctl); + } +} +EXPORT_SYMBOL_GPL(cs_dsp_remove); + +/** + * cs_dsp_read_raw_data_block() - Reads a block of data from DSP memory + * @dsp: pointer to DSP structure + * @mem_type: the type of DSP memory containing the data to be read + * @mem_addr: the address of the data within the memory region + * @num_words: the length of the data to read + * @data: a buffer to store the fetched data + * + * If this is used to read unpacked 24-bit memory, each 24-bit DSP word will + * occupy 32-bits in data (MSbyte will be 0). This padding can be removed using + * cs_dsp_remove_padding() + * + * Return: Zero for success, a negative number on error. + */ +int cs_dsp_read_raw_data_block(struct cs_dsp *dsp, int mem_type, unsigned int mem_addr, + unsigned int num_words, __be32 *data) +{ + struct cs_dsp_region const *mem = cs_dsp_find_region(dsp, mem_type); + unsigned int reg; + int ret; + + if (!mem) + return -EINVAL; + + reg = dsp->ops->region_to_reg(mem, mem_addr); + + ret = regmap_raw_read(dsp->regmap, reg, data, + sizeof(*data) * num_words); + if (ret < 0) + return ret; + + return 0; +} +EXPORT_SYMBOL_GPL(cs_dsp_read_raw_data_block); + +/** + * cs_dsp_read_data_word() - Reads a word from DSP memory + * @dsp: pointer to DSP structure + * @mem_type: the type of DSP memory containing the data to be read + * @mem_addr: the address of the data within the memory region + * @data: a buffer to store the fetched data + * + * Return: Zero for success, a negative number on error. + */ +int cs_dsp_read_data_word(struct cs_dsp *dsp, int mem_type, unsigned int mem_addr, u32 *data) +{ + __be32 raw; + int ret; + + ret = cs_dsp_read_raw_data_block(dsp, mem_type, mem_addr, 1, &raw); + if (ret < 0) + return ret; + + *data = be32_to_cpu(raw) & 0x00ffffffu; + + return 0; +} +EXPORT_SYMBOL_GPL(cs_dsp_read_data_word); + +/** + * cs_dsp_write_data_word() - Writes a word to DSP memory + * @dsp: pointer to DSP structure + * @mem_type: the type of DSP memory containing the data to be written + * @mem_addr: the address of the data within the memory region + * @data: the data to be written + * + * Return: Zero for success, a negative number on error. + */ +int cs_dsp_write_data_word(struct cs_dsp *dsp, int mem_type, unsigned int mem_addr, u32 data) +{ + struct cs_dsp_region const *mem = cs_dsp_find_region(dsp, mem_type); + __be32 val = cpu_to_be32(data & 0x00ffffffu); + unsigned int reg; + + if (!mem) + return -EINVAL; + + reg = dsp->ops->region_to_reg(mem, mem_addr); + + return regmap_raw_write(dsp->regmap, reg, &val, sizeof(val)); +} +EXPORT_SYMBOL_GPL(cs_dsp_write_data_word); + +/** + * cs_dsp_remove_padding() - Convert unpacked words to packed bytes + * @buf: buffer containing DSP words read from DSP memory + * @nwords: number of words to convert + * + * DSP words from the register map have pad bytes and the data bytes + * are in swapped order. This swaps to the native endian order and + * strips the pad bytes. + */ +void cs_dsp_remove_padding(u32 *buf, int nwords) +{ + const __be32 *pack_in = (__be32 *)buf; + u8 *pack_out = (u8 *)buf; + int i; + + for (i = 0; i < nwords; i++) { + u32 word = be32_to_cpu(*pack_in++); + *pack_out++ = (u8)word; + *pack_out++ = (u8)(word >> 8); + *pack_out++ = (u8)(word >> 16); + } +} +EXPORT_SYMBOL_GPL(cs_dsp_remove_padding); + +/** + * cs_dsp_adsp2_bus_error() - Handle a DSP bus error interrupt + * @dsp: pointer to DSP structure + * + * The firmware and DSP state will be logged for future analysis. + */ +void cs_dsp_adsp2_bus_error(struct cs_dsp *dsp) +{ + unsigned int val; + struct regmap *regmap = dsp->regmap; + int ret = 0; + + mutex_lock(&dsp->pwr_lock); + + ret = regmap_read(regmap, dsp->base + ADSP2_LOCK_REGION_CTRL, &val); + if (ret) { + cs_dsp_err(dsp, + "Failed to read Region Lock Ctrl register: %d\n", ret); + goto error; + } + + if (val & ADSP2_WDT_TIMEOUT_STS_MASK) { + cs_dsp_err(dsp, "watchdog timeout error\n"); + dsp->ops->stop_watchdog(dsp); + if (dsp->client_ops->watchdog_expired) + dsp->client_ops->watchdog_expired(dsp); + } + + if (val & (ADSP2_ADDR_ERR_MASK | ADSP2_REGION_LOCK_ERR_MASK)) { + if (val & ADSP2_ADDR_ERR_MASK) + cs_dsp_err(dsp, "bus error: address error\n"); + else + cs_dsp_err(dsp, "bus error: region lock error\n"); + + ret = regmap_read(regmap, dsp->base + ADSP2_BUS_ERR_ADDR, &val); + if (ret) { + cs_dsp_err(dsp, + "Failed to read Bus Err Addr register: %d\n", + ret); + goto error; + } + + cs_dsp_err(dsp, "bus error address = 0x%x\n", + val & ADSP2_BUS_ERR_ADDR_MASK); + + ret = regmap_read(regmap, + dsp->base + ADSP2_PMEM_ERR_ADDR_XMEM_ERR_ADDR, + &val); + if (ret) { + cs_dsp_err(dsp, + "Failed to read Pmem Xmem Err Addr register: %d\n", + ret); + goto error; + } + + cs_dsp_err(dsp, "xmem error address = 0x%x\n", + val & ADSP2_XMEM_ERR_ADDR_MASK); + cs_dsp_err(dsp, "pmem error address = 0x%x\n", + (val & ADSP2_PMEM_ERR_ADDR_MASK) >> + ADSP2_PMEM_ERR_ADDR_SHIFT); + } + + regmap_update_bits(regmap, dsp->base + ADSP2_LOCK_REGION_CTRL, + ADSP2_CTRL_ERR_EINT, ADSP2_CTRL_ERR_EINT); + +error: + mutex_unlock(&dsp->pwr_lock); +} +EXPORT_SYMBOL_GPL(cs_dsp_adsp2_bus_error); + +/** + * cs_dsp_halo_bus_error() - Handle a DSP bus error interrupt + * @dsp: pointer to DSP structure + * + * The firmware and DSP state will be logged for future analysis. + */ +void cs_dsp_halo_bus_error(struct cs_dsp *dsp) +{ + struct regmap *regmap = dsp->regmap; + unsigned int fault[6]; + struct reg_sequence clear[] = { + { dsp->base + HALO_MPU_XM_VIO_STATUS, 0x0 }, + { dsp->base + HALO_MPU_YM_VIO_STATUS, 0x0 }, + { dsp->base + HALO_MPU_PM_VIO_STATUS, 0x0 }, + }; + int ret; + + mutex_lock(&dsp->pwr_lock); + + ret = regmap_read(regmap, dsp->base_sysinfo + HALO_AHBM_WINDOW_DEBUG_1, + fault); + if (ret) { + cs_dsp_warn(dsp, "Failed to read AHB DEBUG_1: %d\n", ret); + goto exit_unlock; + } + + cs_dsp_warn(dsp, "AHB: STATUS: 0x%x ADDR: 0x%x\n", + *fault & HALO_AHBM_FLAGS_ERR_MASK, + (*fault & HALO_AHBM_CORE_ERR_ADDR_MASK) >> + HALO_AHBM_CORE_ERR_ADDR_SHIFT); + + ret = regmap_read(regmap, dsp->base_sysinfo + HALO_AHBM_WINDOW_DEBUG_0, + fault); + if (ret) { + cs_dsp_warn(dsp, "Failed to read AHB DEBUG_0: %d\n", ret); + goto exit_unlock; + } + + cs_dsp_warn(dsp, "AHB: SYS_ADDR: 0x%x\n", *fault); + + ret = regmap_bulk_read(regmap, dsp->base + HALO_MPU_XM_VIO_ADDR, + fault, ARRAY_SIZE(fault)); + if (ret) { + cs_dsp_warn(dsp, "Failed to read MPU fault info: %d\n", ret); + goto exit_unlock; + } + + cs_dsp_warn(dsp, "XM: STATUS:0x%x ADDR:0x%x\n", fault[1], fault[0]); + cs_dsp_warn(dsp, "YM: STATUS:0x%x ADDR:0x%x\n", fault[3], fault[2]); + cs_dsp_warn(dsp, "PM: STATUS:0x%x ADDR:0x%x\n", fault[5], fault[4]); + + ret = regmap_multi_reg_write(dsp->regmap, clear, ARRAY_SIZE(clear)); + if (ret) + cs_dsp_warn(dsp, "Failed to clear MPU status: %d\n", ret); + +exit_unlock: + mutex_unlock(&dsp->pwr_lock); +} +EXPORT_SYMBOL_GPL(cs_dsp_halo_bus_error); + +/** + * cs_dsp_halo_wdt_expire() - Handle DSP watchdog expiry + * @dsp: pointer to DSP structure + * + * This is logged for future analysis. + */ +void cs_dsp_halo_wdt_expire(struct cs_dsp *dsp) +{ + mutex_lock(&dsp->pwr_lock); + + cs_dsp_warn(dsp, "WDT Expiry Fault\n"); + + dsp->ops->stop_watchdog(dsp); + if (dsp->client_ops->watchdog_expired) + dsp->client_ops->watchdog_expired(dsp); + + mutex_unlock(&dsp->pwr_lock); +} +EXPORT_SYMBOL_GPL(cs_dsp_halo_wdt_expire); + +static const struct cs_dsp_ops cs_dsp_adsp1_ops = { + .validate_version = cs_dsp_validate_version, + .parse_sizes = cs_dsp_adsp1_parse_sizes, + .region_to_reg = cs_dsp_region_to_reg, +}; + +static const struct cs_dsp_ops cs_dsp_adsp2_ops[] = { + { + .parse_sizes = cs_dsp_adsp2_parse_sizes, + .validate_version = cs_dsp_validate_version, + .setup_algs = cs_dsp_adsp2_setup_algs, + .region_to_reg = cs_dsp_region_to_reg, + + .show_fw_status = cs_dsp_adsp2_show_fw_status, + + .enable_memory = cs_dsp_adsp2_enable_memory, + .disable_memory = cs_dsp_adsp2_disable_memory, + + .enable_core = cs_dsp_adsp2_enable_core, + .disable_core = cs_dsp_adsp2_disable_core, + + .start_core = cs_dsp_adsp2_start_core, + .stop_core = cs_dsp_adsp2_stop_core, + + }, + { + .parse_sizes = cs_dsp_adsp2_parse_sizes, + .validate_version = cs_dsp_validate_version, + .setup_algs = cs_dsp_adsp2_setup_algs, + .region_to_reg = cs_dsp_region_to_reg, + + .show_fw_status = cs_dsp_adsp2v2_show_fw_status, + + .enable_memory = cs_dsp_adsp2_enable_memory, + .disable_memory = cs_dsp_adsp2_disable_memory, + .lock_memory = cs_dsp_adsp2_lock, + + .enable_core = cs_dsp_adsp2v2_enable_core, + .disable_core = cs_dsp_adsp2v2_disable_core, + + .start_core = cs_dsp_adsp2_start_core, + .stop_core = cs_dsp_adsp2_stop_core, + }, + { + .parse_sizes = cs_dsp_adsp2_parse_sizes, + .validate_version = cs_dsp_validate_version, + .setup_algs = cs_dsp_adsp2_setup_algs, + .region_to_reg = cs_dsp_region_to_reg, + + .show_fw_status = cs_dsp_adsp2v2_show_fw_status, + .stop_watchdog = cs_dsp_stop_watchdog, + + .enable_memory = cs_dsp_adsp2_enable_memory, + .disable_memory = cs_dsp_adsp2_disable_memory, + .lock_memory = cs_dsp_adsp2_lock, + + .enable_core = cs_dsp_adsp2v2_enable_core, + .disable_core = cs_dsp_adsp2v2_disable_core, + + .start_core = cs_dsp_adsp2_start_core, + .stop_core = cs_dsp_adsp2_stop_core, + }, +}; + +static const struct cs_dsp_ops cs_dsp_halo_ops = { + .parse_sizes = cs_dsp_adsp2_parse_sizes, + .validate_version = cs_dsp_halo_validate_version, + .setup_algs = cs_dsp_halo_setup_algs, + .region_to_reg = cs_dsp_halo_region_to_reg, + + .show_fw_status = cs_dsp_halo_show_fw_status, + .stop_watchdog = cs_dsp_halo_stop_watchdog, + + .lock_memory = cs_dsp_halo_configure_mpu, + + .start_core = cs_dsp_halo_start_core, + .stop_core = cs_dsp_halo_stop_core, +}; + +MODULE_DESCRIPTION("Cirrus Logic DSP Support"); +MODULE_AUTHOR("Simon Trimmer simont@opensource.cirrus.com"); +MODULE_LICENSE("GPL v2"); diff --git a/include/linux/firmware/cirrus/cs_dsp.h b/include/linux/firmware/cirrus/cs_dsp.h new file mode 100644 index 000000000000..9ad9eaaaa552 --- /dev/null +++ b/include/linux/firmware/cirrus/cs_dsp.h @@ -0,0 +1,242 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * cs_dsp.h -- Cirrus Logic DSP firmware support + * + * Based on sound/soc/codecs/wm_adsp.h + * + * Copyright 2012 Wolfson Microelectronics plc + * Copyright (C) 2015-2021 Cirrus Logic, Inc. and + * Cirrus Logic International Semiconductor Ltd. + */ +#ifndef __CS_DSP_H +#define __CS_DSP_H + +#define CS_ADSP2_REGION_0 BIT(0) +#define CS_ADSP2_REGION_1 BIT(1) +#define CS_ADSP2_REGION_2 BIT(2) +#define CS_ADSP2_REGION_3 BIT(3) +#define CS_ADSP2_REGION_4 BIT(4) +#define CS_ADSP2_REGION_5 BIT(5) +#define CS_ADSP2_REGION_6 BIT(6) +#define CS_ADSP2_REGION_7 BIT(7) +#define CS_ADSP2_REGION_8 BIT(8) +#define CS_ADSP2_REGION_9 BIT(9) +#define CS_ADSP2_REGION_1_9 (CS_ADSP2_REGION_1 | \ + CS_ADSP2_REGION_2 | CS_ADSP2_REGION_3 | \ + CS_ADSP2_REGION_4 | CS_ADSP2_REGION_5 | \ + CS_ADSP2_REGION_6 | CS_ADSP2_REGION_7 | \ + CS_ADSP2_REGION_8 | CS_ADSP2_REGION_9) +#define CS_ADSP2_REGION_ALL (CS_ADSP2_REGION_0 | CS_ADSP2_REGION_1_9) + +#define CS_DSP_DATA_WORD_SIZE 3 + +#define CS_DSP_ACKED_CTL_TIMEOUT_MS 100 +#define CS_DSP_ACKED_CTL_N_QUICKPOLLS 10 +#define CS_DSP_ACKED_CTL_MIN_VALUE 0 +#define CS_DSP_ACKED_CTL_MAX_VALUE 0xFFFFFF + +/** + * struct cs_dsp_region - Describes a logical memory region in DSP address space + * @type: Memory region type + * @base: Address of region + */ +struct cs_dsp_region { + int type; + unsigned int base; +}; + +/** + * struct cs_dsp_alg_region - Describes a logical algorithm region in DSP address space + * @list: List node for internal use + * @alg: Algorithm id + * @type: Memory region type + * @base: Address of region + */ +struct cs_dsp_alg_region { + struct list_head list; + unsigned int alg; + int type; + unsigned int base; +}; + +/** + * struct cs_dsp_coeff_ctl - Describes a coefficient control + * @fw_name: Name of the firmware + * @subname: Name of the control parsed from the WMFW + * @subname_len: Length of subname + * @alg_region: Logical region associated with this control + * @dsp: DSP instance associated with this control + * @enabled: Flag indicating whether control is enabled + * @list: List node for internal use + * @cache: Cached value of the control + * @offset: Offset of control within alg_region + * @len: Length of the cached value + * @set: Flag indicating the value has been written by the user + * @flags: Bitfield of WMFW_CTL_FLAG_ control flags defined in wmfw.h + * @type: One of the WMFW_CTL_TYPE_ control types defined in wmfw.h + * @priv: For use by the client + */ +struct cs_dsp_coeff_ctl { + const char *fw_name; + /* Subname is needed to match with firmware */ + const char *subname; + unsigned int subname_len; + struct cs_dsp_alg_region alg_region; + struct cs_dsp *dsp; + unsigned int enabled:1; + struct list_head list; + void *cache; + unsigned int offset; + size_t len; + unsigned int set:1; + unsigned int flags; + unsigned int type; + + void *priv; +}; + +struct cs_dsp_ops; +struct cs_dsp_client_ops; + +/** + * struct cs_dsp - Configuration and state of a Cirrus Logic DSP + * @name: The name of the DSP instance + * @rev: Revision of the DSP + * @num: DSP instance number + * @type: Type of DSP + * @dev: Driver model representation of the device + * @regmap: Register map of the device + * @ops: Function pointers for internal callbacks + * @client_ops: Function pointers for client callbacks + * @base: Address of the DSP registers + * @base_sysinfo: Address of the sysinfo register (Halo only) + * @sysclk_reg: Address of the sysclk register (ADSP1 only) + * @sysclk_mask: Mask of frequency bits within sysclk register (ADSP1 only) + * @sysclk_shift: Shift of frequency bits within sysclk register (ADSP1 only) + * @alg_regions: List of currently loaded algorithm regions + * @fw_file_name: Filename of the current firmware + * @fw_name: Name of the current firmware + * @fw_id: ID of the current firmware, obtained from the wmfw + * @fw_id_version: Version of the firmware, obtained from the wmfw + * @fw_vendor_id: Vendor of the firmware, obtained from the wmfw + * @mem: DSP memory region descriptions + * @num_mems: Number of memory regions in this DSP + * @fw_ver: Version of the wmfw file format + * @booted: Flag indicating DSP has been configured + * @running: Flag indicating DSP is executing firmware + * @ctl_list: Controls defined within the loaded DSP firmware + * @lock_regions: Enable MPU traps on specified memory regions + * @pwr_lock: Lock used to serialize accesses + * @debugfs_root: Debugfs directory for this DSP instance + * @wmfw_file_name: Filename of the currently loaded firmware + * @bin_file_name: Filename of the currently loaded coefficients + */ +struct cs_dsp { + const char *name; + int rev; + int num; + int type; + struct device *dev; + struct regmap *regmap; + + const struct cs_dsp_ops *ops; + const struct cs_dsp_client_ops *client_ops; + + unsigned int base; + unsigned int base_sysinfo; + unsigned int sysclk_reg; + unsigned int sysclk_mask; + unsigned int sysclk_shift; + + struct list_head alg_regions; + + const char *fw_name; + unsigned int fw_id; + unsigned int fw_id_version; + unsigned int fw_vendor_id; + + const struct cs_dsp_region *mem; + int num_mems; + + int fw_ver; + + bool booted; + bool running; + + struct list_head ctl_list; + + struct mutex pwr_lock; + + unsigned int lock_regions; + +#ifdef CONFIG_DEBUG_FS + struct dentry *debugfs_root; + char *wmfw_file_name; + char *bin_file_name; +#endif +}; + +/** + * struct cs_dsp_client_ops - client callbacks + * @control_add: Called under the pwr_lock when a control is created + * @control_remove: Called under the pwr_lock when a control is destroyed + * @post_run: Called under the pwr_lock by cs_dsp_run() + * @post_stop: Called under the pwr_lock by cs_dsp_stop() + * @watchdog_expired: Called when a watchdog expiry is detected + * + * These callbacks give the cs_dsp client an opportunity to respond to events + * or to perform actions atomically. + */ +struct cs_dsp_client_ops { + int (*control_add)(struct cs_dsp_coeff_ctl *ctl); + void (*control_remove)(struct cs_dsp_coeff_ctl *ctl); + int (*post_run)(struct cs_dsp *dsp); + void (*post_stop)(struct cs_dsp *dsp); + void (*watchdog_expired)(struct cs_dsp *dsp); +}; + +int cs_dsp_adsp1_init(struct cs_dsp *dsp); +int cs_dsp_adsp2_init(struct cs_dsp *dsp); +int cs_dsp_halo_init(struct cs_dsp *dsp); + +int cs_dsp_adsp1_power_up(struct cs_dsp *dsp, + const struct firmware *wmfw_firmware, char *wmfw_filename, + const struct firmware *coeff_firmware, char *coeff_filename, + const char *fw_name); +void cs_dsp_adsp1_power_down(struct cs_dsp *dsp); +int cs_dsp_power_up(struct cs_dsp *dsp, + const struct firmware *wmfw_firmware, char *wmfw_filename, + const struct firmware *coeff_firmware, char *coeff_filename, + const char *fw_name); +void cs_dsp_power_down(struct cs_dsp *dsp); +int cs_dsp_run(struct cs_dsp *dsp); +void cs_dsp_stop(struct cs_dsp *dsp); + +void cs_dsp_remove(struct cs_dsp *dsp); + +int cs_dsp_set_dspclk(struct cs_dsp *dsp, unsigned int freq); +void cs_dsp_adsp2_bus_error(struct cs_dsp *dsp); +void cs_dsp_halo_bus_error(struct cs_dsp *dsp); +void cs_dsp_halo_wdt_expire(struct cs_dsp *dsp); + +void cs_dsp_init_debugfs(struct cs_dsp *dsp, struct dentry *debugfs_root); +void cs_dsp_cleanup_debugfs(struct cs_dsp *dsp); + +int cs_dsp_coeff_write_acked_control(struct cs_dsp_coeff_ctl *ctl, unsigned int event_id); +int cs_dsp_coeff_write_ctrl(struct cs_dsp_coeff_ctl *ctl, const void *buf, size_t len); +int cs_dsp_coeff_read_ctrl(struct cs_dsp_coeff_ctl *ctl, void *buf, size_t len); +struct cs_dsp_coeff_ctl *cs_dsp_get_ctl(struct cs_dsp *dsp, const char *name, int type, + unsigned int alg); + +int cs_dsp_read_raw_data_block(struct cs_dsp *dsp, int mem_type, unsigned int mem_addr, + unsigned int num_words, __be32 *data); +int cs_dsp_read_data_word(struct cs_dsp *dsp, int mem_type, unsigned int mem_addr, u32 *data); +int cs_dsp_write_data_word(struct cs_dsp *dsp, int mem_type, unsigned int mem_addr, u32 data); +void cs_dsp_remove_padding(u32 *buf, int nwords); + +struct cs_dsp_alg_region *cs_dsp_find_alg_region(struct cs_dsp *dsp, + int type, unsigned int id); + +const char *cs_dsp_mem_region_name(unsigned int type); + +#endif diff --git a/sound/soc/codecs/wmfw.h b/include/linux/firmware/cirrus/wmfw.h similarity index 100% rename from sound/soc/codecs/wmfw.h rename to include/linux/firmware/cirrus/wmfw.h diff --git a/sound/soc/codecs/Kconfig b/sound/soc/codecs/Kconfig index ab7ac5e0bd68..deda5ee02ebb 100644 --- a/sound/soc/codecs/Kconfig +++ b/sound/soc/codecs/Kconfig @@ -333,6 +333,7 @@ config SND_SOC_WM_HUBS
config SND_SOC_WM_ADSP tristate + select CS_DSP select SND_SOC_COMPRESS default y if SND_SOC_MADERA=y default y if SND_SOC_CS47L24=y diff --git a/sound/soc/codecs/wm_adsp.c b/sound/soc/codecs/wm_adsp.c index 6c5d55b3b311..f17c749c24c3 100644 --- a/sound/soc/codecs/wm_adsp.c +++ b/sound/soc/codecs/wm_adsp.c @@ -19,7 +19,6 @@ #include <linux/regmap.h> #include <linux/regulator/consumer.h> #include <linux/slab.h> -#include <linux/vmalloc.h> #include <linux/workqueue.h> #include <linux/debugfs.h> #include <sound/core.h> @@ -44,15 +43,6 @@ #define adsp_dbg(_dsp, fmt, ...) \ dev_dbg(_dsp->cs_dsp.dev, "%s: " fmt, _dsp->cs_dsp.name, ##__VA_ARGS__)
-#define cs_dsp_err(_dsp, fmt, ...) \ - dev_err(_dsp->dev, "%s: " fmt, _dsp->name, ##__VA_ARGS__) -#define cs_dsp_warn(_dsp, fmt, ...) \ - dev_warn(_dsp->dev, "%s: " fmt, _dsp->name, ##__VA_ARGS__) -#define cs_dsp_info(_dsp, fmt, ...) \ - dev_info(_dsp->dev, "%s: " fmt, _dsp->name, ##__VA_ARGS__) -#define cs_dsp_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__) @@ -60,305 +50,11 @@ 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 -#define ADSP1_CONTROL_4 0x04 -#define ADSP1_CONTROL_5 0x06 -#define ADSP1_CONTROL_6 0x07 -#define ADSP1_CONTROL_7 0x08 -#define ADSP1_CONTROL_8 0x09 -#define ADSP1_CONTROL_9 0x0A -#define ADSP1_CONTROL_10 0x0B -#define ADSP1_CONTROL_11 0x0C -#define ADSP1_CONTROL_12 0x0D -#define ADSP1_CONTROL_13 0x0F -#define ADSP1_CONTROL_14 0x10 -#define ADSP1_CONTROL_15 0x11 -#define ADSP1_CONTROL_16 0x12 -#define ADSP1_CONTROL_17 0x13 -#define ADSP1_CONTROL_18 0x14 -#define ADSP1_CONTROL_19 0x16 -#define ADSP1_CONTROL_20 0x17 -#define ADSP1_CONTROL_21 0x18 -#define ADSP1_CONTROL_22 0x1A -#define ADSP1_CONTROL_23 0x1B -#define ADSP1_CONTROL_24 0x1C -#define ADSP1_CONTROL_25 0x1E -#define ADSP1_CONTROL_26 0x20 -#define ADSP1_CONTROL_27 0x21 -#define ADSP1_CONTROL_28 0x22 -#define ADSP1_CONTROL_29 0x23 -#define ADSP1_CONTROL_30 0x24 -#define ADSP1_CONTROL_31 0x26 - -/* - * ADSP1 Control 19 - */ -#define ADSP1_WDMA_BUFFER_LENGTH_MASK 0x00FF /* DSP1_WDMA_BUFFER_LENGTH - [7:0] */ -#define ADSP1_WDMA_BUFFER_LENGTH_SHIFT 0 /* DSP1_WDMA_BUFFER_LENGTH - [7:0] */ -#define ADSP1_WDMA_BUFFER_LENGTH_WIDTH 8 /* DSP1_WDMA_BUFFER_LENGTH - [7:0] */ - - -/* - * ADSP1 Control 30 - */ -#define ADSP1_DBG_CLK_ENA 0x0008 /* DSP1_DBG_CLK_ENA */ -#define ADSP1_DBG_CLK_ENA_MASK 0x0008 /* DSP1_DBG_CLK_ENA */ -#define ADSP1_DBG_CLK_ENA_SHIFT 3 /* DSP1_DBG_CLK_ENA */ -#define ADSP1_DBG_CLK_ENA_WIDTH 1 /* DSP1_DBG_CLK_ENA */ -#define ADSP1_SYS_ENA 0x0004 /* DSP1_SYS_ENA */ -#define ADSP1_SYS_ENA_MASK 0x0004 /* DSP1_SYS_ENA */ -#define ADSP1_SYS_ENA_SHIFT 2 /* DSP1_SYS_ENA */ -#define ADSP1_SYS_ENA_WIDTH 1 /* DSP1_SYS_ENA */ -#define ADSP1_CORE_ENA 0x0002 /* DSP1_CORE_ENA */ -#define ADSP1_CORE_ENA_MASK 0x0002 /* DSP1_CORE_ENA */ -#define ADSP1_CORE_ENA_SHIFT 1 /* DSP1_CORE_ENA */ -#define ADSP1_CORE_ENA_WIDTH 1 /* DSP1_CORE_ENA */ -#define ADSP1_START 0x0001 /* DSP1_START */ -#define ADSP1_START_MASK 0x0001 /* DSP1_START */ -#define ADSP1_START_SHIFT 0 /* DSP1_START */ -#define ADSP1_START_WIDTH 1 /* DSP1_START */ - -/* - * ADSP1 Control 31 - */ -#define ADSP1_CLK_SEL_MASK 0x0007 /* CLK_SEL_ENA */ -#define ADSP1_CLK_SEL_SHIFT 0 /* CLK_SEL_ENA */ -#define ADSP1_CLK_SEL_WIDTH 3 /* CLK_SEL_ENA */ - -#define ADSP2_CONTROL 0x0 -#define ADSP2_CLOCKING 0x1 -#define ADSP2V2_CLOCKING 0x2 -#define ADSP2_STATUS1 0x4 -#define ADSP2_WDMA_CONFIG_1 0x30 -#define ADSP2_WDMA_CONFIG_2 0x31 -#define ADSP2V2_WDMA_CONFIG_2 0x32 -#define ADSP2_RDMA_CONFIG_1 0x34 - -#define ADSP2_SCRATCH0 0x40 -#define ADSP2_SCRATCH1 0x41 -#define ADSP2_SCRATCH2 0x42 -#define ADSP2_SCRATCH3 0x43 - -#define ADSP2V2_SCRATCH0_1 0x40 -#define ADSP2V2_SCRATCH2_3 0x42 - -/* - * ADSP2 Control - */ - -#define ADSP2_MEM_ENA 0x0010 /* DSP1_MEM_ENA */ -#define ADSP2_MEM_ENA_MASK 0x0010 /* DSP1_MEM_ENA */ -#define ADSP2_MEM_ENA_SHIFT 4 /* DSP1_MEM_ENA */ -#define ADSP2_MEM_ENA_WIDTH 1 /* DSP1_MEM_ENA */ -#define ADSP2_SYS_ENA 0x0004 /* DSP1_SYS_ENA */ -#define ADSP2_SYS_ENA_MASK 0x0004 /* DSP1_SYS_ENA */ -#define ADSP2_SYS_ENA_SHIFT 2 /* DSP1_SYS_ENA */ -#define ADSP2_SYS_ENA_WIDTH 1 /* DSP1_SYS_ENA */ -#define ADSP2_CORE_ENA 0x0002 /* DSP1_CORE_ENA */ -#define ADSP2_CORE_ENA_MASK 0x0002 /* DSP1_CORE_ENA */ -#define ADSP2_CORE_ENA_SHIFT 1 /* DSP1_CORE_ENA */ -#define ADSP2_CORE_ENA_WIDTH 1 /* DSP1_CORE_ENA */ -#define ADSP2_START 0x0001 /* DSP1_START */ -#define ADSP2_START_MASK 0x0001 /* DSP1_START */ -#define ADSP2_START_SHIFT 0 /* DSP1_START */ -#define ADSP2_START_WIDTH 1 /* DSP1_START */ - -/* - * ADSP2 clocking - */ -#define ADSP2_CLK_SEL_MASK 0x0007 /* CLK_SEL_ENA */ -#define ADSP2_CLK_SEL_SHIFT 0 /* CLK_SEL_ENA */ -#define ADSP2_CLK_SEL_WIDTH 3 /* CLK_SEL_ENA */ - -/* - * ADSP2V2 clocking - */ -#define ADSP2V2_CLK_SEL_MASK 0x70000 /* CLK_SEL_ENA */ -#define ADSP2V2_CLK_SEL_SHIFT 16 /* CLK_SEL_ENA */ -#define ADSP2V2_CLK_SEL_WIDTH 3 /* CLK_SEL_ENA */ - -#define ADSP2V2_RATE_MASK 0x7800 /* DSP_RATE */ -#define ADSP2V2_RATE_SHIFT 11 /* DSP_RATE */ -#define ADSP2V2_RATE_WIDTH 4 /* DSP_RATE */ - -/* - * ADSP2 Status 1 - */ -#define ADSP2_RAM_RDY 0x0001 -#define ADSP2_RAM_RDY_MASK 0x0001 -#define ADSP2_RAM_RDY_SHIFT 0 -#define ADSP2_RAM_RDY_WIDTH 1 - -/* - * ADSP2 Lock support - */ -#define ADSP2_LOCK_CODE_0 0x5555 -#define ADSP2_LOCK_CODE_1 0xAAAA - -#define ADSP2_WATCHDOG 0x0A -#define ADSP2_BUS_ERR_ADDR 0x52 -#define ADSP2_REGION_LOCK_STATUS 0x64 -#define ADSP2_LOCK_REGION_1_LOCK_REGION_0 0x66 -#define ADSP2_LOCK_REGION_3_LOCK_REGION_2 0x68 -#define ADSP2_LOCK_REGION_5_LOCK_REGION_4 0x6A -#define ADSP2_LOCK_REGION_7_LOCK_REGION_6 0x6C -#define ADSP2_LOCK_REGION_9_LOCK_REGION_8 0x6E -#define ADSP2_LOCK_REGION_CTRL 0x7A -#define ADSP2_PMEM_ERR_ADDR_XMEM_ERR_ADDR 0x7C - -#define ADSP2_REGION_LOCK_ERR_MASK 0x8000 -#define ADSP2_ADDR_ERR_MASK 0x4000 -#define ADSP2_WDT_TIMEOUT_STS_MASK 0x2000 -#define ADSP2_CTRL_ERR_PAUSE_ENA 0x0002 -#define ADSP2_CTRL_ERR_EINT 0x0001 - -#define ADSP2_BUS_ERR_ADDR_MASK 0x00FFFFFF -#define ADSP2_XMEM_ERR_ADDR_MASK 0x0000FFFF -#define ADSP2_PMEM_ERR_ADDR_MASK 0x7FFF0000 -#define ADSP2_PMEM_ERR_ADDR_SHIFT 16 -#define ADSP2_WDT_ENA_MASK 0xFFFFFFFD - -#define ADSP2_LOCK_REGION_SHIFT 16 - #define ADSP_MAX_STD_CTRL_SIZE 512
-#define CS_DSP_ACKED_CTL_TIMEOUT_MS 100 -#define CS_DSP_ACKED_CTL_N_QUICKPOLLS 10 -#define CS_DSP_ACKED_CTL_MIN_VALUE 0 -#define CS_DSP_ACKED_CTL_MAX_VALUE 0xFFFFFF - -/* - * Event control messages - */ -#define CS_DSP_FW_EVENT_SHUTDOWN 0x000001 - -/* - * HALO system info - */ -#define HALO_AHBM_WINDOW_DEBUG_0 0x02040 -#define HALO_AHBM_WINDOW_DEBUG_1 0x02044 - -/* - * HALO core - */ -#define HALO_SCRATCH1 0x005c0 -#define HALO_SCRATCH2 0x005c8 -#define HALO_SCRATCH3 0x005d0 -#define HALO_SCRATCH4 0x005d8 -#define HALO_CCM_CORE_CONTROL 0x41000 -#define HALO_CORE_SOFT_RESET 0x00010 -#define HALO_WDT_CONTROL 0x47000 - -/* - * HALO MPU banks - */ -#define HALO_MPU_XMEM_ACCESS_0 0x43000 -#define HALO_MPU_YMEM_ACCESS_0 0x43004 -#define HALO_MPU_WINDOW_ACCESS_0 0x43008 -#define HALO_MPU_XREG_ACCESS_0 0x4300C -#define HALO_MPU_YREG_ACCESS_0 0x43014 -#define HALO_MPU_XMEM_ACCESS_1 0x43018 -#define HALO_MPU_YMEM_ACCESS_1 0x4301C -#define HALO_MPU_WINDOW_ACCESS_1 0x43020 -#define HALO_MPU_XREG_ACCESS_1 0x43024 -#define HALO_MPU_YREG_ACCESS_1 0x4302C -#define HALO_MPU_XMEM_ACCESS_2 0x43030 -#define HALO_MPU_YMEM_ACCESS_2 0x43034 -#define HALO_MPU_WINDOW_ACCESS_2 0x43038 -#define HALO_MPU_XREG_ACCESS_2 0x4303C -#define HALO_MPU_YREG_ACCESS_2 0x43044 -#define HALO_MPU_XMEM_ACCESS_3 0x43048 -#define HALO_MPU_YMEM_ACCESS_3 0x4304C -#define HALO_MPU_WINDOW_ACCESS_3 0x43050 -#define HALO_MPU_XREG_ACCESS_3 0x43054 -#define HALO_MPU_YREG_ACCESS_3 0x4305C -#define HALO_MPU_XM_VIO_ADDR 0x43100 -#define HALO_MPU_XM_VIO_STATUS 0x43104 -#define HALO_MPU_YM_VIO_ADDR 0x43108 -#define HALO_MPU_YM_VIO_STATUS 0x4310C -#define HALO_MPU_PM_VIO_ADDR 0x43110 -#define HALO_MPU_PM_VIO_STATUS 0x43114 -#define HALO_MPU_LOCK_CONFIG 0x43140 - -/* - * HALO_AHBM_WINDOW_DEBUG_1 - */ -#define HALO_AHBM_CORE_ERR_ADDR_MASK 0x0fffff00 -#define HALO_AHBM_CORE_ERR_ADDR_SHIFT 8 -#define HALO_AHBM_FLAGS_ERR_MASK 0x000000ff - -/* - * HALO_CCM_CORE_CONTROL - */ -#define HALO_CORE_RESET 0x00000200 -#define HALO_CORE_EN 0x00000001 - -/* - * HALO_CORE_SOFT_RESET - */ -#define HALO_CORE_SOFT_RESET_MASK 0x00000001 - -/* - * HALO_WDT_CONTROL - */ -#define HALO_WDT_EN_MASK 0x00000001 - -/* - * HALO_MPU_?M_VIO_STATUS - */ -#define HALO_MPU_VIO_STS_MASK 0x007e0000 -#define HALO_MPU_VIO_STS_SHIFT 17 -#define HALO_MPU_VIO_ERR_WR_MASK 0x00008000 -#define HALO_MPU_VIO_ERR_SRC_MASK 0x00007fff -#define HALO_MPU_VIO_ERR_SRC_SHIFT 0 - -static const struct cs_dsp_ops cs_dsp_adsp1_ops; -static const struct cs_dsp_ops cs_dsp_adsp2_ops[]; -static const struct cs_dsp_ops cs_dsp_halo_ops; - static const struct cs_dsp_client_ops wm_adsp1_client_ops; static const struct cs_dsp_client_ops wm_adsp2_client_ops;
-struct cs_dsp_buf { - struct list_head list; - void *buf; -}; - -static struct cs_dsp_buf *cs_dsp_buf_alloc(const void *src, size_t len, - struct list_head *list) -{ - struct cs_dsp_buf *buf = kzalloc(sizeof(*buf), GFP_KERNEL); - - if (buf == NULL) - return NULL; - - buf->buf = vmalloc(len); - if (!buf->buf) { - kfree(buf); - return NULL; - } - memcpy(buf->buf, src, len); - - if (list) - list_add_tail(&buf->list, list); - - return buf; -} - -static void cs_dsp_buf_free(struct list_head *list) -{ - while (!list_empty(list)) { - struct cs_dsp_buf *buf = list_first_entry(list, - struct cs_dsp_buf, - list); - list_del(&buf->list); - vfree(buf->buf); - kfree(buf); - } -} - #define WM_ADSP_FW_MBC_VSS 0 #define WM_ADSP_FW_HIFI 1 #define WM_ADSP_FW_TX 2 @@ -483,8 +179,6 @@ struct wm_adsp_compr { const char *name; };
-#define CS_DSP_DATA_WORD_SIZE 3 - #define WM_ADSP_MIN_FRAGMENTS 1 #define WM_ADSP_MAX_FRAGMENTS 256 #define WM_ADSP_MIN_FRAGMENT_SIZE (64 * CS_DSP_DATA_WORD_SIZE) @@ -616,166 +310,6 @@ struct wm_coeff_ctl { struct work_struct work; };
-static const char *cs_dsp_mem_region_name(unsigned int type) -{ - switch (type) { - case WMFW_ADSP1_PM: - return "PM"; - case WMFW_HALO_PM_PACKED: - return "PM_PACKED"; - case WMFW_ADSP1_DM: - return "DM"; - case WMFW_ADSP2_XM: - return "XM"; - case WMFW_HALO_XM_PACKED: - return "XM_PACKED"; - case WMFW_ADSP2_YM: - return "YM"; - case WMFW_HALO_YM_PACKED: - return "YM_PACKED"; - case WMFW_ADSP1_ZM: - return "ZM"; - default: - return NULL; - } -} - -#ifdef CONFIG_DEBUG_FS -static void cs_dsp_debugfs_save_wmfwname(struct cs_dsp *dsp, const char *s) -{ - char *tmp = kasprintf(GFP_KERNEL, "%s\n", s); - - kfree(dsp->wmfw_file_name); - dsp->wmfw_file_name = tmp; -} - -static void cs_dsp_debugfs_save_binname(struct cs_dsp *dsp, const char *s) -{ - char *tmp = kasprintf(GFP_KERNEL, "%s\n", s); - - kfree(dsp->bin_file_name); - dsp->bin_file_name = tmp; -} - -static void cs_dsp_debugfs_clear(struct cs_dsp *dsp) -{ - kfree(dsp->wmfw_file_name); - kfree(dsp->bin_file_name); - dsp->wmfw_file_name = NULL; - dsp->bin_file_name = NULL; -} - -static ssize_t cs_dsp_debugfs_wmfw_read(struct file *file, - char __user *user_buf, - size_t count, loff_t *ppos) -{ - struct cs_dsp *dsp = file->private_data; - ssize_t ret; - - mutex_lock(&dsp->pwr_lock); - - if (!dsp->wmfw_file_name || !dsp->booted) - ret = 0; - else - ret = simple_read_from_buffer(user_buf, count, ppos, - dsp->wmfw_file_name, - strlen(dsp->wmfw_file_name)); - - mutex_unlock(&dsp->pwr_lock); - return ret; -} - -static ssize_t cs_dsp_debugfs_bin_read(struct file *file, - char __user *user_buf, - size_t count, loff_t *ppos) -{ - struct cs_dsp *dsp = file->private_data; - ssize_t ret; - - mutex_lock(&dsp->pwr_lock); - - if (!dsp->bin_file_name || !dsp->booted) - ret = 0; - else - ret = simple_read_from_buffer(user_buf, count, ppos, - dsp->bin_file_name, - strlen(dsp->bin_file_name)); - - mutex_unlock(&dsp->pwr_lock); - return ret; -} - -static const struct { - const char *name; - const struct file_operations fops; -} cs_dsp_debugfs_fops[] = { - { - .name = "wmfw_file_name", - .fops = { - .open = simple_open, - .read = cs_dsp_debugfs_wmfw_read, - }, - }, - { - .name = "bin_file_name", - .fops = { - .open = simple_open, - .read = cs_dsp_debugfs_bin_read, - }, - }, -}; - -static void cs_dsp_init_debugfs(struct cs_dsp *dsp, - struct dentry *debugfs_root) -{ - struct dentry *root = NULL; - int i; - - root = debugfs_create_dir(dsp->name, debugfs_root); - - debugfs_create_bool("booted", 0444, root, &dsp->booted); - debugfs_create_bool("running", 0444, root, &dsp->running); - debugfs_create_x32("fw_id", 0444, root, &dsp->fw_id); - debugfs_create_x32("fw_version", 0444, root, &dsp->fw_id_version); - - for (i = 0; i < ARRAY_SIZE(cs_dsp_debugfs_fops); ++i) - debugfs_create_file(cs_dsp_debugfs_fops[i].name, 0444, root, - dsp, &cs_dsp_debugfs_fops[i].fops); - - dsp->debugfs_root = root; -} - -static void cs_dsp_cleanup_debugfs(struct cs_dsp *dsp) -{ - cs_dsp_debugfs_clear(dsp); - debugfs_remove_recursive(dsp->debugfs_root); - dsp->debugfs_root = NULL; -} -#else -static inline void cs_dsp_init_debugfs(struct cs_dsp *dsp, - struct dentry *debugfs_root) -{ -} - -static inline void cs_dsp_cleanup_debugfs(struct cs_dsp *dsp) -{ -} - -static inline void cs_dsp_debugfs_save_wmfwname(struct cs_dsp *dsp, - const char *s) -{ -} - -static inline void cs_dsp_debugfs_save_binname(struct cs_dsp *dsp, - const char *s) -{ -} - -static inline void cs_dsp_debugfs_clear(struct cs_dsp *dsp) -{ -} -#endif - int wm_adsp_fw_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { @@ -827,126 +361,11 @@ const struct soc_enum wm_adsp_fw_enum[] = { }; EXPORT_SYMBOL_GPL(wm_adsp_fw_enum);
-static const struct cs_dsp_region *cs_dsp_find_region(struct cs_dsp *dsp, - int type) -{ - int i; - - for (i = 0; i < dsp->num_mems; i++) - if (dsp->mem[i].type == type) - return &dsp->mem[i]; - - return NULL; -} - -static unsigned int cs_dsp_region_to_reg(struct cs_dsp_region const *mem, - unsigned int offset) -{ - switch (mem->type) { - case WMFW_ADSP1_PM: - return mem->base + (offset * 3); - case WMFW_ADSP1_DM: - case WMFW_ADSP2_XM: - case WMFW_ADSP2_YM: - case WMFW_ADSP1_ZM: - return mem->base + (offset * 2); - default: - WARN(1, "Unknown memory region type"); - return offset; - } -} - -static unsigned int cs_dsp_halo_region_to_reg(struct cs_dsp_region const *mem, - unsigned int offset) -{ - switch (mem->type) { - case WMFW_ADSP2_XM: - case WMFW_ADSP2_YM: - return mem->base + (offset * 4); - case WMFW_HALO_XM_PACKED: - case WMFW_HALO_YM_PACKED: - return (mem->base + (offset * 3)) & ~0x3; - case WMFW_HALO_PM_PACKED: - return mem->base + (offset * 5); - default: - WARN(1, "Unknown memory region type"); - return offset; - } -} - -static void cs_dsp_read_fw_status(struct cs_dsp *dsp, - int noffs, unsigned int *offs) -{ - unsigned int i; - int ret; - - for (i = 0; i < noffs; ++i) { - ret = regmap_read(dsp->regmap, dsp->base + offs[i], &offs[i]); - if (ret) { - cs_dsp_err(dsp, "Failed to read SCRATCH%u: %d\n", i, ret); - return; - } - } -} - -static void cs_dsp_adsp2_show_fw_status(struct cs_dsp *dsp) -{ - unsigned int offs[] = { - ADSP2_SCRATCH0, ADSP2_SCRATCH1, ADSP2_SCRATCH2, ADSP2_SCRATCH3, - }; - - cs_dsp_read_fw_status(dsp, ARRAY_SIZE(offs), offs); - - cs_dsp_dbg(dsp, "FW SCRATCH 0:0x%x 1:0x%x 2:0x%x 3:0x%x\n", - offs[0], offs[1], offs[2], offs[3]); -} - -static void cs_dsp_adsp2v2_show_fw_status(struct cs_dsp *dsp) -{ - unsigned int offs[] = { ADSP2V2_SCRATCH0_1, ADSP2V2_SCRATCH2_3 }; - - cs_dsp_read_fw_status(dsp, ARRAY_SIZE(offs), offs); - - cs_dsp_dbg(dsp, "FW SCRATCH 0:0x%x 1:0x%x 2:0x%x 3:0x%x\n", - offs[0] & 0xFFFF, offs[0] >> 16, - offs[1] & 0xFFFF, offs[1] >> 16); -} - -static void cs_dsp_halo_show_fw_status(struct cs_dsp *dsp) -{ - unsigned int offs[] = { - HALO_SCRATCH1, HALO_SCRATCH2, HALO_SCRATCH3, HALO_SCRATCH4, - }; - - cs_dsp_read_fw_status(dsp, ARRAY_SIZE(offs), offs); - - cs_dsp_dbg(dsp, "FW SCRATCH 0:0x%x 1:0x%x 2:0x%x 3:0x%x\n", - offs[0], offs[1], offs[2], offs[3]); -} - static inline struct wm_coeff_ctl *bytes_ext_to_ctl(struct soc_bytes_ext *ext) { return container_of(ext, struct wm_coeff_ctl, bytes_ext); }
-static int cs_dsp_coeff_base_reg(struct cs_dsp_coeff_ctl *ctl, unsigned int *reg) -{ - const struct cs_dsp_alg_region *alg_region = &ctl->alg_region; - struct cs_dsp *dsp = ctl->dsp; - const struct cs_dsp_region *mem; - - mem = cs_dsp_find_region(dsp, alg_region->type); - if (!mem) { - cs_dsp_err(dsp, "No base for region %x\n", - alg_region->type); - return -EINVAL; - } - - *reg = dsp->ops->region_to_reg(mem, ctl->alg_region.base + ctl->offset); - - return 0; -} - static int wm_coeff_info(struct snd_kcontrol *kctl, struct snd_ctl_elem_info *uinfo) { @@ -972,117 +391,6 @@ static int wm_coeff_info(struct snd_kcontrol *kctl, return 0; }
-static int cs_dsp_coeff_write_acked_control(struct cs_dsp_coeff_ctl *ctl, - unsigned int event_id) -{ - struct cs_dsp *dsp = ctl->dsp; - __be32 val = cpu_to_be32(event_id); - unsigned int reg; - int i, ret; - - if (!dsp->running) - return -EPERM; - - ret = cs_dsp_coeff_base_reg(ctl, ®); - if (ret) - return ret; - - cs_dsp_dbg(dsp, "Sending 0x%x to acked control alg 0x%x %s:0x%x\n", - event_id, ctl->alg_region.alg, - cs_dsp_mem_region_name(ctl->alg_region.type), ctl->offset); - - ret = regmap_raw_write(dsp->regmap, reg, &val, sizeof(val)); - if (ret) { - cs_dsp_err(dsp, "Failed to write %x: %d\n", reg, ret); - return ret; - } - - /* - * Poll for ack, we initially poll at ~1ms intervals for firmwares - * that respond quickly, then go to ~10ms polls. A firmware is unlikely - * to ack instantly so we do the first 1ms delay before reading the - * control to avoid a pointless bus transaction - */ - for (i = 0; i < CS_DSP_ACKED_CTL_TIMEOUT_MS;) { - switch (i) { - case 0 ... CS_DSP_ACKED_CTL_N_QUICKPOLLS - 1: - usleep_range(1000, 2000); - i++; - break; - default: - usleep_range(10000, 20000); - i += 10; - break; - } - - ret = regmap_raw_read(dsp->regmap, reg, &val, sizeof(val)); - if (ret) { - cs_dsp_err(dsp, "Failed to read %x: %d\n", reg, ret); - return ret; - } - - if (val == 0) { - cs_dsp_dbg(dsp, "Acked control ACKED at poll %u\n", i); - return 0; - } - } - - cs_dsp_warn(dsp, "Acked control @0x%x alg:0x%x %s:0x%x timed out\n", - reg, ctl->alg_region.alg, - cs_dsp_mem_region_name(ctl->alg_region.type), - ctl->offset); - - return -ETIMEDOUT; -} - -static int cs_dsp_coeff_write_ctrl_raw(struct cs_dsp_coeff_ctl *ctl, - const void *buf, size_t len) -{ - struct cs_dsp *dsp = ctl->dsp; - void *scratch; - int ret; - unsigned int reg; - - ret = cs_dsp_coeff_base_reg(ctl, ®); - if (ret) - return ret; - - scratch = kmemdup(buf, len, GFP_KERNEL | GFP_DMA); - if (!scratch) - return -ENOMEM; - - ret = regmap_raw_write(dsp->regmap, reg, scratch, - len); - if (ret) { - cs_dsp_err(dsp, "Failed to write %zu bytes to %x: %d\n", - len, reg, ret); - kfree(scratch); - return ret; - } - cs_dsp_dbg(dsp, "Wrote %zu bytes to %x\n", len, reg); - - kfree(scratch); - - return 0; -} - -static int cs_dsp_coeff_write_ctrl(struct cs_dsp_coeff_ctl *ctl, - const void *buf, size_t len) -{ - int ret = 0; - - if (ctl->flags & WMFW_CTL_FLAG_VOLATILE) - ret = -EPERM; - else if (buf != ctl->cache) - memcpy(ctl->cache, buf, len); - - ctl->set = 1; - if (ctl->enabled && ctl->dsp->running) - ret = cs_dsp_coeff_write_ctrl_raw(ctl, buf, len); - - return ret; -} - static int wm_coeff_put(struct snd_kcontrol *kctl, struct snd_ctl_elem_value *ucontrol) { @@ -1146,57 +454,6 @@ static int wm_coeff_put_acked(struct snd_kcontrol *kctl, return ret; }
-static int cs_dsp_coeff_read_ctrl_raw(struct cs_dsp_coeff_ctl *ctl, - void *buf, size_t len) -{ - struct cs_dsp *dsp = ctl->dsp; - void *scratch; - int ret; - unsigned int reg; - - ret = cs_dsp_coeff_base_reg(ctl, ®); - if (ret) - return ret; - - scratch = kmalloc(len, GFP_KERNEL | GFP_DMA); - if (!scratch) - return -ENOMEM; - - ret = regmap_raw_read(dsp->regmap, reg, scratch, len); - if (ret) { - cs_dsp_err(dsp, "Failed to read %zu bytes from %x: %d\n", - len, reg, ret); - kfree(scratch); - return ret; - } - cs_dsp_dbg(dsp, "Read %zu bytes from %x\n", len, reg); - - memcpy(buf, scratch, len); - kfree(scratch); - - return 0; -} - -static int cs_dsp_coeff_read_ctrl(struct cs_dsp_coeff_ctl *ctl, void *buf, size_t len) -{ - int ret = 0; - - if (ctl->flags & WMFW_CTL_FLAG_VOLATILE) { - if (ctl->enabled && ctl->dsp->running) - return cs_dsp_coeff_read_ctrl_raw(ctl, buf, len); - else - return -EPERM; - } else { - if (!ctl->flags && ctl->enabled && ctl->dsp->running) - ret = cs_dsp_coeff_read_ctrl_raw(ctl, ctl->cache, ctl->len); - - if (buf != ctl->cache) - memcpy(buf, ctl->cache, len); - } - - return ret; -} - static int wm_coeff_get(struct snd_kcontrol *kctl, struct snd_ctl_elem_value *ucontrol) { @@ -1328,72 +585,6 @@ static int wmfw_add_ctl(struct wm_adsp *dsp, struct wm_coeff_ctl *ctl) return ret; }
-static int cs_dsp_coeff_init_control_caches(struct cs_dsp *dsp) -{ - struct cs_dsp_coeff_ctl *ctl; - int ret; - - list_for_each_entry(ctl, &dsp->ctl_list, list) { - if (!ctl->enabled || ctl->set) - continue; - if (ctl->flags & WMFW_CTL_FLAG_VOLATILE) - continue; - - /* - * For readable controls populate the cache from the DSP memory. - * For non-readable controls the cache was zero-filled when - * created so we don't need to do anything. - */ - if (!ctl->flags || (ctl->flags & WMFW_CTL_FLAG_READABLE)) { - ret = cs_dsp_coeff_read_ctrl_raw(ctl, ctl->cache, ctl->len); - if (ret < 0) - return ret; - } - } - - return 0; -} - -static int cs_dsp_coeff_sync_controls(struct cs_dsp *dsp) -{ - struct cs_dsp_coeff_ctl *ctl; - int ret; - - list_for_each_entry(ctl, &dsp->ctl_list, list) { - if (!ctl->enabled) - continue; - if (ctl->set && !(ctl->flags & WMFW_CTL_FLAG_VOLATILE)) { - ret = cs_dsp_coeff_write_ctrl_raw(ctl, ctl->cache, - ctl->len); - if (ret < 0) - return ret; - } - } - - return 0; -} - -static void cs_dsp_signal_event_controls(struct cs_dsp *dsp, - unsigned int event) -{ - struct cs_dsp_coeff_ctl *ctl; - int ret; - - list_for_each_entry(ctl, &dsp->ctl_list, list) { - if (ctl->type != WMFW_CTL_TYPE_HOSTEVENT) - continue; - - if (!ctl->enabled) - continue; - - ret = cs_dsp_coeff_write_acked_control(ctl, event); - if (ret) - cs_dsp_warn(dsp, - "Failed to send 0x%x event to alg 0x%x (%d)\n", - event, ctl->alg_region.alg, ret); - } -} - static void wm_adsp_ctl_work(struct work_struct *work) { struct wm_coeff_ctl *ctl = container_of(work, @@ -1406,13 +597,6 @@ static void wm_adsp_ctl_work(struct work_struct *work) wmfw_add_ctl(dsp, ctl); }
-static void cs_dsp_free_ctl_blk(struct cs_dsp_coeff_ctl *ctl) -{ - kfree(ctl->cache); - kfree(ctl->subname); - kfree(ctl); -} - static int wm_adsp_control_add(struct cs_dsp_coeff_ctl *cs_ctl) { struct wm_adsp *dsp = container_of(cs_ctl->dsp, struct wm_adsp, cs_dsp); @@ -1498,315 +682,66 @@ static void wm_adsp_control_remove(struct cs_dsp_coeff_ctl *cs_ctl) kfree(ctl); }
-static int cs_dsp_create_control(struct cs_dsp *dsp, - const struct cs_dsp_alg_region *alg_region, - unsigned int offset, unsigned int len, - const char *subname, unsigned int subname_len, - unsigned int flags, unsigned int type) +int wm_adsp_write_ctl(struct wm_adsp *dsp, const char *name, int type, + unsigned int alg, void *buf, size_t len) { - struct cs_dsp_coeff_ctl *ctl; + struct cs_dsp_coeff_ctl *cs_ctl; + struct wm_coeff_ctl *ctl; + struct snd_kcontrol *kcontrol; + char ctl_name[SNDRV_CTL_ELEM_ID_NAME_MAXLEN]; int ret;
- list_for_each_entry(ctl, &dsp->ctl_list, list) { - if (ctl->fw_name == dsp->fw_name && - ctl->alg_region.alg == alg_region->alg && - ctl->alg_region.type == alg_region->type) { - if ((!subname && !ctl->subname) || - (subname && !strncmp(ctl->subname, subname, ctl->subname_len))) { - if (!ctl->enabled) - ctl->enabled = 1; - return 0; - } - } - } + cs_ctl = cs_dsp_get_ctl(&dsp->cs_dsp, name, type, alg); + if (!cs_ctl) + return -EINVAL;
- ctl = kzalloc(sizeof(*ctl), GFP_KERNEL); - if (!ctl) - return -ENOMEM; + ctl = cs_ctl->priv;
- ctl->fw_name = dsp->fw_name; - ctl->alg_region = *alg_region; - if (subname && dsp->fw_ver >= 2) { - ctl->subname_len = subname_len; - ctl->subname = kmemdup(subname, - strlen(subname) + 1, GFP_KERNEL); - if (!ctl->subname) { - ret = -ENOMEM; - goto err_ctl; - } - } - ctl->enabled = 1; - ctl->set = 0; - ctl->dsp = dsp; + if (len > cs_ctl->len) + return -EINVAL;
- ctl->flags = flags; - ctl->type = type; - ctl->offset = offset; - ctl->len = len; - ctl->cache = kzalloc(ctl->len, GFP_KERNEL); - if (!ctl->cache) { - ret = -ENOMEM; - goto err_ctl_subname; - } + ret = cs_dsp_coeff_write_ctrl(cs_ctl, buf, len); + if (ret) + return ret;
- list_add(&ctl->list, &dsp->ctl_list); - - if (dsp->client_ops->control_add) { - ret = dsp->client_ops->control_add(ctl); - if (ret) - goto err_list_del; - } - - return 0; - -err_list_del: - list_del(&ctl->list); - kfree(ctl->cache); -err_ctl_subname: - kfree(ctl->subname); -err_ctl: - kfree(ctl); - - return ret; -} - -struct cs_dsp_coeff_parsed_alg { - int id; - const u8 *name; - int name_len; - int ncoeff; -}; - -struct cs_dsp_coeff_parsed_coeff { - int offset; - int mem_type; - const u8 *name; - int name_len; - unsigned int ctl_type; - int flags; - int len; -}; - -static int cs_dsp_coeff_parse_string(int bytes, const u8 **pos, const u8 **str) -{ - int length; - - switch (bytes) { - case 1: - length = **pos; - break; - case 2: - length = le16_to_cpu(*((__le16 *)*pos)); - break; - default: + if (cs_ctl->flags & WMFW_CTL_FLAG_SYS) return 0; - } - - if (str) - *str = *pos + bytes; - - *pos += ((length + bytes) + 3) & ~0x03; - - return length; -} - -static int cs_dsp_coeff_parse_int(int bytes, const u8 **pos) -{ - int val = 0; - - switch (bytes) { - case 2: - val = le16_to_cpu(*((__le16 *)*pos)); - break; - case 4: - val = le32_to_cpu(*((__le32 *)*pos)); - break; - default: - break; - } - - *pos += bytes;
- return val; -} - -static inline void cs_dsp_coeff_parse_alg(struct cs_dsp *dsp, const u8 **data, - struct cs_dsp_coeff_parsed_alg *blk) -{ - const struct wmfw_adsp_alg_data *raw; - - switch (dsp->fw_ver) { - case 0: - case 1: - raw = (const struct wmfw_adsp_alg_data *)*data; - *data = raw->data; - - blk->id = le32_to_cpu(raw->id); - blk->name = raw->name; - blk->name_len = strlen(raw->name); - blk->ncoeff = le32_to_cpu(raw->ncoeff); - break; - default: - blk->id = cs_dsp_coeff_parse_int(sizeof(raw->id), data); - blk->name_len = cs_dsp_coeff_parse_string(sizeof(u8), data, - &blk->name); - cs_dsp_coeff_parse_string(sizeof(u16), data, NULL); - blk->ncoeff = cs_dsp_coeff_parse_int(sizeof(raw->ncoeff), data); - break; - } - - cs_dsp_dbg(dsp, "Algorithm ID: %#x\n", blk->id); - cs_dsp_dbg(dsp, "Algorithm name: %.*s\n", blk->name_len, blk->name); - cs_dsp_dbg(dsp, "# of coefficient descriptors: %#x\n", blk->ncoeff); -} - -static inline void cs_dsp_coeff_parse_coeff(struct cs_dsp *dsp, const u8 **data, - struct cs_dsp_coeff_parsed_coeff *blk) -{ - const struct wmfw_adsp_coeff_data *raw; - const u8 *tmp; - int length; + if (dsp->component->name_prefix) + snprintf(ctl_name, SNDRV_CTL_ELEM_ID_NAME_MAXLEN, "%s %s", + dsp->component->name_prefix, ctl->name); + else + snprintf(ctl_name, SNDRV_CTL_ELEM_ID_NAME_MAXLEN, "%s", + ctl->name);
- switch (dsp->fw_ver) { - case 0: - case 1: - raw = (const struct wmfw_adsp_coeff_data *)*data; - *data = *data + sizeof(raw->hdr) + le32_to_cpu(raw->hdr.size); - - blk->offset = le16_to_cpu(raw->hdr.offset); - blk->mem_type = le16_to_cpu(raw->hdr.type); - blk->name = raw->name; - blk->name_len = strlen(raw->name); - blk->ctl_type = le16_to_cpu(raw->ctl_type); - blk->flags = le16_to_cpu(raw->flags); - blk->len = le32_to_cpu(raw->len); - break; - default: - tmp = *data; - blk->offset = cs_dsp_coeff_parse_int(sizeof(raw->hdr.offset), &tmp); - blk->mem_type = cs_dsp_coeff_parse_int(sizeof(raw->hdr.type), &tmp); - length = cs_dsp_coeff_parse_int(sizeof(raw->hdr.size), &tmp); - blk->name_len = cs_dsp_coeff_parse_string(sizeof(u8), &tmp, - &blk->name); - cs_dsp_coeff_parse_string(sizeof(u8), &tmp, NULL); - cs_dsp_coeff_parse_string(sizeof(u16), &tmp, NULL); - blk->ctl_type = cs_dsp_coeff_parse_int(sizeof(raw->ctl_type), &tmp); - blk->flags = cs_dsp_coeff_parse_int(sizeof(raw->flags), &tmp); - blk->len = cs_dsp_coeff_parse_int(sizeof(raw->len), &tmp); - - *data = *data + sizeof(raw->hdr) + length; - break; - } - - cs_dsp_dbg(dsp, "\tCoefficient type: %#x\n", blk->mem_type); - cs_dsp_dbg(dsp, "\tCoefficient offset: %#x\n", blk->offset); - cs_dsp_dbg(dsp, "\tCoefficient name: %.*s\n", blk->name_len, blk->name); - cs_dsp_dbg(dsp, "\tCoefficient flags: %#x\n", blk->flags); - cs_dsp_dbg(dsp, "\tALSA control type: %#x\n", blk->ctl_type); - cs_dsp_dbg(dsp, "\tALSA control len: %#x\n", blk->len); -} - -static int cs_dsp_check_coeff_flags(struct cs_dsp *dsp, - const struct cs_dsp_coeff_parsed_coeff *coeff_blk, - unsigned int f_required, - unsigned int f_illegal) -{ - if ((coeff_blk->flags & f_illegal) || - ((coeff_blk->flags & f_required) != f_required)) { - cs_dsp_err(dsp, "Illegal flags 0x%x for control type 0x%x\n", - coeff_blk->flags, coeff_blk->ctl_type); + kcontrol = snd_soc_card_get_kcontrol(dsp->component->card, ctl_name); + if (!kcontrol) { + adsp_err(dsp, "Can't find kcontrol %s\n", ctl_name); return -EINVAL; }
- return 0; -} - -static int cs_dsp_parse_coeff(struct cs_dsp *dsp, - const struct wmfw_region *region) -{ - struct cs_dsp_alg_region alg_region = {}; - struct cs_dsp_coeff_parsed_alg alg_blk; - struct cs_dsp_coeff_parsed_coeff coeff_blk; - const u8 *data = region->data; - int i, ret; - - cs_dsp_coeff_parse_alg(dsp, &data, &alg_blk); - for (i = 0; i < alg_blk.ncoeff; i++) { - cs_dsp_coeff_parse_coeff(dsp, &data, &coeff_blk); - - switch (coeff_blk.ctl_type) { - case WMFW_CTL_TYPE_BYTES: - break; - case WMFW_CTL_TYPE_ACKED: - if (coeff_blk.flags & WMFW_CTL_FLAG_SYS) - continue; /* ignore */ - - ret = cs_dsp_check_coeff_flags(dsp, &coeff_blk, - WMFW_CTL_FLAG_VOLATILE | - WMFW_CTL_FLAG_WRITEABLE | - WMFW_CTL_FLAG_READABLE, - 0); - if (ret) - return -EINVAL; - break; - case WMFW_CTL_TYPE_HOSTEVENT: - ret = cs_dsp_check_coeff_flags(dsp, &coeff_blk, - WMFW_CTL_FLAG_SYS | - WMFW_CTL_FLAG_VOLATILE | - WMFW_CTL_FLAG_WRITEABLE | - WMFW_CTL_FLAG_READABLE, - 0); - if (ret) - return -EINVAL; - break; - case WMFW_CTL_TYPE_HOST_BUFFER: - ret = cs_dsp_check_coeff_flags(dsp, &coeff_blk, - WMFW_CTL_FLAG_SYS | - WMFW_CTL_FLAG_VOLATILE | - WMFW_CTL_FLAG_READABLE, - 0); - if (ret) - return -EINVAL; - break; - default: - cs_dsp_err(dsp, "Unknown control type: %d\n", - coeff_blk.ctl_type); - return -EINVAL; - } - - alg_region.type = coeff_blk.mem_type; - alg_region.alg = alg_blk.id; - - ret = cs_dsp_create_control(dsp, &alg_region, - coeff_blk.offset, - coeff_blk.len, - coeff_blk.name, - coeff_blk.name_len, - coeff_blk.flags, - coeff_blk.ctl_type); - if (ret < 0) - cs_dsp_err(dsp, "Failed to create control: %.*s, %d\n", - coeff_blk.name_len, coeff_blk.name, ret); - } + snd_ctl_notify(dsp->component->card->snd_card, + SNDRV_CTL_EVENT_MASK_VALUE, &kcontrol->id);
return 0; } +EXPORT_SYMBOL_GPL(wm_adsp_write_ctl);
-static unsigned int cs_dsp_adsp1_parse_sizes(struct cs_dsp *dsp, - const char * const file, - unsigned int pos, - const struct firmware *firmware) +int wm_adsp_read_ctl(struct wm_adsp *dsp, const char *name, int type, + unsigned int alg, void *buf, size_t len) { - const struct wmfw_adsp1_sizes *adsp1_sizes; + struct cs_dsp_coeff_ctl *cs_ctl;
- adsp1_sizes = (void *)&firmware->data[pos]; + cs_ctl = cs_dsp_get_ctl(&dsp->cs_dsp, name, type, alg); + if (!cs_ctl) + return -EINVAL;
- cs_dsp_dbg(dsp, "%s: %d DM, %d PM, %d ZM\n", file, - le32_to_cpu(adsp1_sizes->dm), le32_to_cpu(adsp1_sizes->pm), - le32_to_cpu(adsp1_sizes->zm)); + if (len > cs_ctl->len) + return -EINVAL;
- return pos + sizeof(*adsp1_sizes); + return cs_dsp_coeff_read_ctrl(cs_ctl, buf, len); } +EXPORT_SYMBOL_GPL(wm_adsp_read_ctl);
static void wm_adsp_release_firmware_files(struct wm_adsp *dsp, const struct firmware *wmfw_firmware, @@ -1863,982 +798,6 @@ static int wm_adsp_request_firmware_files(struct wm_adsp *dsp, return 0; }
-static unsigned int cs_dsp_adsp2_parse_sizes(struct cs_dsp *dsp, - const char * const file, - unsigned int pos, - const struct firmware *firmware) -{ - const struct wmfw_adsp2_sizes *adsp2_sizes; - - adsp2_sizes = (void *)&firmware->data[pos]; - - cs_dsp_dbg(dsp, "%s: %d XM, %d YM %d PM, %d ZM\n", file, - le32_to_cpu(adsp2_sizes->xm), le32_to_cpu(adsp2_sizes->ym), - le32_to_cpu(adsp2_sizes->pm), le32_to_cpu(adsp2_sizes->zm)); - - return pos + sizeof(*adsp2_sizes); -} - -static bool cs_dsp_validate_version(struct cs_dsp *dsp, unsigned int version) -{ - switch (version) { - case 0: - cs_dsp_warn(dsp, "Deprecated file format %d\n", version); - return true; - case 1: - case 2: - return true; - default: - return false; - } -} - -static bool cs_dsp_halo_validate_version(struct cs_dsp *dsp, unsigned int version) -{ - switch (version) { - case 3: - return true; - default: - return false; - } -} - -static int cs_dsp_load(struct cs_dsp *dsp, const struct firmware *firmware, - const char *file) -{ - LIST_HEAD(buf_list); - struct regmap *regmap = dsp->regmap; - unsigned int pos = 0; - const struct wmfw_header *header; - const struct wmfw_adsp1_sizes *adsp1_sizes; - const struct wmfw_footer *footer; - const struct wmfw_region *region; - const struct cs_dsp_region *mem; - const char *region_name; - char *text = NULL; - struct cs_dsp_buf *buf; - unsigned int reg; - int regions = 0; - int ret, offset, type; - - ret = -EINVAL; - - pos = sizeof(*header) + sizeof(*adsp1_sizes) + sizeof(*footer); - if (pos >= firmware->size) { - cs_dsp_err(dsp, "%s: file too short, %zu bytes\n", - file, firmware->size); - goto out_fw; - } - - header = (void *)&firmware->data[0]; - - if (memcmp(&header->magic[0], "WMFW", 4) != 0) { - cs_dsp_err(dsp, "%s: invalid magic\n", file); - goto out_fw; - } - - if (!dsp->ops->validate_version(dsp, header->ver)) { - cs_dsp_err(dsp, "%s: unknown file format %d\n", - file, header->ver); - goto out_fw; - } - - cs_dsp_info(dsp, "Firmware version: %d\n", header->ver); - dsp->fw_ver = header->ver; - - if (header->core != dsp->type) { - cs_dsp_err(dsp, "%s: invalid core %d != %d\n", - file, header->core, dsp->type); - goto out_fw; - } - - pos = sizeof(*header); - pos = dsp->ops->parse_sizes(dsp, file, pos, firmware); - - footer = (void *)&firmware->data[pos]; - pos += sizeof(*footer); - - if (le32_to_cpu(header->len) != pos) { - cs_dsp_err(dsp, "%s: unexpected header length %d\n", - file, le32_to_cpu(header->len)); - goto out_fw; - } - - cs_dsp_dbg(dsp, "%s: timestamp %llu\n", file, - le64_to_cpu(footer->timestamp)); - - while (pos < firmware->size && - sizeof(*region) < firmware->size - pos) { - region = (void *)&(firmware->data[pos]); - region_name = "Unknown"; - reg = 0; - text = NULL; - offset = le32_to_cpu(region->offset) & 0xffffff; - type = be32_to_cpu(region->type) & 0xff; - - switch (type) { - case WMFW_NAME_TEXT: - region_name = "Firmware name"; - text = kzalloc(le32_to_cpu(region->len) + 1, - GFP_KERNEL); - break; - case WMFW_ALGORITHM_DATA: - region_name = "Algorithm"; - ret = cs_dsp_parse_coeff(dsp, region); - if (ret != 0) - goto out_fw; - break; - case WMFW_INFO_TEXT: - region_name = "Information"; - text = kzalloc(le32_to_cpu(region->len) + 1, - GFP_KERNEL); - break; - case WMFW_ABSOLUTE: - region_name = "Absolute"; - reg = offset; - break; - case WMFW_ADSP1_PM: - case WMFW_ADSP1_DM: - case WMFW_ADSP2_XM: - case WMFW_ADSP2_YM: - case WMFW_ADSP1_ZM: - case WMFW_HALO_PM_PACKED: - case WMFW_HALO_XM_PACKED: - case WMFW_HALO_YM_PACKED: - mem = cs_dsp_find_region(dsp, type); - if (!mem) { - cs_dsp_err(dsp, "No region of type: %x\n", type); - ret = -EINVAL; - goto out_fw; - } - - region_name = cs_dsp_mem_region_name(type); - reg = dsp->ops->region_to_reg(mem, offset); - break; - default: - cs_dsp_warn(dsp, - "%s.%d: Unknown region type %x at %d(%x)\n", - file, regions, type, pos, pos); - break; - } - - cs_dsp_dbg(dsp, "%s.%d: %d bytes at %d in %s\n", file, - regions, le32_to_cpu(region->len), offset, - region_name); - - if (le32_to_cpu(region->len) > - firmware->size - pos - sizeof(*region)) { - cs_dsp_err(dsp, - "%s.%d: %s region len %d bytes exceeds file length %zu\n", - file, regions, region_name, - le32_to_cpu(region->len), firmware->size); - ret = -EINVAL; - goto out_fw; - } - - if (text) { - memcpy(text, region->data, le32_to_cpu(region->len)); - cs_dsp_info(dsp, "%s: %s\n", file, text); - kfree(text); - text = NULL; - } - - if (reg) { - buf = cs_dsp_buf_alloc(region->data, - le32_to_cpu(region->len), - &buf_list); - if (!buf) { - cs_dsp_err(dsp, "Out of memory\n"); - ret = -ENOMEM; - goto out_fw; - } - - ret = regmap_raw_write_async(regmap, reg, buf->buf, - le32_to_cpu(region->len)); - if (ret != 0) { - cs_dsp_err(dsp, - "%s.%d: Failed to write %d bytes at %d in %s: %d\n", - file, regions, - le32_to_cpu(region->len), offset, - region_name, ret); - goto out_fw; - } - } - - pos += le32_to_cpu(region->len) + sizeof(*region); - regions++; - } - - ret = regmap_async_complete(regmap); - if (ret != 0) { - cs_dsp_err(dsp, "Failed to complete async write: %d\n", ret); - goto out_fw; - } - - if (pos > firmware->size) - cs_dsp_warn(dsp, "%s.%d: %zu bytes at end of file\n", - file, regions, pos - firmware->size); - - cs_dsp_debugfs_save_wmfwname(dsp, file); - -out_fw: - regmap_async_complete(regmap); - cs_dsp_buf_free(&buf_list); - kfree(text); - - return ret; -} - -/* - * Find cs_dsp_coeff_ctl with input name as its subname - * If not found, return NULL - */ -static struct cs_dsp_coeff_ctl *cs_dsp_get_ctl(struct cs_dsp *dsp, - const char *name, int type, - unsigned int alg) -{ - struct cs_dsp_coeff_ctl *pos, *rslt = NULL; - - list_for_each_entry(pos, &dsp->ctl_list, list) { - if (!pos->subname) - continue; - if (strncmp(pos->subname, name, pos->subname_len) == 0 && - pos->fw_name == dsp->fw_name && - pos->alg_region.alg == alg && - pos->alg_region.type == type) { - rslt = pos; - break; - } - } - - return rslt; -} - -int wm_adsp_write_ctl(struct wm_adsp *dsp, const char *name, int type, - unsigned int alg, void *buf, size_t len) -{ - struct cs_dsp_coeff_ctl *cs_ctl; - struct wm_coeff_ctl *ctl; - struct snd_kcontrol *kcontrol; - char ctl_name[SNDRV_CTL_ELEM_ID_NAME_MAXLEN]; - int ret; - - cs_ctl = cs_dsp_get_ctl(&dsp->cs_dsp, name, type, alg); - if (!cs_ctl) - return -EINVAL; - - ctl = cs_ctl->priv; - - if (len > cs_ctl->len) - return -EINVAL; - - ret = cs_dsp_coeff_write_ctrl(cs_ctl, buf, len); - if (ret) - return ret; - - if (cs_ctl->flags & WMFW_CTL_FLAG_SYS) - return 0; - - if (dsp->component->name_prefix) - snprintf(ctl_name, SNDRV_CTL_ELEM_ID_NAME_MAXLEN, "%s %s", - dsp->component->name_prefix, ctl->name); - else - snprintf(ctl_name, SNDRV_CTL_ELEM_ID_NAME_MAXLEN, "%s", - ctl->name); - - kcontrol = snd_soc_card_get_kcontrol(dsp->component->card, ctl_name); - if (!kcontrol) { - adsp_err(dsp, "Can't find kcontrol %s\n", ctl_name); - return -EINVAL; - } - - snd_ctl_notify(dsp->component->card->snd_card, - SNDRV_CTL_EVENT_MASK_VALUE, &kcontrol->id); - - return 0; -} -EXPORT_SYMBOL_GPL(wm_adsp_write_ctl); - -int wm_adsp_read_ctl(struct wm_adsp *dsp, const char *name, int type, - unsigned int alg, void *buf, size_t len) -{ - struct cs_dsp_coeff_ctl *cs_ctl; - - cs_ctl = cs_dsp_get_ctl(&dsp->cs_dsp, name, type, alg); - if (!cs_ctl) - return -EINVAL; - - if (len > cs_ctl->len) - return -EINVAL; - - return cs_dsp_coeff_read_ctrl(cs_ctl, buf, len); -} -EXPORT_SYMBOL_GPL(wm_adsp_read_ctl); - -static void cs_dsp_ctl_fixup_base(struct cs_dsp *dsp, - const struct cs_dsp_alg_region *alg_region) -{ - struct cs_dsp_coeff_ctl *ctl; - - list_for_each_entry(ctl, &dsp->ctl_list, list) { - if (ctl->fw_name == dsp->fw_name && - alg_region->alg == ctl->alg_region.alg && - alg_region->type == ctl->alg_region.type) { - ctl->alg_region.base = alg_region->base; - } - } -} - -static void *cs_dsp_read_algs(struct cs_dsp *dsp, size_t n_algs, - const struct cs_dsp_region *mem, - unsigned int pos, unsigned int len) -{ - void *alg; - unsigned int reg; - int ret; - __be32 val; - - if (n_algs == 0) { - cs_dsp_err(dsp, "No algorithms\n"); - return ERR_PTR(-EINVAL); - } - - if (n_algs > 1024) { - cs_dsp_err(dsp, "Algorithm count %zx excessive\n", n_algs); - return ERR_PTR(-EINVAL); - } - - /* Read the terminator first to validate the length */ - reg = dsp->ops->region_to_reg(mem, pos + len); - - ret = regmap_raw_read(dsp->regmap, reg, &val, sizeof(val)); - if (ret != 0) { - cs_dsp_err(dsp, "Failed to read algorithm list end: %d\n", - ret); - return ERR_PTR(ret); - } - - if (be32_to_cpu(val) != 0xbedead) - cs_dsp_warn(dsp, "Algorithm list end %x 0x%x != 0xbedead\n", - reg, be32_to_cpu(val)); - - /* Convert length from DSP words to bytes */ - len *= sizeof(u32); - - alg = kzalloc(len, GFP_KERNEL | GFP_DMA); - if (!alg) - return ERR_PTR(-ENOMEM); - - reg = dsp->ops->region_to_reg(mem, pos); - - ret = regmap_raw_read(dsp->regmap, reg, alg, len); - if (ret != 0) { - cs_dsp_err(dsp, "Failed to read algorithm list: %d\n", ret); - kfree(alg); - return ERR_PTR(ret); - } - - return alg; -} - -static struct cs_dsp_alg_region * - cs_dsp_find_alg_region(struct cs_dsp *dsp, int type, unsigned int id) -{ - struct cs_dsp_alg_region *alg_region; - - list_for_each_entry(alg_region, &dsp->alg_regions, list) { - if (id == alg_region->alg && type == alg_region->type) - return alg_region; - } - - return NULL; -} - -static struct cs_dsp_alg_region *cs_dsp_create_region(struct cs_dsp *dsp, - int type, __be32 id, - __be32 base) -{ - struct cs_dsp_alg_region *alg_region; - - alg_region = kzalloc(sizeof(*alg_region), GFP_KERNEL); - if (!alg_region) - return ERR_PTR(-ENOMEM); - - alg_region->type = type; - alg_region->alg = be32_to_cpu(id); - alg_region->base = be32_to_cpu(base); - - list_add_tail(&alg_region->list, &dsp->alg_regions); - - if (dsp->fw_ver > 0) - cs_dsp_ctl_fixup_base(dsp, alg_region); - - return alg_region; -} - -static void cs_dsp_free_alg_regions(struct cs_dsp *dsp) -{ - struct cs_dsp_alg_region *alg_region; - - while (!list_empty(&dsp->alg_regions)) { - alg_region = list_first_entry(&dsp->alg_regions, - struct cs_dsp_alg_region, - list); - list_del(&alg_region->list); - kfree(alg_region); - } -} - -static void cs_dsp_parse_wmfw_id_header(struct cs_dsp *dsp, - struct wmfw_id_hdr *fw, int nalgs) -{ - dsp->fw_id = be32_to_cpu(fw->id); - dsp->fw_id_version = be32_to_cpu(fw->ver); - - cs_dsp_info(dsp, "Firmware: %x v%d.%d.%d, %d algorithms\n", - dsp->fw_id, (dsp->fw_id_version & 0xff0000) >> 16, - (dsp->fw_id_version & 0xff00) >> 8, dsp->fw_id_version & 0xff, - nalgs); -} - -static void cs_dsp_parse_wmfw_v3_id_header(struct cs_dsp *dsp, - struct wmfw_v3_id_hdr *fw, int nalgs) -{ - dsp->fw_id = be32_to_cpu(fw->id); - dsp->fw_id_version = be32_to_cpu(fw->ver); - dsp->fw_vendor_id = be32_to_cpu(fw->vendor_id); - - cs_dsp_info(dsp, "Firmware: %x vendor: 0x%x v%d.%d.%d, %d algorithms\n", - dsp->fw_id, dsp->fw_vendor_id, - (dsp->fw_id_version & 0xff0000) >> 16, - (dsp->fw_id_version & 0xff00) >> 8, dsp->fw_id_version & 0xff, - nalgs); -} - -static int cs_dsp_create_regions(struct cs_dsp *dsp, __be32 id, int nregions, - const int *type, __be32 *base) -{ - struct cs_dsp_alg_region *alg_region; - int i; - - for (i = 0; i < nregions; i++) { - alg_region = cs_dsp_create_region(dsp, type[i], id, base[i]); - if (IS_ERR(alg_region)) - return PTR_ERR(alg_region); - } - - return 0; -} - -static int cs_dsp_adsp1_setup_algs(struct cs_dsp *dsp) -{ - struct wmfw_adsp1_id_hdr adsp1_id; - struct wmfw_adsp1_alg_hdr *adsp1_alg; - struct cs_dsp_alg_region *alg_region; - const struct cs_dsp_region *mem; - unsigned int pos, len; - size_t n_algs; - int i, ret; - - mem = cs_dsp_find_region(dsp, WMFW_ADSP1_DM); - if (WARN_ON(!mem)) - return -EINVAL; - - ret = regmap_raw_read(dsp->regmap, mem->base, &adsp1_id, - sizeof(adsp1_id)); - if (ret != 0) { - cs_dsp_err(dsp, "Failed to read algorithm info: %d\n", - ret); - return ret; - } - - n_algs = be32_to_cpu(adsp1_id.n_algs); - - cs_dsp_parse_wmfw_id_header(dsp, &adsp1_id.fw, n_algs); - - alg_region = cs_dsp_create_region(dsp, WMFW_ADSP1_ZM, - adsp1_id.fw.id, adsp1_id.zm); - if (IS_ERR(alg_region)) - return PTR_ERR(alg_region); - - alg_region = cs_dsp_create_region(dsp, WMFW_ADSP1_DM, - adsp1_id.fw.id, adsp1_id.dm); - if (IS_ERR(alg_region)) - return PTR_ERR(alg_region); - - /* Calculate offset and length in DSP words */ - pos = sizeof(adsp1_id) / sizeof(u32); - len = (sizeof(*adsp1_alg) * n_algs) / sizeof(u32); - - adsp1_alg = cs_dsp_read_algs(dsp, n_algs, mem, pos, len); - if (IS_ERR(adsp1_alg)) - return PTR_ERR(adsp1_alg); - - for (i = 0; i < n_algs; i++) { - cs_dsp_info(dsp, "%d: ID %x v%d.%d.%d DM@%x ZM@%x\n", - i, be32_to_cpu(adsp1_alg[i].alg.id), - (be32_to_cpu(adsp1_alg[i].alg.ver) & 0xff0000) >> 16, - (be32_to_cpu(adsp1_alg[i].alg.ver) & 0xff00) >> 8, - be32_to_cpu(adsp1_alg[i].alg.ver) & 0xff, - be32_to_cpu(adsp1_alg[i].dm), - be32_to_cpu(adsp1_alg[i].zm)); - - alg_region = cs_dsp_create_region(dsp, WMFW_ADSP1_DM, - adsp1_alg[i].alg.id, - adsp1_alg[i].dm); - if (IS_ERR(alg_region)) { - ret = PTR_ERR(alg_region); - goto out; - } - if (dsp->fw_ver == 0) { - if (i + 1 < n_algs) { - len = be32_to_cpu(adsp1_alg[i + 1].dm); - len -= be32_to_cpu(adsp1_alg[i].dm); - len *= 4; - cs_dsp_create_control(dsp, alg_region, 0, - len, NULL, 0, 0, - WMFW_CTL_TYPE_BYTES); - } else { - cs_dsp_warn(dsp, "Missing length info for region DM with ID %x\n", - be32_to_cpu(adsp1_alg[i].alg.id)); - } - } - - alg_region = cs_dsp_create_region(dsp, WMFW_ADSP1_ZM, - adsp1_alg[i].alg.id, - adsp1_alg[i].zm); - if (IS_ERR(alg_region)) { - ret = PTR_ERR(alg_region); - goto out; - } - if (dsp->fw_ver == 0) { - if (i + 1 < n_algs) { - len = be32_to_cpu(adsp1_alg[i + 1].zm); - len -= be32_to_cpu(adsp1_alg[i].zm); - len *= 4; - cs_dsp_create_control(dsp, alg_region, 0, - len, NULL, 0, 0, - WMFW_CTL_TYPE_BYTES); - } else { - cs_dsp_warn(dsp, "Missing length info for region ZM with ID %x\n", - be32_to_cpu(adsp1_alg[i].alg.id)); - } - } - } - -out: - kfree(adsp1_alg); - return ret; -} - -static int cs_dsp_adsp2_setup_algs(struct cs_dsp *dsp) -{ - struct wmfw_adsp2_id_hdr adsp2_id; - struct wmfw_adsp2_alg_hdr *adsp2_alg; - struct cs_dsp_alg_region *alg_region; - const struct cs_dsp_region *mem; - unsigned int pos, len; - size_t n_algs; - int i, ret; - - mem = cs_dsp_find_region(dsp, WMFW_ADSP2_XM); - if (WARN_ON(!mem)) - return -EINVAL; - - ret = regmap_raw_read(dsp->regmap, mem->base, &adsp2_id, - sizeof(adsp2_id)); - if (ret != 0) { - cs_dsp_err(dsp, "Failed to read algorithm info: %d\n", - ret); - return ret; - } - - n_algs = be32_to_cpu(adsp2_id.n_algs); - - cs_dsp_parse_wmfw_id_header(dsp, &adsp2_id.fw, n_algs); - - alg_region = cs_dsp_create_region(dsp, WMFW_ADSP2_XM, - adsp2_id.fw.id, adsp2_id.xm); - if (IS_ERR(alg_region)) - return PTR_ERR(alg_region); - - alg_region = cs_dsp_create_region(dsp, WMFW_ADSP2_YM, - adsp2_id.fw.id, adsp2_id.ym); - if (IS_ERR(alg_region)) - return PTR_ERR(alg_region); - - alg_region = cs_dsp_create_region(dsp, WMFW_ADSP2_ZM, - adsp2_id.fw.id, adsp2_id.zm); - if (IS_ERR(alg_region)) - return PTR_ERR(alg_region); - - /* Calculate offset and length in DSP words */ - pos = sizeof(adsp2_id) / sizeof(u32); - len = (sizeof(*adsp2_alg) * n_algs) / sizeof(u32); - - adsp2_alg = cs_dsp_read_algs(dsp, n_algs, mem, pos, len); - if (IS_ERR(adsp2_alg)) - return PTR_ERR(adsp2_alg); - - for (i = 0; i < n_algs; i++) { - cs_dsp_info(dsp, - "%d: ID %x v%d.%d.%d XM@%x YM@%x ZM@%x\n", - i, be32_to_cpu(adsp2_alg[i].alg.id), - (be32_to_cpu(adsp2_alg[i].alg.ver) & 0xff0000) >> 16, - (be32_to_cpu(adsp2_alg[i].alg.ver) & 0xff00) >> 8, - be32_to_cpu(adsp2_alg[i].alg.ver) & 0xff, - be32_to_cpu(adsp2_alg[i].xm), - be32_to_cpu(adsp2_alg[i].ym), - be32_to_cpu(adsp2_alg[i].zm)); - - alg_region = cs_dsp_create_region(dsp, WMFW_ADSP2_XM, - adsp2_alg[i].alg.id, - adsp2_alg[i].xm); - if (IS_ERR(alg_region)) { - ret = PTR_ERR(alg_region); - goto out; - } - if (dsp->fw_ver == 0) { - if (i + 1 < n_algs) { - len = be32_to_cpu(adsp2_alg[i + 1].xm); - len -= be32_to_cpu(adsp2_alg[i].xm); - len *= 4; - cs_dsp_create_control(dsp, alg_region, 0, - len, NULL, 0, 0, - WMFW_CTL_TYPE_BYTES); - } else { - cs_dsp_warn(dsp, "Missing length info for region XM with ID %x\n", - be32_to_cpu(adsp2_alg[i].alg.id)); - } - } - - alg_region = cs_dsp_create_region(dsp, WMFW_ADSP2_YM, - adsp2_alg[i].alg.id, - adsp2_alg[i].ym); - if (IS_ERR(alg_region)) { - ret = PTR_ERR(alg_region); - goto out; - } - if (dsp->fw_ver == 0) { - if (i + 1 < n_algs) { - len = be32_to_cpu(adsp2_alg[i + 1].ym); - len -= be32_to_cpu(adsp2_alg[i].ym); - len *= 4; - cs_dsp_create_control(dsp, alg_region, 0, - len, NULL, 0, 0, - WMFW_CTL_TYPE_BYTES); - } else { - cs_dsp_warn(dsp, "Missing length info for region YM with ID %x\n", - be32_to_cpu(adsp2_alg[i].alg.id)); - } - } - - alg_region = cs_dsp_create_region(dsp, WMFW_ADSP2_ZM, - adsp2_alg[i].alg.id, - adsp2_alg[i].zm); - if (IS_ERR(alg_region)) { - ret = PTR_ERR(alg_region); - goto out; - } - if (dsp->fw_ver == 0) { - if (i + 1 < n_algs) { - len = be32_to_cpu(adsp2_alg[i + 1].zm); - len -= be32_to_cpu(adsp2_alg[i].zm); - len *= 4; - cs_dsp_create_control(dsp, alg_region, 0, - len, NULL, 0, 0, - WMFW_CTL_TYPE_BYTES); - } else { - cs_dsp_warn(dsp, "Missing length info for region ZM with ID %x\n", - be32_to_cpu(adsp2_alg[i].alg.id)); - } - } - } - -out: - kfree(adsp2_alg); - return ret; -} - -static int cs_dsp_halo_create_regions(struct cs_dsp *dsp, __be32 id, - __be32 xm_base, __be32 ym_base) -{ - static const int types[] = { - WMFW_ADSP2_XM, WMFW_HALO_XM_PACKED, - WMFW_ADSP2_YM, WMFW_HALO_YM_PACKED - }; - __be32 bases[] = { xm_base, xm_base, ym_base, ym_base }; - - return cs_dsp_create_regions(dsp, id, ARRAY_SIZE(types), types, bases); -} - -static int cs_dsp_halo_setup_algs(struct cs_dsp *dsp) -{ - struct wmfw_halo_id_hdr halo_id; - struct wmfw_halo_alg_hdr *halo_alg; - const struct cs_dsp_region *mem; - unsigned int pos, len; - size_t n_algs; - int i, ret; - - mem = cs_dsp_find_region(dsp, WMFW_ADSP2_XM); - if (WARN_ON(!mem)) - return -EINVAL; - - ret = regmap_raw_read(dsp->regmap, mem->base, &halo_id, - sizeof(halo_id)); - if (ret != 0) { - cs_dsp_err(dsp, "Failed to read algorithm info: %d\n", - ret); - return ret; - } - - n_algs = be32_to_cpu(halo_id.n_algs); - - cs_dsp_parse_wmfw_v3_id_header(dsp, &halo_id.fw, n_algs); - - ret = cs_dsp_halo_create_regions(dsp, halo_id.fw.id, - halo_id.xm_base, halo_id.ym_base); - if (ret) - return ret; - - /* Calculate offset and length in DSP words */ - pos = sizeof(halo_id) / sizeof(u32); - len = (sizeof(*halo_alg) * n_algs) / sizeof(u32); - - halo_alg = cs_dsp_read_algs(dsp, n_algs, mem, pos, len); - if (IS_ERR(halo_alg)) - return PTR_ERR(halo_alg); - - for (i = 0; i < n_algs; i++) { - cs_dsp_info(dsp, - "%d: ID %x v%d.%d.%d XM@%x YM@%x\n", - i, be32_to_cpu(halo_alg[i].alg.id), - (be32_to_cpu(halo_alg[i].alg.ver) & 0xff0000) >> 16, - (be32_to_cpu(halo_alg[i].alg.ver) & 0xff00) >> 8, - be32_to_cpu(halo_alg[i].alg.ver) & 0xff, - be32_to_cpu(halo_alg[i].xm_base), - be32_to_cpu(halo_alg[i].ym_base)); - - ret = cs_dsp_halo_create_regions(dsp, halo_alg[i].alg.id, - halo_alg[i].xm_base, - halo_alg[i].ym_base); - if (ret) - goto out; - } - -out: - kfree(halo_alg); - return ret; -} - -static int cs_dsp_load_coeff(struct cs_dsp *dsp, const struct firmware *firmware, - const char *file) -{ - LIST_HEAD(buf_list); - struct regmap *regmap = dsp->regmap; - struct wmfw_coeff_hdr *hdr; - struct wmfw_coeff_item *blk; - const struct cs_dsp_region *mem; - struct cs_dsp_alg_region *alg_region; - const char *region_name; - int ret, pos, blocks, type, offset, reg; - struct cs_dsp_buf *buf; - - if (!firmware) - return 0; - - ret = -EINVAL; - - if (sizeof(*hdr) >= firmware->size) { - cs_dsp_err(dsp, "%s: coefficient file too short, %zu bytes\n", - file, firmware->size); - goto out_fw; - } - - hdr = (void *)&firmware->data[0]; - if (memcmp(hdr->magic, "WMDR", 4) != 0) { - cs_dsp_err(dsp, "%s: invalid coefficient magic\n", file); - goto out_fw; - } - - switch (be32_to_cpu(hdr->rev) & 0xff) { - case 1: - break; - default: - cs_dsp_err(dsp, "%s: Unsupported coefficient file format %d\n", - file, be32_to_cpu(hdr->rev) & 0xff); - ret = -EINVAL; - goto out_fw; - } - - cs_dsp_dbg(dsp, "%s: v%d.%d.%d\n", file, - (le32_to_cpu(hdr->ver) >> 16) & 0xff, - (le32_to_cpu(hdr->ver) >> 8) & 0xff, - le32_to_cpu(hdr->ver) & 0xff); - - pos = le32_to_cpu(hdr->len); - - blocks = 0; - while (pos < firmware->size && - sizeof(*blk) < firmware->size - pos) { - blk = (void *)(&firmware->data[pos]); - - type = le16_to_cpu(blk->type); - offset = le16_to_cpu(blk->offset); - - cs_dsp_dbg(dsp, "%s.%d: %x v%d.%d.%d\n", - file, blocks, le32_to_cpu(blk->id), - (le32_to_cpu(blk->ver) >> 16) & 0xff, - (le32_to_cpu(blk->ver) >> 8) & 0xff, - le32_to_cpu(blk->ver) & 0xff); - cs_dsp_dbg(dsp, "%s.%d: %d bytes at 0x%x in %x\n", - file, blocks, le32_to_cpu(blk->len), offset, type); - - reg = 0; - region_name = "Unknown"; - switch (type) { - case (WMFW_NAME_TEXT << 8): - case (WMFW_INFO_TEXT << 8): - case (WMFW_METADATA << 8): - break; - case (WMFW_ABSOLUTE << 8): - /* - * Old files may use this for global - * coefficients. - */ - if (le32_to_cpu(blk->id) == dsp->fw_id && - offset == 0) { - region_name = "global coefficients"; - mem = cs_dsp_find_region(dsp, type); - if (!mem) { - cs_dsp_err(dsp, "No ZM\n"); - break; - } - reg = dsp->ops->region_to_reg(mem, 0); - - } else { - region_name = "register"; - reg = offset; - } - break; - - case WMFW_ADSP1_DM: - case WMFW_ADSP1_ZM: - case WMFW_ADSP2_XM: - case WMFW_ADSP2_YM: - case WMFW_HALO_XM_PACKED: - case WMFW_HALO_YM_PACKED: - case WMFW_HALO_PM_PACKED: - cs_dsp_dbg(dsp, "%s.%d: %d bytes in %x for %x\n", - file, blocks, le32_to_cpu(blk->len), - type, le32_to_cpu(blk->id)); - - mem = cs_dsp_find_region(dsp, type); - if (!mem) { - cs_dsp_err(dsp, "No base for region %x\n", type); - break; - } - - alg_region = cs_dsp_find_alg_region(dsp, type, - le32_to_cpu(blk->id)); - if (alg_region) { - reg = alg_region->base; - reg = dsp->ops->region_to_reg(mem, reg); - reg += offset; - } else { - cs_dsp_err(dsp, "No %x for algorithm %x\n", - type, le32_to_cpu(blk->id)); - } - break; - - default: - cs_dsp_err(dsp, "%s.%d: Unknown region type %x at %d\n", - file, blocks, type, pos); - break; - } - - if (reg) { - if (le32_to_cpu(blk->len) > - firmware->size - pos - sizeof(*blk)) { - cs_dsp_err(dsp, - "%s.%d: %s region len %d bytes exceeds file length %zu\n", - file, blocks, region_name, - le32_to_cpu(blk->len), - firmware->size); - ret = -EINVAL; - goto out_fw; - } - - buf = cs_dsp_buf_alloc(blk->data, - le32_to_cpu(blk->len), - &buf_list); - if (!buf) { - cs_dsp_err(dsp, "Out of memory\n"); - ret = -ENOMEM; - goto out_fw; - } - - cs_dsp_dbg(dsp, "%s.%d: Writing %d bytes at %x\n", - file, blocks, le32_to_cpu(blk->len), - reg); - ret = regmap_raw_write_async(regmap, reg, buf->buf, - le32_to_cpu(blk->len)); - if (ret != 0) { - cs_dsp_err(dsp, - "%s.%d: Failed to write to %x in %s: %d\n", - file, blocks, reg, region_name, ret); - } - } - - pos += (le32_to_cpu(blk->len) + sizeof(*blk) + 3) & ~0x03; - blocks++; - } - - ret = regmap_async_complete(regmap); - if (ret != 0) - cs_dsp_err(dsp, "Failed to complete async write: %d\n", ret); - - if (pos > firmware->size) - cs_dsp_warn(dsp, "%s.%d: %zu bytes at end of file\n", - file, blocks, pos - firmware->size); - - cs_dsp_debugfs_save_binname(dsp, file); - -out_fw: - regmap_async_complete(regmap); - cs_dsp_buf_free(&buf_list); - return ret; -} - -static int cs_dsp_create_name(struct cs_dsp *dsp) -{ - if (!dsp->name) { - dsp->name = devm_kasprintf(dsp->dev, GFP_KERNEL, "DSP%d", - dsp->num); - if (!dsp->name) - return -ENOMEM; - } - - return 0; -} - -static int cs_dsp_common_init(struct cs_dsp *dsp) -{ - int ret; - - ret = cs_dsp_create_name(dsp); - if (ret) - return ret; - - INIT_LIST_HEAD(&dsp->alg_regions); - INIT_LIST_HEAD(&dsp->ctl_list); - - mutex_init(&dsp->pwr_lock); - - return 0; -} - static int wm_adsp_common_init(struct wm_adsp *dsp) { char *p; @@ -2859,13 +818,6 @@ static int wm_adsp_common_init(struct wm_adsp *dsp) return 0; }
-static int cs_dsp_adsp1_init(struct cs_dsp *dsp) -{ - dsp->ops = &cs_dsp_adsp1_ops; - - return cs_dsp_common_init(dsp); -} - int wm_adsp1_init(struct wm_adsp *dsp) { int ret; @@ -2880,113 +832,6 @@ int wm_adsp1_init(struct wm_adsp *dsp) } EXPORT_SYMBOL_GPL(wm_adsp1_init);
-static int cs_dsp_adsp1_power_up(struct cs_dsp *dsp, - const struct firmware *wmfw_firmware, char *wmfw_filename, - const struct firmware *coeff_firmware, char *coeff_filename, - const char *fw_name) -{ - unsigned int val; - int ret; - - mutex_lock(&dsp->pwr_lock); - - dsp->fw_name = fw_name; - - regmap_update_bits(dsp->regmap, dsp->base + ADSP1_CONTROL_30, - ADSP1_SYS_ENA, ADSP1_SYS_ENA); - - /* - * For simplicity set the DSP clock rate to be the - * SYSCLK rate rather than making it configurable. - */ - if (dsp->sysclk_reg) { - ret = regmap_read(dsp->regmap, dsp->sysclk_reg, &val); - if (ret != 0) { - cs_dsp_err(dsp, "Failed to read SYSCLK state: %d\n", ret); - goto err_mutex; - } - - val = (val & dsp->sysclk_mask) >> dsp->sysclk_shift; - - ret = regmap_update_bits(dsp->regmap, - dsp->base + ADSP1_CONTROL_31, - ADSP1_CLK_SEL_MASK, val); - if (ret != 0) { - cs_dsp_err(dsp, "Failed to set clock rate: %d\n", ret); - goto err_mutex; - } - } - - ret = cs_dsp_load(dsp, wmfw_firmware, wmfw_filename); - if (ret != 0) - goto err_ena; - - ret = cs_dsp_adsp1_setup_algs(dsp); - if (ret != 0) - goto err_ena; - - ret = cs_dsp_load_coeff(dsp, coeff_firmware, coeff_filename); - if (ret != 0) - goto err_ena; - - /* Initialize caches for enabled and unset controls */ - ret = cs_dsp_coeff_init_control_caches(dsp); - if (ret != 0) - goto err_ena; - - /* Sync set controls */ - ret = cs_dsp_coeff_sync_controls(dsp); - if (ret != 0) - goto err_ena; - - dsp->booted = true; - - /* Start the core running */ - regmap_update_bits(dsp->regmap, dsp->base + ADSP1_CONTROL_30, - ADSP1_CORE_ENA | ADSP1_START, - ADSP1_CORE_ENA | ADSP1_START); - - dsp->running = true; - - mutex_unlock(&dsp->pwr_lock); - - return 0; - -err_ena: - regmap_update_bits(dsp->regmap, dsp->base + ADSP1_CONTROL_30, - ADSP1_SYS_ENA, 0); -err_mutex: - mutex_unlock(&dsp->pwr_lock); - return ret; -} - -static void cs_dsp_adsp1_power_down(struct cs_dsp *dsp) -{ - struct cs_dsp_coeff_ctl *ctl; - - mutex_lock(&dsp->pwr_lock); - - dsp->running = false; - dsp->booted = false; - - /* Halt the core */ - regmap_update_bits(dsp->regmap, dsp->base + ADSP1_CONTROL_30, - ADSP1_CORE_ENA | ADSP1_START, 0); - - regmap_update_bits(dsp->regmap, dsp->base + ADSP1_CONTROL_19, - ADSP1_WDMA_BUFFER_LENGTH_MASK, 0); - - regmap_update_bits(dsp->regmap, dsp->base + ADSP1_CONTROL_30, - ADSP1_SYS_ENA, 0); - - list_for_each_entry(ctl, &dsp->ctl_list, list) - ctl->enabled = 0; - - cs_dsp_free_alg_regions(dsp); - - mutex_unlock(&dsp->pwr_lock); -} - int wm_adsp1_event(struct snd_soc_dapm_widget *w, struct snd_kcontrol *kcontrol, int event) @@ -3030,148 +875,6 @@ int wm_adsp1_event(struct snd_soc_dapm_widget *w, } EXPORT_SYMBOL_GPL(wm_adsp1_event);
-static int cs_dsp_adsp2v2_enable_core(struct cs_dsp *dsp) -{ - unsigned int val; - int ret, count; - - /* Wait for the RAM to start, should be near instantaneous */ - for (count = 0; count < 10; ++count) { - ret = regmap_read(dsp->regmap, dsp->base + ADSP2_STATUS1, &val); - if (ret != 0) - return ret; - - if (val & ADSP2_RAM_RDY) - break; - - usleep_range(250, 500); - } - - if (!(val & ADSP2_RAM_RDY)) { - cs_dsp_err(dsp, "Failed to start DSP RAM\n"); - return -EBUSY; - } - - cs_dsp_dbg(dsp, "RAM ready after %d polls\n", count); - - return 0; -} - -static int cs_dsp_adsp2_enable_core(struct cs_dsp *dsp) -{ - int ret; - - ret = regmap_update_bits_async(dsp->regmap, dsp->base + ADSP2_CONTROL, - ADSP2_SYS_ENA, ADSP2_SYS_ENA); - if (ret != 0) - return ret; - - return cs_dsp_adsp2v2_enable_core(dsp); -} - -static int cs_dsp_adsp2_lock(struct cs_dsp *dsp, unsigned int lock_regions) -{ - struct regmap *regmap = dsp->regmap; - unsigned int code0, code1, lock_reg; - - if (!(lock_regions & CS_ADSP2_REGION_ALL)) - return 0; - - lock_regions &= CS_ADSP2_REGION_ALL; - lock_reg = dsp->base + ADSP2_LOCK_REGION_1_LOCK_REGION_0; - - while (lock_regions) { - code0 = code1 = 0; - if (lock_regions & BIT(0)) { - code0 = ADSP2_LOCK_CODE_0; - code1 = ADSP2_LOCK_CODE_1; - } - if (lock_regions & BIT(1)) { - code0 |= ADSP2_LOCK_CODE_0 << ADSP2_LOCK_REGION_SHIFT; - code1 |= ADSP2_LOCK_CODE_1 << ADSP2_LOCK_REGION_SHIFT; - } - regmap_write(regmap, lock_reg, code0); - regmap_write(regmap, lock_reg, code1); - lock_regions >>= 2; - lock_reg += 2; - } - - return 0; -} - -static int cs_dsp_adsp2_enable_memory(struct cs_dsp *dsp) -{ - return regmap_update_bits(dsp->regmap, dsp->base + ADSP2_CONTROL, - ADSP2_MEM_ENA, ADSP2_MEM_ENA); -} - -static void cs_dsp_adsp2_disable_memory(struct cs_dsp *dsp) -{ - regmap_update_bits(dsp->regmap, dsp->base + ADSP2_CONTROL, - ADSP2_MEM_ENA, 0); -} - -static void cs_dsp_adsp2_disable_core(struct cs_dsp *dsp) -{ - regmap_write(dsp->regmap, dsp->base + ADSP2_RDMA_CONFIG_1, 0); - regmap_write(dsp->regmap, dsp->base + ADSP2_WDMA_CONFIG_1, 0); - regmap_write(dsp->regmap, dsp->base + ADSP2_WDMA_CONFIG_2, 0); - - regmap_update_bits(dsp->regmap, dsp->base + ADSP2_CONTROL, - ADSP2_SYS_ENA, 0); -} - -static void cs_dsp_adsp2v2_disable_core(struct cs_dsp *dsp) -{ - regmap_write(dsp->regmap, dsp->base + ADSP2_RDMA_CONFIG_1, 0); - regmap_write(dsp->regmap, dsp->base + ADSP2_WDMA_CONFIG_1, 0); - regmap_write(dsp->regmap, dsp->base + ADSP2V2_WDMA_CONFIG_2, 0); -} - -static int cs_dsp_halo_configure_mpu(struct cs_dsp *dsp, unsigned int lock_regions) -{ - struct reg_sequence config[] = { - { dsp->base + HALO_MPU_LOCK_CONFIG, 0x5555 }, - { dsp->base + HALO_MPU_LOCK_CONFIG, 0xAAAA }, - { dsp->base + HALO_MPU_XMEM_ACCESS_0, 0xFFFFFFFF }, - { dsp->base + HALO_MPU_YMEM_ACCESS_0, 0xFFFFFFFF }, - { dsp->base + HALO_MPU_WINDOW_ACCESS_0, lock_regions }, - { dsp->base + HALO_MPU_XREG_ACCESS_0, lock_regions }, - { dsp->base + HALO_MPU_YREG_ACCESS_0, lock_regions }, - { dsp->base + HALO_MPU_XMEM_ACCESS_1, 0xFFFFFFFF }, - { dsp->base + HALO_MPU_YMEM_ACCESS_1, 0xFFFFFFFF }, - { dsp->base + HALO_MPU_WINDOW_ACCESS_1, lock_regions }, - { dsp->base + HALO_MPU_XREG_ACCESS_1, lock_regions }, - { dsp->base + HALO_MPU_YREG_ACCESS_1, lock_regions }, - { dsp->base + HALO_MPU_XMEM_ACCESS_2, 0xFFFFFFFF }, - { dsp->base + HALO_MPU_YMEM_ACCESS_2, 0xFFFFFFFF }, - { dsp->base + HALO_MPU_WINDOW_ACCESS_2, lock_regions }, - { dsp->base + HALO_MPU_XREG_ACCESS_2, lock_regions }, - { dsp->base + HALO_MPU_YREG_ACCESS_2, lock_regions }, - { dsp->base + HALO_MPU_XMEM_ACCESS_3, 0xFFFFFFFF }, - { dsp->base + HALO_MPU_YMEM_ACCESS_3, 0xFFFFFFFF }, - { dsp->base + HALO_MPU_WINDOW_ACCESS_3, lock_regions }, - { dsp->base + HALO_MPU_XREG_ACCESS_3, lock_regions }, - { dsp->base + HALO_MPU_YREG_ACCESS_3, lock_regions }, - { dsp->base + HALO_MPU_LOCK_CONFIG, 0 }, - }; - - return regmap_multi_reg_write(dsp->regmap, config, ARRAY_SIZE(config)); -} - -static int cs_dsp_set_dspclk(struct cs_dsp *dsp, unsigned int freq) -{ - int ret; - - ret = regmap_update_bits(dsp->regmap, dsp->base + ADSP2_CLOCKING, - ADSP2_CLK_SEL_MASK, - freq << ADSP2_CLK_SEL_SHIFT); - if (ret) - cs_dsp_err(dsp, "Failed to set clock rate: %d\n", ret); - - return ret; -} - int wm_adsp2_set_dspclk(struct snd_soc_dapm_widget *w, unsigned int freq) { struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm); @@ -3225,104 +928,6 @@ int wm_adsp2_preloader_put(struct snd_kcontrol *kcontrol, } EXPORT_SYMBOL_GPL(wm_adsp2_preloader_put);
-static void cs_dsp_stop_watchdog(struct cs_dsp *dsp) -{ - regmap_update_bits(dsp->regmap, dsp->base + ADSP2_WATCHDOG, - ADSP2_WDT_ENA_MASK, 0); -} - -static void cs_dsp_halo_stop_watchdog(struct cs_dsp *dsp) -{ - regmap_update_bits(dsp->regmap, dsp->base + HALO_WDT_CONTROL, - HALO_WDT_EN_MASK, 0); -} - -static int cs_dsp_power_up(struct cs_dsp *dsp, - const struct firmware *wmfw_firmware, char *wmfw_filename, - const struct firmware *coeff_firmware, char *coeff_filename, - const char *fw_name) -{ - int ret; - - mutex_lock(&dsp->pwr_lock); - - dsp->fw_name = fw_name; - - if (dsp->ops->enable_memory) { - ret = dsp->ops->enable_memory(dsp); - if (ret != 0) - goto err_mutex; - } - - if (dsp->ops->enable_core) { - ret = dsp->ops->enable_core(dsp); - if (ret != 0) - goto err_mem; - } - - ret = cs_dsp_load(dsp, wmfw_firmware, wmfw_filename); - if (ret != 0) - goto err_ena; - - ret = dsp->ops->setup_algs(dsp); - if (ret != 0) - goto err_ena; - - ret = cs_dsp_load_coeff(dsp, coeff_firmware, coeff_filename); - if (ret != 0) - goto err_ena; - - /* Initialize caches for enabled and unset controls */ - ret = cs_dsp_coeff_init_control_caches(dsp); - if (ret != 0) - goto err_ena; - - if (dsp->ops->disable_core) - dsp->ops->disable_core(dsp); - - dsp->booted = true; - - mutex_unlock(&dsp->pwr_lock); - - return 0; -err_ena: - if (dsp->ops->disable_core) - dsp->ops->disable_core(dsp); -err_mem: - if (dsp->ops->disable_memory) - dsp->ops->disable_memory(dsp); -err_mutex: - mutex_unlock(&dsp->pwr_lock); - - return ret; -} - -static void cs_dsp_power_down(struct cs_dsp *dsp) -{ - struct cs_dsp_coeff_ctl *ctl; - - mutex_lock(&dsp->pwr_lock); - - cs_dsp_debugfs_clear(dsp); - - dsp->fw_id = 0; - dsp->fw_id_version = 0; - - dsp->booted = false; - - if (dsp->ops->disable_memory) - dsp->ops->disable_memory(dsp); - - list_for_each_entry(ctl, &dsp->ctl_list, list) - ctl->enabled = 0; - - cs_dsp_free_alg_regions(dsp); - - mutex_unlock(&dsp->pwr_lock); - - cs_dsp_dbg(dsp, "Shutdown complete\n"); -} - static void wm_adsp_boot_work(struct work_struct *work) { struct wm_adsp *dsp = container_of(work, @@ -3372,19 +977,6 @@ int wm_adsp_early_event(struct snd_soc_dapm_widget *w, } EXPORT_SYMBOL_GPL(wm_adsp_early_event);
-static int cs_dsp_adsp2_start_core(struct cs_dsp *dsp) -{ - return regmap_update_bits(dsp->regmap, dsp->base + ADSP2_CONTROL, - ADSP2_CORE_ENA | ADSP2_START, - ADSP2_CORE_ENA | ADSP2_START); -} - -static void cs_dsp_adsp2_stop_core(struct cs_dsp *dsp) -{ - regmap_update_bits(dsp->regmap, dsp->base + ADSP2_CONTROL, - ADSP2_CORE_ENA | ADSP2_START, 0); -} - static int wm_adsp_event_post_run(struct cs_dsp *cs_dsp) { struct wm_adsp *dsp = container_of(cs_dsp, struct wm_adsp, cs_dsp); @@ -3405,93 +997,6 @@ static void wm_adsp_event_post_stop(struct cs_dsp *cs_dsp) dsp->fatal_error = false; }
-static int cs_dsp_run(struct cs_dsp *dsp) -{ - int ret; - - mutex_lock(&dsp->pwr_lock); - - if (!dsp->booted) { - ret = -EIO; - goto err; - } - - if (dsp->ops->enable_core) { - ret = dsp->ops->enable_core(dsp); - if (ret != 0) - goto err; - } - - /* Sync set controls */ - ret = cs_dsp_coeff_sync_controls(dsp); - if (ret != 0) - goto err; - - if (dsp->ops->lock_memory) { - ret = dsp->ops->lock_memory(dsp, dsp->lock_regions); - if (ret != 0) { - cs_dsp_err(dsp, "Error configuring MPU: %d\n", ret); - goto err; - } - } - - if (dsp->ops->start_core) { - ret = dsp->ops->start_core(dsp); - if (ret != 0) - goto err; - } - - dsp->running = true; - - if (dsp->client_ops->post_run) { - ret = dsp->client_ops->post_run(dsp); - if (ret) - goto err; - } - - mutex_unlock(&dsp->pwr_lock); - - return 0; - -err: - if (dsp->ops->stop_core) - dsp->ops->stop_core(dsp); - if (dsp->ops->disable_core) - dsp->ops->disable_core(dsp); - mutex_unlock(&dsp->pwr_lock); - - return ret; -} - -static void cs_dsp_stop(struct cs_dsp *dsp) -{ - /* Tell the firmware to cleanup */ - cs_dsp_signal_event_controls(dsp, CS_DSP_FW_EVENT_SHUTDOWN); - - if (dsp->ops->stop_watchdog) - dsp->ops->stop_watchdog(dsp); - - /* Log firmware state, it can be useful for analysis */ - if (dsp->ops->show_fw_status) - dsp->ops->show_fw_status(dsp); - - mutex_lock(&dsp->pwr_lock); - - dsp->running = false; - - if (dsp->ops->stop_core) - dsp->ops->stop_core(dsp); - if (dsp->ops->disable_core) - dsp->ops->disable_core(dsp); - - if (dsp->client_ops->post_stop) - dsp->client_ops->post_stop(dsp); - - mutex_unlock(&dsp->pwr_lock); - - cs_dsp_dbg(dsp, "Execution stopped\n"); -} - int wm_adsp_event(struct snd_soc_dapm_widget *w, struct snd_kcontrol *kcontrol, int event) { @@ -3516,24 +1021,6 @@ int wm_adsp_event(struct snd_soc_dapm_widget *w, } EXPORT_SYMBOL_GPL(wm_adsp_event);
-static int cs_dsp_halo_start_core(struct cs_dsp *dsp) -{ - return regmap_update_bits(dsp->regmap, - dsp->base + HALO_CCM_CORE_CONTROL, - HALO_CORE_RESET | HALO_CORE_EN, - HALO_CORE_RESET | HALO_CORE_EN); -} - -static void cs_dsp_halo_stop_core(struct cs_dsp *dsp) -{ - regmap_update_bits(dsp->regmap, dsp->base + HALO_CCM_CORE_CONTROL, - HALO_CORE_EN, 0); - - /* reset halo core with CORE_SOFT_RESET */ - regmap_update_bits(dsp->regmap, dsp->base + HALO_CORE_SOFT_RESET, - HALO_CORE_SOFT_RESET_MASK, 1); -} - int wm_adsp2_component_probe(struct wm_adsp *dsp, struct snd_soc_component *component) { char preload[32]; @@ -3557,37 +1044,6 @@ int wm_adsp2_component_remove(struct wm_adsp *dsp, struct snd_soc_component *com } EXPORT_SYMBOL_GPL(wm_adsp2_component_remove);
-static int cs_dsp_adsp2_init(struct cs_dsp *dsp) -{ - int ret; - - switch (dsp->rev) { - case 0: - /* - * Disable the DSP memory by default when in reset for a small - * power saving. - */ - ret = regmap_update_bits(dsp->regmap, dsp->base + ADSP2_CONTROL, - ADSP2_MEM_ENA, 0); - if (ret) { - cs_dsp_err(dsp, - "Failed to clear memory retention: %d\n", ret); - return ret; - } - - dsp->ops = &cs_dsp_adsp2_ops[0]; - break; - case 1: - dsp->ops = &cs_dsp_adsp2_ops[1]; - break; - default: - dsp->ops = &cs_dsp_adsp2_ops[2]; - break; - } - - return cs_dsp_common_init(dsp); -} - int wm_adsp2_init(struct wm_adsp *dsp) { int ret; @@ -3605,13 +1061,6 @@ int wm_adsp2_init(struct wm_adsp *dsp) } EXPORT_SYMBOL_GPL(wm_adsp2_init);
-static int cs_dsp_halo_init(struct cs_dsp *dsp) -{ - dsp->ops = &cs_dsp_halo_ops; - - return cs_dsp_common_init(dsp); -} - int wm_halo_init(struct wm_adsp *dsp) { int ret; @@ -3629,21 +1078,6 @@ int wm_halo_init(struct wm_adsp *dsp) } EXPORT_SYMBOL_GPL(wm_halo_init);
-static void cs_dsp_remove(struct cs_dsp *dsp) -{ - struct cs_dsp_coeff_ctl *ctl; - - while (!list_empty(&dsp->ctl_list)) { - ctl = list_first_entry(&dsp->ctl_list, struct cs_dsp_coeff_ctl, list); - - if (dsp->client_ops->control_remove) - dsp->client_ops->control_remove(ctl); - - list_del(&ctl->list); - cs_dsp_free_ctl_blk(ctl); - } -} - void wm_adsp2_remove(struct wm_adsp *dsp) { cs_dsp_remove(&dsp->cs_dsp); @@ -3873,57 +1307,6 @@ int wm_adsp_compr_get_caps(struct snd_soc_component *component, } EXPORT_SYMBOL_GPL(wm_adsp_compr_get_caps);
-static int cs_dsp_read_raw_data_block(struct cs_dsp *dsp, int mem_type, - unsigned int mem_addr, - unsigned int num_words, __be32 *data) -{ - struct cs_dsp_region const *mem = cs_dsp_find_region(dsp, mem_type); - unsigned int reg; - int ret; - - if (!mem) - return -EINVAL; - - reg = dsp->ops->region_to_reg(mem, mem_addr); - - ret = regmap_raw_read(dsp->regmap, reg, data, - sizeof(*data) * num_words); - if (ret < 0) - return ret; - - return 0; -} - -static int cs_dsp_read_data_word(struct cs_dsp *dsp, int mem_type, - unsigned int mem_addr, u32 *data) -{ - __be32 raw; - int ret; - - ret = cs_dsp_read_raw_data_block(dsp, mem_type, mem_addr, 1, &raw); - if (ret < 0) - return ret; - - *data = be32_to_cpu(raw) & 0x00ffffffu; - - return 0; -} - -static int cs_dsp_write_data_word(struct cs_dsp *dsp, int mem_type, - unsigned int mem_addr, u32 data) -{ - struct cs_dsp_region const *mem = cs_dsp_find_region(dsp, mem_type); - __be32 val = cpu_to_be32(data & 0x00ffffffu); - unsigned int reg; - - if (!mem) - return -EINVAL; - - reg = dsp->ops->region_to_reg(mem, mem_addr); - - return regmap_raw_write(dsp->regmap, reg, &val, sizeof(val)); -} - static inline int wm_adsp_buffer_read(struct wm_adsp_compr_buf *buf, unsigned int field_offset, u32 *data) { @@ -3939,25 +1322,6 @@ static inline int wm_adsp_buffer_write(struct wm_adsp_compr_buf *buf, data); }
-static void cs_dsp_remove_padding(u32 *buf, int nwords) -{ - const __be32 *pack_in = (__be32 *)buf; - u8 *pack_out = (u8 *)buf; - int i; - - /* - * DSP words from the register map have pad bytes and the data bytes - * are in swapped order. This swaps back to the original little-endian - * order and strips the pad bytes. - */ - for (i = 0; i < nwords; i++) { - u32 word = be32_to_cpu(*pack_in++); - *pack_out++ = (u8)word; - *pack_out++ = (u8)(word >> 8); - *pack_out++ = (u8)(word >> 16); - } -} - 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; @@ -4568,69 +1932,6 @@ static void wm_adsp_fatal_error(struct cs_dsp *cs_dsp) } }
-static void cs_dsp_adsp2_bus_error(struct cs_dsp *dsp) -{ - unsigned int val; - struct regmap *regmap = dsp->regmap; - int ret = 0; - - mutex_lock(&dsp->pwr_lock); - - ret = regmap_read(regmap, dsp->base + ADSP2_LOCK_REGION_CTRL, &val); - if (ret) { - cs_dsp_err(dsp, - "Failed to read Region Lock Ctrl register: %d\n", ret); - goto error; - } - - if (val & ADSP2_WDT_TIMEOUT_STS_MASK) { - cs_dsp_err(dsp, "watchdog timeout error\n"); - dsp->ops->stop_watchdog(dsp); - if (dsp->client_ops->watchdog_expired) - dsp->client_ops->watchdog_expired(dsp); - } - - if (val & (ADSP2_ADDR_ERR_MASK | ADSP2_REGION_LOCK_ERR_MASK)) { - if (val & ADSP2_ADDR_ERR_MASK) - cs_dsp_err(dsp, "bus error: address error\n"); - else - cs_dsp_err(dsp, "bus error: region lock error\n"); - - ret = regmap_read(regmap, dsp->base + ADSP2_BUS_ERR_ADDR, &val); - if (ret) { - cs_dsp_err(dsp, - "Failed to read Bus Err Addr register: %d\n", - ret); - goto error; - } - - cs_dsp_err(dsp, "bus error address = 0x%x\n", - val & ADSP2_BUS_ERR_ADDR_MASK); - - ret = regmap_read(regmap, - dsp->base + ADSP2_PMEM_ERR_ADDR_XMEM_ERR_ADDR, - &val); - if (ret) { - cs_dsp_err(dsp, - "Failed to read Pmem Xmem Err Addr register: %d\n", - ret); - goto error; - } - - cs_dsp_err(dsp, "xmem error address = 0x%x\n", - val & ADSP2_XMEM_ERR_ADDR_MASK); - cs_dsp_err(dsp, "pmem error address = 0x%x\n", - (val & ADSP2_PMEM_ERR_ADDR_MASK) >> - ADSP2_PMEM_ERR_ADDR_SHIFT); - } - - regmap_update_bits(regmap, dsp->base + ADSP2_LOCK_REGION_CTRL, - ADSP2_CTRL_ERR_EINT, ADSP2_CTRL_ERR_EINT); - -error: - mutex_unlock(&dsp->pwr_lock); -} - irqreturn_t wm_adsp2_bus_error(int irq, void *data) { struct wm_adsp *dsp = (struct wm_adsp *)data; @@ -4641,59 +1942,6 @@ irqreturn_t wm_adsp2_bus_error(int irq, void *data) } EXPORT_SYMBOL_GPL(wm_adsp2_bus_error);
-static void cs_dsp_halo_bus_error(struct cs_dsp *dsp) -{ - struct regmap *regmap = dsp->regmap; - unsigned int fault[6]; - struct reg_sequence clear[] = { - { dsp->base + HALO_MPU_XM_VIO_STATUS, 0x0 }, - { dsp->base + HALO_MPU_YM_VIO_STATUS, 0x0 }, - { dsp->base + HALO_MPU_PM_VIO_STATUS, 0x0 }, - }; - int ret; - - mutex_lock(&dsp->pwr_lock); - - ret = regmap_read(regmap, dsp->base_sysinfo + HALO_AHBM_WINDOW_DEBUG_1, - fault); - if (ret) { - cs_dsp_warn(dsp, "Failed to read AHB DEBUG_1: %d\n", ret); - goto exit_unlock; - } - - cs_dsp_warn(dsp, "AHB: STATUS: 0x%x ADDR: 0x%x\n", - *fault & HALO_AHBM_FLAGS_ERR_MASK, - (*fault & HALO_AHBM_CORE_ERR_ADDR_MASK) >> - HALO_AHBM_CORE_ERR_ADDR_SHIFT); - - ret = regmap_read(regmap, dsp->base_sysinfo + HALO_AHBM_WINDOW_DEBUG_0, - fault); - if (ret) { - cs_dsp_warn(dsp, "Failed to read AHB DEBUG_0: %d\n", ret); - goto exit_unlock; - } - - cs_dsp_warn(dsp, "AHB: SYS_ADDR: 0x%x\n", *fault); - - ret = regmap_bulk_read(regmap, dsp->base + HALO_MPU_XM_VIO_ADDR, - fault, ARRAY_SIZE(fault)); - if (ret) { - cs_dsp_warn(dsp, "Failed to read MPU fault info: %d\n", ret); - goto exit_unlock; - } - - cs_dsp_warn(dsp, "XM: STATUS:0x%x ADDR:0x%x\n", fault[1], fault[0]); - cs_dsp_warn(dsp, "YM: STATUS:0x%x ADDR:0x%x\n", fault[3], fault[2]); - cs_dsp_warn(dsp, "PM: STATUS:0x%x ADDR:0x%x\n", fault[5], fault[4]); - - ret = regmap_multi_reg_write(dsp->regmap, clear, ARRAY_SIZE(clear)); - if (ret) - cs_dsp_warn(dsp, "Failed to clear MPU status: %d\n", ret); - -exit_unlock: - mutex_unlock(&dsp->pwr_lock); -} - irqreturn_t wm_halo_bus_error(int irq, void *data) { struct wm_adsp *dsp = (struct wm_adsp *)data; @@ -4704,19 +1952,6 @@ irqreturn_t wm_halo_bus_error(int irq, void *data) } EXPORT_SYMBOL_GPL(wm_halo_bus_error);
-static void cs_dsp_halo_wdt_expire(struct cs_dsp *dsp) -{ - mutex_lock(&dsp->pwr_lock); - - cs_dsp_warn(dsp, "WDT Expiry Fault\n"); - - dsp->ops->stop_watchdog(dsp); - if (dsp->client_ops->watchdog_expired) - dsp->client_ops->watchdog_expired(dsp); - - mutex_unlock(&dsp->pwr_lock); -} - irqreturn_t wm_halo_wdt_expire(int irq, void *data) { struct wm_adsp *dsp = data; @@ -4727,90 +1962,11 @@ irqreturn_t wm_halo_wdt_expire(int irq, void *data) } EXPORT_SYMBOL_GPL(wm_halo_wdt_expire);
-static const struct cs_dsp_ops cs_dsp_adsp1_ops = { - .validate_version = cs_dsp_validate_version, - .parse_sizes = cs_dsp_adsp1_parse_sizes, - .region_to_reg = cs_dsp_region_to_reg, -}; - static const struct cs_dsp_client_ops wm_adsp1_client_ops = { .control_add = wm_adsp_control_add, .control_remove = wm_adsp_control_remove, };
-static const struct cs_dsp_ops cs_dsp_adsp2_ops[] = { - { - .parse_sizes = cs_dsp_adsp2_parse_sizes, - .validate_version = cs_dsp_validate_version, - .setup_algs = cs_dsp_adsp2_setup_algs, - .region_to_reg = cs_dsp_region_to_reg, - - .show_fw_status = cs_dsp_adsp2_show_fw_status, - - .enable_memory = cs_dsp_adsp2_enable_memory, - .disable_memory = cs_dsp_adsp2_disable_memory, - - .enable_core = cs_dsp_adsp2_enable_core, - .disable_core = cs_dsp_adsp2_disable_core, - - .start_core = cs_dsp_adsp2_start_core, - .stop_core = cs_dsp_adsp2_stop_core, - - }, - { - .parse_sizes = cs_dsp_adsp2_parse_sizes, - .validate_version = cs_dsp_validate_version, - .setup_algs = cs_dsp_adsp2_setup_algs, - .region_to_reg = cs_dsp_region_to_reg, - - .show_fw_status = cs_dsp_adsp2v2_show_fw_status, - - .enable_memory = cs_dsp_adsp2_enable_memory, - .disable_memory = cs_dsp_adsp2_disable_memory, - .lock_memory = cs_dsp_adsp2_lock, - - .enable_core = cs_dsp_adsp2v2_enable_core, - .disable_core = cs_dsp_adsp2v2_disable_core, - - .start_core = cs_dsp_adsp2_start_core, - .stop_core = cs_dsp_adsp2_stop_core, - }, - { - .parse_sizes = cs_dsp_adsp2_parse_sizes, - .validate_version = cs_dsp_validate_version, - .setup_algs = cs_dsp_adsp2_setup_algs, - .region_to_reg = cs_dsp_region_to_reg, - - .show_fw_status = cs_dsp_adsp2v2_show_fw_status, - .stop_watchdog = cs_dsp_stop_watchdog, - - .enable_memory = cs_dsp_adsp2_enable_memory, - .disable_memory = cs_dsp_adsp2_disable_memory, - .lock_memory = cs_dsp_adsp2_lock, - - .enable_core = cs_dsp_adsp2v2_enable_core, - .disable_core = cs_dsp_adsp2v2_disable_core, - - .start_core = cs_dsp_adsp2_start_core, - .stop_core = cs_dsp_adsp2_stop_core, - }, -}; - -static const struct cs_dsp_ops cs_dsp_halo_ops = { - .parse_sizes = cs_dsp_adsp2_parse_sizes, - .validate_version = cs_dsp_halo_validate_version, - .setup_algs = cs_dsp_halo_setup_algs, - .region_to_reg = cs_dsp_halo_region_to_reg, - - .show_fw_status = cs_dsp_halo_show_fw_status, - .stop_watchdog = cs_dsp_halo_stop_watchdog, - - .lock_memory = cs_dsp_halo_configure_mpu, - - .start_core = cs_dsp_halo_start_core, - .stop_core = cs_dsp_halo_stop_core, -}; - static const struct cs_dsp_client_ops wm_adsp2_client_ops = { .control_add = wm_adsp_control_add, .control_remove = wm_adsp_control_remove, diff --git a/sound/soc/codecs/wm_adsp.h b/sound/soc/codecs/wm_adsp.h index 25aaef74654c..0e2f113bd342 100644 --- a/sound/soc/codecs/wm_adsp.h +++ b/sound/soc/codecs/wm_adsp.h @@ -10,113 +10,19 @@ #ifndef __WM_ADSP_H #define __WM_ADSP_H
+#include <linux/firmware/cirrus/cs_dsp.h> +#include <linux/firmware/cirrus/wmfw.h> + #include <sound/soc.h> #include <sound/soc-dapm.h> #include <sound/compress_driver.h>
-#include "wmfw.h" - /* Return values for wm_adsp_compr_handle_irq */ #define WM_ADSP_COMPR_OK 0 #define WM_ADSP_COMPR_VOICE_TRIGGER 1
-#define CS_ADSP2_REGION_0 BIT(0) -#define CS_ADSP2_REGION_1 BIT(1) -#define CS_ADSP2_REGION_2 BIT(2) -#define CS_ADSP2_REGION_3 BIT(3) -#define CS_ADSP2_REGION_4 BIT(4) -#define CS_ADSP2_REGION_5 BIT(5) -#define CS_ADSP2_REGION_6 BIT(6) -#define CS_ADSP2_REGION_7 BIT(7) -#define CS_ADSP2_REGION_8 BIT(8) -#define CS_ADSP2_REGION_9 BIT(9) -#define CS_ADSP2_REGION_1_9 (CS_ADSP2_REGION_1 | \ - CS_ADSP2_REGION_2 | CS_ADSP2_REGION_3 | \ - CS_ADSP2_REGION_4 | CS_ADSP2_REGION_5 | \ - CS_ADSP2_REGION_6 | CS_ADSP2_REGION_7 | \ - CS_ADSP2_REGION_8 | CS_ADSP2_REGION_9) -#define CS_ADSP2_REGION_ALL (CS_ADSP2_REGION_0 | CS_ADSP2_REGION_1_9) - -struct cs_dsp_region { - int type; - unsigned int base; -}; - -struct cs_dsp_alg_region { - struct list_head list; - unsigned int alg; - int type; - unsigned int base; -}; - struct wm_adsp_compr; struct wm_adsp_compr_buf; -struct cs_dsp_ops; -struct cs_dsp_client_ops; - -struct cs_dsp_coeff_ctl { - const char *fw_name; - /* Subname is needed to match with firmware */ - const char *subname; - unsigned int subname_len; - struct cs_dsp_alg_region alg_region; - struct cs_dsp *dsp; - unsigned int enabled:1; - struct list_head list; - void *cache; - unsigned int offset; - size_t len; - unsigned int set:1; - unsigned int flags; - unsigned int type; - - void *priv; -}; - -struct cs_dsp { - const char *name; - int rev; - int num; - int type; - struct device *dev; - struct regmap *regmap; - - const struct cs_dsp_ops *ops; - const struct cs_dsp_client_ops *client_ops; - - unsigned int base; - unsigned int base_sysinfo; - unsigned int sysclk_reg; - unsigned int sysclk_mask; - unsigned int sysclk_shift; - - struct list_head alg_regions; - - const char *fw_name; - unsigned int fw_id; - unsigned int fw_id_version; - unsigned int fw_vendor_id; - - const struct cs_dsp_region *mem; - int num_mems; - - int fw_ver; - - bool booted; - bool running; - - struct list_head ctl_list; - - struct mutex pwr_lock; - - unsigned int lock_regions; - -#ifdef CONFIG_DEBUG_FS - struct dentry *debugfs_root; - char *wmfw_file_name; - char *bin_file_name; -#endif -};
struct wm_adsp { struct cs_dsp cs_dsp; @@ -137,30 +43,6 @@ struct wm_adsp { struct list_head buffer_list; };
-struct cs_dsp_ops { - bool (*validate_version)(struct cs_dsp *dsp, unsigned int version); - unsigned int (*parse_sizes)(struct cs_dsp *dsp, - const char * const file, - unsigned int pos, - const struct firmware *firmware); - int (*setup_algs)(struct cs_dsp *dsp); - unsigned int (*region_to_reg)(struct cs_dsp_region const *mem, - unsigned int offset); - - void (*show_fw_status)(struct cs_dsp *dsp); - void (*stop_watchdog)(struct cs_dsp *dsp); - - int (*enable_memory)(struct cs_dsp *dsp); - void (*disable_memory)(struct cs_dsp *dsp); - int (*lock_memory)(struct cs_dsp *dsp, unsigned int lock_regions); - - int (*enable_core)(struct cs_dsp *dsp); - void (*disable_core)(struct cs_dsp *dsp); - - int (*start_core)(struct cs_dsp *dsp); - void (*stop_core)(struct cs_dsp *dsp); -}; - #define WM_ADSP1(wname, num) \ SND_SOC_DAPM_PGA_E(wname, SND_SOC_NOPM, num, 0, NULL, 0, \ wm_adsp1_event, SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD) @@ -239,12 +121,4 @@ int wm_adsp_write_ctl(struct wm_adsp *dsp, const char *name, int type, int wm_adsp_read_ctl(struct wm_adsp *dsp, const char *name, int type, unsigned int alg, void *buf, size_t len);
-struct cs_dsp_client_ops { - int (*control_add)(struct cs_dsp_coeff_ctl *ctl); - void (*control_remove)(struct cs_dsp_coeff_ctl *ctl); - int (*post_run)(struct cs_dsp *dsp); - void (*post_stop)(struct cs_dsp *dsp); - void (*watchdog_expired)(struct cs_dsp *dsp); -}; - #endif
On Mon, 13 Sep 2021 17:00:41 +0100, Simon Trimmer wrote:
This series of patches gradually separates the ASoC specific wm_adsp code from that required to manage firmware in Cirrus Logic DSPs.
The series starts with renaming, progresses to splitting the functionality before finally moving the independent functionality into drivers/firmware so that it can be used by both the existing ASoC wm_adsp and new non-audio parts.
[...]
Applied to
https://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound.git for-next
Thanks!
[01/16] ASoC: wm_adsp: Remove use of snd_ctl_elem_type_t commit: d07a6d454ffa310ee306d57f486eb64380bbdfff [02/16] ASoC: wm_adsp: Move check for control existence commit: 6477960755fb2c0ca9b0497bc86abfa4ee173556 [03/16] ASoC: wm_adsp: Switch to using wm_coeff_read_ctrl for compressed buffers commit: 04ae08596737c4d3872dfb6e617c918d9ecf073e [04/16] ASoC: wm_adsp: Cancel ongoing work when removing controls commit: df6c505c129a114da783ae82b9f0b4d2d4691c91 [05/16] ASoC: wm_adsp: Rename generic DSP support commit: 5beb8eeade2c03b55ae729c05bb9fa245633fe74 [06/16] ASoC: wm_adsp: Introduce cs_dsp logging macros commit: 6ab1d0cc8470100cc8e0b478d94ff00b44df1625 [07/16] ASoC: wm_adsp: Separate some ASoC and generic functions commit: 25ca837ba6f4dd8f969b41aa202a62facdd2370c [08/16] ASoC: wm_adsp: Split DSP power operations into helper functions commit: 186152df4d431650154c3e3aefc7d3e1004987c8 [09/16] ASoC: wm_adsp: Move sys_config_size to wm_adsp commit: 6092be2d93b3b28dfeca4e5944052a1a21f51ca3 [10/16] ASoC: wm_adsp: Separate generic cs_dsp_coeff_ctl handling commit: 0700bc2fb94c28459f57a10d2ee2c7ef4cb70862 [11/16] ASoC: wm_adsp: Move check of dsp->running to better place commit: edb1d6d7f03913b2b6ca299b1f6fd8dc96d511f5 [12/16] ASoC: wm_adsp: Pass firmware names as parameters when starting DSP core commit: 2169f2f15185f9393b1c16eac6e7c7d4adb6279b [13/16] ASoC: wm_adsp: move firmware loading to client commit: a828056fa1fc044beab3cbe32f484fec5f38fe98 [14/16] ASoC: wm_adsp: Split out struct cs_dsp from struct wm_adsp commit: e146820215910d889ab16d6c2484fd51a6bb8f1f [15/16] ASoC: wm_adsp: Separate wm_adsp specifics in cs_dsp_client_ops commit: 2dd044641ec3672433b9fe3ec47b236621757aa8 [16/16] firmware: cs_dsp: add driver to support firmware loading on Cirrus Logic DSPs commit: f6bc909e7673c30abcbdb329e7d0aa2e83c103d7
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
participants (2)
-
Mark Brown
-
Simon Trimmer