linux/sound/soc/intel/boards/sof_sdw.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0-only
   2// Copyright (c) 2020 Intel Corporation
   3
   4/*
   5 *  sof_sdw - ASOC Machine driver for Intel SoundWire platforms
   6 */
   7
   8#include <linux/device.h>
   9#include <linux/dmi.h>
  10#include <linux/module.h>
  11#include <linux/soundwire/sdw.h>
  12#include <linux/soundwire/sdw_type.h>
  13#include <sound/soc.h>
  14#include <sound/soc-acpi.h>
  15#include "sof_sdw_common.h"
  16
  17unsigned long sof_sdw_quirk = SOF_RT711_JD_SRC_JD1;
  18static int quirk_override = -1;
  19module_param_named(quirk, quirk_override, int, 0444);
  20MODULE_PARM_DESC(quirk, "Board-specific quirk override");
  21
  22#define INC_ID(BE, CPU, LINK)   do { (BE)++; (CPU)++; (LINK)++; } while (0)
  23
  24static void log_quirks(struct device *dev)
  25{
  26        if (SOF_RT711_JDSRC(sof_sdw_quirk))
  27                dev_dbg(dev, "quirk realtek,jack-detect-source %ld\n",
  28                        SOF_RT711_JDSRC(sof_sdw_quirk));
  29        if (sof_sdw_quirk & SOF_SDW_FOUR_SPK)
  30                dev_dbg(dev, "quirk SOF_SDW_FOUR_SPK enabled\n");
  31        if (sof_sdw_quirk & SOF_SDW_TGL_HDMI)
  32                dev_dbg(dev, "quirk SOF_SDW_TGL_HDMI enabled\n");
  33        if (sof_sdw_quirk & SOF_SDW_PCH_DMIC)
  34                dev_dbg(dev, "quirk SOF_SDW_PCH_DMIC enabled\n");
  35        if (SOF_SSP_GET_PORT(sof_sdw_quirk))
  36                dev_dbg(dev, "SSP port %ld\n",
  37                        SOF_SSP_GET_PORT(sof_sdw_quirk));
  38        if (sof_sdw_quirk & SOF_RT715_DAI_ID_FIX)
  39                dev_dbg(dev, "quirk SOF_RT715_DAI_ID_FIX enabled\n");
  40        if (sof_sdw_quirk & SOF_SDW_NO_AGGREGATION)
  41                dev_dbg(dev, "quirk SOF_SDW_NO_AGGREGATION enabled\n");
  42}
  43
  44static int sof_sdw_quirk_cb(const struct dmi_system_id *id)
  45{
  46        sof_sdw_quirk = (unsigned long)id->driver_data;
  47        return 1;
  48}
  49
  50static const struct dmi_system_id sof_sdw_quirk_table[] = {
  51        {
  52                .callback = sof_sdw_quirk_cb,
  53                .matches = {
  54                        DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc"),
  55                        DMI_EXACT_MATCH(DMI_PRODUCT_SKU, "09C6")
  56                },
  57                .driver_data = (void *)(SOF_RT711_JD_SRC_JD2 |
  58                                        SOF_RT715_DAI_ID_FIX),
  59        },
  60        {
  61                /* early version of SKU 09C6 */
  62                .callback = sof_sdw_quirk_cb,
  63                .matches = {
  64                        DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc"),
  65                        DMI_EXACT_MATCH(DMI_PRODUCT_SKU, "0983")
  66                },
  67                .driver_data = (void *)(SOF_RT711_JD_SRC_JD2 |
  68                                        SOF_RT715_DAI_ID_FIX),
  69        },
  70        {
  71                .callback = sof_sdw_quirk_cb,
  72                .matches = {
  73                        DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc"),
  74                        DMI_EXACT_MATCH(DMI_PRODUCT_SKU, "098F"),
  75                },
  76                .driver_data = (void *)(SOF_RT711_JD_SRC_JD2 |
  77                                        SOF_RT715_DAI_ID_FIX |
  78                                        SOF_SDW_FOUR_SPK),
  79        },
  80                {
  81                .callback = sof_sdw_quirk_cb,
  82                .matches = {
  83                        DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc"),
  84                        DMI_EXACT_MATCH(DMI_PRODUCT_SKU, "0990"),
  85                },
  86                .driver_data = (void *)(SOF_RT711_JD_SRC_JD2 |
  87                                        SOF_RT715_DAI_ID_FIX |
  88                                        SOF_SDW_FOUR_SPK),
  89        },
  90        {
  91                .callback = sof_sdw_quirk_cb,
  92                .matches = {
  93                        DMI_MATCH(DMI_SYS_VENDOR, "Intel Corporation"),
  94                        DMI_MATCH(DMI_PRODUCT_NAME,
  95                                  "Tiger Lake Client Platform"),
  96                },
  97                .driver_data = (void *)(SOF_RT711_JD_SRC_JD1 |
  98                                SOF_SDW_TGL_HDMI | SOF_SDW_PCH_DMIC |
  99                                SOF_SSP_PORT(SOF_I2S_SSP2)),
 100        },
 101        {
 102                .callback = sof_sdw_quirk_cb,
 103                .matches = {
 104                        DMI_MATCH(DMI_SYS_VENDOR, "Intel Corporation"),
 105                        DMI_MATCH(DMI_PRODUCT_NAME, "Ice Lake Client"),
 106                },
 107                .driver_data = (void *)SOF_SDW_PCH_DMIC,
 108        },
 109        {
 110                .callback = sof_sdw_quirk_cb,
 111                .matches = {
 112                        DMI_MATCH(DMI_SYS_VENDOR, "Intel Corporation"),
 113                        DMI_MATCH(DMI_PRODUCT_NAME, "CometLake Client"),
 114                },
 115                .driver_data = (void *)SOF_SDW_PCH_DMIC,
 116        },
 117        {
 118                .callback = sof_sdw_quirk_cb,
 119                .matches = {
 120                        DMI_MATCH(DMI_SYS_VENDOR, "Google"),
 121                        DMI_MATCH(DMI_PRODUCT_NAME, "Volteer"),
 122                },
 123                .driver_data = (void *)(SOF_SDW_TGL_HDMI | SOF_SDW_PCH_DMIC |
 124                                        SOF_SDW_FOUR_SPK),
 125        },
 126
 127        {}
 128};
 129
 130static struct snd_soc_codec_conf codec_conf[] = {
 131        {
 132                .dlc = COMP_CODEC_CONF("sdw:0:25d:711:0"),
 133                .name_prefix = "rt711",
 134        },
 135        /* rt1308 w/ I2S connection */
 136        {
 137                .dlc = COMP_CODEC_CONF("i2c-10EC1308:00"),
 138                .name_prefix = "rt1308-1",
 139        },
 140        /* rt1308 left on link 1 */
 141        {
 142                .dlc = COMP_CODEC_CONF("sdw:1:25d:1308:0"),
 143                .name_prefix = "rt1308-1",
 144        },
 145        /* two 1308s on link1 with different unique id */
 146        {
 147                .dlc = COMP_CODEC_CONF("sdw:1:25d:1308:0:0"),
 148                .name_prefix = "rt1308-1",
 149        },
 150        {
 151                .dlc = COMP_CODEC_CONF("sdw:1:25d:1308:0:2"),
 152                .name_prefix = "rt1308-2",
 153        },
 154        /* rt1308 right on link 2 */
 155        {
 156                .dlc = COMP_CODEC_CONF("sdw:2:25d:1308:0"),
 157                .name_prefix = "rt1308-2",
 158        },
 159        {
 160                .dlc = COMP_CODEC_CONF("sdw:3:25d:715:0"),
 161                .name_prefix = "rt715",
 162        },
 163        /* two MAX98373s on link1 with different unique id */
 164        {
 165                .dlc = COMP_CODEC_CONF("sdw:1:19f:8373:0:3"),
 166                .name_prefix = "Right",
 167        },
 168        {
 169                .dlc = COMP_CODEC_CONF("sdw:1:19f:8373:0:7"),
 170                .name_prefix = "Left",
 171        },
 172        {
 173                .dlc = COMP_CODEC_CONF("sdw:0:25d:5682:0"),
 174                .name_prefix = "rt5682",
 175        },
 176};
 177
 178static struct snd_soc_dai_link_component dmic_component[] = {
 179        {
 180                .name = "dmic-codec",
 181                .dai_name = "dmic-hifi",
 182        }
 183};
 184
 185static struct snd_soc_dai_link_component platform_component[] = {
 186        {
 187                /* name might be overridden during probe */
 188                .name = "0000:00:1f.3"
 189        }
 190};
 191
 192/* these wrappers are only needed to avoid typecast compilation errors */
 193int sdw_startup(struct snd_pcm_substream *substream)
 194{
 195        return sdw_startup_stream(substream);
 196}
 197
 198void sdw_shutdown(struct snd_pcm_substream *substream)
 199{
 200        sdw_shutdown_stream(substream);
 201}
 202
 203static const struct snd_soc_ops sdw_ops = {
 204        .startup = sdw_startup,
 205        .shutdown = sdw_shutdown,
 206};
 207
 208static struct sof_sdw_codec_info codec_info_list[] = {
 209        {
 210                .id = 0x700,
 211                .direction = {true, true},
 212                .dai_name = "rt700-aif1",
 213                .init = sof_sdw_rt700_init,
 214        },
 215        {
 216                .id = 0x711,
 217                .direction = {true, true},
 218                .dai_name = "rt711-aif1",
 219                .init = sof_sdw_rt711_init,
 220                .exit = sof_sdw_rt711_exit,
 221        },
 222        {
 223                .id = 0x1308,
 224                .acpi_id = "10EC1308",
 225                .direction = {true, false},
 226                .dai_name = "rt1308-aif",
 227                .ops = &sof_sdw_rt1308_i2s_ops,
 228                .init = sof_sdw_rt1308_init,
 229        },
 230        {
 231                .id = 0x715,
 232                .direction = {false, true},
 233                .dai_name = "rt715-aif2",
 234                .init = sof_sdw_rt715_init,
 235        },
 236        {
 237                .id = 0x8373,
 238                .direction = {true, true},
 239                .dai_name = "max98373-aif1",
 240                .init = sof_sdw_mx8373_init,
 241                .codec_card_late_probe = sof_sdw_mx8373_late_probe,
 242        },
 243        {
 244                .id = 0x5682,
 245                .direction = {true, true},
 246                .dai_name = "rt5682-sdw",
 247                .init = sof_sdw_rt5682_init,
 248        },
 249};
 250
 251static inline int find_codec_info_part(unsigned int part_id)
 252{
 253        int i;
 254
 255        for (i = 0; i < ARRAY_SIZE(codec_info_list); i++)
 256                if (part_id == codec_info_list[i].id)
 257                        break;
 258
 259        if (i == ARRAY_SIZE(codec_info_list))
 260                return -EINVAL;
 261
 262        return i;
 263}
 264
 265static inline int find_codec_info_acpi(const u8 *acpi_id)
 266{
 267        int i;
 268
 269        if (!acpi_id[0])
 270                return -EINVAL;
 271
 272        for (i = 0; i < ARRAY_SIZE(codec_info_list); i++)
 273                if (!memcmp(codec_info_list[i].acpi_id, acpi_id,
 274                            ACPI_ID_LEN))
 275                        break;
 276
 277        if (i == ARRAY_SIZE(codec_info_list))
 278                return -EINVAL;
 279
 280        return i;
 281}
 282
 283/*
 284 * get BE dailink number and CPU DAI number based on sdw link adr.
 285 * Since some sdw slaves may be aggregated, the CPU DAI number
 286 * may be larger than the number of BE dailinks.
 287 */
 288static int get_sdw_dailink_info(const struct snd_soc_acpi_link_adr *links,
 289                                int *sdw_be_num, int *sdw_cpu_dai_num)
 290{
 291        const struct snd_soc_acpi_link_adr *link;
 292        bool group_visited[SDW_MAX_GROUPS];
 293        bool no_aggregation;
 294        int i;
 295
 296        no_aggregation = sof_sdw_quirk & SOF_SDW_NO_AGGREGATION;
 297        *sdw_cpu_dai_num = 0;
 298        *sdw_be_num  = 0;
 299
 300        if (!links)
 301                return -EINVAL;
 302
 303        for (i = 0; i < SDW_MAX_GROUPS; i++)
 304                group_visited[i] = false;
 305
 306        for (link = links; link->num_adr; link++) {
 307                const struct snd_soc_acpi_endpoint *endpoint;
 308                int part_id, codec_index;
 309                int stream;
 310                u64 adr;
 311
 312                adr = link->adr_d->adr;
 313                part_id = SDW_PART_ID(adr);
 314                codec_index = find_codec_info_part(part_id);
 315                if (codec_index < 0)
 316                        return codec_index;
 317
 318                endpoint = link->adr_d->endpoints;
 319
 320                /* count DAI number for playback and capture */
 321                for_each_pcm_streams(stream) {
 322                        if (!codec_info_list[codec_index].direction[stream])
 323                                continue;
 324
 325                        (*sdw_cpu_dai_num)++;
 326
 327                        /* count BE for each non-aggregated slave or group */
 328                        if (!endpoint->aggregated || no_aggregation ||
 329                            !group_visited[endpoint->group_id])
 330                                (*sdw_be_num)++;
 331                }
 332
 333                if (endpoint->aggregated)
 334                        group_visited[endpoint->group_id] = true;
 335        }
 336
 337        return 0;
 338}
 339
 340static void init_dai_link(struct snd_soc_dai_link *dai_links, int be_id,
 341                          char *name, int playback, int capture,
 342                          struct snd_soc_dai_link_component *cpus,
 343                          int cpus_num,
 344                          struct snd_soc_dai_link_component *codecs,
 345                          int codecs_num,
 346                          int (*init)(struct snd_soc_pcm_runtime *rtd),
 347                          const struct snd_soc_ops *ops)
 348{
 349        dai_links->id = be_id;
 350        dai_links->name = name;
 351        dai_links->platforms = platform_component;
 352        dai_links->num_platforms = ARRAY_SIZE(platform_component);
 353        dai_links->nonatomic = true;
 354        dai_links->no_pcm = 1;
 355        dai_links->cpus = cpus;
 356        dai_links->num_cpus = cpus_num;
 357        dai_links->codecs = codecs;
 358        dai_links->num_codecs = codecs_num;
 359        dai_links->dpcm_playback = playback;
 360        dai_links->dpcm_capture = capture;
 361        dai_links->init = init;
 362        dai_links->ops = ops;
 363}
 364
 365static bool is_unique_device(const struct snd_soc_acpi_link_adr *link,
 366                             unsigned int sdw_version,
 367                             unsigned int mfg_id,
 368                             unsigned int part_id,
 369                             unsigned int class_id,
 370                             int index_in_link
 371                            )
 372{
 373        int i;
 374
 375        for (i = 0; i < link->num_adr; i++) {
 376                unsigned int sdw1_version, mfg1_id, part1_id, class1_id;
 377                u64 adr;
 378
 379                /* skip itself */
 380                if (i == index_in_link)
 381                        continue;
 382
 383                adr = link->adr_d[i].adr;
 384
 385                sdw1_version = SDW_VERSION(adr);
 386                mfg1_id = SDW_MFG_ID(adr);
 387                part1_id = SDW_PART_ID(adr);
 388                class1_id = SDW_CLASS_ID(adr);
 389
 390                if (sdw_version == sdw1_version &&
 391                    mfg_id == mfg1_id &&
 392                    part_id == part1_id &&
 393                    class_id == class1_id)
 394                        return false;
 395        }
 396
 397        return true;
 398}
 399
 400static int create_codec_dai_name(struct device *dev,
 401                                 const struct snd_soc_acpi_link_adr *link,
 402                                 struct snd_soc_dai_link_component *codec,
 403                                 int offset)
 404{
 405        int i;
 406
 407        for (i = 0; i < link->num_adr; i++) {
 408                unsigned int sdw_version, unique_id, mfg_id;
 409                unsigned int link_id, part_id, class_id;
 410                int codec_index, comp_index;
 411                char *codec_str;
 412                u64 adr;
 413
 414                adr = link->adr_d[i].adr;
 415
 416                sdw_version = SDW_VERSION(adr);
 417                link_id = SDW_DISCO_LINK_ID(adr);
 418                unique_id = SDW_UNIQUE_ID(adr);
 419                mfg_id = SDW_MFG_ID(adr);
 420                part_id = SDW_PART_ID(adr);
 421                class_id = SDW_CLASS_ID(adr);
 422
 423                comp_index = i + offset;
 424                if (is_unique_device(link, sdw_version, mfg_id, part_id,
 425                                     class_id, i)) {
 426                        codec_str = "sdw:%x:%x:%x:%x";
 427                        codec[comp_index].name =
 428                                devm_kasprintf(dev, GFP_KERNEL, codec_str,
 429                                               link_id, mfg_id, part_id,
 430                                               class_id);
 431                } else {
 432                        codec_str = "sdw:%x:%x:%x:%x:%x";
 433                        codec[comp_index].name =
 434                                devm_kasprintf(dev, GFP_KERNEL, codec_str,
 435                                               link_id, mfg_id, part_id,
 436                                               class_id, unique_id);
 437                }
 438
 439                if (!codec[comp_index].name)
 440                        return -ENOMEM;
 441
 442                codec_index = find_codec_info_part(part_id);
 443                if (codec_index < 0)
 444                        return codec_index;
 445
 446                codec[comp_index].dai_name =
 447                        codec_info_list[codec_index].dai_name;
 448        }
 449
 450        return 0;
 451}
 452
 453static int set_codec_init_func(const struct snd_soc_acpi_link_adr *link,
 454                               struct snd_soc_dai_link *dai_links,
 455                               bool playback, int group_id)
 456{
 457        int i;
 458
 459        do {
 460                /*
 461                 * Initialize the codec. If codec is part of an aggregated
 462                 * group (group_id>0), initialize all codecs belonging to
 463                 * same group.
 464                 */
 465                for (i = 0; i < link->num_adr; i++) {
 466                        unsigned int part_id;
 467                        int codec_index;
 468
 469                        part_id = SDW_PART_ID(link->adr_d[i].adr);
 470                        codec_index = find_codec_info_part(part_id);
 471
 472                        if (codec_index < 0)
 473                                return codec_index;
 474                        /* The group_id is > 0 iff the codec is aggregated */
 475                        if (link->adr_d[i].endpoints->group_id != group_id)
 476                                continue;
 477                        if (codec_info_list[codec_index].init)
 478                                codec_info_list[codec_index].init(link,
 479                                                dai_links,
 480                                                &codec_info_list[codec_index],
 481                                                playback);
 482                }
 483                link++;
 484        } while (link->mask && group_id);
 485
 486        return 0;
 487}
 488
 489/*
 490 * check endpoint status in slaves and gather link ID for all slaves in
 491 * the same group to generate different CPU DAI. Now only support
 492 * one sdw link with all slaves set with only single group id.
 493 *
 494 * one slave on one sdw link with aggregated = 0
 495 * one sdw BE DAI <---> one-cpu DAI <---> one-codec DAI
 496 *
 497 * two or more slaves on one sdw link with aggregated = 0
 498 * one sdw BE DAI  <---> one-cpu DAI <---> multi-codec DAIs
 499 *
 500 * multiple links with multiple slaves with aggregated = 1
 501 * one sdw BE DAI  <---> 1 .. N CPU DAIs <----> 1 .. N codec DAIs
 502 */
 503static int get_slave_info(const struct snd_soc_acpi_link_adr *adr_link,
 504                          struct device *dev, int *cpu_dai_id, int *cpu_dai_num,
 505                          int *codec_num, int *group_id,
 506                          bool *group_generated)
 507{
 508        const struct snd_soc_acpi_adr_device *adr_d;
 509        const struct snd_soc_acpi_link_adr *adr_next;
 510        bool no_aggregation;
 511        int index = 0;
 512
 513        no_aggregation = sof_sdw_quirk & SOF_SDW_NO_AGGREGATION;
 514        *codec_num = adr_link->num_adr;
 515        adr_d = adr_link->adr_d;
 516
 517        /* make sure the link mask has a single bit set */
 518        if (!is_power_of_2(adr_link->mask))
 519                return -EINVAL;
 520
 521        cpu_dai_id[index++] = ffs(adr_link->mask) - 1;
 522        if (!adr_d->endpoints->aggregated || no_aggregation) {
 523                *cpu_dai_num = 1;
 524                *group_id = 0;
 525                return 0;
 526        }
 527
 528        *group_id = adr_d->endpoints->group_id;
 529
 530        /* gather other link ID of slaves in the same group */
 531        for (adr_next = adr_link + 1; adr_next && adr_next->num_adr;
 532                adr_next++) {
 533                const struct snd_soc_acpi_endpoint *endpoint;
 534
 535                endpoint = adr_next->adr_d->endpoints;
 536                if (!endpoint->aggregated ||
 537                    endpoint->group_id != *group_id)
 538                        continue;
 539
 540                /* make sure the link mask has a single bit set */
 541                if (!is_power_of_2(adr_next->mask))
 542                        return -EINVAL;
 543
 544                if (index >= SDW_MAX_CPU_DAIS) {
 545                        dev_err(dev, " cpu_dai_id array overflows");
 546                        return -EINVAL;
 547                }
 548
 549                cpu_dai_id[index++] = ffs(adr_next->mask) - 1;
 550                *codec_num += adr_next->num_adr;
 551        }
 552
 553        /*
 554         * indicate CPU DAIs for this group have been generated
 555         * to avoid generating CPU DAIs for this group again.
 556         */
 557        group_generated[*group_id] = true;
 558        *cpu_dai_num = index;
 559
 560        return 0;
 561}
 562
 563static int create_sdw_dailink(struct device *dev, int *be_index,
 564                              struct snd_soc_dai_link *dai_links,
 565                              int sdw_be_num, int sdw_cpu_dai_num,
 566                              struct snd_soc_dai_link_component *cpus,
 567                              const struct snd_soc_acpi_link_adr *link,
 568                              int *cpu_id, bool *group_generated)
 569{
 570        const struct snd_soc_acpi_link_adr *link_next;
 571        struct snd_soc_dai_link_component *codecs;
 572        int cpu_dai_id[SDW_MAX_CPU_DAIS];
 573        int cpu_dai_num, cpu_dai_index;
 574        unsigned int part_id, group_id;
 575        int codec_idx = 0;
 576        int i = 0, j = 0;
 577        int codec_index;
 578        int codec_num;
 579        int stream;
 580        int ret;
 581        int k;
 582
 583        ret = get_slave_info(link, dev, cpu_dai_id, &cpu_dai_num, &codec_num,
 584                             &group_id, group_generated);
 585        if (ret)
 586                return ret;
 587
 588        codecs = devm_kcalloc(dev, codec_num, sizeof(*codecs), GFP_KERNEL);
 589        if (!codecs)
 590                return -ENOMEM;
 591
 592        /* generate codec name on different links in the same group */
 593        for (link_next = link; link_next && link_next->num_adr &&
 594             i < cpu_dai_num; link_next++) {
 595                const struct snd_soc_acpi_endpoint *endpoints;
 596
 597                endpoints = link_next->adr_d->endpoints;
 598                if (group_id && (!endpoints->aggregated ||
 599                                 endpoints->group_id != group_id))
 600                        continue;
 601
 602                /* skip the link excluded by this processed group */
 603                if (cpu_dai_id[i] != ffs(link_next->mask) - 1)
 604                        continue;
 605
 606                ret = create_codec_dai_name(dev, link_next, codecs, codec_idx);
 607                if (ret < 0)
 608                        return ret;
 609
 610                /* check next link to create codec dai in the processed group */
 611                i++;
 612                codec_idx += link_next->num_adr;
 613        }
 614
 615        /* find codec info to create BE DAI */
 616        part_id = SDW_PART_ID(link->adr_d[0].adr);
 617        codec_index = find_codec_info_part(part_id);
 618        if (codec_index < 0)
 619                return codec_index;
 620
 621        cpu_dai_index = *cpu_id;
 622        for_each_pcm_streams(stream) {
 623                char *name, *cpu_name;
 624                int playback, capture;
 625                static const char * const sdw_stream_name[] = {
 626                        "SDW%d-Playback",
 627                        "SDW%d-Capture",
 628                };
 629
 630                if (!codec_info_list[codec_index].direction[stream])
 631                        continue;
 632
 633                /* create stream name according to first link id */
 634                name = devm_kasprintf(dev, GFP_KERNEL,
 635                                      sdw_stream_name[stream], cpu_dai_id[0]);
 636                if (!name)
 637                        return -ENOMEM;
 638
 639                /*
 640                 * generate CPU DAI name base on the sdw link ID and
 641                 * PIN ID with offset of 2 according to sdw dai driver.
 642                 */
 643                for (k = 0; k < cpu_dai_num; k++) {
 644                        cpu_name = devm_kasprintf(dev, GFP_KERNEL,
 645                                                  "SDW%d Pin%d", cpu_dai_id[k],
 646                                                  j + SDW_INTEL_BIDIR_PDI_BASE);
 647                        if (!cpu_name)
 648                                return -ENOMEM;
 649
 650                        if (cpu_dai_index >= sdw_cpu_dai_num) {
 651                                dev_err(dev, "invalid cpu dai index %d",
 652                                        cpu_dai_index);
 653                                return -EINVAL;
 654                        }
 655
 656                        cpus[cpu_dai_index++].dai_name = cpu_name;
 657                }
 658
 659                if (*be_index >= sdw_be_num) {
 660                        dev_err(dev, " invalid be dai index %d", *be_index);
 661                        return -EINVAL;
 662                }
 663
 664                if (*cpu_id >= sdw_cpu_dai_num) {
 665                        dev_err(dev, " invalid cpu dai index %d", *cpu_id);
 666                        return -EINVAL;
 667                }
 668
 669                playback = (stream == SNDRV_PCM_STREAM_PLAYBACK);
 670                capture = (stream == SNDRV_PCM_STREAM_CAPTURE);
 671                init_dai_link(dai_links + *be_index, *be_index, name,
 672                              playback, capture,
 673                              cpus + *cpu_id, cpu_dai_num,
 674                              codecs, codec_num,
 675                              NULL, &sdw_ops);
 676
 677                ret = set_codec_init_func(link, dai_links + (*be_index)++,
 678                                          playback, group_id);
 679                if (ret < 0) {
 680                        dev_err(dev, "failed to init codec %d", codec_index);
 681                        return ret;
 682                }
 683
 684                *cpu_id += cpu_dai_num;
 685                j++;
 686        }
 687
 688        return 0;
 689}
 690
 691/*
 692 * DAI link ID of SSP & DMIC & HDMI are based on last
 693 * link ID used by sdw link. Since be_id may be changed
 694 * in init func of sdw codec, it is not equal to be_id
 695 */
 696static inline int get_next_be_id(struct snd_soc_dai_link *links,
 697                                 int be_id)
 698{
 699        return links[be_id - 1].id + 1;
 700}
 701
 702#define IDISP_CODEC_MASK        0x4
 703
 704static int sof_card_dai_links_create(struct device *dev,
 705                                     struct snd_soc_acpi_mach *mach,
 706                                     struct snd_soc_card *card)
 707{
 708        int ssp_num, sdw_be_num = 0, hdmi_num = 0, dmic_num;
 709        struct mc_private *ctx = snd_soc_card_get_drvdata(card);
 710        struct snd_soc_dai_link_component *idisp_components;
 711        struct snd_soc_dai_link_component *ssp_components;
 712        struct snd_soc_acpi_mach_params *mach_params;
 713        const struct snd_soc_acpi_link_adr *adr_link;
 714        struct snd_soc_dai_link_component *cpus;
 715        bool group_generated[SDW_MAX_GROUPS];
 716        int ssp_codec_index, ssp_mask;
 717        struct snd_soc_dai_link *links;
 718        int num_links, link_id = 0;
 719        char *name, *cpu_name;
 720        int total_cpu_dai_num;
 721        int sdw_cpu_dai_num;
 722        int i, j, be_id = 0;
 723        int cpu_id = 0;
 724        int comp_num;
 725        int ret;
 726
 727        /* reset amp_num to ensure amp_num++ starts from 0 in each probe */
 728        for (i = 0; i < ARRAY_SIZE(codec_info_list); i++)
 729                codec_info_list[i].amp_num = 0;
 730
 731        hdmi_num = sof_sdw_quirk & SOF_SDW_TGL_HDMI ?
 732                                SOF_TGL_HDMI_COUNT : SOF_PRE_TGL_HDMI_COUNT;
 733
 734        ssp_mask = SOF_SSP_GET_PORT(sof_sdw_quirk);
 735        /*
 736         * on generic tgl platform, I2S or sdw mode is supported
 737         * based on board rework. A ACPI device is registered in
 738         * system only when I2S mode is supported, not sdw mode.
 739         * Here check ACPI ID to confirm I2S is supported.
 740         */
 741        ssp_codec_index = find_codec_info_acpi(mach->id);
 742        ssp_num = ssp_codec_index >= 0 ? hweight_long(ssp_mask) : 0;
 743        comp_num = hdmi_num + ssp_num;
 744
 745        mach_params = &mach->mach_params;
 746        ret = get_sdw_dailink_info(mach_params->links,
 747                                   &sdw_be_num, &sdw_cpu_dai_num);
 748        if (ret < 0) {
 749                dev_err(dev, "failed to get sdw link info %d", ret);
 750                return ret;
 751        }
 752
 753        if (mach_params->codec_mask & IDISP_CODEC_MASK)
 754                ctx->idisp_codec = true;
 755
 756        /* enable dmic01 & dmic16k */
 757        dmic_num = (sof_sdw_quirk & SOF_SDW_PCH_DMIC) ? 2 : 0;
 758        comp_num += dmic_num;
 759
 760        dev_dbg(dev, "sdw %d, ssp %d, dmic %d, hdmi %d", sdw_be_num, ssp_num,
 761                dmic_num, ctx->idisp_codec ? hdmi_num : 0);
 762
 763        /* allocate BE dailinks */
 764        num_links = comp_num + sdw_be_num;
 765        links = devm_kcalloc(dev, num_links, sizeof(*links), GFP_KERNEL);
 766
 767        /* allocated CPU DAIs */
 768        total_cpu_dai_num = comp_num + sdw_cpu_dai_num;
 769        cpus = devm_kcalloc(dev, total_cpu_dai_num, sizeof(*cpus),
 770                            GFP_KERNEL);
 771
 772        if (!links || !cpus)
 773                return -ENOMEM;
 774
 775        /* SDW */
 776        if (!sdw_be_num)
 777                goto SSP;
 778
 779        adr_link = mach_params->links;
 780        if (!adr_link)
 781                return -EINVAL;
 782
 783        /*
 784         * SoundWire Slaves aggregated in the same group may be
 785         * located on different hardware links. Clear array to indicate
 786         * CPU DAIs for this group have not been generated.
 787         */
 788        for (i = 0; i < SDW_MAX_GROUPS; i++)
 789                group_generated[i] = false;
 790
 791        /* generate DAI links by each sdw link */
 792        for (; adr_link->num_adr; adr_link++) {
 793                const struct snd_soc_acpi_endpoint *endpoint;
 794
 795                endpoint = adr_link->adr_d->endpoints;
 796                if (endpoint->aggregated && !endpoint->group_id) {
 797                        dev_err(dev, "invalid group id on link %x",
 798                                adr_link->mask);
 799                        continue;
 800                }
 801
 802                /* this group has been generated */
 803                if (endpoint->aggregated &&
 804                    group_generated[endpoint->group_id])
 805                        continue;
 806
 807                ret = create_sdw_dailink(dev, &be_id, links, sdw_be_num,
 808                                         sdw_cpu_dai_num, cpus, adr_link,
 809                                         &cpu_id, group_generated);
 810                if (ret < 0) {
 811                        dev_err(dev, "failed to create dai link %d", be_id);
 812                        return -ENOMEM;
 813                }
 814        }
 815
 816        /* non-sdw DAI follows sdw DAI */
 817        link_id = be_id;
 818
 819        /* get BE ID for non-sdw DAI */
 820        be_id = get_next_be_id(links, be_id);
 821
 822SSP:
 823        /* SSP */
 824        if (!ssp_num)
 825                goto DMIC;
 826
 827        for (i = 0, j = 0; ssp_mask; i++, ssp_mask >>= 1) {
 828                struct sof_sdw_codec_info *info;
 829                int playback, capture;
 830                char *codec_name;
 831
 832                if (!(ssp_mask & 0x1))
 833                        continue;
 834
 835                name = devm_kasprintf(dev, GFP_KERNEL,
 836                                      "SSP%d-Codec", i);
 837                if (!name)
 838                        return -ENOMEM;
 839
 840                cpu_name = devm_kasprintf(dev, GFP_KERNEL, "SSP%d Pin", i);
 841                if (!cpu_name)
 842                        return -ENOMEM;
 843
 844                ssp_components = devm_kzalloc(dev, sizeof(*ssp_components),
 845                                              GFP_KERNEL);
 846                if (!ssp_components)
 847                        return -ENOMEM;
 848
 849                info = &codec_info_list[ssp_codec_index];
 850                codec_name = devm_kasprintf(dev, GFP_KERNEL, "i2c-%s:0%d",
 851                                            info->acpi_id, j++);
 852                if (!codec_name)
 853                        return -ENOMEM;
 854
 855                ssp_components->name = codec_name;
 856                ssp_components->dai_name = info->dai_name;
 857                cpus[cpu_id].dai_name = cpu_name;
 858
 859                playback = info->direction[SNDRV_PCM_STREAM_PLAYBACK];
 860                capture = info->direction[SNDRV_PCM_STREAM_CAPTURE];
 861                init_dai_link(links + link_id, be_id, name,
 862                              playback, capture,
 863                              cpus + cpu_id, 1,
 864                              ssp_components, 1,
 865                              NULL, info->ops);
 866
 867                ret = info->init(NULL, links + link_id, info, 0);
 868                if (ret < 0)
 869                        return ret;
 870
 871                INC_ID(be_id, cpu_id, link_id);
 872        }
 873
 874DMIC:
 875        /* dmic */
 876        if (dmic_num > 0) {
 877                cpus[cpu_id].dai_name = "DMIC01 Pin";
 878                init_dai_link(links + link_id, be_id, "dmic01",
 879                              0, 1, // DMIC only supports capture
 880                              cpus + cpu_id, 1,
 881                              dmic_component, 1,
 882                              sof_sdw_dmic_init, NULL);
 883                INC_ID(be_id, cpu_id, link_id);
 884
 885                cpus[cpu_id].dai_name = "DMIC16k Pin";
 886                init_dai_link(links + link_id, be_id, "dmic16k",
 887                              0, 1, // DMIC only supports capture
 888                              cpus + cpu_id, 1,
 889                              dmic_component, 1,
 890                              /* don't call sof_sdw_dmic_init() twice */
 891                              NULL, NULL);
 892                INC_ID(be_id, cpu_id, link_id);
 893        }
 894
 895        /* HDMI */
 896        if (hdmi_num > 0) {
 897                idisp_components = devm_kcalloc(dev, hdmi_num,
 898                                                sizeof(*idisp_components),
 899                                                GFP_KERNEL);
 900                if (!idisp_components)
 901                        return -ENOMEM;
 902        }
 903
 904        for (i = 0; i < hdmi_num; i++) {
 905                name = devm_kasprintf(dev, GFP_KERNEL,
 906                                      "iDisp%d", i + 1);
 907                if (!name)
 908                        return -ENOMEM;
 909
 910                if (ctx->idisp_codec) {
 911                        idisp_components[i].name = "ehdaudio0D2";
 912                        idisp_components[i].dai_name = devm_kasprintf(dev,
 913                                                                      GFP_KERNEL,
 914                                                                      "intel-hdmi-hifi%d",
 915                                                                      i + 1);
 916                        if (!idisp_components[i].dai_name)
 917                                return -ENOMEM;
 918                } else {
 919                        idisp_components[i].name = "snd-soc-dummy";
 920                        idisp_components[i].dai_name = "snd-soc-dummy-dai";
 921                }
 922
 923                cpu_name = devm_kasprintf(dev, GFP_KERNEL,
 924                                          "iDisp%d Pin", i + 1);
 925                if (!cpu_name)
 926                        return -ENOMEM;
 927
 928                cpus[cpu_id].dai_name = cpu_name;
 929                init_dai_link(links + link_id, be_id, name,
 930                              1, 0, // HDMI only supports playback
 931                              cpus + cpu_id, 1,
 932                              idisp_components + i, 1,
 933                              sof_sdw_hdmi_init, NULL);
 934                INC_ID(be_id, cpu_id, link_id);
 935        }
 936
 937        card->dai_link = links;
 938        card->num_links = num_links;
 939
 940        return 0;
 941}
 942
 943static int sof_sdw_card_late_probe(struct snd_soc_card *card)
 944{
 945        int i, ret;
 946
 947        for (i = 0; i < ARRAY_SIZE(codec_info_list); i++) {
 948                if (!codec_info_list[i].late_probe)
 949                        continue;
 950
 951                ret = codec_info_list[i].codec_card_late_probe(card);
 952                if (ret < 0)
 953                        return ret;
 954        }
 955
 956        return sof_sdw_hdmi_card_late_probe(card);
 957}
 958
 959/* SoC card */
 960static const char sdw_card_long_name[] = "Intel Soundwire SOF";
 961
 962static struct snd_soc_card card_sof_sdw = {
 963        .name = "soundwire",
 964        .owner = THIS_MODULE,
 965        .late_probe = sof_sdw_card_late_probe,
 966        .codec_conf = codec_conf,
 967        .num_configs = ARRAY_SIZE(codec_conf),
 968};
 969
 970static int mc_probe(struct platform_device *pdev)
 971{
 972        struct snd_soc_card *card = &card_sof_sdw;
 973        struct snd_soc_acpi_mach *mach;
 974        struct mc_private *ctx;
 975        int amp_num = 0, i;
 976        int ret;
 977
 978        dev_dbg(&pdev->dev, "Entry %s\n", __func__);
 979
 980        ctx = devm_kzalloc(&pdev->dev, sizeof(*ctx), GFP_KERNEL);
 981        if (!ctx)
 982                return -ENOMEM;
 983
 984        dmi_check_system(sof_sdw_quirk_table);
 985
 986        if (quirk_override != -1) {
 987                dev_info(&pdev->dev, "Overriding quirk 0x%lx => 0x%x\n",
 988                         sof_sdw_quirk, quirk_override);
 989                sof_sdw_quirk = quirk_override;
 990        }
 991        log_quirks(&pdev->dev);
 992
 993        INIT_LIST_HEAD(&ctx->hdmi_pcm_list);
 994
 995        card->dev = &pdev->dev;
 996        snd_soc_card_set_drvdata(card, ctx);
 997
 998        mach = pdev->dev.platform_data;
 999        ret = sof_card_dai_links_create(&pdev->dev, mach,
1000                                        card);
1001        if (ret < 0)
1002                return ret;
1003
1004        ctx->common_hdmi_codec_drv = mach->mach_params.common_hdmi_codec_drv;
1005
1006        /*
1007         * the default amp_num is zero for each codec and
1008         * amp_num will only be increased for active amp
1009         * codecs on used platform
1010         */
1011        for (i = 0; i < ARRAY_SIZE(codec_info_list); i++)
1012                amp_num += codec_info_list[i].amp_num;
1013
1014        card->components = devm_kasprintf(card->dev, GFP_KERNEL,
1015                                          "cfg-spk:%d cfg-amp:%d",
1016                                          (sof_sdw_quirk & SOF_SDW_FOUR_SPK)
1017                                          ? 4 : 2, amp_num);
1018        if (!card->components)
1019                return -ENOMEM;
1020
1021        card->long_name = sdw_card_long_name;
1022
1023        /* Register the card */
1024        ret = devm_snd_soc_register_card(&pdev->dev, card);
1025        if (ret) {
1026                dev_err(card->dev, "snd_soc_register_card failed %d\n", ret);
1027                return ret;
1028        }
1029
1030        platform_set_drvdata(pdev, card);
1031
1032        return ret;
1033}
1034
1035static struct platform_driver sof_sdw_driver = {
1036        .driver = {
1037                .name = "sof_sdw",
1038                .pm = &snd_soc_pm_ops,
1039        },
1040        .probe = mc_probe,
1041};
1042
1043module_platform_driver(sof_sdw_driver);
1044
1045MODULE_DESCRIPTION("ASoC SoundWire Generic Machine driver");
1046MODULE_AUTHOR("Bard Liao <yung-chuan.liao@linux.intel.com>");
1047MODULE_AUTHOR("Rander Wang <rander.wang@linux.intel.com>");
1048MODULE_AUTHOR("Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>");
1049MODULE_LICENSE("GPL v2");
1050MODULE_ALIAS("platform:sof_sdw");
1051