11896b485SSylwester Nawrocki // SPDX-License-Identifier: GPL-2.0 21896b485SSylwester Nawrocki // 31896b485SSylwester Nawrocki // Copyright (C) 2017 Samsung Electronics Co., Ltd. 4aba611fcSSylwester Nawrocki 5aba611fcSSylwester Nawrocki #include <linux/clk.h> 6bc3cf17bSSylwester Nawrocki #include <linux/clk-provider.h> 7aba611fcSSylwester Nawrocki #include <linux/of.h> 8aba611fcSSylwester Nawrocki #include <linux/of_device.h> 9aba611fcSSylwester Nawrocki #include <linux/module.h> 10aba611fcSSylwester Nawrocki #include <sound/soc.h> 11aba611fcSSylwester Nawrocki #include <sound/pcm_params.h> 12aba611fcSSylwester Nawrocki #include "i2s.h" 13aba611fcSSylwester Nawrocki #include "i2s-regs.h" 14aba611fcSSylwester Nawrocki 15aba611fcSSylwester Nawrocki struct odroid_priv { 16aba611fcSSylwester Nawrocki struct snd_soc_card card; 17a8ad0c85SSylwester Nawrocki struct clk *clk_i2s_bus; 18a8ad0c85SSylwester Nawrocki struct clk *sclk_i2s; 19b5c16a24SSylwester Nawrocki 20b5c16a24SSylwester Nawrocki /* Spinlock protecting fields below */ 21b5c16a24SSylwester Nawrocki spinlock_t lock; 22b5c16a24SSylwester Nawrocki unsigned int be_sample_rate; 23b5c16a24SSylwester Nawrocki bool be_active; 24aba611fcSSylwester Nawrocki }; 25aba611fcSSylwester Nawrocki 26bc3cf17bSSylwester Nawrocki static int odroid_card_fe_startup(struct snd_pcm_substream *substream) 27aba611fcSSylwester Nawrocki { 28aba611fcSSylwester Nawrocki struct snd_pcm_runtime *runtime = substream->runtime; 29aba611fcSSylwester Nawrocki 30aba611fcSSylwester Nawrocki snd_pcm_hw_constraint_single(runtime, SNDRV_PCM_HW_PARAM_CHANNELS, 2); 31bc3cf17bSSylwester Nawrocki 32aba611fcSSylwester Nawrocki return 0; 33aba611fcSSylwester Nawrocki } 34aba611fcSSylwester Nawrocki 35b5c16a24SSylwester Nawrocki static int odroid_card_fe_hw_params(struct snd_pcm_substream *substream, 36b5c16a24SSylwester Nawrocki struct snd_pcm_hw_params *params) 37b5c16a24SSylwester Nawrocki { 38c101ce88SKuninori Morimoto struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream); 39b5c16a24SSylwester Nawrocki struct odroid_priv *priv = snd_soc_card_get_drvdata(rtd->card); 40b5c16a24SSylwester Nawrocki unsigned long flags; 41b5c16a24SSylwester Nawrocki int ret = 0; 42b5c16a24SSylwester Nawrocki 43b5c16a24SSylwester Nawrocki spin_lock_irqsave(&priv->lock, flags); 44b5c16a24SSylwester Nawrocki if (priv->be_active && priv->be_sample_rate != params_rate(params)) 45b5c16a24SSylwester Nawrocki ret = -EINVAL; 46b5c16a24SSylwester Nawrocki spin_unlock_irqrestore(&priv->lock, flags); 47b5c16a24SSylwester Nawrocki 48b5c16a24SSylwester Nawrocki return ret; 49b5c16a24SSylwester Nawrocki } 50b5c16a24SSylwester Nawrocki 51bc3cf17bSSylwester Nawrocki static const struct snd_soc_ops odroid_card_fe_ops = { 52bc3cf17bSSylwester Nawrocki .startup = odroid_card_fe_startup, 53b5c16a24SSylwester Nawrocki .hw_params = odroid_card_fe_hw_params, 54bc3cf17bSSylwester Nawrocki }; 55bc3cf17bSSylwester Nawrocki 56bc3cf17bSSylwester Nawrocki static int odroid_card_be_hw_params(struct snd_pcm_substream *substream, 57aba611fcSSylwester Nawrocki struct snd_pcm_hw_params *params) 58aba611fcSSylwester Nawrocki { 59c101ce88SKuninori Morimoto struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream); 60aba611fcSSylwester Nawrocki struct odroid_priv *priv = snd_soc_card_get_drvdata(rtd->card); 611d22c337SSylwester Nawrocki unsigned int pll_freq, rclk_freq, rfs; 62b5c16a24SSylwester Nawrocki unsigned long flags; 63aba611fcSSylwester Nawrocki int ret; 64aba611fcSSylwester Nawrocki 65aba611fcSSylwester Nawrocki switch (params_rate(params)) { 66aba611fcSSylwester Nawrocki case 64000: 671d22c337SSylwester Nawrocki pll_freq = 196608001U; 681d22c337SSylwester Nawrocki rfs = 384; 69aba611fcSSylwester Nawrocki break; 70aba611fcSSylwester Nawrocki case 44100: 71aba611fcSSylwester Nawrocki case 88200: 729d154e42SSylwester Nawrocki pll_freq = 180633609U; 731d22c337SSylwester Nawrocki rfs = 512; 74aba611fcSSylwester Nawrocki break; 751d22c337SSylwester Nawrocki case 32000: 76aba611fcSSylwester Nawrocki case 48000: 77aba611fcSSylwester Nawrocki case 96000: 789d154e42SSylwester Nawrocki pll_freq = 196608001U; 791d22c337SSylwester Nawrocki rfs = 512; 80aba611fcSSylwester Nawrocki break; 81aba611fcSSylwester Nawrocki default: 82aba611fcSSylwester Nawrocki return -EINVAL; 83aba611fcSSylwester Nawrocki } 84aba611fcSSylwester Nawrocki 85a8ad0c85SSylwester Nawrocki ret = clk_set_rate(priv->clk_i2s_bus, pll_freq / 2 + 1); 86aba611fcSSylwester Nawrocki if (ret < 0) 87aba611fcSSylwester Nawrocki return ret; 88aba611fcSSylwester Nawrocki 89a8ad0c85SSylwester Nawrocki /* 902b13bee3SSylwester Nawrocki * We add 2 to the rclk_freq value in order to avoid too low clock 91a8ad0c85SSylwester Nawrocki * frequency values due to the EPLL output frequency not being exact 92a8ad0c85SSylwester Nawrocki * multiple of the audio sampling rate. 93a8ad0c85SSylwester Nawrocki */ 942b13bee3SSylwester Nawrocki rclk_freq = params_rate(params) * rfs + 2; 95aba611fcSSylwester Nawrocki 96a8ad0c85SSylwester Nawrocki ret = clk_set_rate(priv->sclk_i2s, rclk_freq); 97aba611fcSSylwester Nawrocki if (ret < 0) 98aba611fcSSylwester Nawrocki return ret; 99aba611fcSSylwester Nawrocki 1003989ade2SKuninori Morimoto if (rtd->dai_link->num_codecs > 1) { 1017de6b6bcSKuninori Morimoto struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 1); 102aba611fcSSylwester Nawrocki 103aba611fcSSylwester Nawrocki ret = snd_soc_dai_set_sysclk(codec_dai, 0, rclk_freq, 104aba611fcSSylwester Nawrocki SND_SOC_CLOCK_IN); 105aba611fcSSylwester Nawrocki if (ret < 0) 106aba611fcSSylwester Nawrocki return ret; 107aba611fcSSylwester Nawrocki } 108aba611fcSSylwester Nawrocki 109b5c16a24SSylwester Nawrocki spin_lock_irqsave(&priv->lock, flags); 110b5c16a24SSylwester Nawrocki priv->be_sample_rate = params_rate(params); 111b5c16a24SSylwester Nawrocki spin_unlock_irqrestore(&priv->lock, flags); 112b5c16a24SSylwester Nawrocki 113b5c16a24SSylwester Nawrocki return 0; 114b5c16a24SSylwester Nawrocki } 115b5c16a24SSylwester Nawrocki 116b5c16a24SSylwester Nawrocki static int odroid_card_be_trigger(struct snd_pcm_substream *substream, int cmd) 117b5c16a24SSylwester Nawrocki { 118c101ce88SKuninori Morimoto struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream); 119b5c16a24SSylwester Nawrocki struct odroid_priv *priv = snd_soc_card_get_drvdata(rtd->card); 120b5c16a24SSylwester Nawrocki unsigned long flags; 121b5c16a24SSylwester Nawrocki 122b5c16a24SSylwester Nawrocki spin_lock_irqsave(&priv->lock, flags); 123b5c16a24SSylwester Nawrocki 124b5c16a24SSylwester Nawrocki switch (cmd) { 125b5c16a24SSylwester Nawrocki case SNDRV_PCM_TRIGGER_START: 126b5c16a24SSylwester Nawrocki case SNDRV_PCM_TRIGGER_RESUME: 127b5c16a24SSylwester Nawrocki case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: 128b5c16a24SSylwester Nawrocki priv->be_active = true; 129b5c16a24SSylwester Nawrocki break; 130b5c16a24SSylwester Nawrocki 131b5c16a24SSylwester Nawrocki case SNDRV_PCM_TRIGGER_STOP: 132b5c16a24SSylwester Nawrocki case SNDRV_PCM_TRIGGER_SUSPEND: 133b5c16a24SSylwester Nawrocki case SNDRV_PCM_TRIGGER_PAUSE_PUSH: 134b5c16a24SSylwester Nawrocki priv->be_active = false; 135b5c16a24SSylwester Nawrocki break; 136b5c16a24SSylwester Nawrocki } 137b5c16a24SSylwester Nawrocki 138b5c16a24SSylwester Nawrocki spin_unlock_irqrestore(&priv->lock, flags); 139b5c16a24SSylwester Nawrocki 140aba611fcSSylwester Nawrocki return 0; 141aba611fcSSylwester Nawrocki } 142aba611fcSSylwester Nawrocki 143bc3cf17bSSylwester Nawrocki static const struct snd_soc_ops odroid_card_be_ops = { 144bc3cf17bSSylwester Nawrocki .hw_params = odroid_card_be_hw_params, 145b5c16a24SSylwester Nawrocki .trigger = odroid_card_be_trigger, 146bc3cf17bSSylwester Nawrocki }; 147bc3cf17bSSylwester Nawrocki 148f89aea0fSSylwester Nawrocki /* DAPM routes for backward compatibility with old DTS */ 149f89aea0fSSylwester Nawrocki static const struct snd_soc_dapm_route odroid_dapm_routes[] = { 150f89aea0fSSylwester Nawrocki { "I2S Playback", NULL, "Mixer DAI TX" }, 151f89aea0fSSylwester Nawrocki { "HiFi Playback", NULL, "Mixer DAI TX" }, 152f89aea0fSSylwester Nawrocki }; 153f89aea0fSSylwester Nawrocki 1543cddda10SKuninori Morimoto SND_SOC_DAILINK_DEFS(primary, 1553cddda10SKuninori Morimoto DAILINK_COMP_ARRAY(COMP_EMPTY()), 1563cddda10SKuninori Morimoto DAILINK_COMP_ARRAY(COMP_DUMMY()), 1573cddda10SKuninori Morimoto DAILINK_COMP_ARRAY(COMP_PLATFORM("3830000.i2s"))); 1583cddda10SKuninori Morimoto 1593cddda10SKuninori Morimoto SND_SOC_DAILINK_DEFS(mixer, 1603cddda10SKuninori Morimoto DAILINK_COMP_ARRAY(COMP_DUMMY()), 1613cddda10SKuninori Morimoto DAILINK_COMP_ARRAY(COMP_EMPTY()), 1623cddda10SKuninori Morimoto DAILINK_COMP_ARRAY(COMP_DUMMY())); 1633cddda10SKuninori Morimoto 1643cddda10SKuninori Morimoto SND_SOC_DAILINK_DEFS(secondary, 1653cddda10SKuninori Morimoto DAILINK_COMP_ARRAY(COMP_EMPTY()), 1663cddda10SKuninori Morimoto DAILINK_COMP_ARRAY(COMP_DUMMY()), 1673cddda10SKuninori Morimoto DAILINK_COMP_ARRAY(COMP_PLATFORM("3830000.i2s-sec"))); 1683cddda10SKuninori Morimoto 169bc3cf17bSSylwester Nawrocki static struct snd_soc_dai_link odroid_card_dais[] = { 170bc3cf17bSSylwester Nawrocki { 171bc3cf17bSSylwester Nawrocki /* Primary FE <-> BE link */ 172bc3cf17bSSylwester Nawrocki .ops = &odroid_card_fe_ops, 173bc3cf17bSSylwester Nawrocki .name = "Primary", 174bc3cf17bSSylwester Nawrocki .stream_name = "Primary", 175bc3cf17bSSylwester Nawrocki .dynamic = 1, 176bc3cf17bSSylwester Nawrocki .dpcm_playback = 1, 1773cddda10SKuninori Morimoto SND_SOC_DAILINK_REG(primary), 178bc3cf17bSSylwester Nawrocki }, { 179bc3cf17bSSylwester Nawrocki /* BE <-> CODECs link */ 180bc3cf17bSSylwester Nawrocki .name = "I2S Mixer", 181bc3cf17bSSylwester Nawrocki .ops = &odroid_card_be_ops, 182bc3cf17bSSylwester Nawrocki .no_pcm = 1, 183bc3cf17bSSylwester Nawrocki .dpcm_playback = 1, 184bc3cf17bSSylwester Nawrocki .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | 185bc3cf17bSSylwester Nawrocki SND_SOC_DAIFMT_CBS_CFS, 1863cddda10SKuninori Morimoto SND_SOC_DAILINK_REG(mixer), 187bc3cf17bSSylwester Nawrocki }, { 188bc3cf17bSSylwester Nawrocki /* Secondary FE <-> BE link */ 189bc3cf17bSSylwester Nawrocki .playback_only = 1, 190bc3cf17bSSylwester Nawrocki .ops = &odroid_card_fe_ops, 191bc3cf17bSSylwester Nawrocki .name = "Secondary", 192bc3cf17bSSylwester Nawrocki .stream_name = "Secondary", 193bc3cf17bSSylwester Nawrocki .dynamic = 1, 194bc3cf17bSSylwester Nawrocki .dpcm_playback = 1, 1953cddda10SKuninori Morimoto SND_SOC_DAILINK_REG(secondary), 196bc3cf17bSSylwester Nawrocki } 197aba611fcSSylwester Nawrocki }; 198aba611fcSSylwester Nawrocki 199aba611fcSSylwester Nawrocki static int odroid_audio_probe(struct platform_device *pdev) 200aba611fcSSylwester Nawrocki { 201aba611fcSSylwester Nawrocki struct device *dev = &pdev->dev; 2023af81600SSylwester Nawrocki struct device_node *cpu_dai = NULL; 2033af81600SSylwester Nawrocki struct device_node *cpu, *codec; 204aba611fcSSylwester Nawrocki struct odroid_priv *priv; 205aba611fcSSylwester Nawrocki struct snd_soc_card *card; 206bc3cf17bSSylwester Nawrocki struct snd_soc_dai_link *link, *codec_link; 207bc3cf17bSSylwester Nawrocki int num_pcms, ret, i; 208aba611fcSSylwester Nawrocki 209aba611fcSSylwester Nawrocki priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); 210aba611fcSSylwester Nawrocki if (!priv) 211aba611fcSSylwester Nawrocki return -ENOMEM; 212aba611fcSSylwester Nawrocki 213aba611fcSSylwester Nawrocki card = &priv->card; 214aba611fcSSylwester Nawrocki card->dev = dev; 215aba611fcSSylwester Nawrocki 216aba611fcSSylwester Nawrocki card->owner = THIS_MODULE; 217aba611fcSSylwester Nawrocki card->fully_routed = true; 218aba611fcSSylwester Nawrocki 219b5c16a24SSylwester Nawrocki spin_lock_init(&priv->lock); 220aba611fcSSylwester Nawrocki snd_soc_card_set_drvdata(card, priv); 221aba611fcSSylwester Nawrocki 222aba611fcSSylwester Nawrocki ret = snd_soc_of_parse_card_name(card, "model"); 223aba611fcSSylwester Nawrocki if (ret < 0) 224aba611fcSSylwester Nawrocki return ret; 225aba611fcSSylwester Nawrocki 226*ebba2fd5SKrzysztof Kozlowski if (of_property_present(dev->of_node, "samsung,audio-widgets")) { 227aba611fcSSylwester Nawrocki ret = snd_soc_of_parse_audio_simple_widgets(card, 228aba611fcSSylwester Nawrocki "samsung,audio-widgets"); 229aba611fcSSylwester Nawrocki if (ret < 0) 230aba611fcSSylwester Nawrocki return ret; 231aba611fcSSylwester Nawrocki } 232aba611fcSSylwester Nawrocki 233*ebba2fd5SKrzysztof Kozlowski if (of_property_present(dev->of_node, "samsung,audio-routing")) { 234aba611fcSSylwester Nawrocki ret = snd_soc_of_parse_audio_routing(card, 235aba611fcSSylwester Nawrocki "samsung,audio-routing"); 236aba611fcSSylwester Nawrocki if (ret < 0) 237aba611fcSSylwester Nawrocki return ret; 238aba611fcSSylwester Nawrocki } 239aba611fcSSylwester Nawrocki 240bc3cf17bSSylwester Nawrocki card->dai_link = odroid_card_dais; 241bc3cf17bSSylwester Nawrocki card->num_links = ARRAY_SIZE(odroid_card_dais); 242aba611fcSSylwester Nawrocki 243aba611fcSSylwester Nawrocki cpu = of_get_child_by_name(dev->of_node, "cpu"); 244aba611fcSSylwester Nawrocki codec = of_get_child_by_name(dev->of_node, "codec"); 245bc3cf17bSSylwester Nawrocki link = card->dai_link; 246bc3cf17bSSylwester Nawrocki codec_link = &card->dai_link[1]; 247aba611fcSSylwester Nawrocki 248bc3cf17bSSylwester Nawrocki /* 249bc3cf17bSSylwester Nawrocki * For backwards compatibility create the secondary CPU DAI link only 250bc3cf17bSSylwester Nawrocki * if there are 2 CPU DAI entries in the cpu sound-dai property in DT. 251f89aea0fSSylwester Nawrocki * Also add required DAPM routes not available in old DTS. 252bc3cf17bSSylwester Nawrocki */ 253bc3cf17bSSylwester Nawrocki num_pcms = of_count_phandle_with_args(cpu, "sound-dai", 254bc3cf17bSSylwester Nawrocki "#sound-dai-cells"); 255f89aea0fSSylwester Nawrocki if (num_pcms == 1) { 256f89aea0fSSylwester Nawrocki card->dapm_routes = odroid_dapm_routes; 257f89aea0fSSylwester Nawrocki card->num_dapm_routes = ARRAY_SIZE(odroid_dapm_routes); 258bc3cf17bSSylwester Nawrocki card->num_links--; 259f89aea0fSSylwester Nawrocki } 260bc3cf17bSSylwester Nawrocki 261bc3cf17bSSylwester Nawrocki for (i = 0; i < num_pcms; i++, link += 2) { 26250233f28SKuninori Morimoto ret = snd_soc_of_get_dai_name(cpu, &link->cpus->dai_name, i); 263bc3cf17bSSylwester Nawrocki if (ret < 0) 264d832d2b2SSylwester Nawrocki break; 265bc3cf17bSSylwester Nawrocki } 2663af81600SSylwester Nawrocki if (ret == 0) { 267bc3cf17bSSylwester Nawrocki cpu_dai = of_parse_phandle(cpu, "sound-dai", 0); 2683af81600SSylwester Nawrocki if (!cpu_dai) 2693af81600SSylwester Nawrocki ret = -EINVAL; 2703af81600SSylwester Nawrocki } 271d832d2b2SSylwester Nawrocki 272bc3cf17bSSylwester Nawrocki of_node_put(cpu); 273d832d2b2SSylwester Nawrocki if (ret < 0) 2749b6d104aSWen Yang goto err_put_node; 275bc3cf17bSSylwester Nawrocki 276bc3cf17bSSylwester Nawrocki ret = snd_soc_of_get_dai_link_codecs(dev, codec, codec_link); 277aba611fcSSylwester Nawrocki if (ret < 0) 278d832d2b2SSylwester Nawrocki goto err_put_cpu_dai; 279aba611fcSSylwester Nawrocki 280bc3cf17bSSylwester Nawrocki /* Set capture capability only for boards with the MAX98090 CODEC */ 281bc3cf17bSSylwester Nawrocki if (codec_link->num_codecs > 1) { 282bc3cf17bSSylwester Nawrocki card->dai_link[0].dpcm_capture = 1; 283bc3cf17bSSylwester Nawrocki card->dai_link[1].dpcm_capture = 1; 284a8ad0c85SSylwester Nawrocki } 285a8ad0c85SSylwester Nawrocki 286bc3cf17bSSylwester Nawrocki priv->sclk_i2s = of_clk_get_by_name(cpu_dai, "i2s_opclk1"); 287bc3cf17bSSylwester Nawrocki if (IS_ERR(priv->sclk_i2s)) { 288bc3cf17bSSylwester Nawrocki ret = PTR_ERR(priv->sclk_i2s); 289d832d2b2SSylwester Nawrocki goto err_put_cpu_dai; 290bc3cf17bSSylwester Nawrocki } 291bc3cf17bSSylwester Nawrocki 292bc3cf17bSSylwester Nawrocki priv->clk_i2s_bus = of_clk_get_by_name(cpu_dai, "iis"); 293a8ad0c85SSylwester Nawrocki if (IS_ERR(priv->clk_i2s_bus)) { 294a8ad0c85SSylwester Nawrocki ret = PTR_ERR(priv->clk_i2s_bus); 295a8ad0c85SSylwester Nawrocki goto err_put_sclk; 296a8ad0c85SSylwester Nawrocki } 297a8ad0c85SSylwester Nawrocki 298aba611fcSSylwester Nawrocki ret = devm_snd_soc_register_card(dev, card); 299aba611fcSSylwester Nawrocki if (ret < 0) { 30027c6eaebSKuninori Morimoto dev_err_probe(dev, ret, "snd_soc_register_card() failed\n"); 301a8ad0c85SSylwester Nawrocki goto err_put_clk_i2s; 302aba611fcSSylwester Nawrocki } 303aba611fcSSylwester Nawrocki 3042abee12cSWen Yang of_node_put(cpu_dai); 3059b6d104aSWen Yang of_node_put(codec); 306aba611fcSSylwester Nawrocki return 0; 307aba611fcSSylwester Nawrocki 308a8ad0c85SSylwester Nawrocki err_put_clk_i2s: 309a8ad0c85SSylwester Nawrocki clk_put(priv->clk_i2s_bus); 310a8ad0c85SSylwester Nawrocki err_put_sclk: 311a8ad0c85SSylwester Nawrocki clk_put(priv->sclk_i2s); 312d832d2b2SSylwester Nawrocki err_put_cpu_dai: 313d832d2b2SSylwester Nawrocki of_node_put(cpu_dai); 314bc3cf17bSSylwester Nawrocki snd_soc_of_put_dai_link_codecs(codec_link); 3159b6d104aSWen Yang err_put_node: 3169b6d104aSWen Yang of_node_put(codec); 317aba611fcSSylwester Nawrocki return ret; 318aba611fcSSylwester Nawrocki } 319aba611fcSSylwester Nawrocki 320d530e675SUwe Kleine-König static void odroid_audio_remove(struct platform_device *pdev) 321aba611fcSSylwester Nawrocki { 322aba611fcSSylwester Nawrocki struct odroid_priv *priv = platform_get_drvdata(pdev); 323aba611fcSSylwester Nawrocki 324bc3cf17bSSylwester Nawrocki snd_soc_of_put_dai_link_codecs(&priv->card.dai_link[1]); 325a8ad0c85SSylwester Nawrocki clk_put(priv->sclk_i2s); 326a8ad0c85SSylwester Nawrocki clk_put(priv->clk_i2s_bus); 327aba611fcSSylwester Nawrocki } 328aba611fcSSylwester Nawrocki 329aba611fcSSylwester Nawrocki static const struct of_device_id odroid_audio_of_match[] = { 330d9e57512SSylwester Nawrocki { .compatible = "hardkernel,odroid-xu3-audio" }, 331d9e57512SSylwester Nawrocki { .compatible = "hardkernel,odroid-xu4-audio" }, 332aba611fcSSylwester Nawrocki { .compatible = "samsung,odroid-xu3-audio" }, 333aba611fcSSylwester Nawrocki { .compatible = "samsung,odroid-xu4-audio" }, 334aba611fcSSylwester Nawrocki { }, 335aba611fcSSylwester Nawrocki }; 336aba611fcSSylwester Nawrocki MODULE_DEVICE_TABLE(of, odroid_audio_of_match); 337aba611fcSSylwester Nawrocki 338aba611fcSSylwester Nawrocki static struct platform_driver odroid_audio_driver = { 339aba611fcSSylwester Nawrocki .driver = { 340aba611fcSSylwester Nawrocki .name = "odroid-audio", 341aba611fcSSylwester Nawrocki .of_match_table = odroid_audio_of_match, 342aba611fcSSylwester Nawrocki .pm = &snd_soc_pm_ops, 343aba611fcSSylwester Nawrocki }, 344aba611fcSSylwester Nawrocki .probe = odroid_audio_probe, 345d530e675SUwe Kleine-König .remove_new = odroid_audio_remove, 346aba611fcSSylwester Nawrocki }; 347aba611fcSSylwester Nawrocki module_platform_driver(odroid_audio_driver); 348aba611fcSSylwester Nawrocki 349aba611fcSSylwester Nawrocki MODULE_AUTHOR("Sylwester Nawrocki <s.nawrocki@samsung.com>"); 350aba611fcSSylwester Nawrocki MODULE_DESCRIPTION("Odroid XU3/XU4 audio support"); 351aba611fcSSylwester Nawrocki MODULE_LICENSE("GPL v2"); 352