@@ -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 );
@@ -201,6 +203,9 @@ static void tas5805m_refresh(struct snd_soc_component *component)
201
203
set_dsp_scale (rm , 0x24 , tas5805m -> vol [0 ]);
202
204
set_dsp_scale (rm , 0x28 , tas5805m -> vol [1 ]);
203
205
206
+ regmap_write (rm , REG_PAGE , 0x00 );
207
+ regmap_write (rm , REG_BOOK , 0x00 );
208
+
204
209
/* Set/clear digital soft-mute */
205
210
regmap_write (rm , REG_DEVICE_CTRL_2 ,
206
211
(tas5805m -> is_muted ? DCTRL2_MUTE : 0 ) |
@@ -226,8 +231,11 @@ static int tas5805m_vol_get(struct snd_kcontrol *kcontrol,
226
231
struct tas5805m_priv * tas5805m =
227
232
snd_soc_component_get_drvdata (component );
228
233
234
+ mutex_lock (& tas5805m -> lock );
229
235
ucontrol -> value .integer .value [0 ] = tas5805m -> vol [0 ];
230
236
ucontrol -> value .integer .value [1 ] = tas5805m -> vol [1 ];
237
+ mutex_unlock (& tas5805m -> lock );
238
+
231
239
return 0 ;
232
240
}
233
241
@@ -243,11 +251,13 @@ static int tas5805m_vol_put(struct snd_kcontrol *kcontrol,
243
251
snd_soc_kcontrol_component (kcontrol );
244
252
struct tas5805m_priv * tas5805m =
245
253
snd_soc_component_get_drvdata (component );
254
+ int ret = 0 ;
246
255
247
256
if (!(volume_is_valid (ucontrol -> value .integer .value [0 ]) &&
248
257
volume_is_valid (ucontrol -> value .integer .value [1 ])))
249
258
return - EINVAL ;
250
259
260
+ mutex_lock (& tas5805m -> lock );
251
261
if (tas5805m -> vol [0 ] != ucontrol -> value .integer .value [0 ] ||
252
262
tas5805m -> vol [1 ] != ucontrol -> value .integer .value [1 ]) {
253
263
tas5805m -> vol [0 ] = ucontrol -> value .integer .value [0 ];
@@ -256,11 +266,12 @@ static int tas5805m_vol_put(struct snd_kcontrol *kcontrol,
256
266
tas5805m -> vol [0 ], tas5805m -> vol [1 ],
257
267
tas5805m -> is_powered );
258
268
if (tas5805m -> is_powered )
259
- tas5805m_refresh (component );
260
- return 1 ;
269
+ tas5805m_refresh (tas5805m );
270
+ ret = 1 ;
261
271
}
272
+ mutex_unlock (& tas5805m -> lock );
262
273
263
- return 0 ;
274
+ return ret ;
264
275
}
265
276
266
277
static const struct snd_kcontrol_new tas5805m_snd_controls [] = {
@@ -294,54 +305,83 @@ static int tas5805m_trigger(struct snd_pcm_substream *substream, int cmd,
294
305
struct snd_soc_component * component = dai -> component ;
295
306
struct tas5805m_priv * tas5805m =
296
307
snd_soc_component_get_drvdata (component );
297
- struct regmap * rm = tas5805m -> regmap ;
298
- unsigned int chan , global1 , global2 ;
299
308
300
309
switch (cmd ) {
301
310
case SNDRV_PCM_TRIGGER_START :
302
311
case SNDRV_PCM_TRIGGER_RESUME :
303
312
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 );
320
315
break ;
321
316
322
317
case SNDRV_PCM_TRIGGER_STOP :
323
318
case SNDRV_PCM_TRIGGER_SUSPEND :
324
319
case SNDRV_PCM_TRIGGER_PAUSE_PUSH :
325
- dev_dbg ( component -> dev , "DSP shutdown\n" ) ;
320
+ break ;
326
321
327
- tas5805m -> is_powered = false;
322
+ default :
323
+ return - EINVAL ;
324
+ }
328
325
329
- regmap_write ( rm , REG_PAGE , 0x00 ) ;
330
- regmap_write ( rm , REG_BOOK , 0x00 );
326
+ return 0 ;
327
+ }
331
328
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 ;
335
334
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" );
339
336
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
+ }
342
352
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 );
345
385
}
346
386
347
387
return 0 ;
@@ -354,7 +394,8 @@ static const struct snd_soc_dapm_route tas5805m_audio_map[] = {
354
394
355
395
static const struct snd_soc_dapm_widget tas5805m_dapm_widgets [] = {
356
396
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 ),
358
399
SND_SOC_DAPM_OUTPUT ("OUT" )
359
400
};
360
401
@@ -375,11 +416,14 @@ static int tas5805m_mute(struct snd_soc_dai *dai, int mute, int direction)
375
416
struct tas5805m_priv * tas5805m =
376
417
snd_soc_component_get_drvdata (component );
377
418
419
+ mutex_lock (& tas5805m -> lock );
378
420
dev_dbg (component -> dev , "set mute=%d (is_powered=%d)\n" ,
379
421
mute , tas5805m -> is_powered );
422
+
380
423
tas5805m -> is_muted = mute ;
381
424
if (tas5805m -> is_powered )
382
- tas5805m_refresh (component );
425
+ tas5805m_refresh (tas5805m );
426
+ mutex_unlock (& tas5805m -> lock );
383
427
384
428
return 0 ;
385
429
}
@@ -434,6 +478,7 @@ static int tas5805m_i2c_probe(struct i2c_client *i2c)
434
478
if (!tas5805m )
435
479
return - ENOMEM ;
436
480
481
+ tas5805m -> i2c = i2c ;
437
482
tas5805m -> pvdd = devm_regulator_get (dev , "pvdd" );
438
483
if (IS_ERR (tas5805m -> pvdd )) {
439
484
dev_err (dev , "failed to get pvdd supply: %ld\n" ,
@@ -507,6 +552,9 @@ static int tas5805m_i2c_probe(struct i2c_client *i2c)
507
552
gpiod_set_value (tas5805m -> gpio_pdn_n , 1 );
508
553
usleep_range (10000 , 15000 );
509
554
555
+ INIT_WORK (& tas5805m -> work , do_work );
556
+ mutex_init (& tas5805m -> lock );
557
+
510
558
/* Don't register through devm. We need to be able to unregister
511
559
* the component prior to deasserting PDN#
512
560
*/
@@ -527,6 +575,7 @@ static void tas5805m_i2c_remove(struct i2c_client *i2c)
527
575
struct device * dev = & i2c -> dev ;
528
576
struct tas5805m_priv * tas5805m = dev_get_drvdata (dev );
529
577
578
+ cancel_work_sync (& tas5805m -> work );
530
579
snd_soc_unregister_component (dev );
531
580
gpiod_set_value (tas5805m -> gpio_pdn_n , 0 );
532
581
usleep_range (10000 , 15000 );
0 commit comments