xref: /linux/sound/soc/qcom/sc8280xp.c (revision f3caa0b02455409eec4673ddd8df72d8bcad4e98)
1 // SPDX-License-Identifier: GPL-2.0
2 // Copyright (c) 2022, Linaro Limited
3 
4 #include <dt-bindings/sound/qcom,q6afe.h>
5 #include <linux/module.h>
6 #include <linux/platform_device.h>
7 #include <sound/soc.h>
8 #include <sound/soc-dapm.h>
9 #include <sound/pcm.h>
10 #include <sound/pcm_params.h>
11 #include <linux/soundwire/sdw.h>
12 #include <sound/jack.h>
13 #include <linux/input-event-codes.h>
14 #include "qdsp6/q6afe.h"
15 #include "qdsp6/q6apm.h"
16 #include "qdsp6/q6prm.h"
17 #include "qdsp6/q6dsp-common.h"
18 #include "common.h"
19 #include "sdw.h"
20 
21 #define I2S_MCLKFS 256
22 
23 #define I2S_MCLK_RATE(rate) \
24 	((rate) * (I2S_MCLKFS))
25 #define I2S_BIT_RATE(rate, channels, format) \
26 	((rate) * (channels) * (format))
27 
28 static struct snd_soc_dapm_widget sc8280xp_dapm_widgets[] = {
29 	SND_SOC_DAPM_HP("Headphone Jack", NULL),
30 	SND_SOC_DAPM_MIC("Mic Jack", NULL),
31 	SND_SOC_DAPM_SPK("DP0 Jack", NULL),
32 	SND_SOC_DAPM_SPK("DP1 Jack", NULL),
33 	SND_SOC_DAPM_SPK("DP2 Jack", NULL),
34 	SND_SOC_DAPM_SPK("DP3 Jack", NULL),
35 	SND_SOC_DAPM_SPK("DP4 Jack", NULL),
36 	SND_SOC_DAPM_SPK("DP5 Jack", NULL),
37 	SND_SOC_DAPM_SPK("DP6 Jack", NULL),
38 	SND_SOC_DAPM_SPK("DP7 Jack", NULL),
39 };
40 
41 struct snd_soc_common {
42 	const char *driver_name;
43 	const struct snd_soc_dapm_widget *dapm_widgets;
44 	int num_dapm_widgets;
45 	const struct snd_soc_dapm_route *dapm_routes;
46 	int num_dapm_routes;
47 	const struct snd_kcontrol_new *controls;
48 	int num_controls;
49 	unsigned int codec_dai_fmt;
50 	bool codec_sysclk_set;
51 	bool mi2s_mclk_enable;
52 	bool mi2s_bclk_enable;
53 	bool wcd_jack;
54 	int (*snd_prepare)(struct snd_pcm_substream *substream);
55 };
56 
57 struct sc8280xp_snd_data {
58 	bool stream_prepared[AFE_PORT_MAX];
59 	struct snd_soc_card *card;
60 	struct snd_soc_jack jack;
61 	struct snd_soc_jack dp_jack[8];
62 	const struct snd_soc_common *snd_soc_common_priv;
63 	bool jack_setup;
64 };
65 
66 static inline int sc8280xp_get_mclk_freq(struct snd_pcm_hw_params *params)
67 {
68 	int rate = params_rate(params);
69 
70 	switch (rate) {
71 	case 11025:
72 	case 44100:
73 	case 88200:
74 		return I2S_MCLK_RATE(44100);
75 	default:
76 		break;
77 	}
78 
79 	return I2S_MCLK_RATE(rate);
80 }
81 
82 static inline int sc8280xp_get_bclk_freq(struct snd_pcm_hw_params *params)
83 {
84 	return I2S_BIT_RATE(params_rate(params),
85 			    params_channels(params),
86 			    snd_pcm_format_width(params_format(params)));
87 }
88 
89 static int sc8280xp_snd_init(struct snd_soc_pcm_runtime *rtd)
90 {
91 	struct sc8280xp_snd_data *data = snd_soc_card_get_drvdata(rtd->card);
92 	struct snd_soc_dai *cpu_dai = snd_soc_rtd_to_cpu(rtd, 0);
93 	struct snd_soc_card *card = rtd->card;
94 	struct snd_soc_jack *dp_jack  = NULL;
95 	int dp_pcm_id = 0;
96 
97 	switch (cpu_dai->id) {
98 	case WSA_CODEC_DMA_RX_0:
99 	case WSA_CODEC_DMA_RX_1:
100 		/*
101 		 * Set limit of -3 dB on Digital Volume and 0 dB on PA Volume
102 		 * to reduce the risk of speaker damage until we have active
103 		 * speaker protection in place.
104 		 */
105 		snd_soc_limit_volume(card, "WSA_RX0 Digital Volume", 81);
106 		snd_soc_limit_volume(card, "WSA_RX1 Digital Volume", 81);
107 		snd_soc_limit_volume(card, "SpkrLeft PA Volume", 17);
108 		snd_soc_limit_volume(card, "SpkrRight PA Volume", 17);
109 		break;
110 	case DISPLAY_PORT_RX_0:
111 		/* DISPLAY_PORT dai ids are not contiguous */
112 		dp_pcm_id = 0;
113 		dp_jack = &data->dp_jack[dp_pcm_id];
114 		break;
115 	case DISPLAY_PORT_RX_1 ... DISPLAY_PORT_RX_7:
116 		dp_pcm_id = cpu_dai->id - DISPLAY_PORT_RX_1 + 1;
117 		dp_jack = &data->dp_jack[dp_pcm_id];
118 		break;
119 	default:
120 		break;
121 	}
122 
123 	if (dp_jack)
124 		return qcom_snd_dp_jack_setup(rtd, dp_jack, dp_pcm_id);
125 
126 	if (data->snd_soc_common_priv->wcd_jack)
127 		return qcom_snd_wcd_jack_setup(rtd, &data->jack, &data->jack_setup);
128 
129 	return 0;
130 }
131 
132 static int sc8280xp_be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd,
133 				     struct snd_pcm_hw_params *params)
134 {
135 	struct snd_soc_dai *cpu_dai = snd_soc_rtd_to_cpu(rtd, 0);
136 	struct snd_interval *rate = hw_param_interval(params,
137 					SNDRV_PCM_HW_PARAM_RATE);
138 	struct snd_interval *channels = hw_param_interval(params,
139 					SNDRV_PCM_HW_PARAM_CHANNELS);
140 	struct snd_mask *fmt = hw_param_mask(params, SNDRV_PCM_HW_PARAM_FORMAT);
141 
142 	rate->min = rate->max = 48000;
143 	snd_mask_set_format(fmt, SNDRV_PCM_FORMAT_S16_LE);
144 	channels->min = 2;
145 	channels->max = 2;
146 	switch (cpu_dai->id) {
147 	case TX_CODEC_DMA_TX_0:
148 	case TX_CODEC_DMA_TX_1:
149 	case TX_CODEC_DMA_TX_2:
150 	case TX_CODEC_DMA_TX_3:
151 		channels->min = 1;
152 		break;
153 	default:
154 		break;
155 	}
156 
157 
158 	return 0;
159 }
160 
161 static int sc8280xp_snd_hw_params(struct snd_pcm_substream *substream,
162 				  struct snd_pcm_hw_params *params)
163 {
164 	struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream);
165 	struct snd_soc_dai *codec_dai = snd_soc_rtd_to_codec(rtd, 0);
166 	struct snd_soc_dai *cpu_dai = snd_soc_rtd_to_cpu(rtd, 0);
167 	struct sc8280xp_snd_data *data = snd_soc_card_get_drvdata(rtd->card);
168 	int mclk_freq = sc8280xp_get_mclk_freq(params);
169 	int bclk_freq = sc8280xp_get_bclk_freq(params);
170 	int ret;
171 
172 	switch (cpu_dai->id) {
173 	case PRIMARY_MI2S_RX ... QUATERNARY_MI2S_TX:
174 	case QUINARY_MI2S_RX ... QUINARY_MI2S_TX:
175 	case SENARY_MI2S_RX ... SENARY_MI2S_TX:
176 		ret = snd_soc_dai_set_fmt(cpu_dai, SND_SOC_DAIFMT_BP_FP);
177 		if (ret && ret != -ENOTSUPP)
178 			return ret;
179 
180 		if (data->snd_soc_common_priv->codec_dai_fmt) {
181 			ret = snd_soc_dai_set_fmt(codec_dai,
182 						  data->snd_soc_common_priv->codec_dai_fmt);
183 			if (ret && ret != -ENOTSUPP)
184 				return ret;
185 		}
186 
187 		if (data->snd_soc_common_priv->mi2s_mclk_enable) {
188 			ret = snd_soc_dai_set_sysclk(cpu_dai,
189 						     LPAIF_MI2S_MCLK, mclk_freq,
190 						     SND_SOC_CLOCK_OUT);
191 			if (ret)
192 				return ret;
193 		}
194 
195 		if (data->snd_soc_common_priv->mi2s_bclk_enable) {
196 			ret = snd_soc_dai_set_sysclk(cpu_dai,
197 						     LPAIF_MI2S_BCLK, bclk_freq,
198 						     SND_SOC_CLOCK_OUT);
199 			if (ret)
200 				return ret;
201 		}
202 
203 		if (data->snd_soc_common_priv->codec_sysclk_set) {
204 			ret = snd_soc_dai_set_sysclk(codec_dai,
205 						     0, mclk_freq,
206 						     SND_SOC_CLOCK_IN);
207 			if (ret)
208 				return ret;
209 		}
210 		break;
211 	default:
212 		break;
213 	}
214 
215 	return 0;
216 }
217 
218 /*
219  * WSA and WSA2 are handled as a single interface with the
220  * following channels mask:
221  *  __________________________________________________
222  *  | Bits  |     3    |     2    |   1     |     0   |
223  *  ---------------------------------------------------
224  *  | Line  | WSA2 Ch2 | WSA2 Ch1 | WSA Ch2 | WSA Ch1 |
225  *  ---------------------------------------------------
226  *
227  * The Ayaneo Pocket S2 speakers are connected only to
228  * the WSA2 interface and the WSA interface is not enabled.
229  *
230  * Set the channel mapping on the WSA2 channels only.
231  */
232 static const unsigned int ayaneo_ps2_channels_mapping[] = {
233 	0,			/* WSA Ch1 */
234 	0,			/* WSA Ch2 */
235 	PCM_CHANNEL_FL,		/* WSA2 Ch1 */
236 	PCM_CHANNEL_FR		/* WSA2 Ch2 */
237 };
238 
239 static int ayaneo_ps2_snd_prepare(struct snd_pcm_substream *substream)
240 {
241 	struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream);
242 	struct snd_soc_dai *cpu_dai = snd_soc_rtd_to_cpu(rtd, 0);
243 	unsigned int channels = substream->runtime->channels;
244 
245 	if (cpu_dai->id != WSA_CODEC_DMA_RX_0)
246 		return 0;
247 
248 	if (channels != 2)
249 		return -EINVAL;
250 
251 	return snd_soc_dai_set_channel_map(cpu_dai, 0, NULL,
252 					   ARRAY_SIZE(ayaneo_ps2_channels_mapping),
253 					   ayaneo_ps2_channels_mapping);
254 }
255 
256 static int sc8280xp_snd_prepare(struct snd_pcm_substream *substream)
257 {
258 	struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream);
259 	struct snd_soc_dai *cpu_dai = snd_soc_rtd_to_cpu(rtd, 0);
260 	struct sc8280xp_snd_data *data = snd_soc_card_get_drvdata(rtd->card);
261 
262 	if (data->snd_soc_common_priv->snd_prepare) {
263 		int ret;
264 
265 		ret = data->snd_soc_common_priv->snd_prepare(substream);
266 		if (ret)
267 			return ret;
268 	}
269 
270 	return qcom_snd_sdw_prepare(substream, &data->stream_prepared[cpu_dai->id]);
271 }
272 
273 static int sc8280xp_snd_hw_free(struct snd_pcm_substream *substream)
274 {
275 	struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream);
276 	struct sc8280xp_snd_data *data = snd_soc_card_get_drvdata(rtd->card);
277 	struct snd_soc_dai *cpu_dai = snd_soc_rtd_to_cpu(rtd, 0);
278 
279 	return qcom_snd_sdw_hw_free(substream, &data->stream_prepared[cpu_dai->id]);
280 }
281 
282 static const struct snd_soc_ops sc8280xp_be_ops = {
283 	.startup = qcom_snd_sdw_startup,
284 	.shutdown = qcom_snd_sdw_shutdown,
285 	.hw_params = sc8280xp_snd_hw_params,
286 	.hw_free = sc8280xp_snd_hw_free,
287 	.prepare = sc8280xp_snd_prepare,
288 };
289 
290 static void sc8280xp_add_be_ops(struct snd_soc_card *card)
291 {
292 	struct snd_soc_dai_link *link;
293 	int i;
294 
295 	for_each_card_prelinks(card, i, link) {
296 		if (link->no_pcm == 1) {
297 			link->init = sc8280xp_snd_init;
298 			link->be_hw_params_fixup = sc8280xp_be_hw_params_fixup;
299 			link->ops = &sc8280xp_be_ops;
300 		}
301 	}
302 }
303 
304 static int sc8280xp_platform_probe(struct platform_device *pdev)
305 {
306 	struct snd_soc_card *card;
307 	struct sc8280xp_snd_data *data;
308 	struct device *dev = &pdev->dev;
309 	int ret;
310 
311 	card = devm_kzalloc(dev, sizeof(*card), GFP_KERNEL);
312 	if (!card)
313 		return -ENOMEM;
314 
315 	/* Allocate the private data */
316 	data = devm_kzalloc(dev, sizeof(*data), GFP_KERNEL);
317 	if (!data)
318 		return -ENOMEM;
319 
320 	data->snd_soc_common_priv = of_device_get_match_data(dev);
321 	if (!data->snd_soc_common_priv)
322 		return -ENODEV;
323 
324 	card->owner = THIS_MODULE;
325 	card->dev = dev;
326 	dev_set_drvdata(dev, card);
327 	snd_soc_card_set_drvdata(card, data);
328 	card->dapm_widgets = data->snd_soc_common_priv->dapm_widgets;
329 	card->num_dapm_widgets = data->snd_soc_common_priv->num_dapm_widgets;
330 	card->dapm_routes = data->snd_soc_common_priv->dapm_routes;
331 	card->num_dapm_routes = data->snd_soc_common_priv->num_dapm_routes;
332 	card->controls = data->snd_soc_common_priv->controls;
333 	card->num_controls = data->snd_soc_common_priv->num_controls;
334 
335 	ret = qcom_snd_parse_of(card);
336 	if (ret)
337 		return ret;
338 
339 	card->driver_name = data->snd_soc_common_priv->driver_name;
340 	sc8280xp_add_be_ops(card);
341 	return devm_snd_soc_register_card(dev, card);
342 }
343 
344 static struct snd_soc_common ayaneo_ps2_priv_data = {
345 	.driver_name = "ayaneo-ps2",
346 	.dapm_widgets = sc8280xp_dapm_widgets,
347 	.num_dapm_widgets = ARRAY_SIZE(sc8280xp_dapm_widgets),
348 	.snd_prepare = ayaneo_ps2_snd_prepare,
349 	.wcd_jack = true,
350 };
351 
352 static const struct snd_soc_common eliza_priv_data = {
353 	.driver_name = "eliza",
354 	.dapm_widgets = sc8280xp_dapm_widgets,
355 	.num_dapm_widgets = ARRAY_SIZE(sc8280xp_dapm_widgets),
356 	.wcd_jack = true,
357 };
358 
359 static const struct snd_soc_common hawi_priv_data = {
360 	.driver_name = "hawi",
361 	.dapm_widgets = sc8280xp_dapm_widgets,
362 	.num_dapm_widgets = ARRAY_SIZE(sc8280xp_dapm_widgets),
363 	.codec_sysclk_set = true,
364 	.mi2s_bclk_enable = true,
365 	.wcd_jack = true,
366 };
367 
368 static const struct snd_soc_common kaanapali_priv_data = {
369 	.driver_name = "kaanapali",
370 	.dapm_widgets = sc8280xp_dapm_widgets,
371 	.num_dapm_widgets = ARRAY_SIZE(sc8280xp_dapm_widgets),
372 	.wcd_jack = true,
373 };
374 
375 static const struct snd_soc_common qcs9100_priv_data = {
376 	.driver_name = "sa8775p",
377 	.dapm_widgets = sc8280xp_dapm_widgets,
378 	.num_dapm_widgets = ARRAY_SIZE(sc8280xp_dapm_widgets),
379 };
380 
381 static const struct snd_soc_common qcs615_priv_data = {
382 	.driver_name = "qcs615",
383 	.dapm_widgets = sc8280xp_dapm_widgets,
384 	.num_dapm_widgets = ARRAY_SIZE(sc8280xp_dapm_widgets),
385 };
386 
387 static const struct snd_soc_common qcm6490_priv_data = {
388 	.driver_name = "qcm6490",
389 	.dapm_widgets = sc8280xp_dapm_widgets,
390 	.num_dapm_widgets = ARRAY_SIZE(sc8280xp_dapm_widgets),
391 	.wcd_jack = true,
392 };
393 
394 static const struct snd_soc_common qcs6490_priv_data = {
395 	.driver_name = "qcs6490",
396 	.dapm_widgets = sc8280xp_dapm_widgets,
397 	.num_dapm_widgets = ARRAY_SIZE(sc8280xp_dapm_widgets),
398 	.wcd_jack = true,
399 };
400 
401 static const struct snd_soc_common qcs8275_priv_data = {
402 	.driver_name = "qcs8300",
403 	.dapm_widgets = sc8280xp_dapm_widgets,
404 	.num_dapm_widgets = ARRAY_SIZE(sc8280xp_dapm_widgets),
405 };
406 
407 static const struct snd_soc_common sc8280xp_priv_data = {
408 	.driver_name = "sc8280xp",
409 	.dapm_widgets = sc8280xp_dapm_widgets,
410 	.num_dapm_widgets = ARRAY_SIZE(sc8280xp_dapm_widgets),
411 	.wcd_jack = true,
412 };
413 
414 static const struct snd_soc_common sm8450_priv_data = {
415 	.driver_name = "sm8450",
416 	.dapm_widgets = sc8280xp_dapm_widgets,
417 	.num_dapm_widgets = ARRAY_SIZE(sc8280xp_dapm_widgets),
418 	.wcd_jack = true,
419 	/* I2S Connected to HDMI */
420 	.mi2s_mclk_enable = true,
421 	.mi2s_bclk_enable = true,
422 	.codec_dai_fmt = SND_SOC_DAIFMT_BC_FC |
423 			 SND_SOC_DAIFMT_NB_NF |
424 			 SND_SOC_DAIFMT_I2S,
425 };
426 
427 static const struct snd_soc_common sm8475_priv_data = {
428 	.driver_name = "sm8475",
429 	.dapm_widgets = sc8280xp_dapm_widgets,
430 	.num_dapm_widgets = ARRAY_SIZE(sc8280xp_dapm_widgets),
431 	.wcd_jack = true,
432 };
433 
434 static const struct snd_soc_common sm8550_priv_data = {
435 	.driver_name = "sm8550",
436 	.dapm_widgets = sc8280xp_dapm_widgets,
437 	.num_dapm_widgets = ARRAY_SIZE(sc8280xp_dapm_widgets),
438 	.wcd_jack = true,
439 	/* I2S Connected to HDMI */
440 	.mi2s_mclk_enable = true,
441 	.mi2s_bclk_enable = true,
442 	.codec_dai_fmt = SND_SOC_DAIFMT_BC_FC |
443 			 SND_SOC_DAIFMT_NB_NF |
444 			 SND_SOC_DAIFMT_I2S,
445 };
446 
447 static const struct snd_soc_common sm8650_priv_data = {
448 	.driver_name = "sm8650",
449 	.dapm_widgets = sc8280xp_dapm_widgets,
450 	.num_dapm_widgets = ARRAY_SIZE(sc8280xp_dapm_widgets),
451 	.wcd_jack = true,
452 	/* I2S Connected to HDMI */
453 	.mi2s_mclk_enable = true,
454 	.mi2s_bclk_enable = true,
455 	.codec_dai_fmt = SND_SOC_DAIFMT_BC_FC |
456 			 SND_SOC_DAIFMT_NB_NF |
457 			 SND_SOC_DAIFMT_I2S,
458 };
459 
460 static const struct snd_soc_common sm8750_priv_data = {
461 	.driver_name = "sm8750",
462 	.dapm_widgets = sc8280xp_dapm_widgets,
463 	.num_dapm_widgets = ARRAY_SIZE(sc8280xp_dapm_widgets),
464 	.wcd_jack = true,
465 };
466 
467 static const struct of_device_id snd_sc8280xp_dt_match[] = {
468 	{ .compatible = "ayaneo,pocket-s2-sndcard", .data = &ayaneo_ps2_priv_data },
469 	{ .compatible = "qcom,eliza-sndcard", .data = &eliza_priv_data },
470 	{ .compatible = "qcom,hawi-sndcard", .data = &hawi_priv_data },
471 	{ .compatible = "qcom,kaanapali-sndcard", .data = &kaanapali_priv_data },
472 	{ .compatible = "qcom,qcm6490-idp-sndcard", .data = &qcm6490_priv_data },
473 	{ .compatible = "qcom,qcs615-sndcard", .data = &qcs615_priv_data },
474 	{ .compatible = "qcom,qcs6490-rb3gen2-sndcard", .data = &qcs6490_priv_data },
475 	{ .compatible = "qcom,qcs8275-sndcard", .data = &qcs8275_priv_data },
476 	{ .compatible = "qcom,qcs9075-sndcard", .data = &qcs9100_priv_data },
477 	{ .compatible = "qcom,qcs9100-sndcard", .data = &qcs9100_priv_data },
478 	{ .compatible = "qcom,sc8280xp-sndcard", .data = &sc8280xp_priv_data },
479 	{ .compatible = "qcom,sm8450-sndcard", .data = &sm8450_priv_data },
480 	{ .compatible = "qcom,sm8475-sndcard", .data = &sm8475_priv_data },
481 	{ .compatible = "qcom,sm8550-sndcard", .data = &sm8550_priv_data },
482 	{ .compatible = "qcom,sm8650-sndcard", .data = &sm8650_priv_data },
483 	{ .compatible = "qcom,sm8750-sndcard", .data = &sm8750_priv_data },
484 	{}
485 };
486 
487 MODULE_DEVICE_TABLE(of, snd_sc8280xp_dt_match);
488 
489 static struct platform_driver snd_sc8280xp_driver = {
490 	.probe  = sc8280xp_platform_probe,
491 	.driver = {
492 		.name = "snd-sc8280xp",
493 		.of_match_table = snd_sc8280xp_dt_match,
494 	},
495 };
496 module_platform_driver(snd_sc8280xp_driver);
497 MODULE_AUTHOR("Srinivas Kandagatla <srinivas.kandagatla@linaro.org");
498 MODULE_DESCRIPTION("SC8280XP ASoC Machine Driver");
499 MODULE_LICENSE("GPL");
500