1 // SPDX-License-Identifier: GPL-2.0-only 2 // 3 // Copyright(c) 2020 Intel Corporation. All rights reserved. 4 5 #include <linux/device.h> 6 #include <linux/kernel.h> 7 #include <sound/pcm.h> 8 #include <sound/pcm_params.h> 9 #include <sound/soc.h> 10 #include <sound/soc-acpi.h> 11 #include <sound/soc-dai.h> 12 #include <sound/soc-dapm.h> 13 #include <sound/sof.h> 14 #include <uapi/sound/asound.h> 15 #include "../../codecs/rt1011.h" 16 #include "../../codecs/rt1015.h" 17 #include "../../codecs/rt1308.h" 18 #include "sof_realtek_common.h" 19 20 /* 21 * Current only 2-amp configuration is supported for rt1011 22 */ 23 static const struct snd_soc_dapm_route speaker_map_lr[] = { 24 /* speaker */ 25 { "Left Spk", NULL, "Left SPO" }, 26 { "Right Spk", NULL, "Right SPO" }, 27 }; 28 29 /* 30 * Make sure device's Unique ID follows this configuration: 31 * 32 * Two speakers: 33 * 0: left, 1: right 34 * Four speakers: 35 * 0: Woofer left, 1: Woofer right 36 * 2: Tweeter left, 3: Tweeter right 37 */ 38 static struct snd_soc_codec_conf rt1011_codec_confs[] = { 39 { 40 .dlc = COMP_CODEC_CONF(RT1011_DEV0_NAME), 41 .name_prefix = "Left", 42 }, 43 { 44 .dlc = COMP_CODEC_CONF(RT1011_DEV1_NAME), 45 .name_prefix = "Right", 46 }, 47 }; 48 49 static struct snd_soc_dai_link_component rt1011_dai_link_components[] = { 50 { 51 .name = RT1011_DEV0_NAME, 52 .dai_name = RT1011_CODEC_DAI, 53 }, 54 { 55 .name = RT1011_DEV1_NAME, 56 .dai_name = RT1011_CODEC_DAI, 57 }, 58 }; 59 60 static const struct { 61 unsigned int tx; 62 unsigned int rx; 63 } rt1011_tdm_mask[] = { 64 {.tx = 0x4, .rx = 0x1}, 65 {.tx = 0x8, .rx = 0x2}, 66 }; 67 68 static int rt1011_hw_params(struct snd_pcm_substream *substream, 69 struct snd_pcm_hw_params *params) 70 { 71 struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream); 72 struct snd_soc_dai *codec_dai; 73 int srate, i, ret = 0; 74 75 srate = params_rate(params); 76 77 for_each_rtd_codec_dais(rtd, i, codec_dai) { 78 /* 100 Fs to drive 24 bit data */ 79 ret = snd_soc_dai_set_pll(codec_dai, 0, RT1011_PLL1_S_BCLK, 80 100 * srate, 256 * srate); 81 if (ret < 0) { 82 dev_err(codec_dai->dev, "fail to set pll, ret %d\n", 83 ret); 84 return ret; 85 } 86 87 ret = snd_soc_dai_set_sysclk(codec_dai, RT1011_FS_SYS_PRE_S_PLL1, 88 256 * srate, SND_SOC_CLOCK_IN); 89 if (ret < 0) { 90 dev_err(codec_dai->dev, "fail to set sysclk, ret %d\n", 91 ret); 92 return ret; 93 } 94 95 if (i >= ARRAY_SIZE(rt1011_tdm_mask)) { 96 dev_err(codec_dai->dev, "invalid codec index %d\n", 97 i); 98 return -ENODEV; 99 } 100 101 ret = snd_soc_dai_set_tdm_slot(codec_dai, rt1011_tdm_mask[i].tx, 102 rt1011_tdm_mask[i].rx, 4, 103 params_width(params)); 104 if (ret < 0) { 105 dev_err(codec_dai->dev, "fail to set tdm slot, ret %d\n", 106 ret); 107 return ret; 108 } 109 } 110 111 return 0; 112 } 113 114 static const struct snd_soc_ops rt1011_ops = { 115 .hw_params = rt1011_hw_params, 116 }; 117 118 static int rt1011_init(struct snd_soc_pcm_runtime *rtd) 119 { 120 struct snd_soc_card *card = rtd->card; 121 int ret; 122 123 ret = snd_soc_dapm_add_routes(&card->dapm, speaker_map_lr, 124 ARRAY_SIZE(speaker_map_lr)); 125 if (ret) 126 dev_err(rtd->dev, "Speaker map addition failed: %d\n", ret); 127 return ret; 128 } 129 130 void sof_rt1011_dai_link(struct snd_soc_dai_link *link) 131 { 132 link->codecs = rt1011_dai_link_components; 133 link->num_codecs = ARRAY_SIZE(rt1011_dai_link_components); 134 link->init = rt1011_init; 135 link->ops = &rt1011_ops; 136 } 137 EXPORT_SYMBOL_NS(sof_rt1011_dai_link, SND_SOC_INTEL_SOF_REALTEK_COMMON); 138 139 void sof_rt1011_codec_conf(struct snd_soc_card *card) 140 { 141 card->codec_conf = rt1011_codec_confs; 142 card->num_configs = ARRAY_SIZE(rt1011_codec_confs); 143 } 144 EXPORT_SYMBOL_NS(sof_rt1011_codec_conf, SND_SOC_INTEL_SOF_REALTEK_COMMON); 145 146 /* 147 * rt1015: i2c mode driver for ALC1015 and ALC1015Q 148 * rt1015p: auto-mode driver for ALC1015, ALC1015Q, and ALC1015Q-VB 149 * 150 * For stereo output, there are always two amplifiers on the board. 151 * However, the ACPI implements only one device instance (UID=0) if they 152 * are sharing the same enable pin. The code will detect the number of 153 * device instance and use corresponding DAPM structures for 154 * initialization. 155 */ 156 static const struct snd_soc_dapm_route rt1015p_1dev_dapm_routes[] = { 157 /* speaker */ 158 { "Left Spk", NULL, "Speaker" }, 159 { "Right Spk", NULL, "Speaker" }, 160 }; 161 162 static const struct snd_soc_dapm_route rt1015p_2dev_dapm_routes[] = { 163 /* speaker */ 164 { "Left Spk", NULL, "Left Speaker" }, 165 { "Right Spk", NULL, "Right Speaker" }, 166 }; 167 168 static struct snd_soc_codec_conf rt1015p_codec_confs[] = { 169 { 170 .dlc = COMP_CODEC_CONF(RT1015P_DEV0_NAME), 171 .name_prefix = "Left", 172 }, 173 { 174 .dlc = COMP_CODEC_CONF(RT1015P_DEV1_NAME), 175 .name_prefix = "Right", 176 }, 177 }; 178 179 static struct snd_soc_dai_link_component rt1015p_dai_link_components[] = { 180 { 181 .name = RT1015P_DEV0_NAME, 182 .dai_name = RT1015P_CODEC_DAI, 183 }, 184 { 185 .name = RT1015P_DEV1_NAME, 186 .dai_name = RT1015P_CODEC_DAI, 187 }, 188 }; 189 190 static int rt1015p_get_num_codecs(void) 191 { 192 static int dev_num; 193 194 if (dev_num) 195 return dev_num; 196 197 if (!acpi_dev_present("RTL1015", "1", -1)) 198 dev_num = 1; 199 else 200 dev_num = 2; 201 202 return dev_num; 203 } 204 205 static int rt1015p_hw_params(struct snd_pcm_substream *substream, 206 struct snd_pcm_hw_params *params) 207 { 208 /* reserved for debugging purpose */ 209 210 return 0; 211 } 212 213 static const struct snd_soc_ops rt1015p_ops = { 214 .hw_params = rt1015p_hw_params, 215 }; 216 217 static int rt1015p_init(struct snd_soc_pcm_runtime *rtd) 218 { 219 struct snd_soc_card *card = rtd->card; 220 int ret; 221 222 if (rt1015p_get_num_codecs() == 1) 223 ret = snd_soc_dapm_add_routes(&card->dapm, rt1015p_1dev_dapm_routes, 224 ARRAY_SIZE(rt1015p_1dev_dapm_routes)); 225 else 226 ret = snd_soc_dapm_add_routes(&card->dapm, rt1015p_2dev_dapm_routes, 227 ARRAY_SIZE(rt1015p_2dev_dapm_routes)); 228 if (ret) 229 dev_err(rtd->dev, "Speaker map addition failed: %d\n", ret); 230 return ret; 231 } 232 233 void sof_rt1015p_dai_link(struct snd_soc_dai_link *link) 234 { 235 link->codecs = rt1015p_dai_link_components; 236 link->num_codecs = rt1015p_get_num_codecs(); 237 link->init = rt1015p_init; 238 link->ops = &rt1015p_ops; 239 } 240 EXPORT_SYMBOL_NS(sof_rt1015p_dai_link, SND_SOC_INTEL_SOF_REALTEK_COMMON); 241 242 void sof_rt1015p_codec_conf(struct snd_soc_card *card) 243 { 244 if (rt1015p_get_num_codecs() == 1) 245 return; 246 247 card->codec_conf = rt1015p_codec_confs; 248 card->num_configs = ARRAY_SIZE(rt1015p_codec_confs); 249 } 250 EXPORT_SYMBOL_NS(sof_rt1015p_codec_conf, SND_SOC_INTEL_SOF_REALTEK_COMMON); 251 252 /* 253 * RT1015 audio amplifier 254 */ 255 256 static const struct { 257 unsigned int tx; 258 unsigned int rx; 259 } rt1015_tdm_mask[] = { 260 {.tx = 0x0, .rx = 0x1}, 261 {.tx = 0x0, .rx = 0x2}, 262 }; 263 264 static int rt1015_hw_params(struct snd_pcm_substream *substream, 265 struct snd_pcm_hw_params *params) 266 { 267 struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream); 268 struct snd_soc_dai_link *dai_link = rtd->dai_link; 269 struct snd_soc_dai *codec_dai; 270 int i, clk_freq, ret; 271 272 clk_freq = sof_dai_get_bclk(rtd); 273 274 if (clk_freq <= 0) { 275 dev_err(rtd->dev, "fail to get bclk freq, ret %d\n", clk_freq); 276 return -EINVAL; 277 } 278 279 for_each_rtd_codec_dais(rtd, i, codec_dai) { 280 ret = snd_soc_dai_set_pll(codec_dai, 0, RT1015_PLL_S_BCLK, 281 clk_freq, 282 params_rate(params) * 256); 283 if (ret) { 284 dev_err(codec_dai->dev, "fail to set pll, ret %d\n", 285 ret); 286 return ret; 287 } 288 289 ret = snd_soc_dai_set_sysclk(codec_dai, RT1015_SCLK_S_PLL, 290 params_rate(params) * 256, 291 SND_SOC_CLOCK_IN); 292 if (ret) { 293 dev_err(codec_dai->dev, "fail to set sysclk, ret %d\n", 294 ret); 295 return ret; 296 } 297 298 switch (dai_link->dai_fmt & SND_SOC_DAIFMT_FORMAT_MASK) { 299 case SND_SOC_DAIFMT_DSP_A: 300 case SND_SOC_DAIFMT_DSP_B: 301 /* 4-slot TDM */ 302 ret = snd_soc_dai_set_tdm_slot(codec_dai, 303 rt1015_tdm_mask[i].tx, 304 rt1015_tdm_mask[i].rx, 305 4, 306 params_width(params)); 307 if (ret < 0) { 308 dev_err(codec_dai->dev, "fail to set tdm slot, ret %d\n", 309 ret); 310 return ret; 311 } 312 break; 313 default: 314 dev_dbg(codec_dai->dev, "codec is in I2S mode\n"); 315 break; 316 } 317 } 318 319 return ret; 320 } 321 322 static struct snd_soc_ops rt1015_ops = { 323 .hw_params = rt1015_hw_params, 324 }; 325 326 static struct snd_soc_codec_conf rt1015_amp_conf[] = { 327 { 328 .dlc = COMP_CODEC_CONF(RT1015_DEV0_NAME), 329 .name_prefix = "Left", 330 }, 331 { 332 .dlc = COMP_CODEC_CONF(RT1015_DEV1_NAME), 333 .name_prefix = "Right", 334 }, 335 }; 336 337 static struct snd_soc_dai_link_component rt1015_components[] = { 338 { 339 .name = RT1015_DEV0_NAME, 340 .dai_name = RT1015_CODEC_DAI, 341 }, 342 { 343 .name = RT1015_DEV1_NAME, 344 .dai_name = RT1015_CODEC_DAI, 345 }, 346 }; 347 348 static int speaker_codec_init_lr(struct snd_soc_pcm_runtime *rtd) 349 { 350 return snd_soc_dapm_add_routes(&rtd->card->dapm, speaker_map_lr, 351 ARRAY_SIZE(speaker_map_lr)); 352 } 353 354 void sof_rt1015_codec_conf(struct snd_soc_card *card) 355 { 356 card->codec_conf = rt1015_amp_conf; 357 card->num_configs = ARRAY_SIZE(rt1015_amp_conf); 358 } 359 EXPORT_SYMBOL_NS(sof_rt1015_codec_conf, SND_SOC_INTEL_SOF_REALTEK_COMMON); 360 361 void sof_rt1015_dai_link(struct snd_soc_dai_link *link) 362 { 363 link->codecs = rt1015_components; 364 link->num_codecs = ARRAY_SIZE(rt1015_components); 365 link->init = speaker_codec_init_lr; 366 link->ops = &rt1015_ops; 367 } 368 EXPORT_SYMBOL_NS(sof_rt1015_dai_link, SND_SOC_INTEL_SOF_REALTEK_COMMON); 369 370 /* 371 * RT1308 audio amplifier 372 */ 373 static const struct snd_kcontrol_new rt1308_kcontrols[] = { 374 SOC_DAPM_PIN_SWITCH("Speakers"), 375 }; 376 377 static const struct snd_soc_dapm_widget rt1308_dapm_widgets[] = { 378 SND_SOC_DAPM_SPK("Speakers", NULL), 379 }; 380 381 static const struct snd_soc_dapm_route rt1308_dapm_routes[] = { 382 /* speaker */ 383 {"Speakers", NULL, "SPOL"}, 384 {"Speakers", NULL, "SPOR"}, 385 }; 386 387 static struct snd_soc_dai_link_component rt1308_components[] = { 388 { 389 .name = RT1308_DEV0_NAME, 390 .dai_name = RT1308_CODEC_DAI, 391 } 392 }; 393 394 static int rt1308_init(struct snd_soc_pcm_runtime *rtd) 395 { 396 struct snd_soc_card *card = rtd->card; 397 int ret; 398 399 ret = snd_soc_dapm_new_controls(&card->dapm, rt1308_dapm_widgets, 400 ARRAY_SIZE(rt1308_dapm_widgets)); 401 if (ret) { 402 dev_err(rtd->dev, "fail to add dapm controls, ret %d\n", ret); 403 return ret; 404 } 405 406 ret = snd_soc_add_card_controls(card, rt1308_kcontrols, 407 ARRAY_SIZE(rt1308_kcontrols)); 408 if (ret) { 409 dev_err(rtd->dev, "fail to add card controls, ret %d\n", ret); 410 return ret; 411 } 412 413 ret = snd_soc_dapm_add_routes(&card->dapm, rt1308_dapm_routes, 414 ARRAY_SIZE(rt1308_dapm_routes)); 415 416 if (ret) 417 dev_err(rtd->dev, "fail to add dapm routes, ret %d\n", ret); 418 419 return ret; 420 } 421 422 static int rt1308_hw_params(struct snd_pcm_substream *substream, 423 struct snd_pcm_hw_params *params) 424 { 425 struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream); 426 struct snd_soc_card *card = rtd->card; 427 struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 0); 428 int clk_id, clk_freq, pll_out; 429 int ret; 430 431 clk_id = RT1308_PLL_S_MCLK; 432 /* get the tplg configured mclk. */ 433 clk_freq = sof_dai_get_mclk(rtd); 434 435 pll_out = params_rate(params) * 512; 436 437 /* Set rt1308 pll */ 438 ret = snd_soc_dai_set_pll(codec_dai, 0, clk_id, clk_freq, pll_out); 439 if (ret < 0) { 440 dev_err(card->dev, "Failed to set RT1308 PLL: %d\n", ret); 441 return ret; 442 } 443 444 /* Set rt1308 sysclk */ 445 ret = snd_soc_dai_set_sysclk(codec_dai, RT1308_FS_SYS_S_PLL, pll_out, 446 SND_SOC_CLOCK_IN); 447 if (ret < 0) 448 dev_err(card->dev, "Failed to set RT1308 SYSCLK: %d\n", ret); 449 450 return ret; 451 } 452 453 static const struct snd_soc_ops rt1308_ops = { 454 .hw_params = rt1308_hw_params, 455 }; 456 457 void sof_rt1308_dai_link(struct snd_soc_dai_link *link) 458 { 459 link->codecs = rt1308_components; 460 link->num_codecs = ARRAY_SIZE(rt1308_components); 461 link->init = rt1308_init; 462 link->ops = &rt1308_ops; 463 } 464 EXPORT_SYMBOL_NS(sof_rt1308_dai_link, SND_SOC_INTEL_SOF_REALTEK_COMMON); 465 466 /* 467 * 2-amp Configuration for RT1019 468 */ 469 470 static const struct snd_soc_dapm_route rt1019p_dapm_routes[] = { 471 /* speaker */ 472 { "Left Spk", NULL, "Speaker" }, 473 { "Right Spk", NULL, "Speaker" }, 474 }; 475 476 static struct snd_soc_dai_link_component rt1019p_components[] = { 477 { 478 .name = RT1019P_DEV0_NAME, 479 .dai_name = RT1019P_CODEC_DAI, 480 }, 481 }; 482 483 static int rt1019p_init(struct snd_soc_pcm_runtime *rtd) 484 { 485 struct snd_soc_card *card = rtd->card; 486 int ret; 487 488 ret = snd_soc_dapm_add_routes(&card->dapm, rt1019p_dapm_routes, 489 ARRAY_SIZE(rt1019p_dapm_routes)); 490 if (ret) { 491 dev_err(rtd->dev, "Speaker map addition failed: %d\n", ret); 492 return ret; 493 } 494 return ret; 495 } 496 497 void sof_rt1019p_dai_link(struct snd_soc_dai_link *link) 498 { 499 link->codecs = rt1019p_components; 500 link->num_codecs = ARRAY_SIZE(rt1019p_components); 501 link->init = rt1019p_init; 502 } 503 EXPORT_SYMBOL_NS(sof_rt1019p_dai_link, SND_SOC_INTEL_SOF_REALTEK_COMMON); 504 505 MODULE_DESCRIPTION("ASoC Intel SOF Realtek helpers"); 506 MODULE_LICENSE("GPL"); 507