1 // SPDX-License-Identifier: GPL-2.0-only
2 // Copyright(c) 2021 Intel Corporation.
5 * Intel SOF Machine Driver with es8336 Codec
8 #include <linux/device.h>
10 #include <linux/gpio/consumer.h>
11 #include <linux/gpio/machine.h>
12 #include <linux/i2c.h>
13 #include <linux/input.h>
14 #include <linux/module.h>
15 #include <linux/platform_device.h>
16 #include <linux/slab.h>
17 #include <sound/jack.h>
18 #include <sound/pcm.h>
19 #include <sound/pcm_params.h>
20 #include <sound/soc.h>
21 #include <sound/soc-acpi.h>
22 #include "hda_dsp_common.h"
24 /* jd-inv + terminating entry */
25 #define MAX_NO_PROPS 2
27 #define SOF_ES8336_SSP_CODEC(quirk) ((quirk) & GENMASK(3, 0))
28 #define SOF_ES8336_SSP_CODEC_MASK (GENMASK(3, 0))
30 #define SOF_ES8336_SPEAKERS_EN_GPIO1_QUIRK BIT(4)
33 #define SOF_SSP_HDMI_CAPTURE_PRESENT BIT(14)
34 #define SOF_NO_OF_HDMI_CAPTURE_SSP_SHIFT 15
35 #define SOF_NO_OF_HDMI_CAPTURE_SSP_MASK (GENMASK(16, 15))
36 #define SOF_NO_OF_HDMI_CAPTURE_SSP(quirk) \
37 (((quirk) << SOF_NO_OF_HDMI_CAPTURE_SSP_SHIFT) & SOF_NO_OF_HDMI_CAPTURE_SSP_MASK)
39 #define SOF_HDMI_CAPTURE_1_SSP_SHIFT 7
40 #define SOF_HDMI_CAPTURE_1_SSP_MASK (GENMASK(9, 7))
41 #define SOF_HDMI_CAPTURE_1_SSP(quirk) \
42 (((quirk) << SOF_HDMI_CAPTURE_1_SSP_SHIFT) & SOF_HDMI_CAPTURE_1_SSP_MASK)
44 #define SOF_HDMI_CAPTURE_2_SSP_SHIFT 10
45 #define SOF_HDMI_CAPTURE_2_SSP_MASK (GENMASK(12, 10))
46 #define SOF_HDMI_CAPTURE_2_SSP(quirk) \
47 (((quirk) << SOF_HDMI_CAPTURE_2_SSP_SHIFT) & SOF_HDMI_CAPTURE_2_SSP_MASK)
49 #define SOF_ES8336_ENABLE_DMIC BIT(5)
50 #define SOF_ES8336_JD_INVERTED BIT(6)
51 #define SOF_ES8336_HEADPHONE_GPIO BIT(7)
52 #define SOC_ES8336_HEADSET_MIC1 BIT(8)
54 static unsigned long quirk
;
56 static int quirk_override
= -1;
57 module_param_named(quirk
, quirk_override
, int, 0444);
58 MODULE_PARM_DESC(quirk
, "Board-specific quirk override");
60 struct sof_es8336_private
{
61 struct device
*codec_dev
;
62 struct gpio_desc
*gpio_speakers
, *gpio_headphone
;
63 struct snd_soc_jack jack
;
64 struct list_head hdmi_pcm_list
;
66 struct delayed_work pcm_pop_work
;
70 struct list_head head
;
71 struct snd_soc_dai
*codec_dai
;
75 static const struct acpi_gpio_params enable_gpio0
= { 0, 0, true };
76 static const struct acpi_gpio_params enable_gpio1
= { 1, 0, true };
78 static const struct acpi_gpio_mapping acpi_speakers_enable_gpio0
[] = {
79 { "speakers-enable-gpios", &enable_gpio0
, 1, ACPI_GPIO_QUIRK_ONLY_GPIOIO
},
83 static const struct acpi_gpio_mapping acpi_speakers_enable_gpio1
[] = {
84 { "speakers-enable-gpios", &enable_gpio1
, 1, ACPI_GPIO_QUIRK_ONLY_GPIOIO
},
87 static const struct acpi_gpio_mapping acpi_enable_both_gpios
[] = {
88 { "speakers-enable-gpios", &enable_gpio0
, 1, ACPI_GPIO_QUIRK_ONLY_GPIOIO
},
89 { "headphone-enable-gpios", &enable_gpio1
, 1, ACPI_GPIO_QUIRK_ONLY_GPIOIO
},
93 static const struct acpi_gpio_mapping acpi_enable_both_gpios_rev_order
[] = {
94 { "speakers-enable-gpios", &enable_gpio1
, 1, ACPI_GPIO_QUIRK_ONLY_GPIOIO
},
95 { "headphone-enable-gpios", &enable_gpio0
, 1, ACPI_GPIO_QUIRK_ONLY_GPIOIO
},
99 static void log_quirks(struct device
*dev
)
101 dev_info(dev
, "quirk mask %#lx\n", quirk
);
102 dev_info(dev
, "quirk SSP%ld\n", SOF_ES8336_SSP_CODEC(quirk
));
103 if (quirk
& SOF_ES8336_ENABLE_DMIC
)
104 dev_info(dev
, "quirk DMIC enabled\n");
105 if (quirk
& SOF_ES8336_SPEAKERS_EN_GPIO1_QUIRK
)
106 dev_info(dev
, "Speakers GPIO1 quirk enabled\n");
107 if (quirk
& SOF_ES8336_HEADPHONE_GPIO
)
108 dev_info(dev
, "quirk headphone GPIO enabled\n");
109 if (quirk
& SOF_ES8336_JD_INVERTED
)
110 dev_info(dev
, "quirk JD inverted enabled\n");
111 if (quirk
& SOC_ES8336_HEADSET_MIC1
)
112 dev_info(dev
, "quirk headset at mic1 port enabled\n");
115 static void pcm_pop_work_events(struct work_struct
*work
)
117 struct sof_es8336_private
*priv
=
118 container_of(work
, struct sof_es8336_private
, pcm_pop_work
.work
);
120 gpiod_set_value_cansleep(priv
->gpio_speakers
, priv
->speaker_en
);
122 if (quirk
& SOF_ES8336_HEADPHONE_GPIO
)
123 gpiod_set_value_cansleep(priv
->gpio_headphone
, priv
->speaker_en
);
127 static int sof_8336_trigger(struct snd_pcm_substream
*substream
, int cmd
)
129 struct snd_soc_pcm_runtime
*rtd
= snd_soc_substream_to_rtd(substream
);
130 struct snd_soc_card
*card
= rtd
->card
;
131 struct sof_es8336_private
*priv
= snd_soc_card_get_drvdata(card
);
134 case SNDRV_PCM_TRIGGER_START
:
135 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE
:
136 case SNDRV_PCM_TRIGGER_RESUME
:
139 case SNDRV_PCM_TRIGGER_PAUSE_PUSH
:
140 case SNDRV_PCM_TRIGGER_SUSPEND
:
141 case SNDRV_PCM_TRIGGER_STOP
:
142 if (priv
->speaker_en
== false)
143 if (substream
->stream
== 0) {
144 cancel_delayed_work(&priv
->pcm_pop_work
);
145 gpiod_set_value_cansleep(priv
->gpio_speakers
, true);
155 static int sof_es8316_speaker_power_event(struct snd_soc_dapm_widget
*w
,
156 struct snd_kcontrol
*kcontrol
, int event
)
158 struct snd_soc_card
*card
= w
->dapm
->card
;
159 struct sof_es8336_private
*priv
= snd_soc_card_get_drvdata(card
);
161 if (priv
->speaker_en
== !SND_SOC_DAPM_EVENT_ON(event
))
164 priv
->speaker_en
= !SND_SOC_DAPM_EVENT_ON(event
);
166 queue_delayed_work(system_wq
, &priv
->pcm_pop_work
, msecs_to_jiffies(70));
170 static const struct snd_soc_dapm_widget sof_es8316_widgets
[] = {
171 SND_SOC_DAPM_SPK("Speaker", NULL
),
172 SND_SOC_DAPM_HP("Headphone", NULL
),
173 SND_SOC_DAPM_MIC("Headset Mic", NULL
),
174 SND_SOC_DAPM_MIC("Internal Mic", NULL
),
176 SND_SOC_DAPM_SUPPLY("Speaker Power", SND_SOC_NOPM
, 0, 0,
177 sof_es8316_speaker_power_event
,
178 SND_SOC_DAPM_PRE_PMD
| SND_SOC_DAPM_POST_PMU
),
181 static const struct snd_soc_dapm_widget dmic_widgets
[] = {
182 SND_SOC_DAPM_MIC("SoC DMIC", NULL
),
185 static const struct snd_soc_dapm_route sof_es8316_audio_map
[] = {
186 {"Headphone", NULL
, "HPOL"},
187 {"Headphone", NULL
, "HPOR"},
190 * There is no separate speaker output instead the speakers are muxed to
191 * the HP outputs. The mux is controlled Speaker and/or headphone switch.
193 {"Speaker", NULL
, "HPOL"},
194 {"Speaker", NULL
, "HPOR"},
195 {"Speaker", NULL
, "Speaker Power"},
198 static const struct snd_soc_dapm_route sof_es8316_headset_mic2_map
[] = {
199 {"MIC1", NULL
, "Internal Mic"},
200 {"MIC2", NULL
, "Headset Mic"},
203 static const struct snd_soc_dapm_route sof_es8316_headset_mic1_map
[] = {
204 {"MIC2", NULL
, "Internal Mic"},
205 {"MIC1", NULL
, "Headset Mic"},
208 static const struct snd_soc_dapm_route dmic_map
[] = {
210 {"DMic", NULL
, "SoC DMIC"},
213 static const struct snd_kcontrol_new sof_es8316_controls
[] = {
214 SOC_DAPM_PIN_SWITCH("Speaker"),
215 SOC_DAPM_PIN_SWITCH("Headphone"),
216 SOC_DAPM_PIN_SWITCH("Headset Mic"),
217 SOC_DAPM_PIN_SWITCH("Internal Mic"),
220 static struct snd_soc_jack_pin sof_es8316_jack_pins
[] = {
223 .mask
= SND_JACK_HEADPHONE
,
226 .pin
= "Headset Mic",
227 .mask
= SND_JACK_MICROPHONE
,
231 static int dmic_init(struct snd_soc_pcm_runtime
*runtime
)
233 struct snd_soc_card
*card
= runtime
->card
;
236 ret
= snd_soc_dapm_new_controls(&card
->dapm
, dmic_widgets
,
237 ARRAY_SIZE(dmic_widgets
));
239 dev_err(card
->dev
, "DMic widget addition failed: %d\n", ret
);
243 ret
= snd_soc_dapm_add_routes(&card
->dapm
, dmic_map
,
244 ARRAY_SIZE(dmic_map
));
246 dev_err(card
->dev
, "DMic map addition failed: %d\n", ret
);
251 static int sof_hdmi_init(struct snd_soc_pcm_runtime
*runtime
)
253 struct sof_es8336_private
*priv
= snd_soc_card_get_drvdata(runtime
->card
);
254 struct snd_soc_dai
*dai
= snd_soc_rtd_to_codec(runtime
, 0);
255 struct sof_hdmi_pcm
*pcm
;
257 pcm
= devm_kzalloc(runtime
->card
->dev
, sizeof(*pcm
), GFP_KERNEL
);
261 /* dai_link id is 1:1 mapped to the PCM device */
262 pcm
->device
= runtime
->dai_link
->id
;
263 pcm
->codec_dai
= dai
;
265 list_add_tail(&pcm
->head
, &priv
->hdmi_pcm_list
);
270 static int sof_es8316_init(struct snd_soc_pcm_runtime
*runtime
)
272 struct snd_soc_component
*codec
= snd_soc_rtd_to_codec(runtime
, 0)->component
;
273 struct snd_soc_card
*card
= runtime
->card
;
274 struct sof_es8336_private
*priv
= snd_soc_card_get_drvdata(card
);
275 const struct snd_soc_dapm_route
*custom_map
;
279 card
->dapm
.idle_bias_off
= true;
281 if (quirk
& SOC_ES8336_HEADSET_MIC1
) {
282 custom_map
= sof_es8316_headset_mic1_map
;
283 num_routes
= ARRAY_SIZE(sof_es8316_headset_mic1_map
);
285 custom_map
= sof_es8316_headset_mic2_map
;
286 num_routes
= ARRAY_SIZE(sof_es8316_headset_mic2_map
);
289 ret
= snd_soc_dapm_add_routes(&card
->dapm
, custom_map
, num_routes
);
293 ret
= snd_soc_card_jack_new_pins(card
, "Headset",
294 SND_JACK_HEADSET
| SND_JACK_BTN_0
,
295 &priv
->jack
, sof_es8316_jack_pins
,
296 ARRAY_SIZE(sof_es8316_jack_pins
));
298 dev_err(card
->dev
, "jack creation failed %d\n", ret
);
302 snd_jack_set_key(priv
->jack
.jack
, SND_JACK_BTN_0
, KEY_PLAYPAUSE
);
304 snd_soc_component_set_jack(codec
, &priv
->jack
, NULL
);
309 static void sof_es8316_exit(struct snd_soc_pcm_runtime
*rtd
)
311 struct snd_soc_component
*component
= snd_soc_rtd_to_codec(rtd
, 0)->component
;
313 snd_soc_component_set_jack(component
, NULL
, NULL
);
316 static int sof_es8336_quirk_cb(const struct dmi_system_id
*id
)
318 quirk
= (unsigned long)id
->driver_data
;
324 * this table should only be used to add GPIO or jack-detection quirks
325 * that cannot be detected from ACPI tables. The SSP and DMIC
326 * information are providing by the platform driver and are aligned
327 * with the topology used.
329 * If the GPIO support is missing, the quirk parameter can be used to
330 * enable speakers. In that case it's recommended to keep the SSP and DMIC
331 * information consistent, overriding the SSP and DMIC can only be done
332 * if the topology file is modified as well.
334 static const struct dmi_system_id sof_es8336_quirk_table
[] = {
336 .callback
= sof_es8336_quirk_cb
,
338 DMI_MATCH(DMI_SYS_VENDOR
, "IP3 tech"),
339 DMI_MATCH(DMI_BOARD_NAME
, "WN1"),
341 .driver_data
= (void *)(SOF_ES8336_SPEAKERS_EN_GPIO1_QUIRK
)
344 .callback
= sof_es8336_quirk_cb
,
346 DMI_MATCH(DMI_SYS_VENDOR
, "HUAWEI"),
347 DMI_MATCH(DMI_BOARD_NAME
, "BOHB-WAX9-PCB-B2"),
349 .driver_data
= (void *)(SOF_ES8336_HEADPHONE_GPIO
|
350 SOC_ES8336_HEADSET_MIC1
)
355 static int sof_es8336_hw_params(struct snd_pcm_substream
*substream
,
356 struct snd_pcm_hw_params
*params
)
358 struct snd_soc_pcm_runtime
*rtd
= snd_soc_substream_to_rtd(substream
);
359 struct snd_soc_dai
*codec_dai
= snd_soc_rtd_to_codec(rtd
, 0);
360 const int sysclk
= 19200000;
363 ret
= snd_soc_dai_set_sysclk(codec_dai
, 1, sysclk
, SND_SOC_CLOCK_OUT
);
365 dev_err(rtd
->dev
, "%s, Failed to set ES8336 SYSCLK: %d\n",
373 /* machine stream operations */
374 static const struct snd_soc_ops sof_es8336_ops
= {
375 .hw_params
= sof_es8336_hw_params
,
376 .trigger
= sof_8336_trigger
,
379 static struct snd_soc_dai_link_component platform_component
[] = {
381 /* name might be overridden during probe */
382 .name
= "0000:00:1f.3"
386 SND_SOC_DAILINK_DEF(es8336_codec
,
387 DAILINK_COMP_ARRAY(COMP_CODEC("i2c-ESSX8336:00", "ES8316 HiFi")));
389 static struct snd_soc_dai_link_component dmic_component
[] = {
391 .name
= "dmic-codec",
392 .dai_name
= "dmic-hifi",
396 static int sof_es8336_late_probe(struct snd_soc_card
*card
)
398 struct sof_es8336_private
*priv
= snd_soc_card_get_drvdata(card
);
399 struct sof_hdmi_pcm
*pcm
;
401 if (list_empty(&priv
->hdmi_pcm_list
))
404 pcm
= list_first_entry(&priv
->hdmi_pcm_list
, struct sof_hdmi_pcm
, head
);
406 return hda_dsp_hdmi_build_controls(card
, pcm
->codec_dai
->component
);
410 static struct snd_soc_card sof_es8336_card
= {
411 .name
= "essx8336", /* sof- prefix added automatically */
412 .owner
= THIS_MODULE
,
413 .dapm_widgets
= sof_es8316_widgets
,
414 .num_dapm_widgets
= ARRAY_SIZE(sof_es8316_widgets
),
415 .dapm_routes
= sof_es8316_audio_map
,
416 .num_dapm_routes
= ARRAY_SIZE(sof_es8316_audio_map
),
417 .controls
= sof_es8316_controls
,
418 .num_controls
= ARRAY_SIZE(sof_es8316_controls
),
419 .fully_routed
= true,
420 .late_probe
= sof_es8336_late_probe
,
424 static struct snd_soc_dai_link
*sof_card_dai_links_create(struct device
*dev
,
429 struct snd_soc_dai_link_component
*cpus
;
430 struct snd_soc_dai_link
*links
;
431 struct snd_soc_dai_link_component
*idisp_components
;
432 int hdmi_id_offset
= 0;
436 links
= devm_kcalloc(dev
, sof_es8336_card
.num_links
,
437 sizeof(struct snd_soc_dai_link
), GFP_KERNEL
);
438 cpus
= devm_kcalloc(dev
, sof_es8336_card
.num_links
,
439 sizeof(struct snd_soc_dai_link_component
), GFP_KERNEL
);
444 links
[id
].name
= devm_kasprintf(dev
, GFP_KERNEL
,
445 "SSP%d-Codec", ssp_codec
);
450 links
[id
].codecs
= es8336_codec
;
451 links
[id
].num_codecs
= ARRAY_SIZE(es8336_codec
);
452 links
[id
].platforms
= platform_component
;
453 links
[id
].num_platforms
= ARRAY_SIZE(platform_component
);
454 links
[id
].init
= sof_es8316_init
;
455 links
[id
].exit
= sof_es8316_exit
;
456 links
[id
].ops
= &sof_es8336_ops
;
457 links
[id
].nonatomic
= true;
458 links
[id
].no_pcm
= 1;
459 links
[id
].cpus
= &cpus
[id
];
460 links
[id
].num_cpus
= 1;
462 links
[id
].cpus
->dai_name
= devm_kasprintf(dev
, GFP_KERNEL
,
465 if (!links
[id
].cpus
->dai_name
)
471 if (dmic_be_num
> 0) {
472 /* at least we have dmic01 */
473 links
[id
].name
= "dmic01";
474 links
[id
].cpus
= &cpus
[id
];
475 links
[id
].cpus
->dai_name
= "DMIC01 Pin";
476 links
[id
].init
= dmic_init
;
477 if (dmic_be_num
> 1) {
478 /* set up 2 BE links at most */
479 links
[id
+ 1].name
= "dmic16k";
480 links
[id
+ 1].cpus
= &cpus
[id
+ 1];
481 links
[id
+ 1].cpus
->dai_name
= "DMIC16k Pin";
485 /* HDMI dai link starts at 3 according to current topology settings */
489 for (i
= 0; i
< dmic_be_num
; i
++) {
491 links
[id
].num_cpus
= 1;
492 links
[id
].codecs
= dmic_component
;
493 links
[id
].num_codecs
= ARRAY_SIZE(dmic_component
);
494 links
[id
].platforms
= platform_component
;
495 links
[id
].num_platforms
= ARRAY_SIZE(platform_component
);
496 links
[id
].ignore_suspend
= 1;
497 links
[id
].capture_only
= 1;
498 links
[id
].no_pcm
= 1;
505 idisp_components
= devm_kcalloc(dev
,
507 sizeof(struct snd_soc_dai_link_component
),
509 if (!idisp_components
)
513 for (i
= 1; i
<= hdmi_num
; i
++) {
514 links
[id
].name
= devm_kasprintf(dev
, GFP_KERNEL
,
519 links
[id
].id
= id
+ hdmi_id_offset
;
520 links
[id
].cpus
= &cpus
[id
];
521 links
[id
].num_cpus
= 1;
522 links
[id
].cpus
->dai_name
= devm_kasprintf(dev
, GFP_KERNEL
,
524 if (!links
[id
].cpus
->dai_name
)
527 idisp_components
[i
- 1].name
= "ehdaudio0D2";
528 idisp_components
[i
- 1].dai_name
= devm_kasprintf(dev
,
532 if (!idisp_components
[i
- 1].dai_name
)
535 links
[id
].codecs
= &idisp_components
[i
- 1];
536 links
[id
].num_codecs
= 1;
537 links
[id
].platforms
= platform_component
;
538 links
[id
].num_platforms
= ARRAY_SIZE(platform_component
);
539 links
[id
].init
= sof_hdmi_init
;
540 links
[id
].playback_only
= 1;
541 links
[id
].no_pcm
= 1;
547 if (quirk
& SOF_SSP_HDMI_CAPTURE_PRESENT
) {
548 int num_of_hdmi_ssp
= (quirk
& SOF_NO_OF_HDMI_CAPTURE_SSP_MASK
) >>
549 SOF_NO_OF_HDMI_CAPTURE_SSP_SHIFT
;
551 for (i
= 1; i
<= num_of_hdmi_ssp
; i
++) {
552 int port
= (i
== 1 ? (quirk
& SOF_HDMI_CAPTURE_1_SSP_MASK
) >>
553 SOF_HDMI_CAPTURE_1_SSP_SHIFT
:
554 (quirk
& SOF_HDMI_CAPTURE_2_SSP_MASK
) >>
555 SOF_HDMI_CAPTURE_2_SSP_SHIFT
);
557 links
[id
].cpus
= &cpus
[id
];
558 links
[id
].cpus
->dai_name
= devm_kasprintf(dev
, GFP_KERNEL
,
560 if (!links
[id
].cpus
->dai_name
)
562 links
[id
].name
= devm_kasprintf(dev
, GFP_KERNEL
, "SSP%d-HDMI", port
);
565 links
[id
].id
= id
+ hdmi_id_offset
;
566 links
[id
].codecs
= &snd_soc_dummy_dlc
;
567 links
[id
].num_codecs
= 1;
568 links
[id
].platforms
= platform_component
;
569 links
[id
].num_platforms
= ARRAY_SIZE(platform_component
);
570 links
[id
].capture_only
= 1;
571 links
[id
].no_pcm
= 1;
572 links
[id
].num_cpus
= 1;
583 static char soc_components
[30];
585 /* i2c-<HID>:00 with HID being 8 chars */
586 static char codec_name
[SND_ACPI_I2C_ID_LEN
];
588 static int sof_es8336_probe(struct platform_device
*pdev
)
590 struct device
*dev
= &pdev
->dev
;
591 struct snd_soc_card
*card
;
592 struct snd_soc_acpi_mach
*mach
= pdev
->dev
.platform_data
;
593 struct property_entry props
[MAX_NO_PROPS
] = {};
594 struct sof_es8336_private
*priv
;
595 struct fwnode_handle
*fwnode
;
596 struct acpi_device
*adev
;
597 struct snd_soc_dai_link
*dai_links
;
598 struct device
*codec_dev
;
599 const struct acpi_gpio_mapping
*gpio_mapping
;
600 unsigned int cnt
= 0;
605 priv
= devm_kzalloc(dev
, sizeof(*priv
), GFP_KERNEL
);
609 card
= &sof_es8336_card
;
612 if (pdev
->id_entry
&& pdev
->id_entry
->driver_data
)
613 quirk
= (unsigned long)pdev
->id_entry
->driver_data
;
615 /* check GPIO DMI quirks */
616 dmi_check_system(sof_es8336_quirk_table
);
618 /* Use NHLT configuration only for Non-HDMI capture use case.
619 * Because more than one SSP will be enabled for HDMI capture hence wrong codec
622 if (mach
->tplg_quirk_mask
& SND_SOC_ACPI_TPLG_INTEL_SSP_NUMBER
) {
623 if (!mach
->mach_params
.i2s_link_mask
) {
624 dev_warn(dev
, "No I2S link information provided, using SSP0. This may need to be modified with the quirk module parameter\n");
627 * Set configuration based on platform NHLT.
628 * In this machine driver, we can only support one SSP for the
630 * In some cases multiple SSPs can be reported by NHLT, starting MSB-first
631 * seems to pick the right connection.
635 /* fls returns 1-based results, SSPs indices are 0-based */
636 ssp
= fls(mach
->mach_params
.i2s_link_mask
) - 1;
642 if (mach
->mach_params
.dmic_num
)
643 quirk
|= SOF_ES8336_ENABLE_DMIC
;
645 if (quirk_override
!= -1) {
646 dev_info(dev
, "Overriding quirk 0x%lx => 0x%x\n",
647 quirk
, quirk_override
);
648 quirk
= quirk_override
;
652 if (quirk
& SOF_ES8336_ENABLE_DMIC
)
655 /* compute number of dai links */
656 sof_es8336_card
.num_links
= 1 + dmic_be_num
+ hdmi_num
;
658 if (quirk
& SOF_SSP_HDMI_CAPTURE_PRESENT
)
659 sof_es8336_card
.num_links
+= (quirk
& SOF_NO_OF_HDMI_CAPTURE_SSP_MASK
) >>
660 SOF_NO_OF_HDMI_CAPTURE_SSP_SHIFT
;
662 dai_links
= sof_card_dai_links_create(dev
,
663 SOF_ES8336_SSP_CODEC(quirk
),
664 dmic_be_num
, hdmi_num
);
668 sof_es8336_card
.dai_link
= dai_links
;
670 /* fixup codec name based on HID */
671 adev
= acpi_dev_get_first_match_dev(mach
->id
, NULL
, -1);
673 snprintf(codec_name
, sizeof(codec_name
),
674 "i2c-%s", acpi_dev_name(adev
));
675 dai_links
[0].codecs
->name
= codec_name
;
677 /* also fixup codec dai name if relevant */
678 if (!strncmp(mach
->id
, "ESSX8326", SND_ACPI_I2C_ID_LEN
))
679 dai_links
[0].codecs
->dai_name
= "ES8326 HiFi";
681 dev_err(dev
, "Error cannot find '%s' dev\n", mach
->id
);
685 codec_dev
= acpi_get_first_physical_node(adev
);
688 return -EPROBE_DEFER
;
689 priv
->codec_dev
= get_device(codec_dev
);
691 ret
= snd_soc_fixup_dai_links_platform_name(&sof_es8336_card
,
692 mach
->mach_params
.platform
);
694 put_device(codec_dev
);
698 if (quirk
& SOF_ES8336_JD_INVERTED
)
699 props
[cnt
++] = PROPERTY_ENTRY_BOOL("everest,jack-detect-inverted");
702 fwnode
= fwnode_create_software_node(props
, NULL
);
703 if (IS_ERR(fwnode
)) {
704 put_device(codec_dev
);
705 return PTR_ERR(fwnode
);
708 ret
= device_add_software_node(codec_dev
, to_software_node(fwnode
));
710 fwnode_handle_put(fwnode
);
713 put_device(codec_dev
);
718 /* get speaker enable GPIO */
719 if (quirk
& SOF_ES8336_HEADPHONE_GPIO
) {
720 if (quirk
& SOF_ES8336_SPEAKERS_EN_GPIO1_QUIRK
)
721 gpio_mapping
= acpi_enable_both_gpios
;
723 gpio_mapping
= acpi_enable_both_gpios_rev_order
;
724 } else if (quirk
& SOF_ES8336_SPEAKERS_EN_GPIO1_QUIRK
) {
725 gpio_mapping
= acpi_speakers_enable_gpio1
;
727 gpio_mapping
= acpi_speakers_enable_gpio0
;
730 ret
= devm_acpi_dev_add_driver_gpios(codec_dev
, gpio_mapping
);
732 dev_warn(codec_dev
, "unable to add GPIO mapping table\n");
734 priv
->gpio_speakers
= gpiod_get_optional(codec_dev
, "speakers-enable", GPIOD_OUT_LOW
);
735 if (IS_ERR(priv
->gpio_speakers
)) {
736 ret
= dev_err_probe(dev
, PTR_ERR(priv
->gpio_speakers
),
737 "could not get speakers-enable GPIO\n");
741 priv
->gpio_headphone
= gpiod_get_optional(codec_dev
, "headphone-enable", GPIOD_OUT_LOW
);
742 if (IS_ERR(priv
->gpio_headphone
)) {
743 ret
= dev_err_probe(dev
, PTR_ERR(priv
->gpio_headphone
),
744 "could not get headphone-enable GPIO\n");
748 INIT_LIST_HEAD(&priv
->hdmi_pcm_list
);
749 INIT_DELAYED_WORK(&priv
->pcm_pop_work
,
750 pcm_pop_work_events
);
751 snd_soc_card_set_drvdata(card
, priv
);
753 if (mach
->mach_params
.dmic_num
> 0) {
754 snprintf(soc_components
, sizeof(soc_components
),
755 "cfg-dmics:%d", mach
->mach_params
.dmic_num
);
756 card
->components
= soc_components
;
759 ret
= devm_snd_soc_register_card(dev
, card
);
761 gpiod_put(priv
->gpio_speakers
);
762 dev_err(dev
, "snd_soc_register_card failed: %d\n", ret
);
765 platform_set_drvdata(pdev
, &sof_es8336_card
);
769 device_remove_software_node(priv
->codec_dev
);
770 put_device(codec_dev
);
774 static void sof_es8336_remove(struct platform_device
*pdev
)
776 struct snd_soc_card
*card
= platform_get_drvdata(pdev
);
777 struct sof_es8336_private
*priv
= snd_soc_card_get_drvdata(card
);
779 cancel_delayed_work_sync(&priv
->pcm_pop_work
);
780 gpiod_put(priv
->gpio_speakers
);
781 device_remove_software_node(priv
->codec_dev
);
782 put_device(priv
->codec_dev
);
785 static const struct platform_device_id board_ids
[] = {
787 .name
= "sof-essx8336", /* default quirk == 0 */
790 .name
= "adl_es83x6_c1_h02",
791 .driver_data
= (kernel_ulong_t
)(SOF_ES8336_SSP_CODEC(1) |
792 SOF_NO_OF_HDMI_CAPTURE_SSP(2) |
793 SOF_HDMI_CAPTURE_1_SSP(0) |
794 SOF_HDMI_CAPTURE_2_SSP(2) |
795 SOF_SSP_HDMI_CAPTURE_PRESENT
|
796 SOF_ES8336_SPEAKERS_EN_GPIO1_QUIRK
|
797 SOF_ES8336_JD_INVERTED
),
800 .name
= "rpl_es83x6_c1_h02",
801 .driver_data
= (kernel_ulong_t
)(SOF_ES8336_SSP_CODEC(1) |
802 SOF_NO_OF_HDMI_CAPTURE_SSP(2) |
803 SOF_HDMI_CAPTURE_1_SSP(0) |
804 SOF_HDMI_CAPTURE_2_SSP(2) |
805 SOF_SSP_HDMI_CAPTURE_PRESENT
|
806 SOF_ES8336_SPEAKERS_EN_GPIO1_QUIRK
|
807 SOF_ES8336_JD_INVERTED
),
810 .name
= "mtl_es83x6_c1_h02",
811 .driver_data
= (kernel_ulong_t
)(SOF_ES8336_SSP_CODEC(1) |
812 SOF_NO_OF_HDMI_CAPTURE_SSP(2) |
813 SOF_HDMI_CAPTURE_1_SSP(0) |
814 SOF_HDMI_CAPTURE_2_SSP(2) |
815 SOF_SSP_HDMI_CAPTURE_PRESENT
|
816 SOF_ES8336_SPEAKERS_EN_GPIO1_QUIRK
|
817 SOF_ES8336_JD_INVERTED
),
820 .name
= "arl_es83x6_c1_h02",
821 .driver_data
= (kernel_ulong_t
)(SOF_ES8336_SSP_CODEC(1) |
822 SOF_NO_OF_HDMI_CAPTURE_SSP(2) |
823 SOF_HDMI_CAPTURE_1_SSP(0) |
824 SOF_HDMI_CAPTURE_2_SSP(2) |
825 SOF_SSP_HDMI_CAPTURE_PRESENT
|
826 SOF_ES8336_SPEAKERS_EN_GPIO1_QUIRK
|
827 SOF_ES8336_JD_INVERTED
),
831 MODULE_DEVICE_TABLE(platform
, board_ids
);
833 static struct platform_driver sof_es8336_driver
= {
835 .name
= "sof-essx8336",
836 .pm
= &snd_soc_pm_ops
,
838 .probe
= sof_es8336_probe
,
839 .remove
= sof_es8336_remove
,
840 .id_table
= board_ids
,
842 module_platform_driver(sof_es8336_driver
);
844 MODULE_DESCRIPTION("ASoC Intel(R) SOF + ES8336 Machine driver");
845 MODULE_LICENSE("GPL");
846 MODULE_IMPORT_NS("SND_SOC_INTEL_HDA_DSP_COMMON");