linux/sound/soc/fsl/imx-card.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0+
   2// Copyright 2017-2021 NXP
   3
   4#include <linux/module.h>
   5#include <linux/init.h>
   6#include <linux/slab.h>
   7#include <linux/gpio/consumer.h>
   8#include <linux/of_device.h>
   9#include <linux/i2c.h>
  10#include <linux/of_gpio.h>
  11#include <linux/clk.h>
  12#include <sound/soc.h>
  13#include <sound/pcm_params.h>
  14#include <sound/pcm.h>
  15#include <sound/soc-dapm.h>
  16#include <sound/simple_card_utils.h>
  17
  18#include "fsl_sai.h"
  19
  20enum codec_type {
  21        CODEC_DUMMY = 0,
  22        CODEC_AK5558 = 1,
  23        CODEC_AK4458,
  24        CODEC_AK4497,
  25        CODEC_AK5552,
  26};
  27
  28/*
  29 * Mapping LRCK fs and frame width, table 3 & 4 in datasheet
  30 * @rmin: min rate
  31 * @rmax: max rate
  32 * @wmin: min frame ratio
  33 * @wmax: max frame ratio
  34 */
  35struct imx_akcodec_fs_mul {
  36        unsigned int rmin;
  37        unsigned int rmax;
  38        unsigned int wmin;
  39        unsigned int wmax;
  40};
  41
  42/*
  43 * Mapping TDM mode and frame width
  44 */
  45struct imx_akcodec_tdm_fs_mul {
  46        unsigned int min;
  47        unsigned int max;
  48        unsigned int mul;
  49};
  50
  51/*
  52 * struct imx_card_plat_data - specific info for codecs
  53 *
  54 * @fs_mul: ratio of mclk/fs for normal mode
  55 * @tdm_fs_mul: ratio of mclk/fs for tdm mode
  56 * @support_rates: supported sample rate
  57 * @support_tdm_rates: supported sample rate for tdm mode
  58 * @support_channels: supported channels
  59 * @support_tdm_channels: supported channels for tdm mode
  60 * @num_fs_mul: ARRAY_SIZE of fs_mul
  61 * @num_tdm_fs_mul: ARRAY_SIZE of tdm_fs_mul
  62 * @num_rates: ARRAY_SIZE of support_rates
  63 * @num_tdm_rates: ARRAY_SIZE of support_tdm_rates
  64 * @num_channels: ARRAY_SIZE of support_channels
  65 * @num_tdm_channels: ARRAY_SIZE of support_tdm_channels
  66 * @type: codec type
  67 */
  68struct imx_card_plat_data {
  69        struct imx_akcodec_fs_mul  *fs_mul;
  70        struct imx_akcodec_tdm_fs_mul  *tdm_fs_mul;
  71        const u32 *support_rates;
  72        const u32 *support_tdm_rates;
  73        const u32 *support_channels;
  74        const u32 *support_tdm_channels;
  75        unsigned int num_fs_mul;
  76        unsigned int num_tdm_fs_mul;
  77        unsigned int num_rates;
  78        unsigned int num_tdm_rates;
  79        unsigned int num_channels;
  80        unsigned int num_tdm_channels;
  81        unsigned int num_codecs;
  82        enum codec_type type;
  83};
  84
  85/*
  86 * struct dai_link_data - specific info for dai link
  87 *
  88 * @slots: slot number
  89 * @slot_width: slot width value
  90 * @cpu_sysclk_id: sysclk id for cpu dai
  91 * @one2one_ratio: true if mclk equal to bclk
  92 */
  93struct dai_link_data {
  94        unsigned int slots;
  95        unsigned int slot_width;
  96        unsigned int cpu_sysclk_id;
  97        bool one2one_ratio;
  98};
  99
 100/*
 101 * struct imx_card_data - platform device data
 102 *
 103 * @plat_data: pointer of imx_card_plat_data
 104 * @dapm_routes: pointer of dapm_routes
 105 * @link_data: private data for dai link
 106 * @card: card instance
 107 * @num_dapm_routes: number of dapm_routes
 108 * @asrc_rate: asrc rates
 109 * @asrc_format: asrc format
 110 */
 111struct imx_card_data {
 112        struct imx_card_plat_data *plat_data;
 113        struct snd_soc_dapm_route *dapm_routes;
 114        struct dai_link_data *link_data;
 115        struct snd_soc_card card;
 116        int num_dapm_routes;
 117        u32 asrc_rate;
 118        u32 asrc_format;
 119};
 120
 121static struct imx_akcodec_fs_mul ak4458_fs_mul[] = {
 122        /* Normal, < 32kHz */
 123        { .rmin = 8000,   .rmax = 24000,  .wmin = 1024, .wmax = 1024, },
 124        /* Normal, 32kHz */
 125        { .rmin = 32000,  .rmax = 32000,  .wmin = 256,  .wmax = 1024, },
 126        /* Normal */
 127        { .rmin = 44100,  .rmax = 48000,  .wmin = 256,  .wmax = 768,  },
 128        /* Double */
 129        { .rmin = 88200,  .rmax = 96000,  .wmin = 256,  .wmax = 512,  },
 130        /* Quad */
 131        { .rmin = 176400, .rmax = 192000, .wmin = 128,  .wmax = 256,  },
 132        /* Oct */
 133        { .rmin = 352800, .rmax = 384000, .wmin = 32,   .wmax = 128,  },
 134        /* Hex */
 135        { .rmin = 705600, .rmax = 768000, .wmin = 16,   .wmax = 64,   },
 136};
 137
 138static struct imx_akcodec_tdm_fs_mul ak4458_tdm_fs_mul[] = {
 139        /*
 140         * Table 13     - Audio Interface Format
 141         * For TDM mode, MCLK should is set to
 142         * obtained from 2 * slots * slot_width
 143         */
 144        { .min = 128,   .max = 128,     .mul = 256  }, /* TDM128 */
 145        { .min = 256,   .max = 256,     .mul = 512  }, /* TDM256 */
 146        { .min = 512,   .max = 512,     .mul = 1024  }, /* TDM512 */
 147};
 148
 149static struct imx_akcodec_fs_mul ak4497_fs_mul[] = {
 150        /**
 151         * Table 7      - mapping multiplier and speed mode
 152         * Tables 8 & 9 - mapping speed mode and LRCK fs
 153         */
 154        { .rmin = 8000,   .rmax = 32000,  .wmin = 1024, .wmax = 1024, }, /* Normal, <= 32kHz */
 155        { .rmin = 44100,  .rmax = 48000,  .wmin = 512,  .wmax = 512, }, /* Normal */
 156        { .rmin = 88200,  .rmax = 96000,  .wmin = 256,  .wmax = 256, }, /* Double */
 157        { .rmin = 176400, .rmax = 192000, .wmin = 128,  .wmax = 128, }, /* Quad */
 158        { .rmin = 352800, .rmax = 384000, .wmin = 128,  .wmax = 128, }, /* Oct */
 159        { .rmin = 705600, .rmax = 768000, .wmin = 64,   .wmax = 64, }, /* Hex */
 160};
 161
 162/*
 163 * Auto MCLK selection based on LRCK for Normal Mode
 164 * (Table 4 from datasheet)
 165 */
 166static struct imx_akcodec_fs_mul ak5558_fs_mul[] = {
 167        { .rmin = 8000,   .rmax = 32000,  .wmin = 1024, .wmax = 1024, },
 168        { .rmin = 44100,  .rmax = 48000,  .wmin = 512,  .wmax = 512, },
 169        { .rmin = 88200,  .rmax = 96000,  .wmin = 256,  .wmax = 256, },
 170        { .rmin = 176400, .rmax = 192000, .wmin = 128,  .wmax = 128, },
 171        { .rmin = 352800, .rmax = 384000, .wmin = 64,   .wmax = 64, },
 172        { .rmin = 705600, .rmax = 768000, .wmin = 32,   .wmax = 32, },
 173};
 174
 175/*
 176 * MCLK and BCLK selection based on TDM mode
 177 * because of SAI we also add the restriction: MCLK >= 2 * BCLK
 178 * (Table 9 from datasheet)
 179 */
 180static struct imx_akcodec_tdm_fs_mul ak5558_tdm_fs_mul[] = {
 181        { .min = 128,   .max = 128,     .mul = 256 },
 182        { .min = 256,   .max = 256,     .mul = 512 },
 183        { .min = 512,   .max = 512,     .mul = 1024 },
 184};
 185
 186static const u32 akcodec_rates[] = {
 187        8000, 11025, 16000, 22050, 32000, 44100, 48000, 88200,
 188        96000, 176400, 192000, 352800, 384000, 705600, 768000,
 189};
 190
 191static const u32 akcodec_tdm_rates[] = {
 192        8000, 16000, 32000, 48000, 96000,
 193};
 194
 195static const u32 ak4458_channels[] = {
 196        1, 2, 4, 6, 8, 10, 12, 14, 16,
 197};
 198
 199static const u32 ak4458_tdm_channels[] = {
 200        1, 2, 3, 4, 5, 6, 7, 8, 16,
 201};
 202
 203static const u32 ak5558_channels[] = {
 204        1, 2, 4, 6, 8,
 205};
 206
 207static const u32 ak5558_tdm_channels[] = {
 208        1, 2, 3, 4, 5, 6, 7, 8,
 209};
 210
 211static bool format_is_dsd(struct snd_pcm_hw_params *params)
 212{
 213        snd_pcm_format_t format = params_format(params);
 214
 215        switch (format) {
 216        case SNDRV_PCM_FORMAT_DSD_U8:
 217        case SNDRV_PCM_FORMAT_DSD_U16_LE:
 218        case SNDRV_PCM_FORMAT_DSD_U16_BE:
 219        case SNDRV_PCM_FORMAT_DSD_U32_LE:
 220        case SNDRV_PCM_FORMAT_DSD_U32_BE:
 221                return true;
 222        default:
 223                return false;
 224        }
 225}
 226
 227static bool format_is_tdm(struct dai_link_data *link_data)
 228{
 229        if (link_data->slots > 2)
 230                return true;
 231        else
 232                return false;
 233}
 234
 235static bool codec_is_akcodec(unsigned int type)
 236{
 237        switch (type) {
 238        case CODEC_AK4458:
 239        case CODEC_AK4497:
 240        case CODEC_AK5558:
 241        case CODEC_AK5552:
 242                return true;
 243        default:
 244                break;
 245        }
 246        return false;
 247}
 248
 249static unsigned long akcodec_get_mclk_rate(struct snd_pcm_substream *substream,
 250                                           struct snd_pcm_hw_params *params)
 251{
 252        struct snd_soc_pcm_runtime *rtd = substream->private_data;
 253        struct imx_card_data *data = snd_soc_card_get_drvdata(rtd->card);
 254        const struct imx_card_plat_data *plat_data = data->plat_data;
 255        struct dai_link_data *link_data = &data->link_data[rtd->num];
 256        unsigned int width = link_data->slots * link_data->slot_width;
 257        unsigned int rate = params_rate(params);
 258        int i;
 259
 260        if (format_is_tdm(link_data)) {
 261                for (i = 0; i < plat_data->num_tdm_fs_mul; i++) {
 262                        /* min = max = slots * slots_width */
 263                        if (width != plat_data->tdm_fs_mul[i].min)
 264                                continue;
 265                        return rate * plat_data->tdm_fs_mul[i].mul;
 266                }
 267        } else {
 268                for (i = 0; i < plat_data->num_fs_mul; i++) {
 269                        if (rate >= plat_data->fs_mul[i].rmin &&
 270                            rate <= plat_data->fs_mul[i].rmax) {
 271                                width = max(width, plat_data->fs_mul[i].wmin);
 272                                width = min(width, plat_data->fs_mul[i].wmax);
 273
 274                                /* Adjust SAI bclk:mclk ratio */
 275                                width *= link_data->one2one_ratio ? 1 : 2;
 276
 277                                return rate * width;
 278                        }
 279                }
 280        }
 281
 282        /* Let DAI manage clk frequency by default */
 283        return 0;
 284}
 285
 286static int imx_aif_hw_params(struct snd_pcm_substream *substream,
 287                             struct snd_pcm_hw_params *params)
 288{
 289        struct snd_soc_pcm_runtime *rtd = substream->private_data;
 290        struct snd_soc_dai *cpu_dai = asoc_rtd_to_cpu(rtd, 0);
 291        struct snd_soc_card *card = rtd->card;
 292        struct imx_card_data *data = snd_soc_card_get_drvdata(card);
 293        struct dai_link_data *link_data = &data->link_data[rtd->num];
 294        struct imx_card_plat_data *plat_data = data->plat_data;
 295        struct device *dev = card->dev;
 296        struct snd_soc_dai *codec_dai;
 297        unsigned long mclk_freq;
 298        unsigned int fmt = rtd->dai_link->dai_fmt;
 299        unsigned int slots, slot_width;
 300        int ret, i;
 301
 302        slots = link_data->slots;
 303        slot_width = link_data->slot_width;
 304
 305        if (!format_is_tdm(link_data)) {
 306                if (format_is_dsd(params)) {
 307                        slots = 1;
 308                        slot_width = params_width(params);
 309                        fmt = (rtd->dai_link->dai_fmt & ~SND_SOC_DAIFMT_FORMAT_MASK) |
 310                              SND_SOC_DAIFMT_PDM;
 311                } else {
 312                        slots = 2;
 313                        slot_width = params_physical_width(params);
 314                        fmt = (rtd->dai_link->dai_fmt & ~SND_SOC_DAIFMT_FORMAT_MASK) |
 315                              SND_SOC_DAIFMT_I2S;
 316                }
 317        }
 318
 319        ret = snd_soc_dai_set_fmt(cpu_dai, fmt);
 320        if (ret && ret != -ENOTSUPP) {
 321                dev_err(dev, "failed to set cpu dai fmt: %d\n", ret);
 322                return ret;
 323        }
 324        ret = snd_soc_dai_set_tdm_slot(cpu_dai,
 325                                       BIT(slots) - 1,
 326                                       BIT(slots) - 1,
 327                                       slots, slot_width);
 328        if (ret && ret != -ENOTSUPP) {
 329                dev_err(dev, "failed to set cpu dai tdm slot: %d\n", ret);
 330                return ret;
 331        }
 332
 333        for_each_rtd_codec_dais(rtd, i, codec_dai) {
 334                ret = snd_soc_dai_set_fmt(codec_dai, fmt);
 335                if (ret && ret != -ENOTSUPP) {
 336                        dev_err(dev, "failed to set codec dai[%d] fmt: %d\n", i, ret);
 337                        return ret;
 338                }
 339
 340                ret = snd_soc_dai_set_tdm_slot(codec_dai,
 341                                               BIT(slots) - 1,
 342                                               BIT(slots) - 1,
 343                                               slots, slot_width);
 344                if (ret && ret != -ENOTSUPP) {
 345                        dev_err(dev, "failed to set codec dai[%d] tdm slot: %d\n", i, ret);
 346                        return ret;
 347                }
 348        }
 349
 350        /* Set MCLK freq */
 351        if (codec_is_akcodec(plat_data->type))
 352                mclk_freq = akcodec_get_mclk_rate(substream, params);
 353        else
 354                mclk_freq = params_rate(params) * slots * slot_width;
 355        /* Use the maximum freq from DSD512 (512*44100 = 22579200) */
 356        if (format_is_dsd(params))
 357                mclk_freq = 22579200;
 358
 359        ret = snd_soc_dai_set_sysclk(cpu_dai, link_data->cpu_sysclk_id, mclk_freq,
 360                                     SND_SOC_CLOCK_OUT);
 361        if (ret && ret != -ENOTSUPP) {
 362                dev_err(dev, "failed to set cpui dai mclk1 rate (%lu): %d\n", mclk_freq, ret);
 363                return ret;
 364        }
 365
 366        return 0;
 367}
 368
 369static int ak5558_hw_rule_rate(struct snd_pcm_hw_params *p, struct snd_pcm_hw_rule *r)
 370{
 371        struct dai_link_data *link_data = r->private;
 372        struct snd_interval t = { .min = 8000, .max = 8000, };
 373        unsigned long mclk_freq;
 374        unsigned int fs;
 375        int i;
 376
 377        fs = hw_param_interval(p, SNDRV_PCM_HW_PARAM_SAMPLE_BITS)->min;
 378        fs *= link_data->slots;
 379
 380        /* Identify maximum supported rate */
 381        for (i = 0; i < ARRAY_SIZE(akcodec_rates); i++) {
 382                mclk_freq = fs * akcodec_rates[i];
 383                /* Adjust SAI bclk:mclk ratio */
 384                mclk_freq *= link_data->one2one_ratio ? 1 : 2;
 385
 386                /* Skip rates for which MCLK is beyond supported value */
 387                if (mclk_freq > 36864000)
 388                        continue;
 389
 390                if (t.max < akcodec_rates[i])
 391                        t.max = akcodec_rates[i];
 392        }
 393
 394        return snd_interval_refine(hw_param_interval(p, r->var), &t);
 395}
 396
 397static int imx_aif_startup(struct snd_pcm_substream *substream)
 398{
 399        struct snd_pcm_runtime *runtime = substream->runtime;
 400        struct snd_soc_pcm_runtime *rtd = substream->private_data;
 401        struct snd_soc_card *card = rtd->card;
 402        struct imx_card_data *data = snd_soc_card_get_drvdata(card);
 403        struct dai_link_data *link_data = &data->link_data[rtd->num];
 404        static struct snd_pcm_hw_constraint_list constraint_rates;
 405        static struct snd_pcm_hw_constraint_list constraint_channels;
 406        int ret = 0;
 407
 408        if (format_is_tdm(link_data)) {
 409                constraint_channels.list = data->plat_data->support_tdm_channels;
 410                constraint_channels.count = data->plat_data->num_tdm_channels;
 411                constraint_rates.list = data->plat_data->support_tdm_rates;
 412                constraint_rates.count = data->plat_data->num_tdm_rates;
 413        } else {
 414                constraint_channels.list = data->plat_data->support_channels;
 415                constraint_channels.count = data->plat_data->num_channels;
 416                constraint_rates.list = data->plat_data->support_rates;
 417                constraint_rates.count = data->plat_data->num_rates;
 418        }
 419
 420        if (constraint_channels.count) {
 421                ret = snd_pcm_hw_constraint_list(runtime, 0,
 422                                                 SNDRV_PCM_HW_PARAM_CHANNELS,
 423                                                 &constraint_channels);
 424                if (ret)
 425                        return ret;
 426        }
 427
 428        if (constraint_rates.count) {
 429                ret = snd_pcm_hw_constraint_list(runtime, 0,
 430                                                 SNDRV_PCM_HW_PARAM_RATE,
 431                                                 &constraint_rates);
 432                if (ret)
 433                        return ret;
 434        }
 435
 436        if (data->plat_data->type == CODEC_AK5558)
 437                ret = snd_pcm_hw_rule_add(substream->runtime, 0,
 438                                          SNDRV_PCM_HW_PARAM_RATE,
 439                                          ak5558_hw_rule_rate, link_data,
 440                                          SNDRV_PCM_HW_PARAM_SAMPLE_BITS, -1);
 441
 442        return ret;
 443}
 444
 445static struct snd_soc_ops imx_aif_ops = {
 446        .hw_params = imx_aif_hw_params,
 447        .startup = imx_aif_startup,
 448};
 449
 450static struct snd_soc_ops imx_aif_ops_be = {
 451        .hw_params = imx_aif_hw_params,
 452};
 453
 454static int be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd,
 455                              struct snd_pcm_hw_params *params)
 456{
 457        struct snd_soc_card *card = rtd->card;
 458        struct imx_card_data *data = snd_soc_card_get_drvdata(card);
 459        struct snd_interval *rate;
 460        struct snd_mask *mask;
 461
 462        rate = hw_param_interval(params, SNDRV_PCM_HW_PARAM_RATE);
 463        rate->max = data->asrc_rate;
 464        rate->min = data->asrc_rate;
 465
 466        mask = hw_param_mask(params, SNDRV_PCM_HW_PARAM_FORMAT);
 467        snd_mask_none(mask);
 468        snd_mask_set(mask, data->asrc_format);
 469
 470        return 0;
 471}
 472
 473static int imx_card_parse_of(struct imx_card_data *data)
 474{
 475        struct imx_card_plat_data *plat_data = data->plat_data;
 476        struct snd_soc_card *card = &data->card;
 477        struct snd_soc_dai_link_component *dlc;
 478        struct device_node *platform = NULL;
 479        struct device_node *codec = NULL;
 480        struct device_node *cpu = NULL;
 481        struct device_node *np;
 482        struct device *dev = card->dev;
 483        struct snd_soc_dai_link *link;
 484        struct dai_link_data *link_data;
 485        struct of_phandle_args args;
 486        int ret, num_links;
 487        u32 width;
 488
 489        ret = snd_soc_of_parse_card_name(card, "model");
 490        if (ret) {
 491                dev_err(dev, "Error parsing card name: %d\n", ret);
 492                return ret;
 493        }
 494
 495        /* DAPM routes */
 496        if (of_property_read_bool(dev->of_node, "audio-routing")) {
 497                ret = snd_soc_of_parse_audio_routing(card, "audio-routing");
 498                if (ret)
 499                        return ret;
 500        }
 501
 502        /* Populate links */
 503        num_links = of_get_child_count(dev->of_node);
 504
 505        /* Allocate the DAI link array */
 506        card->dai_link = devm_kcalloc(dev, num_links, sizeof(*link), GFP_KERNEL);
 507        if (!card->dai_link)
 508                return -ENOMEM;
 509
 510        data->link_data = devm_kcalloc(dev, num_links, sizeof(*link), GFP_KERNEL);
 511        if (!data->link_data)
 512                return -ENOMEM;
 513
 514        card->num_links = num_links;
 515        link = card->dai_link;
 516        link_data = data->link_data;
 517
 518        for_each_child_of_node(dev->of_node, np) {
 519                dlc = devm_kzalloc(dev, 2 * sizeof(*dlc), GFP_KERNEL);
 520                if (!dlc) {
 521                        ret = -ENOMEM;
 522                        goto err_put_np;
 523                }
 524
 525                link->cpus      = &dlc[0];
 526                link->platforms = &dlc[1];
 527
 528                link->num_cpus          = 1;
 529                link->num_platforms     = 1;
 530
 531                ret = of_property_read_string(np, "link-name", &link->name);
 532                if (ret) {
 533                        dev_err(card->dev, "error getting codec dai_link name\n");
 534                        goto err_put_np;
 535                }
 536
 537                cpu = of_get_child_by_name(np, "cpu");
 538                if (!cpu) {
 539                        dev_err(dev, "%s: Can't find cpu DT node\n", link->name);
 540                        ret = -EINVAL;
 541                        goto err;
 542                }
 543
 544                ret = of_parse_phandle_with_args(cpu, "sound-dai",
 545                                                 "#sound-dai-cells", 0, &args);
 546                if (ret) {
 547                        dev_err(card->dev, "%s: error getting cpu phandle\n", link->name);
 548                        goto err;
 549                }
 550
 551                if (of_node_name_eq(args.np, "sai")) {
 552                        /* sai sysclk id */
 553                        link_data->cpu_sysclk_id = FSL_SAI_CLK_MAST1;
 554
 555                        /* sai may support mclk/bclk = 1 */
 556                        if (of_find_property(np, "fsl,mclk-equal-bclk", NULL))
 557                                link_data->one2one_ratio = true;
 558                }
 559
 560                link->cpus->of_node = args.np;
 561                link->platforms->of_node = link->cpus->of_node;
 562                link->id = args.args[0];
 563
 564                ret = snd_soc_of_get_dai_name(cpu, &link->cpus->dai_name);
 565                if (ret) {
 566                        if (ret != -EPROBE_DEFER)
 567                                dev_err(card->dev, "%s: error getting cpu dai name: %d\n",
 568                                        link->name, ret);
 569                        goto err;
 570                }
 571
 572                codec = of_get_child_by_name(np, "codec");
 573                if (codec) {
 574                        ret = snd_soc_of_get_dai_link_codecs(dev, codec, link);
 575                        if (ret < 0) {
 576                                if (ret != -EPROBE_DEFER)
 577                                        dev_err(dev, "%s: codec dai not found: %d\n",
 578                                                link->name, ret);
 579                                goto err;
 580                        }
 581
 582                        plat_data->num_codecs = link->num_codecs;
 583
 584                        /* Check the akcodec type */
 585                        if (!strcmp(link->codecs->dai_name, "ak4458-aif"))
 586                                plat_data->type = CODEC_AK4458;
 587                        else if (!strcmp(link->codecs->dai_name, "ak4497-aif"))
 588                                plat_data->type = CODEC_AK4497;
 589                        else if (!strcmp(link->codecs->dai_name, "ak5558-aif"))
 590                                plat_data->type = CODEC_AK5558;
 591                        else if (!strcmp(link->codecs->dai_name, "ak5552-aif"))
 592                                plat_data->type = CODEC_AK5552;
 593
 594                } else {
 595                        dlc = devm_kzalloc(dev, sizeof(*dlc), GFP_KERNEL);
 596                        if (!dlc) {
 597                                ret = -ENOMEM;
 598                                goto err;
 599                        }
 600
 601                        link->codecs     = dlc;
 602                        link->num_codecs = 1;
 603
 604                        link->codecs->dai_name = "snd-soc-dummy-dai";
 605                        link->codecs->name = "snd-soc-dummy";
 606                }
 607
 608                if (!strncmp(link->name, "HiFi-ASRC-FE", 12)) {
 609                        /* DPCM frontend */
 610                        link->dynamic = 1;
 611                        link->dpcm_merged_chan = 1;
 612
 613                        ret = of_property_read_u32(args.np, "fsl,asrc-rate", &data->asrc_rate);
 614                        if (ret) {
 615                                dev_err(dev, "failed to get output rate\n");
 616                                ret = -EINVAL;
 617                                goto err;
 618                        }
 619
 620                        ret = of_property_read_u32(args.np, "fsl,asrc-format", &data->asrc_format);
 621                        if (ret) {
 622                                /* Fallback to old binding; translate to asrc_format */
 623                                ret = of_property_read_u32(args.np, "fsl,asrc-width", &width);
 624                                if (ret) {
 625                                        dev_err(dev,
 626                                                "failed to decide output format\n");
 627                                        goto err;
 628                                }
 629
 630                                if (width == 24)
 631                                        data->asrc_format = SNDRV_PCM_FORMAT_S24_LE;
 632                                else
 633                                        data->asrc_format = SNDRV_PCM_FORMAT_S16_LE;
 634                        }
 635                } else if (!strncmp(link->name, "HiFi-ASRC-BE", 12)) {
 636                        /* DPCM backend */
 637                        link->no_pcm = 1;
 638                        link->platforms->of_node = NULL;
 639                        link->platforms->name = "snd-soc-dummy";
 640
 641                        link->be_hw_params_fixup = be_hw_params_fixup;
 642                        link->ops = &imx_aif_ops_be;
 643                } else {
 644                        link->ops = &imx_aif_ops;
 645                }
 646
 647                if (link->no_pcm || link->dynamic)
 648                        snd_soc_dai_link_set_capabilities(link);
 649
 650                /* Get dai fmt */
 651                ret = asoc_simple_parse_daifmt(dev, np, codec,
 652                                               NULL, &link->dai_fmt);
 653                if (ret)
 654                        link->dai_fmt = SND_SOC_DAIFMT_NB_NF |
 655                                        SND_SOC_DAIFMT_CBS_CFS |
 656                                        SND_SOC_DAIFMT_I2S;
 657
 658                /* Get tdm slot */
 659                snd_soc_of_parse_tdm_slot(np, NULL, NULL,
 660                                          &link_data->slots,
 661                                          &link_data->slot_width);
 662                /* default value */
 663                if (!link_data->slots)
 664                        link_data->slots = 2;
 665
 666                if (!link_data->slot_width)
 667                        link_data->slot_width = 32;
 668
 669                link->ignore_pmdown_time = 1;
 670                link->stream_name = link->name;
 671                link++;
 672                link_data++;
 673
 674                of_node_put(cpu);
 675                of_node_put(codec);
 676                of_node_put(platform);
 677        }
 678
 679        return 0;
 680err:
 681        of_node_put(cpu);
 682        of_node_put(codec);
 683        of_node_put(platform);
 684err_put_np:
 685        of_node_put(np);
 686        return ret;
 687}
 688
 689static int imx_card_probe(struct platform_device *pdev)
 690{
 691        struct snd_soc_dai_link *link_be = NULL, *link;
 692        struct imx_card_plat_data *plat_data;
 693        struct imx_card_data *data;
 694        int ret, i;
 695
 696        data = devm_kzalloc(&pdev->dev, sizeof(*data), GFP_KERNEL);
 697        if (!data)
 698                return -ENOMEM;
 699
 700        plat_data = devm_kzalloc(&pdev->dev, sizeof(*plat_data), GFP_KERNEL);
 701        if (!plat_data)
 702                return -ENOMEM;
 703
 704        data->plat_data = plat_data;
 705        data->card.dev = &pdev->dev;
 706
 707        dev_set_drvdata(&pdev->dev, &data->card);
 708        snd_soc_card_set_drvdata(&data->card, data);
 709        ret = imx_card_parse_of(data);
 710        if (ret)
 711                return ret;
 712
 713        data->num_dapm_routes = plat_data->num_codecs + 1;
 714        data->dapm_routes = devm_kcalloc(&pdev->dev, data->num_dapm_routes,
 715                                         sizeof(struct snd_soc_dapm_route),
 716                                         GFP_KERNEL);
 717        if (!data->dapm_routes)
 718                return -ENOMEM;
 719
 720        /* configure the dapm routes */
 721        switch (plat_data->type) {
 722        case CODEC_AK4458:
 723        case CODEC_AK4497:
 724                if (plat_data->num_codecs == 1) {
 725                        data->dapm_routes[0].sink = "Playback";
 726                        data->dapm_routes[0].source = "CPU-Playback";
 727                        i = 1;
 728                } else {
 729                        for (i = 0; i < plat_data->num_codecs; i++) {
 730                                data->dapm_routes[i].sink =
 731                                        devm_kasprintf(&pdev->dev, GFP_KERNEL, "%d %s",
 732                                                       i + 1, "Playback");
 733                                data->dapm_routes[i].source = "CPU-Playback";
 734                        }
 735                }
 736                data->dapm_routes[i].sink = "CPU-Playback";
 737                data->dapm_routes[i].source = "ASRC-Playback";
 738                break;
 739        case CODEC_AK5558:
 740        case CODEC_AK5552:
 741                if (plat_data->num_codecs == 1) {
 742                        data->dapm_routes[0].sink = "CPU-Capture";
 743                        data->dapm_routes[0].source = "Capture";
 744                        i = 1;
 745                } else {
 746                        for (i = 0; i < plat_data->num_codecs; i++) {
 747                                data->dapm_routes[i].source =
 748                                        devm_kasprintf(&pdev->dev, GFP_KERNEL, "%d %s",
 749                                                       i + 1, "Capture");
 750                                data->dapm_routes[i].sink = "CPU-Capture";
 751                        }
 752                }
 753                data->dapm_routes[i].sink = "ASRC-Capture";
 754                data->dapm_routes[i].source = "CPU-Capture";
 755                break;
 756        default:
 757                break;
 758        }
 759
 760        /* default platform data for akcodecs */
 761        if (codec_is_akcodec(plat_data->type)) {
 762                plat_data->support_rates = akcodec_rates;
 763                plat_data->num_rates = ARRAY_SIZE(akcodec_rates);
 764                plat_data->support_tdm_rates = akcodec_tdm_rates;
 765                plat_data->num_tdm_rates = ARRAY_SIZE(akcodec_tdm_rates);
 766
 767                switch (plat_data->type) {
 768                case CODEC_AK4458:
 769                        plat_data->fs_mul = ak4458_fs_mul;
 770                        plat_data->num_fs_mul = ARRAY_SIZE(ak4458_fs_mul);
 771                        plat_data->tdm_fs_mul = ak4458_tdm_fs_mul;
 772                        plat_data->num_tdm_fs_mul = ARRAY_SIZE(ak4458_tdm_fs_mul);
 773                        plat_data->support_channels = ak4458_channels;
 774                        plat_data->num_channels = ARRAY_SIZE(ak4458_channels);
 775                        plat_data->support_tdm_channels = ak4458_tdm_channels;
 776                        plat_data->num_tdm_channels = ARRAY_SIZE(ak4458_tdm_channels);
 777                        break;
 778                case CODEC_AK4497:
 779                        plat_data->fs_mul = ak4497_fs_mul;
 780                        plat_data->num_fs_mul = ARRAY_SIZE(ak4497_fs_mul);
 781                        plat_data->support_channels = ak4458_channels;
 782                        plat_data->num_channels = ARRAY_SIZE(ak4458_channels);
 783                        break;
 784                case CODEC_AK5558:
 785                case CODEC_AK5552:
 786                        plat_data->fs_mul = ak5558_fs_mul;
 787                        plat_data->num_fs_mul = ARRAY_SIZE(ak5558_fs_mul);
 788                        plat_data->tdm_fs_mul = ak5558_tdm_fs_mul;
 789                        plat_data->num_tdm_fs_mul = ARRAY_SIZE(ak5558_tdm_fs_mul);
 790                        plat_data->support_channels = ak5558_channels;
 791                        plat_data->num_channels = ARRAY_SIZE(ak5558_channels);
 792                        plat_data->support_tdm_channels = ak5558_tdm_channels;
 793                        plat_data->num_tdm_channels = ARRAY_SIZE(ak5558_tdm_channels);
 794                        break;
 795                default:
 796                        break;
 797                }
 798        }
 799
 800        /* with asrc as front end */
 801        if (data->card.num_links == 3) {
 802                data->card.dapm_routes = data->dapm_routes;
 803                data->card.num_dapm_routes = data->num_dapm_routes;
 804                for_each_card_prelinks(&data->card, i, link) {
 805                        if (link->no_pcm == 1)
 806                                link_be = link;
 807                }
 808                for_each_card_prelinks(&data->card, i, link) {
 809                        if (link->dynamic == 1 && link_be) {
 810                                link->dpcm_playback = link_be->dpcm_playback;
 811                                link->dpcm_capture = link_be->dpcm_capture;
 812                        }
 813                }
 814        }
 815
 816        ret = devm_snd_soc_register_card(&pdev->dev, &data->card);
 817        if (ret) {
 818                if (ret != -EPROBE_DEFER)
 819                        dev_err(&pdev->dev, "snd_soc_register_card failed (%d)\n", ret);
 820                return ret;
 821        }
 822
 823        return 0;
 824}
 825
 826static const struct of_device_id imx_card_dt_ids[] = {
 827        { .compatible = "fsl,imx-audio-card", },
 828        { },
 829};
 830MODULE_DEVICE_TABLE(of, imx_card_dt_ids);
 831
 832static struct platform_driver imx_card_driver = {
 833        .driver = {
 834                .name = "imx-card",
 835                .pm = &snd_soc_pm_ops,
 836                .of_match_table = imx_card_dt_ids,
 837        },
 838        .probe = imx_card_probe,
 839};
 840module_platform_driver(imx_card_driver);
 841
 842MODULE_DESCRIPTION("Freescale i.MX ASoC Machine Driver");
 843MODULE_LICENSE("GPL v2");
 844MODULE_ALIAS("platform:imx-card");
 845