@@ -154,6 +154,7 @@ static const uint32_t tas5805m_volume[] = {
154
154
#define TAS5805M_VOLUME_MIN 0
155
155
156
156
struct tas5805m_priv {
157
+ struct i2c_client * i2c ;
157
158
struct regulator * pvdd ;
158
159
struct gpio_desc * gpio_pdn_n ;
159
160
@@ -165,6 +166,9 @@ struct tas5805m_priv {
165
166
int vol [2 ];
166
167
bool is_powered ;
167
168
bool is_muted ;
169
+
170
+ struct work_struct work ;
171
+ struct mutex lock ;
168
172
};
169
173
170
174
static 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)
181
185
regmap_bulk_write (rm , offset , v , ARRAY_SIZE (v ));
182
186
}
183
187
184
- static void tas5805m_refresh (struct snd_soc_component * component )
188
+ static void tas5805m_refresh (struct tas5805m_priv * tas5805m )
185
189
{
186
- struct tas5805m_priv * tas5805m =
187
- snd_soc_component_get_drvdata (component );
188
190
struct regmap * rm = tas5805m -> regmap ;
189
191
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" ,
191
193
tas5805m -> is_muted , tas5805m -> vol [0 ], tas5805m -> vol [1 ]);
192
194
193
195
regmap_write (rm , REG_PAGE , 0x00 );
@@ -226,8 +228,11 @@ static int tas5805m_vol_get(struct snd_kcontrol *kcontrol,
226
228
struct tas5805m_priv * tas5805m =
227
229
snd_soc_component_get_drvdata (component );
228
230
231
+ mutex_lock (& tas5805m -> lock );
229
232
ucontrol -> value .integer .value [0 ] = tas5805m -> vol [0 ];
230
233
ucontrol -> value .integer .value [1 ] = tas5805m -> vol [1 ];
234
+ mutex_unlock (& tas5805m -> lock );
235
+
231
236
return 0 ;
232
237
}
233
238
@@ -243,11 +248,13 @@ static int tas5805m_vol_put(struct snd_kcontrol *kcontrol,
243
248
snd_soc_kcontrol_component (kcontrol );
244
249
struct tas5805m_priv * tas5805m =
245
250
snd_soc_component_get_drvdata (component );
251
+ int ret = 0 ;
246
252
247
253
if (!(volume_is_valid (ucontrol -> value .integer .value [0 ]) &&
248
254
volume_is_valid (ucontrol -> value .integer .value [1 ])))
249
255
return - EINVAL ;
250
256
257
+ mutex_lock (& tas5805m -> lock );
251
258
if (tas5805m -> vol [0 ] != ucontrol -> value .integer .value [0 ] ||
252
259
tas5805m -> vol [1 ] != ucontrol -> value .integer .value [1 ]) {
253
260
tas5805m -> vol [0 ] = ucontrol -> value .integer .value [0 ];
@@ -256,11 +263,12 @@ static int tas5805m_vol_put(struct snd_kcontrol *kcontrol,
256
263
tas5805m -> vol [0 ], tas5805m -> vol [1 ],
257
264
tas5805m -> is_powered );
258
265
if (tas5805m -> is_powered )
259
- tas5805m_refresh (component );
260
- return 1 ;
266
+ tas5805m_refresh (tas5805m );
267
+ ret = 1 ;
261
268
}
269
+ mutex_unlock (& tas5805m -> lock );
262
270
263
- return 0 ;
271
+ return ret ;
264
272
}
265
273
266
274
static const struct snd_kcontrol_new tas5805m_snd_controls [] = {
@@ -294,54 +302,83 @@ static int tas5805m_trigger(struct snd_pcm_substream *substream, int cmd,
294
302
struct snd_soc_component * component = dai -> component ;
295
303
struct tas5805m_priv * tas5805m =
296
304
snd_soc_component_get_drvdata (component );
297
- struct regmap * rm = tas5805m -> regmap ;
298
- unsigned int chan , global1 , global2 ;
299
305
300
306
switch (cmd ) {
301
307
case SNDRV_PCM_TRIGGER_START :
302
308
case SNDRV_PCM_TRIGGER_RESUME :
303
309
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 );
320
312
break ;
321
313
322
314
case SNDRV_PCM_TRIGGER_STOP :
323
315
case SNDRV_PCM_TRIGGER_SUSPEND :
324
316
case SNDRV_PCM_TRIGGER_PAUSE_PUSH :
325
- dev_dbg ( component -> dev , "DSP shutdown\n" ) ;
317
+ break ;
326
318
327
- tas5805m -> is_powered = false;
319
+ default :
320
+ return - EINVAL ;
321
+ }
328
322
329
- regmap_write ( rm , REG_PAGE , 0x00 ) ;
330
- regmap_write ( rm , REG_BOOK , 0x00 );
323
+ return 0 ;
324
+ }
331
325
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 ;
335
331
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" );
339
333
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
+ }
342
349
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 );
345
382
}
346
383
347
384
return 0 ;
@@ -354,7 +391,8 @@ static const struct snd_soc_dapm_route tas5805m_audio_map[] = {
354
391
355
392
static const struct snd_soc_dapm_widget tas5805m_dapm_widgets [] = {
356
393
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 ),
358
396
SND_SOC_DAPM_OUTPUT ("OUT" )
359
397
};
360
398
@@ -375,11 +413,14 @@ static int tas5805m_mute(struct snd_soc_dai *dai, int mute, int direction)
375
413
struct tas5805m_priv * tas5805m =
376
414
snd_soc_component_get_drvdata (component );
377
415
416
+ mutex_lock (& tas5805m -> lock );
378
417
dev_dbg (component -> dev , "set mute=%d (is_powered=%d)\n" ,
379
418
mute , tas5805m -> is_powered );
419
+
380
420
tas5805m -> is_muted = mute ;
381
421
if (tas5805m -> is_powered )
382
- tas5805m_refresh (component );
422
+ tas5805m_refresh (tas5805m );
423
+ mutex_unlock (& tas5805m -> lock );
383
424
384
425
return 0 ;
385
426
}
@@ -434,6 +475,7 @@ static int tas5805m_i2c_probe(struct i2c_client *i2c)
434
475
if (!tas5805m )
435
476
return - ENOMEM ;
436
477
478
+ tas5805m -> i2c = i2c ;
437
479
tas5805m -> pvdd = devm_regulator_get (dev , "pvdd" );
438
480
if (IS_ERR (tas5805m -> pvdd )) {
439
481
dev_err (dev , "failed to get pvdd supply: %ld\n" ,
@@ -507,6 +549,9 @@ static int tas5805m_i2c_probe(struct i2c_client *i2c)
507
549
gpiod_set_value (tas5805m -> gpio_pdn_n , 1 );
508
550
usleep_range (10000 , 15000 );
509
551
552
+ INIT_WORK (& tas5805m -> work , do_work );
553
+ mutex_init (& tas5805m -> lock );
554
+
510
555
/* Don't register through devm. We need to be able to unregister
511
556
* the component prior to deasserting PDN#
512
557
*/
@@ -527,6 +572,7 @@ static void tas5805m_i2c_remove(struct i2c_client *i2c)
527
572
struct device * dev = & i2c -> dev ;
528
573
struct tas5805m_priv * tas5805m = dev_get_drvdata (dev );
529
574
575
+ cancel_work_sync (& tas5805m -> work );
530
576
snd_soc_unregister_component (dev );
531
577
gpiod_set_value (tas5805m -> gpio_pdn_n , 0 );
532
578
usleep_range (10000 , 15000 );
0 commit comments