1 // SPDX-License-Identifier: GPL-2.0 2 // 3 // mt6797-mt6351.c -- MT6797 MT6351 ALSA SoC machine driver 4 // 5 // Copyright (c) 2018 MediaTek Inc. 6 // Author: KaiChieh Chuang <kaichieh.chuang@mediatek.com> 7 8 #include <linux/module.h> 9 #include <sound/soc.h> 10 11 #include "mt6797-afe-common.h" 12 13 SND_SOC_DAILINK_DEFS(playback_1, 14 DAILINK_COMP_ARRAY(COMP_CPU("DL1")), 15 DAILINK_COMP_ARRAY(COMP_DUMMY()), 16 DAILINK_COMP_ARRAY(COMP_EMPTY())); 17 18 SND_SOC_DAILINK_DEFS(playback_2, 19 DAILINK_COMP_ARRAY(COMP_CPU("DL2")), 20 DAILINK_COMP_ARRAY(COMP_DUMMY()), 21 DAILINK_COMP_ARRAY(COMP_EMPTY())); 22 23 SND_SOC_DAILINK_DEFS(playback_3, 24 DAILINK_COMP_ARRAY(COMP_CPU("DL3")), 25 DAILINK_COMP_ARRAY(COMP_DUMMY()), 26 DAILINK_COMP_ARRAY(COMP_EMPTY())); 27 28 SND_SOC_DAILINK_DEFS(capture_1, 29 DAILINK_COMP_ARRAY(COMP_CPU("UL1")), 30 DAILINK_COMP_ARRAY(COMP_DUMMY()), 31 DAILINK_COMP_ARRAY(COMP_EMPTY())); 32 33 SND_SOC_DAILINK_DEFS(capture_2, 34 DAILINK_COMP_ARRAY(COMP_CPU("UL2")), 35 DAILINK_COMP_ARRAY(COMP_DUMMY()), 36 DAILINK_COMP_ARRAY(COMP_EMPTY())); 37 38 SND_SOC_DAILINK_DEFS(capture_3, 39 DAILINK_COMP_ARRAY(COMP_CPU("UL3")), 40 DAILINK_COMP_ARRAY(COMP_DUMMY()), 41 DAILINK_COMP_ARRAY(COMP_EMPTY())); 42 43 SND_SOC_DAILINK_DEFS(capture_mono_1, 44 DAILINK_COMP_ARRAY(COMP_CPU("UL_MONO_1")), 45 DAILINK_COMP_ARRAY(COMP_DUMMY()), 46 DAILINK_COMP_ARRAY(COMP_EMPTY())); 47 48 SND_SOC_DAILINK_DEFS(hostless_lpbk, 49 DAILINK_COMP_ARRAY(COMP_CPU("Hostless LPBK DAI")), 50 DAILINK_COMP_ARRAY(COMP_DUMMY()), 51 DAILINK_COMP_ARRAY(COMP_EMPTY())); 52 53 SND_SOC_DAILINK_DEFS(hostless_speech, 54 DAILINK_COMP_ARRAY(COMP_CPU("Hostless Speech DAI")), 55 DAILINK_COMP_ARRAY(COMP_DUMMY()), 56 DAILINK_COMP_ARRAY(COMP_EMPTY())); 57 58 SND_SOC_DAILINK_DEFS(primary_codec, 59 DAILINK_COMP_ARRAY(COMP_CPU("ADDA")), 60 DAILINK_COMP_ARRAY(COMP_CODEC(NULL, "mt6351-snd-codec-aif1")), 61 DAILINK_COMP_ARRAY(COMP_EMPTY())); 62 63 SND_SOC_DAILINK_DEFS(pcm1, 64 DAILINK_COMP_ARRAY(COMP_CPU("PCM 1")), 65 DAILINK_COMP_ARRAY(COMP_DUMMY()), 66 DAILINK_COMP_ARRAY(COMP_EMPTY())); 67 68 SND_SOC_DAILINK_DEFS(pcm2, 69 DAILINK_COMP_ARRAY(COMP_CPU("PCM 2")), 70 DAILINK_COMP_ARRAY(COMP_DUMMY()), 71 DAILINK_COMP_ARRAY(COMP_EMPTY())); 72 73 static struct snd_soc_dai_link mt6797_mt6351_dai_links[] = { 74 /* FE */ 75 { 76 .name = "Playback_1", 77 .stream_name = "Playback_1", 78 .trigger = {SND_SOC_DPCM_TRIGGER_PRE, 79 SND_SOC_DPCM_TRIGGER_PRE}, 80 .dynamic = 1, 81 .dpcm_playback = 1, 82 SND_SOC_DAILINK_REG(playback_1), 83 }, 84 { 85 .name = "Playback_2", 86 .stream_name = "Playback_2", 87 .trigger = {SND_SOC_DPCM_TRIGGER_PRE, 88 SND_SOC_DPCM_TRIGGER_PRE}, 89 .dynamic = 1, 90 .dpcm_playback = 1, 91 SND_SOC_DAILINK_REG(playback_2), 92 }, 93 { 94 .name = "Playback_3", 95 .stream_name = "Playback_3", 96 .trigger = {SND_SOC_DPCM_TRIGGER_PRE, 97 SND_SOC_DPCM_TRIGGER_PRE}, 98 .dynamic = 1, 99 .dpcm_playback = 1, 100 SND_SOC_DAILINK_REG(playback_3), 101 }, 102 { 103 .name = "Capture_1", 104 .stream_name = "Capture_1", 105 .trigger = {SND_SOC_DPCM_TRIGGER_PRE, 106 SND_SOC_DPCM_TRIGGER_PRE}, 107 .dynamic = 1, 108 .dpcm_capture = 1, 109 SND_SOC_DAILINK_REG(capture_1), 110 }, 111 { 112 .name = "Capture_2", 113 .stream_name = "Capture_2", 114 .trigger = {SND_SOC_DPCM_TRIGGER_PRE, 115 SND_SOC_DPCM_TRIGGER_PRE}, 116 .dynamic = 1, 117 .dpcm_capture = 1, 118 SND_SOC_DAILINK_REG(capture_2), 119 }, 120 { 121 .name = "Capture_3", 122 .stream_name = "Capture_3", 123 .trigger = {SND_SOC_DPCM_TRIGGER_PRE, 124 SND_SOC_DPCM_TRIGGER_PRE}, 125 .dynamic = 1, 126 .dpcm_capture = 1, 127 SND_SOC_DAILINK_REG(capture_3), 128 }, 129 { 130 .name = "Capture_Mono_1", 131 .stream_name = "Capture_Mono_1", 132 .trigger = {SND_SOC_DPCM_TRIGGER_PRE, 133 SND_SOC_DPCM_TRIGGER_PRE}, 134 .dynamic = 1, 135 .dpcm_capture = 1, 136 SND_SOC_DAILINK_REG(capture_mono_1), 137 }, 138 { 139 .name = "Hostless_LPBK", 140 .stream_name = "Hostless_LPBK", 141 .trigger = {SND_SOC_DPCM_TRIGGER_PRE, 142 SND_SOC_DPCM_TRIGGER_PRE}, 143 .dynamic = 1, 144 .dpcm_playback = 1, 145 .dpcm_capture = 1, 146 .ignore_suspend = 1, 147 SND_SOC_DAILINK_REG(hostless_lpbk), 148 }, 149 { 150 .name = "Hostless_Speech", 151 .stream_name = "Hostless_Speech", 152 .trigger = {SND_SOC_DPCM_TRIGGER_PRE, 153 SND_SOC_DPCM_TRIGGER_PRE}, 154 .dynamic = 1, 155 .dpcm_playback = 1, 156 .dpcm_capture = 1, 157 .ignore_suspend = 1, 158 SND_SOC_DAILINK_REG(hostless_speech), 159 }, 160 /* BE */ 161 { 162 .name = "Primary Codec", 163 .no_pcm = 1, 164 .dpcm_playback = 1, 165 .dpcm_capture = 1, 166 .ignore_suspend = 1, 167 SND_SOC_DAILINK_REG(primary_codec), 168 }, 169 { 170 .name = "PCM 1", 171 .no_pcm = 1, 172 .dpcm_playback = 1, 173 .dpcm_capture = 1, 174 .ignore_suspend = 1, 175 SND_SOC_DAILINK_REG(pcm1), 176 }, 177 { 178 .name = "PCM 2", 179 .no_pcm = 1, 180 .dpcm_playback = 1, 181 .dpcm_capture = 1, 182 .ignore_suspend = 1, 183 SND_SOC_DAILINK_REG(pcm2), 184 }, 185 }; 186 187 static struct snd_soc_card mt6797_mt6351_card = { 188 .name = "mt6797-mt6351", 189 .owner = THIS_MODULE, 190 .dai_link = mt6797_mt6351_dai_links, 191 .num_links = ARRAY_SIZE(mt6797_mt6351_dai_links), 192 }; 193 194 static int mt6797_mt6351_dev_probe(struct platform_device *pdev) 195 { 196 struct snd_soc_card *card = &mt6797_mt6351_card; 197 struct device_node *platform_node, *codec_node; 198 struct snd_soc_dai_link *dai_link; 199 int ret, i; 200 201 card->dev = &pdev->dev; 202 203 platform_node = of_parse_phandle(pdev->dev.of_node, 204 "mediatek,platform", 0); 205 if (!platform_node) { 206 dev_err(&pdev->dev, "Property 'platform' missing or invalid\n"); 207 return -EINVAL; 208 } 209 for_each_card_prelinks(card, i, dai_link) { 210 if (dai_link->platforms->name) 211 continue; 212 dai_link->platforms->of_node = platform_node; 213 } 214 215 codec_node = of_parse_phandle(pdev->dev.of_node, 216 "mediatek,audio-codec", 0); 217 if (!codec_node) { 218 dev_err(&pdev->dev, 219 "Property 'audio-codec' missing or invalid\n"); 220 ret = -EINVAL; 221 goto put_platform_node; 222 } 223 for_each_card_prelinks(card, i, dai_link) { 224 if (dai_link->codecs->name) 225 continue; 226 dai_link->codecs->of_node = codec_node; 227 } 228 229 ret = devm_snd_soc_register_card(&pdev->dev, card); 230 if (ret) 231 dev_err(&pdev->dev, "%s snd_soc_register_card fail %d\n", 232 __func__, ret); 233 234 of_node_put(codec_node); 235 put_platform_node: 236 of_node_put(platform_node); 237 return ret; 238 } 239 240 #ifdef CONFIG_OF 241 static const struct of_device_id mt6797_mt6351_dt_match[] = { 242 {.compatible = "mediatek,mt6797-mt6351-sound",}, 243 {} 244 }; 245 MODULE_DEVICE_TABLE(of, mt6797_mt6351_dt_match); 246 #endif 247 248 static struct platform_driver mt6797_mt6351_driver = { 249 .driver = { 250 .name = "mt6797-mt6351", 251 #ifdef CONFIG_OF 252 .of_match_table = mt6797_mt6351_dt_match, 253 #endif 254 }, 255 .probe = mt6797_mt6351_dev_probe, 256 }; 257 258 module_platform_driver(mt6797_mt6351_driver); 259 260 /* Module information */ 261 MODULE_DESCRIPTION("MT6797 MT6351 ALSA SoC machine driver"); 262 MODULE_AUTHOR("KaiChieh Chuang <kaichieh.chuang@mediatek.com>"); 263 MODULE_LICENSE("GPL v2"); 264 MODULE_ALIAS("mt6797 mt6351 soc card"); 265 266