xref: /kernel/linux/linux-6.6/sound/soc/qcom/sc7280.c (revision 62306a36)
1// SPDX-License-Identifier: GPL-2.0-only
2//
3// Copyright (c) 2020-2021, The Linux Foundation. All rights reserved.
4//
5// ALSA SoC Machine driver for sc7280
6
7#include <linux/input.h>
8#include <linux/module.h>
9#include <linux/of_device.h>
10#include <linux/platform_device.h>
11#include <sound/core.h>
12#include <sound/jack.h>
13#include <sound/pcm.h>
14#include <sound/soc.h>
15#include <sound/rt5682s.h>
16#include <linux/soundwire/sdw.h>
17#include <sound/pcm_params.h>
18
19#include "../codecs/rt5682.h"
20#include "../codecs/rt5682s.h"
21#include "common.h"
22#include "lpass.h"
23#include "qdsp6/q6afe.h"
24
25#define DEFAULT_MCLK_RATE              19200000
26#define RT5682_PLL_FREQ (48000 * 512)
27#define MI2S_BCLK_RATE		1536000
28
29struct sc7280_snd_data {
30	struct snd_soc_card card;
31	struct sdw_stream_runtime *sruntime[LPASS_MAX_PORTS];
32	u32 pri_mi2s_clk_count;
33	struct snd_soc_jack hs_jack;
34	struct snd_soc_jack hdmi_jack;
35	bool jack_setup;
36	bool stream_prepared[LPASS_MAX_PORTS];
37};
38
39static void sc7280_jack_free(struct snd_jack *jack)
40{
41	struct snd_soc_component *component = jack->private_data;
42
43	snd_soc_component_set_jack(component, NULL, NULL);
44}
45
46static struct snd_soc_jack_pin sc7280_jack_pins[] = {
47	{
48		.pin = "Headphone Jack",
49		.mask = SND_JACK_HEADPHONE,
50	},
51	{
52		.pin = "Headset Mic",
53		.mask = SND_JACK_MICROPHONE,
54	},
55};
56
57static int sc7280_headset_init(struct snd_soc_pcm_runtime *rtd)
58{
59	struct snd_soc_card *card = rtd->card;
60	struct sc7280_snd_data *pdata = snd_soc_card_get_drvdata(card);
61	struct snd_soc_dai *codec_dai = snd_soc_rtd_to_codec(rtd, 0);
62	struct snd_soc_dai *cpu_dai = snd_soc_rtd_to_cpu(rtd, 0);
63	struct snd_soc_component *component = codec_dai->component;
64	struct snd_jack *jack;
65	int rval, i;
66
67	if (!pdata->jack_setup) {
68		rval = snd_soc_card_jack_new_pins(card, "Headset Jack",
69						  SND_JACK_HEADSET | SND_JACK_LINEOUT |
70						  SND_JACK_MECHANICAL |
71						  SND_JACK_BTN_0 | SND_JACK_BTN_1 |
72						  SND_JACK_BTN_2 | SND_JACK_BTN_3 |
73						  SND_JACK_BTN_4 | SND_JACK_BTN_5,
74						  &pdata->hs_jack,
75						  sc7280_jack_pins,
76						  ARRAY_SIZE(sc7280_jack_pins));
77
78		if (rval < 0) {
79			dev_err(card->dev, "Unable to add Headset Jack\n");
80			return rval;
81		}
82
83		jack = pdata->hs_jack.jack;
84
85		snd_jack_set_key(jack, SND_JACK_BTN_0, KEY_PLAYPAUSE);
86		snd_jack_set_key(jack, SND_JACK_BTN_1, KEY_VOICECOMMAND);
87		snd_jack_set_key(jack, SND_JACK_BTN_2, KEY_VOLUMEUP);
88		snd_jack_set_key(jack, SND_JACK_BTN_3, KEY_VOLUMEDOWN);
89
90		jack->private_data = component;
91		jack->private_free = sc7280_jack_free;
92		pdata->jack_setup = true;
93	}
94	switch (cpu_dai->id) {
95	case MI2S_PRIMARY:
96	case LPASS_CDC_DMA_RX0:
97	case LPASS_CDC_DMA_TX3:
98	case TX_CODEC_DMA_TX_3:
99		for_each_rtd_codec_dais(rtd, i, codec_dai) {
100			rval = snd_soc_component_set_jack(component, &pdata->hs_jack, NULL);
101			if (rval != 0 && rval != -ENOTSUPP) {
102				dev_err(card->dev, "Failed to set jack: %d\n", rval);
103				return rval;
104			}
105		}
106		break;
107	default:
108		break;
109	}
110
111	return 0;
112}
113
114static int sc7280_hdmi_init(struct snd_soc_pcm_runtime *rtd)
115{
116	struct snd_soc_card *card = rtd->card;
117	struct sc7280_snd_data *pdata = snd_soc_card_get_drvdata(card);
118	struct snd_soc_dai *codec_dai = snd_soc_rtd_to_codec(rtd, 0);
119	struct snd_soc_component *component = codec_dai->component;
120	struct snd_jack *jack;
121	int rval;
122
123	rval = snd_soc_card_jack_new(card, "HDMI Jack",	SND_JACK_LINEOUT,
124				     &pdata->hdmi_jack);
125
126	if (rval < 0) {
127		dev_err(card->dev, "Unable to add HDMI Jack\n");
128		return rval;
129	}
130
131	jack = pdata->hdmi_jack.jack;
132	jack->private_data = component;
133	jack->private_free = sc7280_jack_free;
134
135	return snd_soc_component_set_jack(component, &pdata->hdmi_jack, NULL);
136}
137
138static int sc7280_rt5682_init(struct snd_soc_pcm_runtime *rtd)
139{
140	struct snd_soc_dai *cpu_dai = snd_soc_rtd_to_cpu(rtd, 0);
141	struct snd_soc_dai *codec_dai = snd_soc_rtd_to_codec(rtd, 0);
142	struct snd_soc_card *card = rtd->card;
143	struct sc7280_snd_data *data = snd_soc_card_get_drvdata(card);
144	int ret;
145
146	if (++data->pri_mi2s_clk_count == 1) {
147		snd_soc_dai_set_sysclk(cpu_dai,
148			LPASS_MCLK0,
149			DEFAULT_MCLK_RATE,
150			SNDRV_PCM_STREAM_PLAYBACK);
151	}
152	snd_soc_dai_set_fmt(codec_dai,
153				SND_SOC_DAIFMT_CBC_CFC |
154				SND_SOC_DAIFMT_NB_NF |
155				SND_SOC_DAIFMT_I2S);
156
157	ret = snd_soc_dai_set_pll(codec_dai, RT5682S_PLL2, RT5682S_PLL_S_MCLK,
158					DEFAULT_MCLK_RATE, RT5682_PLL_FREQ);
159	if (ret) {
160		dev_err(rtd->dev, "can't set codec pll: %d\n", ret);
161		return ret;
162	}
163
164	ret = snd_soc_dai_set_sysclk(codec_dai, RT5682S_SCLK_S_PLL2,
165					RT5682_PLL_FREQ,
166					SND_SOC_CLOCK_IN);
167
168	if (ret) {
169		dev_err(rtd->dev, "snd_soc_dai_set_sysclk err = %d\n",
170			ret);
171		return ret;
172	}
173
174	return 0;
175}
176
177static int sc7280_init(struct snd_soc_pcm_runtime *rtd)
178{
179	struct snd_soc_dai *cpu_dai = snd_soc_rtd_to_cpu(rtd, 0);
180
181	switch (cpu_dai->id) {
182	case MI2S_PRIMARY:
183	case LPASS_CDC_DMA_TX3:
184	case TX_CODEC_DMA_TX_3:
185		return sc7280_headset_init(rtd);
186	case LPASS_CDC_DMA_RX0:
187	case LPASS_CDC_DMA_VA_TX0:
188	case MI2S_SECONDARY:
189	case RX_CODEC_DMA_RX_0:
190	case SECONDARY_MI2S_RX:
191	case VA_CODEC_DMA_TX_0:
192		return 0;
193	case LPASS_DP_RX:
194		return sc7280_hdmi_init(rtd);
195	default:
196		dev_err(rtd->dev, "%s: invalid dai id 0x%x\n", __func__, cpu_dai->id);
197	}
198
199	return -EINVAL;
200}
201
202static int sc7280_snd_hw_params(struct snd_pcm_substream *substream,
203				struct snd_pcm_hw_params *params)
204{
205	struct snd_pcm_runtime *runtime = substream->runtime;
206	struct snd_soc_pcm_runtime *rtd = substream->private_data;
207	struct snd_soc_dai *codec_dai;
208	const struct snd_soc_dai *cpu_dai = snd_soc_rtd_to_cpu(rtd, 0);
209	struct sc7280_snd_data *pdata = snd_soc_card_get_drvdata(rtd->card);
210	struct sdw_stream_runtime *sruntime;
211	int i;
212
213	if (!rtd->dai_link->no_pcm) {
214		snd_pcm_hw_constraint_minmax(runtime, SNDRV_PCM_HW_PARAM_CHANNELS, 2, 2);
215		snd_pcm_hw_constraint_minmax(runtime, SNDRV_PCM_HW_PARAM_RATE, 48000, 48000);
216	}
217
218	switch (cpu_dai->id) {
219	case LPASS_CDC_DMA_TX3:
220	case LPASS_CDC_DMA_RX0:
221	case RX_CODEC_DMA_RX_0:
222	case SECONDARY_MI2S_RX:
223	case TX_CODEC_DMA_TX_3:
224	case VA_CODEC_DMA_TX_0:
225		for_each_rtd_codec_dais(rtd, i, codec_dai) {
226			sruntime = snd_soc_dai_get_stream(codec_dai, substream->stream);
227			if (sruntime != ERR_PTR(-ENOTSUPP))
228				pdata->sruntime[cpu_dai->id] = sruntime;
229		}
230		break;
231	}
232
233	return 0;
234}
235
236static int sc7280_snd_swr_prepare(struct snd_pcm_substream *substream)
237{
238	struct snd_soc_pcm_runtime *rtd = substream->private_data;
239	const struct snd_soc_dai *cpu_dai = snd_soc_rtd_to_cpu(rtd, 0);
240	struct sc7280_snd_data *data = snd_soc_card_get_drvdata(rtd->card);
241	struct sdw_stream_runtime *sruntime = data->sruntime[cpu_dai->id];
242	int ret;
243
244	if (!sruntime)
245		return 0;
246
247	if (data->stream_prepared[cpu_dai->id]) {
248		sdw_disable_stream(sruntime);
249		sdw_deprepare_stream(sruntime);
250		data->stream_prepared[cpu_dai->id] = false;
251	}
252
253	ret = sdw_prepare_stream(sruntime);
254	if (ret)
255		return ret;
256
257	ret = sdw_enable_stream(sruntime);
258	if (ret) {
259		sdw_deprepare_stream(sruntime);
260		return ret;
261	}
262	data->stream_prepared[cpu_dai->id] = true;
263
264	return ret;
265}
266
267static int sc7280_snd_prepare(struct snd_pcm_substream *substream)
268{
269	struct snd_soc_pcm_runtime *rtd = substream->private_data;
270	const struct snd_soc_dai *cpu_dai = snd_soc_rtd_to_cpu(rtd, 0);
271
272	switch (cpu_dai->id) {
273	case LPASS_CDC_DMA_RX0:
274	case LPASS_CDC_DMA_TX3:
275	case RX_CODEC_DMA_RX_0:
276	case TX_CODEC_DMA_TX_3:
277	case VA_CODEC_DMA_TX_0:
278		return sc7280_snd_swr_prepare(substream);
279	default:
280		break;
281	}
282
283	return 0;
284}
285
286static int sc7280_snd_hw_free(struct snd_pcm_substream *substream)
287{
288	struct snd_soc_pcm_runtime *rtd = substream->private_data;
289	struct sc7280_snd_data *data = snd_soc_card_get_drvdata(rtd->card);
290	const struct snd_soc_dai *cpu_dai = snd_soc_rtd_to_cpu(rtd, 0);
291	struct sdw_stream_runtime *sruntime = data->sruntime[cpu_dai->id];
292
293	switch (cpu_dai->id) {
294	case LPASS_CDC_DMA_RX0:
295	case LPASS_CDC_DMA_TX3:
296	case RX_CODEC_DMA_RX_0:
297	case TX_CODEC_DMA_TX_3:
298	case VA_CODEC_DMA_TX_0:
299		if (sruntime && data->stream_prepared[cpu_dai->id]) {
300			sdw_disable_stream(sruntime);
301			sdw_deprepare_stream(sruntime);
302			data->stream_prepared[cpu_dai->id] = false;
303		}
304		break;
305	default:
306		break;
307	}
308	return 0;
309}
310
311static void sc7280_snd_shutdown(struct snd_pcm_substream *substream)
312{
313	struct snd_soc_pcm_runtime *rtd = substream->private_data;
314	struct snd_soc_card *card = rtd->card;
315	struct sc7280_snd_data *data = snd_soc_card_get_drvdata(card);
316	struct snd_soc_dai *cpu_dai = snd_soc_rtd_to_cpu(rtd, 0);
317
318	switch (cpu_dai->id) {
319	case MI2S_PRIMARY:
320		if (--data->pri_mi2s_clk_count == 0) {
321			snd_soc_dai_set_sysclk(cpu_dai,
322					       LPASS_MCLK0,
323					       0,
324					       SNDRV_PCM_STREAM_PLAYBACK);
325		}
326		break;
327	case SECONDARY_MI2S_RX:
328		snd_soc_dai_set_sysclk(cpu_dai, Q6AFE_LPASS_CLK_ID_SEC_MI2S_IBIT,
329					       0, SNDRV_PCM_STREAM_PLAYBACK);
330		break;
331	default:
332		break;
333	}
334}
335
336static int sc7280_snd_startup(struct snd_pcm_substream *substream)
337{
338	unsigned int fmt = SND_SOC_DAIFMT_CBS_CFS;
339	unsigned int codec_dai_fmt = SND_SOC_DAIFMT_CBS_CFS;
340	struct snd_soc_pcm_runtime *rtd = substream->private_data;
341	struct snd_soc_dai *cpu_dai = snd_soc_rtd_to_cpu(rtd, 0);
342	struct snd_soc_dai *codec_dai = snd_soc_rtd_to_codec(rtd, 0);
343	int ret = 0;
344
345	switch (cpu_dai->id) {
346	case MI2S_PRIMARY:
347		ret = sc7280_rt5682_init(rtd);
348		break;
349	case SECONDARY_MI2S_RX:
350		codec_dai_fmt |= SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_I2S;
351
352		snd_soc_dai_set_sysclk(cpu_dai, Q6AFE_LPASS_CLK_ID_SEC_MI2S_IBIT,
353			MI2S_BCLK_RATE, SNDRV_PCM_STREAM_PLAYBACK);
354
355		snd_soc_dai_set_fmt(cpu_dai, fmt);
356		snd_soc_dai_set_fmt(codec_dai, codec_dai_fmt);
357		break;
358	default:
359		break;
360	}
361	return ret;
362}
363
364static const struct snd_soc_ops sc7280_ops = {
365	.startup = sc7280_snd_startup,
366	.hw_params = sc7280_snd_hw_params,
367	.hw_free = sc7280_snd_hw_free,
368	.prepare = sc7280_snd_prepare,
369	.shutdown = sc7280_snd_shutdown,
370};
371
372static const struct snd_soc_dapm_widget sc7280_snd_widgets[] = {
373	SND_SOC_DAPM_HP("Headphone Jack", NULL),
374	SND_SOC_DAPM_MIC("Headset Mic", NULL),
375};
376
377static const struct snd_kcontrol_new sc7280_snd_controls[] = {
378	SOC_DAPM_PIN_SWITCH("Headphone Jack"),
379	SOC_DAPM_PIN_SWITCH("Headset Mic"),
380};
381
382static int sc7280_snd_be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd,
383					 struct snd_pcm_hw_params *params)
384{
385	struct snd_interval *rate = hw_param_interval(params, SNDRV_PCM_HW_PARAM_RATE);
386	struct snd_interval *channels = hw_param_interval(params, SNDRV_PCM_HW_PARAM_CHANNELS);
387	struct snd_mask *fmt = hw_param_mask(params, SNDRV_PCM_HW_PARAM_FORMAT);
388
389	rate->min = rate->max = 48000;
390	channels->min = channels->max = 2;
391	snd_mask_set_format(fmt, SNDRV_PCM_FORMAT_S16_LE);
392
393	return 0;
394}
395
396static int sc7280_snd_platform_probe(struct platform_device *pdev)
397{
398	struct snd_soc_card *card;
399	struct sc7280_snd_data *data;
400	struct device *dev = &pdev->dev;
401	struct snd_soc_dai_link *link;
402	int ret, i;
403
404	data = devm_kzalloc(dev, sizeof(*data), GFP_KERNEL);
405	if (!data)
406		return -ENOMEM;
407
408	card = &data->card;
409	snd_soc_card_set_drvdata(card, data);
410
411	card->owner = THIS_MODULE;
412	card->driver_name = "SC7280";
413	card->dev = dev;
414
415	card->dapm_widgets = sc7280_snd_widgets;
416	card->num_dapm_widgets = ARRAY_SIZE(sc7280_snd_widgets);
417	card->controls = sc7280_snd_controls;
418	card->num_controls = ARRAY_SIZE(sc7280_snd_controls);
419
420	ret = qcom_snd_parse_of(card);
421	if (ret)
422		return ret;
423
424	for_each_card_prelinks(card, i, link) {
425		link->init = sc7280_init;
426		link->ops = &sc7280_ops;
427		if (link->no_pcm == 1)
428			link->be_hw_params_fixup = sc7280_snd_be_hw_params_fixup;
429	}
430
431	return devm_snd_soc_register_card(dev, card);
432}
433
434static const struct of_device_id sc7280_snd_device_id[]  = {
435	{ .compatible = "google,sc7280-herobrine" },
436	{}
437};
438MODULE_DEVICE_TABLE(of, sc7280_snd_device_id);
439
440static struct platform_driver sc7280_snd_driver = {
441	.probe = sc7280_snd_platform_probe,
442	.driver = {
443		.name = "msm-snd-sc7280",
444		.of_match_table = sc7280_snd_device_id,
445		.pm = &snd_soc_pm_ops,
446	},
447};
448module_platform_driver(sc7280_snd_driver);
449
450MODULE_DESCRIPTION("sc7280 ASoC Machine Driver");
451MODULE_LICENSE("GPL");
452