1
1
/*
2
- * wm8985.c -- WM8985 ALSA SoC Audio driver
2
+ * wm8985.c -- WM8985 / WM8758 ALSA SoC Audio driver
3
3
*
4
4
* Copyright 2010 Wolfson Microelectronics plc
5
- *
6
5
* Author: Dimitris Papastamos <[email protected] >
7
6
*
7
+ * WM8758 support:
8
+ * Copyright: 2016 Barix AG
9
+ * Author: Petr Kulhavy <[email protected] >
10
+ *
8
11
* This program is free software; you can redistribute it and/or modify
9
12
* it under the terms of the GNU General Public License version 2 as
10
13
* published by the Free Software Foundation.
@@ -40,6 +43,11 @@ static const char *wm8985_supply_names[WM8985_NUM_SUPPLIES] = {
40
43
"AVDD2"
41
44
};
42
45
46
+ enum wm8985_type {
47
+ WM8985 ,
48
+ WM8758 ,
49
+ };
50
+
43
51
static const struct reg_default wm8985_reg_defaults [] = {
44
52
{ 1 , 0x0000 }, /* R1 - Power management 1 */
45
53
{ 2 , 0x0000 }, /* R2 - Power management 2 */
@@ -181,6 +189,7 @@ static const int volume_update_regs[] = {
181
189
struct wm8985_priv {
182
190
struct regmap * regmap ;
183
191
struct regulator_bulk_data supplies [WM8985_NUM_SUPPLIES ];
192
+ enum wm8985_type dev_type ;
184
193
unsigned int sysclk ;
185
194
unsigned int bclk ;
186
195
};
@@ -289,7 +298,7 @@ static const char *depth_3d_text[] = {
289
298
};
290
299
static SOC_ENUM_SINGLE_DECL (depth_3d , WM8985_3D_CONTROL , 0 , depth_3d_text ) ;
291
300
292
- static const struct snd_kcontrol_new wm8985_snd_controls [] = {
301
+ static const struct snd_kcontrol_new wm8985_common_snd_controls [] = {
293
302
SOC_SINGLE ("Digital Loopback Switch" , WM8985_COMPANDING_CONTROL ,
294
303
0 , 1 , 0 ),
295
304
@@ -355,10 +364,6 @@ static const struct snd_kcontrol_new wm8985_snd_controls[] = {
355
364
SOC_ENUM ("High Pass Filter Mode" , filter_mode ),
356
365
SOC_SINGLE ("High Pass Filter Cutoff" , WM8985_ADC_CONTROL , 4 , 7 , 0 ),
357
366
358
- SOC_DOUBLE_R_TLV ("Aux Bypass Volume" ,
359
- WM8985_LEFT_MIXER_CTRL , WM8985_RIGHT_MIXER_CTRL , 6 , 7 , 0 ,
360
- aux_tlv ),
361
-
362
367
SOC_DOUBLE_R_TLV ("Input PGA Bypass Volume" ,
363
368
WM8985_LEFT_MIXER_CTRL , WM8985_RIGHT_MIXER_CTRL , 2 , 7 , 0 ,
364
369
bypass_tlv ),
@@ -379,20 +384,30 @@ static const struct snd_kcontrol_new wm8985_snd_controls[] = {
379
384
SOC_SINGLE_TLV ("EQ5 Volume" , WM8985_EQ5_HIGH_SHELF , 0 , 24 , 1 , eq_tlv ),
380
385
381
386
SOC_ENUM ("3D Depth" , depth_3d ),
387
+ };
388
+
389
+ static const struct snd_kcontrol_new wm8985_specific_snd_controls [] = {
390
+ SOC_DOUBLE_R_TLV ("Aux Bypass Volume" ,
391
+ WM8985_LEFT_MIXER_CTRL , WM8985_RIGHT_MIXER_CTRL , 6 , 7 , 0 ,
392
+ aux_tlv ),
382
393
383
394
SOC_ENUM ("Speaker Mode" , speaker_mode )
384
395
};
385
396
386
397
static const struct snd_kcontrol_new left_out_mixer [] = {
387
398
SOC_DAPM_SINGLE ("Line Switch" , WM8985_LEFT_MIXER_CTRL , 1 , 1 , 0 ),
388
- SOC_DAPM_SINGLE ("Aux Switch" , WM8985_LEFT_MIXER_CTRL , 5 , 1 , 0 ),
389
399
SOC_DAPM_SINGLE ("PCM Switch" , WM8985_LEFT_MIXER_CTRL , 0 , 1 , 0 ),
400
+
401
+ /* --- WM8985 only --- */
402
+ SOC_DAPM_SINGLE ("Aux Switch" , WM8985_LEFT_MIXER_CTRL , 5 , 1 , 0 ),
390
403
};
391
404
392
405
static const struct snd_kcontrol_new right_out_mixer [] = {
393
406
SOC_DAPM_SINGLE ("Line Switch" , WM8985_RIGHT_MIXER_CTRL , 1 , 1 , 0 ),
394
- SOC_DAPM_SINGLE ("Aux Switch" , WM8985_RIGHT_MIXER_CTRL , 5 , 1 , 0 ),
395
407
SOC_DAPM_SINGLE ("PCM Switch" , WM8985_RIGHT_MIXER_CTRL , 0 , 1 , 0 ),
408
+
409
+ /* --- WM8985 only --- */
410
+ SOC_DAPM_SINGLE ("Aux Switch" , WM8985_RIGHT_MIXER_CTRL , 5 , 1 , 0 ),
396
411
};
397
412
398
413
static const struct snd_kcontrol_new left_input_mixer [] = {
@@ -410,18 +425,22 @@ static const struct snd_kcontrol_new right_input_mixer[] = {
410
425
static const struct snd_kcontrol_new left_boost_mixer [] = {
411
426
SOC_DAPM_SINGLE_TLV ("L2 Volume" , WM8985_LEFT_ADC_BOOST_CTRL ,
412
427
4 , 7 , 0 , boost_tlv ),
428
+
429
+ /* --- WM8985 only --- */
413
430
SOC_DAPM_SINGLE_TLV ("AUXL Volume" , WM8985_LEFT_ADC_BOOST_CTRL ,
414
431
0 , 7 , 0 , boost_tlv )
415
432
};
416
433
417
434
static const struct snd_kcontrol_new right_boost_mixer [] = {
418
435
SOC_DAPM_SINGLE_TLV ("R2 Volume" , WM8985_RIGHT_ADC_BOOST_CTRL ,
419
436
4 , 7 , 0 , boost_tlv ),
437
+
438
+ /* --- WM8985 only --- */
420
439
SOC_DAPM_SINGLE_TLV ("AUXR Volume" , WM8985_RIGHT_ADC_BOOST_CTRL ,
421
440
0 , 7 , 0 , boost_tlv )
422
441
};
423
442
424
- static const struct snd_soc_dapm_widget wm8985_dapm_widgets [] = {
443
+ static const struct snd_soc_dapm_widget wm8985_common_dapm_widgets [] = {
425
444
SND_SOC_DAPM_DAC ("Left DAC" , "Left Playback" , WM8985_POWER_MANAGEMENT_3 ,
426
445
0 , 0 ),
427
446
SND_SOC_DAPM_DAC ("Right DAC" , "Right Playback" , WM8985_POWER_MANAGEMENT_3 ,
@@ -431,21 +450,11 @@ static const struct snd_soc_dapm_widget wm8985_dapm_widgets[] = {
431
450
SND_SOC_DAPM_ADC ("Right ADC" , "Right Capture" , WM8985_POWER_MANAGEMENT_2 ,
432
451
1 , 0 ),
433
452
434
- SND_SOC_DAPM_MIXER ("Left Output Mixer" , WM8985_POWER_MANAGEMENT_3 ,
435
- 2 , 0 , left_out_mixer , ARRAY_SIZE (left_out_mixer )),
436
- SND_SOC_DAPM_MIXER ("Right Output Mixer" , WM8985_POWER_MANAGEMENT_3 ,
437
- 3 , 0 , right_out_mixer , ARRAY_SIZE (right_out_mixer )),
438
-
439
453
SND_SOC_DAPM_MIXER ("Left Input Mixer" , WM8985_POWER_MANAGEMENT_2 ,
440
454
2 , 0 , left_input_mixer , ARRAY_SIZE (left_input_mixer )),
441
455
SND_SOC_DAPM_MIXER ("Right Input Mixer" , WM8985_POWER_MANAGEMENT_2 ,
442
456
3 , 0 , right_input_mixer , ARRAY_SIZE (right_input_mixer )),
443
457
444
- SND_SOC_DAPM_MIXER ("Left Boost Mixer" , WM8985_POWER_MANAGEMENT_2 ,
445
- 4 , 0 , left_boost_mixer , ARRAY_SIZE (left_boost_mixer )),
446
- SND_SOC_DAPM_MIXER ("Right Boost Mixer" , WM8985_POWER_MANAGEMENT_2 ,
447
- 5 , 0 , right_boost_mixer , ARRAY_SIZE (right_boost_mixer )),
448
-
449
458
SND_SOC_DAPM_PGA ("Left Capture PGA" , WM8985_LEFT_INP_PGA_GAIN_CTRL ,
450
459
6 , 1 , NULL , 0 ),
451
460
SND_SOC_DAPM_PGA ("Right Capture PGA" , WM8985_RIGHT_INP_PGA_GAIN_CTRL ,
@@ -468,8 +477,6 @@ static const struct snd_soc_dapm_widget wm8985_dapm_widgets[] = {
468
477
SND_SOC_DAPM_INPUT ("LIP" ),
469
478
SND_SOC_DAPM_INPUT ("RIN" ),
470
479
SND_SOC_DAPM_INPUT ("RIP" ),
471
- SND_SOC_DAPM_INPUT ("AUXL" ),
472
- SND_SOC_DAPM_INPUT ("AUXR" ),
473
480
SND_SOC_DAPM_INPUT ("L2" ),
474
481
SND_SOC_DAPM_INPUT ("R2" ),
475
482
SND_SOC_DAPM_OUTPUT ("HPL" ),
@@ -478,13 +485,42 @@ static const struct snd_soc_dapm_widget wm8985_dapm_widgets[] = {
478
485
SND_SOC_DAPM_OUTPUT ("SPKR" )
479
486
};
480
487
481
- static const struct snd_soc_dapm_route wm8985_dapm_routes [] = {
488
+ static const struct snd_soc_dapm_widget wm8985_dapm_widgets [] = {
489
+ SND_SOC_DAPM_MIXER ("Left Output Mixer" , WM8985_POWER_MANAGEMENT_3 ,
490
+ 2 , 0 , left_out_mixer , ARRAY_SIZE (left_out_mixer )),
491
+ SND_SOC_DAPM_MIXER ("Right Output Mixer" , WM8985_POWER_MANAGEMENT_3 ,
492
+ 3 , 0 , right_out_mixer , ARRAY_SIZE (right_out_mixer )),
493
+
494
+ SND_SOC_DAPM_MIXER ("Left Boost Mixer" , WM8985_POWER_MANAGEMENT_2 ,
495
+ 4 , 0 , left_boost_mixer , ARRAY_SIZE (left_boost_mixer )),
496
+ SND_SOC_DAPM_MIXER ("Right Boost Mixer" , WM8985_POWER_MANAGEMENT_2 ,
497
+ 5 , 0 , right_boost_mixer , ARRAY_SIZE (right_boost_mixer )),
498
+
499
+ SND_SOC_DAPM_INPUT ("AUXL" ),
500
+ SND_SOC_DAPM_INPUT ("AUXR" ),
501
+ };
502
+
503
+ static const struct snd_soc_dapm_widget wm8758_dapm_widgets [] = {
504
+ SND_SOC_DAPM_MIXER ("Left Output Mixer" , WM8985_POWER_MANAGEMENT_3 ,
505
+ 2 , 0 , left_out_mixer ,
506
+ ARRAY_SIZE (left_out_mixer ) - 1 ),
507
+ SND_SOC_DAPM_MIXER ("Right Output Mixer" , WM8985_POWER_MANAGEMENT_3 ,
508
+ 3 , 0 , right_out_mixer ,
509
+ ARRAY_SIZE (right_out_mixer ) - 1 ),
510
+
511
+ SND_SOC_DAPM_MIXER ("Left Boost Mixer" , WM8985_POWER_MANAGEMENT_2 ,
512
+ 4 , 0 , left_boost_mixer ,
513
+ ARRAY_SIZE (left_boost_mixer ) - 1 ),
514
+ SND_SOC_DAPM_MIXER ("Right Boost Mixer" , WM8985_POWER_MANAGEMENT_2 ,
515
+ 5 , 0 , right_boost_mixer ,
516
+ ARRAY_SIZE (right_boost_mixer ) - 1 ),
517
+ };
518
+
519
+ static const struct snd_soc_dapm_route wm8985_common_dapm_routes [] = {
482
520
{ "Right Output Mixer" , "PCM Switch" , "Right DAC" },
483
- { "Right Output Mixer" , "Aux Switch" , "AUXR" },
484
521
{ "Right Output Mixer" , "Line Switch" , "Right Boost Mixer" },
485
522
486
523
{ "Left Output Mixer" , "PCM Switch" , "Left DAC" },
487
- { "Left Output Mixer" , "Aux Switch" , "AUXL" },
488
524
{ "Left Output Mixer" , "Line Switch" , "Left Boost Mixer" },
489
525
490
526
{ "Right Headphone Out" , NULL , "Right Output Mixer" },
@@ -501,13 +537,11 @@ static const struct snd_soc_dapm_route wm8985_dapm_routes[] = {
501
537
502
538
{ "Right ADC" , NULL , "Right Boost Mixer" },
503
539
504
- { "Right Boost Mixer" , "AUXR Volume" , "AUXR" },
505
540
{ "Right Boost Mixer" , NULL , "Right Capture PGA" },
506
541
{ "Right Boost Mixer" , "R2 Volume" , "R2" },
507
542
508
543
{ "Left ADC" , NULL , "Left Boost Mixer" },
509
544
510
- { "Left Boost Mixer" , "AUXL Volume" , "AUXL" },
511
545
{ "Left Boost Mixer" , NULL , "Left Capture PGA" },
512
546
{ "Left Boost Mixer" , "L2 Volume" , "L2" },
513
547
@@ -522,6 +556,38 @@ static const struct snd_soc_dapm_route wm8985_dapm_routes[] = {
522
556
{ "Left Input Mixer" , "MicN Switch" , "LIN" },
523
557
{ "Left Input Mixer" , "MicP Switch" , "LIP" },
524
558
};
559
+ static const struct snd_soc_dapm_route wm8985_aux_dapm_routes [] = {
560
+ { "Right Output Mixer" , "Aux Switch" , "AUXR" },
561
+ { "Left Output Mixer" , "Aux Switch" , "AUXL" },
562
+
563
+ { "Right Boost Mixer" , "AUXR Volume" , "AUXR" },
564
+ { "Left Boost Mixer" , "AUXL Volume" , "AUXL" },
565
+ };
566
+
567
+ static int wm8985_add_widgets (struct snd_soc_codec * codec )
568
+ {
569
+ struct wm8985_priv * wm8985 = snd_soc_codec_get_drvdata (codec );
570
+ struct snd_soc_dapm_context * dapm = snd_soc_codec_get_dapm (codec );
571
+
572
+ switch (wm8985 -> dev_type ) {
573
+ case WM8758 :
574
+ snd_soc_dapm_new_controls (dapm , wm8758_dapm_widgets ,
575
+ ARRAY_SIZE (wm8758_dapm_widgets ));
576
+ break ;
577
+
578
+ case WM8985 :
579
+ snd_soc_add_codec_controls (codec , wm8985_specific_snd_controls ,
580
+ ARRAY_SIZE (wm8985_specific_snd_controls ));
581
+
582
+ snd_soc_dapm_new_controls (dapm , wm8985_dapm_widgets ,
583
+ ARRAY_SIZE (wm8985_dapm_widgets ));
584
+ snd_soc_dapm_add_routes (dapm , wm8985_aux_dapm_routes ,
585
+ ARRAY_SIZE (wm8985_aux_dapm_routes ));
586
+ break ;
587
+ }
588
+
589
+ return 0 ;
590
+ }
525
591
526
592
static int eqmode_get (struct snd_kcontrol * kcontrol ,
527
593
struct snd_ctl_elem_value * ucontrol )
@@ -999,6 +1065,8 @@ static int wm8985_probe(struct snd_soc_codec *codec)
999
1065
snd_soc_update_bits (codec , WM8985_BIAS_CTRL , WM8985_BIASCUT ,
1000
1066
WM8985_BIASCUT );
1001
1067
1068
+ wm8985_add_widgets (codec );
1069
+
1002
1070
return 0 ;
1003
1071
1004
1072
err_reg_enable :
@@ -1042,12 +1110,12 @@ static struct snd_soc_codec_driver soc_codec_dev_wm8985 = {
1042
1110
.set_bias_level = wm8985_set_bias_level ,
1043
1111
.suspend_bias_off = true,
1044
1112
1045
- .controls = wm8985_snd_controls ,
1046
- .num_controls = ARRAY_SIZE (wm8985_snd_controls ),
1047
- .dapm_widgets = wm8985_dapm_widgets ,
1048
- .num_dapm_widgets = ARRAY_SIZE (wm8985_dapm_widgets ),
1049
- .dapm_routes = wm8985_dapm_routes ,
1050
- .num_dapm_routes = ARRAY_SIZE (wm8985_dapm_routes ),
1113
+ .controls = wm8985_common_snd_controls ,
1114
+ .num_controls = ARRAY_SIZE (wm8985_common_snd_controls ),
1115
+ .dapm_widgets = wm8985_common_dapm_widgets ,
1116
+ .num_dapm_widgets = ARRAY_SIZE (wm8985_common_dapm_widgets ),
1117
+ .dapm_routes = wm8985_common_dapm_routes ,
1118
+ .num_dapm_routes = ARRAY_SIZE (wm8985_common_dapm_routes ),
1051
1119
};
1052
1120
1053
1121
static const struct regmap_config wm8985_regmap = {
@@ -1074,6 +1142,8 @@ static int wm8985_spi_probe(struct spi_device *spi)
1074
1142
1075
1143
spi_set_drvdata (spi , wm8985 );
1076
1144
1145
+ wm8985 -> dev_type = WM8985 ;
1146
+
1077
1147
wm8985 -> regmap = devm_regmap_init_spi (spi , & wm8985_regmap );
1078
1148
if (IS_ERR (wm8985 -> regmap )) {
1079
1149
ret = PTR_ERR (wm8985 -> regmap );
@@ -1115,6 +1185,8 @@ static int wm8985_i2c_probe(struct i2c_client *i2c,
1115
1185
1116
1186
i2c_set_clientdata (i2c , wm8985 );
1117
1187
1188
+ wm8985 -> dev_type = id -> driver_data ;
1189
+
1118
1190
wm8985 -> regmap = devm_regmap_init_i2c (i2c , & wm8985_regmap );
1119
1191
if (IS_ERR (wm8985 -> regmap )) {
1120
1192
ret = PTR_ERR (wm8985 -> regmap );
@@ -1135,7 +1207,8 @@ static int wm8985_i2c_remove(struct i2c_client *i2c)
1135
1207
}
1136
1208
1137
1209
static const struct i2c_device_id wm8985_i2c_id [] = {
1138
- { "wm8985" , 0 },
1210
+ { "wm8985" , WM8985 },
1211
+ { "wm8758" , WM8758 },
1139
1212
{ }
1140
1213
};
1141
1214
MODULE_DEVICE_TABLE (i2c , wm8985_i2c_id );
@@ -1183,6 +1256,6 @@ static void __exit wm8985_exit(void)
1183
1256
}
1184
1257
module_exit (wm8985_exit );
1185
1258
1186
- MODULE_DESCRIPTION ("ASoC WM8985 driver" );
1259
+ MODULE_DESCRIPTION ("ASoC WM8985 / WM8758 driver" );
1187
1260
MODULE_AUTHOR (
"Dimitris Papastamos <[email protected] >" );
1188
1261
MODULE_LICENSE ("GPL" );
0 commit comments