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

mt8183-da7219-max98357.c (23041B)


      1// SPDX-License-Identifier: GPL-2.0
      2//
      3// mt8183-da7219-max98357.c
      4//	--  MT8183-DA7219-MAX98357 ALSA SoC machine driver
      5//
      6// Copyright (c) 2018 MediaTek Inc.
      7// Author: Shunli Wang <shunli.wang@mediatek.com>
      8
      9#include <linux/input.h>
     10#include <linux/module.h>
     11#include <linux/of_device.h>
     12#include <linux/pinctrl/consumer.h>
     13#include <sound/jack.h>
     14#include <sound/pcm_params.h>
     15#include <sound/soc.h>
     16
     17#include "../../codecs/da7219-aad.h"
     18#include "../../codecs/da7219.h"
     19#include "../../codecs/rt1015.h"
     20#include "mt8183-afe-common.h"
     21
     22#define DA7219_CODEC_DAI "da7219-hifi"
     23#define DA7219_DEV_NAME "da7219.5-001a"
     24#define RT1015_CODEC_DAI "rt1015-aif"
     25#define RT1015_DEV0_NAME "rt1015.6-0028"
     26#define RT1015_DEV1_NAME "rt1015.6-0029"
     27
     28struct mt8183_da7219_max98357_priv {
     29	struct snd_soc_jack headset_jack, hdmi_jack;
     30};
     31
     32static int mt8183_mt6358_i2s_hw_params(struct snd_pcm_substream *substream,
     33				       struct snd_pcm_hw_params *params)
     34{
     35	struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
     36	unsigned int rate = params_rate(params);
     37	unsigned int mclk_fs_ratio = 128;
     38	unsigned int mclk_fs = rate * mclk_fs_ratio;
     39
     40	return snd_soc_dai_set_sysclk(asoc_rtd_to_cpu(rtd, 0),
     41				      0, mclk_fs, SND_SOC_CLOCK_OUT);
     42}
     43
     44static const struct snd_soc_ops mt8183_mt6358_i2s_ops = {
     45	.hw_params = mt8183_mt6358_i2s_hw_params,
     46};
     47
     48static int mt8183_da7219_i2s_hw_params(struct snd_pcm_substream *substream,
     49				       struct snd_pcm_hw_params *params)
     50{
     51	struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
     52	struct snd_soc_dai *codec_dai;
     53	unsigned int rate = params_rate(params);
     54	unsigned int mclk_fs_ratio = 256;
     55	unsigned int mclk_fs = rate * mclk_fs_ratio;
     56	unsigned int freq;
     57	int ret = 0, j;
     58
     59	ret = snd_soc_dai_set_sysclk(asoc_rtd_to_cpu(rtd, 0), 0,
     60				     mclk_fs, SND_SOC_CLOCK_OUT);
     61	if (ret < 0)
     62		dev_err(rtd->dev, "failed to set cpu dai sysclk\n");
     63
     64	for_each_rtd_codec_dais(rtd, j, codec_dai) {
     65		if (!strcmp(codec_dai->component->name, DA7219_DEV_NAME)) {
     66			ret = snd_soc_dai_set_sysclk(codec_dai,
     67						     DA7219_CLKSRC_MCLK,
     68						     mclk_fs,
     69						     SND_SOC_CLOCK_IN);
     70			if (ret < 0)
     71				dev_err(rtd->dev, "failed to set sysclk\n");
     72
     73			if ((rate % 8000) == 0)
     74				freq = DA7219_PLL_FREQ_OUT_98304;
     75			else
     76				freq = DA7219_PLL_FREQ_OUT_90316;
     77
     78			ret = snd_soc_dai_set_pll(codec_dai, 0,
     79						  DA7219_SYSCLK_PLL_SRM,
     80						  0, freq);
     81			if (ret)
     82				dev_err(rtd->dev, "failed to start PLL: %d\n",
     83					ret);
     84		}
     85	}
     86
     87	return ret;
     88}
     89
     90static int mt8183_da7219_hw_free(struct snd_pcm_substream *substream)
     91{
     92	struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
     93	struct snd_soc_dai *codec_dai;
     94	int ret = 0, j;
     95
     96	for_each_rtd_codec_dais(rtd, j, codec_dai) {
     97		if (!strcmp(codec_dai->component->name, DA7219_DEV_NAME)) {
     98			ret = snd_soc_dai_set_pll(codec_dai,
     99						  0, DA7219_SYSCLK_MCLK, 0, 0);
    100			if (ret < 0) {
    101				dev_err(rtd->dev, "failed to stop PLL: %d\n",
    102					ret);
    103				break;
    104			}
    105		}
    106	}
    107
    108	return ret;
    109}
    110
    111static const struct snd_soc_ops mt8183_da7219_i2s_ops = {
    112	.hw_params = mt8183_da7219_i2s_hw_params,
    113	.hw_free = mt8183_da7219_hw_free,
    114};
    115
    116static int
    117mt8183_da7219_rt1015_i2s_hw_params(struct snd_pcm_substream *substream,
    118				   struct snd_pcm_hw_params *params)
    119{
    120	struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
    121	unsigned int rate = params_rate(params);
    122	struct snd_soc_dai *codec_dai;
    123	int ret = 0, i;
    124
    125	for_each_rtd_codec_dais(rtd, i, codec_dai) {
    126		if (!strcmp(codec_dai->component->name, RT1015_DEV0_NAME) ||
    127		    !strcmp(codec_dai->component->name, RT1015_DEV1_NAME)) {
    128			ret = snd_soc_dai_set_pll(codec_dai, 0,
    129						  RT1015_PLL_S_BCLK,
    130						  rate * 64, rate * 256);
    131			if (ret) {
    132				dev_err(rtd->dev, "failed to set pll\n");
    133				return ret;
    134			}
    135
    136			ret = snd_soc_dai_set_sysclk(codec_dai,
    137						     RT1015_SCLK_S_PLL,
    138						     rate * 256,
    139						     SND_SOC_CLOCK_IN);
    140			if (ret) {
    141				dev_err(rtd->dev, "failed to set sysclk\n");
    142				return ret;
    143			}
    144		}
    145	}
    146
    147	return mt8183_da7219_i2s_hw_params(substream, params);
    148}
    149
    150static const struct snd_soc_ops mt8183_da7219_rt1015_i2s_ops = {
    151	.hw_params = mt8183_da7219_rt1015_i2s_hw_params,
    152	.hw_free = mt8183_da7219_hw_free,
    153};
    154
    155static int mt8183_i2s_hw_params_fixup(struct snd_soc_pcm_runtime *rtd,
    156				      struct snd_pcm_hw_params *params)
    157{
    158	/* fix BE i2s format to S32_LE, clean param mask first */
    159	snd_mask_reset_range(hw_param_mask(params, SNDRV_PCM_HW_PARAM_FORMAT),
    160			     0, (__force unsigned int)SNDRV_PCM_FORMAT_LAST);
    161
    162	params_set_format(params, SNDRV_PCM_FORMAT_S32_LE);
    163
    164	return 0;
    165}
    166
    167static int mt8183_rt1015_i2s_hw_params_fixup(struct snd_soc_pcm_runtime *rtd,
    168					     struct snd_pcm_hw_params *params)
    169{
    170	/* fix BE i2s format to S24_LE, clean param mask first */
    171	snd_mask_reset_range(hw_param_mask(params, SNDRV_PCM_HW_PARAM_FORMAT),
    172			     0, (__force unsigned int)SNDRV_PCM_FORMAT_LAST);
    173
    174	params_set_format(params, SNDRV_PCM_FORMAT_S24_LE);
    175
    176	return 0;
    177}
    178
    179static int
    180mt8183_da7219_max98357_startup(
    181	struct snd_pcm_substream *substream)
    182{
    183	static const unsigned int rates[] = {
    184		48000,
    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	static const unsigned int channels[] = {
    192		2,
    193	};
    194	static const struct snd_pcm_hw_constraint_list constraints_channels = {
    195		.count = ARRAY_SIZE(channels),
    196		.list = channels,
    197		.mask = 0,
    198	};
    199
    200	struct snd_pcm_runtime *runtime = substream->runtime;
    201
    202	snd_pcm_hw_constraint_list(runtime, 0,
    203			SNDRV_PCM_HW_PARAM_RATE, &constraints_rates);
    204	runtime->hw.channels_max = 2;
    205	snd_pcm_hw_constraint_list(runtime, 0,
    206			SNDRV_PCM_HW_PARAM_CHANNELS,
    207			&constraints_channels);
    208
    209	runtime->hw.formats = SNDRV_PCM_FMTBIT_S16_LE;
    210	snd_pcm_hw_constraint_msbits(runtime, 0, 16, 16);
    211
    212	return 0;
    213}
    214
    215static const struct snd_soc_ops mt8183_da7219_max98357_ops = {
    216	.startup = mt8183_da7219_max98357_startup,
    217};
    218
    219static int
    220mt8183_da7219_max98357_bt_sco_startup(
    221	struct snd_pcm_substream *substream)
    222{
    223	static const unsigned int rates[] = {
    224		8000, 16000
    225	};
    226	static const struct snd_pcm_hw_constraint_list constraints_rates = {
    227		.count = ARRAY_SIZE(rates),
    228		.list  = rates,
    229		.mask = 0,
    230	};
    231	static const unsigned int channels[] = {
    232		1,
    233	};
    234	static const struct snd_pcm_hw_constraint_list constraints_channels = {
    235		.count = ARRAY_SIZE(channels),
    236		.list = channels,
    237		.mask = 0,
    238	};
    239
    240	struct snd_pcm_runtime *runtime = substream->runtime;
    241
    242	snd_pcm_hw_constraint_list(runtime, 0,
    243			SNDRV_PCM_HW_PARAM_RATE, &constraints_rates);
    244	runtime->hw.channels_max = 1;
    245	snd_pcm_hw_constraint_list(runtime, 0,
    246			SNDRV_PCM_HW_PARAM_CHANNELS,
    247			&constraints_channels);
    248
    249	runtime->hw.formats = SNDRV_PCM_FMTBIT_S16_LE;
    250	snd_pcm_hw_constraint_msbits(runtime, 0, 16, 16);
    251
    252	return 0;
    253}
    254
    255static const struct snd_soc_ops mt8183_da7219_max98357_bt_sco_ops = {
    256	.startup = mt8183_da7219_max98357_bt_sco_startup,
    257};
    258
    259/* FE */
    260SND_SOC_DAILINK_DEFS(playback1,
    261	DAILINK_COMP_ARRAY(COMP_CPU("DL1")),
    262	DAILINK_COMP_ARRAY(COMP_DUMMY()),
    263	DAILINK_COMP_ARRAY(COMP_EMPTY()));
    264
    265SND_SOC_DAILINK_DEFS(playback2,
    266	DAILINK_COMP_ARRAY(COMP_CPU("DL2")),
    267	DAILINK_COMP_ARRAY(COMP_DUMMY()),
    268	DAILINK_COMP_ARRAY(COMP_EMPTY()));
    269
    270SND_SOC_DAILINK_DEFS(playback3,
    271	DAILINK_COMP_ARRAY(COMP_CPU("DL3")),
    272	DAILINK_COMP_ARRAY(COMP_DUMMY()),
    273	DAILINK_COMP_ARRAY(COMP_EMPTY()));
    274
    275SND_SOC_DAILINK_DEFS(capture1,
    276	DAILINK_COMP_ARRAY(COMP_CPU("UL1")),
    277	DAILINK_COMP_ARRAY(COMP_DUMMY()),
    278	DAILINK_COMP_ARRAY(COMP_EMPTY()));
    279
    280SND_SOC_DAILINK_DEFS(capture2,
    281	DAILINK_COMP_ARRAY(COMP_CPU("UL2")),
    282	DAILINK_COMP_ARRAY(COMP_DUMMY()),
    283	DAILINK_COMP_ARRAY(COMP_EMPTY()));
    284
    285SND_SOC_DAILINK_DEFS(capture3,
    286	DAILINK_COMP_ARRAY(COMP_CPU("UL3")),
    287	DAILINK_COMP_ARRAY(COMP_DUMMY()),
    288	DAILINK_COMP_ARRAY(COMP_EMPTY()));
    289
    290SND_SOC_DAILINK_DEFS(capture_mono,
    291	DAILINK_COMP_ARRAY(COMP_CPU("UL_MONO_1")),
    292	DAILINK_COMP_ARRAY(COMP_DUMMY()),
    293	DAILINK_COMP_ARRAY(COMP_EMPTY()));
    294
    295SND_SOC_DAILINK_DEFS(playback_hdmi,
    296	DAILINK_COMP_ARRAY(COMP_CPU("HDMI")),
    297	DAILINK_COMP_ARRAY(COMP_DUMMY()),
    298	DAILINK_COMP_ARRAY(COMP_EMPTY()));
    299
    300/* BE */
    301SND_SOC_DAILINK_DEFS(primary_codec,
    302	DAILINK_COMP_ARRAY(COMP_CPU("ADDA")),
    303	DAILINK_COMP_ARRAY(COMP_CODEC("mt6358-sound", "mt6358-snd-codec-aif1")),
    304	DAILINK_COMP_ARRAY(COMP_EMPTY()));
    305
    306SND_SOC_DAILINK_DEFS(pcm1,
    307	DAILINK_COMP_ARRAY(COMP_CPU("PCM 1")),
    308	DAILINK_COMP_ARRAY(COMP_DUMMY()),
    309	DAILINK_COMP_ARRAY(COMP_EMPTY()));
    310
    311SND_SOC_DAILINK_DEFS(pcm2,
    312	DAILINK_COMP_ARRAY(COMP_CPU("PCM 2")),
    313	DAILINK_COMP_ARRAY(COMP_DUMMY()),
    314	DAILINK_COMP_ARRAY(COMP_EMPTY()));
    315
    316SND_SOC_DAILINK_DEFS(i2s0,
    317	DAILINK_COMP_ARRAY(COMP_CPU("I2S0")),
    318	DAILINK_COMP_ARRAY(COMP_CODEC("bt-sco", "bt-sco-pcm")),
    319	DAILINK_COMP_ARRAY(COMP_EMPTY()));
    320
    321SND_SOC_DAILINK_DEFS(i2s1,
    322	DAILINK_COMP_ARRAY(COMP_CPU("I2S1")),
    323	DAILINK_COMP_ARRAY(COMP_DUMMY()),
    324	DAILINK_COMP_ARRAY(COMP_EMPTY()));
    325
    326SND_SOC_DAILINK_DEFS(i2s2,
    327	DAILINK_COMP_ARRAY(COMP_CPU("I2S2")),
    328	DAILINK_COMP_ARRAY(COMP_CODEC(DA7219_DEV_NAME, DA7219_CODEC_DAI)),
    329	DAILINK_COMP_ARRAY(COMP_EMPTY()));
    330
    331SND_SOC_DAILINK_DEFS(i2s3_max98357a,
    332	DAILINK_COMP_ARRAY(COMP_CPU("I2S3")),
    333	DAILINK_COMP_ARRAY(COMP_CODEC("max98357a", "HiFi"),
    334			   COMP_CODEC(DA7219_DEV_NAME, DA7219_CODEC_DAI)),
    335	DAILINK_COMP_ARRAY(COMP_EMPTY()));
    336
    337SND_SOC_DAILINK_DEFS(i2s3_rt1015,
    338	DAILINK_COMP_ARRAY(COMP_CPU("I2S3")),
    339	DAILINK_COMP_ARRAY(COMP_CODEC(RT1015_DEV0_NAME, RT1015_CODEC_DAI),
    340			   COMP_CODEC(RT1015_DEV1_NAME, RT1015_CODEC_DAI),
    341			   COMP_CODEC(DA7219_DEV_NAME, DA7219_CODEC_DAI)),
    342	DAILINK_COMP_ARRAY(COMP_EMPTY()));
    343
    344SND_SOC_DAILINK_DEFS(i2s3_rt1015p,
    345	DAILINK_COMP_ARRAY(COMP_CPU("I2S3")),
    346	DAILINK_COMP_ARRAY(COMP_CODEC("rt1015p", "HiFi"),
    347			   COMP_CODEC(DA7219_DEV_NAME, DA7219_CODEC_DAI)),
    348	DAILINK_COMP_ARRAY(COMP_EMPTY()));
    349
    350SND_SOC_DAILINK_DEFS(i2s5,
    351	DAILINK_COMP_ARRAY(COMP_CPU("I2S5")),
    352	DAILINK_COMP_ARRAY(COMP_CODEC("bt-sco", "bt-sco-pcm")),
    353	DAILINK_COMP_ARRAY(COMP_EMPTY()));
    354
    355SND_SOC_DAILINK_DEFS(tdm,
    356	DAILINK_COMP_ARRAY(COMP_CPU("TDM")),
    357	DAILINK_COMP_ARRAY(COMP_CODEC(NULL, "i2s-hifi")),
    358	DAILINK_COMP_ARRAY(COMP_EMPTY()));
    359
    360static int mt8183_da7219_max98357_hdmi_init(struct snd_soc_pcm_runtime *rtd)
    361{
    362	struct mt8183_da7219_max98357_priv *priv =
    363		snd_soc_card_get_drvdata(rtd->card);
    364	int ret;
    365
    366	ret = snd_soc_card_jack_new(rtd->card, "HDMI Jack", SND_JACK_LINEOUT,
    367				    &priv->hdmi_jack);
    368	if (ret)
    369		return ret;
    370
    371	return snd_soc_component_set_jack(asoc_rtd_to_codec(rtd, 0)->component,
    372					  &priv->hdmi_jack, NULL);
    373}
    374
    375static struct snd_soc_dai_link mt8183_da7219_dai_links[] = {
    376	/* FE */
    377	{
    378		.name = "Playback_1",
    379		.stream_name = "Playback_1",
    380		.trigger = {SND_SOC_DPCM_TRIGGER_PRE,
    381			    SND_SOC_DPCM_TRIGGER_PRE},
    382		.dynamic = 1,
    383		.dpcm_playback = 1,
    384		.ops = &mt8183_da7219_max98357_ops,
    385		SND_SOC_DAILINK_REG(playback1),
    386	},
    387	{
    388		.name = "Playback_2",
    389		.stream_name = "Playback_2",
    390		.trigger = {SND_SOC_DPCM_TRIGGER_PRE,
    391			    SND_SOC_DPCM_TRIGGER_PRE},
    392		.dynamic = 1,
    393		.dpcm_playback = 1,
    394		.ops = &mt8183_da7219_max98357_bt_sco_ops,
    395		SND_SOC_DAILINK_REG(playback2),
    396	},
    397	{
    398		.name = "Playback_3",
    399		.stream_name = "Playback_3",
    400		.trigger = {SND_SOC_DPCM_TRIGGER_PRE,
    401			    SND_SOC_DPCM_TRIGGER_PRE},
    402		.dynamic = 1,
    403		.dpcm_playback = 1,
    404		SND_SOC_DAILINK_REG(playback3),
    405	},
    406	{
    407		.name = "Capture_1",
    408		.stream_name = "Capture_1",
    409		.trigger = {SND_SOC_DPCM_TRIGGER_PRE,
    410			    SND_SOC_DPCM_TRIGGER_PRE},
    411		.dynamic = 1,
    412		.dpcm_capture = 1,
    413		.ops = &mt8183_da7219_max98357_bt_sco_ops,
    414		SND_SOC_DAILINK_REG(capture1),
    415	},
    416	{
    417		.name = "Capture_2",
    418		.stream_name = "Capture_2",
    419		.trigger = {SND_SOC_DPCM_TRIGGER_PRE,
    420			    SND_SOC_DPCM_TRIGGER_PRE},
    421		.dynamic = 1,
    422		.dpcm_capture = 1,
    423		SND_SOC_DAILINK_REG(capture2),
    424	},
    425	{
    426		.name = "Capture_3",
    427		.stream_name = "Capture_3",
    428		.trigger = {SND_SOC_DPCM_TRIGGER_PRE,
    429			    SND_SOC_DPCM_TRIGGER_PRE},
    430		.dynamic = 1,
    431		.dpcm_capture = 1,
    432		.ops = &mt8183_da7219_max98357_ops,
    433		SND_SOC_DAILINK_REG(capture3),
    434	},
    435	{
    436		.name = "Capture_Mono_1",
    437		.stream_name = "Capture_Mono_1",
    438		.trigger = {SND_SOC_DPCM_TRIGGER_PRE,
    439			    SND_SOC_DPCM_TRIGGER_PRE},
    440		.dynamic = 1,
    441		.dpcm_capture = 1,
    442		SND_SOC_DAILINK_REG(capture_mono),
    443	},
    444	{
    445		.name = "Playback_HDMI",
    446		.stream_name = "Playback_HDMI",
    447		.trigger = {SND_SOC_DPCM_TRIGGER_PRE,
    448			    SND_SOC_DPCM_TRIGGER_PRE},
    449		.dynamic = 1,
    450		.dpcm_playback = 1,
    451		SND_SOC_DAILINK_REG(playback_hdmi),
    452	},
    453	/* BE */
    454	{
    455		.name = "Primary Codec",
    456		.no_pcm = 1,
    457		.dpcm_playback = 1,
    458		.dpcm_capture = 1,
    459		.ignore_suspend = 1,
    460		SND_SOC_DAILINK_REG(primary_codec),
    461	},
    462	{
    463		.name = "PCM 1",
    464		.no_pcm = 1,
    465		.dpcm_playback = 1,
    466		.dpcm_capture = 1,
    467		.ignore_suspend = 1,
    468		SND_SOC_DAILINK_REG(pcm1),
    469	},
    470	{
    471		.name = "PCM 2",
    472		.no_pcm = 1,
    473		.dpcm_playback = 1,
    474		.dpcm_capture = 1,
    475		.ignore_suspend = 1,
    476		SND_SOC_DAILINK_REG(pcm2),
    477	},
    478	{
    479		.name = "I2S0",
    480		.no_pcm = 1,
    481		.dpcm_capture = 1,
    482		.ignore_suspend = 1,
    483		.be_hw_params_fixup = mt8183_i2s_hw_params_fixup,
    484		.ops = &mt8183_mt6358_i2s_ops,
    485		SND_SOC_DAILINK_REG(i2s0),
    486	},
    487	{
    488		.name = "I2S1",
    489		.no_pcm = 1,
    490		.dpcm_playback = 1,
    491		.ignore_suspend = 1,
    492		.be_hw_params_fixup = mt8183_i2s_hw_params_fixup,
    493		.ops = &mt8183_mt6358_i2s_ops,
    494		SND_SOC_DAILINK_REG(i2s1),
    495	},
    496	{
    497		.name = "I2S2",
    498		.no_pcm = 1,
    499		.dpcm_capture = 1,
    500		.ignore_suspend = 1,
    501		.be_hw_params_fixup = mt8183_i2s_hw_params_fixup,
    502		.ops = &mt8183_da7219_i2s_ops,
    503		SND_SOC_DAILINK_REG(i2s2),
    504	},
    505	{
    506		.name = "I2S3",
    507		.no_pcm = 1,
    508		.dpcm_playback = 1,
    509		.ignore_suspend = 1,
    510	},
    511	{
    512		.name = "I2S5",
    513		.no_pcm = 1,
    514		.dpcm_playback = 1,
    515		.ignore_suspend = 1,
    516		.be_hw_params_fixup = mt8183_i2s_hw_params_fixup,
    517		.ops = &mt8183_mt6358_i2s_ops,
    518		SND_SOC_DAILINK_REG(i2s5),
    519	},
    520	{
    521		.name = "TDM",
    522		.no_pcm = 1,
    523		.dai_fmt = SND_SOC_DAIFMT_I2S |
    524			   SND_SOC_DAIFMT_IB_IF |
    525			   SND_SOC_DAIFMT_CBM_CFM,
    526		.dpcm_playback = 1,
    527		.ignore_suspend = 1,
    528		.be_hw_params_fixup = mt8183_i2s_hw_params_fixup,
    529		.ignore = 1,
    530		.init = mt8183_da7219_max98357_hdmi_init,
    531		SND_SOC_DAILINK_REG(tdm),
    532	},
    533};
    534
    535static int
    536mt8183_da7219_max98357_headset_init(struct snd_soc_component *component)
    537{
    538	int ret;
    539	struct mt8183_da7219_max98357_priv *priv =
    540			snd_soc_card_get_drvdata(component->card);
    541
    542	/* Enable Headset and 4 Buttons Jack detection */
    543	ret = snd_soc_card_jack_new(component->card,
    544				    "Headset Jack",
    545				    SND_JACK_HEADSET |
    546				    SND_JACK_BTN_0 | SND_JACK_BTN_1 |
    547				    SND_JACK_BTN_2 | SND_JACK_BTN_3 |
    548				    SND_JACK_LINEOUT,
    549				    &priv->headset_jack);
    550	if (ret)
    551		return ret;
    552
    553	snd_jack_set_key(
    554		priv->headset_jack.jack, SND_JACK_BTN_0, KEY_PLAYPAUSE);
    555	snd_jack_set_key(
    556		priv->headset_jack.jack, SND_JACK_BTN_1, KEY_VOLUMEUP);
    557	snd_jack_set_key(
    558		priv->headset_jack.jack, SND_JACK_BTN_2, KEY_VOLUMEDOWN);
    559	snd_jack_set_key(
    560		priv->headset_jack.jack, SND_JACK_BTN_3, KEY_VOICECOMMAND);
    561
    562	da7219_aad_jack_det(component, &priv->headset_jack);
    563
    564	return 0;
    565}
    566
    567static struct snd_soc_aux_dev mt8183_da7219_max98357_headset_dev = {
    568	.dlc = COMP_EMPTY(),
    569	.init = mt8183_da7219_max98357_headset_init,
    570};
    571
    572static struct snd_soc_codec_conf mt6358_codec_conf[] = {
    573	{
    574		.dlc = COMP_CODEC_CONF("mt6358-sound"),
    575		.name_prefix = "Mt6358",
    576	},
    577};
    578
    579static const struct snd_kcontrol_new mt8183_da7219_max98357_snd_controls[] = {
    580	SOC_DAPM_PIN_SWITCH("Speakers"),
    581};
    582
    583static const
    584struct snd_soc_dapm_widget mt8183_da7219_max98357_dapm_widgets[] = {
    585	SND_SOC_DAPM_SPK("Speakers", NULL),
    586	SND_SOC_DAPM_PINCTRL("TDM_OUT_PINCTRL",
    587			     "aud_tdm_out_on", "aud_tdm_out_off"),
    588};
    589
    590static const struct snd_soc_dapm_route mt8183_da7219_max98357_dapm_routes[] = {
    591	{"Speakers", NULL, "Speaker"},
    592	{"I2S Playback", NULL, "TDM_OUT_PINCTRL"},
    593};
    594
    595static struct snd_soc_card mt8183_da7219_max98357_card = {
    596	.name = "mt8183_da7219_max98357",
    597	.owner = THIS_MODULE,
    598	.controls = mt8183_da7219_max98357_snd_controls,
    599	.num_controls = ARRAY_SIZE(mt8183_da7219_max98357_snd_controls),
    600	.dapm_widgets = mt8183_da7219_max98357_dapm_widgets,
    601	.num_dapm_widgets = ARRAY_SIZE(mt8183_da7219_max98357_dapm_widgets),
    602	.dapm_routes = mt8183_da7219_max98357_dapm_routes,
    603	.num_dapm_routes = ARRAY_SIZE(mt8183_da7219_max98357_dapm_routes),
    604	.dai_link = mt8183_da7219_dai_links,
    605	.num_links = ARRAY_SIZE(mt8183_da7219_dai_links),
    606	.aux_dev = &mt8183_da7219_max98357_headset_dev,
    607	.num_aux_devs = 1,
    608	.codec_conf = mt6358_codec_conf,
    609	.num_configs = ARRAY_SIZE(mt6358_codec_conf),
    610};
    611
    612static struct snd_soc_codec_conf mt8183_da7219_rt1015_codec_conf[] = {
    613	{
    614		.dlc = COMP_CODEC_CONF("mt6358-sound"),
    615		.name_prefix = "Mt6358",
    616	},
    617	{
    618		.dlc = COMP_CODEC_CONF(RT1015_DEV0_NAME),
    619		.name_prefix = "Left",
    620	},
    621	{
    622		.dlc = COMP_CODEC_CONF(RT1015_DEV1_NAME),
    623		.name_prefix = "Right",
    624	},
    625};
    626
    627static const struct snd_kcontrol_new mt8183_da7219_rt1015_snd_controls[] = {
    628	SOC_DAPM_PIN_SWITCH("Left Spk"),
    629	SOC_DAPM_PIN_SWITCH("Right Spk"),
    630};
    631
    632static const
    633struct snd_soc_dapm_widget mt8183_da7219_rt1015_dapm_widgets[] = {
    634	SND_SOC_DAPM_SPK("Left Spk", NULL),
    635	SND_SOC_DAPM_SPK("Right Spk", NULL),
    636	SND_SOC_DAPM_PINCTRL("TDM_OUT_PINCTRL",
    637			     "aud_tdm_out_on", "aud_tdm_out_off"),
    638};
    639
    640static const struct snd_soc_dapm_route mt8183_da7219_rt1015_dapm_routes[] = {
    641	{"Left Spk", NULL, "Left SPO"},
    642	{"Right Spk", NULL, "Right SPO"},
    643	{"I2S Playback", NULL, "TDM_OUT_PINCTRL"},
    644};
    645
    646static struct snd_soc_card mt8183_da7219_rt1015_card = {
    647	.name = "mt8183_da7219_rt1015",
    648	.owner = THIS_MODULE,
    649	.controls = mt8183_da7219_rt1015_snd_controls,
    650	.num_controls = ARRAY_SIZE(mt8183_da7219_rt1015_snd_controls),
    651	.dapm_widgets = mt8183_da7219_rt1015_dapm_widgets,
    652	.num_dapm_widgets = ARRAY_SIZE(mt8183_da7219_rt1015_dapm_widgets),
    653	.dapm_routes = mt8183_da7219_rt1015_dapm_routes,
    654	.num_dapm_routes = ARRAY_SIZE(mt8183_da7219_rt1015_dapm_routes),
    655	.dai_link = mt8183_da7219_dai_links,
    656	.num_links = ARRAY_SIZE(mt8183_da7219_dai_links),
    657	.aux_dev = &mt8183_da7219_max98357_headset_dev,
    658	.num_aux_devs = 1,
    659	.codec_conf = mt8183_da7219_rt1015_codec_conf,
    660	.num_configs = ARRAY_SIZE(mt8183_da7219_rt1015_codec_conf),
    661};
    662
    663static struct snd_soc_card mt8183_da7219_rt1015p_card = {
    664	.name = "mt8183_da7219_rt1015p",
    665	.owner = THIS_MODULE,
    666	.controls = mt8183_da7219_max98357_snd_controls,
    667	.num_controls = ARRAY_SIZE(mt8183_da7219_max98357_snd_controls),
    668	.dapm_widgets = mt8183_da7219_max98357_dapm_widgets,
    669	.num_dapm_widgets = ARRAY_SIZE(mt8183_da7219_max98357_dapm_widgets),
    670	.dapm_routes = mt8183_da7219_max98357_dapm_routes,
    671	.num_dapm_routes = ARRAY_SIZE(mt8183_da7219_max98357_dapm_routes),
    672	.dai_link = mt8183_da7219_dai_links,
    673	.num_links = ARRAY_SIZE(mt8183_da7219_dai_links),
    674	.aux_dev = &mt8183_da7219_max98357_headset_dev,
    675	.num_aux_devs = 1,
    676	.codec_conf = mt6358_codec_conf,
    677	.num_configs = ARRAY_SIZE(mt6358_codec_conf),
    678};
    679
    680static int mt8183_da7219_max98357_dev_probe(struct platform_device *pdev)
    681{
    682	struct snd_soc_card *card;
    683	struct device_node *platform_node, *hdmi_codec;
    684	struct snd_soc_dai_link *dai_link;
    685	struct mt8183_da7219_max98357_priv *priv;
    686	struct pinctrl *pinctrl;
    687	int ret, i;
    688
    689	platform_node = of_parse_phandle(pdev->dev.of_node,
    690					 "mediatek,platform", 0);
    691	if (!platform_node) {
    692		dev_err(&pdev->dev, "Property 'platform' missing or invalid\n");
    693		return -EINVAL;
    694	}
    695
    696	card = (struct snd_soc_card *)of_device_get_match_data(&pdev->dev);
    697	if (!card) {
    698		ret = -EINVAL;
    699		goto put_platform_node;
    700	}
    701
    702	card->dev = &pdev->dev;
    703
    704	hdmi_codec = of_parse_phandle(pdev->dev.of_node,
    705				      "mediatek,hdmi-codec", 0);
    706
    707	for_each_card_prelinks(card, i, dai_link) {
    708		if (strcmp(dai_link->name, "I2S3") == 0) {
    709			if (card == &mt8183_da7219_max98357_card) {
    710				dai_link->be_hw_params_fixup =
    711					mt8183_i2s_hw_params_fixup;
    712				dai_link->ops = &mt8183_da7219_i2s_ops;
    713				dai_link->cpus = i2s3_max98357a_cpus;
    714				dai_link->num_cpus =
    715					ARRAY_SIZE(i2s3_max98357a_cpus);
    716				dai_link->codecs = i2s3_max98357a_codecs;
    717				dai_link->num_codecs =
    718					ARRAY_SIZE(i2s3_max98357a_codecs);
    719				dai_link->platforms = i2s3_max98357a_platforms;
    720				dai_link->num_platforms =
    721					ARRAY_SIZE(i2s3_max98357a_platforms);
    722			} else if (card == &mt8183_da7219_rt1015_card) {
    723				dai_link->be_hw_params_fixup =
    724					mt8183_rt1015_i2s_hw_params_fixup;
    725				dai_link->ops = &mt8183_da7219_rt1015_i2s_ops;
    726				dai_link->cpus = i2s3_rt1015_cpus;
    727				dai_link->num_cpus =
    728					ARRAY_SIZE(i2s3_rt1015_cpus);
    729				dai_link->codecs = i2s3_rt1015_codecs;
    730				dai_link->num_codecs =
    731					ARRAY_SIZE(i2s3_rt1015_codecs);
    732				dai_link->platforms = i2s3_rt1015_platforms;
    733				dai_link->num_platforms =
    734					ARRAY_SIZE(i2s3_rt1015_platforms);
    735			} else if (card == &mt8183_da7219_rt1015p_card) {
    736				dai_link->be_hw_params_fixup =
    737					mt8183_rt1015_i2s_hw_params_fixup;
    738				dai_link->ops = &mt8183_da7219_i2s_ops;
    739				dai_link->cpus = i2s3_rt1015p_cpus;
    740				dai_link->num_cpus =
    741					ARRAY_SIZE(i2s3_rt1015p_cpus);
    742				dai_link->codecs = i2s3_rt1015p_codecs;
    743				dai_link->num_codecs =
    744					ARRAY_SIZE(i2s3_rt1015p_codecs);
    745				dai_link->platforms = i2s3_rt1015p_platforms;
    746				dai_link->num_platforms =
    747					ARRAY_SIZE(i2s3_rt1015p_platforms);
    748			}
    749		}
    750
    751		if (hdmi_codec && strcmp(dai_link->name, "TDM") == 0) {
    752			dai_link->codecs->of_node = hdmi_codec;
    753			dai_link->ignore = 0;
    754		}
    755
    756		if (!dai_link->platforms->name)
    757			dai_link->platforms->of_node = platform_node;
    758	}
    759
    760	mt8183_da7219_max98357_headset_dev.dlc.of_node =
    761		of_parse_phandle(pdev->dev.of_node,
    762				 "mediatek,headset-codec", 0);
    763	if (!mt8183_da7219_max98357_headset_dev.dlc.of_node) {
    764		dev_err(&pdev->dev,
    765			"Property 'mediatek,headset-codec' missing/invalid\n");
    766		ret = -EINVAL;
    767		goto put_hdmi_codec;
    768	}
    769
    770	priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
    771	if (!priv) {
    772		ret = -ENOMEM;
    773		goto put_hdmi_codec;
    774	}
    775
    776	snd_soc_card_set_drvdata(card, priv);
    777
    778	pinctrl = devm_pinctrl_get_select(&pdev->dev, PINCTRL_STATE_DEFAULT);
    779	if (IS_ERR(pinctrl)) {
    780		ret = PTR_ERR(pinctrl);
    781		dev_err(&pdev->dev, "%s failed to select default state %d\n",
    782			__func__, ret);
    783		goto put_hdmi_codec;
    784	}
    785
    786	ret = devm_snd_soc_register_card(&pdev->dev, card);
    787
    788
    789put_hdmi_codec:
    790	of_node_put(hdmi_codec);
    791put_platform_node:
    792	of_node_put(platform_node);
    793	return ret;
    794}
    795
    796#ifdef CONFIG_OF
    797static const struct of_device_id mt8183_da7219_max98357_dt_match[] = {
    798	{
    799		.compatible = "mediatek,mt8183_da7219_max98357",
    800		.data = &mt8183_da7219_max98357_card,
    801	},
    802	{
    803		.compatible = "mediatek,mt8183_da7219_rt1015",
    804		.data = &mt8183_da7219_rt1015_card,
    805	},
    806	{
    807		.compatible = "mediatek,mt8183_da7219_rt1015p",
    808		.data = &mt8183_da7219_rt1015p_card,
    809	},
    810	{}
    811};
    812#endif
    813
    814static struct platform_driver mt8183_da7219_max98357_driver = {
    815	.driver = {
    816		.name = "mt8183_da7219",
    817#ifdef CONFIG_OF
    818		.of_match_table = mt8183_da7219_max98357_dt_match,
    819#endif
    820		.pm = &snd_soc_pm_ops,
    821	},
    822	.probe = mt8183_da7219_max98357_dev_probe,
    823};
    824
    825module_platform_driver(mt8183_da7219_max98357_driver);
    826
    827/* Module information */
    828MODULE_DESCRIPTION("MT8183-DA7219-MAX98357 ALSA SoC machine driver");
    829MODULE_AUTHOR("Shunli Wang <shunli.wang@mediatek.com>");
    830MODULE_LICENSE("GPL v2");
    831MODULE_ALIAS("mt8183_da7219_max98357 soc card");