10
10
*/
11
11
12
12
#include <linux/acpi.h>
13
+ #include <linux/bitfield.h>
13
14
#include <linux/clk.h>
14
15
#include <linux/device.h>
15
16
#include <linux/init.h>
@@ -37,10 +38,17 @@ struct byt_wm5102_private {
37
38
int mclk_freq ;
38
39
};
39
40
40
- /* Bits 0-15 are reserved for things like an input-map */
41
+ /* Bits 0-3 are reserved for the input-map */
42
+ #define BYT_WM5102_OUT_MAP GENMASK(7, 4)
41
43
#define BYT_WM5102_SSP2 BIT(16)
42
44
#define BYT_WM5102_MCLK_19_2MHZ BIT(17)
43
45
46
+ /* Note these values are pre-shifted for easy use of setting quirks */
47
+ enum {
48
+ BYT_WM5102_SPK_SPK_MAP = FIELD_PREP_CONST (BYT_WM5102_OUT_MAP , 0 ),
49
+ BYT_WM5102_SPK_HPOUT2_MAP = FIELD_PREP_CONST (BYT_WM5102_OUT_MAP , 1 ),
50
+ };
51
+
44
52
static unsigned long quirk ;
45
53
46
54
static int quirk_override = -1 ;
@@ -49,6 +57,20 @@ MODULE_PARM_DESC(quirk, "Board-specific quirk override");
49
57
50
58
static void log_quirks (struct device * dev )
51
59
{
60
+ switch (quirk & BYT_WM5102_OUT_MAP ) {
61
+ case BYT_WM5102_SPK_SPK_MAP :
62
+ dev_info_once (dev , "quirk SPK_SPK_MAP enabled\n" );
63
+ break ;
64
+ case BYT_WM5102_SPK_HPOUT2_MAP :
65
+ dev_info_once (dev , "quirk SPK_HPOUT2_MAP enabled\n" );
66
+ break ;
67
+ default :
68
+ dev_warn_once (dev , "quirk sets invalid output map: 0x%lx, defaulting to SPK_SPK_MAP\n" ,
69
+ quirk & BYT_WM5102_OUT_MAP );
70
+ quirk &= ~BYT_WM5102_OUT_MAP ;
71
+ quirk |= BYT_WM5102_SPK_SPK_MAP ;
72
+ break ;
73
+ }
52
74
if (quirk & BYT_WM5102_SSP2 )
53
75
dev_info_once (dev , "quirk SSP2 enabled" );
54
76
if (quirk & BYT_WM5102_MCLK_19_2MHZ )
@@ -164,12 +186,6 @@ static const struct snd_soc_dapm_route byt_wm5102_audio_map[] = {
164
186
{"Headset Mic" , NULL , "Platform Clock" },
165
187
{"Internal Mic" , NULL , "Platform Clock" },
166
188
{"Speaker" , NULL , "Platform Clock" },
167
- {"Line Out" , NULL , "Platform Clock" },
168
-
169
- {"Speaker" , NULL , "SPKOUTLP" },
170
- {"Speaker" , NULL , "SPKOUTLN" },
171
- {"Speaker" , NULL , "SPKOUTRP" },
172
- {"Speaker" , NULL , "SPKOUTRN" },
173
189
{"Speaker" , NULL , "Speaker VDD" },
174
190
175
191
{"Headphone" , NULL , "HPOUT1L" },
@@ -203,6 +219,18 @@ static const struct snd_soc_dapm_route bytcr_wm5102_ssp2_map[] = {
203
219
{"ssp2 Rx" , NULL , "AIF1 Capture" },
204
220
};
205
221
222
+ static const struct snd_soc_dapm_route byt_wm5102_spk_spk_map [] = {
223
+ {"Speaker" , NULL , "SPKOUTLP" },
224
+ {"Speaker" , NULL , "SPKOUTLN" },
225
+ {"Speaker" , NULL , "SPKOUTRP" },
226
+ {"Speaker" , NULL , "SPKOUTRN" },
227
+ };
228
+
229
+ static const struct snd_soc_dapm_route byt_wm5102_spk_hpout2_map [] = {
230
+ {"Speaker" , NULL , "HPOUT2L" },
231
+ {"Speaker" , NULL , "HPOUT2R" },
232
+ };
233
+
206
234
static const struct snd_kcontrol_new byt_wm5102_controls [] = {
207
235
SOC_DAPM_PIN_SWITCH ("Headphone" ),
208
236
SOC_DAPM_PIN_SWITCH ("Headset Mic" ),
@@ -243,6 +271,20 @@ static int byt_wm5102_init(struct snd_soc_pcm_runtime *runtime)
243
271
return ret ;
244
272
}
245
273
274
+ switch (quirk & BYT_WM5102_OUT_MAP ) {
275
+ case BYT_WM5102_SPK_SPK_MAP :
276
+ custom_map = byt_wm5102_spk_spk_map ;
277
+ num_routes = ARRAY_SIZE (byt_wm5102_spk_spk_map );
278
+ break ;
279
+ case BYT_WM5102_SPK_HPOUT2_MAP :
280
+ custom_map = byt_wm5102_spk_hpout2_map ;
281
+ num_routes = ARRAY_SIZE (byt_wm5102_spk_hpout2_map );
282
+ break ;
283
+ }
284
+ ret = snd_soc_dapm_add_routes (& card -> dapm , custom_map , num_routes );
285
+ if (ret )
286
+ return ret ;
287
+
246
288
if (quirk & BYT_WM5102_SSP2 ) {
247
289
custom_map = bytcr_wm5102_ssp2_map ;
248
290
num_routes = ARRAY_SIZE (bytcr_wm5102_ssp2_map );
@@ -434,8 +476,11 @@ static struct snd_soc_card byt_wm5102_card = {
434
476
.fully_routed = true,
435
477
};
436
478
479
+ static char byt_wm5102_components [64 ]; /* = "cfg-spk:* cfg-int-mic:* cfg-hs-mic:* ..." */
480
+
437
481
static int snd_byt_wm5102_mc_probe (struct platform_device * pdev )
438
482
{
483
+ static const char * const out_map_name [] = { "spk" , "hpout2" };
439
484
char codec_name [SND_ACPI_I2C_ID_LEN ];
440
485
struct device * dev = & pdev -> dev ;
441
486
struct byt_wm5102_private * priv ;
@@ -493,8 +538,13 @@ static int snd_byt_wm5102_mc_probe(struct platform_device *pdev)
493
538
}
494
539
495
540
if (soc_intel_is_cht ()) {
496
- /* On CHT default to SSP2 */
497
- quirk = BYT_WM5102_SSP2 | BYT_WM5102_MCLK_19_2MHZ ;
541
+ /*
542
+ * CHT always uses SSP2 and 19.2 MHz; and
543
+ * the one currently supported CHT design uses HPOUT2 as
544
+ * speaker output.
545
+ */
546
+ quirk = BYT_WM5102_SSP2 | BYT_WM5102_MCLK_19_2MHZ |
547
+ BYT_WM5102_SPK_HPOUT2_MAP ;
498
548
}
499
549
if (quirk_override != -1 ) {
500
550
dev_info_once (dev , "Overriding quirk 0x%lx => 0x%x\n" ,
@@ -503,6 +553,10 @@ static int snd_byt_wm5102_mc_probe(struct platform_device *pdev)
503
553
}
504
554
log_quirks (dev );
505
555
556
+ snprintf (byt_wm5102_components , sizeof (byt_wm5102_components ),
557
+ "cfg-spk:%s" , out_map_name [FIELD_GET (BYT_WM5102_OUT_MAP , quirk )]);
558
+ byt_wm5102_card .components = byt_wm5102_components ;
559
+
506
560
/* find index of codec dai */
507
561
for (i = 0 ; i < ARRAY_SIZE (byt_wm5102_dais ); i ++ ) {
508
562
if (!strcmp (byt_wm5102_dais [i ].codecs -> name ,
0 commit comments