Linux 6.7-rc7
[linux-modified.git] / sound / soc / qcom / sc7180.c
1 // SPDX-License-Identifier: GPL-2.0-only
2 //
3 // Copyright (c) 2020, The Linux Foundation. All rights reserved.
4 //
5 // sc7180.c -- ALSA SoC Machine driver for SC7180
6
7 #include <dt-bindings/sound/sc7180-lpass.h>
8 #include <dt-bindings/sound/qcom,q6afe.h>
9 #include <linux/gpio.h>
10 #include <linux/gpio/consumer.h>
11 #include <linux/module.h>
12 #include <linux/of.h>
13 #include <linux/platform_device.h>
14 #include <sound/core.h>
15 #include <sound/jack.h>
16 #include <sound/pcm.h>
17 #include <sound/soc.h>
18 #include <uapi/linux/input-event-codes.h>
19
20 #include "../codecs/rt5682.h"
21 #include "../codecs/rt5682s.h"
22 #include "common.h"
23 #include "qdsp6/q6afe.h"
24
25 #define DEFAULT_MCLK_RATE               19200000
26 #define MI2S_BCLK_RATE                  1536000
27 #define RT5682_PLL1_FREQ (48000 * 512)
28
29 #define DRIVER_NAME "SC7180"
30
31 struct sc7180_snd_data {
32         struct snd_soc_card card;
33         u32 pri_mi2s_clk_count;
34         struct snd_soc_jack hs_jack;
35         struct snd_soc_jack hdmi_jack;
36         struct gpio_desc *dmic_sel;
37         int dmic_switch;
38 };
39
40 static void sc7180_jack_free(struct snd_jack *jack)
41 {
42         struct snd_soc_component *component = jack->private_data;
43
44         snd_soc_component_set_jack(component, NULL, NULL);
45 }
46
47 static struct snd_soc_jack_pin sc7180_jack_pins[] = {
48         {
49                 .pin = "Headphone Jack",
50                 .mask = SND_JACK_HEADPHONE,
51         },
52         {
53                 .pin = "Headset Mic",
54                 .mask = SND_JACK_MICROPHONE,
55         },
56 };
57
58 static int sc7180_headset_init(struct snd_soc_pcm_runtime *rtd)
59 {
60         struct snd_soc_card *card = rtd->card;
61         struct sc7180_snd_data *pdata = snd_soc_card_get_drvdata(card);
62         struct snd_soc_dai *codec_dai = snd_soc_rtd_to_codec(rtd, 0);
63         struct snd_soc_component *component = codec_dai->component;
64         struct snd_jack *jack;
65         int rval;
66
67         rval = snd_soc_card_jack_new_pins(card, "Headset Jack",
68                                           SND_JACK_HEADSET |
69                                           SND_JACK_HEADPHONE |
70                                           SND_JACK_BTN_0 | SND_JACK_BTN_1 |
71                                           SND_JACK_BTN_2 | SND_JACK_BTN_3,
72                                           &pdata->hs_jack,
73                                           sc7180_jack_pins,
74                                           ARRAY_SIZE(sc7180_jack_pins));
75
76         if (rval < 0) {
77                 dev_err(card->dev, "Unable to add Headset Jack\n");
78                 return rval;
79         }
80
81         jack = pdata->hs_jack.jack;
82
83         snd_jack_set_key(jack, SND_JACK_BTN_0, KEY_PLAYPAUSE);
84         snd_jack_set_key(jack, SND_JACK_BTN_1, KEY_VOICECOMMAND);
85         snd_jack_set_key(jack, SND_JACK_BTN_2, KEY_VOLUMEUP);
86         snd_jack_set_key(jack, SND_JACK_BTN_3, KEY_VOLUMEDOWN);
87
88         jack->private_data = component;
89         jack->private_free = sc7180_jack_free;
90
91         return snd_soc_component_set_jack(component, &pdata->hs_jack, NULL);
92 }
93
94 static int sc7180_hdmi_init(struct snd_soc_pcm_runtime *rtd)
95 {
96         struct snd_soc_card *card = rtd->card;
97         struct sc7180_snd_data *pdata = snd_soc_card_get_drvdata(card);
98         struct snd_soc_dai *codec_dai = snd_soc_rtd_to_codec(rtd, 0);
99         struct snd_soc_component *component = codec_dai->component;
100         struct snd_jack *jack;
101         int rval;
102
103         rval = snd_soc_card_jack_new(
104                         card, "HDMI Jack",
105                         SND_JACK_LINEOUT,
106                         &pdata->hdmi_jack);
107
108         if (rval < 0) {
109                 dev_err(card->dev, "Unable to add HDMI Jack\n");
110                 return rval;
111         }
112
113         jack = pdata->hdmi_jack.jack;
114         jack->private_data = component;
115         jack->private_free = sc7180_jack_free;
116
117         return snd_soc_component_set_jack(component, &pdata->hdmi_jack, NULL);
118 }
119
120 static int sc7180_init(struct snd_soc_pcm_runtime *rtd)
121 {
122         struct snd_soc_dai *cpu_dai = snd_soc_rtd_to_cpu(rtd, 0);
123
124         switch (cpu_dai->id) {
125         case MI2S_PRIMARY:
126                 return sc7180_headset_init(rtd);
127         case MI2S_SECONDARY:
128                 return 0;
129         case LPASS_DP_RX:
130                 return sc7180_hdmi_init(rtd);
131         default:
132                 dev_err(rtd->dev, "%s: invalid dai id 0x%x\n", __func__,
133                         cpu_dai->id);
134                 return -EINVAL;
135         }
136         return 0;
137 }
138
139 static int sc7180_qdsp_init(struct snd_soc_pcm_runtime *rtd)
140 {
141         struct snd_soc_dai *cpu_dai = snd_soc_rtd_to_cpu(rtd, 0);
142
143         switch (cpu_dai->id) {
144         case PRIMARY_MI2S_RX:
145                 return sc7180_headset_init(rtd);
146         case PRIMARY_MI2S_TX:
147         case TERTIARY_MI2S_RX:
148                 return 0;
149         case DISPLAY_PORT_RX:
150                 return sc7180_hdmi_init(rtd);
151         default:
152                 dev_err(rtd->dev, "%s: invalid dai id 0x%x\n", __func__,
153                         cpu_dai->id);
154                 return -EINVAL;
155         }
156         return 0;
157 }
158
159 static int sc7180_startup_realtek_codec(struct snd_soc_pcm_runtime *rtd)
160 {
161         struct snd_soc_dai *codec_dai = snd_soc_rtd_to_codec(rtd, 0);
162         int pll_id, pll_source, pll_in, pll_out, clk_id, ret;
163
164         if (!strcmp(codec_dai->name, "rt5682-aif1")) {
165                 pll_source = RT5682_PLL1_S_MCLK;
166                 pll_id = 0;
167                 clk_id = RT5682_SCLK_S_PLL1;
168                 pll_out = RT5682_PLL1_FREQ;
169                 pll_in = DEFAULT_MCLK_RATE;
170         } else if (!strcmp(codec_dai->name, "rt5682s-aif1")) {
171                 pll_source = RT5682S_PLL_S_MCLK;
172                 pll_id = RT5682S_PLL2;
173                 clk_id = RT5682S_SCLK_S_PLL2;
174                 pll_out = RT5682_PLL1_FREQ;
175                 pll_in = DEFAULT_MCLK_RATE;
176         } else {
177                 return 0;
178         }
179         snd_soc_dai_set_fmt(codec_dai,
180                             SND_SOC_DAIFMT_BC_FC |
181                             SND_SOC_DAIFMT_NB_NF |
182                             SND_SOC_DAIFMT_I2S);
183
184         /* Configure PLL1 for codec */
185         ret = snd_soc_dai_set_pll(codec_dai, pll_id, pll_source,
186                                   pll_in, pll_out);
187         if (ret) {
188                 dev_err(rtd->dev, "can't set codec pll: %d\n", ret);
189                 return ret;
190         }
191
192         /* Configure sysclk for codec */
193         ret = snd_soc_dai_set_sysclk(codec_dai, clk_id, pll_out,
194                                      SND_SOC_CLOCK_IN);
195         if (ret)
196                 dev_err(rtd->dev, "snd_soc_dai_set_sysclk err = %d\n",
197                         ret);
198
199         return ret;
200 }
201
202 static int sc7180_snd_startup(struct snd_pcm_substream *substream)
203 {
204         struct snd_soc_pcm_runtime *rtd = substream->private_data;
205         struct snd_soc_card *card = rtd->card;
206         struct sc7180_snd_data *data = snd_soc_card_get_drvdata(card);
207         struct snd_soc_dai *cpu_dai = snd_soc_rtd_to_cpu(rtd, 0);
208         int ret;
209
210         switch (cpu_dai->id) {
211         case MI2S_PRIMARY:
212                 if (++data->pri_mi2s_clk_count == 1) {
213                         snd_soc_dai_set_sysclk(cpu_dai,
214                                                LPASS_MCLK0,
215                                                DEFAULT_MCLK_RATE,
216                                                SNDRV_PCM_STREAM_PLAYBACK);
217                 }
218
219                 ret = sc7180_startup_realtek_codec(rtd);
220                 if (ret)
221                         return ret;
222
223                 break;
224         case MI2S_SECONDARY:
225                 break;
226         case LPASS_DP_RX:
227                 break;
228         default:
229                 dev_err(rtd->dev, "%s: invalid dai id 0x%x\n", __func__,
230                         cpu_dai->id);
231                 return -EINVAL;
232         }
233         return 0;
234 }
235
236 static int sc7180_qdsp_snd_startup(struct snd_pcm_substream *substream)
237 {
238         struct snd_soc_pcm_runtime *rtd = substream->private_data;
239         struct snd_soc_card *card = rtd->card;
240         struct sc7180_snd_data *data = snd_soc_card_get_drvdata(card);
241         struct snd_soc_dai *cpu_dai = snd_soc_rtd_to_cpu(rtd, 0);
242         struct snd_soc_dai *codec_dai = snd_soc_rtd_to_codec(rtd, 0);
243         int ret;
244
245         switch (cpu_dai->id) {
246         case PRIMARY_MI2S_RX:
247         case PRIMARY_MI2S_TX:
248                 if (++data->pri_mi2s_clk_count == 1) {
249                         snd_soc_dai_set_sysclk(cpu_dai,
250                                                Q6AFE_LPASS_CLK_ID_MCLK_1,
251                                                DEFAULT_MCLK_RATE,
252                                                SNDRV_PCM_STREAM_PLAYBACK);
253                         snd_soc_dai_set_sysclk(cpu_dai,
254                                                Q6AFE_LPASS_CLK_ID_PRI_MI2S_IBIT,
255                                                MI2S_BCLK_RATE,
256                                                SNDRV_PCM_STREAM_PLAYBACK);
257                 }
258
259                 snd_soc_dai_set_fmt(cpu_dai, SND_SOC_DAIFMT_BP_FP);
260
261                 ret = sc7180_startup_realtek_codec(rtd);
262                 if (ret)
263                         return ret;
264
265                 break;
266         case TERTIARY_MI2S_RX:
267                 snd_soc_dai_set_sysclk(cpu_dai,
268                                        Q6AFE_LPASS_CLK_ID_TER_MI2S_IBIT,
269                                        MI2S_BCLK_RATE,
270                                        SNDRV_PCM_STREAM_PLAYBACK);
271
272                 snd_soc_dai_set_fmt(codec_dai,
273                                 SND_SOC_DAIFMT_BC_FC |
274                                 SND_SOC_DAIFMT_NB_NF |
275                                 SND_SOC_DAIFMT_I2S);
276                 snd_soc_dai_set_fmt(cpu_dai, SND_SOC_DAIFMT_BP_FP);
277                 break;
278         case DISPLAY_PORT_RX:
279                 break;
280         default:
281                 dev_err(rtd->dev, "%s: invalid dai id 0x%x\n", __func__,
282                         cpu_dai->id);
283                 return -EINVAL;
284         }
285         return 0;
286 }
287
288 static int dmic_get(struct snd_kcontrol *kcontrol,
289                     struct snd_ctl_elem_value *ucontrol)
290 {
291         struct snd_soc_dapm_context *dapm = snd_soc_dapm_kcontrol_dapm(kcontrol);
292         struct sc7180_snd_data *data = snd_soc_card_get_drvdata(dapm->card);
293
294         ucontrol->value.integer.value[0] = data->dmic_switch;
295         return 0;
296 }
297
298 static int dmic_set(struct snd_kcontrol *kcontrol,
299                     struct snd_ctl_elem_value *ucontrol)
300 {
301         struct snd_soc_dapm_context *dapm = snd_soc_dapm_kcontrol_dapm(kcontrol);
302         struct sc7180_snd_data *data = snd_soc_card_get_drvdata(dapm->card);
303
304         data->dmic_switch = ucontrol->value.integer.value[0];
305         gpiod_set_value(data->dmic_sel, data->dmic_switch);
306         return 0;
307 }
308
309 static void sc7180_snd_shutdown(struct snd_pcm_substream *substream)
310 {
311         struct snd_soc_pcm_runtime *rtd = substream->private_data;
312         struct snd_soc_card *card = rtd->card;
313         struct sc7180_snd_data *data = snd_soc_card_get_drvdata(card);
314         struct snd_soc_dai *cpu_dai = snd_soc_rtd_to_cpu(rtd, 0);
315
316         switch (cpu_dai->id) {
317         case MI2S_PRIMARY:
318                 if (--data->pri_mi2s_clk_count == 0) {
319                         snd_soc_dai_set_sysclk(cpu_dai,
320                                                LPASS_MCLK0,
321                                                0,
322                                                SNDRV_PCM_STREAM_PLAYBACK);
323                 }
324                 break;
325         case MI2S_SECONDARY:
326                 break;
327         case LPASS_DP_RX:
328                 break;
329         default:
330                 dev_err(rtd->dev, "%s: invalid dai id 0x%x\n", __func__,
331                         cpu_dai->id);
332                 break;
333         }
334 }
335
336 static void sc7180_qdsp_snd_shutdown(struct snd_pcm_substream *substream)
337 {
338         struct snd_soc_pcm_runtime *rtd = substream->private_data;
339         struct snd_soc_card *card = rtd->card;
340         struct sc7180_snd_data *data = snd_soc_card_get_drvdata(card);
341         struct snd_soc_dai *cpu_dai = snd_soc_rtd_to_cpu(rtd, 0);
342
343         switch (cpu_dai->id) {
344         case PRIMARY_MI2S_RX:
345         case PRIMARY_MI2S_TX:
346                 if (--data->pri_mi2s_clk_count == 0) {
347                         snd_soc_dai_set_sysclk(cpu_dai,
348                                                Q6AFE_LPASS_CLK_ID_MCLK_1,
349                                                0,
350                                                SNDRV_PCM_STREAM_PLAYBACK);
351                         snd_soc_dai_set_sysclk(cpu_dai,
352                                                Q6AFE_LPASS_CLK_ID_PRI_MI2S_IBIT,
353                                                0,
354                                                SNDRV_PCM_STREAM_PLAYBACK);
355                 }
356                 break;
357         case TERTIARY_MI2S_RX:
358                 snd_soc_dai_set_sysclk(cpu_dai,
359                                        Q6AFE_LPASS_CLK_ID_TER_MI2S_IBIT,
360                                        0,
361                                        SNDRV_PCM_STREAM_PLAYBACK);
362                 break;
363         case DISPLAY_PORT_RX:
364                 break;
365         default:
366                 dev_err(rtd->dev, "%s: invalid dai id 0x%x\n", __func__,
367                         cpu_dai->id);
368                 break;
369         }
370 }
371
372 static int sc7180_adau7002_init(struct snd_soc_pcm_runtime *rtd)
373 {
374         struct snd_soc_dai *cpu_dai = snd_soc_rtd_to_cpu(rtd, 0);
375
376         switch (cpu_dai->id) {
377         case MI2S_PRIMARY:
378                 return 0;
379         case MI2S_SECONDARY:
380                 return 0;
381         case LPASS_DP_RX:
382                 return sc7180_hdmi_init(rtd);
383         default:
384                 dev_err(rtd->dev, "%s: invalid dai id 0x%x\n", __func__,
385                         cpu_dai->id);
386                 return -EINVAL;
387         }
388         return 0;
389 }
390
391 static int sc7180_adau7002_snd_startup(struct snd_pcm_substream *substream)
392 {
393         struct snd_soc_pcm_runtime *rtd = substream->private_data;
394         struct snd_soc_dai *cpu_dai = snd_soc_rtd_to_cpu(rtd, 0);
395         struct snd_soc_dai *codec_dai = snd_soc_rtd_to_codec(rtd, 0);
396         struct snd_pcm_runtime *runtime = substream->runtime;
397
398         switch (cpu_dai->id) {
399         case MI2S_PRIMARY:
400                 snd_soc_dai_set_fmt(codec_dai,
401                                     SND_SOC_DAIFMT_CBS_CFS |
402                                     SND_SOC_DAIFMT_NB_NF |
403                                     SND_SOC_DAIFMT_I2S);
404                 runtime->hw.formats = SNDRV_PCM_FMTBIT_S32_LE;
405                 snd_pcm_hw_constraint_msbits(runtime, 0, 32, 32);
406
407                 break;
408         case MI2S_SECONDARY:
409                 break;
410         case LPASS_DP_RX:
411                 break;
412         default:
413                 dev_err(rtd->dev, "%s: invalid dai id 0x%x\n", __func__,
414                         cpu_dai->id);
415                 return -EINVAL;
416         }
417         return 0;
418 }
419
420 static int sc7180_qdsp_be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd,
421                                      struct snd_pcm_hw_params *params)
422 {
423         struct snd_interval *rate = hw_param_interval(params,
424                                         SNDRV_PCM_HW_PARAM_RATE);
425         struct snd_interval *channels = hw_param_interval(params,
426                                         SNDRV_PCM_HW_PARAM_CHANNELS);
427
428         rate->min = rate->max = 48000;
429         channels->min = channels->max = 2;
430
431         return 0;
432 }
433
434 static const struct snd_soc_ops sc7180_ops = {
435         .startup = sc7180_snd_startup,
436         .shutdown = sc7180_snd_shutdown,
437 };
438
439 static const struct snd_soc_ops sc7180_qdsp_ops = {
440         .startup = sc7180_qdsp_snd_startup,
441         .shutdown = sc7180_qdsp_snd_shutdown,
442 };
443
444 static const struct snd_soc_ops sc7180_adau7002_ops = {
445         .startup = sc7180_adau7002_snd_startup,
446 };
447
448 static const struct snd_soc_dapm_widget sc7180_snd_widgets[] = {
449         SND_SOC_DAPM_HP("Headphone Jack", NULL),
450         SND_SOC_DAPM_MIC("Headset Mic", NULL),
451 };
452
453 static const struct snd_kcontrol_new sc7180_snd_controls[] = {
454         SOC_DAPM_PIN_SWITCH("Headphone Jack"),
455         SOC_DAPM_PIN_SWITCH("Headset Mic"),
456 };
457
458 static const struct snd_soc_dapm_widget sc7180_adau7002_snd_widgets[] = {
459         SND_SOC_DAPM_MIC("DMIC", NULL),
460 };
461
462 static const char * const dmic_mux_text[] = {
463         "Front Mic",
464         "Rear Mic",
465 };
466
467 static SOC_ENUM_SINGLE_DECL(sc7180_dmic_enum,
468                             SND_SOC_NOPM, 0, dmic_mux_text);
469
470 static const struct snd_kcontrol_new sc7180_dmic_mux_control =
471         SOC_DAPM_ENUM_EXT("DMIC Select Mux", sc7180_dmic_enum,
472                           dmic_get, dmic_set);
473
474 static const struct snd_soc_dapm_widget sc7180_snd_dual_mic_widgets[] = {
475         SND_SOC_DAPM_HP("Headphone Jack", NULL),
476         SND_SOC_DAPM_MIC("Headset Mic", NULL),
477         SND_SOC_DAPM_MIC("DMIC", NULL),
478         SND_SOC_DAPM_MUX("Dmic Mux", SND_SOC_NOPM, 0, 0, &sc7180_dmic_mux_control),
479 };
480
481 static const struct snd_kcontrol_new sc7180_snd_dual_mic_controls[] = {
482         SOC_DAPM_PIN_SWITCH("Headphone Jack"),
483         SOC_DAPM_PIN_SWITCH("Headset Mic"),
484 };
485
486 static const struct snd_soc_dapm_route sc7180_snd_dual_mic_audio_route[] = {
487         {"Dmic Mux", "Front Mic", "DMIC"},
488         {"Dmic Mux", "Rear Mic", "DMIC"},
489 };
490
491 static int sc7180_snd_platform_probe(struct platform_device *pdev)
492 {
493         struct snd_soc_card *card;
494         struct sc7180_snd_data *data;
495         struct device *dev = &pdev->dev;
496         struct snd_soc_dai_link *link;
497         int ret;
498         int i;
499         bool qdsp = false, no_headphone = false;
500
501         /* Allocate the private data */
502         data = devm_kzalloc(dev, sizeof(*data), GFP_KERNEL);
503         if (!data)
504                 return -ENOMEM;
505
506         card = &data->card;
507         snd_soc_card_set_drvdata(card, data);
508
509         card->owner = THIS_MODULE;
510         card->driver_name = DRIVER_NAME;
511         card->dev = dev;
512         card->dapm_widgets = sc7180_snd_widgets;
513         card->num_dapm_widgets = ARRAY_SIZE(sc7180_snd_widgets);
514         card->controls = sc7180_snd_controls;
515         card->num_controls = ARRAY_SIZE(sc7180_snd_controls);
516
517         if (of_property_read_bool(dev->of_node, "dmic-gpios")) {
518                 card->dapm_widgets = sc7180_snd_dual_mic_widgets,
519                 card->num_dapm_widgets = ARRAY_SIZE(sc7180_snd_dual_mic_widgets),
520                 card->controls = sc7180_snd_dual_mic_controls,
521                 card->num_controls = ARRAY_SIZE(sc7180_snd_dual_mic_controls),
522                 card->dapm_routes = sc7180_snd_dual_mic_audio_route,
523                 card->num_dapm_routes = ARRAY_SIZE(sc7180_snd_dual_mic_audio_route),
524                 data->dmic_sel = devm_gpiod_get(&pdev->dev, "dmic", GPIOD_OUT_LOW);
525                 if (IS_ERR(data->dmic_sel)) {
526                         dev_err(&pdev->dev, "DMIC gpio failed err=%ld\n", PTR_ERR(data->dmic_sel));
527                         return PTR_ERR(data->dmic_sel);
528                 }
529         }
530
531         if (of_device_is_compatible(dev->of_node, "google,sc7180-coachz")) {
532                 no_headphone = true;
533                 card->dapm_widgets = sc7180_adau7002_snd_widgets;
534                 card->num_dapm_widgets = ARRAY_SIZE(sc7180_adau7002_snd_widgets);
535         } else if (of_device_is_compatible(dev->of_node, "qcom,sc7180-qdsp6-sndcard")) {
536                 qdsp = true;
537         }
538
539         ret = qcom_snd_parse_of(card);
540         if (ret)
541                 return ret;
542
543         for_each_card_prelinks(card, i, link) {
544                 if (no_headphone) {
545                         link->ops = &sc7180_adau7002_ops;
546                         link->init = sc7180_adau7002_init;
547                 } else if (qdsp) {
548                         if (link->no_pcm == 1) {
549                                 link->ops = &sc7180_qdsp_ops;
550                                 link->be_hw_params_fixup = sc7180_qdsp_be_hw_params_fixup;
551                                 link->init = sc7180_qdsp_init;
552                         }
553                 } else {
554                         link->ops = &sc7180_ops;
555                         link->init = sc7180_init;
556                 }
557         }
558
559         return devm_snd_soc_register_card(dev, card);
560 }
561
562 static const struct of_device_id sc7180_snd_device_id[]  = {
563         {.compatible = "google,sc7180-trogdor"},
564         {.compatible = "google,sc7180-coachz"},
565         {.compatible = "qcom,sc7180-qdsp6-sndcard"},
566         {},
567 };
568 MODULE_DEVICE_TABLE(of, sc7180_snd_device_id);
569
570 static struct platform_driver sc7180_snd_driver = {
571         .probe = sc7180_snd_platform_probe,
572         .driver = {
573                 .name = "msm-snd-sc7180",
574                 .of_match_table = sc7180_snd_device_id,
575                 .pm = &snd_soc_pm_ops,
576         },
577 };
578 module_platform_driver(sc7180_snd_driver);
579
580 MODULE_DESCRIPTION("sc7180 ASoC Machine Driver");
581 MODULE_LICENSE("GPL v2");