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