3131#include <linux/mfd/clsic/core.h>
3232#include <linux/mfd/clsic/clsic-tacna.h>
3333
34+ /* Revision A hardware does not have DSP power status registers */
35+ #define CLSIC_REVID_A 0xA0
36+
3437#define CLSIC_N_FLL 2
3538#define CLSIC_NUM_DSP 2
3639#define CLSIC_DSP1_N_RX_CHANNELS 9
@@ -51,6 +54,7 @@ struct clsic_codec {
5154 struct clsic * clsic ;
5255 struct snd_soc_codec * codec ;
5356 bool host_controls_dsp2 ;
57+ bool check_dsp2_power_ok ;
5458 bool micbias_active_discharge [CLSIC_MICBIAS_COUNT ];
5559};
5660
@@ -119,6 +123,12 @@ static int clsic_dsp_power_ev(struct snd_soc_dapm_widget *w,
119123 struct snd_kcontrol * kcontrol , int event )
120124{
121125 struct snd_soc_codec * codec = snd_soc_dapm_to_codec (w -> dapm );
126+ /*
127+ * the snd_soc_codec_get_drvdata() gets the address of both the
128+ * clsic_codec and the tacna_priv structures because tacna_priv is the
129+ * first member of clsic_codec
130+ */
131+ struct clsic_codec * clsic_codec = snd_soc_codec_get_drvdata (codec );
122132 struct tacna_priv * priv = snd_soc_codec_get_drvdata (codec );
123133 struct tacna * tacna = priv -> tacna ;
124134 struct wm_adsp * dsps = snd_soc_codec_get_drvdata (codec );
@@ -147,14 +157,17 @@ static int clsic_dsp_power_ev(struct snd_soc_dapm_widget *w,
147157 /* Performed in different writes to maintain separation */
148158 regmap_write (tacna -> regmap , CLSIC_DSP2_PWR_CTRL , 0 );
149159
150- ret = regmap_read (tacna -> regmap , CLSIC_DSP2_PWR_CTRL , & val );
151- if (ret || !(val & CLSIC_DSP2_POWER_OK )) {
152- dev_err (codec -> dev ,
153- "Failed to enable DSP2 power: %d (0x%x)\n" ,
154- ret , val );
155- return ret ;
160+ /* if the dsp includes a status bit for power then check it */
161+ if (clsic_codec -> check_dsp2_power_ok ) {
162+ ret = regmap_read (tacna -> regmap , CLSIC_DSP2_PWR_CTRL ,
163+ & val );
164+ if (ret || !(val & CLSIC_DSP2_POWER_OK )) {
165+ dev_err (codec -> dev ,
166+ "Failed to enable DSP2 power: %d (0x%x)\n" ,
167+ ret , val );
168+ return ret ;
169+ }
156170 }
157-
158171 ret = regmap_write (tacna -> regmap , CLSIC_DSP2_PWR_CTRL ,
159172 CLSIC_DSP2_RST_N );
160173 if (ret ) {
@@ -2038,6 +2051,7 @@ static int clsic_codec_probe(struct snd_soc_codec *codec)
20382051{
20392052 struct clsic_codec * clsic_codec =
20402053 snd_soc_codec_get_drvdata (codec );
2054+ unsigned int revid ;
20412055 int ret ;
20422056
20432057 dev_info (codec -> dev , "%s() %p\n" , __func__ , codec );
@@ -2053,6 +2067,17 @@ static int clsic_codec_probe(struct snd_soc_codec *codec)
20532067 clsic_dsps_add_codec_controls (clsic_codec );
20542068
20552069 if (clsic_codec -> host_controls_dsp2 ) {
2070+ /*
2071+ * Revision A silicon did not have a DSP2 power OK signal, so
2072+ * if a revid can be read and it is not revision A then the
2073+ * driver will check power_ok when it activates DSP2
2074+ */
2075+ ret = regmap_read (clsic_codec -> core .tacna -> regmap , TACNA_REVID ,
2076+ & revid );
2077+ revid &= TACNA_AREVID_MASK ;
2078+ if (!ret && ((revid & TACNA_AREVID_MASK ) != CLSIC_REVID_A ))
2079+ clsic_codec -> check_dsp2_power_ok = true;
2080+
20562081 ret = snd_soc_add_codec_controls (codec ,
20572082 clsic_snd_controls_dsp2_visible ,
20582083 ARRAY_SIZE (clsic_snd_controls_dsp2_visible ));
0 commit comments