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 <uapi/sound/asound.h> 14 #include "../../codecs/rt1011.h" 15 #include "../../codecs/rt1015.h" 16 #include "sof_realtek_common.h" 17 18 /* 19 * Current only 2-amp configuration is supported for rt1011 20 */ 21 static const struct snd_soc_dapm_route speaker_map_lr[] = { 22 /* speaker */ 23 { "Left Spk", NULL, "Left SPO" }, 24 { "Right Spk", NULL, "Right SPO" }, 25 }; 26 27 /* 28 * Make sure device's Unique ID follows this configuration: 29 * 30 * Two speakers: 31 * 0: left, 1: right 32 * Four speakers: 33 * 0: Woofer left, 1: Woofer right 34 * 2: Tweeter left, 3: Tweeter right 35 */ 36 static struct snd_soc_codec_conf rt1011_codec_confs[] = { 37 { 38 .dlc = COMP_CODEC_CONF(RT1011_DEV0_NAME), 39 .name_prefix = "Left", 40 }, 41 { 42 .dlc = COMP_CODEC_CONF(RT1011_DEV1_NAME), 43 .name_prefix = "Right", 44 }, 45 }; 46 47 static struct snd_soc_dai_link_component rt1011_dai_link_components[] = { 48 { 49 .name = RT1011_DEV0_NAME, 50 .dai_name = RT1011_CODEC_DAI, 51 }, 52 { 53 .name = RT1011_DEV1_NAME, 54 .dai_name = RT1011_CODEC_DAI, 55 }, 56 }; 57 58 static const struct { 59 unsigned int tx; 60 unsigned int rx; 61 } rt1011_tdm_mask[] = { 62 {.tx = 0x4, .rx = 0x1}, 63 {.tx = 0x8, .rx = 0x2}, 64 }; 65 66 static int rt1011_hw_params(struct snd_pcm_substream *substream, 67 struct snd_pcm_hw_params *params) 68 { 69 struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream); 70 struct snd_soc_dai *codec_dai; 71 int srate, i, ret = 0; 72 73 srate = params_rate(params); 74 75 for_each_rtd_codec_dais(rtd, i, codec_dai) { 76 /* 100 Fs to drive 24 bit data */ 77 ret = snd_soc_dai_set_pll(codec_dai, 0, RT1011_PLL1_S_BCLK, 78 100 * srate, 256 * srate); 79 if (ret < 0) { 80 dev_err(codec_dai->dev, "fail to set pll, ret %d\n", 81 ret); 82 return ret; 83 } 84 85 ret = snd_soc_dai_set_sysclk(codec_dai, RT1011_FS_SYS_PRE_S_PLL1, 86 256 * srate, SND_SOC_CLOCK_IN); 87 if (ret < 0) { 88 dev_err(codec_dai->dev, "fail to set sysclk, ret %d\n", 89 ret); 90 return ret; 91 } 92 93 if (i >= ARRAY_SIZE(rt1011_tdm_mask)) { 94 dev_err(codec_dai->dev, "invalid codec index %d\n", 95 i); 96 return -ENODEV; 97 } 98 99 ret = snd_soc_dai_set_tdm_slot(codec_dai, rt1011_tdm_mask[i].tx, 100 rt1011_tdm_mask[i].rx, 4, 101 params_width(params)); 102 if (ret < 0) { 103 dev_err(codec_dai->dev, "fail to set tdm slot, ret %d\n", 104 ret); 105 return ret; 106 } 107 } 108 109 return 0; 110 } 111 112 static const struct snd_soc_ops rt1011_ops = { 113 .hw_params = rt1011_hw_params, 114 }; 115 116 static int rt1011_init(struct snd_soc_pcm_runtime *rtd) 117 { 118 struct snd_soc_card *card = rtd->card; 119 int ret; 120 121 ret = snd_soc_dapm_add_routes(&card->dapm, speaker_map_lr, 122 ARRAY_SIZE(speaker_map_lr)); 123 if (ret) 124 dev_err(rtd->dev, "Speaker map addition failed: %d\n", ret); 125 return ret; 126 } 127 128 void sof_rt1011_dai_link(struct snd_soc_dai_link *link) 129 { 130 link->codecs = rt1011_dai_link_components; 131 link->num_codecs = ARRAY_SIZE(rt1011_dai_link_components); 132 link->init = rt1011_init; 133 link->ops = &rt1011_ops; 134 } 135 136 void sof_rt1011_codec_conf(struct snd_soc_card *card) 137 { 138 card->codec_conf = rt1011_codec_confs; 139 card->num_configs = ARRAY_SIZE(rt1011_codec_confs); 140 } 141 142 /* 143 * rt1015: i2c mode driver for ALC1015 and ALC1015Q 144 * rt1015p: auto-mode driver for ALC1015, ALC1015Q, and ALC1015Q-VB 145 * 146 * For stereo output, there are always two amplifiers on the board. 147 * However, the ACPI implements only one device instance (UID=0) if they 148 * are sharing the same enable pin. The code will detect the number of 149 * device instance and use corresponding DAPM structures for 150 * initialization. 151 */ 152 static const struct snd_soc_dapm_route rt1015p_1dev_dapm_routes[] = { 153 /* speaker */ 154 { "Left Spk", NULL, "Speaker" }, 155 { "Right Spk", NULL, "Speaker" }, 156 }; 157 158 static const struct snd_soc_dapm_route rt1015p_2dev_dapm_routes[] = { 159 /* speaker */ 160 { "Left Spk", NULL, "Left Speaker" }, 161 { "Right Spk", NULL, "Right Speaker" }, 162 }; 163 164 static struct snd_soc_codec_conf rt1015p_codec_confs[] = { 165 { 166 .dlc = COMP_CODEC_CONF(RT1015P_DEV0_NAME), 167 .name_prefix = "Left", 168 }, 169 { 170 .dlc = COMP_CODEC_CONF(RT1015P_DEV1_NAME), 171 .name_prefix = "Right", 172 }, 173 }; 174 175 static struct snd_soc_dai_link_component rt1015p_dai_link_components[] = { 176 { 177 .name = RT1015P_DEV0_NAME, 178 .dai_name = RT1015P_CODEC_DAI, 179 }, 180 { 181 .name = RT1015P_DEV1_NAME, 182 .dai_name = RT1015P_CODEC_DAI, 183 }, 184 }; 185 186 static int rt1015p_get_num_codecs(void) 187 { 188 static int dev_num; 189 190 if (dev_num) 191 return dev_num; 192 193 if (!acpi_dev_present("RTL1015", "1", -1)) 194 dev_num = 1; 195 else 196 dev_num = 2; 197 198 return dev_num; 199 } 200 201 static int rt1015p_hw_params(struct snd_pcm_substream *substream, 202 struct snd_pcm_hw_params *params) 203 { 204 /* reserved for debugging purpose */ 205 206 return 0; 207 } 208 209 static const struct snd_soc_ops rt1015p_ops = { 210 .hw_params = rt1015p_hw_params, 211 }; 212 213 static int rt1015p_init(struct snd_soc_pcm_runtime *rtd) 214 { 215 struct snd_soc_card *card = rtd->card; 216 int ret; 217 218 if (rt1015p_get_num_codecs() == 1) 219 ret = snd_soc_dapm_add_routes(&card->dapm, rt1015p_1dev_dapm_routes, 220 ARRAY_SIZE(rt1015p_1dev_dapm_routes)); 221 else 222 ret = snd_soc_dapm_add_routes(&card->dapm, rt1015p_2dev_dapm_routes, 223 ARRAY_SIZE(rt1015p_2dev_dapm_routes)); 224 if (ret) 225 dev_err(rtd->dev, "Speaker map addition failed: %d\n", ret); 226 return ret; 227 } 228 229 void sof_rt1015p_dai_link(struct snd_soc_dai_link *link) 230 { 231 link->codecs = rt1015p_dai_link_components; 232 link->num_codecs = rt1015p_get_num_codecs(); 233 link->init = rt1015p_init; 234 link->ops = &rt1015p_ops; 235 } 236 237 void sof_rt1015p_codec_conf(struct snd_soc_card *card) 238 { 239 if (rt1015p_get_num_codecs() == 1) 240 return; 241 242 card->codec_conf = rt1015p_codec_confs; 243 card->num_configs = ARRAY_SIZE(rt1015p_codec_confs); 244 } 245 246 /* 247 * RT1015 audio amplifier 248 */ 249 250 static int rt1015_hw_params(struct snd_pcm_substream *substream, 251 struct snd_pcm_hw_params *params) 252 { 253 struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream); 254 struct snd_soc_dai *codec_dai; 255 int i, fs = 64, ret; 256 257 for_each_rtd_codec_dais(rtd, i, codec_dai) { 258 ret = snd_soc_dai_set_pll(codec_dai, 0, RT1015_PLL_S_BCLK, 259 params_rate(params) * fs, 260 params_rate(params) * 256); 261 if (ret) 262 return ret; 263 264 ret = snd_soc_dai_set_sysclk(codec_dai, RT1015_SCLK_S_PLL, 265 params_rate(params) * 256, 266 SND_SOC_CLOCK_IN); 267 if (ret) 268 return ret; 269 } 270 271 return 0; 272 } 273 274 static int rt1015_hw_params_pll_and_tdm(struct snd_pcm_substream *substream, 275 struct snd_pcm_hw_params *params) 276 { 277 struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream); 278 struct snd_soc_dai *codec_dai; 279 int i, fs = 100, ret; 280 281 for_each_rtd_codec_dais(rtd, i, codec_dai) { 282 ret = snd_soc_dai_set_pll(codec_dai, 0, RT1015_PLL_S_BCLK, 283 params_rate(params) * fs, 284 params_rate(params) * 256); 285 if (ret) 286 return ret; 287 288 ret = snd_soc_dai_set_sysclk(codec_dai, RT1015_SCLK_S_PLL, 289 params_rate(params) * 256, 290 SND_SOC_CLOCK_IN); 291 if (ret) 292 return ret; 293 } 294 /* rx slot 1 for RT1015_DEV0_NAME */ 295 ret = snd_soc_dai_set_tdm_slot(asoc_rtd_to_codec(rtd, 0), 296 0x0, 0x1, 4, 24); 297 if (ret) 298 return ret; 299 300 /* rx slot 2 for RT1015_DEV1_NAME */ 301 ret = snd_soc_dai_set_tdm_slot(asoc_rtd_to_codec(rtd, 1), 302 0x0, 0x2, 4, 24); 303 if (ret) 304 return ret; 305 306 return 0; 307 } 308 309 static struct snd_soc_ops rt1015_ops = { 310 .hw_params = rt1015_hw_params, 311 }; 312 313 static struct snd_soc_codec_conf rt1015_amp_conf[] = { 314 { 315 .dlc = COMP_CODEC_CONF(RT1015_DEV0_NAME), 316 .name_prefix = "Left", 317 }, 318 { 319 .dlc = COMP_CODEC_CONF(RT1015_DEV1_NAME), 320 .name_prefix = "Right", 321 }, 322 }; 323 324 static struct snd_soc_dai_link_component rt1015_components[] = { 325 { 326 .name = RT1015_DEV0_NAME, 327 .dai_name = RT1015_CODEC_DAI, 328 }, 329 { 330 .name = RT1015_DEV1_NAME, 331 .dai_name = RT1015_CODEC_DAI, 332 }, 333 }; 334 335 static int speaker_codec_init_lr(struct snd_soc_pcm_runtime *rtd) 336 { 337 return snd_soc_dapm_add_routes(&rtd->card->dapm, speaker_map_lr, 338 ARRAY_SIZE(speaker_map_lr)); 339 } 340 341 void sof_rt1015_codec_conf(struct snd_soc_card *card) 342 { 343 card->codec_conf = rt1015_amp_conf; 344 card->num_configs = ARRAY_SIZE(rt1015_amp_conf); 345 } 346 347 void sof_rt1015_dai_link(struct snd_soc_dai_link *link, unsigned int fs) 348 { 349 link->codecs = rt1015_components; 350 link->num_codecs = ARRAY_SIZE(rt1015_components); 351 link->init = speaker_codec_init_lr; 352 link->ops = &rt1015_ops; 353 354 if (fs == 100) 355 rt1015_ops.hw_params = rt1015_hw_params_pll_and_tdm; 356 } 357