@@ -154,6 +154,7 @@ static const uint32_t tas5805m_volume[] = {
154154#define TAS5805M_VOLUME_MIN 0
155155
156156struct tas5805m_priv {
157+ struct i2c_client * i2c ;
157158 struct regulator * pvdd ;
158159 struct gpio_desc * gpio_pdn_n ;
159160
@@ -165,6 +166,9 @@ struct tas5805m_priv {
165166 int vol [2 ];
166167 bool is_powered ;
167168 bool is_muted ;
169+
170+ struct work_struct work ;
171+ struct mutex lock ;
168172};
169173
170174static void set_dsp_scale (struct regmap * rm , int offset , int vol )
@@ -181,13 +185,11 @@ static void set_dsp_scale(struct regmap *rm, int offset, int vol)
181185 regmap_bulk_write (rm , offset , v , ARRAY_SIZE (v ));
182186}
183187
184- static void tas5805m_refresh (struct snd_soc_component * component )
188+ static void tas5805m_refresh (struct tas5805m_priv * tas5805m )
185189{
186- struct tas5805m_priv * tas5805m =
187- snd_soc_component_get_drvdata (component );
188190 struct regmap * rm = tas5805m -> regmap ;
189191
190- dev_dbg (component -> dev , "refresh: is_muted=%d, vol=%d/%d\n" ,
192+ dev_dbg (& tas5805m -> i2c -> dev , "refresh: is_muted=%d, vol=%d/%d\n" ,
191193 tas5805m -> is_muted , tas5805m -> vol [0 ], tas5805m -> vol [1 ]);
192194
193195 regmap_write (rm , REG_PAGE , 0x00 );
@@ -226,8 +228,11 @@ static int tas5805m_vol_get(struct snd_kcontrol *kcontrol,
226228 struct tas5805m_priv * tas5805m =
227229 snd_soc_component_get_drvdata (component );
228230
231+ mutex_lock (& tas5805m -> lock );
229232 ucontrol -> value .integer .value [0 ] = tas5805m -> vol [0 ];
230233 ucontrol -> value .integer .value [1 ] = tas5805m -> vol [1 ];
234+ mutex_unlock (& tas5805m -> lock );
235+
231236 return 0 ;
232237}
233238
@@ -243,11 +248,13 @@ static int tas5805m_vol_put(struct snd_kcontrol *kcontrol,
243248 snd_soc_kcontrol_component (kcontrol );
244249 struct tas5805m_priv * tas5805m =
245250 snd_soc_component_get_drvdata (component );
251+ int ret = 0 ;
246252
247253 if (!(volume_is_valid (ucontrol -> value .integer .value [0 ]) &&
248254 volume_is_valid (ucontrol -> value .integer .value [1 ])))
249255 return - EINVAL ;
250256
257+ mutex_lock (& tas5805m -> lock );
251258 if (tas5805m -> vol [0 ] != ucontrol -> value .integer .value [0 ] ||
252259 tas5805m -> vol [1 ] != ucontrol -> value .integer .value [1 ]) {
253260 tas5805m -> vol [0 ] = ucontrol -> value .integer .value [0 ];
@@ -256,11 +263,12 @@ static int tas5805m_vol_put(struct snd_kcontrol *kcontrol,
256263 tas5805m -> vol [0 ], tas5805m -> vol [1 ],
257264 tas5805m -> is_powered );
258265 if (tas5805m -> is_powered )
259- tas5805m_refresh (component );
260- return 1 ;
266+ tas5805m_refresh (tas5805m );
267+ ret = 1 ;
261268 }
269+ mutex_unlock (& tas5805m -> lock );
262270
263- return 0 ;
271+ return ret ;
264272}
265273
266274static const struct snd_kcontrol_new tas5805m_snd_controls [] = {
@@ -294,54 +302,83 @@ static int tas5805m_trigger(struct snd_pcm_substream *substream, int cmd,
294302 struct snd_soc_component * component = dai -> component ;
295303 struct tas5805m_priv * tas5805m =
296304 snd_soc_component_get_drvdata (component );
297- struct regmap * rm = tas5805m -> regmap ;
298- unsigned int chan , global1 , global2 ;
299305
300306 switch (cmd ) {
301307 case SNDRV_PCM_TRIGGER_START :
302308 case SNDRV_PCM_TRIGGER_RESUME :
303309 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE :
304- dev_dbg (component -> dev , "DSP startup\n" );
305-
306- /* We mustn't issue any I2C transactions until the I2S
307- * clock is stable. Furthermore, we must allow a 5ms
308- * delay after the first set of register writes to
309- * allow the DSP to boot before configuring it.
310- */
311- usleep_range (5000 , 10000 );
312- send_cfg (rm , dsp_cfg_preboot ,
313- ARRAY_SIZE (dsp_cfg_preboot ));
314- usleep_range (5000 , 15000 );
315- send_cfg (rm , tas5805m -> dsp_cfg_data ,
316- tas5805m -> dsp_cfg_len );
317-
318- tas5805m -> is_powered = true;
319- tas5805m_refresh (component );
310+ dev_dbg (component -> dev , "clock start\n" );
311+ schedule_work (& tas5805m -> work );
320312 break ;
321313
322314 case SNDRV_PCM_TRIGGER_STOP :
323315 case SNDRV_PCM_TRIGGER_SUSPEND :
324316 case SNDRV_PCM_TRIGGER_PAUSE_PUSH :
325- dev_dbg ( component -> dev , "DSP shutdown\n" ) ;
317+ break ;
326318
327- tas5805m -> is_powered = false;
319+ default :
320+ return - EINVAL ;
321+ }
328322
329- regmap_write ( rm , REG_PAGE , 0x00 ) ;
330- regmap_write ( rm , REG_BOOK , 0x00 );
323+ return 0 ;
324+ }
331325
332- regmap_read (rm , REG_CHAN_FAULT , & chan );
333- regmap_read (rm , REG_GLOBAL_FAULT1 , & global1 );
334- regmap_read (rm , REG_GLOBAL_FAULT2 , & global2 );
326+ static void do_work (struct work_struct * work )
327+ {
328+ struct tas5805m_priv * tas5805m =
329+ container_of (work , struct tas5805m_priv , work );
330+ struct regmap * rm = tas5805m -> regmap ;
335331
336- dev_dbg (component -> dev ,
337- "fault regs: CHAN=%02x, GLOBAL1=%02x, GLOBAL2=%02x\n" ,
338- chan , global1 , global2 );
332+ dev_dbg (& tas5805m -> i2c -> dev , "DSP startup\n" );
339333
340- regmap_write (rm , REG_DEVICE_CTRL_2 , DCTRL2_MODE_HIZ );
341- break ;
334+ mutex_lock (& tas5805m -> lock );
335+ /* We mustn't issue any I2C transactions until the I2S
336+ * clock is stable. Furthermore, we must allow a 5ms
337+ * delay after the first set of register writes to
338+ * allow the DSP to boot before configuring it.
339+ */
340+ usleep_range (5000 , 10000 );
341+ send_cfg (rm , dsp_cfg_preboot , ARRAY_SIZE (dsp_cfg_preboot ));
342+ usleep_range (5000 , 15000 );
343+ send_cfg (rm , tas5805m -> dsp_cfg_data , tas5805m -> dsp_cfg_len );
344+
345+ tas5805m -> is_powered = true;
346+ tas5805m_refresh (tas5805m );
347+ mutex_unlock (& tas5805m -> lock );
348+ }
342349
343- default :
344- return - EINVAL ;
350+ static int tas5805m_dac_event (struct snd_soc_dapm_widget * w ,
351+ struct snd_kcontrol * kcontrol , int event )
352+ {
353+ struct snd_soc_component * component = snd_soc_dapm_to_component (w -> dapm );
354+ struct tas5805m_priv * tas5805m =
355+ snd_soc_component_get_drvdata (component );
356+ struct regmap * rm = tas5805m -> regmap ;
357+
358+ if (event & SND_SOC_DAPM_PRE_PMD ) {
359+ unsigned int chan , global1 , global2 ;
360+
361+ dev_dbg (component -> dev , "DSP shutdown\n" );
362+ cancel_work_sync (& tas5805m -> work );
363+
364+ mutex_lock (& tas5805m -> lock );
365+ if (tas5805m -> is_powered ) {
366+ tas5805m -> is_powered = false;
367+
368+ regmap_write (rm , REG_PAGE , 0x00 );
369+ regmap_write (rm , REG_BOOK , 0x00 );
370+
371+ regmap_read (rm , REG_CHAN_FAULT , & chan );
372+ regmap_read (rm , REG_GLOBAL_FAULT1 , & global1 );
373+ regmap_read (rm , REG_GLOBAL_FAULT2 , & global2 );
374+
375+ dev_dbg (component -> dev , "fault regs: CHAN=%02x, "
376+ "GLOBAL1=%02x, GLOBAL2=%02x\n" ,
377+ chan , global1 , global2 );
378+
379+ regmap_write (rm , REG_DEVICE_CTRL_2 , DCTRL2_MODE_HIZ );
380+ }
381+ mutex_unlock (& tas5805m -> lock );
345382 }
346383
347384 return 0 ;
@@ -354,7 +391,8 @@ static const struct snd_soc_dapm_route tas5805m_audio_map[] = {
354391
355392static const struct snd_soc_dapm_widget tas5805m_dapm_widgets [] = {
356393 SND_SOC_DAPM_AIF_IN ("DAC IN" , "Playback" , 0 , SND_SOC_NOPM , 0 , 0 ),
357- SND_SOC_DAPM_DAC ("DAC" , NULL , SND_SOC_NOPM , 0 , 0 ),
394+ SND_SOC_DAPM_DAC_E ("DAC" , NULL , SND_SOC_NOPM , 0 , 0 ,
395+ tas5805m_dac_event , SND_SOC_DAPM_PRE_PMD ),
358396 SND_SOC_DAPM_OUTPUT ("OUT" )
359397};
360398
@@ -375,11 +413,14 @@ static int tas5805m_mute(struct snd_soc_dai *dai, int mute, int direction)
375413 struct tas5805m_priv * tas5805m =
376414 snd_soc_component_get_drvdata (component );
377415
416+ mutex_lock (& tas5805m -> lock );
378417 dev_dbg (component -> dev , "set mute=%d (is_powered=%d)\n" ,
379418 mute , tas5805m -> is_powered );
419+
380420 tas5805m -> is_muted = mute ;
381421 if (tas5805m -> is_powered )
382- tas5805m_refresh (component );
422+ tas5805m_refresh (tas5805m );
423+ mutex_unlock (& tas5805m -> lock );
383424
384425 return 0 ;
385426}
@@ -434,6 +475,7 @@ static int tas5805m_i2c_probe(struct i2c_client *i2c)
434475 if (!tas5805m )
435476 return - ENOMEM ;
436477
478+ tas5805m -> i2c = i2c ;
437479 tas5805m -> pvdd = devm_regulator_get (dev , "pvdd" );
438480 if (IS_ERR (tas5805m -> pvdd )) {
439481 dev_err (dev , "failed to get pvdd supply: %ld\n" ,
@@ -507,6 +549,9 @@ static int tas5805m_i2c_probe(struct i2c_client *i2c)
507549 gpiod_set_value (tas5805m -> gpio_pdn_n , 1 );
508550 usleep_range (10000 , 15000 );
509551
552+ INIT_WORK (& tas5805m -> work , do_work );
553+ mutex_init (& tas5805m -> lock );
554+
510555 /* Don't register through devm. We need to be able to unregister
511556 * the component prior to deasserting PDN#
512557 */
@@ -527,6 +572,7 @@ static void tas5805m_i2c_remove(struct i2c_client *i2c)
527572 struct device * dev = & i2c -> dev ;
528573 struct tas5805m_priv * tas5805m = dev_get_drvdata (dev );
529574
575+ cancel_work_sync (& tas5805m -> work );
530576 snd_soc_unregister_component (dev );
531577 gpiod_set_value (tas5805m -> gpio_pdn_n , 0 );
532578 usleep_range (10000 , 15000 );
0 commit comments