162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0 262306a36Sopenharmony_ci// 362306a36Sopenharmony_ci// mt8183-da7219-max98357.c 462306a36Sopenharmony_ci// -- MT8183-DA7219-MAX98357 ALSA SoC machine driver 562306a36Sopenharmony_ci// 662306a36Sopenharmony_ci// Copyright (c) 2018 MediaTek Inc. 762306a36Sopenharmony_ci// Author: Shunli Wang <shunli.wang@mediatek.com> 862306a36Sopenharmony_ci 962306a36Sopenharmony_ci#include <linux/input.h> 1062306a36Sopenharmony_ci#include <linux/module.h> 1162306a36Sopenharmony_ci#include <linux/of_device.h> 1262306a36Sopenharmony_ci#include <linux/pinctrl/consumer.h> 1362306a36Sopenharmony_ci#include <sound/jack.h> 1462306a36Sopenharmony_ci#include <sound/pcm_params.h> 1562306a36Sopenharmony_ci#include <sound/soc.h> 1662306a36Sopenharmony_ci 1762306a36Sopenharmony_ci#include "../../codecs/da7219.h" 1862306a36Sopenharmony_ci#include "../../codecs/rt1015.h" 1962306a36Sopenharmony_ci#include "../common/mtk-afe-platform-driver.h" 2062306a36Sopenharmony_ci#include "mt8183-afe-common.h" 2162306a36Sopenharmony_ci 2262306a36Sopenharmony_ci#define DA7219_CODEC_DAI "da7219-hifi" 2362306a36Sopenharmony_ci#define DA7219_DEV_NAME "da7219.5-001a" 2462306a36Sopenharmony_ci#define RT1015_CODEC_DAI "rt1015-aif" 2562306a36Sopenharmony_ci#define RT1015_DEV0_NAME "rt1015.6-0028" 2662306a36Sopenharmony_ci#define RT1015_DEV1_NAME "rt1015.6-0029" 2762306a36Sopenharmony_ci 2862306a36Sopenharmony_cistruct mt8183_da7219_max98357_priv { 2962306a36Sopenharmony_ci struct snd_soc_jack headset_jack, hdmi_jack; 3062306a36Sopenharmony_ci}; 3162306a36Sopenharmony_ci 3262306a36Sopenharmony_cistatic struct snd_soc_jack_pin mt8183_da7219_max98357_jack_pins[] = { 3362306a36Sopenharmony_ci { 3462306a36Sopenharmony_ci .pin = "Headphone", 3562306a36Sopenharmony_ci .mask = SND_JACK_HEADPHONE, 3662306a36Sopenharmony_ci }, 3762306a36Sopenharmony_ci { 3862306a36Sopenharmony_ci .pin = "Headset Mic", 3962306a36Sopenharmony_ci .mask = SND_JACK_MICROPHONE, 4062306a36Sopenharmony_ci }, 4162306a36Sopenharmony_ci { 4262306a36Sopenharmony_ci .pin = "Line Out", 4362306a36Sopenharmony_ci .mask = SND_JACK_LINEOUT, 4462306a36Sopenharmony_ci }, 4562306a36Sopenharmony_ci}; 4662306a36Sopenharmony_ci 4762306a36Sopenharmony_cistatic int mt8183_mt6358_i2s_hw_params(struct snd_pcm_substream *substream, 4862306a36Sopenharmony_ci struct snd_pcm_hw_params *params) 4962306a36Sopenharmony_ci{ 5062306a36Sopenharmony_ci struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream); 5162306a36Sopenharmony_ci unsigned int rate = params_rate(params); 5262306a36Sopenharmony_ci unsigned int mclk_fs_ratio = 128; 5362306a36Sopenharmony_ci unsigned int mclk_fs = rate * mclk_fs_ratio; 5462306a36Sopenharmony_ci 5562306a36Sopenharmony_ci return snd_soc_dai_set_sysclk(asoc_rtd_to_cpu(rtd, 0), 5662306a36Sopenharmony_ci 0, mclk_fs, SND_SOC_CLOCK_OUT); 5762306a36Sopenharmony_ci} 5862306a36Sopenharmony_ci 5962306a36Sopenharmony_cistatic const struct snd_soc_ops mt8183_mt6358_i2s_ops = { 6062306a36Sopenharmony_ci .hw_params = mt8183_mt6358_i2s_hw_params, 6162306a36Sopenharmony_ci}; 6262306a36Sopenharmony_ci 6362306a36Sopenharmony_cistatic int mt8183_da7219_i2s_hw_params(struct snd_pcm_substream *substream, 6462306a36Sopenharmony_ci struct snd_pcm_hw_params *params) 6562306a36Sopenharmony_ci{ 6662306a36Sopenharmony_ci struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream); 6762306a36Sopenharmony_ci struct snd_soc_dai *codec_dai; 6862306a36Sopenharmony_ci unsigned int rate = params_rate(params); 6962306a36Sopenharmony_ci unsigned int mclk_fs_ratio = 256; 7062306a36Sopenharmony_ci unsigned int mclk_fs = rate * mclk_fs_ratio; 7162306a36Sopenharmony_ci unsigned int freq; 7262306a36Sopenharmony_ci int ret = 0, j; 7362306a36Sopenharmony_ci 7462306a36Sopenharmony_ci ret = snd_soc_dai_set_sysclk(asoc_rtd_to_cpu(rtd, 0), 0, 7562306a36Sopenharmony_ci mclk_fs, SND_SOC_CLOCK_OUT); 7662306a36Sopenharmony_ci if (ret < 0) 7762306a36Sopenharmony_ci dev_err(rtd->dev, "failed to set cpu dai sysclk\n"); 7862306a36Sopenharmony_ci 7962306a36Sopenharmony_ci for_each_rtd_codec_dais(rtd, j, codec_dai) { 8062306a36Sopenharmony_ci if (!strcmp(codec_dai->component->name, DA7219_DEV_NAME)) { 8162306a36Sopenharmony_ci ret = snd_soc_dai_set_sysclk(codec_dai, 8262306a36Sopenharmony_ci DA7219_CLKSRC_MCLK, 8362306a36Sopenharmony_ci mclk_fs, 8462306a36Sopenharmony_ci SND_SOC_CLOCK_IN); 8562306a36Sopenharmony_ci if (ret < 0) 8662306a36Sopenharmony_ci dev_err(rtd->dev, "failed to set sysclk\n"); 8762306a36Sopenharmony_ci 8862306a36Sopenharmony_ci if ((rate % 8000) == 0) 8962306a36Sopenharmony_ci freq = DA7219_PLL_FREQ_OUT_98304; 9062306a36Sopenharmony_ci else 9162306a36Sopenharmony_ci freq = DA7219_PLL_FREQ_OUT_90316; 9262306a36Sopenharmony_ci 9362306a36Sopenharmony_ci ret = snd_soc_dai_set_pll(codec_dai, 0, 9462306a36Sopenharmony_ci DA7219_SYSCLK_PLL_SRM, 9562306a36Sopenharmony_ci 0, freq); 9662306a36Sopenharmony_ci if (ret) 9762306a36Sopenharmony_ci dev_err(rtd->dev, "failed to start PLL: %d\n", 9862306a36Sopenharmony_ci ret); 9962306a36Sopenharmony_ci } 10062306a36Sopenharmony_ci } 10162306a36Sopenharmony_ci 10262306a36Sopenharmony_ci return ret; 10362306a36Sopenharmony_ci} 10462306a36Sopenharmony_ci 10562306a36Sopenharmony_cistatic int mt8183_da7219_hw_free(struct snd_pcm_substream *substream) 10662306a36Sopenharmony_ci{ 10762306a36Sopenharmony_ci struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream); 10862306a36Sopenharmony_ci struct snd_soc_dai *codec_dai; 10962306a36Sopenharmony_ci int ret = 0, j; 11062306a36Sopenharmony_ci 11162306a36Sopenharmony_ci for_each_rtd_codec_dais(rtd, j, codec_dai) { 11262306a36Sopenharmony_ci if (!strcmp(codec_dai->component->name, DA7219_DEV_NAME)) { 11362306a36Sopenharmony_ci ret = snd_soc_dai_set_pll(codec_dai, 11462306a36Sopenharmony_ci 0, DA7219_SYSCLK_MCLK, 0, 0); 11562306a36Sopenharmony_ci if (ret < 0) { 11662306a36Sopenharmony_ci dev_err(rtd->dev, "failed to stop PLL: %d\n", 11762306a36Sopenharmony_ci ret); 11862306a36Sopenharmony_ci break; 11962306a36Sopenharmony_ci } 12062306a36Sopenharmony_ci } 12162306a36Sopenharmony_ci } 12262306a36Sopenharmony_ci 12362306a36Sopenharmony_ci return ret; 12462306a36Sopenharmony_ci} 12562306a36Sopenharmony_ci 12662306a36Sopenharmony_cistatic const struct snd_soc_ops mt8183_da7219_i2s_ops = { 12762306a36Sopenharmony_ci .hw_params = mt8183_da7219_i2s_hw_params, 12862306a36Sopenharmony_ci .hw_free = mt8183_da7219_hw_free, 12962306a36Sopenharmony_ci}; 13062306a36Sopenharmony_ci 13162306a36Sopenharmony_cistatic int 13262306a36Sopenharmony_cimt8183_da7219_rt1015_i2s_hw_params(struct snd_pcm_substream *substream, 13362306a36Sopenharmony_ci struct snd_pcm_hw_params *params) 13462306a36Sopenharmony_ci{ 13562306a36Sopenharmony_ci struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream); 13662306a36Sopenharmony_ci unsigned int rate = params_rate(params); 13762306a36Sopenharmony_ci struct snd_soc_dai *codec_dai; 13862306a36Sopenharmony_ci int ret = 0, i; 13962306a36Sopenharmony_ci 14062306a36Sopenharmony_ci for_each_rtd_codec_dais(rtd, i, codec_dai) { 14162306a36Sopenharmony_ci if (!strcmp(codec_dai->component->name, RT1015_DEV0_NAME) || 14262306a36Sopenharmony_ci !strcmp(codec_dai->component->name, RT1015_DEV1_NAME)) { 14362306a36Sopenharmony_ci ret = snd_soc_dai_set_pll(codec_dai, 0, 14462306a36Sopenharmony_ci RT1015_PLL_S_BCLK, 14562306a36Sopenharmony_ci rate * 64, rate * 256); 14662306a36Sopenharmony_ci if (ret) { 14762306a36Sopenharmony_ci dev_err(rtd->dev, "failed to set pll\n"); 14862306a36Sopenharmony_ci return ret; 14962306a36Sopenharmony_ci } 15062306a36Sopenharmony_ci 15162306a36Sopenharmony_ci ret = snd_soc_dai_set_sysclk(codec_dai, 15262306a36Sopenharmony_ci RT1015_SCLK_S_PLL, 15362306a36Sopenharmony_ci rate * 256, 15462306a36Sopenharmony_ci SND_SOC_CLOCK_IN); 15562306a36Sopenharmony_ci if (ret) { 15662306a36Sopenharmony_ci dev_err(rtd->dev, "failed to set sysclk\n"); 15762306a36Sopenharmony_ci return ret; 15862306a36Sopenharmony_ci } 15962306a36Sopenharmony_ci } 16062306a36Sopenharmony_ci } 16162306a36Sopenharmony_ci 16262306a36Sopenharmony_ci return mt8183_da7219_i2s_hw_params(substream, params); 16362306a36Sopenharmony_ci} 16462306a36Sopenharmony_ci 16562306a36Sopenharmony_cistatic const struct snd_soc_ops mt8183_da7219_rt1015_i2s_ops = { 16662306a36Sopenharmony_ci .hw_params = mt8183_da7219_rt1015_i2s_hw_params, 16762306a36Sopenharmony_ci .hw_free = mt8183_da7219_hw_free, 16862306a36Sopenharmony_ci}; 16962306a36Sopenharmony_ci 17062306a36Sopenharmony_cistatic int mt8183_i2s_hw_params_fixup(struct snd_soc_pcm_runtime *rtd, 17162306a36Sopenharmony_ci struct snd_pcm_hw_params *params) 17262306a36Sopenharmony_ci{ 17362306a36Sopenharmony_ci /* fix BE i2s format to S32_LE, clean param mask first */ 17462306a36Sopenharmony_ci snd_mask_reset_range(hw_param_mask(params, SNDRV_PCM_HW_PARAM_FORMAT), 17562306a36Sopenharmony_ci 0, (__force unsigned int)SNDRV_PCM_FORMAT_LAST); 17662306a36Sopenharmony_ci 17762306a36Sopenharmony_ci params_set_format(params, SNDRV_PCM_FORMAT_S32_LE); 17862306a36Sopenharmony_ci 17962306a36Sopenharmony_ci return 0; 18062306a36Sopenharmony_ci} 18162306a36Sopenharmony_ci 18262306a36Sopenharmony_cistatic int mt8183_rt1015_i2s_hw_params_fixup(struct snd_soc_pcm_runtime *rtd, 18362306a36Sopenharmony_ci struct snd_pcm_hw_params *params) 18462306a36Sopenharmony_ci{ 18562306a36Sopenharmony_ci /* fix BE i2s format to S24_LE, clean param mask first */ 18662306a36Sopenharmony_ci snd_mask_reset_range(hw_param_mask(params, SNDRV_PCM_HW_PARAM_FORMAT), 18762306a36Sopenharmony_ci 0, (__force unsigned int)SNDRV_PCM_FORMAT_LAST); 18862306a36Sopenharmony_ci 18962306a36Sopenharmony_ci params_set_format(params, SNDRV_PCM_FORMAT_S24_LE); 19062306a36Sopenharmony_ci 19162306a36Sopenharmony_ci return 0; 19262306a36Sopenharmony_ci} 19362306a36Sopenharmony_ci 19462306a36Sopenharmony_cistatic int 19562306a36Sopenharmony_cimt8183_da7219_max98357_startup( 19662306a36Sopenharmony_ci struct snd_pcm_substream *substream) 19762306a36Sopenharmony_ci{ 19862306a36Sopenharmony_ci static const unsigned int rates[] = { 19962306a36Sopenharmony_ci 48000, 20062306a36Sopenharmony_ci }; 20162306a36Sopenharmony_ci static const struct snd_pcm_hw_constraint_list constraints_rates = { 20262306a36Sopenharmony_ci .count = ARRAY_SIZE(rates), 20362306a36Sopenharmony_ci .list = rates, 20462306a36Sopenharmony_ci .mask = 0, 20562306a36Sopenharmony_ci }; 20662306a36Sopenharmony_ci static const unsigned int channels[] = { 20762306a36Sopenharmony_ci 2, 20862306a36Sopenharmony_ci }; 20962306a36Sopenharmony_ci static const struct snd_pcm_hw_constraint_list constraints_channels = { 21062306a36Sopenharmony_ci .count = ARRAY_SIZE(channels), 21162306a36Sopenharmony_ci .list = channels, 21262306a36Sopenharmony_ci .mask = 0, 21362306a36Sopenharmony_ci }; 21462306a36Sopenharmony_ci 21562306a36Sopenharmony_ci struct snd_pcm_runtime *runtime = substream->runtime; 21662306a36Sopenharmony_ci 21762306a36Sopenharmony_ci snd_pcm_hw_constraint_list(runtime, 0, 21862306a36Sopenharmony_ci SNDRV_PCM_HW_PARAM_RATE, &constraints_rates); 21962306a36Sopenharmony_ci runtime->hw.channels_max = 2; 22062306a36Sopenharmony_ci snd_pcm_hw_constraint_list(runtime, 0, 22162306a36Sopenharmony_ci SNDRV_PCM_HW_PARAM_CHANNELS, 22262306a36Sopenharmony_ci &constraints_channels); 22362306a36Sopenharmony_ci 22462306a36Sopenharmony_ci runtime->hw.formats = SNDRV_PCM_FMTBIT_S16_LE; 22562306a36Sopenharmony_ci snd_pcm_hw_constraint_msbits(runtime, 0, 16, 16); 22662306a36Sopenharmony_ci 22762306a36Sopenharmony_ci return 0; 22862306a36Sopenharmony_ci} 22962306a36Sopenharmony_ci 23062306a36Sopenharmony_cistatic const struct snd_soc_ops mt8183_da7219_max98357_ops = { 23162306a36Sopenharmony_ci .startup = mt8183_da7219_max98357_startup, 23262306a36Sopenharmony_ci}; 23362306a36Sopenharmony_ci 23462306a36Sopenharmony_cistatic int 23562306a36Sopenharmony_cimt8183_da7219_max98357_bt_sco_startup( 23662306a36Sopenharmony_ci struct snd_pcm_substream *substream) 23762306a36Sopenharmony_ci{ 23862306a36Sopenharmony_ci static const unsigned int rates[] = { 23962306a36Sopenharmony_ci 8000, 16000 24062306a36Sopenharmony_ci }; 24162306a36Sopenharmony_ci static const struct snd_pcm_hw_constraint_list constraints_rates = { 24262306a36Sopenharmony_ci .count = ARRAY_SIZE(rates), 24362306a36Sopenharmony_ci .list = rates, 24462306a36Sopenharmony_ci .mask = 0, 24562306a36Sopenharmony_ci }; 24662306a36Sopenharmony_ci static const unsigned int channels[] = { 24762306a36Sopenharmony_ci 1, 24862306a36Sopenharmony_ci }; 24962306a36Sopenharmony_ci static const struct snd_pcm_hw_constraint_list constraints_channels = { 25062306a36Sopenharmony_ci .count = ARRAY_SIZE(channels), 25162306a36Sopenharmony_ci .list = channels, 25262306a36Sopenharmony_ci .mask = 0, 25362306a36Sopenharmony_ci }; 25462306a36Sopenharmony_ci 25562306a36Sopenharmony_ci struct snd_pcm_runtime *runtime = substream->runtime; 25662306a36Sopenharmony_ci 25762306a36Sopenharmony_ci snd_pcm_hw_constraint_list(runtime, 0, 25862306a36Sopenharmony_ci SNDRV_PCM_HW_PARAM_RATE, &constraints_rates); 25962306a36Sopenharmony_ci runtime->hw.channels_max = 1; 26062306a36Sopenharmony_ci snd_pcm_hw_constraint_list(runtime, 0, 26162306a36Sopenharmony_ci SNDRV_PCM_HW_PARAM_CHANNELS, 26262306a36Sopenharmony_ci &constraints_channels); 26362306a36Sopenharmony_ci 26462306a36Sopenharmony_ci runtime->hw.formats = SNDRV_PCM_FMTBIT_S16_LE; 26562306a36Sopenharmony_ci snd_pcm_hw_constraint_msbits(runtime, 0, 16, 16); 26662306a36Sopenharmony_ci 26762306a36Sopenharmony_ci return 0; 26862306a36Sopenharmony_ci} 26962306a36Sopenharmony_ci 27062306a36Sopenharmony_cistatic const struct snd_soc_ops mt8183_da7219_max98357_bt_sco_ops = { 27162306a36Sopenharmony_ci .startup = mt8183_da7219_max98357_bt_sco_startup, 27262306a36Sopenharmony_ci}; 27362306a36Sopenharmony_ci 27462306a36Sopenharmony_ci/* FE */ 27562306a36Sopenharmony_ciSND_SOC_DAILINK_DEFS(playback1, 27662306a36Sopenharmony_ci DAILINK_COMP_ARRAY(COMP_CPU("DL1")), 27762306a36Sopenharmony_ci DAILINK_COMP_ARRAY(COMP_DUMMY()), 27862306a36Sopenharmony_ci DAILINK_COMP_ARRAY(COMP_EMPTY())); 27962306a36Sopenharmony_ci 28062306a36Sopenharmony_ciSND_SOC_DAILINK_DEFS(playback2, 28162306a36Sopenharmony_ci DAILINK_COMP_ARRAY(COMP_CPU("DL2")), 28262306a36Sopenharmony_ci DAILINK_COMP_ARRAY(COMP_DUMMY()), 28362306a36Sopenharmony_ci DAILINK_COMP_ARRAY(COMP_EMPTY())); 28462306a36Sopenharmony_ci 28562306a36Sopenharmony_ciSND_SOC_DAILINK_DEFS(playback3, 28662306a36Sopenharmony_ci DAILINK_COMP_ARRAY(COMP_CPU("DL3")), 28762306a36Sopenharmony_ci DAILINK_COMP_ARRAY(COMP_DUMMY()), 28862306a36Sopenharmony_ci DAILINK_COMP_ARRAY(COMP_EMPTY())); 28962306a36Sopenharmony_ci 29062306a36Sopenharmony_ciSND_SOC_DAILINK_DEFS(capture1, 29162306a36Sopenharmony_ci DAILINK_COMP_ARRAY(COMP_CPU("UL1")), 29262306a36Sopenharmony_ci DAILINK_COMP_ARRAY(COMP_DUMMY()), 29362306a36Sopenharmony_ci DAILINK_COMP_ARRAY(COMP_EMPTY())); 29462306a36Sopenharmony_ci 29562306a36Sopenharmony_ciSND_SOC_DAILINK_DEFS(capture2, 29662306a36Sopenharmony_ci DAILINK_COMP_ARRAY(COMP_CPU("UL2")), 29762306a36Sopenharmony_ci DAILINK_COMP_ARRAY(COMP_DUMMY()), 29862306a36Sopenharmony_ci DAILINK_COMP_ARRAY(COMP_EMPTY())); 29962306a36Sopenharmony_ci 30062306a36Sopenharmony_ciSND_SOC_DAILINK_DEFS(capture3, 30162306a36Sopenharmony_ci DAILINK_COMP_ARRAY(COMP_CPU("UL3")), 30262306a36Sopenharmony_ci DAILINK_COMP_ARRAY(COMP_DUMMY()), 30362306a36Sopenharmony_ci DAILINK_COMP_ARRAY(COMP_EMPTY())); 30462306a36Sopenharmony_ci 30562306a36Sopenharmony_ciSND_SOC_DAILINK_DEFS(capture_mono, 30662306a36Sopenharmony_ci DAILINK_COMP_ARRAY(COMP_CPU("UL_MONO_1")), 30762306a36Sopenharmony_ci DAILINK_COMP_ARRAY(COMP_DUMMY()), 30862306a36Sopenharmony_ci DAILINK_COMP_ARRAY(COMP_EMPTY())); 30962306a36Sopenharmony_ci 31062306a36Sopenharmony_ciSND_SOC_DAILINK_DEFS(playback_hdmi, 31162306a36Sopenharmony_ci DAILINK_COMP_ARRAY(COMP_CPU("HDMI")), 31262306a36Sopenharmony_ci DAILINK_COMP_ARRAY(COMP_DUMMY()), 31362306a36Sopenharmony_ci DAILINK_COMP_ARRAY(COMP_EMPTY())); 31462306a36Sopenharmony_ci 31562306a36Sopenharmony_ci/* BE */ 31662306a36Sopenharmony_ciSND_SOC_DAILINK_DEFS(primary_codec, 31762306a36Sopenharmony_ci DAILINK_COMP_ARRAY(COMP_CPU("ADDA")), 31862306a36Sopenharmony_ci DAILINK_COMP_ARRAY(COMP_CODEC("mt6358-sound", "mt6358-snd-codec-aif1")), 31962306a36Sopenharmony_ci DAILINK_COMP_ARRAY(COMP_EMPTY())); 32062306a36Sopenharmony_ci 32162306a36Sopenharmony_ciSND_SOC_DAILINK_DEFS(pcm1, 32262306a36Sopenharmony_ci DAILINK_COMP_ARRAY(COMP_CPU("PCM 1")), 32362306a36Sopenharmony_ci DAILINK_COMP_ARRAY(COMP_DUMMY()), 32462306a36Sopenharmony_ci DAILINK_COMP_ARRAY(COMP_EMPTY())); 32562306a36Sopenharmony_ci 32662306a36Sopenharmony_ciSND_SOC_DAILINK_DEFS(pcm2, 32762306a36Sopenharmony_ci DAILINK_COMP_ARRAY(COMP_CPU("PCM 2")), 32862306a36Sopenharmony_ci DAILINK_COMP_ARRAY(COMP_DUMMY()), 32962306a36Sopenharmony_ci DAILINK_COMP_ARRAY(COMP_EMPTY())); 33062306a36Sopenharmony_ci 33162306a36Sopenharmony_ciSND_SOC_DAILINK_DEFS(i2s0, 33262306a36Sopenharmony_ci DAILINK_COMP_ARRAY(COMP_CPU("I2S0")), 33362306a36Sopenharmony_ci DAILINK_COMP_ARRAY(COMP_CODEC("bt-sco", "bt-sco-pcm")), 33462306a36Sopenharmony_ci DAILINK_COMP_ARRAY(COMP_EMPTY())); 33562306a36Sopenharmony_ci 33662306a36Sopenharmony_ciSND_SOC_DAILINK_DEFS(i2s1, 33762306a36Sopenharmony_ci DAILINK_COMP_ARRAY(COMP_CPU("I2S1")), 33862306a36Sopenharmony_ci DAILINK_COMP_ARRAY(COMP_DUMMY()), 33962306a36Sopenharmony_ci DAILINK_COMP_ARRAY(COMP_EMPTY())); 34062306a36Sopenharmony_ci 34162306a36Sopenharmony_ciSND_SOC_DAILINK_DEFS(i2s2, 34262306a36Sopenharmony_ci DAILINK_COMP_ARRAY(COMP_CPU("I2S2")), 34362306a36Sopenharmony_ci DAILINK_COMP_ARRAY(COMP_CODEC(DA7219_DEV_NAME, DA7219_CODEC_DAI)), 34462306a36Sopenharmony_ci DAILINK_COMP_ARRAY(COMP_EMPTY())); 34562306a36Sopenharmony_ci 34662306a36Sopenharmony_ciSND_SOC_DAILINK_DEFS(i2s3_max98357a, 34762306a36Sopenharmony_ci DAILINK_COMP_ARRAY(COMP_CPU("I2S3")), 34862306a36Sopenharmony_ci DAILINK_COMP_ARRAY(COMP_CODEC("max98357a", "HiFi"), 34962306a36Sopenharmony_ci COMP_CODEC(DA7219_DEV_NAME, DA7219_CODEC_DAI)), 35062306a36Sopenharmony_ci DAILINK_COMP_ARRAY(COMP_EMPTY())); 35162306a36Sopenharmony_ci 35262306a36Sopenharmony_ciSND_SOC_DAILINK_DEFS(i2s3_rt1015, 35362306a36Sopenharmony_ci DAILINK_COMP_ARRAY(COMP_CPU("I2S3")), 35462306a36Sopenharmony_ci DAILINK_COMP_ARRAY(COMP_CODEC(RT1015_DEV0_NAME, RT1015_CODEC_DAI), 35562306a36Sopenharmony_ci COMP_CODEC(RT1015_DEV1_NAME, RT1015_CODEC_DAI), 35662306a36Sopenharmony_ci COMP_CODEC(DA7219_DEV_NAME, DA7219_CODEC_DAI)), 35762306a36Sopenharmony_ci DAILINK_COMP_ARRAY(COMP_EMPTY())); 35862306a36Sopenharmony_ci 35962306a36Sopenharmony_ciSND_SOC_DAILINK_DEFS(i2s3_rt1015p, 36062306a36Sopenharmony_ci DAILINK_COMP_ARRAY(COMP_CPU("I2S3")), 36162306a36Sopenharmony_ci DAILINK_COMP_ARRAY(COMP_CODEC("rt1015p", "HiFi"), 36262306a36Sopenharmony_ci COMP_CODEC(DA7219_DEV_NAME, DA7219_CODEC_DAI)), 36362306a36Sopenharmony_ci DAILINK_COMP_ARRAY(COMP_EMPTY())); 36462306a36Sopenharmony_ci 36562306a36Sopenharmony_ciSND_SOC_DAILINK_DEFS(i2s5, 36662306a36Sopenharmony_ci DAILINK_COMP_ARRAY(COMP_CPU("I2S5")), 36762306a36Sopenharmony_ci DAILINK_COMP_ARRAY(COMP_CODEC("bt-sco", "bt-sco-pcm")), 36862306a36Sopenharmony_ci DAILINK_COMP_ARRAY(COMP_EMPTY())); 36962306a36Sopenharmony_ci 37062306a36Sopenharmony_ciSND_SOC_DAILINK_DEFS(tdm, 37162306a36Sopenharmony_ci DAILINK_COMP_ARRAY(COMP_CPU("TDM")), 37262306a36Sopenharmony_ci DAILINK_COMP_ARRAY(COMP_CODEC(NULL, "i2s-hifi")), 37362306a36Sopenharmony_ci DAILINK_COMP_ARRAY(COMP_EMPTY())); 37462306a36Sopenharmony_ci 37562306a36Sopenharmony_cistatic int mt8183_da7219_max98357_hdmi_init(struct snd_soc_pcm_runtime *rtd) 37662306a36Sopenharmony_ci{ 37762306a36Sopenharmony_ci struct mt8183_da7219_max98357_priv *priv = 37862306a36Sopenharmony_ci snd_soc_card_get_drvdata(rtd->card); 37962306a36Sopenharmony_ci int ret; 38062306a36Sopenharmony_ci 38162306a36Sopenharmony_ci ret = snd_soc_card_jack_new(rtd->card, "HDMI Jack", SND_JACK_LINEOUT, 38262306a36Sopenharmony_ci &priv->hdmi_jack); 38362306a36Sopenharmony_ci if (ret) 38462306a36Sopenharmony_ci return ret; 38562306a36Sopenharmony_ci 38662306a36Sopenharmony_ci return snd_soc_component_set_jack(asoc_rtd_to_codec(rtd, 0)->component, 38762306a36Sopenharmony_ci &priv->hdmi_jack, NULL); 38862306a36Sopenharmony_ci} 38962306a36Sopenharmony_ci 39062306a36Sopenharmony_cistatic int mt8183_bt_init(struct snd_soc_pcm_runtime *rtd) 39162306a36Sopenharmony_ci{ 39262306a36Sopenharmony_ci struct snd_soc_component *cmpnt_afe = 39362306a36Sopenharmony_ci snd_soc_rtdcom_lookup(rtd, AFE_PCM_NAME); 39462306a36Sopenharmony_ci struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt_afe); 39562306a36Sopenharmony_ci int ret; 39662306a36Sopenharmony_ci 39762306a36Sopenharmony_ci ret = mt8183_dai_i2s_set_share(afe, "I2S5", "I2S0"); 39862306a36Sopenharmony_ci if (ret) { 39962306a36Sopenharmony_ci dev_err(rtd->dev, "Failed to set up shared clocks\n"); 40062306a36Sopenharmony_ci return ret; 40162306a36Sopenharmony_ci } 40262306a36Sopenharmony_ci return 0; 40362306a36Sopenharmony_ci} 40462306a36Sopenharmony_ci 40562306a36Sopenharmony_cistatic int mt8183_da7219_init(struct snd_soc_pcm_runtime *rtd) 40662306a36Sopenharmony_ci{ 40762306a36Sopenharmony_ci struct snd_soc_component *cmpnt_afe = 40862306a36Sopenharmony_ci snd_soc_rtdcom_lookup(rtd, AFE_PCM_NAME); 40962306a36Sopenharmony_ci struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt_afe); 41062306a36Sopenharmony_ci int ret; 41162306a36Sopenharmony_ci 41262306a36Sopenharmony_ci ret = mt8183_dai_i2s_set_share(afe, "I2S2", "I2S3"); 41362306a36Sopenharmony_ci if (ret) { 41462306a36Sopenharmony_ci dev_err(rtd->dev, "Failed to set up shared clocks\n"); 41562306a36Sopenharmony_ci return ret; 41662306a36Sopenharmony_ci } 41762306a36Sopenharmony_ci return 0; 41862306a36Sopenharmony_ci} 41962306a36Sopenharmony_ci 42062306a36Sopenharmony_cistatic struct snd_soc_dai_link mt8183_da7219_dai_links[] = { 42162306a36Sopenharmony_ci /* FE */ 42262306a36Sopenharmony_ci { 42362306a36Sopenharmony_ci .name = "Playback_1", 42462306a36Sopenharmony_ci .stream_name = "Playback_1", 42562306a36Sopenharmony_ci .trigger = {SND_SOC_DPCM_TRIGGER_PRE, 42662306a36Sopenharmony_ci SND_SOC_DPCM_TRIGGER_PRE}, 42762306a36Sopenharmony_ci .dynamic = 1, 42862306a36Sopenharmony_ci .dpcm_playback = 1, 42962306a36Sopenharmony_ci .ops = &mt8183_da7219_max98357_ops, 43062306a36Sopenharmony_ci SND_SOC_DAILINK_REG(playback1), 43162306a36Sopenharmony_ci }, 43262306a36Sopenharmony_ci { 43362306a36Sopenharmony_ci .name = "Playback_2", 43462306a36Sopenharmony_ci .stream_name = "Playback_2", 43562306a36Sopenharmony_ci .trigger = {SND_SOC_DPCM_TRIGGER_PRE, 43662306a36Sopenharmony_ci SND_SOC_DPCM_TRIGGER_PRE}, 43762306a36Sopenharmony_ci .dynamic = 1, 43862306a36Sopenharmony_ci .dpcm_playback = 1, 43962306a36Sopenharmony_ci .ops = &mt8183_da7219_max98357_bt_sco_ops, 44062306a36Sopenharmony_ci SND_SOC_DAILINK_REG(playback2), 44162306a36Sopenharmony_ci }, 44262306a36Sopenharmony_ci { 44362306a36Sopenharmony_ci .name = "Playback_3", 44462306a36Sopenharmony_ci .stream_name = "Playback_3", 44562306a36Sopenharmony_ci .trigger = {SND_SOC_DPCM_TRIGGER_PRE, 44662306a36Sopenharmony_ci SND_SOC_DPCM_TRIGGER_PRE}, 44762306a36Sopenharmony_ci .dynamic = 1, 44862306a36Sopenharmony_ci .dpcm_playback = 1, 44962306a36Sopenharmony_ci SND_SOC_DAILINK_REG(playback3), 45062306a36Sopenharmony_ci }, 45162306a36Sopenharmony_ci { 45262306a36Sopenharmony_ci .name = "Capture_1", 45362306a36Sopenharmony_ci .stream_name = "Capture_1", 45462306a36Sopenharmony_ci .trigger = {SND_SOC_DPCM_TRIGGER_PRE, 45562306a36Sopenharmony_ci SND_SOC_DPCM_TRIGGER_PRE}, 45662306a36Sopenharmony_ci .dynamic = 1, 45762306a36Sopenharmony_ci .dpcm_capture = 1, 45862306a36Sopenharmony_ci .ops = &mt8183_da7219_max98357_bt_sco_ops, 45962306a36Sopenharmony_ci SND_SOC_DAILINK_REG(capture1), 46062306a36Sopenharmony_ci }, 46162306a36Sopenharmony_ci { 46262306a36Sopenharmony_ci .name = "Capture_2", 46362306a36Sopenharmony_ci .stream_name = "Capture_2", 46462306a36Sopenharmony_ci .trigger = {SND_SOC_DPCM_TRIGGER_PRE, 46562306a36Sopenharmony_ci SND_SOC_DPCM_TRIGGER_PRE}, 46662306a36Sopenharmony_ci .dynamic = 1, 46762306a36Sopenharmony_ci .dpcm_capture = 1, 46862306a36Sopenharmony_ci SND_SOC_DAILINK_REG(capture2), 46962306a36Sopenharmony_ci }, 47062306a36Sopenharmony_ci { 47162306a36Sopenharmony_ci .name = "Capture_3", 47262306a36Sopenharmony_ci .stream_name = "Capture_3", 47362306a36Sopenharmony_ci .trigger = {SND_SOC_DPCM_TRIGGER_PRE, 47462306a36Sopenharmony_ci SND_SOC_DPCM_TRIGGER_PRE}, 47562306a36Sopenharmony_ci .dynamic = 1, 47662306a36Sopenharmony_ci .dpcm_capture = 1, 47762306a36Sopenharmony_ci .ops = &mt8183_da7219_max98357_ops, 47862306a36Sopenharmony_ci SND_SOC_DAILINK_REG(capture3), 47962306a36Sopenharmony_ci }, 48062306a36Sopenharmony_ci { 48162306a36Sopenharmony_ci .name = "Capture_Mono_1", 48262306a36Sopenharmony_ci .stream_name = "Capture_Mono_1", 48362306a36Sopenharmony_ci .trigger = {SND_SOC_DPCM_TRIGGER_PRE, 48462306a36Sopenharmony_ci SND_SOC_DPCM_TRIGGER_PRE}, 48562306a36Sopenharmony_ci .dynamic = 1, 48662306a36Sopenharmony_ci .dpcm_capture = 1, 48762306a36Sopenharmony_ci SND_SOC_DAILINK_REG(capture_mono), 48862306a36Sopenharmony_ci }, 48962306a36Sopenharmony_ci { 49062306a36Sopenharmony_ci .name = "Playback_HDMI", 49162306a36Sopenharmony_ci .stream_name = "Playback_HDMI", 49262306a36Sopenharmony_ci .trigger = {SND_SOC_DPCM_TRIGGER_PRE, 49362306a36Sopenharmony_ci SND_SOC_DPCM_TRIGGER_PRE}, 49462306a36Sopenharmony_ci .dynamic = 1, 49562306a36Sopenharmony_ci .dpcm_playback = 1, 49662306a36Sopenharmony_ci SND_SOC_DAILINK_REG(playback_hdmi), 49762306a36Sopenharmony_ci }, 49862306a36Sopenharmony_ci /* BE */ 49962306a36Sopenharmony_ci { 50062306a36Sopenharmony_ci .name = "Primary Codec", 50162306a36Sopenharmony_ci .no_pcm = 1, 50262306a36Sopenharmony_ci .dpcm_playback = 1, 50362306a36Sopenharmony_ci .dpcm_capture = 1, 50462306a36Sopenharmony_ci .ignore_suspend = 1, 50562306a36Sopenharmony_ci SND_SOC_DAILINK_REG(primary_codec), 50662306a36Sopenharmony_ci }, 50762306a36Sopenharmony_ci { 50862306a36Sopenharmony_ci .name = "PCM 1", 50962306a36Sopenharmony_ci .no_pcm = 1, 51062306a36Sopenharmony_ci .dpcm_playback = 1, 51162306a36Sopenharmony_ci .dpcm_capture = 1, 51262306a36Sopenharmony_ci .ignore_suspend = 1, 51362306a36Sopenharmony_ci SND_SOC_DAILINK_REG(pcm1), 51462306a36Sopenharmony_ci }, 51562306a36Sopenharmony_ci { 51662306a36Sopenharmony_ci .name = "PCM 2", 51762306a36Sopenharmony_ci .no_pcm = 1, 51862306a36Sopenharmony_ci .dpcm_playback = 1, 51962306a36Sopenharmony_ci .dpcm_capture = 1, 52062306a36Sopenharmony_ci .ignore_suspend = 1, 52162306a36Sopenharmony_ci SND_SOC_DAILINK_REG(pcm2), 52262306a36Sopenharmony_ci }, 52362306a36Sopenharmony_ci { 52462306a36Sopenharmony_ci .name = "I2S0", 52562306a36Sopenharmony_ci .no_pcm = 1, 52662306a36Sopenharmony_ci .dpcm_capture = 1, 52762306a36Sopenharmony_ci .ignore_suspend = 1, 52862306a36Sopenharmony_ci .be_hw_params_fixup = mt8183_i2s_hw_params_fixup, 52962306a36Sopenharmony_ci .ops = &mt8183_mt6358_i2s_ops, 53062306a36Sopenharmony_ci SND_SOC_DAILINK_REG(i2s0), 53162306a36Sopenharmony_ci }, 53262306a36Sopenharmony_ci { 53362306a36Sopenharmony_ci .name = "I2S1", 53462306a36Sopenharmony_ci .no_pcm = 1, 53562306a36Sopenharmony_ci .dpcm_playback = 1, 53662306a36Sopenharmony_ci .ignore_suspend = 1, 53762306a36Sopenharmony_ci .be_hw_params_fixup = mt8183_i2s_hw_params_fixup, 53862306a36Sopenharmony_ci .ops = &mt8183_mt6358_i2s_ops, 53962306a36Sopenharmony_ci SND_SOC_DAILINK_REG(i2s1), 54062306a36Sopenharmony_ci }, 54162306a36Sopenharmony_ci { 54262306a36Sopenharmony_ci .name = "I2S2", 54362306a36Sopenharmony_ci .no_pcm = 1, 54462306a36Sopenharmony_ci .dpcm_capture = 1, 54562306a36Sopenharmony_ci .ignore_suspend = 1, 54662306a36Sopenharmony_ci .be_hw_params_fixup = mt8183_i2s_hw_params_fixup, 54762306a36Sopenharmony_ci .ops = &mt8183_da7219_i2s_ops, 54862306a36Sopenharmony_ci .init = &mt8183_da7219_init, 54962306a36Sopenharmony_ci SND_SOC_DAILINK_REG(i2s2), 55062306a36Sopenharmony_ci }, 55162306a36Sopenharmony_ci { 55262306a36Sopenharmony_ci .name = "I2S3", 55362306a36Sopenharmony_ci .no_pcm = 1, 55462306a36Sopenharmony_ci .dpcm_playback = 1, 55562306a36Sopenharmony_ci .ignore_suspend = 1, 55662306a36Sopenharmony_ci }, 55762306a36Sopenharmony_ci { 55862306a36Sopenharmony_ci .name = "I2S5", 55962306a36Sopenharmony_ci .no_pcm = 1, 56062306a36Sopenharmony_ci .dpcm_playback = 1, 56162306a36Sopenharmony_ci .ignore_suspend = 1, 56262306a36Sopenharmony_ci .be_hw_params_fixup = mt8183_i2s_hw_params_fixup, 56362306a36Sopenharmony_ci .ops = &mt8183_mt6358_i2s_ops, 56462306a36Sopenharmony_ci .init = &mt8183_bt_init, 56562306a36Sopenharmony_ci SND_SOC_DAILINK_REG(i2s5), 56662306a36Sopenharmony_ci }, 56762306a36Sopenharmony_ci { 56862306a36Sopenharmony_ci .name = "TDM", 56962306a36Sopenharmony_ci .no_pcm = 1, 57062306a36Sopenharmony_ci .dai_fmt = SND_SOC_DAIFMT_I2S | 57162306a36Sopenharmony_ci SND_SOC_DAIFMT_IB_IF | 57262306a36Sopenharmony_ci SND_SOC_DAIFMT_CBM_CFM, 57362306a36Sopenharmony_ci .dpcm_playback = 1, 57462306a36Sopenharmony_ci .ignore_suspend = 1, 57562306a36Sopenharmony_ci .be_hw_params_fixup = mt8183_i2s_hw_params_fixup, 57662306a36Sopenharmony_ci .ignore = 1, 57762306a36Sopenharmony_ci .init = mt8183_da7219_max98357_hdmi_init, 57862306a36Sopenharmony_ci SND_SOC_DAILINK_REG(tdm), 57962306a36Sopenharmony_ci }, 58062306a36Sopenharmony_ci}; 58162306a36Sopenharmony_ci 58262306a36Sopenharmony_cistatic int 58362306a36Sopenharmony_cimt8183_da7219_max98357_headset_init(struct snd_soc_component *component) 58462306a36Sopenharmony_ci{ 58562306a36Sopenharmony_ci int ret; 58662306a36Sopenharmony_ci struct mt8183_da7219_max98357_priv *priv = 58762306a36Sopenharmony_ci snd_soc_card_get_drvdata(component->card); 58862306a36Sopenharmony_ci 58962306a36Sopenharmony_ci /* Enable Headset and 4 Buttons Jack detection */ 59062306a36Sopenharmony_ci ret = snd_soc_card_jack_new_pins(component->card, 59162306a36Sopenharmony_ci "Headset Jack", 59262306a36Sopenharmony_ci SND_JACK_HEADSET | 59362306a36Sopenharmony_ci SND_JACK_BTN_0 | SND_JACK_BTN_1 | 59462306a36Sopenharmony_ci SND_JACK_BTN_2 | SND_JACK_BTN_3 | 59562306a36Sopenharmony_ci SND_JACK_LINEOUT, 59662306a36Sopenharmony_ci &priv->headset_jack, 59762306a36Sopenharmony_ci mt8183_da7219_max98357_jack_pins, 59862306a36Sopenharmony_ci ARRAY_SIZE(mt8183_da7219_max98357_jack_pins)); 59962306a36Sopenharmony_ci if (ret) 60062306a36Sopenharmony_ci return ret; 60162306a36Sopenharmony_ci 60262306a36Sopenharmony_ci snd_jack_set_key( 60362306a36Sopenharmony_ci priv->headset_jack.jack, SND_JACK_BTN_0, KEY_PLAYPAUSE); 60462306a36Sopenharmony_ci snd_jack_set_key( 60562306a36Sopenharmony_ci priv->headset_jack.jack, SND_JACK_BTN_1, KEY_VOLUMEUP); 60662306a36Sopenharmony_ci snd_jack_set_key( 60762306a36Sopenharmony_ci priv->headset_jack.jack, SND_JACK_BTN_2, KEY_VOLUMEDOWN); 60862306a36Sopenharmony_ci snd_jack_set_key( 60962306a36Sopenharmony_ci priv->headset_jack.jack, SND_JACK_BTN_3, KEY_VOICECOMMAND); 61062306a36Sopenharmony_ci 61162306a36Sopenharmony_ci snd_soc_component_set_jack(component, &priv->headset_jack, NULL); 61262306a36Sopenharmony_ci 61362306a36Sopenharmony_ci return 0; 61462306a36Sopenharmony_ci} 61562306a36Sopenharmony_ci 61662306a36Sopenharmony_cistatic struct snd_soc_aux_dev mt8183_da7219_max98357_headset_dev = { 61762306a36Sopenharmony_ci .dlc = COMP_EMPTY(), 61862306a36Sopenharmony_ci .init = mt8183_da7219_max98357_headset_init, 61962306a36Sopenharmony_ci}; 62062306a36Sopenharmony_ci 62162306a36Sopenharmony_cistatic struct snd_soc_codec_conf mt6358_codec_conf[] = { 62262306a36Sopenharmony_ci { 62362306a36Sopenharmony_ci .dlc = COMP_CODEC_CONF("mt6358-sound"), 62462306a36Sopenharmony_ci .name_prefix = "Mt6358", 62562306a36Sopenharmony_ci }, 62662306a36Sopenharmony_ci}; 62762306a36Sopenharmony_ci 62862306a36Sopenharmony_cistatic const struct snd_kcontrol_new mt8183_da7219_max98357_snd_controls[] = { 62962306a36Sopenharmony_ci SOC_DAPM_PIN_SWITCH("Headphone"), 63062306a36Sopenharmony_ci SOC_DAPM_PIN_SWITCH("Headset Mic"), 63162306a36Sopenharmony_ci SOC_DAPM_PIN_SWITCH("Speakers"), 63262306a36Sopenharmony_ci SOC_DAPM_PIN_SWITCH("Line Out"), 63362306a36Sopenharmony_ci}; 63462306a36Sopenharmony_ci 63562306a36Sopenharmony_cistatic const 63662306a36Sopenharmony_cistruct snd_soc_dapm_widget mt8183_da7219_max98357_dapm_widgets[] = { 63762306a36Sopenharmony_ci SND_SOC_DAPM_HP("Headphone", NULL), 63862306a36Sopenharmony_ci SND_SOC_DAPM_MIC("Headset Mic", NULL), 63962306a36Sopenharmony_ci SND_SOC_DAPM_SPK("Speakers", NULL), 64062306a36Sopenharmony_ci SND_SOC_DAPM_SPK("Line Out", NULL), 64162306a36Sopenharmony_ci SND_SOC_DAPM_PINCTRL("TDM_OUT_PINCTRL", 64262306a36Sopenharmony_ci "aud_tdm_out_on", "aud_tdm_out_off"), 64362306a36Sopenharmony_ci}; 64462306a36Sopenharmony_ci 64562306a36Sopenharmony_cistatic const struct snd_soc_dapm_route mt8183_da7219_max98357_dapm_routes[] = { 64662306a36Sopenharmony_ci {"Speakers", NULL, "Speaker"}, 64762306a36Sopenharmony_ci {"I2S Playback", NULL, "TDM_OUT_PINCTRL"}, 64862306a36Sopenharmony_ci}; 64962306a36Sopenharmony_ci 65062306a36Sopenharmony_cistatic struct snd_soc_card mt8183_da7219_max98357_card = { 65162306a36Sopenharmony_ci .name = "mt8183_da7219_max98357", 65262306a36Sopenharmony_ci .owner = THIS_MODULE, 65362306a36Sopenharmony_ci .controls = mt8183_da7219_max98357_snd_controls, 65462306a36Sopenharmony_ci .num_controls = ARRAY_SIZE(mt8183_da7219_max98357_snd_controls), 65562306a36Sopenharmony_ci .dapm_widgets = mt8183_da7219_max98357_dapm_widgets, 65662306a36Sopenharmony_ci .num_dapm_widgets = ARRAY_SIZE(mt8183_da7219_max98357_dapm_widgets), 65762306a36Sopenharmony_ci .dapm_routes = mt8183_da7219_max98357_dapm_routes, 65862306a36Sopenharmony_ci .num_dapm_routes = ARRAY_SIZE(mt8183_da7219_max98357_dapm_routes), 65962306a36Sopenharmony_ci .dai_link = mt8183_da7219_dai_links, 66062306a36Sopenharmony_ci .num_links = ARRAY_SIZE(mt8183_da7219_dai_links), 66162306a36Sopenharmony_ci .aux_dev = &mt8183_da7219_max98357_headset_dev, 66262306a36Sopenharmony_ci .num_aux_devs = 1, 66362306a36Sopenharmony_ci .codec_conf = mt6358_codec_conf, 66462306a36Sopenharmony_ci .num_configs = ARRAY_SIZE(mt6358_codec_conf), 66562306a36Sopenharmony_ci}; 66662306a36Sopenharmony_ci 66762306a36Sopenharmony_cistatic struct snd_soc_codec_conf mt8183_da7219_rt1015_codec_conf[] = { 66862306a36Sopenharmony_ci { 66962306a36Sopenharmony_ci .dlc = COMP_CODEC_CONF("mt6358-sound"), 67062306a36Sopenharmony_ci .name_prefix = "Mt6358", 67162306a36Sopenharmony_ci }, 67262306a36Sopenharmony_ci { 67362306a36Sopenharmony_ci .dlc = COMP_CODEC_CONF(RT1015_DEV0_NAME), 67462306a36Sopenharmony_ci .name_prefix = "Left", 67562306a36Sopenharmony_ci }, 67662306a36Sopenharmony_ci { 67762306a36Sopenharmony_ci .dlc = COMP_CODEC_CONF(RT1015_DEV1_NAME), 67862306a36Sopenharmony_ci .name_prefix = "Right", 67962306a36Sopenharmony_ci }, 68062306a36Sopenharmony_ci}; 68162306a36Sopenharmony_ci 68262306a36Sopenharmony_cistatic const struct snd_kcontrol_new mt8183_da7219_rt1015_snd_controls[] = { 68362306a36Sopenharmony_ci SOC_DAPM_PIN_SWITCH("Headphone"), 68462306a36Sopenharmony_ci SOC_DAPM_PIN_SWITCH("Headset Mic"), 68562306a36Sopenharmony_ci SOC_DAPM_PIN_SWITCH("Left Spk"), 68662306a36Sopenharmony_ci SOC_DAPM_PIN_SWITCH("Right Spk"), 68762306a36Sopenharmony_ci SOC_DAPM_PIN_SWITCH("Line Out"), 68862306a36Sopenharmony_ci}; 68962306a36Sopenharmony_ci 69062306a36Sopenharmony_cistatic const 69162306a36Sopenharmony_cistruct snd_soc_dapm_widget mt8183_da7219_rt1015_dapm_widgets[] = { 69262306a36Sopenharmony_ci SND_SOC_DAPM_HP("Headphone", NULL), 69362306a36Sopenharmony_ci SND_SOC_DAPM_MIC("Headset Mic", NULL), 69462306a36Sopenharmony_ci SND_SOC_DAPM_SPK("Left Spk", NULL), 69562306a36Sopenharmony_ci SND_SOC_DAPM_SPK("Right Spk", NULL), 69662306a36Sopenharmony_ci SND_SOC_DAPM_LINE("Line Out", NULL), 69762306a36Sopenharmony_ci SND_SOC_DAPM_PINCTRL("TDM_OUT_PINCTRL", 69862306a36Sopenharmony_ci "aud_tdm_out_on", "aud_tdm_out_off"), 69962306a36Sopenharmony_ci}; 70062306a36Sopenharmony_ci 70162306a36Sopenharmony_cistatic const struct snd_soc_dapm_route mt8183_da7219_rt1015_dapm_routes[] = { 70262306a36Sopenharmony_ci {"Left Spk", NULL, "Left SPO"}, 70362306a36Sopenharmony_ci {"Right Spk", NULL, "Right SPO"}, 70462306a36Sopenharmony_ci {"I2S Playback", NULL, "TDM_OUT_PINCTRL"}, 70562306a36Sopenharmony_ci}; 70662306a36Sopenharmony_ci 70762306a36Sopenharmony_cistatic struct snd_soc_card mt8183_da7219_rt1015_card = { 70862306a36Sopenharmony_ci .name = "mt8183_da7219_rt1015", 70962306a36Sopenharmony_ci .owner = THIS_MODULE, 71062306a36Sopenharmony_ci .controls = mt8183_da7219_rt1015_snd_controls, 71162306a36Sopenharmony_ci .num_controls = ARRAY_SIZE(mt8183_da7219_rt1015_snd_controls), 71262306a36Sopenharmony_ci .dapm_widgets = mt8183_da7219_rt1015_dapm_widgets, 71362306a36Sopenharmony_ci .num_dapm_widgets = ARRAY_SIZE(mt8183_da7219_rt1015_dapm_widgets), 71462306a36Sopenharmony_ci .dapm_routes = mt8183_da7219_rt1015_dapm_routes, 71562306a36Sopenharmony_ci .num_dapm_routes = ARRAY_SIZE(mt8183_da7219_rt1015_dapm_routes), 71662306a36Sopenharmony_ci .dai_link = mt8183_da7219_dai_links, 71762306a36Sopenharmony_ci .num_links = ARRAY_SIZE(mt8183_da7219_dai_links), 71862306a36Sopenharmony_ci .aux_dev = &mt8183_da7219_max98357_headset_dev, 71962306a36Sopenharmony_ci .num_aux_devs = 1, 72062306a36Sopenharmony_ci .codec_conf = mt8183_da7219_rt1015_codec_conf, 72162306a36Sopenharmony_ci .num_configs = ARRAY_SIZE(mt8183_da7219_rt1015_codec_conf), 72262306a36Sopenharmony_ci}; 72362306a36Sopenharmony_ci 72462306a36Sopenharmony_cistatic struct snd_soc_card mt8183_da7219_rt1015p_card = { 72562306a36Sopenharmony_ci .name = "mt8183_da7219_rt1015p", 72662306a36Sopenharmony_ci .owner = THIS_MODULE, 72762306a36Sopenharmony_ci .controls = mt8183_da7219_max98357_snd_controls, 72862306a36Sopenharmony_ci .num_controls = ARRAY_SIZE(mt8183_da7219_max98357_snd_controls), 72962306a36Sopenharmony_ci .dapm_widgets = mt8183_da7219_max98357_dapm_widgets, 73062306a36Sopenharmony_ci .num_dapm_widgets = ARRAY_SIZE(mt8183_da7219_max98357_dapm_widgets), 73162306a36Sopenharmony_ci .dapm_routes = mt8183_da7219_max98357_dapm_routes, 73262306a36Sopenharmony_ci .num_dapm_routes = ARRAY_SIZE(mt8183_da7219_max98357_dapm_routes), 73362306a36Sopenharmony_ci .dai_link = mt8183_da7219_dai_links, 73462306a36Sopenharmony_ci .num_links = ARRAY_SIZE(mt8183_da7219_dai_links), 73562306a36Sopenharmony_ci .aux_dev = &mt8183_da7219_max98357_headset_dev, 73662306a36Sopenharmony_ci .num_aux_devs = 1, 73762306a36Sopenharmony_ci .codec_conf = mt6358_codec_conf, 73862306a36Sopenharmony_ci .num_configs = ARRAY_SIZE(mt6358_codec_conf), 73962306a36Sopenharmony_ci}; 74062306a36Sopenharmony_ci 74162306a36Sopenharmony_cistatic int mt8183_da7219_max98357_dev_probe(struct platform_device *pdev) 74262306a36Sopenharmony_ci{ 74362306a36Sopenharmony_ci struct snd_soc_card *card; 74462306a36Sopenharmony_ci struct device_node *platform_node, *hdmi_codec; 74562306a36Sopenharmony_ci struct snd_soc_dai_link *dai_link; 74662306a36Sopenharmony_ci struct mt8183_da7219_max98357_priv *priv; 74762306a36Sopenharmony_ci struct pinctrl *pinctrl; 74862306a36Sopenharmony_ci int ret, i; 74962306a36Sopenharmony_ci 75062306a36Sopenharmony_ci platform_node = of_parse_phandle(pdev->dev.of_node, 75162306a36Sopenharmony_ci "mediatek,platform", 0); 75262306a36Sopenharmony_ci if (!platform_node) { 75362306a36Sopenharmony_ci dev_err(&pdev->dev, "Property 'platform' missing or invalid\n"); 75462306a36Sopenharmony_ci return -EINVAL; 75562306a36Sopenharmony_ci } 75662306a36Sopenharmony_ci 75762306a36Sopenharmony_ci card = (struct snd_soc_card *)of_device_get_match_data(&pdev->dev); 75862306a36Sopenharmony_ci if (!card) { 75962306a36Sopenharmony_ci ret = -EINVAL; 76062306a36Sopenharmony_ci goto put_platform_node; 76162306a36Sopenharmony_ci } 76262306a36Sopenharmony_ci 76362306a36Sopenharmony_ci card->dev = &pdev->dev; 76462306a36Sopenharmony_ci 76562306a36Sopenharmony_ci hdmi_codec = of_parse_phandle(pdev->dev.of_node, 76662306a36Sopenharmony_ci "mediatek,hdmi-codec", 0); 76762306a36Sopenharmony_ci 76862306a36Sopenharmony_ci for_each_card_prelinks(card, i, dai_link) { 76962306a36Sopenharmony_ci if (strcmp(dai_link->name, "I2S3") == 0) { 77062306a36Sopenharmony_ci if (card == &mt8183_da7219_max98357_card) { 77162306a36Sopenharmony_ci dai_link->be_hw_params_fixup = 77262306a36Sopenharmony_ci mt8183_i2s_hw_params_fixup; 77362306a36Sopenharmony_ci dai_link->ops = &mt8183_da7219_i2s_ops; 77462306a36Sopenharmony_ci dai_link->cpus = i2s3_max98357a_cpus; 77562306a36Sopenharmony_ci dai_link->num_cpus = 77662306a36Sopenharmony_ci ARRAY_SIZE(i2s3_max98357a_cpus); 77762306a36Sopenharmony_ci dai_link->codecs = i2s3_max98357a_codecs; 77862306a36Sopenharmony_ci dai_link->num_codecs = 77962306a36Sopenharmony_ci ARRAY_SIZE(i2s3_max98357a_codecs); 78062306a36Sopenharmony_ci dai_link->platforms = i2s3_max98357a_platforms; 78162306a36Sopenharmony_ci dai_link->num_platforms = 78262306a36Sopenharmony_ci ARRAY_SIZE(i2s3_max98357a_platforms); 78362306a36Sopenharmony_ci } else if (card == &mt8183_da7219_rt1015_card) { 78462306a36Sopenharmony_ci dai_link->be_hw_params_fixup = 78562306a36Sopenharmony_ci mt8183_rt1015_i2s_hw_params_fixup; 78662306a36Sopenharmony_ci dai_link->ops = &mt8183_da7219_rt1015_i2s_ops; 78762306a36Sopenharmony_ci dai_link->cpus = i2s3_rt1015_cpus; 78862306a36Sopenharmony_ci dai_link->num_cpus = 78962306a36Sopenharmony_ci ARRAY_SIZE(i2s3_rt1015_cpus); 79062306a36Sopenharmony_ci dai_link->codecs = i2s3_rt1015_codecs; 79162306a36Sopenharmony_ci dai_link->num_codecs = 79262306a36Sopenharmony_ci ARRAY_SIZE(i2s3_rt1015_codecs); 79362306a36Sopenharmony_ci dai_link->platforms = i2s3_rt1015_platforms; 79462306a36Sopenharmony_ci dai_link->num_platforms = 79562306a36Sopenharmony_ci ARRAY_SIZE(i2s3_rt1015_platforms); 79662306a36Sopenharmony_ci } else if (card == &mt8183_da7219_rt1015p_card) { 79762306a36Sopenharmony_ci dai_link->be_hw_params_fixup = 79862306a36Sopenharmony_ci mt8183_rt1015_i2s_hw_params_fixup; 79962306a36Sopenharmony_ci dai_link->ops = &mt8183_da7219_i2s_ops; 80062306a36Sopenharmony_ci dai_link->cpus = i2s3_rt1015p_cpus; 80162306a36Sopenharmony_ci dai_link->num_cpus = 80262306a36Sopenharmony_ci ARRAY_SIZE(i2s3_rt1015p_cpus); 80362306a36Sopenharmony_ci dai_link->codecs = i2s3_rt1015p_codecs; 80462306a36Sopenharmony_ci dai_link->num_codecs = 80562306a36Sopenharmony_ci ARRAY_SIZE(i2s3_rt1015p_codecs); 80662306a36Sopenharmony_ci dai_link->platforms = i2s3_rt1015p_platforms; 80762306a36Sopenharmony_ci dai_link->num_platforms = 80862306a36Sopenharmony_ci ARRAY_SIZE(i2s3_rt1015p_platforms); 80962306a36Sopenharmony_ci } 81062306a36Sopenharmony_ci } 81162306a36Sopenharmony_ci 81262306a36Sopenharmony_ci if (hdmi_codec && strcmp(dai_link->name, "TDM") == 0) { 81362306a36Sopenharmony_ci dai_link->codecs->of_node = hdmi_codec; 81462306a36Sopenharmony_ci dai_link->ignore = 0; 81562306a36Sopenharmony_ci } 81662306a36Sopenharmony_ci 81762306a36Sopenharmony_ci if (!dai_link->platforms->name) 81862306a36Sopenharmony_ci dai_link->platforms->of_node = platform_node; 81962306a36Sopenharmony_ci } 82062306a36Sopenharmony_ci 82162306a36Sopenharmony_ci mt8183_da7219_max98357_headset_dev.dlc.of_node = 82262306a36Sopenharmony_ci of_parse_phandle(pdev->dev.of_node, 82362306a36Sopenharmony_ci "mediatek,headset-codec", 0); 82462306a36Sopenharmony_ci if (!mt8183_da7219_max98357_headset_dev.dlc.of_node) { 82562306a36Sopenharmony_ci dev_err(&pdev->dev, 82662306a36Sopenharmony_ci "Property 'mediatek,headset-codec' missing/invalid\n"); 82762306a36Sopenharmony_ci ret = -EINVAL; 82862306a36Sopenharmony_ci goto put_hdmi_codec; 82962306a36Sopenharmony_ci } 83062306a36Sopenharmony_ci 83162306a36Sopenharmony_ci priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL); 83262306a36Sopenharmony_ci if (!priv) { 83362306a36Sopenharmony_ci ret = -ENOMEM; 83462306a36Sopenharmony_ci goto put_hdmi_codec; 83562306a36Sopenharmony_ci } 83662306a36Sopenharmony_ci 83762306a36Sopenharmony_ci snd_soc_card_set_drvdata(card, priv); 83862306a36Sopenharmony_ci 83962306a36Sopenharmony_ci pinctrl = devm_pinctrl_get_select(&pdev->dev, PINCTRL_STATE_DEFAULT); 84062306a36Sopenharmony_ci if (IS_ERR(pinctrl)) { 84162306a36Sopenharmony_ci ret = PTR_ERR(pinctrl); 84262306a36Sopenharmony_ci dev_err(&pdev->dev, "%s failed to select default state %d\n", 84362306a36Sopenharmony_ci __func__, ret); 84462306a36Sopenharmony_ci goto put_hdmi_codec; 84562306a36Sopenharmony_ci } 84662306a36Sopenharmony_ci 84762306a36Sopenharmony_ci ret = devm_snd_soc_register_card(&pdev->dev, card); 84862306a36Sopenharmony_ci 84962306a36Sopenharmony_ci 85062306a36Sopenharmony_ciput_hdmi_codec: 85162306a36Sopenharmony_ci of_node_put(hdmi_codec); 85262306a36Sopenharmony_ciput_platform_node: 85362306a36Sopenharmony_ci of_node_put(platform_node); 85462306a36Sopenharmony_ci return ret; 85562306a36Sopenharmony_ci} 85662306a36Sopenharmony_ci 85762306a36Sopenharmony_ci#ifdef CONFIG_OF 85862306a36Sopenharmony_cistatic const struct of_device_id mt8183_da7219_max98357_dt_match[] = { 85962306a36Sopenharmony_ci { 86062306a36Sopenharmony_ci .compatible = "mediatek,mt8183_da7219_max98357", 86162306a36Sopenharmony_ci .data = &mt8183_da7219_max98357_card, 86262306a36Sopenharmony_ci }, 86362306a36Sopenharmony_ci { 86462306a36Sopenharmony_ci .compatible = "mediatek,mt8183_da7219_rt1015", 86562306a36Sopenharmony_ci .data = &mt8183_da7219_rt1015_card, 86662306a36Sopenharmony_ci }, 86762306a36Sopenharmony_ci { 86862306a36Sopenharmony_ci .compatible = "mediatek,mt8183_da7219_rt1015p", 86962306a36Sopenharmony_ci .data = &mt8183_da7219_rt1015p_card, 87062306a36Sopenharmony_ci }, 87162306a36Sopenharmony_ci {} 87262306a36Sopenharmony_ci}; 87362306a36Sopenharmony_ciMODULE_DEVICE_TABLE(of, mt8183_da7219_max98357_dt_match); 87462306a36Sopenharmony_ci#endif 87562306a36Sopenharmony_ci 87662306a36Sopenharmony_cistatic struct platform_driver mt8183_da7219_max98357_driver = { 87762306a36Sopenharmony_ci .driver = { 87862306a36Sopenharmony_ci .name = "mt8183_da7219", 87962306a36Sopenharmony_ci#ifdef CONFIG_OF 88062306a36Sopenharmony_ci .of_match_table = mt8183_da7219_max98357_dt_match, 88162306a36Sopenharmony_ci#endif 88262306a36Sopenharmony_ci .pm = &snd_soc_pm_ops, 88362306a36Sopenharmony_ci }, 88462306a36Sopenharmony_ci .probe = mt8183_da7219_max98357_dev_probe, 88562306a36Sopenharmony_ci}; 88662306a36Sopenharmony_ci 88762306a36Sopenharmony_cimodule_platform_driver(mt8183_da7219_max98357_driver); 88862306a36Sopenharmony_ci 88962306a36Sopenharmony_ci/* Module information */ 89062306a36Sopenharmony_ciMODULE_DESCRIPTION("MT8183-DA7219-MAX98357 ALSA SoC machine driver"); 89162306a36Sopenharmony_ciMODULE_AUTHOR("Shunli Wang <shunli.wang@mediatek.com>"); 89262306a36Sopenharmony_ciMODULE_LICENSE("GPL v2"); 89362306a36Sopenharmony_ciMODULE_ALIAS("mt8183_da7219_max98357 soc card"); 894