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 = 256,  .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 = 256,  .wmax = 1024, }, /* Normal, <= 32kHz */
 155        { .rmin = 44100,  .rmax = 48000,  .wmin = 256,  .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 = 512,  .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                                           int slots, int slot_width)
 252{
 253        struct snd_soc_pcm_runtime *rtd = substream->private_data;
 254        struct imx_card_data *data = snd_soc_card_get_drvdata(rtd->card);
 255        const struct imx_card_plat_data *plat_data = data->plat_data;
 256        struct dai_link_data *link_data = &data->link_data[rtd->num];
 257        unsigned int width = slots * slot_width;
 258        unsigned int rate = params_rate(params);
 259        int i;
 260
 261        if (format_is_tdm(link_data)) {
 262                for (i = 0; i < plat_data->num_tdm_fs_mul; i++) {
 263                        /* min = max = slots * slots_width */
 264                        if (width != plat_data->tdm_fs_mul[i].min)
 265                                continue;
 266                        return rate * plat_data->tdm_fs_mul[i].mul;
 267                }
 268        } else {
 269                for (i = 0; i < plat_data->num_fs_mul; i++) {
 270                        if (rate >= plat_data->fs_mul[i].rmin &&
 271                            rate <= plat_data->fs_mul[i].rmax) {
 272                                width = max(width, plat_data->fs_mul[i].wmin);
 273                                width = min(width, plat_data->fs_mul[i].wmax);
 274
 275                                /* Adjust SAI bclk:mclk ratio */
 276                                width *= link_data->one2one_ratio ? 1 : 2;
 277
 278                                return rate * width;
 279                        }
 280                }
 281        }
 282
 283        /* Let DAI manage clk frequency by default */
 284        return 0;
 285}
 286
 287static int imx_aif_hw_params(struct snd_pcm_substream *substream,
 288                             struct snd_pcm_hw_params *params)
 289{
 290        struct snd_soc_pcm_runtime *rtd = substream->private_data;
 291        struct snd_soc_dai *cpu_dai = asoc_rtd_to_cpu(rtd, 0);
 292        struct snd_soc_card *card = rtd->card;
 293        struct imx_card_data *data = snd_soc_card_get_drvdata(card);
 294        struct dai_link_data *link_data = &data->link_data[rtd->num];
 295        struct imx_card_plat_data *plat_data = data->plat_data;
 296        struct device *dev = card->dev;
 297        struct snd_soc_dai *codec_dai;
 298        unsigned long mclk_freq;
 299        unsigned int fmt = rtd->dai_link->dai_fmt;
 300        unsigned int slots, slot_width;
 301        int ret, i;
 302
 303        slots = link_data->slots;
 304        slot_width = link_data->slot_width;
 305
 306        if (!format_is_tdm(link_data)) {
 307                if (format_is_dsd(params)) {
 308                        slots = 1;
 309                        slot_width = params_width(params);
 310                        fmt = (rtd->dai_link->dai_fmt & ~SND_SOC_DAIFMT_FORMAT_MASK) |
 311                              SND_SOC_DAIFMT_PDM;
 312                } else {
 313                        slots = 2;
 314                        slot_width = params_physical_width(params);
 315                        fmt = (rtd->dai_link->dai_fmt & ~SND_SOC_DAIFMT_FORMAT_MASK) |
 316                              SND_SOC_DAIFMT_I2S;
 317                }
 318        }
 319
 320        ret = snd_soc_dai_set_fmt(cpu_dai, fmt);
 321        if (ret && ret != -ENOTSUPP) {
 322                dev_err(dev, "failed to set cpu dai fmt: %d\n", ret);
 323                return ret;
 324        }
 325        ret = snd_soc_dai_set_tdm_slot(cpu_dai,
 326                                       BIT(slots) - 1,
 327                                       BIT(slots) - 1,
 328                                       slots, slot_width);
 329        if (ret && ret != -ENOTSUPP) {
 330                dev_err(dev, "failed to set cpu dai tdm slot: %d\n", ret);
 331                return ret;
 332        }
 333
 334        for_each_rtd_codec_dais(rtd, i, codec_dai) {
 335                ret = snd_soc_dai_set_fmt(codec_dai, fmt);
 336                if (ret && ret != -ENOTSUPP) {
 337                        dev_err(dev, "failed to set codec dai[%d] fmt: %d\n", i, ret);
 338                        return ret;
 339                }
 340
 341                ret = snd_soc_dai_set_tdm_slot(codec_dai,
 342                                               BIT(slots) - 1,
 343                                               BIT(slots) - 1,
 344                                               slots, slot_width);
 345                if (ret && ret != -ENOTSUPP) {
 346                        dev_err(dev, "failed to set codec dai[%d] tdm slot: %d\n", i, ret);
 347                        return ret;
 348                }
 349        }
 350
 351        /* Set MCLK freq */
 352        if (codec_is_akcodec(plat_data->type))
 353                mclk_freq = akcodec_get_mclk_rate(substream, params, slots, slot_width);
 354        else
 355                mclk_freq = params_rate(params) * slots * slot_width;
 356        /* Use the maximum freq from DSD512 (512*44100 = 22579200) */
 357        if (format_is_dsd(params))
 358                mclk_freq = 22579200;
 359
 360        ret = snd_soc_dai_set_sysclk(cpu_dai, link_data->cpu_sysclk_id, mclk_freq,
 361                                     SND_SOC_CLOCK_OUT);
 362        if (ret && ret != -ENOTSUPP) {
 363                dev_err(dev, "failed to set cpui dai mclk1 rate (%lu): %d\n", mclk_freq, ret);
 364                return ret;
 365        }
 366
 367        return 0;
 368}
 369
 370static int ak5558_hw_rule_rate(struct snd_pcm_hw_params *p, struct snd_pcm_hw_rule *r)
 371{
 372        struct dai_link_data *link_data = r->private;
 373        struct snd_interval t = { .min = 8000, .max = 8000, };
 374        unsigned long mclk_freq;
 375        unsigned int fs;
 376        int i;
 377
 378        fs = hw_param_interval(p, SNDRV_PCM_HW_PARAM_SAMPLE_BITS)->min;
 379        fs *= link_data->slots;
 380
 381        /* Identify maximum supported rate */
 382        for (i = 0; i < ARRAY_SIZE(akcodec_rates); i++) {
 383                mclk_freq = fs * akcodec_rates[i];
 384                /* Adjust SAI bclk:mclk ratio */
 385                mclk_freq *= link_data->one2one_ratio ? 1 : 2;
 386
 387                /* Skip rates for which MCLK is beyond supported value */
 388                if (mclk_freq > 36864000)
 389                        continue;
 390
 391                if (t.max < akcodec_rates[i])
 392                        t.max = akcodec_rates[i];
 393        }
 394
 395        return snd_interval_refine(hw_param_interval(p, r->var), &t);
 396}
 397
 398static int imx_aif_startup(struct snd_pcm_substream *substream)
 399{
 400        struct snd_pcm_runtime *runtime = substream->runtime;
 401        struct snd_soc_pcm_runtime *rtd = substream->private_data;
 402        struct snd_soc_card *card = rtd->card;
 403        struct imx_card_data *data = snd_soc_card_get_drvdata(card);
 404        struct dai_link_data *link_data = &data->link_data[rtd->num];
 405        static struct snd_pcm_hw_constraint_list constraint_rates;
 406        static struct snd_pcm_hw_constraint_list constraint_channels;
 407        int ret = 0;
 408
 409        if (format_is_tdm(link_data)) {
 410                constraint_channels.list = data->plat_data->support_tdm_channels;
 411                constraint_channels.count = data->plat_data->num_tdm_channels;
 412                constraint_rates.list = data->plat_data->support_tdm_rates;
 413                constraint_rates.count = data->plat_data->num_tdm_rates;
 414        } else {
 415                constraint_channels.list = data->plat_data->support_channels;
 416                constraint_channels.count = data->plat_data->num_channels;
 417                constraint_rates.list = data->plat_data->support_rates;
 418                constraint_rates.count = data->plat_data->num_rates;
 419        }
 420
 421        if (constraint_channels.count) {
 422                ret = snd_pcm_hw_constraint_list(runtime, 0,
 423                                                 SNDRV_PCM_HW_PARAM_CHANNELS,
 424                                                 &constraint_channels);
 425                if (ret)
 426                        return ret;
 427        }
 428
 429        if (constraint_rates.count) {
 430                ret = snd_pcm_hw_constraint_list(runtime, 0,
 431                                                 SNDRV_PCM_HW_PARAM_RATE,
 432                                                 &constraint_rates);
 433                if (ret)
 434                        return ret;
 435        }
 436
 437        if (data->plat_data->type == CODEC_AK5558)
 438                ret = snd_pcm_hw_rule_add(substream->runtime, 0,
 439                                          SNDRV_PCM_HW_PARAM_RATE,
 440                                          ak5558_hw_rule_rate, link_data,
 441                                          SNDRV_PCM_HW_PARAM_SAMPLE_BITS, -1);
 442
 443        return ret;
 444}
 445
 446static const struct snd_soc_ops imx_aif_ops = {
 447        .hw_params = imx_aif_hw_params,
 448        .startup = imx_aif_startup,
 449};
 450
 451static const struct snd_soc_ops imx_aif_ops_be = {
 452        .hw_params = imx_aif_hw_params,
 453};
 454
 455static int be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd,
 456                              struct snd_pcm_hw_params *params)
 457{
 458        struct snd_soc_card *card = rtd->card;
 459        struct imx_card_data *data = snd_soc_card_get_drvdata(card);
 460        struct snd_interval *rate;
 461        struct snd_mask *mask;
 462
 463        rate = hw_param_interval(params, SNDRV_PCM_HW_PARAM_RATE);
 464        rate->max = data->asrc_rate;
 465        rate->min = data->asrc_rate;
 466
 467        mask = hw_param_mask(params, SNDRV_PCM_HW_PARAM_FORMAT);
 468        snd_mask_none(mask);
 469        snd_mask_set(mask, data->asrc_format);
 470
 471        return 0;
 472}
 473
 474static int imx_card_parse_of(struct imx_card_data *data)
 475{
 476        struct imx_card_plat_data *plat_data = data->plat_data;
 477        struct snd_soc_card *card = &data->card;
 478        struct snd_soc_dai_link_component *dlc;
 479        struct device_node *platform = NULL;
 480        struct device_node *codec = NULL;
 481        struct device_node *cpu = NULL;
 482        struct device_node *np;
 483        struct device *dev = card->dev;
 484        struct snd_soc_dai_link *link;
 485        struct dai_link_data *link_data;
 486        struct of_phandle_args args;
 487        int ret, num_links;
 488        u32 width;
 489
 490        ret = snd_soc_of_parse_card_name(card, "model");
 491        if (ret) {
 492                dev_err(dev, "Error parsing card name: %d\n", ret);
 493                return ret;
 494        }
 495
 496        /* DAPM routes */
 497        if (of_property_read_bool(dev->of_node, "audio-routing")) {
 498                ret = snd_soc_of_parse_audio_routing(card, "audio-routing");
 499                if (ret)
 500                        return ret;
 501        }
 502
 503        /* Populate links */
 504        num_links = of_get_child_count(dev->of_node);
 505
 506        /* Allocate the DAI link array */
 507        card->dai_link = devm_kcalloc(dev, num_links, sizeof(*link), GFP_KERNEL);
 508        if (!card->dai_link)
 509                return -ENOMEM;
 510
 511        data->link_data = devm_kcalloc(dev, num_links, sizeof(*link), GFP_KERNEL);
 512        if (!data->link_data)
 513                return -ENOMEM;
 514
 515        card->num_links = num_links;
 516        link = card->dai_link;
 517        link_data = data->link_data;
 518
 519        for_each_child_of_node(dev->of_node, np) {
 520                dlc = devm_kzalloc(dev, 2 * sizeof(*dlc), GFP_KERNEL);
 521                if (!dlc) {
 522                        ret = -ENOMEM;
 523                        goto err_put_np;
 524                }
 525
 526                link->cpus      = &dlc[0];
 527                link->platforms = &dlc[1];
 528
 529                link->num_cpus          = 1;
 530                link->num_platforms     = 1;
 531
 532                ret = of_property_read_string(np, "link-name", &link->name);
 533                if (ret) {
 534                        dev_err(card->dev, "error getting codec dai_link name\n");
 535                        goto err_put_np;
 536                }
 537
 538                cpu = of_get_child_by_name(np, "cpu");
 539                if (!cpu) {
 540                        dev_err(dev, "%s: Can't find cpu DT node\n", link->name);
 541                        ret = -EINVAL;
 542                        goto err;
 543                }
 544
 545                ret = of_parse_phandle_with_args(cpu, "sound-dai",
 546                                                 "#sound-dai-cells", 0, &args);
 547                if (ret) {
 548                        dev_err(card->dev, "%s: error getting cpu phandle\n", link->name);
 549                        goto err;
 550                }
 551
 552                if (of_node_name_eq(args.np, "sai")) {
 553                        /* sai sysclk id */
 554                        link_data->cpu_sysclk_id = FSL_SAI_CLK_MAST1;
 555
 556                        /* sai may support mclk/bclk = 1 */
 557                        if (of_find_property(np, "fsl,mclk-equal-bclk", NULL)) {
 558                                link_data->one2one_ratio = true;
 559                        } else {
 560                                int i;
 561
 562                                /*
 563                                 * i.MX8MQ don't support one2one ratio, then
 564                                 * with ak4497 only 16bit case is supported.
 565                                 */
 566                                for (i = 0; i < ARRAY_SIZE(ak4497_fs_mul); i++) {
 567                                        if (ak4497_fs_mul[i].rmin == 705600 &&
 568                                            ak4497_fs_mul[i].rmax == 768000) {
 569                                                ak4497_fs_mul[i].wmin = 32;
 570                                                ak4497_fs_mul[i].wmax = 32;
 571                                        }
 572                                }
 573                        }
 574                }
 575
 576                link->cpus->of_node = args.np;
 577                link->platforms->of_node = link->cpus->of_node;
 578                link->id = args.args[0];
 579
 580                ret = snd_soc_of_get_dai_name(cpu, &link->cpus->dai_name);
 581                if (ret) {
 582                        dev_err_probe(card->dev, ret,
 583                                      "%s: error getting cpu dai name\n", link->name);
 584                        goto err;
 585                }
 586
 587                codec = of_get_child_by_name(np, "codec");
 588                if (codec) {
 589                        ret = snd_soc_of_get_dai_link_codecs(dev, codec, link);
 590                        if (ret < 0) {
 591                                dev_err_probe(dev, ret, "%s: codec dai not found\n",
 592                                                link->name);
 593                                goto err;
 594                        }
 595
 596                        plat_data->num_codecs = link->num_codecs;
 597
 598                        /* Check the akcodec type */
 599                        if (!strcmp(link->codecs->dai_name, "ak4458-aif"))
 600                                plat_data->type = CODEC_AK4458;
 601                        else if (!strcmp(link->codecs->dai_name, "ak4497-aif"))
 602                                plat_data->type = CODEC_AK4497;
 603                        else if (!strcmp(link->codecs->dai_name, "ak5558-aif"))
 604                                plat_data->type = CODEC_AK5558;
 605                        else if (!strcmp(link->codecs->dai_name, "ak5552-aif"))
 606                                plat_data->type = CODEC_AK5552;
 607
 608                } else {
 609                        dlc = devm_kzalloc(dev, sizeof(*dlc), GFP_KERNEL);
 610                        if (!dlc) {
 611                                ret = -ENOMEM;
 612                                goto err;
 613                        }
 614
 615                        link->codecs     = dlc;
 616                        link->num_codecs = 1;
 617
 618                        link->codecs->dai_name = "snd-soc-dummy-dai";
 619                        link->codecs->name = "snd-soc-dummy";
 620                }
 621
 622                if (!strncmp(link->name, "HiFi-ASRC-FE", 12)) {
 623                        /* DPCM frontend */
 624                        link->dynamic = 1;
 625                        link->dpcm_merged_chan = 1;
 626
 627                        ret = of_property_read_u32(args.np, "fsl,asrc-rate", &data->asrc_rate);
 628                        if (ret) {
 629                                dev_err(dev, "failed to get output rate\n");
 630                                ret = -EINVAL;
 631                                goto err;
 632                        }
 633
 634                        ret = of_property_read_u32(args.np, "fsl,asrc-format", &data->asrc_format);
 635                        if (ret) {
 636                                /* Fallback to old binding; translate to asrc_format */
 637                                ret = of_property_read_u32(args.np, "fsl,asrc-width", &width);
 638                                if (ret) {
 639                                        dev_err(dev,
 640                                                "failed to decide output format\n");
 641                                        goto err;
 642                                }
 643
 644                                if (width == 24)
 645                                        data->asrc_format = SNDRV_PCM_FORMAT_S24_LE;
 646                                else
 647                                        data->asrc_format = SNDRV_PCM_FORMAT_S16_LE;
 648                        }
 649                } else if (!strncmp(link->name, "HiFi-ASRC-BE", 12)) {
 650                        /* DPCM backend */
 651                        link->no_pcm = 1;
 652                        link->platforms->of_node = NULL;
 653                        link->platforms->name = "snd-soc-dummy";
 654
 655                        link->be_hw_params_fixup = be_hw_params_fixup;
 656                        link->ops = &imx_aif_ops_be;
 657                } else {
 658                        link->ops = &imx_aif_ops;
 659                }
 660
 661                if (link->no_pcm || link->dynamic)
 662                        snd_soc_dai_link_set_capabilities(link);
 663
 664                /* Get dai fmt */
 665                ret = asoc_simple_parse_daifmt(dev, np, codec,
 666                                               NULL, &link->dai_fmt);
 667                if (ret)
 668                        link->dai_fmt = SND_SOC_DAIFMT_NB_NF |
 669                                        SND_SOC_DAIFMT_CBC_CFC |
 670                                        SND_SOC_DAIFMT_I2S;
 671
 672                /* Get tdm slot */
 673                snd_soc_of_parse_tdm_slot(np, NULL, NULL,
 674                                          &link_data->slots,
 675                                          &link_data->slot_width);
 676                /* default value */
 677                if (!link_data->slots)
 678                        link_data->slots = 2;
 679
 680                if (!link_data->slot_width)
 681                        link_data->slot_width = 32;
 682
 683                link->ignore_pmdown_time = 1;
 684                link->stream_name = link->name;
 685                link++;
 686                link_data++;
 687
 688                of_node_put(cpu);
 689                of_node_put(codec);
 690                of_node_put(platform);
 691        }
 692
 693        return 0;
 694err:
 695        of_node_put(cpu);
 696        of_node_put(codec);
 697        of_node_put(platform);
 698err_put_np:
 699        of_node_put(np);
 700        return ret;
 701}
 702
 703static int imx_card_probe(struct platform_device *pdev)
 704{
 705        struct snd_soc_dai_link *link_be = NULL, *link;
 706        struct imx_card_plat_data *plat_data;
 707        struct imx_card_data *data;
 708        int ret, i;
 709
 710        data = devm_kzalloc(&pdev->dev, sizeof(*data), GFP_KERNEL);
 711        if (!data)
 712                return -ENOMEM;
 713
 714        plat_data = devm_kzalloc(&pdev->dev, sizeof(*plat_data), GFP_KERNEL);
 715        if (!plat_data)
 716                return -ENOMEM;
 717
 718        data->plat_data = plat_data;
 719        data->card.dev = &pdev->dev;
 720
 721        dev_set_drvdata(&pdev->dev, &data->card);
 722        snd_soc_card_set_drvdata(&data->card, data);
 723        ret = imx_card_parse_of(data);
 724        if (ret)
 725                return ret;
 726
 727        data->num_dapm_routes = plat_data->num_codecs + 1;
 728        data->dapm_routes = devm_kcalloc(&pdev->dev, data->num_dapm_routes,
 729                                         sizeof(struct snd_soc_dapm_route),
 730                                         GFP_KERNEL);
 731        if (!data->dapm_routes)
 732                return -ENOMEM;
 733
 734        /* configure the dapm routes */
 735        switch (plat_data->type) {
 736        case CODEC_AK4458:
 737        case CODEC_AK4497:
 738                if (plat_data->num_codecs == 1) {
 739                        data->dapm_routes[0].sink = "Playback";
 740                        data->dapm_routes[0].source = "CPU-Playback";
 741                        i = 1;
 742                } else {
 743                        for (i = 0; i < plat_data->num_codecs; i++) {
 744                                data->dapm_routes[i].sink =
 745                                        devm_kasprintf(&pdev->dev, GFP_KERNEL, "%d %s",
 746                                                       i + 1, "Playback");
 747                                data->dapm_routes[i].source = "CPU-Playback";
 748                        }
 749                }
 750                data->dapm_routes[i].sink = "CPU-Playback";
 751                data->dapm_routes[i].source = "ASRC-Playback";
 752                break;
 753        case CODEC_AK5558:
 754        case CODEC_AK5552:
 755                if (plat_data->num_codecs == 1) {
 756                        data->dapm_routes[0].sink = "CPU-Capture";
 757                        data->dapm_routes[0].source = "Capture";
 758                        i = 1;
 759                } else {
 760                        for (i = 0; i < plat_data->num_codecs; i++) {
 761                                data->dapm_routes[i].source =
 762                                        devm_kasprintf(&pdev->dev, GFP_KERNEL, "%d %s",
 763                                                       i + 1, "Capture");
 764                                data->dapm_routes[i].sink = "CPU-Capture";
 765                        }
 766                }
 767                data->dapm_routes[i].sink = "ASRC-Capture";
 768                data->dapm_routes[i].source = "CPU-Capture";
 769                break;
 770        default:
 771                break;
 772        }
 773
 774        /* default platform data for akcodecs */
 775        if (codec_is_akcodec(plat_data->type)) {
 776                plat_data->support_rates = akcodec_rates;
 777                plat_data->num_rates = ARRAY_SIZE(akcodec_rates);
 778                plat_data->support_tdm_rates = akcodec_tdm_rates;
 779                plat_data->num_tdm_rates = ARRAY_SIZE(akcodec_tdm_rates);
 780
 781                switch (plat_data->type) {
 782                case CODEC_AK4458:
 783                        plat_data->fs_mul = ak4458_fs_mul;
 784                        plat_data->num_fs_mul = ARRAY_SIZE(ak4458_fs_mul);
 785                        plat_data->tdm_fs_mul = ak4458_tdm_fs_mul;
 786                        plat_data->num_tdm_fs_mul = ARRAY_SIZE(ak4458_tdm_fs_mul);
 787                        plat_data->support_channels = ak4458_channels;
 788                        plat_data->num_channels = ARRAY_SIZE(ak4458_channels);
 789                        plat_data->support_tdm_channels = ak4458_tdm_channels;
 790                        plat_data->num_tdm_channels = ARRAY_SIZE(ak4458_tdm_channels);
 791                        break;
 792                case CODEC_AK4497:
 793                        plat_data->fs_mul = ak4497_fs_mul;
 794                        plat_data->num_fs_mul = ARRAY_SIZE(ak4497_fs_mul);
 795                        plat_data->support_channels = ak4458_channels;
 796                        plat_data->num_channels = ARRAY_SIZE(ak4458_channels);
 797                        break;
 798                case CODEC_AK5558:
 799                case CODEC_AK5552:
 800                        plat_data->fs_mul = ak5558_fs_mul;
 801                        plat_data->num_fs_mul = ARRAY_SIZE(ak5558_fs_mul);
 802                        plat_data->tdm_fs_mul = ak5558_tdm_fs_mul;
 803                        plat_data->num_tdm_fs_mul = ARRAY_SIZE(ak5558_tdm_fs_mul);
 804                        plat_data->support_channels = ak5558_channels;
 805                        plat_data->num_channels = ARRAY_SIZE(ak5558_channels);
 806                        plat_data->support_tdm_channels = ak5558_tdm_channels;
 807                        plat_data->num_tdm_channels = ARRAY_SIZE(ak5558_tdm_channels);
 808                        break;
 809                default:
 810                        break;
 811                }
 812        }
 813
 814        /* with asrc as front end */
 815        if (data->card.num_links == 3) {
 816                data->card.dapm_routes = data->dapm_routes;
 817                data->card.num_dapm_routes = data->num_dapm_routes;
 818                for_each_card_prelinks(&data->card, i, link) {
 819                        if (link->no_pcm == 1)
 820                                link_be = link;
 821                }
 822                for_each_card_prelinks(&data->card, i, link) {
 823                        if (link->dynamic == 1 && link_be) {
 824                                link->dpcm_playback = link_be->dpcm_playback;
 825                                link->dpcm_capture = link_be->dpcm_capture;
 826                        }
 827                }
 828        }
 829
 830        ret = devm_snd_soc_register_card(&pdev->dev, &data->card);
 831        if (ret)
 832                return dev_err_probe(&pdev->dev, ret, "snd_soc_register_card failed\n");
 833
 834        return 0;
 835}
 836
 837static const struct of_device_id imx_card_dt_ids[] = {
 838        { .compatible = "fsl,imx-audio-card", },
 839        { },
 840};
 841MODULE_DEVICE_TABLE(of, imx_card_dt_ids);
 842
 843static struct platform_driver imx_card_driver = {
 844        .driver = {
 845                .name = "imx-card",
 846                .pm = &snd_soc_pm_ops,
 847                .of_match_table = imx_card_dt_ids,
 848        },
 849        .probe = imx_card_probe,
 850};
 851module_platform_driver(imx_card_driver);
 852
 853MODULE_DESCRIPTION("Freescale i.MX ASoC Machine Driver");
 854MODULE_LICENSE("GPL v2");
 855MODULE_ALIAS("platform:imx-card");
 856