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                .playback = {
 222                        .stream_name = AUD_NAME_PCMOUT1,
 223                        .formats     = SNDRV_PCM_FMTBIT_S32_LE,
 224                        .rates       = SNDRV_PCM_RATE_48000,
 225                        .channels_min = 2,
 226                        .channels_max = 2,
 227                },
 228                .capture = {
 229                        .stream_name = AUD_NAME_PCMIN1,
 230                        .formats     = SNDRV_PCM_FMTBIT_S32_LE,
 231                        .rates       = SNDRV_PCM_RATE_48000 |
 232                                SNDRV_PCM_RATE_44100 |
 233                                SNDRV_PCM_RATE_32000,
 234                        .channels_min = 2,
 235                        .channels_max = 2,
 236                },
 237                .ops = &uniphier_aio_i2s_ops,
 238        },
 239        {
 240                .name    = AUD_NAME_PCMIN2,
 241                .probe   = uniphier_aio_ld11_probe,
 242                .remove  = uniphier_aio_dai_remove,
 243                .capture = {
 244                        .stream_name = AUD_NAME_PCMIN2,
 245                        .formats     = SNDRV_PCM_FMTBIT_S32_LE,
 246                        .rates       = SNDRV_PCM_RATE_48000,
 247                        .channels_min = 2,
 248                        .channels_max = 2,
 249                },
 250                .ops = &uniphier_aio_i2s_ops,
 251        },
 252        {
 253                .name    = AUD_GNAME_LINE,
 254                .probe   = uniphier_aio_ld11_probe,
 255                .remove  = uniphier_aio_dai_remove,
 256                .playback = {
 257                        .stream_name = AUD_NAME_PCMOUT2,
 258                        .formats     = SNDRV_PCM_FMTBIT_S32_LE,
 259                        .rates       = SNDRV_PCM_RATE_48000,
 260                        .channels_min = 2,
 261                        .channels_max = 2,
 262                },
 263                .capture = {
 264                        .stream_name = AUD_NAME_PCMIN3,
 265                        .formats     = SNDRV_PCM_FMTBIT_S32_LE,
 266                        .rates       = SNDRV_PCM_RATE_48000,
 267                        .channels_min = 2,
 268                        .channels_max = 2,
 269                },
 270                .ops = &uniphier_aio_i2s_ops,
 271        },
 272        {
 273                .name    = AUD_NAME_HPCMOUT1,
 274                .probe   = uniphier_aio_ld11_probe,
 275                .remove  = uniphier_aio_dai_remove,
 276                .playback = {
 277                        .stream_name = AUD_NAME_HPCMOUT1,
 278                        .formats     = SNDRV_PCM_FMTBIT_S32_LE,
 279                        .rates       = SNDRV_PCM_RATE_48000,
 280                        .channels_min = 2,
 281                        .channels_max = 8,
 282                },
 283                .ops = &uniphier_aio_i2s_ops,
 284        },
 285        {
 286                .name    = AUD_NAME_PCMOUT3,
 287                .probe   = uniphier_aio_ld11_probe,
 288                .remove  = uniphier_aio_dai_remove,
 289                .playback = {
 290                        .stream_name = AUD_NAME_PCMOUT3,
 291                        .formats     = SNDRV_PCM_FMTBIT_S32_LE,
 292                        .rates       = SNDRV_PCM_RATE_48000,
 293                        .channels_min = 2,
 294                        .channels_max = 2,
 295                },
 296                .ops = &uniphier_aio_i2s_ops,
 297        },
 298        {
 299                .name    = AUD_NAME_HIECOUT1,
 300                .probe   = uniphier_aio_ld11_probe,
 301                .remove  = uniphier_aio_dai_remove,
 302                .playback = {
 303                        .stream_name = AUD_NAME_HIECOUT1,
 304                        .formats     = SNDRV_PCM_FMTBIT_S32_LE,
 305                        .rates       = SNDRV_PCM_RATE_48000,
 306                        .channels_min = 2,
 307                        .channels_max = 2,
 308                },
 309                .ops = &uniphier_aio_spdif_ops,
 310        },
 311        {
 312                .name    = AUD_NAME_EPCMOUT2,
 313                .probe   = uniphier_aio_ld11_probe,
 314                .remove  = uniphier_aio_dai_remove,
 315                .playback = {
 316                        .stream_name = AUD_NAME_EPCMOUT2,
 317                        .formats     = SNDRV_PCM_FMTBIT_S32_LE,
 318                        .rates       = SNDRV_PCM_RATE_48000 |
 319                                SNDRV_PCM_RATE_44100 |
 320                                SNDRV_PCM_RATE_32000,
 321                        .channels_min = 2,
 322                        .channels_max = 2,
 323                },
 324                .ops = &uniphier_aio_i2s_ops,
 325        },
 326        {
 327                .name    = AUD_NAME_EPCMOUT3,
 328                .probe   = uniphier_aio_ld11_probe,
 329                .remove  = uniphier_aio_dai_remove,
 330                .playback = {
 331                        .stream_name = AUD_NAME_EPCMOUT3,
 332                        .formats     = SNDRV_PCM_FMTBIT_S32_LE,
 333                        .rates       = SNDRV_PCM_RATE_48000 |
 334                                SNDRV_PCM_RATE_44100 |
 335                                SNDRV_PCM_RATE_32000,
 336                        .channels_min = 2,
 337                        .channels_max = 2,
 338                },
 339                .ops = &uniphier_aio_i2s_ops,
 340        },
 341        {
 342                .name    = AUD_NAME_HIECCOMPOUT1,
 343                .probe   = uniphier_aio_ld11_probe,
 344                .remove  = uniphier_aio_dai_remove,
 345                .compress_new = snd_soc_new_compress,
 346                .playback = {
 347                        .stream_name = AUD_NAME_HIECCOMPOUT1,
 348                        .channels_min = 1,
 349                        .channels_max = 1,
 350                },
 351                .ops = &uniphier_aio_spdif_ops,
 352        },
 353};
 354
 355static const struct uniphier_aio_chip_spec uniphier_aio_ld11_spec = {
 356        .specs     = uniphier_aio_ld11,
 357        .num_specs = ARRAY_SIZE(uniphier_aio_ld11),
 358        .dais      = uniphier_aio_dai_ld11,
 359        .num_dais  = ARRAY_SIZE(uniphier_aio_dai_ld11),
 360        .plls      = uniphier_aio_pll_ld11,
 361        .num_plls  = ARRAY_SIZE(uniphier_aio_pll_ld11),
 362        .addr_ext  = 0,
 363};
 364
 365static const struct uniphier_aio_chip_spec uniphier_aio_ld20_spec = {
 366        .specs     = uniphier_aio_ld11,
 367        .num_specs = ARRAY_SIZE(uniphier_aio_ld11),
 368        .dais      = uniphier_aio_dai_ld11,
 369        .num_dais  = ARRAY_SIZE(uniphier_aio_dai_ld11),
 370        .plls      = uniphier_aio_pll_ld11,
 371        .num_plls  = ARRAY_SIZE(uniphier_aio_pll_ld11),
 372        .addr_ext  = 1,
 373};
 374
 375static const struct of_device_id uniphier_aio_of_match[] __maybe_unused = {
 376        {
 377                .compatible = "socionext,uniphier-ld11-aio",
 378                .data = &uniphier_aio_ld11_spec,
 379        },
 380        {
 381                .compatible = "socionext,uniphier-ld20-aio",
 382                .data = &uniphier_aio_ld20_spec,
 383        },
 384        {},
 385};
 386MODULE_DEVICE_TABLE(of, uniphier_aio_of_match);
 387
 388static struct platform_driver uniphier_aio_driver = {
 389        .driver = {
 390                .name = "snd-uniphier-aio-ld11",
 391                .of_match_table = of_match_ptr(uniphier_aio_of_match),
 392        },
 393        .probe    = uniphier_aio_probe,
 394        .remove   = uniphier_aio_remove,
 395};
 396module_platform_driver(uniphier_aio_driver);
 397
 398MODULE_AUTHOR("Katsuhiro Suzuki <suzuki.katsuhiro@socionext.com>");
 399MODULE_DESCRIPTION("UniPhier LD11/LD20 AIO driver.");
 400MODULE_LICENSE("GPL v2");
 401