Loading sound/soc/codecs/wm_adsp.c +48 −5 Original line number Diff line number Diff line Loading @@ -103,6 +103,13 @@ #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 0 #define ADSP2_CLOCKING 1 #define ADSP2_STATUS1 4 Loading Loading @@ -686,6 +693,16 @@ static int wm_adsp_load_coeff(struct wm_adsp *dsp) return -EINVAL; } switch (be32_to_cpu(hdr->rev) & 0xff) { case 1: break; default: adsp_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, Loading @@ -698,8 +715,8 @@ static int wm_adsp_load_coeff(struct wm_adsp *dsp) pos - firmware->size > sizeof(*blk)) { blk = (void*)(&firmware->data[pos]); type = be32_to_cpu(blk->type) & 0xff; offset = le32_to_cpu(blk->offset) & 0xffffff; 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), Loading @@ -712,10 +729,10 @@ static int wm_adsp_load_coeff(struct wm_adsp *dsp) reg = 0; region_name = "Unknown"; switch (type) { case WMFW_NAME_TEXT: case WMFW_INFO_TEXT: case (WMFW_NAME_TEXT << 8): case (WMFW_INFO_TEXT << 8): break; case WMFW_ABSOLUTE: case (WMFW_ABSOLUTE << 8): region_name = "register"; reg = offset; break; Loading Loading @@ -796,12 +813,38 @@ int wm_adsp1_event(struct snd_soc_dapm_widget *w, struct wm_adsp *dsps = snd_soc_codec_get_drvdata(codec); struct wm_adsp *dsp = &dsps[w->shift]; int ret; int val; 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) { adsp_err(dsp, "Failed to read SYSCLK state: %d\n", ret); return ret; } 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) { adsp_err(dsp, "Failed to set clock rate: %d\n", ret); return ret; } } ret = wm_adsp_load(dsp); if (ret != 0) goto err; Loading sound/soc/codecs/wm_adsp.h +3 −0 Original line number Diff line number Diff line Loading @@ -40,6 +40,9 @@ struct wm_adsp { struct regmap *regmap; int base; int sysclk_reg; int sysclk_mask; int sysclk_shift; struct list_head alg_regions; Loading sound/soc/codecs/wmfw.h +10 −5 Original line number Diff line number Diff line Loading @@ -93,15 +93,20 @@ struct wmfw_adsp2_alg_hdr { struct wmfw_coeff_hdr { u8 magic[4]; __le32 len; union { __be32 rev; __le32 ver; }; union { __be32 core; __le32 core_ver; }; u8 data[]; } __packed; struct wmfw_coeff_item { union { __be32 type; __le32 offset; }; __le16 offset; __le16 type; __le32 id; __le32 ver; __le32 sr; Loading Loading
sound/soc/codecs/wm_adsp.c +48 −5 Original line number Diff line number Diff line Loading @@ -103,6 +103,13 @@ #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 0 #define ADSP2_CLOCKING 1 #define ADSP2_STATUS1 4 Loading Loading @@ -686,6 +693,16 @@ static int wm_adsp_load_coeff(struct wm_adsp *dsp) return -EINVAL; } switch (be32_to_cpu(hdr->rev) & 0xff) { case 1: break; default: adsp_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, Loading @@ -698,8 +715,8 @@ static int wm_adsp_load_coeff(struct wm_adsp *dsp) pos - firmware->size > sizeof(*blk)) { blk = (void*)(&firmware->data[pos]); type = be32_to_cpu(blk->type) & 0xff; offset = le32_to_cpu(blk->offset) & 0xffffff; 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), Loading @@ -712,10 +729,10 @@ static int wm_adsp_load_coeff(struct wm_adsp *dsp) reg = 0; region_name = "Unknown"; switch (type) { case WMFW_NAME_TEXT: case WMFW_INFO_TEXT: case (WMFW_NAME_TEXT << 8): case (WMFW_INFO_TEXT << 8): break; case WMFW_ABSOLUTE: case (WMFW_ABSOLUTE << 8): region_name = "register"; reg = offset; break; Loading Loading @@ -796,12 +813,38 @@ int wm_adsp1_event(struct snd_soc_dapm_widget *w, struct wm_adsp *dsps = snd_soc_codec_get_drvdata(codec); struct wm_adsp *dsp = &dsps[w->shift]; int ret; int val; 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) { adsp_err(dsp, "Failed to read SYSCLK state: %d\n", ret); return ret; } 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) { adsp_err(dsp, "Failed to set clock rate: %d\n", ret); return ret; } } ret = wm_adsp_load(dsp); if (ret != 0) goto err; Loading
sound/soc/codecs/wm_adsp.h +3 −0 Original line number Diff line number Diff line Loading @@ -40,6 +40,9 @@ struct wm_adsp { struct regmap *regmap; int base; int sysclk_reg; int sysclk_mask; int sysclk_shift; struct list_head alg_regions; Loading
sound/soc/codecs/wmfw.h +10 −5 Original line number Diff line number Diff line Loading @@ -93,15 +93,20 @@ struct wmfw_adsp2_alg_hdr { struct wmfw_coeff_hdr { u8 magic[4]; __le32 len; union { __be32 rev; __le32 ver; }; union { __be32 core; __le32 core_ver; }; u8 data[]; } __packed; struct wmfw_coeff_item { union { __be32 type; __le32 offset; }; __le16 offset; __le16 type; __le32 id; __le32 ver; __le32 sr; Loading