GNU Linux-libre 5.4.200-gnu1
[releases.git] / sound / soc / qcom / sdm845.c
1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  * Copyright (c) 2018, The Linux Foundation. All rights reserved.
4  */
5
6 #include <linux/module.h>
7 #include <linux/platform_device.h>
8 #include <linux/of_device.h>
9 #include <sound/core.h>
10 #include <sound/pcm.h>
11 #include <sound/pcm_params.h>
12 #include <sound/jack.h>
13 #include <sound/soc.h>
14 #include <uapi/linux/input-event-codes.h>
15 #include "common.h"
16 #include "qdsp6/q6afe.h"
17 #include "../codecs/rt5663.h"
18
19 #define DRIVER_NAME     "sdm845"
20 #define DEFAULT_SAMPLE_RATE_48K         48000
21 #define DEFAULT_MCLK_RATE               24576000
22 #define TDM_BCLK_RATE           6144000
23 #define MI2S_BCLK_RATE          1536000
24 #define LEFT_SPK_TDM_TX_MASK    0x30
25 #define RIGHT_SPK_TDM_TX_MASK   0xC0
26 #define SPK_TDM_RX_MASK         0x03
27 #define NUM_TDM_SLOTS           8
28
29 struct sdm845_snd_data {
30         struct snd_soc_jack jack;
31         bool jack_setup;
32         struct snd_soc_card *card;
33         uint32_t pri_mi2s_clk_count;
34         uint32_t sec_mi2s_clk_count;
35         uint32_t quat_tdm_clk_count;
36 };
37
38 static unsigned int tdm_slot_offset[8] = {0, 4, 8, 12, 16, 20, 24, 28};
39
40 static int sdm845_tdm_snd_hw_params(struct snd_pcm_substream *substream,
41                                         struct snd_pcm_hw_params *params)
42 {
43         struct snd_soc_pcm_runtime *rtd = substream->private_data;
44         struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
45         int ret = 0, j;
46         int channels, slot_width;
47
48         switch (params_format(params)) {
49         case SNDRV_PCM_FORMAT_S16_LE:
50                 slot_width = 16;
51                 break;
52         default:
53                 dev_err(rtd->dev, "%s: invalid param format 0x%x\n",
54                                 __func__, params_format(params));
55                 return -EINVAL;
56         }
57
58         channels = params_channels(params);
59         if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
60                 ret = snd_soc_dai_set_tdm_slot(cpu_dai, 0, 0x3,
61                                 8, slot_width);
62                 if (ret < 0) {
63                         dev_err(rtd->dev, "%s: failed to set tdm slot, err:%d\n",
64                                         __func__, ret);
65                         goto end;
66                 }
67
68                 ret = snd_soc_dai_set_channel_map(cpu_dai, 0, NULL,
69                                 channels, tdm_slot_offset);
70                 if (ret < 0) {
71                         dev_err(rtd->dev, "%s: failed to set channel map, err:%d\n",
72                                         __func__, ret);
73                         goto end;
74                 }
75         } else {
76                 ret = snd_soc_dai_set_tdm_slot(cpu_dai, 0xf, 0,
77                                 8, slot_width);
78                 if (ret < 0) {
79                         dev_err(rtd->dev, "%s: failed to set tdm slot, err:%d\n",
80                                         __func__, ret);
81                         goto end;
82                 }
83
84                 ret = snd_soc_dai_set_channel_map(cpu_dai, channels,
85                                 tdm_slot_offset, 0, NULL);
86                 if (ret < 0) {
87                         dev_err(rtd->dev, "%s: failed to set channel map, err:%d\n",
88                                         __func__, ret);
89                         goto end;
90                 }
91         }
92
93         for (j = 0; j < rtd->num_codecs; j++) {
94                 struct snd_soc_dai *codec_dai = rtd->codec_dais[j];
95
96                 if (!strcmp(codec_dai->component->name_prefix, "Left")) {
97                         ret = snd_soc_dai_set_tdm_slot(
98                                         codec_dai, LEFT_SPK_TDM_TX_MASK,
99                                         SPK_TDM_RX_MASK, NUM_TDM_SLOTS,
100                                         slot_width);
101                         if (ret < 0) {
102                                 dev_err(rtd->dev,
103                                         "DEV0 TDM slot err:%d\n", ret);
104                                 return ret;
105                         }
106                 }
107
108                 if (!strcmp(codec_dai->component->name_prefix, "Right")) {
109                         ret = snd_soc_dai_set_tdm_slot(
110                                         codec_dai, RIGHT_SPK_TDM_TX_MASK,
111                                         SPK_TDM_RX_MASK, NUM_TDM_SLOTS,
112                                         slot_width);
113                         if (ret < 0) {
114                                 dev_err(rtd->dev,
115                                         "DEV1 TDM slot err:%d\n", ret);
116                                 return ret;
117                         }
118                 }
119         }
120
121 end:
122         return ret;
123 }
124
125 static int sdm845_snd_hw_params(struct snd_pcm_substream *substream,
126                                         struct snd_pcm_hw_params *params)
127 {
128         struct snd_soc_pcm_runtime *rtd = substream->private_data;
129         struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
130         struct snd_soc_dai *codec_dai = rtd->codec_dai;
131         int ret = 0;
132
133         switch (cpu_dai->id) {
134         case PRIMARY_MI2S_RX:
135         case PRIMARY_MI2S_TX:
136                 /*
137                  * Use ASRC for internal clocks, as PLL rate isn't multiple
138                  * of BCLK.
139                  */
140                 rt5663_sel_asrc_clk_src(
141                         codec_dai->component,
142                         RT5663_DA_STEREO_FILTER | RT5663_AD_STEREO_FILTER,
143                         RT5663_CLK_SEL_I2S1_ASRC);
144                 ret = snd_soc_dai_set_sysclk(
145                         codec_dai, RT5663_SCLK_S_MCLK, DEFAULT_MCLK_RATE,
146                         SND_SOC_CLOCK_IN);
147                 if (ret < 0)
148                         dev_err(rtd->dev,
149                                 "snd_soc_dai_set_sysclk err = %d\n", ret);
150                 break;
151         case QUATERNARY_TDM_RX_0:
152         case QUATERNARY_TDM_TX_0:
153                 ret = sdm845_tdm_snd_hw_params(substream, params);
154                 break;
155         default:
156                 pr_err("%s: invalid dai id 0x%x\n", __func__, cpu_dai->id);
157                 break;
158         }
159         return ret;
160 }
161
162 static void sdm845_jack_free(struct snd_jack *jack)
163 {
164         struct snd_soc_component *component = jack->private_data;
165
166         snd_soc_component_set_jack(component, NULL, NULL);
167 }
168
169 static int sdm845_dai_init(struct snd_soc_pcm_runtime *rtd)
170 {
171         struct snd_soc_component *component;
172         struct snd_soc_card *card = rtd->card;
173         struct snd_soc_dai *codec_dai = rtd->codec_dai;
174         struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
175         struct sdm845_snd_data *pdata = snd_soc_card_get_drvdata(card);
176         struct snd_jack *jack;
177         int rval;
178
179         if (!pdata->jack_setup) {
180                 rval = snd_soc_card_jack_new(card, "Headset Jack",
181                                 SND_JACK_HEADSET |
182                                 SND_JACK_HEADPHONE |
183                                 SND_JACK_BTN_0 | SND_JACK_BTN_1 |
184                                 SND_JACK_BTN_2 | SND_JACK_BTN_3,
185                                 &pdata->jack, NULL, 0);
186
187                 if (rval < 0) {
188                         dev_err(card->dev, "Unable to add Headphone Jack\n");
189                         return rval;
190                 }
191
192                 jack = pdata->jack.jack;
193
194                 snd_jack_set_key(jack, SND_JACK_BTN_0, KEY_PLAYPAUSE);
195                 snd_jack_set_key(jack, SND_JACK_BTN_1, KEY_VOICECOMMAND);
196                 snd_jack_set_key(jack, SND_JACK_BTN_2, KEY_VOLUMEUP);
197                 snd_jack_set_key(jack, SND_JACK_BTN_3, KEY_VOLUMEDOWN);
198                 pdata->jack_setup = true;
199         }
200
201         switch (cpu_dai->id) {
202         case PRIMARY_MI2S_RX:
203                 jack  = pdata->jack.jack;
204                 component = codec_dai->component;
205
206                 jack->private_data = component;
207                 jack->private_free = sdm845_jack_free;
208                 rval = snd_soc_component_set_jack(component,
209                                                   &pdata->jack, NULL);
210                 if (rval != 0 && rval != -ENOTSUPP) {
211                         dev_warn(card->dev, "Failed to set jack: %d\n", rval);
212                         return rval;
213                 }
214                 break;
215         default:
216                 break;
217         }
218
219         return 0;
220 }
221
222
223 static int sdm845_snd_startup(struct snd_pcm_substream *substream)
224 {
225         unsigned int fmt = SND_SOC_DAIFMT_CBS_CFS;
226         unsigned int codec_dai_fmt = SND_SOC_DAIFMT_CBS_CFS;
227         struct snd_soc_pcm_runtime *rtd = substream->private_data;
228         struct snd_soc_card *card = rtd->card;
229         struct sdm845_snd_data *data = snd_soc_card_get_drvdata(card);
230         struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
231         struct snd_soc_dai *codec_dai = rtd->codec_dai;
232         int j;
233         int ret;
234
235         switch (cpu_dai->id) {
236         case PRIMARY_MI2S_RX:
237         case PRIMARY_MI2S_TX:
238                 codec_dai_fmt |= SND_SOC_DAIFMT_NB_NF;
239                 if (++(data->pri_mi2s_clk_count) == 1) {
240                         snd_soc_dai_set_sysclk(cpu_dai,
241                                 Q6AFE_LPASS_CLK_ID_MCLK_1,
242                                 DEFAULT_MCLK_RATE, SNDRV_PCM_STREAM_PLAYBACK);
243                         snd_soc_dai_set_sysclk(cpu_dai,
244                                 Q6AFE_LPASS_CLK_ID_PRI_MI2S_IBIT,
245                                 MI2S_BCLK_RATE, SNDRV_PCM_STREAM_PLAYBACK);
246                 }
247                 snd_soc_dai_set_fmt(cpu_dai, fmt);
248                 snd_soc_dai_set_fmt(codec_dai, codec_dai_fmt);
249                 break;
250
251         case SECONDARY_MI2S_TX:
252                 codec_dai_fmt |= SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_I2S;
253                 if (++(data->sec_mi2s_clk_count) == 1) {
254                         snd_soc_dai_set_sysclk(cpu_dai,
255                                 Q6AFE_LPASS_CLK_ID_SEC_MI2S_IBIT,
256                                 MI2S_BCLK_RATE, SNDRV_PCM_STREAM_CAPTURE);
257                 }
258                 snd_soc_dai_set_fmt(cpu_dai, fmt);
259                 snd_soc_dai_set_fmt(codec_dai, codec_dai_fmt);
260                 break;
261
262         case QUATERNARY_TDM_RX_0:
263         case QUATERNARY_TDM_TX_0:
264                 if (++(data->quat_tdm_clk_count) == 1) {
265                         snd_soc_dai_set_sysclk(cpu_dai,
266                                 Q6AFE_LPASS_CLK_ID_QUAD_TDM_IBIT,
267                                 TDM_BCLK_RATE, SNDRV_PCM_STREAM_PLAYBACK);
268                 }
269
270                 codec_dai_fmt |= SND_SOC_DAIFMT_IB_NF | SND_SOC_DAIFMT_DSP_B;
271
272                 for (j = 0; j < rtd->num_codecs; j++) {
273                         codec_dai = rtd->codec_dais[j];
274
275                         if (!strcmp(codec_dai->component->name_prefix,
276                                     "Left")) {
277                                 ret = snd_soc_dai_set_fmt(
278                                                 codec_dai, codec_dai_fmt);
279                                 if (ret < 0) {
280                                         dev_err(rtd->dev,
281                                                 "Left TDM fmt err:%d\n", ret);
282                                         return ret;
283                                 }
284                         }
285
286                         if (!strcmp(codec_dai->component->name_prefix,
287                                     "Right")) {
288                                 ret = snd_soc_dai_set_fmt(
289                                                 codec_dai, codec_dai_fmt);
290                                 if (ret < 0) {
291                                         dev_err(rtd->dev,
292                                                 "Right TDM slot err:%d\n", ret);
293                                         return ret;
294                                 }
295                         }
296                 }
297                 break;
298
299         default:
300                 pr_err("%s: invalid dai id 0x%x\n", __func__, cpu_dai->id);
301                 break;
302         }
303         return 0;
304 }
305
306 static void  sdm845_snd_shutdown(struct snd_pcm_substream *substream)
307 {
308         struct snd_soc_pcm_runtime *rtd = substream->private_data;
309         struct snd_soc_card *card = rtd->card;
310         struct sdm845_snd_data *data = snd_soc_card_get_drvdata(card);
311         struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
312
313         switch (cpu_dai->id) {
314         case PRIMARY_MI2S_RX:
315         case PRIMARY_MI2S_TX:
316                 if (--(data->pri_mi2s_clk_count) == 0) {
317                         snd_soc_dai_set_sysclk(cpu_dai,
318                                 Q6AFE_LPASS_CLK_ID_MCLK_1,
319                                 0, SNDRV_PCM_STREAM_PLAYBACK);
320                         snd_soc_dai_set_sysclk(cpu_dai,
321                                 Q6AFE_LPASS_CLK_ID_PRI_MI2S_IBIT,
322                                 0, SNDRV_PCM_STREAM_PLAYBACK);
323                 }
324                 break;
325
326         case SECONDARY_MI2S_TX:
327                 if (--(data->sec_mi2s_clk_count) == 0) {
328                         snd_soc_dai_set_sysclk(cpu_dai,
329                                 Q6AFE_LPASS_CLK_ID_SEC_MI2S_IBIT,
330                                 0, SNDRV_PCM_STREAM_CAPTURE);
331                 }
332                 break;
333
334         case QUATERNARY_TDM_RX_0:
335         case QUATERNARY_TDM_TX_0:
336                 if (--(data->quat_tdm_clk_count) == 0) {
337                         snd_soc_dai_set_sysclk(cpu_dai,
338                                 Q6AFE_LPASS_CLK_ID_QUAD_TDM_IBIT,
339                                 0, SNDRV_PCM_STREAM_PLAYBACK);
340                 }
341                 break;
342
343         default:
344                 pr_err("%s: invalid dai id 0x%x\n", __func__, cpu_dai->id);
345                 break;
346         }
347 }
348
349 static const struct snd_soc_ops sdm845_be_ops = {
350         .hw_params = sdm845_snd_hw_params,
351         .startup = sdm845_snd_startup,
352         .shutdown = sdm845_snd_shutdown,
353 };
354
355 static int sdm845_be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd,
356                                 struct snd_pcm_hw_params *params)
357 {
358         struct snd_interval *rate = hw_param_interval(params,
359                                         SNDRV_PCM_HW_PARAM_RATE);
360         struct snd_interval *channels = hw_param_interval(params,
361                                         SNDRV_PCM_HW_PARAM_CHANNELS);
362         struct snd_mask *fmt = hw_param_mask(params, SNDRV_PCM_HW_PARAM_FORMAT);
363
364         rate->min = rate->max = DEFAULT_SAMPLE_RATE_48K;
365         channels->min = channels->max = 2;
366         snd_mask_set_format(fmt, SNDRV_PCM_FORMAT_S16_LE);
367
368         return 0;
369 }
370
371 static const struct snd_soc_dapm_widget sdm845_snd_widgets[] = {
372         SND_SOC_DAPM_HP("Headphone Jack", NULL),
373         SND_SOC_DAPM_MIC("Headset Mic", NULL),
374         SND_SOC_DAPM_SPK("Left Spk", NULL),
375         SND_SOC_DAPM_SPK("Right Spk", NULL),
376         SND_SOC_DAPM_MIC("Int Mic", NULL),
377 };
378
379 static void sdm845_add_ops(struct snd_soc_card *card)
380 {
381         struct snd_soc_dai_link *link;
382         int i;
383
384         for_each_card_prelinks(card, i, link) {
385                 if (link->no_pcm == 1) {
386                         link->ops = &sdm845_be_ops;
387                         link->be_hw_params_fixup = sdm845_be_hw_params_fixup;
388                 }
389                 link->init = sdm845_dai_init;
390         }
391 }
392
393 static int sdm845_snd_platform_probe(struct platform_device *pdev)
394 {
395         struct snd_soc_card *card;
396         struct sdm845_snd_data *data;
397         struct device *dev = &pdev->dev;
398         int ret;
399
400         card = kzalloc(sizeof(*card), GFP_KERNEL);
401         if (!card)
402                 return -ENOMEM;
403
404         /* Allocate the private data */
405         data = kzalloc(sizeof(*data), GFP_KERNEL);
406         if (!data) {
407                 ret = -ENOMEM;
408                 goto data_alloc_fail;
409         }
410
411         card->driver_name = DRIVER_NAME;
412         card->dapm_widgets = sdm845_snd_widgets;
413         card->num_dapm_widgets = ARRAY_SIZE(sdm845_snd_widgets);
414         card->dev = dev;
415         card->owner = THIS_MODULE;
416         dev_set_drvdata(dev, card);
417         ret = qcom_snd_parse_of(card);
418         if (ret) {
419                 dev_err(dev, "Error parsing OF data\n");
420                 goto parse_dt_fail;
421         }
422
423         data->card = card;
424         snd_soc_card_set_drvdata(card, data);
425
426         sdm845_add_ops(card);
427         ret = snd_soc_register_card(card);
428         if (ret) {
429                 dev_err(dev, "Sound card registration failed\n");
430                 goto register_card_fail;
431         }
432         return ret;
433
434 register_card_fail:
435         kfree(card->dai_link);
436 parse_dt_fail:
437         kfree(data);
438 data_alloc_fail:
439         kfree(card);
440         return ret;
441 }
442
443 static int sdm845_snd_platform_remove(struct platform_device *pdev)
444 {
445         struct snd_soc_card *card = dev_get_drvdata(&pdev->dev);
446         struct sdm845_snd_data *data = snd_soc_card_get_drvdata(card);
447
448         snd_soc_unregister_card(card);
449         kfree(card->dai_link);
450         kfree(data);
451         kfree(card);
452         return 0;
453 }
454
455 static const struct of_device_id sdm845_snd_device_id[]  = {
456         { .compatible = "qcom,sdm845-sndcard" },
457         {},
458 };
459 MODULE_DEVICE_TABLE(of, sdm845_snd_device_id);
460
461 static struct platform_driver sdm845_snd_driver = {
462         .probe = sdm845_snd_platform_probe,
463         .remove = sdm845_snd_platform_remove,
464         .driver = {
465                 .name = "msm-snd-sdm845",
466                 .of_match_table = sdm845_snd_device_id,
467         },
468 };
469 module_platform_driver(sdm845_snd_driver);
470
471 MODULE_DESCRIPTION("sdm845 ASoC Machine Driver");
472 MODULE_LICENSE("GPL v2");