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 "sof_realtek_common.h" 16 17 /* 18 * Current only 2-amp configuration is supported for rt1011 19 */ 20 static const struct snd_soc_dapm_route rt1011_dapm_routes[] = { 21 /* speaker */ 22 { "Left Spk", NULL, "Left SPO" }, 23 { "Right Spk", NULL, "Right SPO" }, 24 }; 25 26 /* 27 * Make sure device's Unique ID follows this configuration: 28 * 29 * Two speakers: 30 * 0: left, 1: right 31 * Four speakers: 32 * 0: Woofer left, 1: Woofer right 33 * 2: Tweeter left, 3: Tweeter right 34 */ 35 static struct snd_soc_codec_conf rt1011_codec_confs[] = { 36 { 37 .dlc = COMP_CODEC_CONF(RT1011_DEV0_NAME), 38 .name_prefix = "Left", 39 }, 40 { 41 .dlc = COMP_CODEC_CONF(RT1011_DEV1_NAME), 42 .name_prefix = "Right", 43 }, 44 }; 45 46 static struct snd_soc_dai_link_component rt1011_dai_link_components[] = { 47 { 48 .name = RT1011_DEV0_NAME, 49 .dai_name = RT1011_CODEC_DAI, 50 }, 51 { 52 .name = RT1011_DEV1_NAME, 53 .dai_name = RT1011_CODEC_DAI, 54 }, 55 }; 56 57 static const struct { 58 unsigned int tx; 59 unsigned int rx; 60 } rt1011_tdm_mask[] = { 61 {.tx = 0x4, .rx = 0x1}, 62 {.tx = 0x8, .rx = 0x2}, 63 }; 64 65 static int rt1011_hw_params(struct snd_pcm_substream *substream, 66 struct snd_pcm_hw_params *params) 67 { 68 struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream); 69 struct snd_soc_dai *codec_dai; 70 int srate, i, ret = 0; 71 72 srate = params_rate(params); 73 74 for_each_rtd_codec_dais(rtd, i, codec_dai) { 75 /* 100 Fs to drive 24 bit data */ 76 ret = snd_soc_dai_set_pll(codec_dai, 0, RT1011_PLL1_S_BCLK, 77 100 * srate, 256 * srate); 78 if (ret < 0) { 79 dev_err(codec_dai->dev, "fail to set pll, ret %d\n", 80 ret); 81 return ret; 82 } 83 84 ret = snd_soc_dai_set_sysclk(codec_dai, RT1011_FS_SYS_PRE_S_PLL1, 85 256 * srate, SND_SOC_CLOCK_IN); 86 if (ret < 0) { 87 dev_err(codec_dai->dev, "fail to set sysclk, ret %d\n", 88 ret); 89 return ret; 90 } 91 92 if (i >= ARRAY_SIZE(rt1011_tdm_mask)) { 93 dev_err(codec_dai->dev, "invalid codec index %d\n", 94 i); 95 return -ENODEV; 96 } 97 98 ret = snd_soc_dai_set_tdm_slot(codec_dai, rt1011_tdm_mask[i].tx, 99 rt1011_tdm_mask[i].rx, 4, 100 params_width(params)); 101 if (ret < 0) { 102 dev_err(codec_dai->dev, "fail to set tdm slot, ret %d\n", 103 ret); 104 return ret; 105 } 106 } 107 108 return 0; 109 } 110 111 static const struct snd_soc_ops rt1011_ops = { 112 .hw_params = rt1011_hw_params, 113 }; 114 115 static int rt1011_init(struct snd_soc_pcm_runtime *rtd) 116 { 117 struct snd_soc_card *card = rtd->card; 118 int ret; 119 120 ret = snd_soc_dapm_add_routes(&card->dapm, rt1011_dapm_routes, 121 ARRAY_SIZE(rt1011_dapm_routes)); 122 if (ret) 123 dev_err(rtd->dev, "Speaker map addition failed: %d\n", ret); 124 return ret; 125 } 126 127 void sof_rt1011_dai_link(struct snd_soc_dai_link *link) 128 { 129 link->codecs = rt1011_dai_link_components; 130 link->num_codecs = ARRAY_SIZE(rt1011_dai_link_components); 131 link->init = rt1011_init; 132 link->ops = &rt1011_ops; 133 } 134 135 void sof_rt1011_codec_conf(struct snd_soc_card *card) 136 { 137 card->codec_conf = rt1011_codec_confs; 138 card->num_configs = ARRAY_SIZE(rt1011_codec_confs); 139 } 140 141 /* 142 * rt1015: i2c mode driver for ALC1015 and ALC1015Q 143 * rt1015p: auto-mode driver for ALC1015, ALC1015Q, and ALC1015Q-VB 144 * 145 * For stereo output, there are always two amplifiers on the board. 146 * However, the ACPI implements only one device instance (UID=0) if they 147 * are sharing the same enable pin. The code will detect the number of 148 * device instance and use corresponding DAPM structures for 149 * initialization. 150 */ 151 static const struct snd_soc_dapm_route rt1015p_1dev_dapm_routes[] = { 152 /* speaker */ 153 { "Left Spk", NULL, "Speaker" }, 154 { "Right Spk", NULL, "Speaker" }, 155 }; 156 157 static const struct snd_soc_dapm_route rt1015p_2dev_dapm_routes[] = { 158 /* speaker */ 159 { "Left Spk", NULL, "Left Speaker" }, 160 { "Right Spk", NULL, "Right Speaker" }, 161 }; 162 163 static struct snd_soc_codec_conf rt1015p_codec_confs[] = { 164 { 165 .dlc = COMP_CODEC_CONF(RT1015P_DEV0_NAME), 166 .name_prefix = "Left", 167 }, 168 { 169 .dlc = COMP_CODEC_CONF(RT1015P_DEV1_NAME), 170 .name_prefix = "Right", 171 }, 172 }; 173 174 static struct snd_soc_dai_link_component rt1015p_dai_link_components[] = { 175 { 176 .name = RT1015P_DEV0_NAME, 177 .dai_name = RT1015P_CODEC_DAI, 178 }, 179 { 180 .name = RT1015P_DEV1_NAME, 181 .dai_name = RT1015P_CODEC_DAI, 182 }, 183 }; 184 185 static int rt1015p_get_num_codecs(void) 186 { 187 static int dev_num; 188 189 if (dev_num) 190 return dev_num; 191 192 if (!acpi_dev_present("RTL1015", "1", -1)) 193 dev_num = 1; 194 else 195 dev_num = 2; 196 197 return dev_num; 198 } 199 200 static int rt1015p_hw_params(struct snd_pcm_substream *substream, 201 struct snd_pcm_hw_params *params) 202 { 203 /* reserved for debugging purpose */ 204 205 return 0; 206 } 207 208 static const struct snd_soc_ops rt1015p_ops = { 209 .hw_params = rt1015p_hw_params, 210 }; 211 212 static int rt1015p_init(struct snd_soc_pcm_runtime *rtd) 213 { 214 struct snd_soc_card *card = rtd->card; 215 int ret; 216 217 if (rt1015p_get_num_codecs() == 1) 218 ret = snd_soc_dapm_add_routes(&card->dapm, rt1015p_1dev_dapm_routes, 219 ARRAY_SIZE(rt1015p_1dev_dapm_routes)); 220 else 221 ret = snd_soc_dapm_add_routes(&card->dapm, rt1015p_2dev_dapm_routes, 222 ARRAY_SIZE(rt1015p_2dev_dapm_routes)); 223 if (ret) 224 dev_err(rtd->dev, "Speaker map addition failed: %d\n", ret); 225 return ret; 226 } 227 228 void sof_rt1015p_dai_link(struct snd_soc_dai_link *link) 229 { 230 link->codecs = rt1015p_dai_link_components; 231 link->num_codecs = rt1015p_get_num_codecs(); 232 link->init = rt1015p_init; 233 link->ops = &rt1015p_ops; 234 } 235 236 void sof_rt1015p_codec_conf(struct snd_soc_card *card) 237 { 238 if (rt1015p_get_num_codecs() == 1) 239 return; 240 241 card->codec_conf = rt1015p_codec_confs; 242 card->num_configs = ARRAY_SIZE(rt1015p_codec_confs); 243 } 244