xref: /linux/sound/soc/intel/boards/sof_nau8825.c (revision 44267e97d0d8899deb8f0db1924b3461f88a2029)
1 // SPDX-License-Identifier: GPL-2.0-only
2 // Copyright(c) 2021 Intel Corporation.
3 // Copyright(c) 2021 Nuvoton Corporation.
4 
5 /*
6  * Intel SOF Machine Driver with Nuvoton headphone codec NAU8825
7  * and speaker codec RT1019P MAX98360a or MAX98373
8  */
9 #include <linux/i2c.h>
10 #include <linux/input.h>
11 #include <linux/module.h>
12 #include <linux/platform_device.h>
13 #include <linux/dmi.h>
14 #include <sound/core.h>
15 #include <sound/jack.h>
16 #include <sound/pcm.h>
17 #include <sound/pcm_params.h>
18 #include <sound/soc.h>
19 #include <sound/sof.h>
20 #include <sound/soc-acpi.h>
21 #include "../../codecs/nau8825.h"
22 #include "../common/soc-intel-quirks.h"
23 #include "hda_dsp_common.h"
24 #include "sof_realtek_common.h"
25 #include "sof_hdmi_common.h"
26 #include "sof_maxim_common.h"
27 #include "sof_nuvoton_common.h"
28 #include "sof_ssp_common.h"
29 
30 #define SOF_NAU8825_SSP_CODEC(quirk)		((quirk) & GENMASK(2, 0))
31 #define SOF_NAU8825_SSP_CODEC_MASK		(GENMASK(2, 0))
32 #define SOF_NAU8825_SSP_AMP_SHIFT		4
33 #define SOF_NAU8825_SSP_AMP_MASK		(GENMASK(6, 4))
34 #define SOF_NAU8825_SSP_AMP(quirk)	\
35 	(((quirk) << SOF_NAU8825_SSP_AMP_SHIFT) & SOF_NAU8825_SSP_AMP_MASK)
36 #define SOF_NAU8825_NUM_HDMIDEV_SHIFT		7
37 #define SOF_NAU8825_NUM_HDMIDEV_MASK		(GENMASK(9, 7))
38 #define SOF_NAU8825_NUM_HDMIDEV(quirk)	\
39 	(((quirk) << SOF_NAU8825_NUM_HDMIDEV_SHIFT) & SOF_NAU8825_NUM_HDMIDEV_MASK)
40 
41 /* BT audio offload: reserve 3 bits for future */
42 #define SOF_BT_OFFLOAD_SSP_SHIFT		10
43 #define SOF_BT_OFFLOAD_SSP_MASK		(GENMASK(12, 10))
44 #define SOF_BT_OFFLOAD_SSP(quirk)	\
45 	(((quirk) << SOF_BT_OFFLOAD_SSP_SHIFT) & SOF_BT_OFFLOAD_SSP_MASK)
46 #define SOF_SSP_BT_OFFLOAD_PRESENT		BIT(13)
47 
48 static unsigned long sof_nau8825_quirk = SOF_NAU8825_SSP_CODEC(0);
49 
50 struct sof_card_private {
51 	struct clk *mclk;
52 	struct snd_soc_jack sof_headset;
53 	struct sof_hdmi_private hdmi;
54 	enum sof_ssp_codec codec_type;
55 	enum sof_ssp_codec amp_type;
56 };
57 
58 static int sof_hdmi_init(struct snd_soc_pcm_runtime *rtd)
59 {
60 	struct sof_card_private *ctx = snd_soc_card_get_drvdata(rtd->card);
61 	struct snd_soc_dai *dai = snd_soc_rtd_to_codec(rtd, 0);
62 
63 	ctx->hdmi.hdmi_comp = dai->component;
64 
65 	return 0;
66 }
67 
68 static struct snd_soc_jack_pin jack_pins[] = {
69 	{
70 		.pin    = "Headphone Jack",
71 		.mask   = SND_JACK_HEADPHONE,
72 	},
73 	{
74 		.pin    = "Headset Mic",
75 		.mask   = SND_JACK_MICROPHONE,
76 	},
77 };
78 
79 static int sof_nau8825_codec_init(struct snd_soc_pcm_runtime *rtd)
80 {
81 	struct sof_card_private *ctx = snd_soc_card_get_drvdata(rtd->card);
82 	struct snd_soc_component *component = snd_soc_rtd_to_codec(rtd, 0)->component;
83 
84 	struct snd_soc_jack *jack;
85 	int ret;
86 
87 	/*
88 	 * Headset buttons map to the google Reference headset.
89 	 * These can be configured by userspace.
90 	 */
91 	ret = snd_soc_card_jack_new_pins(rtd->card, "Headset Jack",
92 					 SND_JACK_HEADSET | SND_JACK_BTN_0 |
93 					 SND_JACK_BTN_1 | SND_JACK_BTN_2 |
94 					 SND_JACK_BTN_3,
95 					 &ctx->sof_headset,
96 					 jack_pins,
97 					 ARRAY_SIZE(jack_pins));
98 	if (ret) {
99 		dev_err(rtd->dev, "Headset Jack creation failed: %d\n", ret);
100 		return ret;
101 	}
102 
103 	jack = &ctx->sof_headset;
104 
105 	snd_jack_set_key(jack->jack, SND_JACK_BTN_0, KEY_PLAYPAUSE);
106 	snd_jack_set_key(jack->jack, SND_JACK_BTN_1, KEY_VOICECOMMAND);
107 	snd_jack_set_key(jack->jack, SND_JACK_BTN_2, KEY_VOLUMEUP);
108 	snd_jack_set_key(jack->jack, SND_JACK_BTN_3, KEY_VOLUMEDOWN);
109 	ret = snd_soc_component_set_jack(component, jack, NULL);
110 
111 	if (ret) {
112 		dev_err(rtd->dev, "Headset Jack call-back failed: %d\n", ret);
113 		return ret;
114 	}
115 
116 	return ret;
117 };
118 
119 static void sof_nau8825_codec_exit(struct snd_soc_pcm_runtime *rtd)
120 {
121 	struct snd_soc_component *component = snd_soc_rtd_to_codec(rtd, 0)->component;
122 
123 	snd_soc_component_set_jack(component, NULL, NULL);
124 }
125 
126 static int sof_nau8825_hw_params(struct snd_pcm_substream *substream,
127 				 struct snd_pcm_hw_params *params)
128 {
129 	struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream);
130 	struct snd_soc_dai *codec_dai = snd_soc_rtd_to_codec(rtd, 0);
131 	int clk_freq, ret;
132 
133 	clk_freq = sof_dai_get_bclk(rtd); /* BCLK freq */
134 
135 	if (clk_freq <= 0) {
136 		dev_err(rtd->dev, "get bclk freq failed: %d\n", clk_freq);
137 		return -EINVAL;
138 	}
139 
140 	/* Configure clock for codec */
141 	ret = snd_soc_dai_set_sysclk(codec_dai, NAU8825_CLK_FLL_BLK, 0,
142 				     SND_SOC_CLOCK_IN);
143 	if (ret < 0) {
144 		dev_err(codec_dai->dev, "can't set BCLK clock %d\n", ret);
145 		return ret;
146 	}
147 
148 	/* Configure pll for codec */
149 	ret = snd_soc_dai_set_pll(codec_dai, 0, 0, clk_freq,
150 				  params_rate(params) * 256);
151 	if (ret < 0) {
152 		dev_err(codec_dai->dev, "can't set BCLK: %d\n", ret);
153 		return ret;
154 	}
155 
156 	return ret;
157 }
158 
159 static struct snd_soc_ops sof_nau8825_ops = {
160 	.hw_params = sof_nau8825_hw_params,
161 };
162 
163 static struct snd_soc_dai_link_component platform_component[] = {
164 	{
165 		/* name might be overridden during probe */
166 		.name = "0000:00:1f.3"
167 	}
168 };
169 
170 static int sof_card_late_probe(struct snd_soc_card *card)
171 {
172 	struct sof_card_private *ctx = snd_soc_card_get_drvdata(card);
173 	struct snd_soc_dapm_context *dapm = &card->dapm;
174 	int err;
175 
176 	if (ctx->amp_type == CODEC_MAX98373) {
177 		/* Disable Left and Right Spk pin after boot */
178 		snd_soc_dapm_disable_pin(dapm, "Left Spk");
179 		snd_soc_dapm_disable_pin(dapm, "Right Spk");
180 		err = snd_soc_dapm_sync(dapm);
181 		if (err < 0)
182 			return err;
183 	}
184 
185 	if (!ctx->hdmi.idisp_codec)
186 		return 0;
187 
188 	if (!ctx->hdmi.hdmi_comp)
189 		return -EINVAL;
190 
191 	return hda_dsp_hdmi_build_controls(card, ctx->hdmi.hdmi_comp);
192 }
193 
194 static const struct snd_kcontrol_new sof_controls[] = {
195 	SOC_DAPM_PIN_SWITCH("Headphone Jack"),
196 	SOC_DAPM_PIN_SWITCH("Headset Mic"),
197 	SOC_DAPM_PIN_SWITCH("Left Spk"),
198 	SOC_DAPM_PIN_SWITCH("Right Spk"),
199 };
200 
201 static const struct snd_soc_dapm_widget sof_widgets[] = {
202 	SND_SOC_DAPM_HP("Headphone Jack", NULL),
203 	SND_SOC_DAPM_MIC("Headset Mic", NULL),
204 	SND_SOC_DAPM_SPK("Left Spk", NULL),
205 	SND_SOC_DAPM_SPK("Right Spk", NULL),
206 };
207 
208 static const struct snd_soc_dapm_widget dmic_widgets[] = {
209 	SND_SOC_DAPM_MIC("SoC DMIC", NULL),
210 };
211 
212 static const struct snd_soc_dapm_route sof_map[] = {
213 	/* HP jack connectors - unknown if we have jack detection */
214 	{ "Headphone Jack", NULL, "HPOL" },
215 	{ "Headphone Jack", NULL, "HPOR" },
216 
217 	/* other jacks */
218 	{ "MIC", NULL, "Headset Mic" },
219 };
220 
221 static const struct snd_soc_dapm_route dmic_map[] = {
222 	/* digital mics */
223 	{"DMic", NULL, "SoC DMIC"},
224 };
225 
226 static int dmic_init(struct snd_soc_pcm_runtime *rtd)
227 {
228 	struct snd_soc_card *card = rtd->card;
229 	int ret;
230 
231 	ret = snd_soc_dapm_new_controls(&card->dapm, dmic_widgets,
232 					ARRAY_SIZE(dmic_widgets));
233 	if (ret) {
234 		dev_err(card->dev, "DMic widget addition failed: %d\n", ret);
235 		/* Don't need to add routes if widget addition failed */
236 		return ret;
237 	}
238 
239 	ret = snd_soc_dapm_add_routes(&card->dapm, dmic_map,
240 				      ARRAY_SIZE(dmic_map));
241 
242 	if (ret)
243 		dev_err(card->dev, "DMic map addition failed: %d\n", ret);
244 
245 	return ret;
246 }
247 
248 /* sof audio machine driver for nau8825 codec */
249 static struct snd_soc_card sof_audio_card_nau8825 = {
250 	.name = "nau8825", /* the sof- prefix is added by the core */
251 	.owner = THIS_MODULE,
252 	.controls = sof_controls,
253 	.num_controls = ARRAY_SIZE(sof_controls),
254 	.dapm_widgets = sof_widgets,
255 	.num_dapm_widgets = ARRAY_SIZE(sof_widgets),
256 	.dapm_routes = sof_map,
257 	.num_dapm_routes = ARRAY_SIZE(sof_map),
258 	.fully_routed = true,
259 	.late_probe = sof_card_late_probe,
260 };
261 
262 static struct snd_soc_dai_link_component nau8825_component[] = {
263 	{
264 		.name = "i2c-10508825:00",
265 		.dai_name = "nau8825-hifi",
266 	}
267 };
268 
269 static struct snd_soc_dai_link_component dmic_component[] = {
270 	{
271 		.name = "dmic-codec",
272 		.dai_name = "dmic-hifi",
273 	}
274 };
275 
276 static struct snd_soc_dai_link *
277 sof_card_dai_links_create(struct device *dev, enum sof_ssp_codec amp_type,
278 			  int ssp_codec, int ssp_amp, int dmic_be_num,
279 			  int hdmi_num)
280 {
281 	struct snd_soc_dai_link_component *idisp_components;
282 	struct snd_soc_dai_link_component *cpus;
283 	struct snd_soc_dai_link *links;
284 	int i, id = 0;
285 
286 	links = devm_kcalloc(dev, sof_audio_card_nau8825.num_links,
287 			    sizeof(struct snd_soc_dai_link), GFP_KERNEL);
288 	cpus = devm_kcalloc(dev, sof_audio_card_nau8825.num_links,
289 			    sizeof(struct snd_soc_dai_link_component), GFP_KERNEL);
290 	if (!links || !cpus)
291 		goto devm_err;
292 
293 	/* codec SSP */
294 	links[id].name = devm_kasprintf(dev, GFP_KERNEL,
295 					"SSP%d-Codec", ssp_codec);
296 	if (!links[id].name)
297 		goto devm_err;
298 
299 	links[id].id = id;
300 	links[id].codecs = nau8825_component;
301 	links[id].num_codecs = ARRAY_SIZE(nau8825_component);
302 	links[id].platforms = platform_component;
303 	links[id].num_platforms = ARRAY_SIZE(platform_component);
304 	links[id].init = sof_nau8825_codec_init;
305 	links[id].exit = sof_nau8825_codec_exit;
306 	links[id].ops = &sof_nau8825_ops;
307 	links[id].dpcm_playback = 1;
308 	links[id].dpcm_capture = 1;
309 	links[id].no_pcm = 1;
310 	links[id].cpus = &cpus[id];
311 	links[id].num_cpus = 1;
312 
313 	links[id].cpus->dai_name = devm_kasprintf(dev, GFP_KERNEL,
314 						  "SSP%d Pin",
315 						  ssp_codec);
316 	if (!links[id].cpus->dai_name)
317 		goto devm_err;
318 
319 	id++;
320 
321 	/* dmic */
322 	if (dmic_be_num > 0) {
323 		/* at least we have dmic01 */
324 		links[id].name = "dmic01";
325 		links[id].cpus = &cpus[id];
326 		links[id].cpus->dai_name = "DMIC01 Pin";
327 		links[id].init = dmic_init;
328 		if (dmic_be_num > 1) {
329 			/* set up 2 BE links at most */
330 			links[id + 1].name = "dmic16k";
331 			links[id + 1].cpus = &cpus[id + 1];
332 			links[id + 1].cpus->dai_name = "DMIC16k Pin";
333 			dmic_be_num = 2;
334 		}
335 	}
336 
337 	for (i = 0; i < dmic_be_num; i++) {
338 		links[id].id = id;
339 		links[id].num_cpus = 1;
340 		links[id].codecs = dmic_component;
341 		links[id].num_codecs = ARRAY_SIZE(dmic_component);
342 		links[id].platforms = platform_component;
343 		links[id].num_platforms = ARRAY_SIZE(platform_component);
344 		links[id].ignore_suspend = 1;
345 		links[id].dpcm_capture = 1;
346 		links[id].no_pcm = 1;
347 		id++;
348 	}
349 
350 	/* HDMI */
351 	if (hdmi_num > 0) {
352 		idisp_components = devm_kcalloc(dev,
353 						hdmi_num,
354 						sizeof(struct snd_soc_dai_link_component),
355 						GFP_KERNEL);
356 		if (!idisp_components)
357 			goto devm_err;
358 	}
359 	for (i = 1; i <= hdmi_num; i++) {
360 		links[id].name = devm_kasprintf(dev, GFP_KERNEL,
361 						"iDisp%d", i);
362 		if (!links[id].name)
363 			goto devm_err;
364 
365 		links[id].id = id;
366 		links[id].cpus = &cpus[id];
367 		links[id].num_cpus = 1;
368 		links[id].cpus->dai_name = devm_kasprintf(dev, GFP_KERNEL,
369 							  "iDisp%d Pin", i);
370 		if (!links[id].cpus->dai_name)
371 			goto devm_err;
372 
373 		idisp_components[i - 1].name = "ehdaudio0D2";
374 		idisp_components[i - 1].dai_name = devm_kasprintf(dev,
375 								  GFP_KERNEL,
376 								  "intel-hdmi-hifi%d",
377 								  i);
378 		if (!idisp_components[i - 1].dai_name)
379 			goto devm_err;
380 
381 		links[id].codecs = &idisp_components[i - 1];
382 		links[id].num_codecs = 1;
383 		links[id].platforms = platform_component;
384 		links[id].num_platforms = ARRAY_SIZE(platform_component);
385 		links[id].init = (i == 1) ? sof_hdmi_init : NULL;
386 		links[id].dpcm_playback = 1;
387 		links[id].no_pcm = 1;
388 		id++;
389 	}
390 
391 	/* speaker amp */
392 	if (amp_type != CODEC_NONE) {
393 		links[id].name = devm_kasprintf(dev, GFP_KERNEL,
394 						"SSP%d-Codec", ssp_amp);
395 		if (!links[id].name)
396 			goto devm_err;
397 
398 		links[id].id = id;
399 
400 		switch (amp_type) {
401 		case CODEC_MAX98360A:
402 			max_98360a_dai_link(&links[id]);
403 			break;
404 		case CODEC_MAX98373:
405 			links[id].codecs = max_98373_components;
406 			links[id].num_codecs = ARRAY_SIZE(max_98373_components);
407 			links[id].init = max_98373_spk_codec_init;
408 			links[id].ops = &max_98373_ops;
409 			break;
410 		case CODEC_NAU8318:
411 			nau8318_set_dai_link(&links[id]);
412 			break;
413 		case CODEC_RT1015P:
414 			sof_rt1015p_dai_link(&links[id]);
415 			break;
416 		case CODEC_RT1019P:
417 			sof_rt1019p_dai_link(&links[id]);
418 			break;
419 		default:
420 			dev_err(dev, "invalid amp type %d\n", amp_type);
421 			return NULL;
422 		}
423 
424 		links[id].platforms = platform_component;
425 		links[id].num_platforms = ARRAY_SIZE(platform_component);
426 		links[id].dpcm_playback = 1;
427 		/* feedback stream or firmware-generated echo reference */
428 		links[id].dpcm_capture = 1;
429 
430 		links[id].no_pcm = 1;
431 		links[id].cpus = &cpus[id];
432 		links[id].num_cpus = 1;
433 		links[id].cpus->dai_name = devm_kasprintf(dev, GFP_KERNEL,
434 							  "SSP%d Pin",
435 							  ssp_amp);
436 		if (!links[id].cpus->dai_name)
437 			goto devm_err;
438 		id++;
439 	}
440 
441 	/* BT audio offload */
442 	if (sof_nau8825_quirk & SOF_SSP_BT_OFFLOAD_PRESENT) {
443 		int port = (sof_nau8825_quirk & SOF_BT_OFFLOAD_SSP_MASK) >>
444 				SOF_BT_OFFLOAD_SSP_SHIFT;
445 
446 		links[id].id = id;
447 		links[id].cpus = &cpus[id];
448 		links[id].cpus->dai_name = devm_kasprintf(dev, GFP_KERNEL,
449 							  "SSP%d Pin", port);
450 		if (!links[id].cpus->dai_name)
451 			goto devm_err;
452 		links[id].name = devm_kasprintf(dev, GFP_KERNEL, "SSP%d-BT", port);
453 		if (!links[id].name)
454 			goto devm_err;
455 		links[id].codecs = &snd_soc_dummy_dlc;
456 		links[id].num_codecs = 1;
457 		links[id].platforms = platform_component;
458 		links[id].num_platforms = ARRAY_SIZE(platform_component);
459 		links[id].dpcm_playback = 1;
460 		links[id].dpcm_capture = 1;
461 		links[id].no_pcm = 1;
462 		links[id].num_cpus = 1;
463 	}
464 
465 	return links;
466 devm_err:
467 	return NULL;
468 }
469 
470 static int sof_audio_probe(struct platform_device *pdev)
471 {
472 	struct snd_soc_acpi_mach *mach = pdev->dev.platform_data;
473 	struct snd_soc_dai_link *dai_links;
474 	struct sof_card_private *ctx;
475 	int dmic_be_num, hdmi_num;
476 	int ret, ssp_amp, ssp_codec;
477 
478 	ctx = devm_kzalloc(&pdev->dev, sizeof(*ctx), GFP_KERNEL);
479 	if (!ctx)
480 		return -ENOMEM;
481 
482 	if (pdev->id_entry && pdev->id_entry->driver_data)
483 		sof_nau8825_quirk = (unsigned long)pdev->id_entry->driver_data;
484 
485 	ctx->codec_type = sof_ssp_detect_codec_type(&pdev->dev);
486 	ctx->amp_type = sof_ssp_detect_amp_type(&pdev->dev);
487 
488 	dev_dbg(&pdev->dev, "sof_nau8825_quirk = %lx\n", sof_nau8825_quirk);
489 
490 	/* default number of DMIC DAI's */
491 	dmic_be_num = 2;
492 	hdmi_num = (sof_nau8825_quirk & SOF_NAU8825_NUM_HDMIDEV_MASK) >>
493 			SOF_NAU8825_NUM_HDMIDEV_SHIFT;
494 	/* default number of HDMI DAI's */
495 	if (!hdmi_num)
496 		hdmi_num = 3;
497 
498 	if (mach->mach_params.codec_mask & IDISP_CODEC_MASK)
499 		ctx->hdmi.idisp_codec = true;
500 
501 	ssp_amp = (sof_nau8825_quirk & SOF_NAU8825_SSP_AMP_MASK) >>
502 			SOF_NAU8825_SSP_AMP_SHIFT;
503 
504 	ssp_codec = sof_nau8825_quirk & SOF_NAU8825_SSP_CODEC_MASK;
505 
506 	/* compute number of dai links */
507 	sof_audio_card_nau8825.num_links = 1 + dmic_be_num + hdmi_num;
508 
509 	if (ctx->amp_type != CODEC_NONE)
510 		sof_audio_card_nau8825.num_links++;
511 
512 	if (sof_nau8825_quirk & SOF_SSP_BT_OFFLOAD_PRESENT)
513 		sof_audio_card_nau8825.num_links++;
514 
515 	dai_links = sof_card_dai_links_create(&pdev->dev, ctx->amp_type,
516 					      ssp_codec, ssp_amp, dmic_be_num,
517 					      hdmi_num);
518 	if (!dai_links)
519 		return -ENOMEM;
520 
521 	sof_audio_card_nau8825.dai_link = dai_links;
522 
523 	/* update codec_conf */
524 	switch (ctx->amp_type) {
525 	case CODEC_MAX98373:
526 		max_98373_set_codec_conf(&sof_audio_card_nau8825);
527 		break;
528 	case CODEC_RT1015P:
529 		sof_rt1015p_codec_conf(&sof_audio_card_nau8825);
530 		break;
531 	case CODEC_NONE:
532 	case CODEC_MAX98360A:
533 	case CODEC_NAU8318:
534 	case CODEC_RT1019P:
535 		/* no codec conf required */
536 		break;
537 	default:
538 		dev_err(&pdev->dev, "invalid amp type %d\n", ctx->amp_type);
539 		return -EINVAL;
540 	}
541 
542 	sof_audio_card_nau8825.dev = &pdev->dev;
543 
544 	/* set platform name for each dailink */
545 	ret = snd_soc_fixup_dai_links_platform_name(&sof_audio_card_nau8825,
546 						    mach->mach_params.platform);
547 	if (ret)
548 		return ret;
549 
550 	snd_soc_card_set_drvdata(&sof_audio_card_nau8825, ctx);
551 
552 	return devm_snd_soc_register_card(&pdev->dev,
553 					  &sof_audio_card_nau8825);
554 }
555 
556 static const struct platform_device_id board_ids[] = {
557 	{
558 		.name = "sof_nau8825",
559 		.driver_data = (kernel_ulong_t)(SOF_NAU8825_SSP_CODEC(0) |
560 					SOF_NAU8825_NUM_HDMIDEV(4) |
561 					SOF_BT_OFFLOAD_SSP(2) |
562 					SOF_SSP_BT_OFFLOAD_PRESENT),
563 
564 	},
565 	{
566 		.name = "adl_rt1019p_8825",
567 		.driver_data = (kernel_ulong_t)(SOF_NAU8825_SSP_CODEC(0) |
568 					SOF_NAU8825_SSP_AMP(2) |
569 					SOF_NAU8825_NUM_HDMIDEV(4)),
570 	},
571 	{
572 		.name = "adl_max98373_8825",
573 		.driver_data = (kernel_ulong_t)(SOF_NAU8825_SSP_CODEC(0) |
574 					SOF_NAU8825_SSP_AMP(1) |
575 					SOF_NAU8825_NUM_HDMIDEV(4) |
576 					SOF_BT_OFFLOAD_SSP(2) |
577 					SOF_SSP_BT_OFFLOAD_PRESENT),
578 	},
579 	{
580 		/* The limitation of length of char array, shorten the name */
581 		.name = "adl_mx98360a_8825",
582 		.driver_data = (kernel_ulong_t)(SOF_NAU8825_SSP_CODEC(0) |
583 					SOF_NAU8825_SSP_AMP(1) |
584 					SOF_NAU8825_NUM_HDMIDEV(4) |
585 					SOF_BT_OFFLOAD_SSP(2) |
586 					SOF_SSP_BT_OFFLOAD_PRESENT),
587 
588 	},
589 	{
590 		.name = "adl_rt1015p_8825",
591 		.driver_data = (kernel_ulong_t)(SOF_NAU8825_SSP_CODEC(0) |
592 					SOF_NAU8825_SSP_AMP(1) |
593 					SOF_NAU8825_NUM_HDMIDEV(4) |
594 					SOF_BT_OFFLOAD_SSP(2) |
595 					SOF_SSP_BT_OFFLOAD_PRESENT),
596 	},
597 	{
598 		.name = "adl_nau8318_8825",
599 		.driver_data = (kernel_ulong_t)(SOF_NAU8825_SSP_CODEC(0) |
600 					SOF_NAU8825_SSP_AMP(1) |
601 					SOF_NAU8825_NUM_HDMIDEV(4) |
602 					SOF_BT_OFFLOAD_SSP(2) |
603 					SOF_SSP_BT_OFFLOAD_PRESENT),
604 	},
605 	{
606 		.name = "rpl_max98373_8825",
607 		.driver_data = (kernel_ulong_t)(SOF_NAU8825_SSP_CODEC(0) |
608 					SOF_NAU8825_SSP_AMP(1) |
609 					SOF_NAU8825_NUM_HDMIDEV(4) |
610 					SOF_BT_OFFLOAD_SSP(2) |
611 					SOF_SSP_BT_OFFLOAD_PRESENT),
612 	},
613 	{
614 		.name = "rpl_nau8318_8825",
615 		.driver_data = (kernel_ulong_t)(SOF_NAU8825_SSP_CODEC(0) |
616 					SOF_NAU8825_SSP_AMP(1) |
617 					SOF_NAU8825_NUM_HDMIDEV(4) |
618 					SOF_BT_OFFLOAD_SSP(2) |
619 					SOF_SSP_BT_OFFLOAD_PRESENT),
620 	},
621 	{ }
622 };
623 MODULE_DEVICE_TABLE(platform, board_ids);
624 
625 static struct platform_driver sof_audio = {
626 	.probe = sof_audio_probe,
627 	.driver = {
628 		.name = "sof_nau8825",
629 		.pm = &snd_soc_pm_ops,
630 	},
631 	.id_table = board_ids,
632 };
633 module_platform_driver(sof_audio)
634 
635 /* Module information */
636 MODULE_DESCRIPTION("SOF Audio Machine driver for NAU8825");
637 MODULE_AUTHOR("David Lin <ctlin0@nuvoton.com>");
638 MODULE_AUTHOR("Mac Chiang <mac.chiang@intel.com>");
639 MODULE_AUTHOR("Brent Lu <brent.lu@intel.com>");
640 MODULE_LICENSE("GPL");
641 MODULE_IMPORT_NS(SND_SOC_INTEL_HDA_DSP_COMMON);
642 MODULE_IMPORT_NS(SND_SOC_INTEL_SOF_MAXIM_COMMON);
643 MODULE_IMPORT_NS(SND_SOC_INTEL_SOF_NUVOTON_COMMON);
644 MODULE_IMPORT_NS(SND_SOC_INTEL_SOF_REALTEK_COMMON);
645 MODULE_IMPORT_NS(SND_SOC_INTEL_SOF_SSP_COMMON);
646