GNU Linux-libre 6.8.9-gnu
[releases.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 struct snd_soc_dai_driver uniphier_aio_dai_ld11[] = {
192         {
193                 .name    = AUD_GNAME_HDMI,
194                 .playback = {
195                         .stream_name = AUD_NAME_PCMOUT1,
196                         .formats     = SNDRV_PCM_FMTBIT_S32_LE,
197                         .rates       = SNDRV_PCM_RATE_48000,
198                         .channels_min = 2,
199                         .channels_max = 2,
200                 },
201                 .capture = {
202                         .stream_name = AUD_NAME_PCMIN1,
203                         .formats     = SNDRV_PCM_FMTBIT_S32_LE,
204                         .rates       = SNDRV_PCM_RATE_48000 |
205                                 SNDRV_PCM_RATE_44100 |
206                                 SNDRV_PCM_RATE_32000,
207                         .channels_min = 2,
208                         .channels_max = 2,
209                 },
210                 .ops = &uniphier_aio_i2s_ld11_ops,
211         },
212         {
213                 .name    = AUD_NAME_PCMIN2,
214                 .capture = {
215                         .stream_name = AUD_NAME_PCMIN2,
216                         .formats     = SNDRV_PCM_FMTBIT_S32_LE,
217                         .rates       = SNDRV_PCM_RATE_48000,
218                         .channels_min = 2,
219                         .channels_max = 2,
220                 },
221                 .ops = &uniphier_aio_i2s_ld11_ops,
222         },
223         {
224                 .name    = AUD_GNAME_LINE,
225                 .playback = {
226                         .stream_name = AUD_NAME_PCMOUT2,
227                         .formats     = SNDRV_PCM_FMTBIT_S32_LE,
228                         .rates       = SNDRV_PCM_RATE_48000,
229                         .channels_min = 2,
230                         .channels_max = 2,
231                 },
232                 .capture = {
233                         .stream_name = AUD_NAME_PCMIN3,
234                         .formats     = SNDRV_PCM_FMTBIT_S32_LE,
235                         .rates       = SNDRV_PCM_RATE_48000,
236                         .channels_min = 2,
237                         .channels_max = 2,
238                 },
239                 .ops = &uniphier_aio_i2s_ld11_ops,
240         },
241         {
242                 .name    = AUD_NAME_HPCMOUT1,
243                 .playback = {
244                         .stream_name = AUD_NAME_HPCMOUT1,
245                         .formats     = SNDRV_PCM_FMTBIT_S32_LE,
246                         .rates       = SNDRV_PCM_RATE_48000,
247                         .channels_min = 2,
248                         .channels_max = 8,
249                 },
250                 .ops = &uniphier_aio_i2s_ld11_ops,
251         },
252         {
253                 .name    = AUD_NAME_PCMOUT3,
254                 .playback = {
255                         .stream_name = AUD_NAME_PCMOUT3,
256                         .formats     = SNDRV_PCM_FMTBIT_S32_LE,
257                         .rates       = SNDRV_PCM_RATE_48000,
258                         .channels_min = 2,
259                         .channels_max = 2,
260                 },
261                 .ops = &uniphier_aio_i2s_ld11_ops,
262         },
263         {
264                 .name    = AUD_NAME_HIECOUT1,
265                 .playback = {
266                         .stream_name = AUD_NAME_HIECOUT1,
267                         .formats     = SNDRV_PCM_FMTBIT_S32_LE,
268                         .rates       = SNDRV_PCM_RATE_48000,
269                         .channels_min = 2,
270                         .channels_max = 2,
271                 },
272                 .ops = &uniphier_aio_spdif_ld11_ops,
273         },
274         {
275                 .name    = AUD_NAME_EPCMOUT2,
276                 .playback = {
277                         .stream_name = AUD_NAME_EPCMOUT2,
278                         .formats     = SNDRV_PCM_FMTBIT_S32_LE,
279                         .rates       = SNDRV_PCM_RATE_48000 |
280                                 SNDRV_PCM_RATE_44100 |
281                                 SNDRV_PCM_RATE_32000,
282                         .channels_min = 2,
283                         .channels_max = 2,
284                 },
285                 .ops = &uniphier_aio_i2s_ld11_ops,
286         },
287         {
288                 .name    = AUD_NAME_EPCMOUT3,
289                 .playback = {
290                         .stream_name = AUD_NAME_EPCMOUT3,
291                         .formats     = SNDRV_PCM_FMTBIT_S32_LE,
292                         .rates       = SNDRV_PCM_RATE_48000 |
293                                 SNDRV_PCM_RATE_44100 |
294                                 SNDRV_PCM_RATE_32000,
295                         .channels_min = 2,
296                         .channels_max = 2,
297                 },
298                 .ops = &uniphier_aio_i2s_ld11_ops,
299         },
300         {
301                 .name    = AUD_NAME_HIECCOMPOUT1,
302                 .playback = {
303                         .stream_name = AUD_NAME_HIECCOMPOUT1,
304                         .channels_min = 1,
305                         .channels_max = 1,
306                 },
307                 .ops = &uniphier_aio_spdif_ld11_ops2,
308         },
309 };
310
311 static const struct uniphier_aio_chip_spec uniphier_aio_ld11_spec = {
312         .specs     = uniphier_aio_ld11,
313         .num_specs = ARRAY_SIZE(uniphier_aio_ld11),
314         .dais      = uniphier_aio_dai_ld11,
315         .num_dais  = ARRAY_SIZE(uniphier_aio_dai_ld11),
316         .plls      = uniphier_aio_pll_ld11,
317         .num_plls  = ARRAY_SIZE(uniphier_aio_pll_ld11),
318         .addr_ext  = 0,
319 };
320
321 static const struct uniphier_aio_chip_spec uniphier_aio_ld20_spec = {
322         .specs     = uniphier_aio_ld11,
323         .num_specs = ARRAY_SIZE(uniphier_aio_ld11),
324         .dais      = uniphier_aio_dai_ld11,
325         .num_dais  = ARRAY_SIZE(uniphier_aio_dai_ld11),
326         .plls      = uniphier_aio_pll_ld11,
327         .num_plls  = ARRAY_SIZE(uniphier_aio_pll_ld11),
328         .addr_ext  = 1,
329 };
330
331 static const struct of_device_id uniphier_aio_of_match[] __maybe_unused = {
332         {
333                 .compatible = "socionext,uniphier-ld11-aio",
334                 .data = &uniphier_aio_ld11_spec,
335         },
336         {
337                 .compatible = "socionext,uniphier-ld20-aio",
338                 .data = &uniphier_aio_ld20_spec,
339         },
340         {},
341 };
342 MODULE_DEVICE_TABLE(of, uniphier_aio_of_match);
343
344 static struct platform_driver uniphier_aio_driver = {
345         .driver = {
346                 .name = "snd-uniphier-aio-ld11",
347                 .of_match_table = of_match_ptr(uniphier_aio_of_match),
348         },
349         .probe    = uniphier_aio_probe,
350         .remove_new = uniphier_aio_remove,
351 };
352 module_platform_driver(uniphier_aio_driver);
353
354 MODULE_AUTHOR("Katsuhiro Suzuki <suzuki.katsuhiro@socionext.com>");
355 MODULE_DESCRIPTION("UniPhier LD11/LD20 AIO driver.");
356 MODULE_LICENSE("GPL v2");