18c2ecf20Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0 28c2ecf20Sopenharmony_ci/* 38c2ecf20Sopenharmony_ci * mt8173-rt5650-rt5676.c -- MT8173 machine driver with RT5650/5676 codecs 48c2ecf20Sopenharmony_ci * 58c2ecf20Sopenharmony_ci * Copyright (c) 2015 MediaTek Inc. 68c2ecf20Sopenharmony_ci * Author: Koro Chen <koro.chen@mediatek.com> 78c2ecf20Sopenharmony_ci */ 88c2ecf20Sopenharmony_ci 98c2ecf20Sopenharmony_ci#include <linux/module.h> 108c2ecf20Sopenharmony_ci#include <linux/gpio.h> 118c2ecf20Sopenharmony_ci#include <linux/of_gpio.h> 128c2ecf20Sopenharmony_ci#include <sound/soc.h> 138c2ecf20Sopenharmony_ci#include <sound/jack.h> 148c2ecf20Sopenharmony_ci#include "../../codecs/rt5645.h" 158c2ecf20Sopenharmony_ci#include "../../codecs/rt5677.h" 168c2ecf20Sopenharmony_ci 178c2ecf20Sopenharmony_ci#define MCLK_FOR_CODECS 12288000 188c2ecf20Sopenharmony_ci 198c2ecf20Sopenharmony_cistatic const struct snd_soc_dapm_widget mt8173_rt5650_rt5676_widgets[] = { 208c2ecf20Sopenharmony_ci SND_SOC_DAPM_SPK("Speaker", NULL), 218c2ecf20Sopenharmony_ci SND_SOC_DAPM_MIC("Int Mic", NULL), 228c2ecf20Sopenharmony_ci SND_SOC_DAPM_HP("Headphone", NULL), 238c2ecf20Sopenharmony_ci SND_SOC_DAPM_MIC("Headset Mic", NULL), 248c2ecf20Sopenharmony_ci}; 258c2ecf20Sopenharmony_ci 268c2ecf20Sopenharmony_cistatic const struct snd_soc_dapm_route mt8173_rt5650_rt5676_routes[] = { 278c2ecf20Sopenharmony_ci {"Speaker", NULL, "SPOL"}, 288c2ecf20Sopenharmony_ci {"Speaker", NULL, "SPOR"}, 298c2ecf20Sopenharmony_ci {"Speaker", NULL, "Sub AIF2TX"}, /* IF2 ADC to 5650 */ 308c2ecf20Sopenharmony_ci {"Sub DMIC L1", NULL, "Int Mic"}, /* DMIC from 5676 */ 318c2ecf20Sopenharmony_ci {"Sub DMIC R1", NULL, "Int Mic"}, 328c2ecf20Sopenharmony_ci {"Headphone", NULL, "HPOL"}, 338c2ecf20Sopenharmony_ci {"Headphone", NULL, "HPOR"}, 348c2ecf20Sopenharmony_ci {"Headphone", NULL, "Sub AIF2TX"}, /* IF2 ADC to 5650 */ 358c2ecf20Sopenharmony_ci {"IN1P", NULL, "Headset Mic"}, 368c2ecf20Sopenharmony_ci {"IN1N", NULL, "Headset Mic"}, 378c2ecf20Sopenharmony_ci {"Sub AIF2RX", NULL, "Headset Mic"}, /* IF2 DAC from 5650 */ 388c2ecf20Sopenharmony_ci}; 398c2ecf20Sopenharmony_ci 408c2ecf20Sopenharmony_cistatic const struct snd_kcontrol_new mt8173_rt5650_rt5676_controls[] = { 418c2ecf20Sopenharmony_ci SOC_DAPM_PIN_SWITCH("Speaker"), 428c2ecf20Sopenharmony_ci SOC_DAPM_PIN_SWITCH("Int Mic"), 438c2ecf20Sopenharmony_ci SOC_DAPM_PIN_SWITCH("Headphone"), 448c2ecf20Sopenharmony_ci SOC_DAPM_PIN_SWITCH("Headset Mic"), 458c2ecf20Sopenharmony_ci}; 468c2ecf20Sopenharmony_ci 478c2ecf20Sopenharmony_cistatic int mt8173_rt5650_rt5676_hw_params(struct snd_pcm_substream *substream, 488c2ecf20Sopenharmony_ci struct snd_pcm_hw_params *params) 498c2ecf20Sopenharmony_ci{ 508c2ecf20Sopenharmony_ci struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream); 518c2ecf20Sopenharmony_ci struct snd_soc_dai *codec_dai; 528c2ecf20Sopenharmony_ci int i, ret; 538c2ecf20Sopenharmony_ci 548c2ecf20Sopenharmony_ci for_each_rtd_codec_dais(rtd, i, codec_dai) { 558c2ecf20Sopenharmony_ci /* pll from mclk 12.288M */ 568c2ecf20Sopenharmony_ci ret = snd_soc_dai_set_pll(codec_dai, 0, 0, MCLK_FOR_CODECS, 578c2ecf20Sopenharmony_ci params_rate(params) * 512); 588c2ecf20Sopenharmony_ci if (ret) 598c2ecf20Sopenharmony_ci return ret; 608c2ecf20Sopenharmony_ci 618c2ecf20Sopenharmony_ci /* sysclk from pll */ 628c2ecf20Sopenharmony_ci ret = snd_soc_dai_set_sysclk(codec_dai, 1, 638c2ecf20Sopenharmony_ci params_rate(params) * 512, 648c2ecf20Sopenharmony_ci SND_SOC_CLOCK_IN); 658c2ecf20Sopenharmony_ci if (ret) 668c2ecf20Sopenharmony_ci return ret; 678c2ecf20Sopenharmony_ci } 688c2ecf20Sopenharmony_ci return 0; 698c2ecf20Sopenharmony_ci} 708c2ecf20Sopenharmony_ci 718c2ecf20Sopenharmony_cistatic const struct snd_soc_ops mt8173_rt5650_rt5676_ops = { 728c2ecf20Sopenharmony_ci .hw_params = mt8173_rt5650_rt5676_hw_params, 738c2ecf20Sopenharmony_ci}; 748c2ecf20Sopenharmony_ci 758c2ecf20Sopenharmony_cistatic struct snd_soc_jack mt8173_rt5650_rt5676_jack; 768c2ecf20Sopenharmony_ci 778c2ecf20Sopenharmony_cistatic int mt8173_rt5650_rt5676_init(struct snd_soc_pcm_runtime *runtime) 788c2ecf20Sopenharmony_ci{ 798c2ecf20Sopenharmony_ci struct snd_soc_card *card = runtime->card; 808c2ecf20Sopenharmony_ci struct snd_soc_component *component = asoc_rtd_to_codec(runtime, 0)->component; 818c2ecf20Sopenharmony_ci struct snd_soc_component *component_sub = asoc_rtd_to_codec(runtime, 1)->component; 828c2ecf20Sopenharmony_ci int ret; 838c2ecf20Sopenharmony_ci 848c2ecf20Sopenharmony_ci rt5645_sel_asrc_clk_src(component, 858c2ecf20Sopenharmony_ci RT5645_DA_STEREO_FILTER | 868c2ecf20Sopenharmony_ci RT5645_AD_STEREO_FILTER, 878c2ecf20Sopenharmony_ci RT5645_CLK_SEL_I2S1_ASRC); 888c2ecf20Sopenharmony_ci rt5677_sel_asrc_clk_src(component_sub, 898c2ecf20Sopenharmony_ci RT5677_DA_STEREO_FILTER | 908c2ecf20Sopenharmony_ci RT5677_AD_STEREO1_FILTER, 918c2ecf20Sopenharmony_ci RT5677_CLK_SEL_I2S1_ASRC); 928c2ecf20Sopenharmony_ci rt5677_sel_asrc_clk_src(component_sub, 938c2ecf20Sopenharmony_ci RT5677_AD_STEREO2_FILTER | 948c2ecf20Sopenharmony_ci RT5677_I2S2_SOURCE, 958c2ecf20Sopenharmony_ci RT5677_CLK_SEL_I2S2_ASRC); 968c2ecf20Sopenharmony_ci 978c2ecf20Sopenharmony_ci /* enable jack detection */ 988c2ecf20Sopenharmony_ci ret = snd_soc_card_jack_new(card, "Headset Jack", 998c2ecf20Sopenharmony_ci SND_JACK_HEADPHONE | SND_JACK_MICROPHONE | 1008c2ecf20Sopenharmony_ci SND_JACK_BTN_0 | SND_JACK_BTN_1 | 1018c2ecf20Sopenharmony_ci SND_JACK_BTN_2 | SND_JACK_BTN_3, 1028c2ecf20Sopenharmony_ci &mt8173_rt5650_rt5676_jack, NULL, 0); 1038c2ecf20Sopenharmony_ci if (ret) { 1048c2ecf20Sopenharmony_ci dev_err(card->dev, "Can't new Headset Jack %d\n", ret); 1058c2ecf20Sopenharmony_ci return ret; 1068c2ecf20Sopenharmony_ci } 1078c2ecf20Sopenharmony_ci 1088c2ecf20Sopenharmony_ci return rt5645_set_jack_detect(component, 1098c2ecf20Sopenharmony_ci &mt8173_rt5650_rt5676_jack, 1108c2ecf20Sopenharmony_ci &mt8173_rt5650_rt5676_jack, 1118c2ecf20Sopenharmony_ci &mt8173_rt5650_rt5676_jack); 1128c2ecf20Sopenharmony_ci} 1138c2ecf20Sopenharmony_ci 1148c2ecf20Sopenharmony_ci 1158c2ecf20Sopenharmony_cienum { 1168c2ecf20Sopenharmony_ci DAI_LINK_PLAYBACK, 1178c2ecf20Sopenharmony_ci DAI_LINK_CAPTURE, 1188c2ecf20Sopenharmony_ci DAI_LINK_HDMI, 1198c2ecf20Sopenharmony_ci DAI_LINK_CODEC_I2S, 1208c2ecf20Sopenharmony_ci DAI_LINK_HDMI_I2S, 1218c2ecf20Sopenharmony_ci DAI_LINK_INTERCODEC 1228c2ecf20Sopenharmony_ci}; 1238c2ecf20Sopenharmony_ci 1248c2ecf20Sopenharmony_ciSND_SOC_DAILINK_DEFS(playback, 1258c2ecf20Sopenharmony_ci DAILINK_COMP_ARRAY(COMP_CPU("DL1")), 1268c2ecf20Sopenharmony_ci DAILINK_COMP_ARRAY(COMP_DUMMY()), 1278c2ecf20Sopenharmony_ci DAILINK_COMP_ARRAY(COMP_EMPTY())); 1288c2ecf20Sopenharmony_ci 1298c2ecf20Sopenharmony_ciSND_SOC_DAILINK_DEFS(capture, 1308c2ecf20Sopenharmony_ci DAILINK_COMP_ARRAY(COMP_CPU("VUL")), 1318c2ecf20Sopenharmony_ci DAILINK_COMP_ARRAY(COMP_DUMMY()), 1328c2ecf20Sopenharmony_ci DAILINK_COMP_ARRAY(COMP_EMPTY())); 1338c2ecf20Sopenharmony_ci 1348c2ecf20Sopenharmony_ciSND_SOC_DAILINK_DEFS(hdmi_pcm, 1358c2ecf20Sopenharmony_ci DAILINK_COMP_ARRAY(COMP_CPU("HDMI")), 1368c2ecf20Sopenharmony_ci DAILINK_COMP_ARRAY(COMP_DUMMY()), 1378c2ecf20Sopenharmony_ci DAILINK_COMP_ARRAY(COMP_EMPTY())); 1388c2ecf20Sopenharmony_ci 1398c2ecf20Sopenharmony_ciSND_SOC_DAILINK_DEFS(codec, 1408c2ecf20Sopenharmony_ci DAILINK_COMP_ARRAY(COMP_CPU("I2S")), 1418c2ecf20Sopenharmony_ci DAILINK_COMP_ARRAY(COMP_CODEC(NULL, "rt5645-aif1"), 1428c2ecf20Sopenharmony_ci COMP_CODEC(NULL, "rt5677-aif1")), 1438c2ecf20Sopenharmony_ci DAILINK_COMP_ARRAY(COMP_EMPTY())); 1448c2ecf20Sopenharmony_ci 1458c2ecf20Sopenharmony_ciSND_SOC_DAILINK_DEFS(hdmi_be, 1468c2ecf20Sopenharmony_ci DAILINK_COMP_ARRAY(COMP_CPU("HDMIO")), 1478c2ecf20Sopenharmony_ci DAILINK_COMP_ARRAY(COMP_CODEC(NULL, "i2s-hifi")), 1488c2ecf20Sopenharmony_ci DAILINK_COMP_ARRAY(COMP_EMPTY())); 1498c2ecf20Sopenharmony_ci 1508c2ecf20Sopenharmony_ciSND_SOC_DAILINK_DEFS(intercodec, 1518c2ecf20Sopenharmony_ci DAILINK_COMP_ARRAY(COMP_DUMMY()), 1528c2ecf20Sopenharmony_ci DAILINK_COMP_ARRAY(COMP_CODEC(NULL, "rt5677-aif2")), 1538c2ecf20Sopenharmony_ci DAILINK_COMP_ARRAY(COMP_DUMMY())); 1548c2ecf20Sopenharmony_ci 1558c2ecf20Sopenharmony_ci/* Digital audio interface glue - connects codec <---> CPU */ 1568c2ecf20Sopenharmony_cistatic struct snd_soc_dai_link mt8173_rt5650_rt5676_dais[] = { 1578c2ecf20Sopenharmony_ci /* Front End DAI links */ 1588c2ecf20Sopenharmony_ci [DAI_LINK_PLAYBACK] = { 1598c2ecf20Sopenharmony_ci .name = "rt5650_rt5676 Playback", 1608c2ecf20Sopenharmony_ci .stream_name = "rt5650_rt5676 Playback", 1618c2ecf20Sopenharmony_ci .trigger = {SND_SOC_DPCM_TRIGGER_POST, SND_SOC_DPCM_TRIGGER_POST}, 1628c2ecf20Sopenharmony_ci .dynamic = 1, 1638c2ecf20Sopenharmony_ci .dpcm_playback = 1, 1648c2ecf20Sopenharmony_ci SND_SOC_DAILINK_REG(playback), 1658c2ecf20Sopenharmony_ci }, 1668c2ecf20Sopenharmony_ci [DAI_LINK_CAPTURE] = { 1678c2ecf20Sopenharmony_ci .name = "rt5650_rt5676 Capture", 1688c2ecf20Sopenharmony_ci .stream_name = "rt5650_rt5676 Capture", 1698c2ecf20Sopenharmony_ci .trigger = {SND_SOC_DPCM_TRIGGER_POST, SND_SOC_DPCM_TRIGGER_POST}, 1708c2ecf20Sopenharmony_ci .dynamic = 1, 1718c2ecf20Sopenharmony_ci .dpcm_capture = 1, 1728c2ecf20Sopenharmony_ci SND_SOC_DAILINK_REG(capture), 1738c2ecf20Sopenharmony_ci }, 1748c2ecf20Sopenharmony_ci [DAI_LINK_HDMI] = { 1758c2ecf20Sopenharmony_ci .name = "HDMI", 1768c2ecf20Sopenharmony_ci .stream_name = "HDMI PCM", 1778c2ecf20Sopenharmony_ci .trigger = {SND_SOC_DPCM_TRIGGER_POST, SND_SOC_DPCM_TRIGGER_POST}, 1788c2ecf20Sopenharmony_ci .dynamic = 1, 1798c2ecf20Sopenharmony_ci .dpcm_playback = 1, 1808c2ecf20Sopenharmony_ci SND_SOC_DAILINK_REG(hdmi_pcm), 1818c2ecf20Sopenharmony_ci }, 1828c2ecf20Sopenharmony_ci 1838c2ecf20Sopenharmony_ci /* Back End DAI links */ 1848c2ecf20Sopenharmony_ci [DAI_LINK_CODEC_I2S] = { 1858c2ecf20Sopenharmony_ci .name = "Codec", 1868c2ecf20Sopenharmony_ci .no_pcm = 1, 1878c2ecf20Sopenharmony_ci .init = mt8173_rt5650_rt5676_init, 1888c2ecf20Sopenharmony_ci .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | 1898c2ecf20Sopenharmony_ci SND_SOC_DAIFMT_CBS_CFS, 1908c2ecf20Sopenharmony_ci .ops = &mt8173_rt5650_rt5676_ops, 1918c2ecf20Sopenharmony_ci .ignore_pmdown_time = 1, 1928c2ecf20Sopenharmony_ci .dpcm_playback = 1, 1938c2ecf20Sopenharmony_ci .dpcm_capture = 1, 1948c2ecf20Sopenharmony_ci SND_SOC_DAILINK_REG(codec), 1958c2ecf20Sopenharmony_ci }, 1968c2ecf20Sopenharmony_ci [DAI_LINK_HDMI_I2S] = { 1978c2ecf20Sopenharmony_ci .name = "HDMI BE", 1988c2ecf20Sopenharmony_ci .no_pcm = 1, 1998c2ecf20Sopenharmony_ci .dpcm_playback = 1, 2008c2ecf20Sopenharmony_ci SND_SOC_DAILINK_REG(hdmi_be), 2018c2ecf20Sopenharmony_ci }, 2028c2ecf20Sopenharmony_ci /* rt5676 <-> rt5650 intercodec link: Sets rt5676 I2S2 as master */ 2038c2ecf20Sopenharmony_ci [DAI_LINK_INTERCODEC] = { 2048c2ecf20Sopenharmony_ci .name = "rt5650_rt5676 intercodec", 2058c2ecf20Sopenharmony_ci .stream_name = "rt5650_rt5676 intercodec", 2068c2ecf20Sopenharmony_ci .no_pcm = 1, 2078c2ecf20Sopenharmony_ci .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | 2088c2ecf20Sopenharmony_ci SND_SOC_DAIFMT_CBM_CFM, 2098c2ecf20Sopenharmony_ci SND_SOC_DAILINK_REG(intercodec), 2108c2ecf20Sopenharmony_ci }, 2118c2ecf20Sopenharmony_ci}; 2128c2ecf20Sopenharmony_ci 2138c2ecf20Sopenharmony_cistatic struct snd_soc_codec_conf mt8173_rt5650_rt5676_codec_conf[] = { 2148c2ecf20Sopenharmony_ci { 2158c2ecf20Sopenharmony_ci .name_prefix = "Sub", 2168c2ecf20Sopenharmony_ci }, 2178c2ecf20Sopenharmony_ci}; 2188c2ecf20Sopenharmony_ci 2198c2ecf20Sopenharmony_cistatic struct snd_soc_card mt8173_rt5650_rt5676_card = { 2208c2ecf20Sopenharmony_ci .name = "mtk-rt5650-rt5676", 2218c2ecf20Sopenharmony_ci .owner = THIS_MODULE, 2228c2ecf20Sopenharmony_ci .dai_link = mt8173_rt5650_rt5676_dais, 2238c2ecf20Sopenharmony_ci .num_links = ARRAY_SIZE(mt8173_rt5650_rt5676_dais), 2248c2ecf20Sopenharmony_ci .codec_conf = mt8173_rt5650_rt5676_codec_conf, 2258c2ecf20Sopenharmony_ci .num_configs = ARRAY_SIZE(mt8173_rt5650_rt5676_codec_conf), 2268c2ecf20Sopenharmony_ci .controls = mt8173_rt5650_rt5676_controls, 2278c2ecf20Sopenharmony_ci .num_controls = ARRAY_SIZE(mt8173_rt5650_rt5676_controls), 2288c2ecf20Sopenharmony_ci .dapm_widgets = mt8173_rt5650_rt5676_widgets, 2298c2ecf20Sopenharmony_ci .num_dapm_widgets = ARRAY_SIZE(mt8173_rt5650_rt5676_widgets), 2308c2ecf20Sopenharmony_ci .dapm_routes = mt8173_rt5650_rt5676_routes, 2318c2ecf20Sopenharmony_ci .num_dapm_routes = ARRAY_SIZE(mt8173_rt5650_rt5676_routes), 2328c2ecf20Sopenharmony_ci}; 2338c2ecf20Sopenharmony_ci 2348c2ecf20Sopenharmony_cistatic int mt8173_rt5650_rt5676_dev_probe(struct platform_device *pdev) 2358c2ecf20Sopenharmony_ci{ 2368c2ecf20Sopenharmony_ci struct snd_soc_card *card = &mt8173_rt5650_rt5676_card; 2378c2ecf20Sopenharmony_ci struct device_node *platform_node; 2388c2ecf20Sopenharmony_ci struct snd_soc_dai_link *dai_link; 2398c2ecf20Sopenharmony_ci int i, ret; 2408c2ecf20Sopenharmony_ci 2418c2ecf20Sopenharmony_ci platform_node = of_parse_phandle(pdev->dev.of_node, 2428c2ecf20Sopenharmony_ci "mediatek,platform", 0); 2438c2ecf20Sopenharmony_ci if (!platform_node) { 2448c2ecf20Sopenharmony_ci dev_err(&pdev->dev, "Property 'platform' missing or invalid\n"); 2458c2ecf20Sopenharmony_ci return -EINVAL; 2468c2ecf20Sopenharmony_ci } 2478c2ecf20Sopenharmony_ci 2488c2ecf20Sopenharmony_ci for_each_card_prelinks(card, i, dai_link) { 2498c2ecf20Sopenharmony_ci if (dai_link->platforms->name) 2508c2ecf20Sopenharmony_ci continue; 2518c2ecf20Sopenharmony_ci dai_link->platforms->of_node = platform_node; 2528c2ecf20Sopenharmony_ci } 2538c2ecf20Sopenharmony_ci 2548c2ecf20Sopenharmony_ci mt8173_rt5650_rt5676_dais[DAI_LINK_CODEC_I2S].codecs[0].of_node = 2558c2ecf20Sopenharmony_ci of_parse_phandle(pdev->dev.of_node, "mediatek,audio-codec", 0); 2568c2ecf20Sopenharmony_ci if (!mt8173_rt5650_rt5676_dais[DAI_LINK_CODEC_I2S].codecs[0].of_node) { 2578c2ecf20Sopenharmony_ci dev_err(&pdev->dev, 2588c2ecf20Sopenharmony_ci "Property 'audio-codec' missing or invalid\n"); 2598c2ecf20Sopenharmony_ci ret = -EINVAL; 2608c2ecf20Sopenharmony_ci goto put_node; 2618c2ecf20Sopenharmony_ci } 2628c2ecf20Sopenharmony_ci mt8173_rt5650_rt5676_dais[DAI_LINK_CODEC_I2S].codecs[1].of_node = 2638c2ecf20Sopenharmony_ci of_parse_phandle(pdev->dev.of_node, "mediatek,audio-codec", 1); 2648c2ecf20Sopenharmony_ci if (!mt8173_rt5650_rt5676_dais[DAI_LINK_CODEC_I2S].codecs[1].of_node) { 2658c2ecf20Sopenharmony_ci dev_err(&pdev->dev, 2668c2ecf20Sopenharmony_ci "Property 'audio-codec' missing or invalid\n"); 2678c2ecf20Sopenharmony_ci ret = -EINVAL; 2688c2ecf20Sopenharmony_ci goto put_node; 2698c2ecf20Sopenharmony_ci } 2708c2ecf20Sopenharmony_ci mt8173_rt5650_rt5676_codec_conf[0].dlc.of_node = 2718c2ecf20Sopenharmony_ci mt8173_rt5650_rt5676_dais[DAI_LINK_CODEC_I2S].codecs[1].of_node; 2728c2ecf20Sopenharmony_ci 2738c2ecf20Sopenharmony_ci mt8173_rt5650_rt5676_dais[DAI_LINK_INTERCODEC].codecs->of_node = 2748c2ecf20Sopenharmony_ci mt8173_rt5650_rt5676_dais[DAI_LINK_CODEC_I2S].codecs[1].of_node; 2758c2ecf20Sopenharmony_ci 2768c2ecf20Sopenharmony_ci mt8173_rt5650_rt5676_dais[DAI_LINK_HDMI_I2S].codecs->of_node = 2778c2ecf20Sopenharmony_ci of_parse_phandle(pdev->dev.of_node, "mediatek,audio-codec", 2); 2788c2ecf20Sopenharmony_ci if (!mt8173_rt5650_rt5676_dais[DAI_LINK_HDMI_I2S].codecs->of_node) { 2798c2ecf20Sopenharmony_ci dev_err(&pdev->dev, 2808c2ecf20Sopenharmony_ci "Property 'audio-codec' missing or invalid\n"); 2818c2ecf20Sopenharmony_ci ret = -EINVAL; 2828c2ecf20Sopenharmony_ci goto put_node; 2838c2ecf20Sopenharmony_ci } 2848c2ecf20Sopenharmony_ci 2858c2ecf20Sopenharmony_ci card->dev = &pdev->dev; 2868c2ecf20Sopenharmony_ci 2878c2ecf20Sopenharmony_ci ret = devm_snd_soc_register_card(&pdev->dev, card); 2888c2ecf20Sopenharmony_ci if (ret) 2898c2ecf20Sopenharmony_ci dev_err(&pdev->dev, "%s snd_soc_register_card fail %d\n", 2908c2ecf20Sopenharmony_ci __func__, ret); 2918c2ecf20Sopenharmony_ci 2928c2ecf20Sopenharmony_ciput_node: 2938c2ecf20Sopenharmony_ci of_node_put(platform_node); 2948c2ecf20Sopenharmony_ci return ret; 2958c2ecf20Sopenharmony_ci} 2968c2ecf20Sopenharmony_ci 2978c2ecf20Sopenharmony_cistatic const struct of_device_id mt8173_rt5650_rt5676_dt_match[] = { 2988c2ecf20Sopenharmony_ci { .compatible = "mediatek,mt8173-rt5650-rt5676", }, 2998c2ecf20Sopenharmony_ci { } 3008c2ecf20Sopenharmony_ci}; 3018c2ecf20Sopenharmony_ciMODULE_DEVICE_TABLE(of, mt8173_rt5650_rt5676_dt_match); 3028c2ecf20Sopenharmony_ci 3038c2ecf20Sopenharmony_cistatic struct platform_driver mt8173_rt5650_rt5676_driver = { 3048c2ecf20Sopenharmony_ci .driver = { 3058c2ecf20Sopenharmony_ci .name = "mtk-rt5650-rt5676", 3068c2ecf20Sopenharmony_ci .of_match_table = mt8173_rt5650_rt5676_dt_match, 3078c2ecf20Sopenharmony_ci#ifdef CONFIG_PM 3088c2ecf20Sopenharmony_ci .pm = &snd_soc_pm_ops, 3098c2ecf20Sopenharmony_ci#endif 3108c2ecf20Sopenharmony_ci }, 3118c2ecf20Sopenharmony_ci .probe = mt8173_rt5650_rt5676_dev_probe, 3128c2ecf20Sopenharmony_ci}; 3138c2ecf20Sopenharmony_ci 3148c2ecf20Sopenharmony_cimodule_platform_driver(mt8173_rt5650_rt5676_driver); 3158c2ecf20Sopenharmony_ci 3168c2ecf20Sopenharmony_ci/* Module information */ 3178c2ecf20Sopenharmony_ciMODULE_DESCRIPTION("MT8173 RT5650 and RT5676 SoC machine driver"); 3188c2ecf20Sopenharmony_ciMODULE_AUTHOR("Koro Chen <koro.chen@mediatek.com>"); 3198c2ecf20Sopenharmony_ciMODULE_LICENSE("GPL v2"); 3208c2ecf20Sopenharmony_ciMODULE_ALIAS("platform:mtk-rt5650-rt5676"); 3218c2ecf20Sopenharmony_ci 322