Merge existing fixes from regulator/for-5.11
[linux-2.6-microblaze.git] / sound / soc / uniphier / aio-ld11.c
1 // SPDX-License-Identifier: GPL-2.0
2 //
3 // Socionext UniPhier AIO ALSA driver for LD11/LD20.
4 //
5 // Copyright (c) 2016-2018 Socionext Inc.
6
7 #include <linux/module.h>
8
9 #include "aio.h"
10
11 static const struct uniphier_aio_spec uniphier_aio_ld11[] = {
12         /* for HDMI PCM In, Pin:AI1Dx */
13         {
14                 .name = AUD_NAME_PCMIN1,
15                 .gname = AUD_GNAME_HDMI,
16                 .swm = {
17                         .type  = PORT_TYPE_I2S,
18                         .dir   = PORT_DIR_INPUT,
19                         .rb    = { 21, 14, },
20                         .ch    = { 21, 14, },
21                         .iif   = { 5, 3, },
22                         .iport = { 0, AUD_HW_PCMIN1, },
23                 },
24         },
25
26         /* for SIF In, Pin:AI2Dx */
27         {
28                 .name = AUD_NAME_PCMIN2,
29                 .swm = {
30                         .type  = PORT_TYPE_I2S,
31                         .dir   = PORT_DIR_INPUT,
32                         .rb    = { 22, 15, },
33                         .ch    = { 22, 15, },
34                         .iif   = { 6, 4, },
35                         .iport = { 1, AUD_HW_PCMIN2, },
36                 },
37         },
38
39         /* for Line In, Pin:AI3Dx */
40         {
41                 .name = AUD_NAME_PCMIN3,
42                 .gname = AUD_GNAME_LINE,
43                 .swm = {
44                         .type  = PORT_TYPE_EVE,
45                         .dir   = PORT_DIR_INPUT,
46                         .rb    = { 23, 16, },
47                         .ch    = { 23, 16, },
48                         .iif   = { 7, 5, },
49                         .iport = { 2, AUD_HW_PCMIN3, },
50                 },
51         },
52
53         /* for S/PDIF In, Pin:AI1IEC */
54         {
55                 .name = AUD_NAME_IECIN1,
56                 .gname = AUD_GNAME_IEC,
57                 .swm = {
58                         .type  = PORT_TYPE_SPDIF,
59                         .dir   = PORT_DIR_INPUT,
60                         .rb    = { 26, 17, },
61                         .ch    = { 26, 17, },
62                         .iif   = { 10, 6, },
63                         .iport = { 3, AUD_HW_IECIN1, },
64                 },
65         },
66
67         /* for Speaker, Pin:AO1Dx */
68         {
69                 .name = AUD_NAME_HPCMOUT1,
70                 .swm = {
71                         .type  = PORT_TYPE_I2S,
72                         .dir   = PORT_DIR_OUTPUT,
73                         .rb    = { 0, 0, },
74                         .ch    = { 0, 0, },
75                         .oif   = { 0, 0, },
76                         .oport = { 0, AUD_HW_HPCMOUT1, },
77                 },
78         },
79
80         /* for HDMI PCM, Pin:AO2Dx */
81         {
82                 .name = AUD_NAME_PCMOUT1,
83                 .gname = AUD_GNAME_HDMI,
84                 .swm = {
85                         .type  = PORT_TYPE_I2S,
86                         .dir   = PORT_DIR_OUTPUT,
87                         .rb    = { 0, 0, },
88                         .ch    = { 0, 0, },
89                         .oif   = { 0, 0, },
90                         .oport = { 3, AUD_HW_PCMOUT1, },
91                 },
92         },
93
94         /* for Line Out, Pin:LO2_x */
95         {
96                 .name = AUD_NAME_PCMOUT2,
97                 .gname = AUD_GNAME_LINE,
98                 .swm = {
99                         .type  = PORT_TYPE_EVE,
100                         .dir   = PORT_DIR_OUTPUT,
101                         .rb    = { 2, 2, },
102                         .ch    = { 2, 2, },
103                         .oif   = { 2, 2, },
104                         .oport = { 1, AUD_HW_PCMOUT2, },
105                 },
106         },
107
108         /* for Headphone, Pin:HP1_x */
109         {
110                 .name = AUD_NAME_PCMOUT3,
111                 .swm = {
112                         .type  = PORT_TYPE_EVE,
113                         .dir   = PORT_DIR_OUTPUT,
114                         .rb    = { 3, 3, },
115                         .ch    = { 3, 3, },
116                         .oif   = { 3, 3, },
117                         .oport = { 2, AUD_HW_PCMOUT3, },
118                 },
119         },
120
121         /* for HW Sampling Rate Converter */
122         {
123                 .name = AUD_NAME_EPCMOUT2,
124                 .swm = {
125                         .type  = PORT_TYPE_CONV,
126                         .dir   = PORT_DIR_OUTPUT,
127                         .rb    = { 7, 5, },
128                         .ch    = { 7, 5, },
129                         .oif   = { 7, 5, },
130                         .oport = { 6, AUD_HW_EPCMOUT2, },
131                         .och   = { 17, 12, },
132                         .iif   = { 1, 1, },
133                 },
134         },
135
136         /* for HW Sampling Rate Converter 2 */
137         {
138                 .name = AUD_NAME_EPCMOUT3,
139                 .swm = {
140                         .type  = PORT_TYPE_CONV,
141                         .dir   = PORT_DIR_OUTPUT,
142                         .rb    = { 8, 6, },
143                         .ch    = { 8, 6, },
144                         .oif   = { 8, 6, },
145                         .oport = { 7, AUD_HW_EPCMOUT3, },
146                         .och   = { 18, 13, },
147                         .iif   = { 2, 2, },
148                 },
149         },
150
151         /* for S/PDIF Out, Pin:AO1IEC */
152         {
153                 .name = AUD_NAME_HIECOUT1,
154                 .gname = AUD_GNAME_IEC,
155                 .swm = {
156                         .type  = PORT_TYPE_SPDIF,
157                         .dir   = PORT_DIR_OUTPUT,
158                         .rb    = { 1, 1, },
159                         .ch    = { 1, 1, },
160                         .oif   = { 1, 1, },
161                         .oport = { 12, AUD_HW_HIECOUT1, },
162                 },
163         },
164
165         /* for S/PDIF Out, Pin:AO1IEC, Compress */
166         {
167                 .name = AUD_NAME_HIECCOMPOUT1,
168                 .gname = AUD_GNAME_IEC,
169                 .swm = {
170                         .type  = PORT_TYPE_SPDIF,
171                         .dir   = PORT_DIR_OUTPUT,
172                         .rb    = { 1, 1, },
173                         .ch    = { 1, 1, },
174                         .oif   = { 1, 1, },
175                         .oport = { 12, AUD_HW_HIECOUT1, },
176                 },
177         },
178 };
179
180 static const struct uniphier_aio_pll uniphier_aio_pll_ld11[] = {
181         [AUD_PLL_A1]   = { .enable = true, },
182         [AUD_PLL_F1]   = { .enable = true, },
183         [AUD_PLL_A2]   = { .enable = true, },
184         [AUD_PLL_F2]   = { .enable = true, },
185         [AUD_PLL_APLL] = { .enable = true, },
186         [AUD_PLL_RX0]  = { .enable = true, },
187         [AUD_PLL_USB0] = { .enable = true, },
188         [AUD_PLL_HSC0] = { .enable = true, },
189 };
190
191 static int uniphier_aio_ld11_probe(struct snd_soc_dai *dai)
192 {
193         int ret;
194
195         ret = uniphier_aio_dai_probe(dai);
196         if (ret < 0)
197                 return ret;
198
199         ret = snd_soc_dai_set_pll(dai, AUD_PLL_A1, 0, 0, 36864000);
200         if (ret < 0)
201                 return ret;
202         ret = snd_soc_dai_set_pll(dai, AUD_PLL_F1, 0, 0, 36864000);
203         if (ret < 0)
204                 return ret;
205
206         ret = snd_soc_dai_set_pll(dai, AUD_PLL_A2, 0, 0, 33868800);
207         if (ret < 0)
208                 return ret;
209         ret = snd_soc_dai_set_pll(dai, AUD_PLL_F2, 0, 0, 33868800);
210         if (ret < 0)
211                 return ret;
212
213         return 0;
214 }
215
216 static struct snd_soc_dai_driver uniphier_aio_dai_ld11[] = {
217         {
218                 .name    = AUD_GNAME_HDMI,
219                 .probe   = uniphier_aio_ld11_probe,
220                 .remove  = uniphier_aio_dai_remove,
221                 .playback = {
222                         .stream_name = AUD_NAME_PCMOUT1,
223                         .formats     = SNDRV_PCM_FMTBIT_S32_LE,
224                         .rates       = SNDRV_PCM_RATE_48000,
225                         .channels_min = 2,
226                         .channels_max = 2,
227                 },
228                 .capture = {
229                         .stream_name = AUD_NAME_PCMIN1,
230                         .formats     = SNDRV_PCM_FMTBIT_S32_LE,
231                         .rates       = SNDRV_PCM_RATE_48000 |
232                                 SNDRV_PCM_RATE_44100 |
233                                 SNDRV_PCM_RATE_32000,
234                         .channels_min = 2,
235                         .channels_max = 2,
236                 },
237                 .ops = &uniphier_aio_i2s_ops,
238         },
239         {
240                 .name    = AUD_NAME_PCMIN2,
241                 .probe   = uniphier_aio_ld11_probe,
242                 .remove  = uniphier_aio_dai_remove,
243                 .capture = {
244                         .stream_name = AUD_NAME_PCMIN2,
245                         .formats     = SNDRV_PCM_FMTBIT_S32_LE,
246                         .rates       = SNDRV_PCM_RATE_48000,
247                         .channels_min = 2,
248                         .channels_max = 2,
249                 },
250                 .ops = &uniphier_aio_i2s_ops,
251         },
252         {
253                 .name    = AUD_GNAME_LINE,
254                 .probe   = uniphier_aio_ld11_probe,
255                 .remove  = uniphier_aio_dai_remove,
256                 .playback = {
257                         .stream_name = AUD_NAME_PCMOUT2,
258                         .formats     = SNDRV_PCM_FMTBIT_S32_LE,
259                         .rates       = SNDRV_PCM_RATE_48000,
260                         .channels_min = 2,
261                         .channels_max = 2,
262                 },
263                 .capture = {
264                         .stream_name = AUD_NAME_PCMIN3,
265                         .formats     = SNDRV_PCM_FMTBIT_S32_LE,
266                         .rates       = SNDRV_PCM_RATE_48000,
267                         .channels_min = 2,
268                         .channels_max = 2,
269                 },
270                 .ops = &uniphier_aio_i2s_ops,
271         },
272         {
273                 .name    = AUD_NAME_HPCMOUT1,
274                 .probe   = uniphier_aio_ld11_probe,
275                 .remove  = uniphier_aio_dai_remove,
276                 .playback = {
277                         .stream_name = AUD_NAME_HPCMOUT1,
278                         .formats     = SNDRV_PCM_FMTBIT_S32_LE,
279                         .rates       = SNDRV_PCM_RATE_48000,
280                         .channels_min = 2,
281                         .channels_max = 8,
282                 },
283                 .ops = &uniphier_aio_i2s_ops,
284         },
285         {
286                 .name    = AUD_NAME_PCMOUT3,
287                 .probe   = uniphier_aio_ld11_probe,
288                 .remove  = uniphier_aio_dai_remove,
289                 .playback = {
290                         .stream_name = AUD_NAME_PCMOUT3,
291                         .formats     = SNDRV_PCM_FMTBIT_S32_LE,
292                         .rates       = SNDRV_PCM_RATE_48000,
293                         .channels_min = 2,
294                         .channels_max = 2,
295                 },
296                 .ops = &uniphier_aio_i2s_ops,
297         },
298         {
299                 .name    = AUD_NAME_HIECOUT1,
300                 .probe   = uniphier_aio_ld11_probe,
301                 .remove  = uniphier_aio_dai_remove,
302                 .playback = {
303                         .stream_name = AUD_NAME_HIECOUT1,
304                         .formats     = SNDRV_PCM_FMTBIT_S32_LE,
305                         .rates       = SNDRV_PCM_RATE_48000,
306                         .channels_min = 2,
307                         .channels_max = 2,
308                 },
309                 .ops = &uniphier_aio_spdif_ops,
310         },
311         {
312                 .name    = AUD_NAME_EPCMOUT2,
313                 .probe   = uniphier_aio_ld11_probe,
314                 .remove  = uniphier_aio_dai_remove,
315                 .playback = {
316                         .stream_name = AUD_NAME_EPCMOUT2,
317                         .formats     = SNDRV_PCM_FMTBIT_S32_LE,
318                         .rates       = SNDRV_PCM_RATE_48000 |
319                                 SNDRV_PCM_RATE_44100 |
320                                 SNDRV_PCM_RATE_32000,
321                         .channels_min = 2,
322                         .channels_max = 2,
323                 },
324                 .ops = &uniphier_aio_i2s_ops,
325         },
326         {
327                 .name    = AUD_NAME_EPCMOUT3,
328                 .probe   = uniphier_aio_ld11_probe,
329                 .remove  = uniphier_aio_dai_remove,
330                 .playback = {
331                         .stream_name = AUD_NAME_EPCMOUT3,
332                         .formats     = SNDRV_PCM_FMTBIT_S32_LE,
333                         .rates       = SNDRV_PCM_RATE_48000 |
334                                 SNDRV_PCM_RATE_44100 |
335                                 SNDRV_PCM_RATE_32000,
336                         .channels_min = 2,
337                         .channels_max = 2,
338                 },
339                 .ops = &uniphier_aio_i2s_ops,
340         },
341         {
342                 .name    = AUD_NAME_HIECCOMPOUT1,
343                 .probe   = uniphier_aio_ld11_probe,
344                 .remove  = uniphier_aio_dai_remove,
345                 .compress_new = snd_soc_new_compress,
346                 .playback = {
347                         .stream_name = AUD_NAME_HIECCOMPOUT1,
348                         .channels_min = 1,
349                         .channels_max = 1,
350                 },
351                 .ops = &uniphier_aio_spdif_ops,
352         },
353 };
354
355 static const struct uniphier_aio_chip_spec uniphier_aio_ld11_spec = {
356         .specs     = uniphier_aio_ld11,
357         .num_specs = ARRAY_SIZE(uniphier_aio_ld11),
358         .dais      = uniphier_aio_dai_ld11,
359         .num_dais  = ARRAY_SIZE(uniphier_aio_dai_ld11),
360         .plls      = uniphier_aio_pll_ld11,
361         .num_plls  = ARRAY_SIZE(uniphier_aio_pll_ld11),
362         .addr_ext  = 0,
363 };
364
365 static const struct uniphier_aio_chip_spec uniphier_aio_ld20_spec = {
366         .specs     = uniphier_aio_ld11,
367         .num_specs = ARRAY_SIZE(uniphier_aio_ld11),
368         .dais      = uniphier_aio_dai_ld11,
369         .num_dais  = ARRAY_SIZE(uniphier_aio_dai_ld11),
370         .plls      = uniphier_aio_pll_ld11,
371         .num_plls  = ARRAY_SIZE(uniphier_aio_pll_ld11),
372         .addr_ext  = 1,
373 };
374
375 static const struct of_device_id uniphier_aio_of_match[] __maybe_unused = {
376         {
377                 .compatible = "socionext,uniphier-ld11-aio",
378                 .data = &uniphier_aio_ld11_spec,
379         },
380         {
381                 .compatible = "socionext,uniphier-ld20-aio",
382                 .data = &uniphier_aio_ld20_spec,
383         },
384         {},
385 };
386 MODULE_DEVICE_TABLE(of, uniphier_aio_of_match);
387
388 static struct platform_driver uniphier_aio_driver = {
389         .driver = {
390                 .name = "snd-uniphier-aio-ld11",
391                 .of_match_table = of_match_ptr(uniphier_aio_of_match),
392         },
393         .probe    = uniphier_aio_probe,
394         .remove   = uniphier_aio_remove,
395 };
396 module_platform_driver(uniphier_aio_driver);
397
398 MODULE_AUTHOR("Katsuhiro Suzuki <suzuki.katsuhiro@socionext.com>");
399 MODULE_DESCRIPTION("UniPhier LD11/LD20 AIO driver.");
400 MODULE_LICENSE("GPL v2");