Loading sound/soc/codecs/wm_adsp.c +95 −2 Original line number Diff line number Diff line Loading @@ -18,6 +18,7 @@ #include <linux/pm.h> #include <linux/pm_runtime.h> #include <linux/regmap.h> #include <linux/regulator/consumer.h> #include <linux/slab.h> #include <sound/core.h> #include <sound/pcm.h> Loading Loading @@ -103,6 +104,7 @@ #define ADSP1_START_WIDTH 1 /* DSP1_START */ #define ADSP2_CONTROL 0 #define ADSP2_CLOCKING 1 #define ADSP2_STATUS1 4 /* Loading @@ -126,6 +128,13 @@ #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 */ /* * ADSP2 Status 1 */ Loading Loading @@ -530,10 +539,41 @@ int wm_adsp2_event(struct snd_soc_dapm_widget *w, struct snd_soc_codec *codec = w->codec; struct wm_adsp *dsps = snd_soc_codec_get_drvdata(codec); struct wm_adsp *dsp = &dsps[w->shift]; unsigned int val; int ret; switch (event) { case SND_SOC_DAPM_POST_PMU: if (dsp->dvfs) { ret = regmap_read(dsp->regmap, dsp->base + ADSP2_CLOCKING, &val); if (ret != 0) { dev_err(dsp->dev, "Failed to read clocking: %d\n", ret); return ret; } if (val & ADSP2_CLK_SEL_MASK >= 3) { ret = regulator_enable(dsp->dvfs); if (ret != 0) { dev_err(dsp->dev, "Failed to enable supply: %d\n", ret); return ret; } ret = regulator_set_voltage(dsp->dvfs, 1800000, 1800000); if (ret != 0) { dev_err(dsp->dev, "Failed to raise supply: %d\n", ret); return ret; } } } ret = wm_adsp2_ena(dsp); if (ret != 0) return ret; Loading @@ -556,6 +596,21 @@ int wm_adsp2_event(struct snd_soc_dapm_widget *w, case SND_SOC_DAPM_PRE_PMD: regmap_update_bits(dsp->regmap, dsp->base + ADSP2_CONTROL, ADSP2_SYS_ENA | ADSP2_START, 0); if (dsp->dvfs) { ret = regulator_set_voltage(dsp->dvfs, 1200000, 1800000); if (ret != 0) dev_warn(dsp->dev, "Failed to lower supply: %d\n", ret); ret = regulator_disable(dsp->dvfs); if (ret != 0) dev_err(dsp->dev, "Failed to enable supply: %d\n", ret); } break; default: Loading @@ -569,3 +624,41 @@ int wm_adsp2_event(struct snd_soc_dapm_widget *w, return ret; } EXPORT_SYMBOL_GPL(wm_adsp2_event); int wm_adsp2_init(struct wm_adsp *adsp, bool dvfs) { int ret; if (dvfs) { adsp->dvfs = devm_regulator_get(adsp->dev, "DCVDD"); if (IS_ERR(adsp->dvfs)) { ret = PTR_ERR(adsp->dvfs); dev_err(adsp->dev, "Failed to get DCVDD: %d\n", ret); return ret; } ret = regulator_enable(adsp->dvfs); if (ret != 0) { dev_err(adsp->dev, "Failed to enable DCVDD: %d\n", ret); return ret; } ret = regulator_set_voltage(adsp->dvfs, 1200000, 1800000); if (ret != 0) { dev_err(adsp->dev, "Failed to initialise DVFS: %d\n", ret); return ret; } ret = regulator_disable(adsp->dvfs); if (ret != 0) { dev_err(adsp->dev, "Failed to disable DCVDD: %d\n", ret); return ret; } } return 0; } EXPORT_SYMBOL_GPL(wm_adsp2_init); sound/soc/codecs/wm_adsp.h +5 −0 Original line number Diff line number Diff line Loading @@ -18,6 +18,8 @@ #include "wmfw.h" struct regulator; struct wm_adsp_region { int type; unsigned int base; Loading @@ -34,6 +36,8 @@ struct wm_adsp { const struct wm_adsp_region *mem; int num_mems; struct regulator *dvfs; }; #define WM_ADSP1(wname, num) \ Loading @@ -46,6 +50,7 @@ struct wm_adsp { .shift = num, .event = wm_adsp2_event, \ .event_flags = SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD } int wm_adsp2_init(struct wm_adsp *adsp, bool dvfs); int wm_adsp1_event(struct snd_soc_dapm_widget *w, struct snd_kcontrol *kcontrol, int event); int wm_adsp2_event(struct snd_soc_dapm_widget *w, Loading Loading
sound/soc/codecs/wm_adsp.c +95 −2 Original line number Diff line number Diff line Loading @@ -18,6 +18,7 @@ #include <linux/pm.h> #include <linux/pm_runtime.h> #include <linux/regmap.h> #include <linux/regulator/consumer.h> #include <linux/slab.h> #include <sound/core.h> #include <sound/pcm.h> Loading Loading @@ -103,6 +104,7 @@ #define ADSP1_START_WIDTH 1 /* DSP1_START */ #define ADSP2_CONTROL 0 #define ADSP2_CLOCKING 1 #define ADSP2_STATUS1 4 /* Loading @@ -126,6 +128,13 @@ #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 */ /* * ADSP2 Status 1 */ Loading Loading @@ -530,10 +539,41 @@ int wm_adsp2_event(struct snd_soc_dapm_widget *w, struct snd_soc_codec *codec = w->codec; struct wm_adsp *dsps = snd_soc_codec_get_drvdata(codec); struct wm_adsp *dsp = &dsps[w->shift]; unsigned int val; int ret; switch (event) { case SND_SOC_DAPM_POST_PMU: if (dsp->dvfs) { ret = regmap_read(dsp->regmap, dsp->base + ADSP2_CLOCKING, &val); if (ret != 0) { dev_err(dsp->dev, "Failed to read clocking: %d\n", ret); return ret; } if (val & ADSP2_CLK_SEL_MASK >= 3) { ret = regulator_enable(dsp->dvfs); if (ret != 0) { dev_err(dsp->dev, "Failed to enable supply: %d\n", ret); return ret; } ret = regulator_set_voltage(dsp->dvfs, 1800000, 1800000); if (ret != 0) { dev_err(dsp->dev, "Failed to raise supply: %d\n", ret); return ret; } } } ret = wm_adsp2_ena(dsp); if (ret != 0) return ret; Loading @@ -556,6 +596,21 @@ int wm_adsp2_event(struct snd_soc_dapm_widget *w, case SND_SOC_DAPM_PRE_PMD: regmap_update_bits(dsp->regmap, dsp->base + ADSP2_CONTROL, ADSP2_SYS_ENA | ADSP2_START, 0); if (dsp->dvfs) { ret = regulator_set_voltage(dsp->dvfs, 1200000, 1800000); if (ret != 0) dev_warn(dsp->dev, "Failed to lower supply: %d\n", ret); ret = regulator_disable(dsp->dvfs); if (ret != 0) dev_err(dsp->dev, "Failed to enable supply: %d\n", ret); } break; default: Loading @@ -569,3 +624,41 @@ int wm_adsp2_event(struct snd_soc_dapm_widget *w, return ret; } EXPORT_SYMBOL_GPL(wm_adsp2_event); int wm_adsp2_init(struct wm_adsp *adsp, bool dvfs) { int ret; if (dvfs) { adsp->dvfs = devm_regulator_get(adsp->dev, "DCVDD"); if (IS_ERR(adsp->dvfs)) { ret = PTR_ERR(adsp->dvfs); dev_err(adsp->dev, "Failed to get DCVDD: %d\n", ret); return ret; } ret = regulator_enable(adsp->dvfs); if (ret != 0) { dev_err(adsp->dev, "Failed to enable DCVDD: %d\n", ret); return ret; } ret = regulator_set_voltage(adsp->dvfs, 1200000, 1800000); if (ret != 0) { dev_err(adsp->dev, "Failed to initialise DVFS: %d\n", ret); return ret; } ret = regulator_disable(adsp->dvfs); if (ret != 0) { dev_err(adsp->dev, "Failed to disable DCVDD: %d\n", ret); return ret; } } return 0; } EXPORT_SYMBOL_GPL(wm_adsp2_init);
sound/soc/codecs/wm_adsp.h +5 −0 Original line number Diff line number Diff line Loading @@ -18,6 +18,8 @@ #include "wmfw.h" struct regulator; struct wm_adsp_region { int type; unsigned int base; Loading @@ -34,6 +36,8 @@ struct wm_adsp { const struct wm_adsp_region *mem; int num_mems; struct regulator *dvfs; }; #define WM_ADSP1(wname, num) \ Loading @@ -46,6 +50,7 @@ struct wm_adsp { .shift = num, .event = wm_adsp2_event, \ .event_flags = SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD } int wm_adsp2_init(struct wm_adsp *adsp, bool dvfs); int wm_adsp1_event(struct snd_soc_dapm_widget *w, struct snd_kcontrol *kcontrol, int event); int wm_adsp2_event(struct snd_soc_dapm_widget *w, Loading