@@ -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
165210error :
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