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