Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0
0002 //
0003 // Socionext UniPhier AIO ALSA driver for PXs2.
0004 //
0005 // Copyright (c) 2018 Socionext Inc.
0006 
0007 #include <linux/module.h>
0008 
0009 #include "aio.h"
0010 
0011 static const struct uniphier_aio_spec uniphier_aio_pxs2[] = {
0012     /* for Line PCM In, Pin:AI1Dx */
0013     {
0014         .name = AUD_NAME_PCMIN1,
0015         .gname = AUD_GNAME_LINE,
0016         .swm = {
0017             .type  = PORT_TYPE_I2S,
0018             .dir   = PORT_DIR_INPUT,
0019             .rb    = { 16, 11, },
0020             .ch    = { 16, 11, },
0021             .iif   = { 0, 0, },
0022             .iport = { 0, AUD_HW_PCMIN1, },
0023         },
0024     },
0025 
0026     /* for Speaker/Headphone/Mic PCM In, Pin:AI2Dx */
0027     {
0028         .name = AUD_NAME_PCMIN2,
0029         .gname = AUD_GNAME_AUX,
0030         .swm = {
0031             .type  = PORT_TYPE_I2S,
0032             .dir   = PORT_DIR_INPUT,
0033             .rb    = { 17, 12, },
0034             .ch    = { 17, 12, },
0035             .iif   = { 1, 1, },
0036             .iport = { 1, AUD_HW_PCMIN2, },
0037         },
0038     },
0039 
0040     /* for HDMI PCM Out, Pin:AO1Dx (inner) */
0041     {
0042         .name = AUD_NAME_HPCMOUT1,
0043         .gname = AUD_GNAME_HDMI,
0044         .swm = {
0045             .type  = PORT_TYPE_I2S,
0046             .dir   = PORT_DIR_OUTPUT,
0047             .rb    = { 0, 0, },
0048             .ch    = { 0, 0, },
0049             .oif   = { 0, 0, },
0050             .oport = { 3, AUD_HW_HPCMOUT1, },
0051         },
0052     },
0053 
0054     /* for Line PCM Out, Pin:AO2Dx */
0055     {
0056         .name = AUD_NAME_PCMOUT1,
0057         .gname = AUD_GNAME_LINE,
0058         .swm = {
0059             .type  = PORT_TYPE_I2S,
0060             .dir   = PORT_DIR_OUTPUT,
0061             .rb    = { 1, 1, },
0062             .ch    = { 1, 1, },
0063             .oif   = { 1, 1, },
0064             .oport = { 0, AUD_HW_PCMOUT1, },
0065         },
0066     },
0067 
0068     /* for Speaker/Headphone/Mic PCM Out, Pin:AO3Dx */
0069     {
0070         .name = AUD_NAME_PCMOUT2,
0071         .gname = AUD_GNAME_AUX,
0072         .swm = {
0073             .type  = PORT_TYPE_I2S,
0074             .dir   = PORT_DIR_OUTPUT,
0075             .rb    = { 2, 2, },
0076             .ch    = { 2, 2, },
0077             .oif   = { 2, 2, },
0078             .oport = { 1, AUD_HW_PCMOUT2, },
0079         },
0080     },
0081 
0082     /* for HDMI Out, Pin:AO1IEC */
0083     {
0084         .name = AUD_NAME_HIECOUT1,
0085         .swm = {
0086             .type  = PORT_TYPE_SPDIF,
0087             .dir   = PORT_DIR_OUTPUT,
0088             .rb    = { 6, 4, },
0089             .ch    = { 6, 4, },
0090             .oif   = { 6, 4, },
0091             .oport = { 12, AUD_HW_HIECOUT1, },
0092         },
0093     },
0094 
0095     /* for HDMI Out, Pin:AO1IEC, Compress */
0096     {
0097         .name = AUD_NAME_HIECCOMPOUT1,
0098         .swm = {
0099             .type  = PORT_TYPE_SPDIF,
0100             .dir   = PORT_DIR_OUTPUT,
0101             .rb    = { 6, 4, },
0102             .ch    = { 6, 4, },
0103             .oif   = { 6, 4, },
0104             .oport = { 12, AUD_HW_HIECOUT1, },
0105         },
0106     },
0107 
0108     /* for S/PDIF Out, Pin:AO2IEC */
0109     {
0110         .name = AUD_NAME_IECOUT1,
0111         .swm = {
0112             .type  = PORT_TYPE_SPDIF,
0113             .dir   = PORT_DIR_OUTPUT,
0114             .rb    = { 7, 5, },
0115             .ch    = { 7, 5, },
0116             .oif   = { 7, 5, },
0117             .oport = { 13, AUD_HW_IECOUT1, },
0118         },
0119     },
0120 
0121     /* for S/PDIF Out, Pin:AO2IEC */
0122     {
0123         .name = AUD_NAME_IECCOMPOUT1,
0124         .swm = {
0125             .type  = PORT_TYPE_SPDIF,
0126             .dir   = PORT_DIR_OUTPUT,
0127             .rb    = { 7, 5, },
0128             .ch    = { 7, 5, },
0129             .oif   = { 7, 5, },
0130             .oport = { 13, AUD_HW_IECOUT1, },
0131         },
0132     },
0133 };
0134 
0135 static const struct uniphier_aio_pll uniphier_aio_pll_pxs2[] = {
0136     [AUD_PLL_A1]   = { .enable = true, },
0137     [AUD_PLL_F1]   = { .enable = true, },
0138     [AUD_PLL_A2]   = { .enable = true, },
0139     [AUD_PLL_F2]   = { .enable = true, },
0140     [AUD_PLL_APLL] = { .enable = true, },
0141     [AUD_PLL_HSC0] = { .enable = true, },
0142 };
0143 
0144 static int uniphier_aio_pxs2_probe(struct snd_soc_dai *dai)
0145 {
0146     int ret;
0147 
0148     ret = uniphier_aio_dai_probe(dai);
0149     if (ret < 0)
0150         return ret;
0151 
0152     ret = snd_soc_dai_set_pll(dai, AUD_PLL_A1, 0, 0, 36864000);
0153     if (ret < 0)
0154         return ret;
0155     ret = snd_soc_dai_set_pll(dai, AUD_PLL_F1, 0, 0, 36864000);
0156     if (ret < 0)
0157         return ret;
0158 
0159     ret = snd_soc_dai_set_pll(dai, AUD_PLL_A2, 0, 0, 33868800);
0160     if (ret < 0)
0161         return ret;
0162     ret = snd_soc_dai_set_pll(dai, AUD_PLL_F2, 0, 0, 33868800);
0163     if (ret < 0)
0164         return ret;
0165 
0166     return 0;
0167 }
0168 
0169 static struct snd_soc_dai_driver uniphier_aio_dai_pxs2[] = {
0170     {
0171         .name    = AUD_GNAME_HDMI,
0172         .probe   = uniphier_aio_pxs2_probe,
0173         .remove  = uniphier_aio_dai_remove,
0174         .playback = {
0175             .stream_name = AUD_NAME_HPCMOUT1,
0176             .formats     = SNDRV_PCM_FMTBIT_S32_LE,
0177             .rates       = SNDRV_PCM_RATE_48000,
0178             .channels_min = 2,
0179             .channels_max = 2,
0180         },
0181         .ops = &uniphier_aio_i2s_ops,
0182     },
0183     {
0184         .name    = AUD_GNAME_LINE,
0185         .probe   = uniphier_aio_pxs2_probe,
0186         .remove  = uniphier_aio_dai_remove,
0187         .playback = {
0188             .stream_name = AUD_NAME_PCMOUT1,
0189             .formats     = SNDRV_PCM_FMTBIT_S32_LE,
0190             .rates       = SNDRV_PCM_RATE_48000,
0191             .channels_min = 2,
0192             .channels_max = 2,
0193         },
0194         .capture = {
0195             .stream_name = AUD_NAME_PCMIN1,
0196             .formats     = SNDRV_PCM_FMTBIT_S32_LE,
0197             .rates       = SNDRV_PCM_RATE_48000,
0198             .channels_min = 2,
0199             .channels_max = 2,
0200         },
0201         .ops = &uniphier_aio_i2s_ops,
0202     },
0203     {
0204         .name    = AUD_GNAME_AUX,
0205         .probe   = uniphier_aio_pxs2_probe,
0206         .remove  = uniphier_aio_dai_remove,
0207         .playback = {
0208             .stream_name = AUD_NAME_PCMOUT2,
0209             .formats     = SNDRV_PCM_FMTBIT_S32_LE,
0210             .rates       = SNDRV_PCM_RATE_48000,
0211             .channels_min = 2,
0212             .channels_max = 2,
0213         },
0214         .capture = {
0215             .stream_name = AUD_NAME_PCMIN2,
0216             .formats     = SNDRV_PCM_FMTBIT_S32_LE,
0217             .rates       = SNDRV_PCM_RATE_48000,
0218             .channels_min = 2,
0219             .channels_max = 2,
0220         },
0221         .ops = &uniphier_aio_i2s_ops,
0222     },
0223     {
0224         .name    = AUD_NAME_HIECOUT1,
0225         .probe   = uniphier_aio_pxs2_probe,
0226         .remove  = uniphier_aio_dai_remove,
0227         .playback = {
0228             .stream_name = AUD_NAME_HIECOUT1,
0229             .formats     = SNDRV_PCM_FMTBIT_S32_LE,
0230             .rates       = SNDRV_PCM_RATE_48000,
0231             .channels_min = 2,
0232             .channels_max = 2,
0233         },
0234         .ops = &uniphier_aio_spdif_ops,
0235     },
0236     {
0237         .name    = AUD_NAME_IECOUT1,
0238         .probe   = uniphier_aio_pxs2_probe,
0239         .remove  = uniphier_aio_dai_remove,
0240         .playback = {
0241             .stream_name = AUD_NAME_IECOUT1,
0242             .formats     = SNDRV_PCM_FMTBIT_S32_LE,
0243             .rates       = SNDRV_PCM_RATE_48000,
0244             .channels_min = 2,
0245             .channels_max = 2,
0246         },
0247         .ops = &uniphier_aio_spdif_ops,
0248     },
0249     {
0250         .name    = AUD_NAME_HIECCOMPOUT1,
0251         .probe   = uniphier_aio_pxs2_probe,
0252         .remove  = uniphier_aio_dai_remove,
0253         .compress_new = snd_soc_new_compress,
0254         .playback = {
0255             .stream_name = AUD_NAME_HIECCOMPOUT1,
0256             .channels_min = 1,
0257             .channels_max = 1,
0258         },
0259         .ops = &uniphier_aio_spdif_ops,
0260     },
0261     {
0262         .name    = AUD_NAME_IECCOMPOUT1,
0263         .probe   = uniphier_aio_pxs2_probe,
0264         .remove  = uniphier_aio_dai_remove,
0265         .compress_new = snd_soc_new_compress,
0266         .playback = {
0267             .stream_name = AUD_NAME_IECCOMPOUT1,
0268             .channels_min = 1,
0269             .channels_max = 1,
0270         },
0271         .ops = &uniphier_aio_spdif_ops,
0272     },
0273 };
0274 
0275 static const struct uniphier_aio_chip_spec uniphier_aio_pxs2_spec = {
0276     .specs     = uniphier_aio_pxs2,
0277     .num_specs = ARRAY_SIZE(uniphier_aio_pxs2),
0278     .dais      = uniphier_aio_dai_pxs2,
0279     .num_dais  = ARRAY_SIZE(uniphier_aio_dai_pxs2),
0280     .plls      = uniphier_aio_pll_pxs2,
0281     .num_plls  = ARRAY_SIZE(uniphier_aio_pll_pxs2),
0282     .addr_ext  = 0,
0283 };
0284 
0285 static const struct of_device_id uniphier_aio_of_match[] __maybe_unused = {
0286     {
0287         .compatible = "socionext,uniphier-pxs2-aio",
0288         .data = &uniphier_aio_pxs2_spec,
0289     },
0290     {},
0291 };
0292 MODULE_DEVICE_TABLE(of, uniphier_aio_of_match);
0293 
0294 static struct platform_driver uniphier_aio_driver = {
0295     .driver = {
0296         .name = "snd-uniphier-aio-pxs2",
0297         .of_match_table = of_match_ptr(uniphier_aio_of_match),
0298     },
0299     .probe    = uniphier_aio_probe,
0300     .remove   = uniphier_aio_remove,
0301 };
0302 module_platform_driver(uniphier_aio_driver);
0303 
0304 MODULE_AUTHOR("Katsuhiro Suzuki <suzuki.katsuhiro@socionext.com>");
0305 MODULE_DESCRIPTION("UniPhier PXs2 AIO driver.");
0306 MODULE_LICENSE("GPL v2");