xref: /linux/sound/soc/amd/acp3x-rt5682-max9836.c (revision 9e4e86a604dfd06402933467578c4b79f5412b2c)
1 // SPDX-License-Identifier: GPL-2.0+
2 //
3 // Machine driver for AMD ACP Audio engine using DA7219 & MAX98357 codec.
4 //
5 //Copyright 2016 Advanced Micro Devices, Inc.
6 
7 #include <sound/core.h>
8 #include <sound/soc.h>
9 #include <sound/pcm.h>
10 #include <sound/pcm_params.h>
11 #include <sound/soc-dapm.h>
12 #include <sound/jack.h>
13 #include <linux/clk.h>
14 #include <linux/gpio/consumer.h>
15 #include <linux/module.h>
16 #include <linux/i2c.h>
17 #include <linux/input.h>
18 #include <linux/io.h>
19 #include <linux/acpi.h>
20 
21 #include "raven/acp3x.h"
22 #include "../codecs/rt5682.h"
23 #include "../codecs/rt1015.h"
24 
25 #define PCO_PLAT_CLK 48000000
26 #define RT5682_PLL_FREQ (48000 * 512)
27 #define DUAL_CHANNEL		2
28 
29 static struct snd_soc_jack pco_jack;
30 static struct snd_soc_jack_pin pco_jack_pins[] = {
31 	{
32 		.pin = "Headphone Jack",
33 		.mask = SND_JACK_HEADPHONE,
34 	},
35 	{
36 		.pin = "Headset Mic",
37 		.mask = SND_JACK_MICROPHONE,
38 	},
39 };
40 
41 static struct clk *rt5682_dai_wclk;
42 static struct clk *rt5682_dai_bclk;
43 static struct gpio_desc *dmic_sel;
44 void *soc_is_rltk_max(struct device *dev);
45 
46 enum {
47 	RT5682 = 0,
48 	MAX,
49 	EC,
50 };
51 
acp3x_5682_init(struct snd_soc_pcm_runtime * rtd)52 static int acp3x_5682_init(struct snd_soc_pcm_runtime *rtd)
53 {
54 	int ret;
55 	struct snd_soc_card *card = rtd->card;
56 	struct snd_soc_dai *codec_dai = snd_soc_rtd_to_codec(rtd, 0);
57 	struct snd_soc_component *component = codec_dai->component;
58 
59 	dev_info(rtd->dev, "codec dai name = %s\n", codec_dai->name);
60 
61 	/* set rt5682 dai fmt */
62 	ret =  snd_soc_dai_set_fmt(codec_dai, SND_SOC_DAIFMT_I2S
63 			| SND_SOC_DAIFMT_NB_NF
64 			| SND_SOC_DAIFMT_CBP_CFP);
65 	if (ret < 0) {
66 		dev_err(rtd->card->dev,
67 				"Failed to set rt5682 dai fmt: %d\n", ret);
68 		return ret;
69 	}
70 
71 	/* set codec PLL */
72 	ret = snd_soc_dai_set_pll(codec_dai, RT5682_PLL2, RT5682_PLL2_S_MCLK,
73 				  PCO_PLAT_CLK, RT5682_PLL_FREQ);
74 	if (ret < 0) {
75 		dev_err(rtd->dev, "can't set rt5682 PLL: %d\n", ret);
76 		return ret;
77 	}
78 
79 	/* Set codec sysclk */
80 	ret = snd_soc_dai_set_sysclk(codec_dai, RT5682_SCLK_S_PLL2,
81 			RT5682_PLL_FREQ, SND_SOC_CLOCK_IN);
82 	if (ret < 0) {
83 		dev_err(rtd->dev,
84 			"Failed to set rt5682 SYSCLK: %d\n", ret);
85 		return ret;
86 	}
87 
88 	/* Set tdm/i2s1 master bclk ratio */
89 	ret = snd_soc_dai_set_bclk_ratio(codec_dai, 64);
90 	if (ret < 0) {
91 		dev_err(rtd->dev,
92 			"Failed to set rt5682 tdm bclk ratio: %d\n", ret);
93 		return ret;
94 	}
95 
96 	rt5682_dai_wclk = devm_clk_get(component->dev, "rt5682-dai-wclk");
97 	if (IS_ERR(rt5682_dai_wclk))
98 		return PTR_ERR(rt5682_dai_wclk);
99 
100 	rt5682_dai_bclk = devm_clk_get(component->dev, "rt5682-dai-bclk");
101 	if (IS_ERR(rt5682_dai_bclk))
102 		return PTR_ERR(rt5682_dai_bclk);
103 
104 	ret = snd_soc_card_jack_new_pins(card, "Headset Jack",
105 					 SND_JACK_HEADSET |
106 					 SND_JACK_BTN_0 | SND_JACK_BTN_1 |
107 					 SND_JACK_BTN_2 | SND_JACK_BTN_3,
108 					 &pco_jack,
109 					 pco_jack_pins,
110 					 ARRAY_SIZE(pco_jack_pins));
111 	if (ret) {
112 		dev_err(card->dev, "HP jack creation failed %d\n", ret);
113 		return ret;
114 	}
115 
116 	snd_jack_set_key(pco_jack.jack, SND_JACK_BTN_0, KEY_PLAYPAUSE);
117 	snd_jack_set_key(pco_jack.jack, SND_JACK_BTN_1, KEY_VOICECOMMAND);
118 	snd_jack_set_key(pco_jack.jack, SND_JACK_BTN_2, KEY_VOLUMEUP);
119 	snd_jack_set_key(pco_jack.jack, SND_JACK_BTN_3, KEY_VOLUMEDOWN);
120 
121 	ret = snd_soc_component_set_jack(component, &pco_jack, NULL);
122 	if (ret) {
123 		dev_err(rtd->dev, "Headset Jack call-back failed: %d\n", ret);
124 		return ret;
125 	}
126 
127 	return ret;
128 }
129 
rt5682_clk_enable(struct snd_pcm_substream * substream)130 static int rt5682_clk_enable(struct snd_pcm_substream *substream)
131 {
132 	int ret = 0;
133 	struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream);
134 
135 	/* RT5682 will support only 48K output with 48M mclk */
136 	clk_set_rate(rt5682_dai_wclk, 48000);
137 	clk_set_rate(rt5682_dai_bclk, 48000 * 64);
138 	ret = clk_prepare_enable(rt5682_dai_wclk);
139 	if (ret < 0) {
140 		dev_err(rtd->dev, "can't enable wclk %d\n", ret);
141 		return ret;
142 	}
143 
144 	return ret;
145 }
146 
acp3x_1015_hw_params(struct snd_pcm_substream * substream,struct snd_pcm_hw_params * params)147 static int acp3x_1015_hw_params(struct snd_pcm_substream *substream,
148 					struct snd_pcm_hw_params *params)
149 {
150 	struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream);
151 	struct snd_soc_dai *codec_dai;
152 	int srate, i, ret;
153 
154 	ret = 0;
155 	srate = params_rate(params);
156 
157 	for_each_rtd_codec_dais(rtd, i, codec_dai) {
158 		if (strcmp(codec_dai->name, "rt1015-aif"))
159 			continue;
160 
161 		ret = snd_soc_dai_set_pll(codec_dai, 0, RT1015_PLL_S_BCLK,
162 						64 * srate, 256 * srate);
163 		if (ret < 0)
164 			return ret;
165 		ret = snd_soc_dai_set_sysclk(codec_dai, RT1015_SCLK_S_PLL,
166 					256 * srate, SND_SOC_CLOCK_IN);
167 		if (ret < 0)
168 			return ret;
169 	}
170 	return ret;
171 }
172 
rt5682_clk_disable(void)173 static void rt5682_clk_disable(void)
174 {
175 	clk_disable_unprepare(rt5682_dai_wclk);
176 }
177 
178 static const unsigned int channels[] = {
179 	DUAL_CHANNEL,
180 };
181 
182 static const unsigned int rates[] = {
183 	48000,
184 };
185 
186 static const struct snd_pcm_hw_constraint_list constraints_rates = {
187 	.count = ARRAY_SIZE(rates),
188 	.list  = rates,
189 	.mask = 0,
190 };
191 
192 static const struct snd_pcm_hw_constraint_list constraints_channels = {
193 	.count = ARRAY_SIZE(channels),
194 	.list = channels,
195 	.mask = 0,
196 };
197 
acp3x_5682_startup(struct snd_pcm_substream * substream)198 static int acp3x_5682_startup(struct snd_pcm_substream *substream)
199 {
200 	struct snd_pcm_runtime *runtime = substream->runtime;
201 	struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream);
202 	struct snd_soc_card *card = rtd->card;
203 	struct acp3x_platform_info *machine = snd_soc_card_get_drvdata(card);
204 
205 	machine->play_i2s_instance = I2S_SP_INSTANCE;
206 	machine->cap_i2s_instance = I2S_SP_INSTANCE;
207 
208 	runtime->hw.channels_max = DUAL_CHANNEL;
209 	snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS,
210 				   &constraints_channels);
211 	snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_RATE,
212 				   &constraints_rates);
213 	return rt5682_clk_enable(substream);
214 }
215 
acp3x_max_startup(struct snd_pcm_substream * substream)216 static int acp3x_max_startup(struct snd_pcm_substream *substream)
217 {
218 	struct snd_pcm_runtime *runtime = substream->runtime;
219 	struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream);
220 	struct snd_soc_card *card = rtd->card;
221 	struct acp3x_platform_info *machine = snd_soc_card_get_drvdata(card);
222 
223 	machine->play_i2s_instance = I2S_BT_INSTANCE;
224 
225 	runtime->hw.channels_max = DUAL_CHANNEL;
226 	snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS,
227 				   &constraints_channels);
228 	snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_RATE,
229 				   &constraints_rates);
230 	return rt5682_clk_enable(substream);
231 }
232 
acp3x_ec_dmic0_startup(struct snd_pcm_substream * substream)233 static int acp3x_ec_dmic0_startup(struct snd_pcm_substream *substream)
234 {
235 	struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream);
236 	struct snd_soc_card *card = rtd->card;
237 	struct snd_soc_dai *codec_dai = snd_soc_rtd_to_codec(rtd, 0);
238 	struct acp3x_platform_info *machine = snd_soc_card_get_drvdata(card);
239 
240 	machine->cap_i2s_instance = I2S_BT_INSTANCE;
241 	snd_soc_dai_set_bclk_ratio(codec_dai, 64);
242 
243 	return rt5682_clk_enable(substream);
244 }
245 
246 static int dmic_switch;
247 
dmic_get(struct snd_kcontrol * kcontrol,struct snd_ctl_elem_value * ucontrol)248 static int dmic_get(struct snd_kcontrol *kcontrol,
249 			 struct snd_ctl_elem_value *ucontrol)
250 {
251 	ucontrol->value.integer.value[0] = dmic_switch;
252 	return 0;
253 }
254 
dmic_set(struct snd_kcontrol * kcontrol,struct snd_ctl_elem_value * ucontrol)255 static int dmic_set(struct snd_kcontrol *kcontrol,
256 			 struct snd_ctl_elem_value *ucontrol)
257 {
258 	if (dmic_sel) {
259 		dmic_switch = ucontrol->value.integer.value[0];
260 		gpiod_set_value(dmic_sel, dmic_switch);
261 	}
262 	return 0;
263 }
264 
rt5682_shutdown(struct snd_pcm_substream * substream)265 static void rt5682_shutdown(struct snd_pcm_substream *substream)
266 {
267 	rt5682_clk_disable();
268 }
269 
270 static const struct snd_soc_ops acp3x_5682_ops = {
271 	.startup = acp3x_5682_startup,
272 	.shutdown = rt5682_shutdown,
273 };
274 
275 static const struct snd_soc_ops acp3x_max_play_ops = {
276 	.startup = acp3x_max_startup,
277 	.shutdown = rt5682_shutdown,
278 	.hw_params = acp3x_1015_hw_params,
279 };
280 
281 static const struct snd_soc_ops acp3x_ec_cap0_ops = {
282 	.startup = acp3x_ec_dmic0_startup,
283 	.shutdown = rt5682_shutdown,
284 };
285 
286 SND_SOC_DAILINK_DEF(acp3x_i2s,
287 	DAILINK_COMP_ARRAY(COMP_CPU("acp3x_i2s_playcap.0")));
288 SND_SOC_DAILINK_DEF(acp3x_bt,
289 	DAILINK_COMP_ARRAY(COMP_CPU("acp3x_i2s_playcap.2")));
290 
291 SND_SOC_DAILINK_DEF(rt5682,
292 	DAILINK_COMP_ARRAY(COMP_CODEC("i2c-10EC5682:00", "rt5682-aif1")));
293 SND_SOC_DAILINK_DEF(max,
294 	DAILINK_COMP_ARRAY(COMP_CODEC("MX98357A:00", "HiFi")));
295 SND_SOC_DAILINK_DEF(rt1015p,
296 	DAILINK_COMP_ARRAY(COMP_CODEC("RTL1015:00", "HiFi")));
297 SND_SOC_DAILINK_DEF(rt1015,
298 	DAILINK_COMP_ARRAY(COMP_CODEC("i2c-10EC1015:00", "rt1015-aif"),
299 			COMP_CODEC("i2c-10EC1015:01", "rt1015-aif")));
300 SND_SOC_DAILINK_DEF(cros_ec,
301 	DAILINK_COMP_ARRAY(COMP_CODEC("GOOG0013:00", "EC Codec I2S RX")));
302 
303 SND_SOC_DAILINK_DEF(platform,
304 	DAILINK_COMP_ARRAY(COMP_PLATFORM("acp3x_rv_i2s_dma.0")));
305 
306 static struct snd_soc_codec_conf rt1015_conf[] = {
307 	{
308 		.dlc = COMP_CODEC_CONF("i2c-10EC1015:00"),
309 		.name_prefix = "Left",
310 	},
311 	{
312 		.dlc = COMP_CODEC_CONF("i2c-10EC1015:01"),
313 		.name_prefix = "Right",
314 	},
315 };
316 
317 static struct snd_soc_dai_link acp3x_dai[] = {
318 	[RT5682] = {
319 		.name = "acp3x-5682-play",
320 		.stream_name = "Playback",
321 		.dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF
322 				| SND_SOC_DAIFMT_CBP_CFP,
323 		.init = acp3x_5682_init,
324 		.ops = &acp3x_5682_ops,
325 		SND_SOC_DAILINK_REG(acp3x_i2s, rt5682, platform),
326 	},
327 	[MAX] = {
328 		.name = "acp3x-max98357-play",
329 		.stream_name = "HiFi Playback",
330 		.dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF
331 				| SND_SOC_DAIFMT_CBC_CFC,
332 		.playback_only = 1,
333 		.ops = &acp3x_max_play_ops,
334 		.cpus = acp3x_bt,
335 		.num_cpus = ARRAY_SIZE(acp3x_bt),
336 		.platforms = platform,
337 		.num_platforms = ARRAY_SIZE(platform),
338 	},
339 	[EC] = {
340 		.name = "acp3x-ec-dmic0-capture",
341 		.stream_name = "Capture DMIC0",
342 		.dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF
343 				| SND_SOC_DAIFMT_CBC_CFC,
344 		.capture_only = 1,
345 		.ops = &acp3x_ec_cap0_ops,
346 		SND_SOC_DAILINK_REG(acp3x_bt, cros_ec, platform),
347 	},
348 };
349 
350 static const char * const dmic_mux_text[] = {
351 	"Front Mic",
352 	"Rear Mic",
353 };
354 
355 static SOC_ENUM_SINGLE_DECL(
356 		acp3x_dmic_enum, SND_SOC_NOPM, 0, dmic_mux_text);
357 
358 static const struct snd_kcontrol_new acp3x_dmic_mux_control =
359 	SOC_DAPM_ENUM_EXT("DMIC Select Mux", acp3x_dmic_enum,
360 			  dmic_get, dmic_set);
361 
362 static const struct snd_soc_dapm_widget acp3x_5682_widgets[] = {
363 	SND_SOC_DAPM_HP("Headphone Jack", NULL),
364 	SND_SOC_DAPM_SPK("Spk", NULL),
365 	SND_SOC_DAPM_MIC("Headset Mic", NULL),
366 	SND_SOC_DAPM_MUX("Dmic Mux", SND_SOC_NOPM, 0, 0,
367 			 &acp3x_dmic_mux_control),
368 };
369 
370 static const struct snd_soc_dapm_route acp3x_5682_audio_route[] = {
371 	{"Headphone Jack", NULL, "HPOL"},
372 	{"Headphone Jack", NULL, "HPOR"},
373 	{"IN1P", NULL, "Headset Mic"},
374 	{"Spk", NULL, "Speaker"},
375 	{"Dmic Mux", "Front Mic", "DMIC"},
376 	{"Dmic Mux", "Rear Mic", "DMIC"},
377 };
378 
379 static const struct snd_kcontrol_new acp3x_5682_mc_controls[] = {
380 	SOC_DAPM_PIN_SWITCH("Headphone Jack"),
381 	SOC_DAPM_PIN_SWITCH("Spk"),
382 	SOC_DAPM_PIN_SWITCH("Headset Mic"),
383 };
384 
385 static struct snd_soc_card acp3x_5682 = {
386 	.name = "acp3xalc5682m98357",
387 	.owner = THIS_MODULE,
388 	.dai_link = acp3x_dai,
389 	.num_links = ARRAY_SIZE(acp3x_dai),
390 	.dapm_widgets = acp3x_5682_widgets,
391 	.num_dapm_widgets = ARRAY_SIZE(acp3x_5682_widgets),
392 	.dapm_routes = acp3x_5682_audio_route,
393 	.num_dapm_routes = ARRAY_SIZE(acp3x_5682_audio_route),
394 	.controls = acp3x_5682_mc_controls,
395 	.num_controls = ARRAY_SIZE(acp3x_5682_mc_controls),
396 };
397 
398 static const struct snd_soc_dapm_widget acp3x_1015_widgets[] = {
399 	SND_SOC_DAPM_HP("Headphone Jack", NULL),
400 	SND_SOC_DAPM_MIC("Headset Mic", NULL),
401 	SND_SOC_DAPM_MUX("Dmic Mux", SND_SOC_NOPM, 0, 0,
402 			 &acp3x_dmic_mux_control),
403 	SND_SOC_DAPM_SPK("Left Spk", NULL),
404 	SND_SOC_DAPM_SPK("Right Spk", NULL),
405 };
406 
407 static const struct snd_soc_dapm_route acp3x_1015_route[] = {
408 	{"Headphone Jack", NULL, "HPOL"},
409 	{"Headphone Jack", NULL, "HPOR"},
410 	{"IN1P", NULL, "Headset Mic"},
411 	{"Dmic Mux", "Front Mic", "DMIC"},
412 	{"Dmic Mux", "Rear Mic", "DMIC"},
413 	{"Left Spk", NULL, "Left SPO"},
414 	{"Right Spk", NULL, "Right SPO"},
415 };
416 
417 static const struct snd_kcontrol_new acp3x_mc_1015_controls[] = {
418 	SOC_DAPM_PIN_SWITCH("Headphone Jack"),
419 	SOC_DAPM_PIN_SWITCH("Headset Mic"),
420 	SOC_DAPM_PIN_SWITCH("Left Spk"),
421 	SOC_DAPM_PIN_SWITCH("Right Spk"),
422 };
423 
424 static struct snd_soc_card acp3x_1015 = {
425 	.name = "acp3xalc56821015",
426 	.owner = THIS_MODULE,
427 	.dai_link = acp3x_dai,
428 	.num_links = ARRAY_SIZE(acp3x_dai),
429 	.dapm_widgets = acp3x_1015_widgets,
430 	.num_dapm_widgets = ARRAY_SIZE(acp3x_1015_widgets),
431 	.dapm_routes = acp3x_1015_route,
432 	.num_dapm_routes = ARRAY_SIZE(acp3x_1015_route),
433 	.codec_conf = rt1015_conf,
434 	.num_configs = ARRAY_SIZE(rt1015_conf),
435 	.controls = acp3x_mc_1015_controls,
436 	.num_controls = ARRAY_SIZE(acp3x_mc_1015_controls),
437 };
438 
439 static const struct snd_soc_dapm_widget acp3x_1015p_widgets[] = {
440 	SND_SOC_DAPM_HP("Headphone Jack", NULL),
441 	SND_SOC_DAPM_MIC("Headset Mic", NULL),
442 	SND_SOC_DAPM_MUX("Dmic Mux", SND_SOC_NOPM, 0, 0,
443 			 &acp3x_dmic_mux_control),
444 	SND_SOC_DAPM_SPK("Speakers", NULL),
445 };
446 
447 static const struct snd_soc_dapm_route acp3x_1015p_route[] = {
448 	{"Headphone Jack", NULL, "HPOL"},
449 	{"Headphone Jack", NULL, "HPOR"},
450 	{"IN1P", NULL, "Headset Mic"},
451 	{"Dmic Mux", "Front Mic", "DMIC"},
452 	{"Dmic Mux", "Rear Mic", "DMIC"},
453 	/* speaker */
454 	{ "Speakers", NULL, "Speaker" },
455 };
456 
457 static const struct snd_kcontrol_new acp3x_mc_1015p_controls[] = {
458 	SOC_DAPM_PIN_SWITCH("Speakers"),
459 	SOC_DAPM_PIN_SWITCH("Headphone Jack"),
460 	SOC_DAPM_PIN_SWITCH("Headset Mic"),
461 };
462 
463 static struct snd_soc_card acp3x_1015p = {
464 	.name = "acp3xalc56821015p",
465 	.owner = THIS_MODULE,
466 	.dai_link = acp3x_dai,
467 	.num_links = ARRAY_SIZE(acp3x_dai),
468 	.dapm_widgets = acp3x_1015p_widgets,
469 	.num_dapm_widgets = ARRAY_SIZE(acp3x_1015p_widgets),
470 	.dapm_routes = acp3x_1015p_route,
471 	.num_dapm_routes = ARRAY_SIZE(acp3x_1015p_route),
472 	.controls = acp3x_mc_1015p_controls,
473 	.num_controls = ARRAY_SIZE(acp3x_mc_1015p_controls),
474 };
475 
soc_is_rltk_max(struct device * dev)476 void *soc_is_rltk_max(struct device *dev)
477 {
478 	const struct acpi_device_id *match;
479 
480 	match = acpi_match_device(dev->driver->acpi_match_table, dev);
481 	if (!match)
482 		return NULL;
483 	return (void *)match->driver_data;
484 }
485 
card_spk_dai_link_present(struct snd_soc_dai_link * links,const char * card_name)486 static void card_spk_dai_link_present(struct snd_soc_dai_link *links,
487 						const char *card_name)
488 {
489 	if (!strcmp(card_name, "acp3xalc56821015")) {
490 		links[1].codecs = rt1015;
491 		links[1].num_codecs = ARRAY_SIZE(rt1015);
492 	} else if (!strcmp(card_name, "acp3xalc56821015p")) {
493 		links[1].codecs = rt1015p;
494 		links[1].num_codecs = ARRAY_SIZE(rt1015p);
495 	} else {
496 		links[1].codecs = max;
497 		links[1].num_codecs = ARRAY_SIZE(max);
498 	}
499 }
500 
acp3x_probe(struct platform_device * pdev)501 static int acp3x_probe(struct platform_device *pdev)
502 {
503 	int ret;
504 	struct snd_soc_card *card;
505 	struct acp3x_platform_info *machine;
506 	struct device *dev = &pdev->dev;
507 
508 	card = (struct snd_soc_card *)soc_is_rltk_max(dev);
509 	if (!card)
510 		return -ENODEV;
511 
512 	machine = devm_kzalloc(&pdev->dev, sizeof(*machine), GFP_KERNEL);
513 	if (!machine)
514 		return -ENOMEM;
515 
516 	card_spk_dai_link_present(card->dai_link, card->name);
517 	card->dev = &pdev->dev;
518 	platform_set_drvdata(pdev, card);
519 	snd_soc_card_set_drvdata(card, machine);
520 
521 	dmic_sel = devm_gpiod_get(&pdev->dev, "dmic", GPIOD_OUT_LOW);
522 	if (IS_ERR(dmic_sel)) {
523 		dev_err(&pdev->dev, "DMIC gpio failed err=%ld\n",
524 			PTR_ERR(dmic_sel));
525 		return PTR_ERR(dmic_sel);
526 	}
527 
528 	ret = devm_snd_soc_register_card(&pdev->dev, card);
529 	if (ret) {
530 		return dev_err_probe(&pdev->dev, ret,
531 				"devm_snd_soc_register_card(%s) failed\n",
532 				card->name);
533 	}
534 	return 0;
535 }
536 
537 static const struct acpi_device_id acp3x_audio_acpi_match[] = {
538 	{ "AMDI5682", (unsigned long)&acp3x_5682},
539 	{ "AMDI1015", (unsigned long)&acp3x_1015},
540 	{ "10021015", (unsigned long)&acp3x_1015p},
541 	{},
542 };
543 MODULE_DEVICE_TABLE(acpi, acp3x_audio_acpi_match);
544 
545 static struct platform_driver acp3x_audio = {
546 	.driver = {
547 		.name = "acp3x-alc5682-max98357",
548 		.acpi_match_table = ACPI_PTR(acp3x_audio_acpi_match),
549 		.pm = &snd_soc_pm_ops,
550 	},
551 	.probe = acp3x_probe,
552 };
553 
554 module_platform_driver(acp3x_audio);
555 
556 MODULE_AUTHOR("akshu.agrawal@amd.com");
557 MODULE_AUTHOR("Vishnuvardhanrao.Ravulapati@amd.com");
558 MODULE_AUTHOR("Vijendar.Mukunda@amd.com");
559 MODULE_DESCRIPTION("ALC5682 ALC1015, ALC1015P & MAX98357 audio support");
560 MODULE_LICENSE("GPL v2");
561