linux/sound/soc/uniphier/aio-ld11.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0
   2//
   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 int uniphier_aio_ld11_probe(struct snd_soc_dai *dai)
 192{
 193        int ret;
 194
 195        ret = uniphier_aio_dai_probe(dai);
 196        if (ret < 0)
 197                return ret;
 198
 199        ret = snd_soc_dai_set_pll(dai, AUD_PLL_A1, 0, 0, 36864000);
 200        if (ret < 0)
 201                return ret;
 202        ret = snd_soc_dai_set_pll(dai, AUD_PLL_F1, 0, 0, 36864000);
 203        if (ret < 0)
 204                return ret;
 205
 206        ret = snd_soc_dai_set_pll(dai, AUD_PLL_A2, 0, 0, 33868800);
 207        if (ret < 0)
 208                return ret;
 209        ret = snd_soc_dai_set_pll(dai, AUD_PLL_F2, 0, 0, 33868800);
 210        if (ret < 0)
 211                return ret;
 212
 213        return 0;
 214}
 215
 216static struct snd_soc_dai_driver uniphier_aio_dai_ld11[] = {
 217        {
 218                .name    = AUD_GNAME_HDMI,
 219                .probe   = uniphier_aio_ld11_probe,
 220                .remove  = uniphier_aio_dai_remove,
 221                .suspend = uniphier_aio_dai_suspend,
 222                .resume  = uniphier_aio_dai_resume,
 223                .playback = {
 224                        .stream_name = AUD_NAME_PCMOUT1,
 225                        .formats     = SNDRV_PCM_FMTBIT_S32_LE,
 226                        .rates       = SNDRV_PCM_RATE_48000,
 227                        .channels_min = 2,
 228                        .channels_max = 2,
 229                },
 230                .capture = {
 231                        .stream_name = AUD_NAME_PCMIN1,
 232                        .formats     = SNDRV_PCM_FMTBIT_S32_LE,
 233                        .rates       = SNDRV_PCM_RATE_48000 |
 234                                SNDRV_PCM_RATE_44100 |
 235                                SNDRV_PCM_RATE_32000,
 236                        .channels_min = 2,
 237                        .channels_max = 2,
 238                },
 239                .ops = &uniphier_aio_i2s_ops,
 240        },
 241        {
 242                .name    = AUD_NAME_PCMIN2,
 243                .probe   = uniphier_aio_ld11_probe,
 244                .remove  = uniphier_aio_dai_remove,
 245                .suspend = uniphier_aio_dai_suspend,
 246                .resume  = uniphier_aio_dai_resume,
 247                .capture = {
 248                        .stream_name = AUD_NAME_PCMIN2,
 249                        .formats     = SNDRV_PCM_FMTBIT_S32_LE,
 250                        .rates       = SNDRV_PCM_RATE_48000,
 251                        .channels_min = 2,
 252                        .channels_max = 2,
 253                },
 254                .ops = &uniphier_aio_i2s_ops,
 255        },
 256        {
 257                .name    = AUD_GNAME_LINE,
 258                .probe   = uniphier_aio_ld11_probe,
 259                .remove  = uniphier_aio_dai_remove,
 260                .suspend = uniphier_aio_dai_suspend,
 261                .resume  = uniphier_aio_dai_resume,
 262                .playback = {
 263                        .stream_name = AUD_NAME_PCMOUT2,
 264                        .formats     = SNDRV_PCM_FMTBIT_S32_LE,
 265                        .rates       = SNDRV_PCM_RATE_48000,
 266                        .channels_min = 2,
 267                        .channels_max = 2,
 268                },
 269                .capture = {
 270                        .stream_name = AUD_NAME_PCMIN3,
 271                        .formats     = SNDRV_PCM_FMTBIT_S32_LE,
 272                        .rates       = SNDRV_PCM_RATE_48000,
 273                        .channels_min = 2,
 274                        .channels_max = 2,
 275                },
 276                .ops = &uniphier_aio_i2s_ops,
 277        },
 278        {
 279                .name    = AUD_NAME_HPCMOUT1,
 280                .probe   = uniphier_aio_ld11_probe,
 281                .remove  = uniphier_aio_dai_remove,
 282                .suspend = uniphier_aio_dai_suspend,
 283                .resume  = uniphier_aio_dai_resume,
 284                .playback = {
 285                        .stream_name = AUD_NAME_HPCMOUT1,
 286                        .formats     = SNDRV_PCM_FMTBIT_S32_LE,
 287                        .rates       = SNDRV_PCM_RATE_48000,
 288                        .channels_min = 2,
 289                        .channels_max = 8,
 290                },
 291                .ops = &uniphier_aio_i2s_ops,
 292        },
 293        {
 294                .name    = AUD_NAME_PCMOUT3,
 295                .probe   = uniphier_aio_ld11_probe,
 296                .remove  = uniphier_aio_dai_remove,
 297                .suspend = uniphier_aio_dai_suspend,
 298                .resume  = uniphier_aio_dai_resume,
 299                .playback = {
 300                        .stream_name = AUD_NAME_PCMOUT3,
 301                        .formats     = SNDRV_PCM_FMTBIT_S32_LE,
 302                        .rates       = SNDRV_PCM_RATE_48000,
 303                        .channels_min = 2,
 304                        .channels_max = 2,
 305                },
 306                .ops = &uniphier_aio_i2s_ops,
 307        },
 308        {
 309                .name    = AUD_NAME_HIECOUT1,
 310                .probe   = uniphier_aio_ld11_probe,
 311                .remove  = uniphier_aio_dai_remove,
 312                .suspend = uniphier_aio_dai_suspend,
 313                .resume  = uniphier_aio_dai_resume,
 314                .playback = {
 315                        .stream_name = AUD_NAME_HIECOUT1,
 316                        .formats     = SNDRV_PCM_FMTBIT_S32_LE,
 317                        .rates       = SNDRV_PCM_RATE_48000,
 318                        .channels_min = 2,
 319                        .channels_max = 2,
 320                },
 321                .ops = &uniphier_aio_spdif_ops,
 322        },
 323        {
 324                .name    = AUD_NAME_EPCMOUT2,
 325                .probe   = uniphier_aio_ld11_probe,
 326                .remove  = uniphier_aio_dai_remove,
 327                .suspend = uniphier_aio_dai_suspend,
 328                .resume  = uniphier_aio_dai_resume,
 329                .playback = {
 330                        .stream_name = AUD_NAME_EPCMOUT2,
 331                        .formats     = SNDRV_PCM_FMTBIT_S32_LE,
 332                        .rates       = SNDRV_PCM_RATE_48000 |
 333                                SNDRV_PCM_RATE_44100 |
 334                                SNDRV_PCM_RATE_32000,
 335                        .channels_min = 2,
 336                        .channels_max = 2,
 337                },
 338                .ops = &uniphier_aio_i2s_ops,
 339        },
 340        {
 341                .name    = AUD_NAME_EPCMOUT3,
 342                .probe   = uniphier_aio_ld11_probe,
 343                .remove  = uniphier_aio_dai_remove,
 344                .suspend = uniphier_aio_dai_suspend,
 345                .resume  = uniphier_aio_dai_resume,
 346                .playback = {
 347                        .stream_name = AUD_NAME_EPCMOUT3,
 348                        .formats     = SNDRV_PCM_FMTBIT_S32_LE,
 349                        .rates       = SNDRV_PCM_RATE_48000 |
 350                                SNDRV_PCM_RATE_44100 |
 351                                SNDRV_PCM_RATE_32000,
 352                        .channels_min = 2,
 353                        .channels_max = 2,
 354                },
 355                .ops = &uniphier_aio_i2s_ops,
 356        },
 357        {
 358                .name    = AUD_NAME_HIECCOMPOUT1,
 359                .probe   = uniphier_aio_ld11_probe,
 360                .remove  = uniphier_aio_dai_remove,
 361                .suspend = uniphier_aio_dai_suspend,
 362                .resume  = uniphier_aio_dai_resume,
 363                .compress_new = snd_soc_new_compress,
 364                .playback = {
 365                        .stream_name = AUD_NAME_HIECCOMPOUT1,
 366                        .channels_min = 1,
 367                        .channels_max = 1,
 368                },
 369                .ops = &uniphier_aio_spdif_ops,
 370        },
 371};
 372
 373static const struct uniphier_aio_chip_spec uniphier_aio_ld11_spec = {
 374        .specs     = uniphier_aio_ld11,
 375        .num_specs = ARRAY_SIZE(uniphier_aio_ld11),
 376        .dais      = uniphier_aio_dai_ld11,
 377        .num_dais  = ARRAY_SIZE(uniphier_aio_dai_ld11),
 378        .plls      = uniphier_aio_pll_ld11,
 379        .num_plls  = ARRAY_SIZE(uniphier_aio_pll_ld11),
 380        .addr_ext  = 0,
 381};
 382
 383static const struct uniphier_aio_chip_spec uniphier_aio_ld20_spec = {
 384        .specs     = uniphier_aio_ld11,
 385        .num_specs = ARRAY_SIZE(uniphier_aio_ld11),
 386        .dais      = uniphier_aio_dai_ld11,
 387        .num_dais  = ARRAY_SIZE(uniphier_aio_dai_ld11),
 388        .plls      = uniphier_aio_pll_ld11,
 389        .num_plls  = ARRAY_SIZE(uniphier_aio_pll_ld11),
 390        .addr_ext  = 1,
 391};
 392
 393static const struct of_device_id uniphier_aio_of_match[] = {
 394        {
 395                .compatible = "socionext,uniphier-ld11-aio",
 396                .data = &uniphier_aio_ld11_spec,
 397        },
 398        {
 399                .compatible = "socionext,uniphier-ld20-aio",
 400                .data = &uniphier_aio_ld20_spec,
 401        },
 402        {},
 403};
 404MODULE_DEVICE_TABLE(of, uniphier_aio_of_match);
 405
 406static struct platform_driver uniphier_aio_driver = {
 407        .driver = {
 408                .name = "snd-uniphier-aio-ld11",
 409                .of_match_table = of_match_ptr(uniphier_aio_of_match),
 410        },
 411        .probe    = uniphier_aio_probe,
 412        .remove   = uniphier_aio_remove,
 413};
 414module_platform_driver(uniphier_aio_driver);
 415
 416MODULE_AUTHOR("Katsuhiro Suzuki <suzuki.katsuhiro@socionext.com>");
 417MODULE_DESCRIPTION("UniPhier LD11/LD20 AIO driver.");
 418MODULE_LICENSE("GPL v2");
 419