linux/sound/soc/uniphier/aio-pxs2.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0
   2//
   3// Socionext UniPhier AIO ALSA driver for PXs2.
   4//
   5// Copyright (c) 2018 Socionext Inc.
   6
   7#include <linux/module.h>
   8
   9#include "aio.h"
  10
  11static const struct uniphier_aio_spec uniphier_aio_pxs2[] = {
  12        /* for Line PCM In, Pin:AI1Dx */
  13        {
  14                .name = AUD_NAME_PCMIN1,
  15                .gname = AUD_GNAME_LINE,
  16                .swm = {
  17                        .type  = PORT_TYPE_I2S,
  18                        .dir   = PORT_DIR_INPUT,
  19                        .rb    = { 16, 11, },
  20                        .ch    = { 16, 11, },
  21                        .iif   = { 0, 0, },
  22                        .iport = { 0, AUD_HW_PCMIN1, },
  23                },
  24        },
  25
  26        /* for Speaker/Headphone/Mic PCM In, Pin:AI2Dx */
  27        {
  28                .name = AUD_NAME_PCMIN2,
  29                .gname = AUD_GNAME_AUX,
  30                .swm = {
  31                        .type  = PORT_TYPE_I2S,
  32                        .dir   = PORT_DIR_INPUT,
  33                        .rb    = { 17, 12, },
  34                        .ch    = { 17, 12, },
  35                        .iif   = { 1, 1, },
  36                        .iport = { 1, AUD_HW_PCMIN2, },
  37                },
  38        },
  39
  40        /* for HDMI PCM Out, Pin:AO1Dx (inner) */
  41        {
  42                .name = AUD_NAME_HPCMOUT1,
  43                .gname = AUD_GNAME_HDMI,
  44                .swm = {
  45                        .type  = PORT_TYPE_I2S,
  46                        .dir   = PORT_DIR_OUTPUT,
  47                        .rb    = { 0, 0, },
  48                        .ch    = { 0, 0, },
  49                        .oif   = { 0, 0, },
  50                        .oport = { 3, AUD_HW_HPCMOUT1, },
  51                },
  52        },
  53
  54        /* for Line PCM Out, Pin:AO2Dx */
  55        {
  56                .name = AUD_NAME_PCMOUT1,
  57                .gname = AUD_GNAME_LINE,
  58                .swm = {
  59                        .type  = PORT_TYPE_I2S,
  60                        .dir   = PORT_DIR_OUTPUT,
  61                        .rb    = { 1, 1, },
  62                        .ch    = { 1, 1, },
  63                        .oif   = { 1, 1, },
  64                        .oport = { 0, AUD_HW_PCMOUT1, },
  65                },
  66        },
  67
  68        /* for Speaker/Headphone/Mic PCM Out, Pin:AO3Dx */
  69        {
  70                .name = AUD_NAME_PCMOUT2,
  71                .gname = AUD_GNAME_AUX,
  72                .swm = {
  73                        .type  = PORT_TYPE_I2S,
  74                        .dir   = PORT_DIR_OUTPUT,
  75                        .rb    = { 2, 2, },
  76                        .ch    = { 2, 2, },
  77                        .oif   = { 2, 2, },
  78                        .oport = { 1, AUD_HW_PCMOUT2, },
  79                },
  80        },
  81
  82        /* for HDMI Out, Pin:AO1IEC */
  83        {
  84                .name = AUD_NAME_HIECOUT1,
  85                .swm = {
  86                        .type  = PORT_TYPE_SPDIF,
  87                        .dir   = PORT_DIR_OUTPUT,
  88                        .rb    = { 6, 4, },
  89                        .ch    = { 6, 4, },
  90                        .oif   = { 6, 4, },
  91                        .oport = { 12, AUD_HW_HIECOUT1, },
  92                },
  93        },
  94
  95        /* for HDMI Out, Pin:AO1IEC, Compress */
  96        {
  97                .name = AUD_NAME_HIECCOMPOUT1,
  98                .swm = {
  99                        .type  = PORT_TYPE_SPDIF,
 100                        .dir   = PORT_DIR_OUTPUT,
 101                        .rb    = { 6, 4, },
 102                        .ch    = { 6, 4, },
 103                        .oif   = { 6, 4, },
 104                        .oport = { 12, AUD_HW_HIECOUT1, },
 105                },
 106        },
 107
 108        /* for S/PDIF Out, Pin:AO2IEC */
 109        {
 110                .name = AUD_NAME_IECOUT1,
 111                .swm = {
 112                        .type  = PORT_TYPE_SPDIF,
 113                        .dir   = PORT_DIR_OUTPUT,
 114                        .rb    = { 7, 5, },
 115                        .ch    = { 7, 5, },
 116                        .oif   = { 7, 5, },
 117                        .oport = { 13, AUD_HW_IECOUT1, },
 118                },
 119        },
 120
 121        /* for S/PDIF Out, Pin:AO2IEC */
 122        {
 123                .name = AUD_NAME_IECCOMPOUT1,
 124                .swm = {
 125                        .type  = PORT_TYPE_SPDIF,
 126                        .dir   = PORT_DIR_OUTPUT,
 127                        .rb    = { 7, 5, },
 128                        .ch    = { 7, 5, },
 129                        .oif   = { 7, 5, },
 130                        .oport = { 13, AUD_HW_IECOUT1, },
 131                },
 132        },
 133};
 134
 135static 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, },
 142};
 143
 144static int uniphier_aio_pxs2_probe(struct snd_soc_dai *dai)
 145{
 146        int ret;
 147
 148        ret = uniphier_aio_dai_probe(dai);
 149        if (ret < 0)
 150                return ret;
 151
 152        ret = snd_soc_dai_set_pll(dai, AUD_PLL_A1, 0, 0, 36864000);
 153        if (ret < 0)
 154                return ret;
 155        ret = snd_soc_dai_set_pll(dai, AUD_PLL_F1, 0, 0, 36864000);
 156        if (ret < 0)
 157                return ret;
 158
 159        ret = snd_soc_dai_set_pll(dai, AUD_PLL_A2, 0, 0, 33868800);
 160        if (ret < 0)
 161                return ret;
 162        ret = snd_soc_dai_set_pll(dai, AUD_PLL_F2, 0, 0, 33868800);
 163        if (ret < 0)
 164                return ret;
 165
 166        return 0;
 167}
 168
 169static struct snd_soc_dai_driver uniphier_aio_dai_pxs2[] = {
 170        {
 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,
 176                .playback = {
 177                        .stream_name = AUD_NAME_HPCMOUT1,
 178                        .formats     = SNDRV_PCM_FMTBIT_S32_LE,
 179                        .rates       = SNDRV_PCM_RATE_48000,
 180                        .channels_min = 2,
 181                        .channels_max = 2,
 182                },
 183                .ops = &uniphier_aio_i2s_ops,
 184        },
 185        {
 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,
 191                .playback = {
 192                        .stream_name = AUD_NAME_PCMOUT1,
 193                        .formats     = SNDRV_PCM_FMTBIT_S32_LE,
 194                        .rates       = SNDRV_PCM_RATE_48000,
 195                        .channels_min = 2,
 196                        .channels_max = 2,
 197                },
 198                .capture = {
 199                        .stream_name = AUD_NAME_PCMIN1,
 200                        .formats     = SNDRV_PCM_FMTBIT_S32_LE,
 201                        .rates       = SNDRV_PCM_RATE_48000,
 202                        .channels_min = 2,
 203                        .channels_max = 2,
 204                },
 205                .ops = &uniphier_aio_i2s_ops,
 206        },
 207        {
 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,
 213                .playback = {
 214                        .stream_name = AUD_NAME_PCMOUT2,
 215                        .formats     = SNDRV_PCM_FMTBIT_S32_LE,
 216                        .rates       = SNDRV_PCM_RATE_48000,
 217                        .channels_min = 2,
 218                        .channels_max = 2,
 219                },
 220                .capture = {
 221                        .stream_name = AUD_NAME_PCMIN2,
 222                        .formats     = SNDRV_PCM_FMTBIT_S32_LE,
 223                        .rates       = SNDRV_PCM_RATE_48000,
 224                        .channels_min = 2,
 225                        .channels_max = 2,
 226                },
 227                .ops = &uniphier_aio_i2s_ops,
 228        },
 229        {
 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,
 235                .playback = {
 236                        .stream_name = AUD_NAME_HIECOUT1,
 237                        .formats     = SNDRV_PCM_FMTBIT_S32_LE,
 238                        .rates       = SNDRV_PCM_RATE_48000,
 239                        .channels_min = 2,
 240                        .channels_max = 2,
 241                },
 242                .ops = &uniphier_aio_spdif_ops,
 243        },
 244        {
 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,
 250                .playback = {
 251                        .stream_name = AUD_NAME_IECOUT1,
 252                        .formats     = SNDRV_PCM_FMTBIT_S32_LE,
 253                        .rates       = SNDRV_PCM_RATE_48000,
 254                        .channels_min = 2,
 255                        .channels_max = 2,
 256                },
 257                .ops = &uniphier_aio_spdif_ops,
 258        },
 259        {
 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,
 266                .playback = {
 267                        .stream_name = AUD_NAME_HIECCOMPOUT1,
 268                        .channels_min = 1,
 269                        .channels_max = 1,
 270                },
 271                .ops = &uniphier_aio_spdif_ops,
 272        },
 273        {
 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,
 280                .playback = {
 281                        .stream_name = AUD_NAME_IECCOMPOUT1,
 282                        .channels_min = 1,
 283                        .channels_max = 1,
 284                },
 285                .ops = &uniphier_aio_spdif_ops,
 286        },
 287};
 288
 289static 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),
 296        .addr_ext  = 0,
 297};
 298
 299static const struct of_device_id uniphier_aio_of_match[] = {
 300        {
 301                .compatible = "socionext,uniphier-pxs2-aio",
 302                .data = &uniphier_aio_pxs2_spec,
 303        },
 304        {},
 305};
 306MODULE_DEVICE_TABLE(of, uniphier_aio_of_match);
 307
 308static struct platform_driver uniphier_aio_driver = {
 309        .driver = {
 310                .name = "snd-uniphier-aio-pxs2",
 311                .of_match_table = of_match_ptr(uniphier_aio_of_match),
 312        },
 313        .probe    = uniphier_aio_probe,
 314        .remove   = uniphier_aio_remove,
 315};
 316module_platform_driver(uniphier_aio_driver);
 317
 318MODULE_AUTHOR("Katsuhiro Suzuki <suzuki.katsuhiro@socionext.com>");
 319MODULE_DESCRIPTION("UniPhier PXs2 AIO driver.");
 320MODULE_LICENSE("GPL v2");
 321