1 // SPDX-License-Identifier: GPL-2.0 2 // 3 // Copyright (C) 2017 Samsung Electronics Co., Ltd. 4 5 #include <linux/clk.h> 6 #include <linux/clk-provider.h> 7 #include <linux/of.h> 8 #include <linux/of_device.h> 9 #include <linux/module.h> 10 #include <sound/soc.h> 11 #include <sound/pcm_params.h> 12 #include "i2s.h" 13 #include "i2s-regs.h" 14 15 struct odroid_priv { 16 struct snd_soc_card card; 17 struct clk *clk_i2s_bus; 18 struct clk *sclk_i2s; 19 20 /* Spinlock protecting fields below */ 21 spinlock_t lock; 22 unsigned int be_sample_rate; 23 bool be_active; 24 }; 25 26 static int odroid_card_fe_startup(struct snd_pcm_substream *substream) 27 { 28 struct snd_pcm_runtime *runtime = substream->runtime; 29 30 snd_pcm_hw_constraint_single(runtime, SNDRV_PCM_HW_PARAM_CHANNELS, 2); 31 32 return 0; 33 } 34 35 static int odroid_card_fe_hw_params(struct snd_pcm_substream *substream, 36 struct snd_pcm_hw_params *params) 37 { 38 struct snd_soc_pcm_runtime *rtd = substream->private_data; 39 struct odroid_priv *priv = snd_soc_card_get_drvdata(rtd->card); 40 unsigned long flags; 41 int ret = 0; 42 43 spin_lock_irqsave(&priv->lock, flags); 44 if (priv->be_active && priv->be_sample_rate != params_rate(params)) 45 ret = -EINVAL; 46 spin_unlock_irqrestore(&priv->lock, flags); 47 48 return ret; 49 } 50 51 static const struct snd_soc_ops odroid_card_fe_ops = { 52 .startup = odroid_card_fe_startup, 53 .hw_params = odroid_card_fe_hw_params, 54 }; 55 56 static int odroid_card_be_hw_params(struct snd_pcm_substream *substream, 57 struct snd_pcm_hw_params *params) 58 { 59 struct snd_soc_pcm_runtime *rtd = substream->private_data; 60 struct odroid_priv *priv = snd_soc_card_get_drvdata(rtd->card); 61 unsigned int pll_freq, rclk_freq, rfs; 62 unsigned long flags; 63 int ret; 64 65 switch (params_rate(params)) { 66 case 64000: 67 pll_freq = 196608001U; 68 rfs = 384; 69 break; 70 case 44100: 71 case 88200: 72 pll_freq = 180633609U; 73 rfs = 512; 74 break; 75 case 32000: 76 case 48000: 77 case 96000: 78 pll_freq = 196608001U; 79 rfs = 512; 80 break; 81 default: 82 return -EINVAL; 83 } 84 85 ret = clk_set_rate(priv->clk_i2s_bus, pll_freq / 2 + 1); 86 if (ret < 0) 87 return ret; 88 89 /* 90 * We add 2 to the rclk_freq value in order to avoid too low clock 91 * frequency values due to the EPLL output frequency not being exact 92 * multiple of the audio sampling rate. 93 */ 94 rclk_freq = params_rate(params) * rfs + 2; 95 96 ret = clk_set_rate(priv->sclk_i2s, rclk_freq); 97 if (ret < 0) 98 return ret; 99 100 if (rtd->num_codecs > 1) { 101 struct snd_soc_dai *codec_dai = rtd->codec_dais[1]; 102 103 ret = snd_soc_dai_set_sysclk(codec_dai, 0, rclk_freq, 104 SND_SOC_CLOCK_IN); 105 if (ret < 0) 106 return ret; 107 } 108 109 spin_lock_irqsave(&priv->lock, flags); 110 priv->be_sample_rate = params_rate(params); 111 spin_unlock_irqrestore(&priv->lock, flags); 112 113 return 0; 114 } 115 116 static int odroid_card_be_trigger(struct snd_pcm_substream *substream, int cmd) 117 { 118 struct snd_soc_pcm_runtime *rtd = substream->private_data; 119 struct odroid_priv *priv = snd_soc_card_get_drvdata(rtd->card); 120 unsigned long flags; 121 122 spin_lock_irqsave(&priv->lock, flags); 123 124 switch (cmd) { 125 case SNDRV_PCM_TRIGGER_START: 126 case SNDRV_PCM_TRIGGER_RESUME: 127 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: 128 priv->be_active = true; 129 break; 130 131 case SNDRV_PCM_TRIGGER_STOP: 132 case SNDRV_PCM_TRIGGER_SUSPEND: 133 case SNDRV_PCM_TRIGGER_PAUSE_PUSH: 134 priv->be_active = false; 135 break; 136 } 137 138 spin_unlock_irqrestore(&priv->lock, flags); 139 140 return 0; 141 } 142 143 static const struct snd_soc_ops odroid_card_be_ops = { 144 .hw_params = odroid_card_be_hw_params, 145 .trigger = odroid_card_be_trigger, 146 }; 147 148 /* DAPM routes for backward compatibility with old DTS */ 149 static const struct snd_soc_dapm_route odroid_dapm_routes[] = { 150 { "I2S Playback", NULL, "Mixer DAI TX" }, 151 { "HiFi Playback", NULL, "Mixer DAI TX" }, 152 }; 153 154 static struct snd_soc_dai_link odroid_card_dais[] = { 155 { 156 /* Primary FE <-> BE link */ 157 .codec_name = "snd-soc-dummy", 158 .codec_dai_name = "snd-soc-dummy-dai", 159 .ops = &odroid_card_fe_ops, 160 .name = "Primary", 161 .stream_name = "Primary", 162 .platform_name = "3830000.i2s", 163 .dynamic = 1, 164 .dpcm_playback = 1, 165 }, { 166 /* BE <-> CODECs link */ 167 .name = "I2S Mixer", 168 .cpu_name = "snd-soc-dummy", 169 .cpu_dai_name = "snd-soc-dummy-dai", 170 .platform_name = "snd-soc-dummy", 171 .ops = &odroid_card_be_ops, 172 .no_pcm = 1, 173 .dpcm_playback = 1, 174 .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | 175 SND_SOC_DAIFMT_CBS_CFS, 176 }, { 177 /* Secondary FE <-> BE link */ 178 .playback_only = 1, 179 .codec_name = "snd-soc-dummy", 180 .codec_dai_name = "snd-soc-dummy-dai", 181 .ops = &odroid_card_fe_ops, 182 .name = "Secondary", 183 .stream_name = "Secondary", 184 .platform_name = "3830000.i2s-sec", 185 .dynamic = 1, 186 .dpcm_playback = 1, 187 } 188 }; 189 190 static int odroid_audio_probe(struct platform_device *pdev) 191 { 192 struct device *dev = &pdev->dev; 193 struct device_node *cpu_dai = NULL; 194 struct device_node *cpu, *codec; 195 struct odroid_priv *priv; 196 struct snd_soc_card *card; 197 struct snd_soc_dai_link *link, *codec_link; 198 int num_pcms, ret, i; 199 struct of_phandle_args args = {}; 200 201 priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); 202 if (!priv) 203 return -ENOMEM; 204 205 card = &priv->card; 206 card->dev = dev; 207 208 card->owner = THIS_MODULE; 209 card->fully_routed = true; 210 211 spin_lock_init(&priv->lock); 212 snd_soc_card_set_drvdata(card, priv); 213 214 ret = snd_soc_of_parse_card_name(card, "model"); 215 if (ret < 0) 216 return ret; 217 218 if (of_property_read_bool(dev->of_node, "samsung,audio-widgets")) { 219 ret = snd_soc_of_parse_audio_simple_widgets(card, 220 "samsung,audio-widgets"); 221 if (ret < 0) 222 return ret; 223 } 224 225 if (of_property_read_bool(dev->of_node, "samsung,audio-routing")) { 226 ret = snd_soc_of_parse_audio_routing(card, 227 "samsung,audio-routing"); 228 if (ret < 0) 229 return ret; 230 } 231 232 card->dai_link = odroid_card_dais; 233 card->num_links = ARRAY_SIZE(odroid_card_dais); 234 235 cpu = of_get_child_by_name(dev->of_node, "cpu"); 236 codec = of_get_child_by_name(dev->of_node, "codec"); 237 link = card->dai_link; 238 codec_link = &card->dai_link[1]; 239 240 /* 241 * For backwards compatibility create the secondary CPU DAI link only 242 * if there are 2 CPU DAI entries in the cpu sound-dai property in DT. 243 * Also add required DAPM routes not available in old DTS. 244 */ 245 num_pcms = of_count_phandle_with_args(cpu, "sound-dai", 246 "#sound-dai-cells"); 247 if (num_pcms == 1) { 248 card->dapm_routes = odroid_dapm_routes; 249 card->num_dapm_routes = ARRAY_SIZE(odroid_dapm_routes); 250 card->num_links--; 251 } 252 253 for (i = 0; i < num_pcms; i++, link += 2) { 254 ret = of_parse_phandle_with_args(cpu, "sound-dai", 255 "#sound-dai-cells", i, &args); 256 if (ret < 0) 257 break; 258 259 if (!args.np) { 260 dev_err(dev, "sound-dai property parse error: %d\n", ret); 261 ret = -EINVAL; 262 break; 263 } 264 265 ret = snd_soc_get_dai_name(&args, &link->cpu_dai_name); 266 of_node_put(args.np); 267 268 if (ret < 0) 269 break; 270 } 271 if (ret == 0) { 272 cpu_dai = of_parse_phandle(cpu, "sound-dai", 0); 273 if (!cpu_dai) 274 ret = -EINVAL; 275 } 276 277 of_node_put(cpu); 278 of_node_put(codec); 279 if (ret < 0) 280 return ret; 281 282 ret = snd_soc_of_get_dai_link_codecs(dev, codec, codec_link); 283 if (ret < 0) 284 goto err_put_cpu_dai; 285 286 /* Set capture capability only for boards with the MAX98090 CODEC */ 287 if (codec_link->num_codecs > 1) { 288 card->dai_link[0].dpcm_capture = 1; 289 card->dai_link[1].dpcm_capture = 1; 290 } 291 292 priv->sclk_i2s = of_clk_get_by_name(cpu_dai, "i2s_opclk1"); 293 if (IS_ERR(priv->sclk_i2s)) { 294 ret = PTR_ERR(priv->sclk_i2s); 295 goto err_put_cpu_dai; 296 } 297 298 priv->clk_i2s_bus = of_clk_get_by_name(cpu_dai, "iis"); 299 if (IS_ERR(priv->clk_i2s_bus)) { 300 ret = PTR_ERR(priv->clk_i2s_bus); 301 goto err_put_sclk; 302 } 303 of_node_put(cpu_dai); 304 305 ret = devm_snd_soc_register_card(dev, card); 306 if (ret < 0) { 307 dev_err(dev, "snd_soc_register_card() failed: %d\n", ret); 308 goto err_put_clk_i2s; 309 } 310 311 return 0; 312 313 err_put_clk_i2s: 314 clk_put(priv->clk_i2s_bus); 315 err_put_sclk: 316 clk_put(priv->sclk_i2s); 317 err_put_cpu_dai: 318 of_node_put(cpu_dai); 319 snd_soc_of_put_dai_link_codecs(codec_link); 320 return ret; 321 } 322 323 static int odroid_audio_remove(struct platform_device *pdev) 324 { 325 struct odroid_priv *priv = platform_get_drvdata(pdev); 326 327 snd_soc_of_put_dai_link_codecs(&priv->card.dai_link[1]); 328 clk_put(priv->sclk_i2s); 329 clk_put(priv->clk_i2s_bus); 330 331 return 0; 332 } 333 334 static const struct of_device_id odroid_audio_of_match[] = { 335 { .compatible = "hardkernel,odroid-xu3-audio" }, 336 { .compatible = "hardkernel,odroid-xu4-audio" }, 337 { .compatible = "samsung,odroid-xu3-audio" }, 338 { .compatible = "samsung,odroid-xu4-audio" }, 339 { }, 340 }; 341 MODULE_DEVICE_TABLE(of, odroid_audio_of_match); 342 343 static struct platform_driver odroid_audio_driver = { 344 .driver = { 345 .name = "odroid-audio", 346 .of_match_table = odroid_audio_of_match, 347 .pm = &snd_soc_pm_ops, 348 }, 349 .probe = odroid_audio_probe, 350 .remove = odroid_audio_remove, 351 }; 352 module_platform_driver(odroid_audio_driver); 353 354 MODULE_AUTHOR("Sylwester Nawrocki <s.nawrocki@samsung.com>"); 355 MODULE_DESCRIPTION("Odroid XU3/XU4 audio support"); 356 MODULE_LICENSE("GPL v2"); 357