@@ -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 );
@@ -201,6 +203,9 @@ static void tas5805m_refresh(struct snd_soc_component *component)
201203 set_dsp_scale (rm , 0x24 , tas5805m -> vol [0 ]);
202204 set_dsp_scale (rm , 0x28 , tas5805m -> vol [1 ]);
203205
206+ regmap_write (rm , REG_PAGE , 0x00 );
207+ regmap_write (rm , REG_BOOK , 0x00 );
208+
204209 /* Set/clear digital soft-mute */
205210 regmap_write (rm , REG_DEVICE_CTRL_2 ,
206211 (tas5805m -> is_muted ? DCTRL2_MUTE : 0 ) |
@@ -226,8 +231,11 @@ static int tas5805m_vol_get(struct snd_kcontrol *kcontrol,
226231 struct tas5805m_priv * tas5805m =
227232 snd_soc_component_get_drvdata (component );
228233
234+ mutex_lock (& tas5805m -> lock );
229235 ucontrol -> value .integer .value [0 ] = tas5805m -> vol [0 ];
230236 ucontrol -> value .integer .value [1 ] = tas5805m -> vol [1 ];
237+ mutex_unlock (& tas5805m -> lock );
238+
231239 return 0 ;
232240}
233241
@@ -243,11 +251,13 @@ static int tas5805m_vol_put(struct snd_kcontrol *kcontrol,
243251 snd_soc_kcontrol_component (kcontrol );
244252 struct tas5805m_priv * tas5805m =
245253 snd_soc_component_get_drvdata (component );
254+ int ret = 0 ;
246255
247256 if (!(volume_is_valid (ucontrol -> value .integer .value [0 ]) &&
248257 volume_is_valid (ucontrol -> value .integer .value [1 ])))
249258 return - EINVAL ;
250259
260+ mutex_lock (& tas5805m -> lock );
251261 if (tas5805m -> vol [0 ] != ucontrol -> value .integer .value [0 ] ||
252262 tas5805m -> vol [1 ] != ucontrol -> value .integer .value [1 ]) {
253263 tas5805m -> vol [0 ] = ucontrol -> value .integer .value [0 ];
@@ -256,11 +266,12 @@ static int tas5805m_vol_put(struct snd_kcontrol *kcontrol,
256266 tas5805m -> vol [0 ], tas5805m -> vol [1 ],
257267 tas5805m -> is_powered );
258268 if (tas5805m -> is_powered )
259- tas5805m_refresh (component );
260- return 1 ;
269+ tas5805m_refresh (tas5805m );
270+ ret = 1 ;
261271 }
272+ mutex_unlock (& tas5805m -> lock );
262273
263- return 0 ;
274+ return ret ;
264275}
265276
266277static const struct snd_kcontrol_new tas5805m_snd_controls [] = {
@@ -294,54 +305,83 @@ static int tas5805m_trigger(struct snd_pcm_substream *substream, int cmd,
294305 struct snd_soc_component * component = dai -> component ;
295306 struct tas5805m_priv * tas5805m =
296307 snd_soc_component_get_drvdata (component );
297- struct regmap * rm = tas5805m -> regmap ;
298- unsigned int chan , global1 , global2 ;
299308
300309 switch (cmd ) {
301310 case SNDRV_PCM_TRIGGER_START :
302311 case SNDRV_PCM_TRIGGER_RESUME :
303312 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 );
313+ dev_dbg (component -> dev , "clock start\n" );
314+ schedule_work (& tas5805m -> work );
320315 break ;
321316
322317 case SNDRV_PCM_TRIGGER_STOP :
323318 case SNDRV_PCM_TRIGGER_SUSPEND :
324319 case SNDRV_PCM_TRIGGER_PAUSE_PUSH :
325- dev_dbg ( component -> dev , "DSP shutdown\n" ) ;
320+ break ;
326321
327- tas5805m -> is_powered = false;
322+ default :
323+ return - EINVAL ;
324+ }
328325
329- regmap_write ( rm , REG_PAGE , 0x00 ) ;
330- regmap_write ( rm , REG_BOOK , 0x00 );
326+ return 0 ;
327+ }
331328
332- regmap_read (rm , REG_CHAN_FAULT , & chan );
333- regmap_read (rm , REG_GLOBAL_FAULT1 , & global1 );
334- regmap_read (rm , REG_GLOBAL_FAULT2 , & global2 );
329+ static void do_work (struct work_struct * work )
330+ {
331+ struct tas5805m_priv * tas5805m =
332+ container_of (work , struct tas5805m_priv , work );
333+ struct regmap * rm = tas5805m -> regmap ;
335334
336- dev_dbg (component -> dev ,
337- "fault regs: CHAN=%02x, GLOBAL1=%02x, GLOBAL2=%02x\n" ,
338- chan , global1 , global2 );
335+ dev_dbg (& tas5805m -> i2c -> dev , "DSP startup\n" );
339336
340- regmap_write (rm , REG_DEVICE_CTRL_2 , DCTRL2_MODE_HIZ );
341- break ;
337+ mutex_lock (& tas5805m -> lock );
338+ /* We mustn't issue any I2C transactions until the I2S
339+ * clock is stable. Furthermore, we must allow a 5ms
340+ * delay after the first set of register writes to
341+ * allow the DSP to boot before configuring it.
342+ */
343+ usleep_range (5000 , 10000 );
344+ send_cfg (rm , dsp_cfg_preboot , ARRAY_SIZE (dsp_cfg_preboot ));
345+ usleep_range (5000 , 15000 );
346+ send_cfg (rm , tas5805m -> dsp_cfg_data , tas5805m -> dsp_cfg_len );
347+
348+ tas5805m -> is_powered = true;
349+ tas5805m_refresh (tas5805m );
350+ mutex_unlock (& tas5805m -> lock );
351+ }
342352
343- default :
344- return - EINVAL ;
353+ static int tas5805m_dac_event (struct snd_soc_dapm_widget * w ,
354+ struct snd_kcontrol * kcontrol , int event )
355+ {
356+ struct snd_soc_component * component = snd_soc_dapm_to_component (w -> dapm );
357+ struct tas5805m_priv * tas5805m =
358+ snd_soc_component_get_drvdata (component );
359+ struct regmap * rm = tas5805m -> regmap ;
360+
361+ if (event & SND_SOC_DAPM_PRE_PMD ) {
362+ unsigned int chan , global1 , global2 ;
363+
364+ dev_dbg (component -> dev , "DSP shutdown\n" );
365+ cancel_work_sync (& tas5805m -> work );
366+
367+ mutex_lock (& tas5805m -> lock );
368+ if (tas5805m -> is_powered ) {
369+ tas5805m -> is_powered = false;
370+
371+ regmap_write (rm , REG_PAGE , 0x00 );
372+ regmap_write (rm , REG_BOOK , 0x00 );
373+
374+ regmap_read (rm , REG_CHAN_FAULT , & chan );
375+ regmap_read (rm , REG_GLOBAL_FAULT1 , & global1 );
376+ regmap_read (rm , REG_GLOBAL_FAULT2 , & global2 );
377+
378+ dev_dbg (component -> dev , "fault regs: CHAN=%02x, "
379+ "GLOBAL1=%02x, GLOBAL2=%02x\n" ,
380+ chan , global1 , global2 );
381+
382+ regmap_write (rm , REG_DEVICE_CTRL_2 , DCTRL2_MODE_HIZ );
383+ }
384+ mutex_unlock (& tas5805m -> lock );
345385 }
346386
347387 return 0 ;
@@ -354,7 +394,8 @@ static const struct snd_soc_dapm_route tas5805m_audio_map[] = {
354394
355395static const struct snd_soc_dapm_widget tas5805m_dapm_widgets [] = {
356396 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 ),
397+ SND_SOC_DAPM_DAC_E ("DAC" , NULL , SND_SOC_NOPM , 0 , 0 ,
398+ tas5805m_dac_event , SND_SOC_DAPM_PRE_PMD ),
358399 SND_SOC_DAPM_OUTPUT ("OUT" )
359400};
360401
@@ -375,11 +416,14 @@ static int tas5805m_mute(struct snd_soc_dai *dai, int mute, int direction)
375416 struct tas5805m_priv * tas5805m =
376417 snd_soc_component_get_drvdata (component );
377418
419+ mutex_lock (& tas5805m -> lock );
378420 dev_dbg (component -> dev , "set mute=%d (is_powered=%d)\n" ,
379421 mute , tas5805m -> is_powered );
422+
380423 tas5805m -> is_muted = mute ;
381424 if (tas5805m -> is_powered )
382- tas5805m_refresh (component );
425+ tas5805m_refresh (tas5805m );
426+ mutex_unlock (& tas5805m -> lock );
383427
384428 return 0 ;
385429}
@@ -434,6 +478,7 @@ static int tas5805m_i2c_probe(struct i2c_client *i2c)
434478 if (!tas5805m )
435479 return - ENOMEM ;
436480
481+ tas5805m -> i2c = i2c ;
437482 tas5805m -> pvdd = devm_regulator_get (dev , "pvdd" );
438483 if (IS_ERR (tas5805m -> pvdd )) {
439484 dev_err (dev , "failed to get pvdd supply: %ld\n" ,
@@ -507,6 +552,9 @@ static int tas5805m_i2c_probe(struct i2c_client *i2c)
507552 gpiod_set_value (tas5805m -> gpio_pdn_n , 1 );
508553 usleep_range (10000 , 15000 );
509554
555+ INIT_WORK (& tas5805m -> work , do_work );
556+ mutex_init (& tas5805m -> lock );
557+
510558 /* Don't register through devm. We need to be able to unregister
511559 * the component prior to deasserting PDN#
512560 */
@@ -527,6 +575,7 @@ static void tas5805m_i2c_remove(struct i2c_client *i2c)
527575 struct device * dev = & i2c -> dev ;
528576 struct tas5805m_priv * tas5805m = dev_get_drvdata (dev );
529577
578+ cancel_work_sync (& tas5805m -> work );
530579 snd_soc_unregister_component (dev );
531580 gpiod_set_value (tas5805m -> gpio_pdn_n , 0 );
532581 usleep_range (10000 , 15000 );
0 commit comments