brintos

brintos / linux-shallow public Read only

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