357 lines · c
1// SPDX-License-Identifier: GPL-2.02//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 11static 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 180static 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 191static 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 311static 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 321static 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 331static 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};342MODULE_DEVICE_TABLE(of, uniphier_aio_of_match);343 344static 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 = uniphier_aio_remove,351};352module_platform_driver(uniphier_aio_driver);353 354MODULE_AUTHOR("Katsuhiro Suzuki <suzuki.katsuhiro@socionext.com>");355MODULE_DESCRIPTION("UniPhier LD11/LD20 AIO driver.");356MODULE_LICENSE("GPL v2");357