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
,
175 .stream_name
= AUD_NAME_HPCMOUT1
,
176 .formats
= SNDRV_PCM_FMTBIT_S32_LE
,
177 .rates
= SNDRV_PCM_RATE_48000
,
181 .ops
= &uniphier_aio_i2s_ops
,
184 .name
= AUD_GNAME_LINE
,
185 .probe
= uniphier_aio_pxs2_probe
,
186 .remove
= uniphier_aio_dai_remove
,
188 .stream_name
= AUD_NAME_PCMOUT1
,
189 .formats
= SNDRV_PCM_FMTBIT_S32_LE
,
190 .rates
= SNDRV_PCM_RATE_48000
,
195 .stream_name
= AUD_NAME_PCMIN1
,
196 .formats
= SNDRV_PCM_FMTBIT_S32_LE
,
197 .rates
= SNDRV_PCM_RATE_48000
,
201 .ops
= &uniphier_aio_i2s_ops
,
204 .name
= AUD_GNAME_AUX
,
205 .probe
= uniphier_aio_pxs2_probe
,
206 .remove
= uniphier_aio_dai_remove
,
208 .stream_name
= AUD_NAME_PCMOUT2
,
209 .formats
= SNDRV_PCM_FMTBIT_S32_LE
,
210 .rates
= SNDRV_PCM_RATE_48000
,
215 .stream_name
= AUD_NAME_PCMIN2
,
216 .formats
= SNDRV_PCM_FMTBIT_S32_LE
,
217 .rates
= SNDRV_PCM_RATE_48000
,
221 .ops
= &uniphier_aio_i2s_ops
,
224 .name
= AUD_NAME_HIECOUT1
,
225 .probe
= uniphier_aio_pxs2_probe
,
226 .remove
= uniphier_aio_dai_remove
,
228 .stream_name
= AUD_NAME_HIECOUT1
,
229 .formats
= SNDRV_PCM_FMTBIT_S32_LE
,
230 .rates
= SNDRV_PCM_RATE_48000
,
234 .ops
= &uniphier_aio_spdif_ops
,
237 .name
= AUD_NAME_IECOUT1
,
238 .probe
= uniphier_aio_pxs2_probe
,
239 .remove
= uniphier_aio_dai_remove
,
241 .stream_name
= AUD_NAME_IECOUT1
,
242 .formats
= SNDRV_PCM_FMTBIT_S32_LE
,
243 .rates
= SNDRV_PCM_RATE_48000
,
247 .ops
= &uniphier_aio_spdif_ops
,
250 .name
= AUD_NAME_HIECCOMPOUT1
,
251 .probe
= uniphier_aio_pxs2_probe
,
252 .remove
= uniphier_aio_dai_remove
,
253 .compress_new
= snd_soc_new_compress
,
255 .stream_name
= AUD_NAME_HIECCOMPOUT1
,
259 .ops
= &uniphier_aio_spdif_ops
,
262 .name
= AUD_NAME_IECCOMPOUT1
,
263 .probe
= uniphier_aio_pxs2_probe
,
264 .remove
= uniphier_aio_dai_remove
,
265 .compress_new
= snd_soc_new_compress
,
267 .stream_name
= AUD_NAME_IECCOMPOUT1
,
271 .ops
= &uniphier_aio_spdif_ops
,
275 static const struct uniphier_aio_chip_spec uniphier_aio_pxs2_spec
= {
276 .specs
= uniphier_aio_pxs2
,
277 .num_specs
= ARRAY_SIZE(uniphier_aio_pxs2
),
278 .dais
= uniphier_aio_dai_pxs2
,
279 .num_dais
= ARRAY_SIZE(uniphier_aio_dai_pxs2
),
280 .plls
= uniphier_aio_pll_pxs2
,
281 .num_plls
= ARRAY_SIZE(uniphier_aio_pll_pxs2
),
285 static const struct of_device_id uniphier_aio_of_match
[] __maybe_unused
= {
287 .compatible
= "socionext,uniphier-pxs2-aio",
288 .data
= &uniphier_aio_pxs2_spec
,
292 MODULE_DEVICE_TABLE(of
, uniphier_aio_of_match
);
294 static struct platform_driver uniphier_aio_driver
= {
296 .name
= "snd-uniphier-aio-pxs2",
297 .of_match_table
= of_match_ptr(uniphier_aio_of_match
),
299 .probe
= uniphier_aio_probe
,
300 .remove
= uniphier_aio_remove
,
302 module_platform_driver(uniphier_aio_driver
);
304 MODULE_AUTHOR("Katsuhiro Suzuki <suzuki.katsuhiro@socionext.com>");
305 MODULE_DESCRIPTION("UniPhier PXs2 AIO driver.");
306 MODULE_LICENSE("GPL v2");