brintos

brintos / linux-shallow public Read only

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