0001
0002
0003
0004
0005
0006
0007 #include <linux/module.h>
0008
0009 #include "aio.h"
0010
0011 static const struct uniphier_aio_spec uniphier_aio_ld11[] = {
0012
0013 {
0014 .name = AUD_NAME_PCMIN1,
0015 .gname = AUD_GNAME_HDMI,
0016 .swm = {
0017 .type = PORT_TYPE_I2S,
0018 .dir = PORT_DIR_INPUT,
0019 .rb = { 21, 14, },
0020 .ch = { 21, 14, },
0021 .iif = { 5, 3, },
0022 .iport = { 0, AUD_HW_PCMIN1, },
0023 },
0024 },
0025
0026
0027 {
0028 .name = AUD_NAME_PCMIN2,
0029 .swm = {
0030 .type = PORT_TYPE_I2S,
0031 .dir = PORT_DIR_INPUT,
0032 .rb = { 22, 15, },
0033 .ch = { 22, 15, },
0034 .iif = { 6, 4, },
0035 .iport = { 1, AUD_HW_PCMIN2, },
0036 },
0037 },
0038
0039
0040 {
0041 .name = AUD_NAME_PCMIN3,
0042 .gname = AUD_GNAME_LINE,
0043 .swm = {
0044 .type = PORT_TYPE_EVE,
0045 .dir = PORT_DIR_INPUT,
0046 .rb = { 23, 16, },
0047 .ch = { 23, 16, },
0048 .iif = { 7, 5, },
0049 .iport = { 2, AUD_HW_PCMIN3, },
0050 },
0051 },
0052
0053
0054 {
0055 .name = AUD_NAME_IECIN1,
0056 .gname = AUD_GNAME_IEC,
0057 .swm = {
0058 .type = PORT_TYPE_SPDIF,
0059 .dir = PORT_DIR_INPUT,
0060 .rb = { 26, 17, },
0061 .ch = { 26, 17, },
0062 .iif = { 10, 6, },
0063 .iport = { 3, AUD_HW_IECIN1, },
0064 },
0065 },
0066
0067
0068 {
0069 .name = AUD_NAME_HPCMOUT1,
0070 .swm = {
0071 .type = PORT_TYPE_I2S,
0072 .dir = PORT_DIR_OUTPUT,
0073 .rb = { 0, 0, },
0074 .ch = { 0, 0, },
0075 .oif = { 0, 0, },
0076 .oport = { 0, AUD_HW_HPCMOUT1, },
0077 },
0078 },
0079
0080
0081 {
0082 .name = AUD_NAME_PCMOUT1,
0083 .gname = AUD_GNAME_HDMI,
0084 .swm = {
0085 .type = PORT_TYPE_I2S,
0086 .dir = PORT_DIR_OUTPUT,
0087 .rb = { 0, 0, },
0088 .ch = { 0, 0, },
0089 .oif = { 0, 0, },
0090 .oport = { 3, AUD_HW_PCMOUT1, },
0091 },
0092 },
0093
0094
0095 {
0096 .name = AUD_NAME_PCMOUT2,
0097 .gname = AUD_GNAME_LINE,
0098 .swm = {
0099 .type = PORT_TYPE_EVE,
0100 .dir = PORT_DIR_OUTPUT,
0101 .rb = { 2, 2, },
0102 .ch = { 2, 2, },
0103 .oif = { 2, 2, },
0104 .oport = { 1, AUD_HW_PCMOUT2, },
0105 },
0106 },
0107
0108
0109 {
0110 .name = AUD_NAME_PCMOUT3,
0111 .swm = {
0112 .type = PORT_TYPE_EVE,
0113 .dir = PORT_DIR_OUTPUT,
0114 .rb = { 3, 3, },
0115 .ch = { 3, 3, },
0116 .oif = { 3, 3, },
0117 .oport = { 2, AUD_HW_PCMOUT3, },
0118 },
0119 },
0120
0121
0122 {
0123 .name = AUD_NAME_EPCMOUT2,
0124 .swm = {
0125 .type = PORT_TYPE_CONV,
0126 .dir = PORT_DIR_OUTPUT,
0127 .rb = { 7, 5, },
0128 .ch = { 7, 5, },
0129 .oif = { 7, 5, },
0130 .oport = { 6, AUD_HW_EPCMOUT2, },
0131 .och = { 17, 12, },
0132 .iif = { 1, 1, },
0133 },
0134 },
0135
0136
0137 {
0138 .name = AUD_NAME_EPCMOUT3,
0139 .swm = {
0140 .type = PORT_TYPE_CONV,
0141 .dir = PORT_DIR_OUTPUT,
0142 .rb = { 8, 6, },
0143 .ch = { 8, 6, },
0144 .oif = { 8, 6, },
0145 .oport = { 7, AUD_HW_EPCMOUT3, },
0146 .och = { 18, 13, },
0147 .iif = { 2, 2, },
0148 },
0149 },
0150
0151
0152 {
0153 .name = AUD_NAME_HIECOUT1,
0154 .gname = AUD_GNAME_IEC,
0155 .swm = {
0156 .type = PORT_TYPE_SPDIF,
0157 .dir = PORT_DIR_OUTPUT,
0158 .rb = { 1, 1, },
0159 .ch = { 1, 1, },
0160 .oif = { 1, 1, },
0161 .oport = { 12, AUD_HW_HIECOUT1, },
0162 },
0163 },
0164
0165
0166 {
0167 .name = AUD_NAME_HIECCOMPOUT1,
0168 .gname = AUD_GNAME_IEC,
0169 .swm = {
0170 .type = PORT_TYPE_SPDIF,
0171 .dir = PORT_DIR_OUTPUT,
0172 .rb = { 1, 1, },
0173 .ch = { 1, 1, },
0174 .oif = { 1, 1, },
0175 .oport = { 12, AUD_HW_HIECOUT1, },
0176 },
0177 },
0178 };
0179
0180 static const struct uniphier_aio_pll uniphier_aio_pll_ld11[] = {
0181 [AUD_PLL_A1] = { .enable = true, },
0182 [AUD_PLL_F1] = { .enable = true, },
0183 [AUD_PLL_A2] = { .enable = true, },
0184 [AUD_PLL_F2] = { .enable = true, },
0185 [AUD_PLL_APLL] = { .enable = true, },
0186 [AUD_PLL_RX0] = { .enable = true, },
0187 [AUD_PLL_USB0] = { .enable = true, },
0188 [AUD_PLL_HSC0] = { .enable = true, },
0189 };
0190
0191 static int uniphier_aio_ld11_probe(struct snd_soc_dai *dai)
0192 {
0193 int ret;
0194
0195 ret = uniphier_aio_dai_probe(dai);
0196 if (ret < 0)
0197 return ret;
0198
0199 ret = snd_soc_dai_set_pll(dai, AUD_PLL_A1, 0, 0, 36864000);
0200 if (ret < 0)
0201 return ret;
0202 ret = snd_soc_dai_set_pll(dai, AUD_PLL_F1, 0, 0, 36864000);
0203 if (ret < 0)
0204 return ret;
0205
0206 ret = snd_soc_dai_set_pll(dai, AUD_PLL_A2, 0, 0, 33868800);
0207 if (ret < 0)
0208 return ret;
0209 ret = snd_soc_dai_set_pll(dai, AUD_PLL_F2, 0, 0, 33868800);
0210 if (ret < 0)
0211 return ret;
0212
0213 return 0;
0214 }
0215
0216 static struct snd_soc_dai_driver uniphier_aio_dai_ld11[] = {
0217 {
0218 .name = AUD_GNAME_HDMI,
0219 .probe = uniphier_aio_ld11_probe,
0220 .remove = uniphier_aio_dai_remove,
0221 .playback = {
0222 .stream_name = AUD_NAME_PCMOUT1,
0223 .formats = SNDRV_PCM_FMTBIT_S32_LE,
0224 .rates = SNDRV_PCM_RATE_48000,
0225 .channels_min = 2,
0226 .channels_max = 2,
0227 },
0228 .capture = {
0229 .stream_name = AUD_NAME_PCMIN1,
0230 .formats = SNDRV_PCM_FMTBIT_S32_LE,
0231 .rates = SNDRV_PCM_RATE_48000 |
0232 SNDRV_PCM_RATE_44100 |
0233 SNDRV_PCM_RATE_32000,
0234 .channels_min = 2,
0235 .channels_max = 2,
0236 },
0237 .ops = &uniphier_aio_i2s_ops,
0238 },
0239 {
0240 .name = AUD_NAME_PCMIN2,
0241 .probe = uniphier_aio_ld11_probe,
0242 .remove = uniphier_aio_dai_remove,
0243 .capture = {
0244 .stream_name = AUD_NAME_PCMIN2,
0245 .formats = SNDRV_PCM_FMTBIT_S32_LE,
0246 .rates = SNDRV_PCM_RATE_48000,
0247 .channels_min = 2,
0248 .channels_max = 2,
0249 },
0250 .ops = &uniphier_aio_i2s_ops,
0251 },
0252 {
0253 .name = AUD_GNAME_LINE,
0254 .probe = uniphier_aio_ld11_probe,
0255 .remove = uniphier_aio_dai_remove,
0256 .playback = {
0257 .stream_name = AUD_NAME_PCMOUT2,
0258 .formats = SNDRV_PCM_FMTBIT_S32_LE,
0259 .rates = SNDRV_PCM_RATE_48000,
0260 .channels_min = 2,
0261 .channels_max = 2,
0262 },
0263 .capture = {
0264 .stream_name = AUD_NAME_PCMIN3,
0265 .formats = SNDRV_PCM_FMTBIT_S32_LE,
0266 .rates = SNDRV_PCM_RATE_48000,
0267 .channels_min = 2,
0268 .channels_max = 2,
0269 },
0270 .ops = &uniphier_aio_i2s_ops,
0271 },
0272 {
0273 .name = AUD_NAME_HPCMOUT1,
0274 .probe = uniphier_aio_ld11_probe,
0275 .remove = uniphier_aio_dai_remove,
0276 .playback = {
0277 .stream_name = AUD_NAME_HPCMOUT1,
0278 .formats = SNDRV_PCM_FMTBIT_S32_LE,
0279 .rates = SNDRV_PCM_RATE_48000,
0280 .channels_min = 2,
0281 .channels_max = 8,
0282 },
0283 .ops = &uniphier_aio_i2s_ops,
0284 },
0285 {
0286 .name = AUD_NAME_PCMOUT3,
0287 .probe = uniphier_aio_ld11_probe,
0288 .remove = uniphier_aio_dai_remove,
0289 .playback = {
0290 .stream_name = AUD_NAME_PCMOUT3,
0291 .formats = SNDRV_PCM_FMTBIT_S32_LE,
0292 .rates = SNDRV_PCM_RATE_48000,
0293 .channels_min = 2,
0294 .channels_max = 2,
0295 },
0296 .ops = &uniphier_aio_i2s_ops,
0297 },
0298 {
0299 .name = AUD_NAME_HIECOUT1,
0300 .probe = uniphier_aio_ld11_probe,
0301 .remove = uniphier_aio_dai_remove,
0302 .playback = {
0303 .stream_name = AUD_NAME_HIECOUT1,
0304 .formats = SNDRV_PCM_FMTBIT_S32_LE,
0305 .rates = SNDRV_PCM_RATE_48000,
0306 .channels_min = 2,
0307 .channels_max = 2,
0308 },
0309 .ops = &uniphier_aio_spdif_ops,
0310 },
0311 {
0312 .name = AUD_NAME_EPCMOUT2,
0313 .probe = uniphier_aio_ld11_probe,
0314 .remove = uniphier_aio_dai_remove,
0315 .playback = {
0316 .stream_name = AUD_NAME_EPCMOUT2,
0317 .formats = SNDRV_PCM_FMTBIT_S32_LE,
0318 .rates = SNDRV_PCM_RATE_48000 |
0319 SNDRV_PCM_RATE_44100 |
0320 SNDRV_PCM_RATE_32000,
0321 .channels_min = 2,
0322 .channels_max = 2,
0323 },
0324 .ops = &uniphier_aio_i2s_ops,
0325 },
0326 {
0327 .name = AUD_NAME_EPCMOUT3,
0328 .probe = uniphier_aio_ld11_probe,
0329 .remove = uniphier_aio_dai_remove,
0330 .playback = {
0331 .stream_name = AUD_NAME_EPCMOUT3,
0332 .formats = SNDRV_PCM_FMTBIT_S32_LE,
0333 .rates = SNDRV_PCM_RATE_48000 |
0334 SNDRV_PCM_RATE_44100 |
0335 SNDRV_PCM_RATE_32000,
0336 .channels_min = 2,
0337 .channels_max = 2,
0338 },
0339 .ops = &uniphier_aio_i2s_ops,
0340 },
0341 {
0342 .name = AUD_NAME_HIECCOMPOUT1,
0343 .probe = uniphier_aio_ld11_probe,
0344 .remove = uniphier_aio_dai_remove,
0345 .compress_new = snd_soc_new_compress,
0346 .playback = {
0347 .stream_name = AUD_NAME_HIECCOMPOUT1,
0348 .channels_min = 1,
0349 .channels_max = 1,
0350 },
0351 .ops = &uniphier_aio_spdif_ops,
0352 },
0353 };
0354
0355 static const struct uniphier_aio_chip_spec uniphier_aio_ld11_spec = {
0356 .specs = uniphier_aio_ld11,
0357 .num_specs = ARRAY_SIZE(uniphier_aio_ld11),
0358 .dais = uniphier_aio_dai_ld11,
0359 .num_dais = ARRAY_SIZE(uniphier_aio_dai_ld11),
0360 .plls = uniphier_aio_pll_ld11,
0361 .num_plls = ARRAY_SIZE(uniphier_aio_pll_ld11),
0362 .addr_ext = 0,
0363 };
0364
0365 static const struct uniphier_aio_chip_spec uniphier_aio_ld20_spec = {
0366 .specs = uniphier_aio_ld11,
0367 .num_specs = ARRAY_SIZE(uniphier_aio_ld11),
0368 .dais = uniphier_aio_dai_ld11,
0369 .num_dais = ARRAY_SIZE(uniphier_aio_dai_ld11),
0370 .plls = uniphier_aio_pll_ld11,
0371 .num_plls = ARRAY_SIZE(uniphier_aio_pll_ld11),
0372 .addr_ext = 1,
0373 };
0374
0375 static const struct of_device_id uniphier_aio_of_match[] __maybe_unused = {
0376 {
0377 .compatible = "socionext,uniphier-ld11-aio",
0378 .data = &uniphier_aio_ld11_spec,
0379 },
0380 {
0381 .compatible = "socionext,uniphier-ld20-aio",
0382 .data = &uniphier_aio_ld20_spec,
0383 },
0384 {},
0385 };
0386 MODULE_DEVICE_TABLE(of, uniphier_aio_of_match);
0387
0388 static struct platform_driver uniphier_aio_driver = {
0389 .driver = {
0390 .name = "snd-uniphier-aio-ld11",
0391 .of_match_table = of_match_ptr(uniphier_aio_of_match),
0392 },
0393 .probe = uniphier_aio_probe,
0394 .remove = uniphier_aio_remove,
0395 };
0396 module_platform_driver(uniphier_aio_driver);
0397
0398 MODULE_AUTHOR("Katsuhiro Suzuki <suzuki.katsuhiro@socionext.com>");
0399 MODULE_DESCRIPTION("UniPhier LD11/LD20 AIO driver.");
0400 MODULE_LICENSE("GPL v2");