^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) //
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) // ASoC machine driver for Snow boards
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) #include <linux/clk.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) #include <linux/platform_device.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) #include <linux/of.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) #include <linux/of_device.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) #include <sound/pcm_params.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #include <sound/soc.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include "i2s.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #define FIN_PLL_RATE 24000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) SND_SOC_DAILINK_DEFS(links,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) DAILINK_COMP_ARRAY(COMP_EMPTY()),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) DAILINK_COMP_ARRAY(COMP_EMPTY()),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) DAILINK_COMP_ARRAY(COMP_EMPTY()));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) struct snow_priv {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) struct snd_soc_dai_link dai_link;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) struct clk *clk_i2s_bus;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) static int snow_card_hw_params(struct snd_pcm_substream *substream,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) struct snd_pcm_hw_params *params)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) static const unsigned int pll_rate[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) 73728000U, 67737602U, 49152000U, 45158401U, 32768001U
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) struct snow_priv *priv = snd_soc_card_get_drvdata(rtd->card);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) int bfs, psr, rfs, bitwidth;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) unsigned long int rclk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) long int freq = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) int ret, i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) bitwidth = snd_pcm_format_width(params_format(params));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) if (bitwidth < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) dev_err(rtd->card->dev, "Invalid bit-width: %d\n", bitwidth);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) return bitwidth;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) if (bitwidth != 16 && bitwidth != 24) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) dev_err(rtd->card->dev, "Unsupported bit-width: %d\n", bitwidth);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) bfs = 2 * bitwidth;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) switch (params_rate(params)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) case 16000:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) case 22050:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) case 24000:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) case 32000:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) case 44100:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) case 48000:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) case 88200:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) case 96000:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) rfs = 8 * bfs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) case 64000:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) rfs = 384;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) case 8000:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) case 11025:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) case 12000:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) rfs = 16 * bfs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) rclk = params_rate(params) * rfs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) for (psr = 8; psr > 0; psr /= 2) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) for (i = 0; i < ARRAY_SIZE(pll_rate); i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) if ((pll_rate[i] - rclk * psr) <= 2) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) freq = pll_rate[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) if (freq < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) dev_err(rtd->card->dev, "Unsupported RCLK rate: %lu\n", rclk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) ret = clk_set_rate(priv->clk_i2s_bus, freq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) dev_err(rtd->card->dev, "I2S bus clock rate set failed\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) static const struct snd_soc_ops snow_card_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) .hw_params = snow_card_hw_params,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) static int snow_late_probe(struct snd_soc_card *card)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) struct snd_soc_pcm_runtime *rtd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) struct snd_soc_dai *codec_dai;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) rtd = snd_soc_get_pcm_runtime(card, &card->dai_link[0]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) /* In the multi-codec case codec_dais 0 is MAX98095 and 1 is HDMI. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) if (rtd->num_codecs > 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) codec_dai = asoc_rtd_to_codec(rtd, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) codec_dai = asoc_rtd_to_codec(rtd, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) /* Set the MCLK rate for the codec */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) return snd_soc_dai_set_sysclk(codec_dai, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) FIN_PLL_RATE, SND_SOC_CLOCK_IN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) static struct snd_soc_card snow_snd = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) .name = "Snow-I2S",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) .owner = THIS_MODULE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) .late_probe = snow_late_probe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) static int snow_probe(struct platform_device *pdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) struct device *dev = &pdev->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) struct snd_soc_card *card = &snow_snd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) struct device_node *cpu, *codec;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) struct snd_soc_dai_link *link;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) struct snow_priv *priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) if (!priv)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) link = &priv->dai_link;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) link->dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) SND_SOC_DAIFMT_CBS_CFS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) link->name = "Primary";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) link->stream_name = link->name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) link->cpus = links_cpus;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) link->num_cpus = ARRAY_SIZE(links_cpus);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) link->codecs = links_codecs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) link->num_codecs = ARRAY_SIZE(links_codecs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) link->platforms = links_platforms;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) link->num_platforms = ARRAY_SIZE(links_platforms);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) card->dai_link = link;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) card->num_links = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) card->dev = dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) /* Try new DT bindings with HDMI support first. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) cpu = of_get_child_by_name(dev->of_node, "cpu");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) if (cpu) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) link->ops = &snow_card_ops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) link->cpus->of_node = of_parse_phandle(cpu, "sound-dai", 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) of_node_put(cpu);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) if (!link->cpus->of_node) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) dev_err(dev, "Failed parsing cpu/sound-dai property\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) codec = of_get_child_by_name(dev->of_node, "codec");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) ret = snd_soc_of_get_dai_link_codecs(dev, codec, link);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) of_node_put(codec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) of_node_put(link->cpus->of_node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) dev_err(dev, "Failed parsing codec node\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) priv->clk_i2s_bus = of_clk_get_by_name(link->cpus->of_node,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) "i2s_opclk0");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) if (IS_ERR(priv->clk_i2s_bus)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) snd_soc_of_put_dai_link_codecs(link);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) of_node_put(link->cpus->of_node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) return PTR_ERR(priv->clk_i2s_bus);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) link->codecs->dai_name = "HiFi",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) link->cpus->of_node = of_parse_phandle(dev->of_node,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) "samsung,i2s-controller", 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) if (!link->cpus->of_node) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) dev_err(dev, "i2s-controller property parse error\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) link->codecs->of_node = of_parse_phandle(dev->of_node,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) "samsung,audio-codec", 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) if (!link->codecs->of_node) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) of_node_put(link->cpus->of_node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) dev_err(dev, "audio-codec property parse error\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) link->platforms->of_node = link->cpus->of_node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) /* Update card-name if provided through DT, else use default name */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) snd_soc_of_parse_card_name(card, "samsung,model");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) snd_soc_card_set_drvdata(card, priv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) ret = devm_snd_soc_register_card(dev, card);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) if (ret != -EPROBE_DEFER)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) dev_err(&pdev->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) "snd_soc_register_card failed (%d)\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) static int snow_remove(struct platform_device *pdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) struct snow_priv *priv = platform_get_drvdata(pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) struct snd_soc_dai_link *link = &priv->dai_link;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) of_node_put(link->cpus->of_node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) of_node_put(link->codecs->of_node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) snd_soc_of_put_dai_link_codecs(link);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) clk_put(priv->clk_i2s_bus);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) static const struct of_device_id snow_of_match[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) { .compatible = "google,snow-audio-max98090", },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) { .compatible = "google,snow-audio-max98091", },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) { .compatible = "google,snow-audio-max98095", },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) {},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) MODULE_DEVICE_TABLE(of, snow_of_match);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) static struct platform_driver snow_driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) .driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) .name = "snow-audio",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) .pm = &snd_soc_pm_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) .of_match_table = snow_of_match,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) .probe = snow_probe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) .remove = snow_remove,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) module_platform_driver(snow_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) MODULE_DESCRIPTION("ALSA SoC Audio machine driver for Snow");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) MODULE_LICENSE("GPL");