cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

bxt_da7219_max98357a.c (23010B)


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