1 // SPDX-License-Identifier: GPL-2.0-only
3 * bytcr_rt5651.c - ASoc Machine driver for Intel Byt CR platform
4 * (derived from bytcr_rt5640.c)
6 * Copyright (C) 2015 Intel Corp
7 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
9 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
12 #include <linux/init.h>
13 #include <linux/i2c.h>
14 #include <linux/module.h>
15 #include <linux/platform_device.h>
16 #include <linux/property.h>
17 #include <linux/acpi.h>
18 #include <linux/clk.h>
19 #include <linux/device.h>
20 #include <linux/dmi.h>
21 #include <linux/input.h>
22 #include <linux/gpio/consumer.h>
23 #include <linux/gpio/machine.h>
24 #include <linux/slab.h>
25 #include <sound/pcm.h>
26 #include <sound/pcm_params.h>
27 #include <sound/soc.h>
28 #include <sound/jack.h>
29 #include <sound/soc-acpi.h>
30 #include "../../codecs/rt5651.h"
31 #include "../atom/sst-atom-controls.h"
32 #include "../common/soc-intel-quirks.h"
38 BYT_RT5651_IN1_IN2_MAP
,
42 BYT_RT5651_JD_NULL
= (RT5651_JD_NULL
<< 4),
43 BYT_RT5651_JD1_1
= (RT5651_JD1_1
<< 4),
44 BYT_RT5651_JD1_2
= (RT5651_JD1_2
<< 4),
45 BYT_RT5651_JD2
= (RT5651_JD2
<< 4),
49 BYT_RT5651_OVCD_TH_600UA
= (6 << 8),
50 BYT_RT5651_OVCD_TH_1500UA
= (15 << 8),
51 BYT_RT5651_OVCD_TH_2000UA
= (20 << 8),
55 BYT_RT5651_OVCD_SF_0P5
= (RT5651_OVCD_SF_0P5
<< 13),
56 BYT_RT5651_OVCD_SF_0P75
= (RT5651_OVCD_SF_0P75
<< 13),
57 BYT_RT5651_OVCD_SF_1P0
= (RT5651_OVCD_SF_1P0
<< 13),
58 BYT_RT5651_OVCD_SF_1P5
= (RT5651_OVCD_SF_1P5
<< 13),
61 #define BYT_RT5651_MAP(quirk) ((quirk) & GENMASK(3, 0))
62 #define BYT_RT5651_JDSRC(quirk) (((quirk) & GENMASK(7, 4)) >> 4)
63 #define BYT_RT5651_OVCD_TH(quirk) (((quirk) & GENMASK(12, 8)) >> 8)
64 #define BYT_RT5651_OVCD_SF(quirk) (((quirk) & GENMASK(14, 13)) >> 13)
65 #define BYT_RT5651_DMIC_EN BIT(16)
66 #define BYT_RT5651_MCLK_EN BIT(17)
67 #define BYT_RT5651_MCLK_25MHZ BIT(18)
68 #define BYT_RT5651_SSP2_AIF2 BIT(19) /* default is using AIF1 */
69 #define BYT_RT5651_SSP0_AIF1 BIT(20)
70 #define BYT_RT5651_SSP0_AIF2 BIT(21)
71 #define BYT_RT5651_HP_LR_SWAPPED BIT(22)
72 #define BYT_RT5651_MONO_SPEAKER BIT(23)
73 #define BYT_RT5651_JD_NOT_INV BIT(24)
75 #define BYT_RT5651_DEFAULT_QUIRKS (BYT_RT5651_MCLK_EN | \
77 BYT_RT5651_OVCD_TH_2000UA | \
78 BYT_RT5651_OVCD_SF_0P75)
80 /* jack-detect-source + inv + dmic-en + ovcd-th + -sf + terminating entry */
81 #define MAX_NO_PROPS 6
83 struct byt_rt5651_private
{
85 struct gpio_desc
*ext_amp_gpio
;
86 struct gpio_desc
*hp_detect
;
87 struct snd_soc_jack jack
;
90 static const struct acpi_gpio_mapping
*byt_rt5651_gpios
;
92 /* Default: jack-detect on JD1_1, internal mic on in2, headsetmic on in3 */
93 static unsigned long byt_rt5651_quirk
= BYT_RT5651_DEFAULT_QUIRKS
|
96 static int quirk_override
= -1;
97 module_param_named(quirk
, quirk_override
, int, 0444);
98 MODULE_PARM_DESC(quirk
, "Board-specific quirk override");
100 static void log_quirks(struct device
*dev
)
102 if (BYT_RT5651_MAP(byt_rt5651_quirk
) == BYT_RT5651_DMIC_MAP
)
103 dev_info(dev
, "quirk DMIC_MAP enabled");
104 if (BYT_RT5651_MAP(byt_rt5651_quirk
) == BYT_RT5651_IN1_MAP
)
105 dev_info(dev
, "quirk IN1_MAP enabled");
106 if (BYT_RT5651_MAP(byt_rt5651_quirk
) == BYT_RT5651_IN2_MAP
)
107 dev_info(dev
, "quirk IN2_MAP enabled");
108 if (BYT_RT5651_MAP(byt_rt5651_quirk
) == BYT_RT5651_IN1_IN2_MAP
)
109 dev_info(dev
, "quirk IN1_IN2_MAP enabled");
110 if (BYT_RT5651_JDSRC(byt_rt5651_quirk
)) {
111 dev_info(dev
, "quirk realtek,jack-detect-source %ld\n",
112 BYT_RT5651_JDSRC(byt_rt5651_quirk
));
113 dev_info(dev
, "quirk realtek,over-current-threshold-microamp %ld\n",
114 BYT_RT5651_OVCD_TH(byt_rt5651_quirk
) * 100);
115 dev_info(dev
, "quirk realtek,over-current-scale-factor %ld\n",
116 BYT_RT5651_OVCD_SF(byt_rt5651_quirk
));
118 if (byt_rt5651_quirk
& BYT_RT5651_DMIC_EN
)
119 dev_info(dev
, "quirk DMIC enabled");
120 if (byt_rt5651_quirk
& BYT_RT5651_MCLK_EN
)
121 dev_info(dev
, "quirk MCLK_EN enabled");
122 if (byt_rt5651_quirk
& BYT_RT5651_MCLK_25MHZ
)
123 dev_info(dev
, "quirk MCLK_25MHZ enabled");
124 if (byt_rt5651_quirk
& BYT_RT5651_SSP2_AIF2
)
125 dev_info(dev
, "quirk SSP2_AIF2 enabled\n");
126 if (byt_rt5651_quirk
& BYT_RT5651_SSP0_AIF1
)
127 dev_info(dev
, "quirk SSP0_AIF1 enabled\n");
128 if (byt_rt5651_quirk
& BYT_RT5651_SSP0_AIF2
)
129 dev_info(dev
, "quirk SSP0_AIF2 enabled\n");
130 if (byt_rt5651_quirk
& BYT_RT5651_MONO_SPEAKER
)
131 dev_info(dev
, "quirk MONO_SPEAKER enabled\n");
132 if (byt_rt5651_quirk
& BYT_RT5651_JD_NOT_INV
)
133 dev_info(dev
, "quirk JD_NOT_INV enabled\n");
136 #define BYT_CODEC_DAI1 "rt5651-aif1"
137 #define BYT_CODEC_DAI2 "rt5651-aif2"
139 static int byt_rt5651_prepare_and_enable_pll1(struct snd_soc_dai
*codec_dai
,
140 int rate
, int bclk_ratio
)
142 int clk_id
, clk_freq
, ret
;
144 /* Configure the PLL before selecting it */
145 if (!(byt_rt5651_quirk
& BYT_RT5651_MCLK_EN
)) {
146 clk_id
= RT5651_PLL1_S_BCLK1
,
147 clk_freq
= rate
* bclk_ratio
;
149 clk_id
= RT5651_PLL1_S_MCLK
;
150 if (byt_rt5651_quirk
& BYT_RT5651_MCLK_25MHZ
)
155 ret
= snd_soc_dai_set_pll(codec_dai
, 0, clk_id
, clk_freq
, rate
* 512);
157 dev_err(codec_dai
->component
->dev
, "can't set pll: %d\n", ret
);
161 ret
= snd_soc_dai_set_sysclk(codec_dai
, RT5651_SCLK_S_PLL1
,
162 rate
* 512, SND_SOC_CLOCK_IN
);
164 dev_err(codec_dai
->component
->dev
, "can't set clock %d\n", ret
);
171 static int platform_clock_control(struct snd_soc_dapm_widget
*w
,
172 struct snd_kcontrol
*k
, int event
)
174 struct snd_soc_dapm_context
*dapm
= w
->dapm
;
175 struct snd_soc_card
*card
= dapm
->card
;
176 struct snd_soc_dai
*codec_dai
;
177 struct byt_rt5651_private
*priv
= snd_soc_card_get_drvdata(card
);
180 codec_dai
= snd_soc_card_get_codec_dai(card
, BYT_CODEC_DAI1
);
182 codec_dai
= snd_soc_card_get_codec_dai(card
, BYT_CODEC_DAI2
);
185 "Codec dai not found; Unable to set platform clock\n");
189 if (SND_SOC_DAPM_EVENT_ON(event
)) {
190 if (byt_rt5651_quirk
& BYT_RT5651_MCLK_EN
) {
191 ret
= clk_prepare_enable(priv
->mclk
);
194 "could not configure MCLK state");
198 ret
= byt_rt5651_prepare_and_enable_pll1(codec_dai
, 48000, 50);
201 * Set codec clock source to internal clock before
202 * turning off the platform clock. Codec needs clock
203 * for Jack detection and button press
205 ret
= snd_soc_dai_set_sysclk(codec_dai
, RT5651_SCLK_S_RCCLK
,
209 if (byt_rt5651_quirk
& BYT_RT5651_MCLK_EN
)
210 clk_disable_unprepare(priv
->mclk
);
214 dev_err(card
->dev
, "can't set codec sysclk: %d\n", ret
);
221 static int rt5651_ext_amp_power_event(struct snd_soc_dapm_widget
*w
,
222 struct snd_kcontrol
*kcontrol
, int event
)
224 struct snd_soc_card
*card
= w
->dapm
->card
;
225 struct byt_rt5651_private
*priv
= snd_soc_card_get_drvdata(card
);
227 if (SND_SOC_DAPM_EVENT_ON(event
))
228 gpiod_set_value_cansleep(priv
->ext_amp_gpio
, 1);
230 gpiod_set_value_cansleep(priv
->ext_amp_gpio
, 0);
235 static const struct snd_soc_dapm_widget byt_rt5651_widgets
[] = {
236 SND_SOC_DAPM_HP("Headphone", NULL
),
237 SND_SOC_DAPM_MIC("Headset Mic", NULL
),
238 SND_SOC_DAPM_MIC("Internal Mic", NULL
),
239 SND_SOC_DAPM_SPK("Speaker", NULL
),
240 SND_SOC_DAPM_LINE("Line In", NULL
),
241 SND_SOC_DAPM_SUPPLY("Platform Clock", SND_SOC_NOPM
, 0, 0,
242 platform_clock_control
, SND_SOC_DAPM_PRE_PMU
|
243 SND_SOC_DAPM_POST_PMD
),
244 SND_SOC_DAPM_SUPPLY("Ext Amp Power", SND_SOC_NOPM
, 0, 0,
245 rt5651_ext_amp_power_event
,
246 SND_SOC_DAPM_PRE_PMD
| SND_SOC_DAPM_POST_PMU
),
249 static const struct snd_soc_dapm_route byt_rt5651_audio_map
[] = {
250 {"Headphone", NULL
, "Platform Clock"},
251 {"Headset Mic", NULL
, "Platform Clock"},
252 {"Internal Mic", NULL
, "Platform Clock"},
253 {"Speaker", NULL
, "Platform Clock"},
254 {"Speaker", NULL
, "Ext Amp Power"},
255 {"Line In", NULL
, "Platform Clock"},
257 {"Headset Mic", NULL
, "micbias1"}, /* lowercase for rt5651 */
258 {"Headphone", NULL
, "HPOL"},
259 {"Headphone", NULL
, "HPOR"},
260 {"Speaker", NULL
, "LOUTL"},
261 {"Speaker", NULL
, "LOUTR"},
262 {"IN2P", NULL
, "Line In"},
263 {"IN2N", NULL
, "Line In"},
267 static const struct snd_soc_dapm_route byt_rt5651_intmic_dmic_map
[] = {
268 {"DMIC L1", NULL
, "Internal Mic"},
269 {"DMIC R1", NULL
, "Internal Mic"},
270 {"IN2P", NULL
, "Headset Mic"},
273 static const struct snd_soc_dapm_route byt_rt5651_intmic_in1_map
[] = {
274 {"Internal Mic", NULL
, "micbias1"},
275 {"IN1P", NULL
, "Internal Mic"},
276 {"IN3P", NULL
, "Headset Mic"},
279 static const struct snd_soc_dapm_route byt_rt5651_intmic_in2_map
[] = {
280 {"Internal Mic", NULL
, "micbias1"},
281 {"IN2P", NULL
, "Internal Mic"},
282 {"IN3P", NULL
, "Headset Mic"},
285 static const struct snd_soc_dapm_route byt_rt5651_intmic_in1_in2_map
[] = {
286 {"Internal Mic", NULL
, "micbias1"},
287 {"IN1P", NULL
, "Internal Mic"},
288 {"IN2P", NULL
, "Internal Mic"},
289 {"IN3P", NULL
, "Headset Mic"},
292 static const struct snd_soc_dapm_route byt_rt5651_ssp0_aif1_map
[] = {
293 {"ssp0 Tx", NULL
, "modem_out"},
294 {"modem_in", NULL
, "ssp0 Rx"},
296 {"AIF1 Playback", NULL
, "ssp0 Tx"},
297 {"ssp0 Rx", NULL
, "AIF1 Capture"},
300 static const struct snd_soc_dapm_route byt_rt5651_ssp0_aif2_map
[] = {
301 {"ssp0 Tx", NULL
, "modem_out"},
302 {"modem_in", NULL
, "ssp0 Rx"},
304 {"AIF2 Playback", NULL
, "ssp0 Tx"},
305 {"ssp0 Rx", NULL
, "AIF2 Capture"},
308 static const struct snd_soc_dapm_route byt_rt5651_ssp2_aif1_map
[] = {
309 {"ssp2 Tx", NULL
, "codec_out0"},
310 {"ssp2 Tx", NULL
, "codec_out1"},
311 {"codec_in0", NULL
, "ssp2 Rx"},
312 {"codec_in1", NULL
, "ssp2 Rx"},
314 {"AIF1 Playback", NULL
, "ssp2 Tx"},
315 {"ssp2 Rx", NULL
, "AIF1 Capture"},
318 static const struct snd_soc_dapm_route byt_rt5651_ssp2_aif2_map
[] = {
319 {"ssp2 Tx", NULL
, "codec_out0"},
320 {"ssp2 Tx", NULL
, "codec_out1"},
321 {"codec_in0", NULL
, "ssp2 Rx"},
322 {"codec_in1", NULL
, "ssp2 Rx"},
324 {"AIF2 Playback", NULL
, "ssp2 Tx"},
325 {"ssp2 Rx", NULL
, "AIF2 Capture"},
328 static const struct snd_kcontrol_new byt_rt5651_controls
[] = {
329 SOC_DAPM_PIN_SWITCH("Headphone"),
330 SOC_DAPM_PIN_SWITCH("Headset Mic"),
331 SOC_DAPM_PIN_SWITCH("Internal Mic"),
332 SOC_DAPM_PIN_SWITCH("Speaker"),
333 SOC_DAPM_PIN_SWITCH("Line In"),
336 static struct snd_soc_jack_pin bytcr_jack_pins
[] = {
339 .mask
= SND_JACK_HEADPHONE
,
342 .pin
= "Headset Mic",
343 .mask
= SND_JACK_MICROPHONE
,
347 static int byt_rt5651_aif1_hw_params(struct snd_pcm_substream
*substream
,
348 struct snd_pcm_hw_params
*params
)
350 struct snd_soc_pcm_runtime
*rtd
= substream
->private_data
;
351 struct snd_soc_dai
*codec_dai
= rtd
->codec_dai
;
352 snd_pcm_format_t format
= params_format(params
);
353 int rate
= params_rate(params
);
356 if (format
== SNDRV_PCM_FORMAT_S16_LE
)
361 return byt_rt5651_prepare_and_enable_pll1(codec_dai
, rate
, bclk_ratio
);
364 static const struct acpi_gpio_params pov_p1006w_hp_detect
= { 1, 0, false };
365 static const struct acpi_gpio_params pov_p1006w_ext_amp_en
= { 2, 0, true };
367 static const struct acpi_gpio_mapping byt_rt5651_pov_p1006w_gpios
[] = {
368 { "hp-detect-gpios", &pov_p1006w_hp_detect
, 1, },
369 { "ext-amp-enable-gpios", &pov_p1006w_ext_amp_en
, 1, },
373 static int byt_rt5651_pov_p1006w_quirk_cb(const struct dmi_system_id
*id
)
375 byt_rt5651_quirk
= (unsigned long)id
->driver_data
;
376 byt_rt5651_gpios
= byt_rt5651_pov_p1006w_gpios
;
380 static int byt_rt5651_quirk_cb(const struct dmi_system_id
*id
)
382 byt_rt5651_quirk
= (unsigned long)id
->driver_data
;
386 static const struct dmi_system_id byt_rt5651_quirk_table
[] = {
388 /* Chuwi Hi8 Pro (CWI513) */
389 .callback
= byt_rt5651_quirk_cb
,
391 DMI_MATCH(DMI_SYS_VENDOR
, "Hampoo"),
392 DMI_MATCH(DMI_PRODUCT_NAME
, "X1D3_C806N"),
394 .driver_data
= (void *)(BYT_RT5651_DEFAULT_QUIRKS
|
396 BYT_RT5651_HP_LR_SWAPPED
|
397 BYT_RT5651_MONO_SPEAKER
),
400 /* Chuwi Vi8 Plus (CWI519) */
401 .callback
= byt_rt5651_quirk_cb
,
403 DMI_MATCH(DMI_SYS_VENDOR
, "Hampoo"),
404 DMI_MATCH(DMI_PRODUCT_NAME
, "D2D3_Vi8A1"),
406 .driver_data
= (void *)(BYT_RT5651_DEFAULT_QUIRKS
|
408 BYT_RT5651_HP_LR_SWAPPED
|
409 BYT_RT5651_MONO_SPEAKER
),
412 /* Complet Electro Serv MY8307 */
413 .callback
= byt_rt5651_quirk_cb
,
415 DMI_MATCH(DMI_SYS_VENDOR
, "Complet Electro Serv"),
416 DMI_MATCH(DMI_PRODUCT_NAME
, "MY8307"),
418 .driver_data
= (void *)(BYT_RT5651_DEFAULT_QUIRKS
|
420 BYT_RT5651_MONO_SPEAKER
|
421 BYT_RT5651_JD_NOT_INV
),
424 /* I.T.Works TW701, Ployer Momo7w and Trekstor ST70416-6
425 * (these all use the same mainboard) */
426 .callback
= byt_rt5651_quirk_cb
,
428 DMI_MATCH(DMI_BIOS_VENDOR
, "INSYDE Corp."),
429 /* Partial match for all of itWORKS.G.WI71C.JGBMRBA,
430 * TREK.G.WI71C.JGBMRBA0x and MOMO.G.WI71C.MABMRBA02 */
431 DMI_MATCH(DMI_BIOS_VERSION
, ".G.WI71C."),
433 .driver_data
= (void *)(BYT_RT5651_DEFAULT_QUIRKS
|
435 BYT_RT5651_SSP0_AIF1
|
436 BYT_RT5651_MONO_SPEAKER
),
439 /* KIANO SlimNote 14.2 */
440 .callback
= byt_rt5651_quirk_cb
,
442 DMI_MATCH(DMI_SYS_VENDOR
, "KIANO"),
443 DMI_MATCH(DMI_PRODUCT_NAME
, "KIANO SlimNote 14.2"),
445 .driver_data
= (void *)(BYT_RT5651_DEFAULT_QUIRKS
|
446 BYT_RT5651_IN1_IN2_MAP
),
449 /* Minnowboard Max B3 */
450 .callback
= byt_rt5651_quirk_cb
,
452 DMI_MATCH(DMI_SYS_VENDOR
, "Circuitco"),
453 DMI_MATCH(DMI_PRODUCT_NAME
, "Minnowboard Max B3 PLATFORM"),
455 .driver_data
= (void *)(BYT_RT5651_IN1_MAP
),
458 /* Minnowboard Turbot */
459 .callback
= byt_rt5651_quirk_cb
,
461 DMI_MATCH(DMI_SYS_VENDOR
, "ADI"),
462 DMI_MATCH(DMI_PRODUCT_NAME
, "Minnowboard Turbot"),
464 .driver_data
= (void *)(BYT_RT5651_MCLK_EN
|
468 /* Point of View mobii wintab p1006w (v1.0) */
469 .callback
= byt_rt5651_pov_p1006w_quirk_cb
,
471 DMI_EXACT_MATCH(DMI_SYS_VENDOR
, "Insyde"),
472 DMI_EXACT_MATCH(DMI_PRODUCT_NAME
, "BayTrail"),
473 /* Note 105b is Foxcon's USB/PCI vendor id */
474 DMI_EXACT_MATCH(DMI_BOARD_VENDOR
, "105B"),
475 DMI_EXACT_MATCH(DMI_BOARD_NAME
, "0E57"),
477 .driver_data
= (void *)(BYT_RT5651_DMIC_MAP
|
478 BYT_RT5651_OVCD_TH_2000UA
|
479 BYT_RT5651_OVCD_SF_0P75
|
482 BYT_RT5651_SSP0_AIF1
),
486 .callback
= byt_rt5651_quirk_cb
,
488 DMI_MATCH(DMI_SYS_VENDOR
, "VIOS"),
489 DMI_MATCH(DMI_PRODUCT_NAME
, "LTH17"),
491 .driver_data
= (void *)(BYT_RT5651_IN1_IN2_MAP
|
493 BYT_RT5651_OVCD_TH_2000UA
|
494 BYT_RT5651_OVCD_SF_1P0
|
498 /* Yours Y8W81 (and others using the same mainboard) */
499 .callback
= byt_rt5651_quirk_cb
,
501 DMI_MATCH(DMI_BIOS_VENDOR
, "INSYDE Corp."),
502 /* Partial match for all devs with a W86C mainboard */
503 DMI_MATCH(DMI_BIOS_VERSION
, ".F.W86C."),
505 .driver_data
= (void *)(BYT_RT5651_DEFAULT_QUIRKS
|
507 BYT_RT5651_SSP0_AIF1
|
508 BYT_RT5651_MONO_SPEAKER
),
514 * Note this MUST be called before snd_soc_register_card(), so that the props
515 * are in place before the codec component driver's probe function parses them.
517 static int byt_rt5651_add_codec_device_props(struct device
*i2c_dev
)
519 struct property_entry props
[MAX_NO_PROPS
] = {};
522 props
[cnt
++] = PROPERTY_ENTRY_U32("realtek,jack-detect-source",
523 BYT_RT5651_JDSRC(byt_rt5651_quirk
));
525 props
[cnt
++] = PROPERTY_ENTRY_U32("realtek,over-current-threshold-microamp",
526 BYT_RT5651_OVCD_TH(byt_rt5651_quirk
) * 100);
528 props
[cnt
++] = PROPERTY_ENTRY_U32("realtek,over-current-scale-factor",
529 BYT_RT5651_OVCD_SF(byt_rt5651_quirk
));
531 if (byt_rt5651_quirk
& BYT_RT5651_DMIC_EN
)
532 props
[cnt
++] = PROPERTY_ENTRY_BOOL("realtek,dmic-en");
534 if (byt_rt5651_quirk
& BYT_RT5651_JD_NOT_INV
)
535 props
[cnt
++] = PROPERTY_ENTRY_BOOL("realtek,jack-detect-not-inverted");
537 return device_add_properties(i2c_dev
, props
);
540 static int byt_rt5651_init(struct snd_soc_pcm_runtime
*runtime
)
542 struct snd_soc_card
*card
= runtime
->card
;
543 struct snd_soc_component
*codec
= runtime
->codec_dai
->component
;
544 struct byt_rt5651_private
*priv
= snd_soc_card_get_drvdata(card
);
545 const struct snd_soc_dapm_route
*custom_map
;
550 card
->dapm
.idle_bias_off
= true;
552 /* Start with RC clk for jack-detect (we disable MCLK below) */
553 if (byt_rt5651_quirk
& BYT_RT5651_MCLK_EN
)
554 snd_soc_component_update_bits(codec
, RT5651_GLB_CLK
,
555 RT5651_SCLK_SRC_MASK
, RT5651_SCLK_SRC_RCCLK
);
557 switch (BYT_RT5651_MAP(byt_rt5651_quirk
)) {
558 case BYT_RT5651_IN1_MAP
:
559 custom_map
= byt_rt5651_intmic_in1_map
;
560 num_routes
= ARRAY_SIZE(byt_rt5651_intmic_in1_map
);
562 case BYT_RT5651_IN2_MAP
:
563 custom_map
= byt_rt5651_intmic_in2_map
;
564 num_routes
= ARRAY_SIZE(byt_rt5651_intmic_in2_map
);
566 case BYT_RT5651_IN1_IN2_MAP
:
567 custom_map
= byt_rt5651_intmic_in1_in2_map
;
568 num_routes
= ARRAY_SIZE(byt_rt5651_intmic_in1_in2_map
);
571 custom_map
= byt_rt5651_intmic_dmic_map
;
572 num_routes
= ARRAY_SIZE(byt_rt5651_intmic_dmic_map
);
574 ret
= snd_soc_dapm_add_routes(&card
->dapm
, custom_map
, num_routes
);
578 if (byt_rt5651_quirk
& BYT_RT5651_SSP2_AIF2
) {
579 ret
= snd_soc_dapm_add_routes(&card
->dapm
,
580 byt_rt5651_ssp2_aif2_map
,
581 ARRAY_SIZE(byt_rt5651_ssp2_aif2_map
));
582 } else if (byt_rt5651_quirk
& BYT_RT5651_SSP0_AIF1
) {
583 ret
= snd_soc_dapm_add_routes(&card
->dapm
,
584 byt_rt5651_ssp0_aif1_map
,
585 ARRAY_SIZE(byt_rt5651_ssp0_aif1_map
));
586 } else if (byt_rt5651_quirk
& BYT_RT5651_SSP0_AIF2
) {
587 ret
= snd_soc_dapm_add_routes(&card
->dapm
,
588 byt_rt5651_ssp0_aif2_map
,
589 ARRAY_SIZE(byt_rt5651_ssp0_aif2_map
));
591 ret
= snd_soc_dapm_add_routes(&card
->dapm
,
592 byt_rt5651_ssp2_aif1_map
,
593 ARRAY_SIZE(byt_rt5651_ssp2_aif1_map
));
598 ret
= snd_soc_add_card_controls(card
, byt_rt5651_controls
,
599 ARRAY_SIZE(byt_rt5651_controls
));
601 dev_err(card
->dev
, "unable to add card controls\n");
604 snd_soc_dapm_ignore_suspend(&card
->dapm
, "Headphone");
605 snd_soc_dapm_ignore_suspend(&card
->dapm
, "Speaker");
607 if (byt_rt5651_quirk
& BYT_RT5651_MCLK_EN
) {
609 * The firmware might enable the clock at
610 * boot (this information may or may not
611 * be reflected in the enable clock register).
612 * To change the rate we must disable the clock
613 * first to cover these cases. Due to common
614 * clock framework restrictions that do not allow
615 * to disable a clock that has not been enabled,
616 * we need to enable the clock first.
618 ret
= clk_prepare_enable(priv
->mclk
);
620 clk_disable_unprepare(priv
->mclk
);
622 if (byt_rt5651_quirk
& BYT_RT5651_MCLK_25MHZ
)
623 ret
= clk_set_rate(priv
->mclk
, 25000000);
625 ret
= clk_set_rate(priv
->mclk
, 19200000);
628 dev_err(card
->dev
, "unable to set MCLK rate\n");
632 if (BYT_RT5651_JDSRC(byt_rt5651_quirk
))
633 report
= SND_JACK_HEADSET
| SND_JACK_BTN_0
;
634 else if (priv
->hp_detect
)
635 report
= SND_JACK_HEADSET
;
638 ret
= snd_soc_card_jack_new(runtime
->card
, "Headset",
639 report
, &priv
->jack
, bytcr_jack_pins
,
640 ARRAY_SIZE(bytcr_jack_pins
));
642 dev_err(runtime
->dev
, "jack creation failed %d\n", ret
);
646 if (report
& SND_JACK_BTN_0
)
647 snd_jack_set_key(priv
->jack
.jack
, SND_JACK_BTN_0
,
650 ret
= snd_soc_component_set_jack(codec
, &priv
->jack
,
659 static int byt_rt5651_codec_fixup(struct snd_soc_pcm_runtime
*rtd
,
660 struct snd_pcm_hw_params
*params
)
662 struct snd_interval
*rate
= hw_param_interval(params
,
663 SNDRV_PCM_HW_PARAM_RATE
);
664 struct snd_interval
*channels
= hw_param_interval(params
,
665 SNDRV_PCM_HW_PARAM_CHANNELS
);
668 /* The DSP will covert the FE rate to 48k, stereo */
669 rate
->min
= rate
->max
= 48000;
670 channels
->min
= channels
->max
= 2;
672 if ((byt_rt5651_quirk
& BYT_RT5651_SSP0_AIF1
) ||
673 (byt_rt5651_quirk
& BYT_RT5651_SSP0_AIF2
)) {
674 /* set SSP0 to 16-bit */
675 params_set_format(params
, SNDRV_PCM_FORMAT_S16_LE
);
678 /* set SSP2 to 24-bit */
679 params_set_format(params
, SNDRV_PCM_FORMAT_S24_LE
);
684 * Default mode for SSP configuration is TDM 4 slot, override config
685 * with explicit setting to I2S 2ch. The word length is set with
686 * dai_set_tdm_slot() since there is no other API exposed
688 ret
= snd_soc_dai_set_fmt(rtd
->cpu_dai
,
690 SND_SOC_DAIFMT_NB_NF
|
691 SND_SOC_DAIFMT_CBS_CFS
695 dev_err(rtd
->dev
, "can't set format to I2S, err %d\n", ret
);
699 ret
= snd_soc_dai_set_tdm_slot(rtd
->cpu_dai
, 0x3, 0x3, 2, bits
);
701 dev_err(rtd
->dev
, "can't set I2S config, err %d\n", ret
);
708 static const unsigned int rates_48000
[] = {
712 static const struct snd_pcm_hw_constraint_list constraints_48000
= {
713 .count
= ARRAY_SIZE(rates_48000
),
717 static int byt_rt5651_aif1_startup(struct snd_pcm_substream
*substream
)
719 return snd_pcm_hw_constraint_list(substream
->runtime
, 0,
720 SNDRV_PCM_HW_PARAM_RATE
,
724 static const struct snd_soc_ops byt_rt5651_aif1_ops
= {
725 .startup
= byt_rt5651_aif1_startup
,
728 static const struct snd_soc_ops byt_rt5651_be_ssp2_ops
= {
729 .hw_params
= byt_rt5651_aif1_hw_params
,
732 SND_SOC_DAILINK_DEF(dummy
,
733 DAILINK_COMP_ARRAY(COMP_DUMMY()));
735 SND_SOC_DAILINK_DEF(media
,
736 DAILINK_COMP_ARRAY(COMP_CPU("media-cpu-dai")));
738 SND_SOC_DAILINK_DEF(deepbuffer
,
739 DAILINK_COMP_ARRAY(COMP_CPU("deepbuffer-cpu-dai")));
741 SND_SOC_DAILINK_DEF(ssp2_port
,
742 DAILINK_COMP_ARRAY(COMP_CPU("ssp2-port")));
743 SND_SOC_DAILINK_DEF(ssp2_codec
,
744 DAILINK_COMP_ARRAY(COMP_CODEC("i2c-10EC5651:00", "rt5651-aif1")));
746 SND_SOC_DAILINK_DEF(platform
,
747 DAILINK_COMP_ARRAY(COMP_PLATFORM("sst-mfld-platform")));
749 static struct snd_soc_dai_link byt_rt5651_dais
[] = {
750 [MERR_DPCM_AUDIO
] = {
751 .name
= "Audio Port",
752 .stream_name
= "Audio",
757 .ops
= &byt_rt5651_aif1_ops
,
758 SND_SOC_DAILINK_REG(media
, dummy
, platform
),
760 [MERR_DPCM_DEEP_BUFFER
] = {
761 .name
= "Deep-Buffer Audio Port",
762 .stream_name
= "Deep-Buffer Audio",
766 .ops
= &byt_rt5651_aif1_ops
,
767 SND_SOC_DAILINK_REG(deepbuffer
, dummy
, platform
),
769 /* CODEC<->CODEC link */
772 .name
= "SSP2-Codec",
775 .dai_fmt
= SND_SOC_DAIFMT_I2S
| SND_SOC_DAIFMT_NB_NF
776 | SND_SOC_DAIFMT_CBS_CFS
,
777 .be_hw_params_fixup
= byt_rt5651_codec_fixup
,
782 .init
= byt_rt5651_init
,
783 .ops
= &byt_rt5651_be_ssp2_ops
,
784 SND_SOC_DAILINK_REG(ssp2_port
, ssp2_codec
, platform
),
789 static char byt_rt5651_codec_name
[SND_ACPI_I2C_ID_LEN
];
790 #if !IS_ENABLED(CONFIG_SND_SOC_INTEL_USER_FRIENDLY_LONG_NAMES)
791 static char byt_rt5651_long_name
[50]; /* = "bytcr-rt5651-*-spk-*-mic[-swapped-hp]" */
793 static char byt_rt5651_components
[50]; /* = "cfg-spk:* cfg-mic:*" */
795 static int byt_rt5651_suspend(struct snd_soc_card
*card
)
797 struct snd_soc_component
*component
;
799 if (!BYT_RT5651_JDSRC(byt_rt5651_quirk
))
802 for_each_card_components(card
, component
) {
803 if (!strcmp(component
->name
, byt_rt5651_codec_name
)) {
804 dev_dbg(component
->dev
, "disabling jack detect before suspend\n");
805 snd_soc_component_set_jack(component
, NULL
, NULL
);
813 static int byt_rt5651_resume(struct snd_soc_card
*card
)
815 struct byt_rt5651_private
*priv
= snd_soc_card_get_drvdata(card
);
816 struct snd_soc_component
*component
;
818 if (!BYT_RT5651_JDSRC(byt_rt5651_quirk
))
821 for_each_card_components(card
, component
) {
822 if (!strcmp(component
->name
, byt_rt5651_codec_name
)) {
823 dev_dbg(component
->dev
, "re-enabling jack detect after resume\n");
824 snd_soc_component_set_jack(component
, &priv
->jack
,
833 static struct snd_soc_card byt_rt5651_card
= {
834 .name
= "bytcr-rt5651",
835 .owner
= THIS_MODULE
,
836 .dai_link
= byt_rt5651_dais
,
837 .num_links
= ARRAY_SIZE(byt_rt5651_dais
),
838 .dapm_widgets
= byt_rt5651_widgets
,
839 .num_dapm_widgets
= ARRAY_SIZE(byt_rt5651_widgets
),
840 .dapm_routes
= byt_rt5651_audio_map
,
841 .num_dapm_routes
= ARRAY_SIZE(byt_rt5651_audio_map
),
842 .fully_routed
= true,
843 .suspend_pre
= byt_rt5651_suspend
,
844 .resume_post
= byt_rt5651_resume
,
847 static const struct acpi_gpio_params ext_amp_enable_gpios
= { 0, 0, false };
849 static const struct acpi_gpio_mapping cht_rt5651_gpios
[] = {
851 * Some boards have I2cSerialBusV2, GpioIo, GpioInt as ACPI resources,
852 * other boards may have I2cSerialBusV2, GpioInt, GpioIo instead.
853 * We want the GpioIo one for the ext-amp-enable-gpio.
855 { "ext-amp-enable-gpios", &ext_amp_enable_gpios
, 1, ACPI_GPIO_QUIRK_ONLY_GPIOIO
},
859 struct acpi_chan_package
{ /* ACPICA seems to require 64 bit integers */
860 u64 aif_value
; /* 1: AIF1, 2: AIF2 */
861 u64 mclock_value
; /* usually 25MHz (0x17d7940), ignored */
864 static int snd_byt_rt5651_mc_probe(struct platform_device
*pdev
)
866 static const char * const mic_name
[] = { "dmic", "in1", "in2", "in12" };
867 struct byt_rt5651_private
*priv
;
868 struct snd_soc_acpi_mach
*mach
;
869 const char *platform_name
;
870 struct acpi_device
*adev
;
871 struct device
*codec_dev
;
872 bool is_bytcr
= false;
877 priv
= devm_kzalloc(&pdev
->dev
, sizeof(*priv
), GFP_KERNEL
);
881 /* register the soc card */
882 byt_rt5651_card
.dev
= &pdev
->dev
;
884 mach
= byt_rt5651_card
.dev
->platform_data
;
885 snd_soc_card_set_drvdata(&byt_rt5651_card
, priv
);
887 /* fix index of codec dai */
888 for (i
= 0; i
< ARRAY_SIZE(byt_rt5651_dais
); i
++) {
889 if (!strcmp(byt_rt5651_dais
[i
].codecs
->name
,
890 "i2c-10EC5651:00")) {
896 /* fixup codec name based on HID */
897 adev
= acpi_dev_get_first_match_dev(mach
->id
, NULL
, -1);
899 snprintf(byt_rt5651_codec_name
, sizeof(byt_rt5651_codec_name
),
900 "i2c-%s", acpi_dev_name(adev
));
901 put_device(&adev
->dev
);
902 byt_rt5651_dais
[dai_index
].codecs
->name
= byt_rt5651_codec_name
;
904 dev_err(&pdev
->dev
, "Error cannot find '%s' dev\n", mach
->id
);
908 codec_dev
= bus_find_device_by_name(&i2c_bus_type
, NULL
,
909 byt_rt5651_codec_name
);
911 return -EPROBE_DEFER
;
914 * swap SSP0 if bytcr is detected
915 * (will be overridden if DMI quirk is detected)
917 if (soc_intel_is_byt()) {
918 if (mach
->mach_params
.acpi_ipc_irq_index
== 0)
924 * Baytrail CR platforms may have CHAN package in BIOS, try
925 * to find relevant routing quirk based as done on Windows
926 * platforms. We have to read the information directly from the
927 * BIOS, at this stage the card is not created and the links
928 * with the codec driver/pdata are non-existent
931 struct acpi_chan_package chan_package
;
933 /* format specified: 2 64-bit integers */
934 struct acpi_buffer format
= {sizeof("NN"), "NN"};
935 struct acpi_buffer state
= {0, NULL
};
936 struct snd_soc_acpi_package_context pkg_ctx
;
937 bool pkg_found
= false;
939 state
.length
= sizeof(chan_package
);
940 state
.pointer
= &chan_package
;
942 pkg_ctx
.name
= "CHAN";
944 pkg_ctx
.format
= &format
;
945 pkg_ctx
.state
= &state
;
946 pkg_ctx
.data_valid
= false;
948 pkg_found
= snd_soc_acpi_find_package_from_hid(mach
->id
,
951 if (chan_package
.aif_value
== 1) {
952 dev_info(&pdev
->dev
, "BIOS Routing: AIF1 connected\n");
953 byt_rt5651_quirk
|= BYT_RT5651_SSP0_AIF1
;
954 } else if (chan_package
.aif_value
== 2) {
955 dev_info(&pdev
->dev
, "BIOS Routing: AIF2 connected\n");
956 byt_rt5651_quirk
|= BYT_RT5651_SSP0_AIF2
;
958 dev_info(&pdev
->dev
, "BIOS Routing isn't valid, ignored\n");
964 /* no BIOS indications, assume SSP0-AIF2 connection */
965 byt_rt5651_quirk
|= BYT_RT5651_SSP0_AIF2
;
969 /* check quirks before creating card */
970 dmi_check_system(byt_rt5651_quirk_table
);
972 if (quirk_override
!= -1) {
973 dev_info(&pdev
->dev
, "Overriding quirk 0x%x => 0x%x\n",
974 (unsigned int)byt_rt5651_quirk
, quirk_override
);
975 byt_rt5651_quirk
= quirk_override
;
978 /* Must be called before register_card, also see declaration comment. */
979 ret_val
= byt_rt5651_add_codec_device_props(codec_dev
);
981 put_device(codec_dev
);
985 /* Cherry Trail devices use an external amplifier enable gpio */
986 if (soc_intel_is_cht() && !byt_rt5651_gpios
)
987 byt_rt5651_gpios
= cht_rt5651_gpios
;
989 if (byt_rt5651_gpios
) {
990 devm_acpi_dev_add_driver_gpios(codec_dev
, byt_rt5651_gpios
);
991 priv
->ext_amp_gpio
= devm_fwnode_gpiod_get(&pdev
->dev
,
996 if (IS_ERR(priv
->ext_amp_gpio
)) {
997 ret_val
= PTR_ERR(priv
->ext_amp_gpio
);
1000 priv
->ext_amp_gpio
= NULL
;
1003 dev_err(&pdev
->dev
, "Failed to get ext-amp-enable GPIO: %d\n",
1007 put_device(codec_dev
);
1011 priv
->hp_detect
= devm_fwnode_gpiod_get(&pdev
->dev
,
1016 if (IS_ERR(priv
->hp_detect
)) {
1017 ret_val
= PTR_ERR(priv
->hp_detect
);
1020 priv
->hp_detect
= NULL
;
1023 dev_err(&pdev
->dev
, "Failed to get hp-detect GPIO: %d\n",
1027 put_device(codec_dev
);
1033 put_device(codec_dev
);
1035 log_quirks(&pdev
->dev
);
1037 if ((byt_rt5651_quirk
& BYT_RT5651_SSP2_AIF2
) ||
1038 (byt_rt5651_quirk
& BYT_RT5651_SSP0_AIF2
))
1039 byt_rt5651_dais
[dai_index
].codecs
->dai_name
= "rt5651-aif2";
1041 if ((byt_rt5651_quirk
& BYT_RT5651_SSP0_AIF1
) ||
1042 (byt_rt5651_quirk
& BYT_RT5651_SSP0_AIF2
))
1043 byt_rt5651_dais
[dai_index
].cpus
->dai_name
= "ssp0-port";
1045 if (byt_rt5651_quirk
& BYT_RT5651_MCLK_EN
) {
1046 priv
->mclk
= devm_clk_get(&pdev
->dev
, "pmc_plt_clk_3");
1047 if (IS_ERR(priv
->mclk
)) {
1048 ret_val
= PTR_ERR(priv
->mclk
);
1050 "Failed to get MCLK from pmc_plt_clk_3: %d\n",
1053 * Fall back to bit clock usage for -ENOENT (clock not
1054 * available likely due to missing dependencies), bail
1055 * for all other errors, including -EPROBE_DEFER
1057 if (ret_val
!= -ENOENT
)
1059 byt_rt5651_quirk
&= ~BYT_RT5651_MCLK_EN
;
1063 snprintf(byt_rt5651_components
, sizeof(byt_rt5651_components
),
1064 "cfg-spk:%s cfg-mic:%s%s",
1065 (byt_rt5651_quirk
& BYT_RT5651_MONO_SPEAKER
) ? "1" : "2",
1066 mic_name
[BYT_RT5651_MAP(byt_rt5651_quirk
)],
1067 (byt_rt5651_quirk
& BYT_RT5651_HP_LR_SWAPPED
) ?
1068 " cfg-hp:lrswap" : "");
1069 byt_rt5651_card
.components
= byt_rt5651_components
;
1070 #if !IS_ENABLED(CONFIG_SND_SOC_INTEL_USER_FRIENDLY_LONG_NAMES)
1071 snprintf(byt_rt5651_long_name
, sizeof(byt_rt5651_long_name
),
1072 "bytcr-rt5651-%s-spk-%s-mic%s",
1073 (byt_rt5651_quirk
& BYT_RT5651_MONO_SPEAKER
) ?
1075 mic_name
[BYT_RT5651_MAP(byt_rt5651_quirk
)],
1076 (byt_rt5651_quirk
& BYT_RT5651_HP_LR_SWAPPED
) ?
1077 "-hp-swapped" : "");
1078 byt_rt5651_card
.long_name
= byt_rt5651_long_name
;
1081 /* override plaform name, if required */
1082 platform_name
= mach
->mach_params
.platform
;
1084 ret_val
= snd_soc_fixup_dai_links_platform_name(&byt_rt5651_card
,
1089 ret_val
= devm_snd_soc_register_card(&pdev
->dev
, &byt_rt5651_card
);
1092 dev_err(&pdev
->dev
, "devm_snd_soc_register_card failed %d\n",
1096 platform_set_drvdata(pdev
, &byt_rt5651_card
);
1100 static struct platform_driver snd_byt_rt5651_mc_driver
= {
1102 .name
= "bytcr_rt5651",
1104 .probe
= snd_byt_rt5651_mc_probe
,
1107 module_platform_driver(snd_byt_rt5651_mc_driver
);
1109 MODULE_DESCRIPTION("ASoC Intel(R) Baytrail CR Machine driver for RT5651");
1110 MODULE_AUTHOR("Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>");
1111 MODULE_LICENSE("GPL v2");
1112 MODULE_ALIAS("platform:bytcr_rt5651");