1 // SPDX-License-Identifier: GPL-2.0
3 // Socionext UniPhier AIO ALSA driver for PXs2.
5 // Copyright (c) 2018 Socionext Inc.
7 #include <linux/module.h>
11 static const struct uniphier_aio_spec uniphier_aio_pxs2
[] = {
12 /* for Line PCM In, Pin:AI1Dx */
14 .name
= AUD_NAME_PCMIN1
,
15 .gname
= AUD_GNAME_LINE
,
17 .type
= PORT_TYPE_I2S
,
18 .dir
= PORT_DIR_INPUT
,
22 .iport
= { 0, AUD_HW_PCMIN1
, },
26 /* for Speaker/Headphone/Mic PCM In, Pin:AI2Dx */
28 .name
= AUD_NAME_PCMIN2
,
29 .gname
= AUD_GNAME_AUX
,
31 .type
= PORT_TYPE_I2S
,
32 .dir
= PORT_DIR_INPUT
,
36 .iport
= { 1, AUD_HW_PCMIN2
, },
40 /* for HDMI PCM Out, Pin:AO1Dx (inner) */
42 .name
= AUD_NAME_HPCMOUT1
,
43 .gname
= AUD_GNAME_HDMI
,
45 .type
= PORT_TYPE_I2S
,
46 .dir
= PORT_DIR_OUTPUT
,
50 .oport
= { 3, AUD_HW_HPCMOUT1
, },
54 /* for Line PCM Out, Pin:AO2Dx */
56 .name
= AUD_NAME_PCMOUT1
,
57 .gname
= AUD_GNAME_LINE
,
59 .type
= PORT_TYPE_I2S
,
60 .dir
= PORT_DIR_OUTPUT
,
64 .oport
= { 0, AUD_HW_PCMOUT1
, },
68 /* for Speaker/Headphone/Mic PCM Out, Pin:AO3Dx */
70 .name
= AUD_NAME_PCMOUT2
,
71 .gname
= AUD_GNAME_AUX
,
73 .type
= PORT_TYPE_I2S
,
74 .dir
= PORT_DIR_OUTPUT
,
78 .oport
= { 1, AUD_HW_PCMOUT2
, },
82 /* for HDMI Out, Pin:AO1IEC */
84 .name
= AUD_NAME_HIECOUT1
,
86 .type
= PORT_TYPE_SPDIF
,
87 .dir
= PORT_DIR_OUTPUT
,
91 .oport
= { 12, AUD_HW_HIECOUT1
, },
95 /* for HDMI Out, Pin:AO1IEC, Compress */
97 .name
= AUD_NAME_HIECCOMPOUT1
,
99 .type
= PORT_TYPE_SPDIF
,
100 .dir
= PORT_DIR_OUTPUT
,
104 .oport
= { 12, AUD_HW_HIECOUT1
, },
108 /* for S/PDIF Out, Pin:AO2IEC */
110 .name
= AUD_NAME_IECOUT1
,
112 .type
= PORT_TYPE_SPDIF
,
113 .dir
= PORT_DIR_OUTPUT
,
117 .oport
= { 13, AUD_HW_IECOUT1
, },
121 /* for S/PDIF Out, Pin:AO2IEC */
123 .name
= AUD_NAME_IECCOMPOUT1
,
125 .type
= PORT_TYPE_SPDIF
,
126 .dir
= PORT_DIR_OUTPUT
,
130 .oport
= { 13, AUD_HW_IECOUT1
, },
135 static const struct uniphier_aio_pll uniphier_aio_pll_pxs2
[] = {
136 [AUD_PLL_A1
] = { .enable
= true, },
137 [AUD_PLL_F1
] = { .enable
= true, },
138 [AUD_PLL_A2
] = { .enable
= true, },
139 [AUD_PLL_F2
] = { .enable
= true, },
140 [AUD_PLL_APLL
] = { .enable
= true, },
141 [AUD_PLL_HSC0
] = { .enable
= true, },
144 static int uniphier_aio_pxs2_probe(struct snd_soc_dai
*dai
)
148 ret
= uniphier_aio_dai_probe(dai
);
152 ret
= snd_soc_dai_set_pll(dai
, AUD_PLL_A1
, 0, 0, 36864000);
155 ret
= snd_soc_dai_set_pll(dai
, AUD_PLL_F1
, 0, 0, 36864000);
159 ret
= snd_soc_dai_set_pll(dai
, AUD_PLL_A2
, 0, 0, 33868800);
162 ret
= snd_soc_dai_set_pll(dai
, AUD_PLL_F2
, 0, 0, 33868800);
169 static struct snd_soc_dai_driver uniphier_aio_dai_pxs2
[] = {
171 .name
= AUD_GNAME_HDMI
,
172 .probe
= uniphier_aio_pxs2_probe
,
173 .remove
= uniphier_aio_dai_remove
,
174 .suspend
= uniphier_aio_dai_suspend
,
175 .resume
= uniphier_aio_dai_resume
,
177 .stream_name
= AUD_NAME_HPCMOUT1
,
178 .formats
= SNDRV_PCM_FMTBIT_S32_LE
,
179 .rates
= SNDRV_PCM_RATE_48000
,
183 .ops
= &uniphier_aio_i2s_ops
,
186 .name
= AUD_GNAME_LINE
,
187 .probe
= uniphier_aio_pxs2_probe
,
188 .remove
= uniphier_aio_dai_remove
,
189 .suspend
= uniphier_aio_dai_suspend
,
190 .resume
= uniphier_aio_dai_resume
,
192 .stream_name
= AUD_NAME_PCMOUT1
,
193 .formats
= SNDRV_PCM_FMTBIT_S32_LE
,
194 .rates
= SNDRV_PCM_RATE_48000
,
199 .stream_name
= AUD_NAME_PCMIN1
,
200 .formats
= SNDRV_PCM_FMTBIT_S32_LE
,
201 .rates
= SNDRV_PCM_RATE_48000
,
205 .ops
= &uniphier_aio_i2s_ops
,
208 .name
= AUD_GNAME_AUX
,
209 .probe
= uniphier_aio_pxs2_probe
,
210 .remove
= uniphier_aio_dai_remove
,
211 .suspend
= uniphier_aio_dai_suspend
,
212 .resume
= uniphier_aio_dai_resume
,
214 .stream_name
= AUD_NAME_PCMOUT2
,
215 .formats
= SNDRV_PCM_FMTBIT_S32_LE
,
216 .rates
= SNDRV_PCM_RATE_48000
,
221 .stream_name
= AUD_NAME_PCMIN2
,
222 .formats
= SNDRV_PCM_FMTBIT_S32_LE
,
223 .rates
= SNDRV_PCM_RATE_48000
,
227 .ops
= &uniphier_aio_i2s_ops
,
230 .name
= AUD_NAME_HIECOUT1
,
231 .probe
= uniphier_aio_pxs2_probe
,
232 .remove
= uniphier_aio_dai_remove
,
233 .suspend
= uniphier_aio_dai_suspend
,
234 .resume
= uniphier_aio_dai_resume
,
236 .stream_name
= AUD_NAME_HIECOUT1
,
237 .formats
= SNDRV_PCM_FMTBIT_S32_LE
,
238 .rates
= SNDRV_PCM_RATE_48000
,
242 .ops
= &uniphier_aio_spdif_ops
,
245 .name
= AUD_NAME_IECOUT1
,
246 .probe
= uniphier_aio_pxs2_probe
,
247 .remove
= uniphier_aio_dai_remove
,
248 .suspend
= uniphier_aio_dai_suspend
,
249 .resume
= uniphier_aio_dai_resume
,
251 .stream_name
= AUD_NAME_IECOUT1
,
252 .formats
= SNDRV_PCM_FMTBIT_S32_LE
,
253 .rates
= SNDRV_PCM_RATE_48000
,
257 .ops
= &uniphier_aio_spdif_ops
,
260 .name
= AUD_NAME_HIECCOMPOUT1
,
261 .probe
= uniphier_aio_pxs2_probe
,
262 .remove
= uniphier_aio_dai_remove
,
263 .suspend
= uniphier_aio_dai_suspend
,
264 .resume
= uniphier_aio_dai_resume
,
265 .compress_new
= snd_soc_new_compress
,
267 .stream_name
= AUD_NAME_HIECCOMPOUT1
,
271 .ops
= &uniphier_aio_spdif_ops
,
274 .name
= AUD_NAME_IECCOMPOUT1
,
275 .probe
= uniphier_aio_pxs2_probe
,
276 .remove
= uniphier_aio_dai_remove
,
277 .suspend
= uniphier_aio_dai_suspend
,
278 .resume
= uniphier_aio_dai_resume
,
279 .compress_new
= snd_soc_new_compress
,
281 .stream_name
= AUD_NAME_IECCOMPOUT1
,
285 .ops
= &uniphier_aio_spdif_ops
,
289 static const struct uniphier_aio_chip_spec uniphier_aio_pxs2_spec
= {
290 .specs
= uniphier_aio_pxs2
,
291 .num_specs
= ARRAY_SIZE(uniphier_aio_pxs2
),
292 .dais
= uniphier_aio_dai_pxs2
,
293 .num_dais
= ARRAY_SIZE(uniphier_aio_dai_pxs2
),
294 .plls
= uniphier_aio_pll_pxs2
,
295 .num_plls
= ARRAY_SIZE(uniphier_aio_pll_pxs2
),
299 static const struct of_device_id uniphier_aio_of_match
[] = {
301 .compatible
= "socionext,uniphier-pxs2-aio",
302 .data
= &uniphier_aio_pxs2_spec
,
306 MODULE_DEVICE_TABLE(of
, uniphier_aio_of_match
);
308 static struct platform_driver uniphier_aio_driver
= {
310 .name
= "snd-uniphier-aio-pxs2",
311 .of_match_table
= of_match_ptr(uniphier_aio_of_match
),
313 .probe
= uniphier_aio_probe
,
314 .remove
= uniphier_aio_remove
,
316 module_platform_driver(uniphier_aio_driver
);
318 MODULE_AUTHOR("Katsuhiro Suzuki <suzuki.katsuhiro@socionext.com>");
319 MODULE_DESCRIPTION("UniPhier PXs2 AIO driver.");
320 MODULE_LICENSE("GPL v2");