1// SPDX-License-Identifier: GPL-2.0-only
2/*
3 * Intel Broxton-P I2S Machine Driver
4 *
5 * Copyright (C) 2016, Intel Corporation. All rights reserved.
6 *
7 * Modified from:
8 *   Intel Skylake I2S Machine driver
9 */
10
11#include <linux/input.h>
12#include <linux/module.h>
13#include <linux/platform_device.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/soc-acpi.h>
20#include "../../codecs/hdac_hdmi.h"
21#include "../../codecs/da7219.h"
22#include "../common/soc-intel-quirks.h"
23#include "hda_dsp_common.h"
24
25#define BXT_DIALOG_CODEC_DAI	"da7219-hifi"
26#define BXT_MAXIM_CODEC_DAI	"HiFi"
27#define MAX98390_DEV0_NAME	"i2c-MX98390:00"
28#define MAX98390_DEV1_NAME	"i2c-MX98390:01"
29#define DUAL_CHANNEL		2
30#define QUAD_CHANNEL		4
31
32#define SPKAMP_MAX98357A	1
33#define SPKAMP_MAX98390	2
34
35static struct snd_soc_jack broxton_headset;
36static struct snd_soc_jack broxton_hdmi[3];
37
38struct bxt_hdmi_pcm {
39	struct list_head head;
40	struct snd_soc_dai *codec_dai;
41	int device;
42};
43
44struct bxt_card_private {
45	struct list_head hdmi_pcm_list;
46	bool common_hdmi_codec_drv;
47	int spkamp;
48};
49
50enum {
51	BXT_DPCM_AUDIO_PB = 0,
52	BXT_DPCM_AUDIO_CP,
53	BXT_DPCM_AUDIO_HS_PB,
54	BXT_DPCM_AUDIO_REF_CP,
55	BXT_DPCM_AUDIO_DMIC_CP,
56	BXT_DPCM_AUDIO_HDMI1_PB,
57	BXT_DPCM_AUDIO_HDMI2_PB,
58	BXT_DPCM_AUDIO_HDMI3_PB,
59};
60
61static int platform_clock_control(struct snd_soc_dapm_widget *w,
62	struct snd_kcontrol *k, int  event)
63{
64	int ret = 0;
65	struct snd_soc_dapm_context *dapm = w->dapm;
66	struct snd_soc_card *card = dapm->card;
67	struct snd_soc_dai *codec_dai;
68
69	codec_dai = snd_soc_card_get_codec_dai(card, BXT_DIALOG_CODEC_DAI);
70	if (!codec_dai) {
71		dev_err(card->dev, "Codec dai not found; Unable to set/unset codec pll\n");
72		return -EIO;
73	}
74
75	if (SND_SOC_DAPM_EVENT_OFF(event)) {
76		ret = snd_soc_dai_set_pll(codec_dai, 0,
77			DA7219_SYSCLK_MCLK, 0, 0);
78		if (ret)
79			dev_err(card->dev, "failed to stop PLL: %d\n", ret);
80	} else if(SND_SOC_DAPM_EVENT_ON(event)) {
81		ret = snd_soc_dai_set_pll(codec_dai, 0,
82			DA7219_SYSCLK_PLL_SRM, 0, DA7219_PLL_FREQ_OUT_98304);
83		if (ret)
84			dev_err(card->dev, "failed to start PLL: %d\n", ret);
85	}
86
87	return ret;
88}
89
90static const struct snd_kcontrol_new broxton_controls[] = {
91	SOC_DAPM_PIN_SWITCH("Headphone Jack"),
92	SOC_DAPM_PIN_SWITCH("Headset Mic"),
93	SOC_DAPM_PIN_SWITCH("Line Out"),
94};
95
96static const struct snd_kcontrol_new max98357a_controls[] = {
97	SOC_DAPM_PIN_SWITCH("Spk"),
98};
99
100static const struct snd_kcontrol_new max98390_controls[] = {
101	SOC_DAPM_PIN_SWITCH("Left Spk"),
102	SOC_DAPM_PIN_SWITCH("Right Spk"),
103};
104
105static const struct snd_soc_dapm_widget broxton_widgets[] = {
106	SND_SOC_DAPM_HP("Headphone Jack", NULL),
107	SND_SOC_DAPM_MIC("Headset Mic", NULL),
108	SND_SOC_DAPM_LINE("Line Out", NULL),
109	SND_SOC_DAPM_MIC("SoC DMIC", NULL),
110	SND_SOC_DAPM_SPK("HDMI1", NULL),
111	SND_SOC_DAPM_SPK("HDMI2", NULL),
112	SND_SOC_DAPM_SPK("HDMI3", NULL),
113	SND_SOC_DAPM_SUPPLY("Platform Clock", SND_SOC_NOPM, 0, 0,
114			platform_clock_control,	SND_SOC_DAPM_POST_PMD|SND_SOC_DAPM_PRE_PMU),
115};
116
117static const struct snd_soc_dapm_widget max98357a_widgets[] = {
118	SND_SOC_DAPM_SPK("Spk", NULL),
119};
120
121static const struct snd_soc_dapm_widget max98390_widgets[] = {
122	SND_SOC_DAPM_SPK("Left Spk", NULL),
123	SND_SOC_DAPM_SPK("Right Spk", NULL),
124};
125
126static const struct snd_soc_dapm_route audio_map[] = {
127	/* HP jack connectors - unknown if we have jack detection */
128	{"Headphone Jack", NULL, "HPL"},
129	{"Headphone Jack", NULL, "HPR"},
130
131	/* other jacks */
132	{"MIC", NULL, "Headset Mic"},
133
134	/* digital mics */
135	{"DMic", NULL, "SoC DMIC"},
136
137	/* CODEC BE connections */
138	{"HDMI1", NULL, "hif5-0 Output"},
139	{"HDMI2", NULL, "hif6-0 Output"},
140	{"HDMI2", NULL, "hif7-0 Output"},
141
142	{"hifi3", NULL, "iDisp3 Tx"},
143	{"iDisp3 Tx", NULL, "iDisp3_out"},
144	{"hifi2", NULL, "iDisp2 Tx"},
145	{"iDisp2 Tx", NULL, "iDisp2_out"},
146	{"hifi1", NULL, "iDisp1 Tx"},
147	{"iDisp1 Tx", NULL, "iDisp1_out"},
148
149	/* DMIC */
150	{"dmic01_hifi", NULL, "DMIC01 Rx"},
151	{"DMIC01 Rx", NULL, "DMIC AIF"},
152
153	{ "Headphone Jack", NULL, "Platform Clock" },
154	{ "Headset Mic", NULL, "Platform Clock" },
155	{ "Line Out", NULL, "Platform Clock" },
156};
157
158static const struct snd_soc_dapm_route max98357a_routes[] = {
159	/* speaker */
160	{"Spk", NULL, "Speaker"},
161};
162
163static const struct snd_soc_dapm_route max98390_routes[] = {
164	/* Speaker */
165	{"Left Spk", NULL, "Left BE_OUT"},
166	{"Right Spk", NULL, "Right BE_OUT"},
167};
168
169static const struct snd_soc_dapm_route broxton_map[] = {
170	{"HiFi Playback", NULL, "ssp5 Tx"},
171	{"ssp5 Tx", NULL, "codec0_out"},
172
173	{"Playback", NULL, "ssp1 Tx"},
174	{"ssp1 Tx", NULL, "codec1_out"},
175
176	{"codec0_in", NULL, "ssp1 Rx"},
177	{"ssp1 Rx", NULL, "Capture"},
178};
179
180static const struct snd_soc_dapm_route gemini_map[] = {
181	{"HiFi Playback", NULL, "ssp1 Tx"},
182	{"ssp1 Tx", NULL, "codec0_out"},
183
184	{"Playback", NULL, "ssp2 Tx"},
185	{"ssp2 Tx", NULL, "codec1_out"},
186
187	{"codec0_in", NULL, "ssp2 Rx"},
188	{"ssp2 Rx", NULL, "Capture"},
189};
190
191static struct snd_soc_jack_pin jack_pins[] = {
192	{
193		.pin    = "Headphone Jack",
194		.mask   = SND_JACK_HEADPHONE,
195	},
196	{
197		.pin    = "Headset Mic",
198		.mask   = SND_JACK_MICROPHONE,
199	},
200	{
201		.pin    = "Line Out",
202		.mask   = SND_JACK_LINEOUT,
203	},
204};
205
206static int broxton_ssp_fixup(struct snd_soc_pcm_runtime *rtd,
207			struct snd_pcm_hw_params *params)
208{
209	struct snd_interval *rate = hw_param_interval(params,
210			SNDRV_PCM_HW_PARAM_RATE);
211	struct snd_interval *chan = hw_param_interval(params,
212			SNDRV_PCM_HW_PARAM_CHANNELS);
213	struct snd_mask *fmt = hw_param_mask(params, SNDRV_PCM_HW_PARAM_FORMAT);
214
215	/* The ADSP will convert the FE rate to 48k, stereo */
216	rate->min = rate->max = 48000;
217	chan->min = chan->max = DUAL_CHANNEL;
218
219	/* set SSP to 24 bit */
220	snd_mask_none(fmt);
221	snd_mask_set_format(fmt, SNDRV_PCM_FORMAT_S24_LE);
222
223	return 0;
224}
225
226static int broxton_da7219_codec_init(struct snd_soc_pcm_runtime *rtd)
227{
228	int ret;
229	struct snd_soc_dai *codec_dai = snd_soc_rtd_to_codec(rtd, 0);
230	struct snd_soc_component *component = snd_soc_rtd_to_codec(rtd, 0)->component;
231	int clk_freq;
232
233	/* Configure sysclk for codec */
234	if (soc_intel_is_cml())
235		clk_freq = 24000000;
236	else
237		clk_freq = 19200000;
238
239	ret = snd_soc_dai_set_sysclk(codec_dai, DA7219_CLKSRC_MCLK, clk_freq,
240				     SND_SOC_CLOCK_IN);
241
242	if (ret) {
243		dev_err(rtd->dev, "can't set codec sysclk configuration\n");
244		return ret;
245	}
246
247	/*
248	 * Headset buttons map to the google Reference headset.
249	 * These can be configured by userspace.
250	 */
251	ret = snd_soc_card_jack_new_pins(rtd->card, "Headset Jack",
252					 SND_JACK_HEADSET | SND_JACK_BTN_0 | SND_JACK_BTN_1 |
253					 SND_JACK_BTN_2 | SND_JACK_BTN_3 | SND_JACK_LINEOUT,
254					 &broxton_headset,
255					 jack_pins,
256					 ARRAY_SIZE(jack_pins));
257	if (ret) {
258		dev_err(rtd->dev, "Headset Jack creation failed: %d\n", ret);
259		return ret;
260	}
261
262	snd_jack_set_key(broxton_headset.jack, SND_JACK_BTN_0, KEY_PLAYPAUSE);
263	snd_jack_set_key(broxton_headset.jack, SND_JACK_BTN_1, KEY_VOLUMEUP);
264	snd_jack_set_key(broxton_headset.jack, SND_JACK_BTN_2, KEY_VOLUMEDOWN);
265	snd_jack_set_key(broxton_headset.jack, SND_JACK_BTN_3,
266			 KEY_VOICECOMMAND);
267
268	snd_soc_component_set_jack(component, &broxton_headset, NULL);
269
270	snd_soc_dapm_ignore_suspend(&rtd->card->dapm, "SoC DMIC");
271
272	return ret;
273}
274
275static int broxton_hdmi_init(struct snd_soc_pcm_runtime *rtd)
276{
277	struct bxt_card_private *ctx = snd_soc_card_get_drvdata(rtd->card);
278	struct snd_soc_dai *dai = snd_soc_rtd_to_codec(rtd, 0);
279	struct bxt_hdmi_pcm *pcm;
280
281	pcm = devm_kzalloc(rtd->card->dev, sizeof(*pcm), GFP_KERNEL);
282	if (!pcm)
283		return -ENOMEM;
284
285	pcm->device = BXT_DPCM_AUDIO_HDMI1_PB + dai->id;
286	pcm->codec_dai = dai;
287
288	list_add_tail(&pcm->head, &ctx->hdmi_pcm_list);
289
290	return 0;
291}
292
293static int broxton_da7219_fe_init(struct snd_soc_pcm_runtime *rtd)
294{
295	struct snd_soc_dapm_context *dapm;
296	struct snd_soc_component *component = snd_soc_rtd_to_cpu(rtd, 0)->component;
297
298	dapm = snd_soc_component_get_dapm(component);
299	snd_soc_dapm_ignore_suspend(dapm, "Reference Capture");
300
301	return 0;
302}
303
304static const unsigned int rates[] = {
305	48000,
306};
307
308static const struct snd_pcm_hw_constraint_list constraints_rates = {
309	.count = ARRAY_SIZE(rates),
310	.list  = rates,
311	.mask = 0,
312};
313
314static const unsigned int channels[] = {
315	DUAL_CHANNEL,
316};
317
318static const struct snd_pcm_hw_constraint_list constraints_channels = {
319	.count = ARRAY_SIZE(channels),
320	.list = channels,
321	.mask = 0,
322};
323
324static const unsigned int channels_quad[] = {
325	QUAD_CHANNEL,
326};
327
328static const struct snd_pcm_hw_constraint_list constraints_channels_quad = {
329	.count = ARRAY_SIZE(channels_quad),
330	.list = channels_quad,
331	.mask = 0,
332};
333
334static int bxt_fe_startup(struct snd_pcm_substream *substream)
335{
336	struct snd_pcm_runtime *runtime = substream->runtime;
337
338	/*
339	 * On this platform for PCM device we support,
340	 * 48Khz
341	 * stereo
342	 * 16 bit audio
343	 */
344
345	runtime->hw.channels_max = DUAL_CHANNEL;
346	snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS,
347					   &constraints_channels);
348
349	runtime->hw.formats = SNDRV_PCM_FMTBIT_S16_LE;
350	snd_pcm_hw_constraint_msbits(runtime, 0, 16, 16);
351
352	snd_pcm_hw_constraint_list(runtime, 0,
353				SNDRV_PCM_HW_PARAM_RATE, &constraints_rates);
354
355	return 0;
356}
357
358static const struct snd_soc_ops broxton_da7219_fe_ops = {
359	.startup = bxt_fe_startup,
360};
361
362static int broxton_dmic_fixup(struct snd_soc_pcm_runtime *rtd,
363			struct snd_pcm_hw_params *params)
364{
365	struct snd_interval *chan = hw_param_interval(params,
366						SNDRV_PCM_HW_PARAM_CHANNELS);
367	if (params_channels(params) == 2)
368		chan->min = chan->max = 2;
369	else
370		chan->min = chan->max = 4;
371
372	return 0;
373}
374
375static int broxton_dmic_startup(struct snd_pcm_substream *substream)
376{
377	struct snd_pcm_runtime *runtime = substream->runtime;
378
379	runtime->hw.channels_min = runtime->hw.channels_max = QUAD_CHANNEL;
380	snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS,
381			&constraints_channels_quad);
382
383	return snd_pcm_hw_constraint_list(substream->runtime, 0,
384			SNDRV_PCM_HW_PARAM_RATE, &constraints_rates);
385}
386
387static const struct snd_soc_ops broxton_dmic_ops = {
388	.startup = broxton_dmic_startup,
389};
390
391static const unsigned int rates_16000[] = {
392	16000,
393};
394
395static const struct snd_pcm_hw_constraint_list constraints_16000 = {
396	.count = ARRAY_SIZE(rates_16000),
397	.list  = rates_16000,
398};
399
400static const unsigned int ch_mono[] = {
401	1,
402};
403
404static const struct snd_pcm_hw_constraint_list constraints_refcap = {
405	.count = ARRAY_SIZE(ch_mono),
406	.list  = ch_mono,
407};
408
409static int broxton_refcap_startup(struct snd_pcm_substream *substream)
410{
411	substream->runtime->hw.channels_max = 1;
412	snd_pcm_hw_constraint_list(substream->runtime, 0,
413				   SNDRV_PCM_HW_PARAM_CHANNELS,
414				   &constraints_refcap);
415
416	return snd_pcm_hw_constraint_list(substream->runtime, 0,
417			SNDRV_PCM_HW_PARAM_RATE,
418			&constraints_16000);
419};
420
421static const struct snd_soc_ops broxton_refcap_ops = {
422	.startup = broxton_refcap_startup,
423};
424
425/* broxton digital audio interface glue - connects codec <--> CPU */
426SND_SOC_DAILINK_DEF(dummy,
427	DAILINK_COMP_ARRAY(COMP_DUMMY()));
428
429SND_SOC_DAILINK_DEF(system,
430	DAILINK_COMP_ARRAY(COMP_CPU("System Pin")));
431
432SND_SOC_DAILINK_DEF(system2,
433	DAILINK_COMP_ARRAY(COMP_CPU("System Pin2")));
434
435SND_SOC_DAILINK_DEF(reference,
436	DAILINK_COMP_ARRAY(COMP_CPU("Reference Pin")));
437
438SND_SOC_DAILINK_DEF(dmic,
439	DAILINK_COMP_ARRAY(COMP_CPU("DMIC Pin")));
440
441SND_SOC_DAILINK_DEF(hdmi1,
442	DAILINK_COMP_ARRAY(COMP_CPU("HDMI1 Pin")));
443
444SND_SOC_DAILINK_DEF(hdmi2,
445	DAILINK_COMP_ARRAY(COMP_CPU("HDMI2 Pin")));
446
447SND_SOC_DAILINK_DEF(hdmi3,
448	DAILINK_COMP_ARRAY(COMP_CPU("HDMI3 Pin")));
449
450 /* Back End DAI */
451SND_SOC_DAILINK_DEF(ssp5_pin,
452	DAILINK_COMP_ARRAY(COMP_CPU("SSP5 Pin")));
453SND_SOC_DAILINK_DEF(ssp5_codec,
454	DAILINK_COMP_ARRAY(COMP_CODEC("MX98357A:00",
455				      BXT_MAXIM_CODEC_DAI)));
456SND_SOC_DAILINK_DEF(max98390_codec,
457	DAILINK_COMP_ARRAY(
458	/* Left */	COMP_CODEC(MAX98390_DEV0_NAME, "max98390-aif1"),
459	/* Right */	COMP_CODEC(MAX98390_DEV1_NAME, "max98390-aif1")));
460
461SND_SOC_DAILINK_DEF(ssp1_pin,
462	DAILINK_COMP_ARRAY(COMP_CPU("SSP1 Pin")));
463SND_SOC_DAILINK_DEF(ssp1_codec,
464	DAILINK_COMP_ARRAY(COMP_CODEC("i2c-DLGS7219:00",
465				      BXT_DIALOG_CODEC_DAI)));
466
467SND_SOC_DAILINK_DEF(dmic_pin,
468	DAILINK_COMP_ARRAY(COMP_CPU("DMIC01 Pin")));
469
470SND_SOC_DAILINK_DEF(dmic16k_pin,
471	DAILINK_COMP_ARRAY(COMP_CPU("DMIC16k Pin")));
472
473SND_SOC_DAILINK_DEF(dmic_codec,
474	DAILINK_COMP_ARRAY(COMP_CODEC("dmic-codec", "dmic-hifi")));
475
476SND_SOC_DAILINK_DEF(idisp1_pin,
477	DAILINK_COMP_ARRAY(COMP_CPU("iDisp1 Pin")));
478SND_SOC_DAILINK_DEF(idisp1_codec,
479	DAILINK_COMP_ARRAY(COMP_CODEC("ehdaudio0D2", "intel-hdmi-hifi1")));
480
481SND_SOC_DAILINK_DEF(idisp2_pin,
482	DAILINK_COMP_ARRAY(COMP_CPU("iDisp2 Pin")));
483SND_SOC_DAILINK_DEF(idisp2_codec,
484	DAILINK_COMP_ARRAY(COMP_CODEC("ehdaudio0D2",
485				      "intel-hdmi-hifi2")));
486
487SND_SOC_DAILINK_DEF(idisp3_pin,
488	DAILINK_COMP_ARRAY(COMP_CPU("iDisp3 Pin")));
489SND_SOC_DAILINK_DEF(idisp3_codec,
490	DAILINK_COMP_ARRAY(COMP_CODEC("ehdaudio0D2",
491				      "intel-hdmi-hifi3")));
492
493SND_SOC_DAILINK_DEF(platform,
494	DAILINK_COMP_ARRAY(COMP_PLATFORM("0000:00:0e.0")));
495
496static struct snd_soc_dai_link broxton_dais[] = {
497	/* Front End DAI links */
498	[BXT_DPCM_AUDIO_PB] =
499	{
500		.name = "Bxt Audio Port",
501		.stream_name = "Audio",
502		.dynamic = 1,
503		.nonatomic = 1,
504		.init = broxton_da7219_fe_init,
505		.trigger = {
506			SND_SOC_DPCM_TRIGGER_POST, SND_SOC_DPCM_TRIGGER_POST},
507		.dpcm_playback = 1,
508		.ops = &broxton_da7219_fe_ops,
509		SND_SOC_DAILINK_REG(system, dummy, platform),
510	},
511	[BXT_DPCM_AUDIO_CP] =
512	{
513		.name = "Bxt Audio Capture Port",
514		.stream_name = "Audio Record",
515		.dynamic = 1,
516		.nonatomic = 1,
517		.trigger = {
518			SND_SOC_DPCM_TRIGGER_POST, SND_SOC_DPCM_TRIGGER_POST},
519		.dpcm_capture = 1,
520		.ops = &broxton_da7219_fe_ops,
521		SND_SOC_DAILINK_REG(system, dummy, platform),
522	},
523	[BXT_DPCM_AUDIO_HS_PB] = {
524		.name = "Bxt Audio Headset Playback",
525		.stream_name = "Headset Playback",
526		.dynamic = 1,
527		.nonatomic = 1,
528		.trigger = {
529			SND_SOC_DPCM_TRIGGER_POST, SND_SOC_DPCM_TRIGGER_POST},
530		.dpcm_playback = 1,
531		.ops = &broxton_da7219_fe_ops,
532		SND_SOC_DAILINK_REG(system2, dummy, platform),
533	},
534	[BXT_DPCM_AUDIO_REF_CP] =
535	{
536		.name = "Bxt Audio Reference cap",
537		.stream_name = "Refcap",
538		.init = NULL,
539		.dpcm_capture = 1,
540		.nonatomic = 1,
541		.dynamic = 1,
542		.ops = &broxton_refcap_ops,
543		SND_SOC_DAILINK_REG(reference, dummy, platform),
544	},
545	[BXT_DPCM_AUDIO_DMIC_CP] =
546	{
547		.name = "Bxt Audio DMIC cap",
548		.stream_name = "dmiccap",
549		.init = NULL,
550		.dpcm_capture = 1,
551		.nonatomic = 1,
552		.dynamic = 1,
553		.ops = &broxton_dmic_ops,
554		SND_SOC_DAILINK_REG(dmic, dummy, platform),
555	},
556	[BXT_DPCM_AUDIO_HDMI1_PB] =
557	{
558		.name = "Bxt HDMI Port1",
559		.stream_name = "Hdmi1",
560		.dpcm_playback = 1,
561		.init = NULL,
562		.nonatomic = 1,
563		.dynamic = 1,
564		SND_SOC_DAILINK_REG(hdmi1, dummy, platform),
565	},
566	[BXT_DPCM_AUDIO_HDMI2_PB] =
567	{
568		.name = "Bxt HDMI Port2",
569		.stream_name = "Hdmi2",
570		.dpcm_playback = 1,
571		.init = NULL,
572		.nonatomic = 1,
573		.dynamic = 1,
574		SND_SOC_DAILINK_REG(hdmi2, dummy, platform),
575	},
576	[BXT_DPCM_AUDIO_HDMI3_PB] =
577	{
578		.name = "Bxt HDMI Port3",
579		.stream_name = "Hdmi3",
580		.dpcm_playback = 1,
581		.init = NULL,
582		.nonatomic = 1,
583		.dynamic = 1,
584		SND_SOC_DAILINK_REG(hdmi3, dummy, platform),
585	},
586	/* Back End DAI links */
587	{
588		/* SSP5 - Codec */
589		.name = "SSP5-Codec",
590		.id = 0,
591		.no_pcm = 1,
592		.dai_fmt = SND_SOC_DAIFMT_I2S |
593			SND_SOC_DAIFMT_NB_NF |
594			SND_SOC_DAIFMT_CBC_CFC,
595		.ignore_pmdown_time = 1,
596		.be_hw_params_fixup = broxton_ssp_fixup,
597		.dpcm_playback = 1,
598		SND_SOC_DAILINK_REG(ssp5_pin, ssp5_codec, platform),
599	},
600	{
601		/* SSP1 - Codec */
602		.name = "SSP1-Codec",
603		.id = 1,
604		.no_pcm = 1,
605		.init = broxton_da7219_codec_init,
606		.dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF |
607			SND_SOC_DAIFMT_CBC_CFC,
608		.ignore_pmdown_time = 1,
609		.be_hw_params_fixup = broxton_ssp_fixup,
610		.dpcm_playback = 1,
611		.dpcm_capture = 1,
612		SND_SOC_DAILINK_REG(ssp1_pin, ssp1_codec, platform),
613	},
614	{
615		.name = "dmic01",
616		.id = 2,
617		.ignore_suspend = 1,
618		.be_hw_params_fixup = broxton_dmic_fixup,
619		.dpcm_capture = 1,
620		.no_pcm = 1,
621		SND_SOC_DAILINK_REG(dmic_pin, dmic_codec, platform),
622	},
623	{
624		.name = "iDisp1",
625		.id = 3,
626		.init = broxton_hdmi_init,
627		.dpcm_playback = 1,
628		.no_pcm = 1,
629		SND_SOC_DAILINK_REG(idisp1_pin, idisp1_codec, platform),
630	},
631	{
632		.name = "iDisp2",
633		.id = 4,
634		.init = broxton_hdmi_init,
635		.dpcm_playback = 1,
636		.no_pcm = 1,
637		SND_SOC_DAILINK_REG(idisp2_pin, idisp2_codec, platform),
638	},
639	{
640		.name = "iDisp3",
641		.id = 5,
642		.init = broxton_hdmi_init,
643		.dpcm_playback = 1,
644		.no_pcm = 1,
645		SND_SOC_DAILINK_REG(idisp3_pin, idisp3_codec, platform),
646	},
647	{
648		.name = "dmic16k",
649		.id = 6,
650		.be_hw_params_fixup = broxton_dmic_fixup,
651		.dpcm_capture = 1,
652		.no_pcm = 1,
653		SND_SOC_DAILINK_REG(dmic16k_pin, dmic_codec, platform),
654	},
655};
656
657static struct snd_soc_codec_conf max98390_codec_confs[] = {
658	{
659		.dlc = COMP_CODEC_CONF(MAX98390_DEV0_NAME),
660		.name_prefix = "Left",
661	},
662	{
663		.dlc = COMP_CODEC_CONF(MAX98390_DEV1_NAME),
664		.name_prefix = "Right",
665	},
666};
667
668#define NAME_SIZE	32
669static int bxt_card_late_probe(struct snd_soc_card *card)
670{
671	struct bxt_card_private *ctx = snd_soc_card_get_drvdata(card);
672	struct bxt_hdmi_pcm *pcm;
673	struct snd_soc_component *component = NULL;
674	const struct snd_kcontrol_new *controls;
675	const struct snd_soc_dapm_widget *widgets;
676	const struct snd_soc_dapm_route *routes;
677	int num_controls, num_widgets, num_routes, err, i = 0;
678	char jack_name[NAME_SIZE];
679
680	switch (ctx->spkamp) {
681	case SPKAMP_MAX98357A:
682		controls = max98357a_controls;
683		num_controls = ARRAY_SIZE(max98357a_controls);
684		widgets = max98357a_widgets;
685		num_widgets = ARRAY_SIZE(max98357a_widgets);
686		routes = max98357a_routes;
687		num_routes = ARRAY_SIZE(max98357a_routes);
688		break;
689	case SPKAMP_MAX98390:
690		controls = max98390_controls;
691		num_controls = ARRAY_SIZE(max98390_controls);
692		widgets = max98390_widgets;
693		num_widgets = ARRAY_SIZE(max98390_widgets);
694		routes = max98390_routes;
695		num_routes = ARRAY_SIZE(max98390_routes);
696		break;
697	default:
698		dev_err(card->dev, "Invalid speaker amplifier %d\n", ctx->spkamp);
699		return -EINVAL;
700	}
701
702	err = snd_soc_dapm_new_controls(&card->dapm, widgets, num_widgets);
703	if (err) {
704		dev_err(card->dev, "Fail to new widgets\n");
705		return err;
706	}
707
708	err = snd_soc_add_card_controls(card, controls, num_controls);
709	if (err) {
710		dev_err(card->dev, "Fail to add controls\n");
711		return err;
712	}
713
714	err = snd_soc_dapm_add_routes(&card->dapm, routes, num_routes);
715	if (err) {
716		dev_err(card->dev, "Fail to add routes\n");
717		return err;
718	}
719
720	if (soc_intel_is_glk())
721		snd_soc_dapm_add_routes(&card->dapm, gemini_map,
722					ARRAY_SIZE(gemini_map));
723	else
724		snd_soc_dapm_add_routes(&card->dapm, broxton_map,
725					ARRAY_SIZE(broxton_map));
726
727	if (list_empty(&ctx->hdmi_pcm_list))
728		return -EINVAL;
729
730	if (ctx->common_hdmi_codec_drv) {
731		pcm = list_first_entry(&ctx->hdmi_pcm_list, struct bxt_hdmi_pcm,
732				       head);
733		component = pcm->codec_dai->component;
734		return hda_dsp_hdmi_build_controls(card, component);
735	}
736
737	list_for_each_entry(pcm, &ctx->hdmi_pcm_list, head) {
738		component = pcm->codec_dai->component;
739		snprintf(jack_name, sizeof(jack_name),
740			"HDMI/DP, pcm=%d Jack", pcm->device);
741		err = snd_soc_card_jack_new(card, jack_name,
742					SND_JACK_AVOUT, &broxton_hdmi[i]);
743
744		if (err)
745			return err;
746
747		err = hdac_hdmi_jack_init(pcm->codec_dai, pcm->device,
748						&broxton_hdmi[i]);
749		if (err < 0)
750			return err;
751
752		i++;
753	}
754
755	return hdac_hdmi_jack_port_init(component, &card->dapm);
756}
757
758/* broxton audio machine driver for SPT + da7219 */
759static struct snd_soc_card broxton_audio_card = {
760	.name = "bxtda7219max",
761	.owner = THIS_MODULE,
762	.dai_link = broxton_dais,
763	.num_links = ARRAY_SIZE(broxton_dais),
764	.controls = broxton_controls,
765	.num_controls = ARRAY_SIZE(broxton_controls),
766	.dapm_widgets = broxton_widgets,
767	.num_dapm_widgets = ARRAY_SIZE(broxton_widgets),
768	.dapm_routes = audio_map,
769	.num_dapm_routes = ARRAY_SIZE(audio_map),
770	.fully_routed = true,
771	.late_probe = bxt_card_late_probe,
772};
773
774static int broxton_audio_probe(struct platform_device *pdev)
775{
776	struct bxt_card_private *ctx;
777	struct snd_soc_acpi_mach *mach;
778	const char *platform_name;
779	int ret;
780
781	ctx = devm_kzalloc(&pdev->dev, sizeof(*ctx), GFP_KERNEL);
782	if (!ctx)
783		return -ENOMEM;
784
785	INIT_LIST_HEAD(&ctx->hdmi_pcm_list);
786
787	if (acpi_dev_present("MX98390", NULL, -1))
788		ctx->spkamp = SPKAMP_MAX98390;
789	else
790		ctx->spkamp = SPKAMP_MAX98357A;
791
792	broxton_audio_card.dev = &pdev->dev;
793	snd_soc_card_set_drvdata(&broxton_audio_card, ctx);
794	if (soc_intel_is_glk()) {
795		unsigned int i;
796
797		broxton_audio_card.name = "glkda7219max";
798		/* Fixup the SSP entries for geminilake */
799		for (i = 0; i < ARRAY_SIZE(broxton_dais); i++) {
800			if (!broxton_dais[i].codecs->dai_name)
801				continue;
802
803			/* MAXIM_CODEC is connected to SSP1. */
804			if (!strcmp(broxton_dais[i].codecs->dai_name,
805				    BXT_MAXIM_CODEC_DAI)) {
806				broxton_dais[i].name = "SSP1-Codec";
807				broxton_dais[i].cpus->dai_name = "SSP1 Pin";
808			}
809			/* DIALOG_CODE is connected to SSP2 */
810			else if (!strcmp(broxton_dais[i].codecs->dai_name,
811					 BXT_DIALOG_CODEC_DAI)) {
812				broxton_dais[i].name = "SSP2-Codec";
813				broxton_dais[i].cpus->dai_name = "SSP2 Pin";
814			}
815		}
816	} else if (soc_intel_is_cml()) {
817		unsigned int i;
818
819		if (ctx->spkamp == SPKAMP_MAX98390) {
820			broxton_audio_card.name = "cml_max98390_da7219";
821
822			broxton_audio_card.codec_conf = max98390_codec_confs;
823			broxton_audio_card.num_configs = ARRAY_SIZE(max98390_codec_confs);
824		} else
825			broxton_audio_card.name = "cmlda7219max";
826
827		for (i = 0; i < ARRAY_SIZE(broxton_dais); i++) {
828			if (!broxton_dais[i].codecs->dai_name)
829				continue;
830
831			/* MAXIM_CODEC is connected to SSP1. */
832			if (!strcmp(broxton_dais[i].codecs->dai_name,
833					BXT_MAXIM_CODEC_DAI)) {
834				broxton_dais[i].name = "SSP1-Codec";
835				broxton_dais[i].cpus->dai_name = "SSP1 Pin";
836
837				if (ctx->spkamp == SPKAMP_MAX98390) {
838					broxton_dais[i].codecs = max98390_codec;
839					broxton_dais[i].num_codecs = ARRAY_SIZE(max98390_codec);
840					broxton_dais[i].dpcm_capture = 1;
841				}
842			}
843			/* DIALOG_CODEC is connected to SSP0 */
844			else if (!strcmp(broxton_dais[i].codecs->dai_name,
845					BXT_DIALOG_CODEC_DAI)) {
846				broxton_dais[i].name = "SSP0-Codec";
847				broxton_dais[i].cpus->dai_name = "SSP0 Pin";
848			}
849		}
850	}
851
852	/* override platform name, if required */
853	mach = pdev->dev.platform_data;
854	platform_name = mach->mach_params.platform;
855
856	ret = snd_soc_fixup_dai_links_platform_name(&broxton_audio_card,
857						    platform_name);
858	if (ret)
859		return ret;
860
861	ctx->common_hdmi_codec_drv = mach->mach_params.common_hdmi_codec_drv;
862
863	return devm_snd_soc_register_card(&pdev->dev, &broxton_audio_card);
864}
865
866static const struct platform_device_id bxt_board_ids[] = {
867	{ .name = "bxt_da7219_mx98357a" },
868	{ .name = "glk_da7219_mx98357a" },
869	{ .name = "cml_da7219_mx98357a" },
870	{ }
871};
872MODULE_DEVICE_TABLE(platform, bxt_board_ids);
873
874static struct platform_driver broxton_audio = {
875	.probe = broxton_audio_probe,
876	.driver = {
877		.name = "bxt_da7219_max98357a",
878		.pm = &snd_soc_pm_ops,
879	},
880	.id_table = bxt_board_ids,
881};
882module_platform_driver(broxton_audio)
883
884/* Module information */
885MODULE_DESCRIPTION("Audio Machine driver-DA7219 & MAX98357A in I2S mode");
886MODULE_AUTHOR("Sathyanarayana Nujella <sathyanarayana.nujella@intel.com>");
887MODULE_AUTHOR("Rohit Ainapure <rohit.m.ainapure@intel.com>");
888MODULE_AUTHOR("Harsha Priya <harshapriya.n@intel.com>");
889MODULE_AUTHOR("Conrad Cooke <conrad.cooke@intel.com>");
890MODULE_AUTHOR("Naveen Manohar <naveen.m@intel.com>");
891MODULE_AUTHOR("Mac Chiang <mac.chiang@intel.com>");
892MODULE_AUTHOR("Brent Lu <brent.lu@intel.com>");
893MODULE_LICENSE("GPL v2");
894MODULE_IMPORT_NS(SND_SOC_INTEL_HDA_DSP_COMMON);
895