Skip to content

Commit 0d42ea1

Browse files
simontrimmerLucas Tanure
authored andcommitted
ASoC: clsic-codec: implement recommended DSP2 power control sequences
Change-Id: Ie34b21b7688776abe3b850bde17178bb8a8fdc44 Signed-off-by: Simon Trimmer <[email protected]>
1 parent 137c492 commit 0d42ea1

File tree

3 files changed

+60
-6
lines changed

3 files changed

+60
-6
lines changed

drivers/mfd/clsic/clsic-tables.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -734,6 +734,7 @@ bool clsic_volatile_register(struct device *dev, unsigned int reg)
734734
case TACNA_ASYNC_SAMPLE_RATE_STATUS2:
735735
case TACNA_DSP_CLOCK3:
736736
case TACNA_DSP_CLOCK4:
737+
case CLSIC_DSP2_PWR_CTRL:
737738
case TACNA_FLL1_CONTROL5:
738739
case TACNA_FLL1_CONTROL6:
739740
case TACNA_FLL2_CONTROL5:

include/linux/mfd/clsic/registers.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -166,6 +166,14 @@
166166
#define CLSIC_PDM_CLK_SRC_WIDTH 3
167167

168168
/* (0x17218) DSP2_PWR_CTRL */
169+
#define CLSIC_DSP2_POWER_OFF_OK 0x00000200
170+
#define CLSIC_DSP2_POWER_OFF_OK_MASK 0x00000200
171+
#define CLSIC_DSP2_POWER_OFF_OK_SHIFT 9
172+
#define CLSIC_DSP2_POWER_OFF_OK_WIDTH 1
173+
#define CLSIC_DSP2_POWER_OK 0x00000100
174+
#define CLSIC_DSP2_POWER_OK_MASK 0x00000100
175+
#define CLSIC_DSP2_POWER_OK_SHIFT 8
176+
#define CLSIC_DSP2_POWER_OK_WIDTH 1
169177
#define CLSIC_DSP2_RST_N 0x00000004
170178
#define CLSIC_DSP2_RST_N_MASK 0x00000004
171179
#define CLSIC_DSP2_RST_N_SHIFT 2

sound/soc/codecs/clsic-codec.c

Lines changed: 51 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -121,18 +121,45 @@ static int clsic_dsp_power_ev(struct snd_soc_dapm_widget *w,
121121
struct wm_adsp *dsps = snd_soc_codec_get_drvdata(codec);
122122
struct wm_adsp *dsp = &dsps[w->shift];
123123
unsigned int freq;
124+
unsigned int val;
124125
int ret;
125126

126127
switch (event) {
127128
case SND_SOC_DAPM_PRE_PMU:
128-
/* write to DSP2_PWR_CTRL to enable core */
129-
ret = regmap_write(dsp->regmap, CLSIC_DSP2_PWR_CTRL,
130-
CLSIC_DSP2_RST_N);
131-
if (ret) {
132-
dev_err(codec->dev, "Failed to enable DSP2: %d\n", ret);
129+
/*
130+
* This PRE_PMU steps through the process of closing the power
131+
* switches, removing isolation logic and de-asserting reset
132+
* through a series of writes. If the DSP is not in the default
133+
* state then it will be reset.
134+
*
135+
* SHUTOFF ISOLATE RST_N
136+
* Starting state 1 1 0
137+
* Close power switches 0 1 0
138+
* Remove isolation 0 0 0
139+
* (check powered)
140+
* De-assert reset 0 0 1
141+
*/
142+
regmap_write(tacna->regmap, CLSIC_DSP2_PWR_CTRL,
143+
CLSIC_DSP2_ISOLATE_ENABLE);
144+
/* Performed in different writes to maintain separation */
145+
regmap_write(tacna->regmap, CLSIC_DSP2_PWR_CTRL, 0);
146+
147+
ret = regmap_read(tacna->regmap, CLSIC_DSP2_PWR_CTRL, &val);
148+
if (ret || !(val & CLSIC_DSP2_POWER_OK)) {
149+
dev_err(codec->dev,
150+
"Failed to enable DSP2 power: %d (0x%x)\n",
151+
ret, val);
133152
return ret;
134153
}
135154

155+
ret = regmap_write(tacna->regmap, CLSIC_DSP2_PWR_CTRL,
156+
CLSIC_DSP2_RST_N);
157+
if (ret) {
158+
dev_err(codec->dev,
159+
"Failed to de-assert reset: %d\n", ret);
160+
goto error;
161+
}
162+
136163
ret = regmap_read(tacna->regmap, TACNA_DSP_CLOCK3, &freq);
137164
if (ret) {
138165
dev_err(codec->dev,
@@ -157,13 +184,31 @@ static int clsic_dsp_power_ev(struct snd_soc_dapm_widget *w,
157184
case SND_SOC_DAPM_PRE_PMD:
158185
ret = wm_halo_early_event(w, kcontrol, event);
159186
clsic_dsp_memory_disable(priv);
187+
188+
/*
189+
* This PRE_PMD steps through the process of shutting down the
190+
* DSP.
191+
*
192+
* SHUTOFF ISOLATE RST_N
193+
* Assert reset 0 0 0
194+
* Apply isolation logic 0 1 0
195+
* Open power switches 1 1 0
196+
*/
197+
regmap_write(tacna->regmap, CLSIC_DSP2_PWR_CTRL, 0);
198+
199+
regmap_write(tacna->regmap, CLSIC_DSP2_PWR_CTRL,
200+
CLSIC_DSP2_ISOLATE_ENABLE);
201+
202+
regmap_write(tacna->regmap, CLSIC_DSP2_PWR_CTRL,
203+
CLSIC_DSP2_ISOLATE_ENABLE | CLSIC_DSP2_SHUTOFF);
204+
160205
return ret;
161206
default:
162207
return 0;
163208
}
164209

165210
error:
166-
regmap_write(dsp->regmap, CLSIC_DSP2_PWR_CTRL,
211+
regmap_write(tacna->regmap, CLSIC_DSP2_PWR_CTRL,
167212
CLSIC_DSP2_ISOLATE_ENABLE | CLSIC_DSP2_SHUTOFF);
168213
return ret;
169214
}

0 commit comments

Comments
 (0)