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