linux/sound/soc/rockchip/rk3399_gru_sound.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0-only
   2/*
   3 * Rockchip machine ASoC driver for boards using MAX98357A/RT5514/DA7219
   4 *
   5 * Copyright (c) 2016, ROCKCHIP CORPORATION.  All rights reserved.
   6 */
   7
   8#include <linux/module.h>
   9#include <linux/platform_device.h>
  10#include <linux/slab.h>
  11#include <linux/gpio.h>
  12#include <linux/of_gpio.h>
  13#include <linux/delay.h>
  14#include <linux/spi/spi.h>
  15#include <linux/i2c.h>
  16#include <linux/input.h>
  17#include <sound/core.h>
  18#include <sound/jack.h>
  19#include <sound/pcm.h>
  20#include <sound/pcm_params.h>
  21#include <sound/soc.h>
  22#include "rockchip_i2s.h"
  23#include "../codecs/da7219.h"
  24#include "../codecs/da7219-aad.h"
  25#include "../codecs/rt5514.h"
  26
  27#define DRV_NAME "rk3399-gru-sound"
  28
  29#define SOUND_FS        256
  30
  31static unsigned int dmic_wakeup_delay;
  32
  33static struct snd_soc_jack rockchip_sound_jack;
  34
  35/* Headset jack detection DAPM pins */
  36static struct snd_soc_jack_pin rockchip_sound_jack_pins[] = {
  37        {
  38                .pin = "Headphones",
  39                .mask = SND_JACK_HEADPHONE,
  40        },
  41        {
  42                .pin = "Headset Mic",
  43                .mask = SND_JACK_MICROPHONE,
  44        },
  45
  46};
  47
  48static const struct snd_soc_dapm_widget rockchip_dapm_widgets[] = {
  49        SND_SOC_DAPM_HP("Headphones", NULL),
  50        SND_SOC_DAPM_SPK("Speakers", NULL),
  51        SND_SOC_DAPM_MIC("Headset Mic", NULL),
  52        SND_SOC_DAPM_MIC("Int Mic", NULL),
  53        SND_SOC_DAPM_LINE("HDMI", NULL),
  54};
  55
  56static const struct snd_kcontrol_new rockchip_controls[] = {
  57        SOC_DAPM_PIN_SWITCH("Headphones"),
  58        SOC_DAPM_PIN_SWITCH("Speakers"),
  59        SOC_DAPM_PIN_SWITCH("Headset Mic"),
  60        SOC_DAPM_PIN_SWITCH("Int Mic"),
  61        SOC_DAPM_PIN_SWITCH("HDMI"),
  62};
  63
  64static int rockchip_sound_max98357a_hw_params(struct snd_pcm_substream *substream,
  65                             struct snd_pcm_hw_params *params)
  66{
  67        struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
  68        unsigned int mclk;
  69        int ret;
  70
  71        mclk = params_rate(params) * SOUND_FS;
  72
  73        ret = snd_soc_dai_set_sysclk(asoc_rtd_to_cpu(rtd, 0), 0, mclk, 0);
  74        if (ret) {
  75                dev_err(rtd->card->dev, "%s() error setting sysclk to %u: %d\n",
  76                                __func__, mclk, ret);
  77                return ret;
  78        }
  79
  80        return 0;
  81}
  82
  83static int rockchip_sound_rt5514_hw_params(struct snd_pcm_substream *substream,
  84                             struct snd_pcm_hw_params *params)
  85{
  86        struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
  87        struct snd_soc_dai *cpu_dai = asoc_rtd_to_cpu(rtd, 0);
  88        struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 0);
  89        unsigned int mclk;
  90        int ret;
  91
  92        mclk = params_rate(params) * SOUND_FS;
  93
  94        ret = snd_soc_dai_set_sysclk(cpu_dai, 0, mclk,
  95                                     SND_SOC_CLOCK_OUT);
  96        if (ret < 0) {
  97                dev_err(rtd->card->dev, "Can't set cpu clock out %d\n", ret);
  98                return ret;
  99        }
 100
 101        ret = snd_soc_dai_set_sysclk(codec_dai, RT5514_SCLK_S_MCLK,
 102                                     mclk, SND_SOC_CLOCK_IN);
 103        if (ret) {
 104                dev_err(rtd->card->dev, "%s() error setting sysclk to %u: %d\n",
 105                                __func__, params_rate(params) * 512, ret);
 106                return ret;
 107        }
 108
 109        /* Wait for DMIC stable */
 110        msleep(dmic_wakeup_delay);
 111
 112        return 0;
 113}
 114
 115static int rockchip_sound_da7219_hw_params(struct snd_pcm_substream *substream,
 116                             struct snd_pcm_hw_params *params)
 117{
 118        struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
 119        struct snd_soc_dai *cpu_dai = asoc_rtd_to_cpu(rtd, 0);
 120        struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 0);
 121        int mclk, ret;
 122
 123        /* in bypass mode, the mclk has to be one of the frequencies below */
 124        switch (params_rate(params)) {
 125        case 8000:
 126        case 16000:
 127        case 24000:
 128        case 32000:
 129        case 48000:
 130        case 64000:
 131        case 96000:
 132                mclk = 12288000;
 133                break;
 134        case 11025:
 135        case 22050:
 136        case 44100:
 137        case 88200:
 138                mclk = 11289600;
 139                break;
 140        default:
 141                return -EINVAL;
 142        }
 143
 144        ret = snd_soc_dai_set_sysclk(cpu_dai, 0, mclk,
 145                                     SND_SOC_CLOCK_OUT);
 146        if (ret < 0) {
 147                dev_err(codec_dai->dev, "Can't set cpu clock out %d\n", ret);
 148                return ret;
 149        }
 150
 151        ret = snd_soc_dai_set_sysclk(codec_dai, 0, mclk,
 152                                     SND_SOC_CLOCK_IN);
 153        if (ret < 0) {
 154                dev_err(codec_dai->dev, "Can't set codec clock in %d\n", ret);
 155                return ret;
 156        }
 157
 158        ret = snd_soc_dai_set_pll(codec_dai, 0, DA7219_SYSCLK_MCLK, 0, 0);
 159        if (ret < 0) {
 160                dev_err(codec_dai->dev, "Can't set pll sysclk mclk %d\n", ret);
 161                return ret;
 162        }
 163
 164        return 0;
 165}
 166
 167static int rockchip_sound_da7219_init(struct snd_soc_pcm_runtime *rtd)
 168{
 169        struct snd_soc_component *component = asoc_rtd_to_codec(rtd, 0)->component;
 170        struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 0);
 171        int ret;
 172
 173        /* We need default MCLK and PLL settings for the accessory detection */
 174        ret = snd_soc_dai_set_sysclk(codec_dai, 0, 12288000,
 175                                     SND_SOC_CLOCK_IN);
 176        if (ret < 0) {
 177                dev_err(codec_dai->dev, "Init can't set codec clock in %d\n", ret);
 178                return ret;
 179        }
 180
 181        ret = snd_soc_dai_set_pll(codec_dai, 0, DA7219_SYSCLK_MCLK, 0, 0);
 182        if (ret < 0) {
 183                dev_err(codec_dai->dev, "Init can't set pll sysclk mclk %d\n", ret);
 184                return ret;
 185        }
 186
 187        /* Enable Headset and 4 Buttons Jack detection */
 188        ret = snd_soc_card_jack_new(rtd->card, "Headset Jack",
 189                                    SND_JACK_HEADSET | SND_JACK_LINEOUT |
 190                                    SND_JACK_BTN_0 | SND_JACK_BTN_1 |
 191                                    SND_JACK_BTN_2 | SND_JACK_BTN_3,
 192                                    &rockchip_sound_jack,
 193                                    rockchip_sound_jack_pins,
 194                                    ARRAY_SIZE(rockchip_sound_jack_pins));
 195
 196        if (ret) {
 197                dev_err(rtd->card->dev, "New Headset Jack failed! (%d)\n", ret);
 198                return ret;
 199        }
 200
 201        snd_jack_set_key(
 202                rockchip_sound_jack.jack, SND_JACK_BTN_0, KEY_PLAYPAUSE);
 203        snd_jack_set_key(
 204                rockchip_sound_jack.jack, SND_JACK_BTN_1, KEY_VOLUMEUP);
 205        snd_jack_set_key(
 206                rockchip_sound_jack.jack, SND_JACK_BTN_2, KEY_VOLUMEDOWN);
 207        snd_jack_set_key(
 208                rockchip_sound_jack.jack, SND_JACK_BTN_3, KEY_VOICECOMMAND);
 209
 210        da7219_aad_jack_det(component, &rockchip_sound_jack);
 211
 212        return 0;
 213}
 214
 215static int rockchip_sound_dmic_hw_params(struct snd_pcm_substream *substream,
 216                             struct snd_pcm_hw_params *params)
 217{
 218        struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
 219        unsigned int mclk;
 220        int ret;
 221
 222        mclk = params_rate(params) * SOUND_FS;
 223
 224        ret = snd_soc_dai_set_sysclk(asoc_rtd_to_cpu(rtd, 0), 0, mclk, 0);
 225        if (ret) {
 226                dev_err(rtd->card->dev, "%s() error setting sysclk to %u: %d\n",
 227                                __func__, mclk, ret);
 228                return ret;
 229        }
 230
 231        /* Wait for DMIC stable */
 232        msleep(dmic_wakeup_delay);
 233
 234        return 0;
 235}
 236
 237static int rockchip_sound_startup(struct snd_pcm_substream *substream)
 238{
 239        struct snd_pcm_runtime *runtime = substream->runtime;
 240
 241        runtime->hw.formats = SNDRV_PCM_FMTBIT_S16_LE;
 242        return snd_pcm_hw_constraint_minmax(runtime, SNDRV_PCM_HW_PARAM_RATE,
 243                        8000, 96000);
 244}
 245
 246static const struct snd_soc_ops rockchip_sound_max98357a_ops = {
 247        .startup = rockchip_sound_startup,
 248        .hw_params = rockchip_sound_max98357a_hw_params,
 249};
 250
 251static const struct snd_soc_ops rockchip_sound_rt5514_ops = {
 252        .startup = rockchip_sound_startup,
 253        .hw_params = rockchip_sound_rt5514_hw_params,
 254};
 255
 256static const struct snd_soc_ops rockchip_sound_da7219_ops = {
 257        .startup = rockchip_sound_startup,
 258        .hw_params = rockchip_sound_da7219_hw_params,
 259};
 260
 261static const struct snd_soc_ops rockchip_sound_dmic_ops = {
 262        .startup = rockchip_sound_startup,
 263        .hw_params = rockchip_sound_dmic_hw_params,
 264};
 265
 266static struct snd_soc_card rockchip_sound_card = {
 267        .name = "rk3399-gru-sound",
 268        .owner = THIS_MODULE,
 269        .dapm_widgets = rockchip_dapm_widgets,
 270        .num_dapm_widgets = ARRAY_SIZE(rockchip_dapm_widgets),
 271        .controls = rockchip_controls,
 272        .num_controls = ARRAY_SIZE(rockchip_controls),
 273};
 274
 275enum {
 276        DAILINK_CDNDP,
 277        DAILINK_DA7219,
 278        DAILINK_DMIC,
 279        DAILINK_MAX98357A,
 280        DAILINK_RT5514,
 281        DAILINK_RT5514_DSP,
 282};
 283
 284SND_SOC_DAILINK_DEFS(cdndp,
 285        DAILINK_COMP_ARRAY(COMP_EMPTY()),
 286        DAILINK_COMP_ARRAY(COMP_CODEC(NULL, "spdif-hifi")),
 287        DAILINK_COMP_ARRAY(COMP_EMPTY()));
 288
 289SND_SOC_DAILINK_DEFS(da7219,
 290        DAILINK_COMP_ARRAY(COMP_EMPTY()),
 291        DAILINK_COMP_ARRAY(COMP_CODEC(NULL, "da7219-hifi")),
 292        DAILINK_COMP_ARRAY(COMP_EMPTY()));
 293
 294SND_SOC_DAILINK_DEFS(dmic,
 295        DAILINK_COMP_ARRAY(COMP_EMPTY()),
 296        DAILINK_COMP_ARRAY(COMP_CODEC(NULL, "dmic-hifi")),
 297        DAILINK_COMP_ARRAY(COMP_EMPTY()));
 298
 299SND_SOC_DAILINK_DEFS(max98357a,
 300        DAILINK_COMP_ARRAY(COMP_EMPTY()),
 301        DAILINK_COMP_ARRAY(COMP_CODEC(NULL, "HiFi")),
 302        DAILINK_COMP_ARRAY(COMP_EMPTY()));
 303
 304SND_SOC_DAILINK_DEFS(rt5514,
 305        DAILINK_COMP_ARRAY(COMP_EMPTY()),
 306        DAILINK_COMP_ARRAY(COMP_CODEC(NULL, "rt5514-aif1")),
 307        DAILINK_COMP_ARRAY(COMP_EMPTY()));
 308
 309SND_SOC_DAILINK_DEFS(rt5514_dsp,
 310        DAILINK_COMP_ARRAY(COMP_EMPTY()),
 311        DAILINK_COMP_ARRAY(COMP_DUMMY()),
 312        DAILINK_COMP_ARRAY(COMP_EMPTY()));
 313
 314static const struct snd_soc_dai_link rockchip_dais[] = {
 315        [DAILINK_CDNDP] = {
 316                .name = "DP",
 317                .stream_name = "DP PCM",
 318                .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF |
 319                        SND_SOC_DAIFMT_CBS_CFS,
 320                SND_SOC_DAILINK_REG(cdndp),
 321        },
 322        [DAILINK_DA7219] = {
 323                .name = "DA7219",
 324                .stream_name = "DA7219 PCM",
 325                .init = rockchip_sound_da7219_init,
 326                .ops = &rockchip_sound_da7219_ops,
 327                /* set da7219 as slave */
 328                .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF |
 329                        SND_SOC_DAIFMT_CBS_CFS,
 330                SND_SOC_DAILINK_REG(da7219),
 331        },
 332        [DAILINK_DMIC] = {
 333                .name = "DMIC",
 334                .stream_name = "DMIC PCM",
 335                .ops = &rockchip_sound_dmic_ops,
 336                .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF |
 337                        SND_SOC_DAIFMT_CBS_CFS,
 338                SND_SOC_DAILINK_REG(dmic),
 339        },
 340        [DAILINK_MAX98357A] = {
 341                .name = "MAX98357A",
 342                .stream_name = "MAX98357A PCM",
 343                .ops = &rockchip_sound_max98357a_ops,
 344                /* set max98357a as slave */
 345                .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF |
 346                        SND_SOC_DAIFMT_CBS_CFS,
 347                SND_SOC_DAILINK_REG(max98357a),
 348        },
 349        [DAILINK_RT5514] = {
 350                .name = "RT5514",
 351                .stream_name = "RT5514 PCM",
 352                .ops = &rockchip_sound_rt5514_ops,
 353                /* set rt5514 as slave */
 354                .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF |
 355                        SND_SOC_DAIFMT_CBS_CFS,
 356                SND_SOC_DAILINK_REG(rt5514),
 357        },
 358        /* RT5514 DSP for voice wakeup via spi bus */
 359        [DAILINK_RT5514_DSP] = {
 360                .name = "RT5514 DSP",
 361                .stream_name = "Wake on Voice",
 362                SND_SOC_DAILINK_REG(rt5514_dsp),
 363        },
 364};
 365
 366static const struct snd_soc_dapm_route rockchip_sound_cdndp_routes[] = {
 367        /* Output */
 368        {"HDMI", NULL, "TX"},
 369};
 370
 371static const struct snd_soc_dapm_route rockchip_sound_da7219_routes[] = {
 372        /* Output */
 373        {"Headphones", NULL, "HPL"},
 374        {"Headphones", NULL, "HPR"},
 375
 376        /* Input */
 377        {"MIC", NULL, "Headset Mic"},
 378};
 379
 380static const struct snd_soc_dapm_route rockchip_sound_dmic_routes[] = {
 381        /* Input */
 382        {"DMic", NULL, "Int Mic"},
 383};
 384
 385static const struct snd_soc_dapm_route rockchip_sound_max98357a_routes[] = {
 386        /* Output */
 387        {"Speakers", NULL, "Speaker"},
 388};
 389
 390static const struct snd_soc_dapm_route rockchip_sound_rt5514_routes[] = {
 391        /* Input */
 392        {"DMIC1L", NULL, "Int Mic"},
 393        {"DMIC1R", NULL, "Int Mic"},
 394};
 395
 396struct rockchip_sound_route {
 397        const struct snd_soc_dapm_route *routes;
 398        int num_routes;
 399};
 400
 401static const struct rockchip_sound_route rockchip_routes[] = {
 402        [DAILINK_CDNDP] = {
 403                .routes = rockchip_sound_cdndp_routes,
 404                .num_routes = ARRAY_SIZE(rockchip_sound_cdndp_routes),
 405        },
 406        [DAILINK_DA7219] = {
 407                .routes = rockchip_sound_da7219_routes,
 408                .num_routes = ARRAY_SIZE(rockchip_sound_da7219_routes),
 409        },
 410        [DAILINK_DMIC] = {
 411                .routes = rockchip_sound_dmic_routes,
 412                .num_routes = ARRAY_SIZE(rockchip_sound_dmic_routes),
 413        },
 414        [DAILINK_MAX98357A] = {
 415                .routes = rockchip_sound_max98357a_routes,
 416                .num_routes = ARRAY_SIZE(rockchip_sound_max98357a_routes),
 417        },
 418        [DAILINK_RT5514] = {
 419                .routes = rockchip_sound_rt5514_routes,
 420                .num_routes = ARRAY_SIZE(rockchip_sound_rt5514_routes),
 421        },
 422        [DAILINK_RT5514_DSP] = {},
 423};
 424
 425struct dailink_match_data {
 426        const char *compatible;
 427        struct bus_type *bus_type;
 428};
 429
 430static const struct dailink_match_data dailink_match[] = {
 431        [DAILINK_CDNDP] = {
 432                .compatible = "rockchip,rk3399-cdn-dp",
 433        },
 434        [DAILINK_DA7219] = {
 435                .compatible = "dlg,da7219",
 436        },
 437        [DAILINK_DMIC] = {
 438                .compatible = "dmic-codec",
 439        },
 440        [DAILINK_MAX98357A] = {
 441                .compatible = "maxim,max98357a",
 442        },
 443        [DAILINK_RT5514] = {
 444                .compatible = "realtek,rt5514",
 445                .bus_type = &i2c_bus_type,
 446        },
 447        [DAILINK_RT5514_DSP] = {
 448                .compatible = "realtek,rt5514",
 449                .bus_type = &spi_bus_type,
 450        },
 451};
 452
 453static int rockchip_sound_codec_node_match(struct device_node *np_codec)
 454{
 455        struct device *dev;
 456        int i;
 457
 458        for (i = 0; i < ARRAY_SIZE(dailink_match); i++) {
 459                if (!of_device_is_compatible(np_codec,
 460                                             dailink_match[i].compatible))
 461                        continue;
 462
 463                if (dailink_match[i].bus_type) {
 464                        dev = bus_find_device_by_of_node(dailink_match[i].bus_type,
 465                                                         np_codec);
 466                        if (!dev)
 467                                continue;
 468                        put_device(dev);
 469                }
 470
 471                return i;
 472        }
 473        return -1;
 474}
 475
 476static int rockchip_sound_of_parse_dais(struct device *dev,
 477                                        struct snd_soc_card *card)
 478{
 479        struct device_node *np_cpu, *np_cpu0, *np_cpu1;
 480        struct device_node *np_codec;
 481        struct snd_soc_dai_link *dai;
 482        struct snd_soc_dapm_route *routes;
 483        int i, index;
 484        int num_routes;
 485
 486        card->dai_link = devm_kzalloc(dev, sizeof(rockchip_dais),
 487                                      GFP_KERNEL);
 488        if (!card->dai_link)
 489                return -ENOMEM;
 490
 491        num_routes = 0;
 492        for (i = 0; i < ARRAY_SIZE(rockchip_routes); i++)
 493                num_routes += rockchip_routes[i].num_routes;
 494        routes = devm_kcalloc(dev, num_routes, sizeof(*routes),
 495                              GFP_KERNEL);
 496        if (!routes)
 497                return -ENOMEM;
 498        card->dapm_routes = routes;
 499
 500        np_cpu0 = of_parse_phandle(dev->of_node, "rockchip,cpu", 0);
 501        np_cpu1 = of_parse_phandle(dev->of_node, "rockchip,cpu", 1);
 502
 503        card->num_dapm_routes = 0;
 504        card->num_links = 0;
 505        for (i = 0; i < ARRAY_SIZE(rockchip_dais); i++) {
 506                np_codec = of_parse_phandle(dev->of_node,
 507                                            "rockchip,codec", i);
 508                if (!np_codec)
 509                        break;
 510
 511                if (!of_device_is_available(np_codec))
 512                        continue;
 513
 514                index = rockchip_sound_codec_node_match(np_codec);
 515                if (index < 0)
 516                        continue;
 517
 518                switch (index) {
 519                case DAILINK_CDNDP:
 520                        np_cpu = np_cpu1;
 521                        break;
 522                case DAILINK_RT5514_DSP:
 523                        np_cpu = np_codec;
 524                        break;
 525                default:
 526                        np_cpu = np_cpu0;
 527                        break;
 528                }
 529
 530                if (!np_cpu) {
 531                        dev_err(dev, "Missing 'rockchip,cpu' for %s\n",
 532                                rockchip_dais[index].name);
 533                        return -EINVAL;
 534                }
 535
 536                dai = &card->dai_link[card->num_links++];
 537                *dai = rockchip_dais[index];
 538
 539                if (!dai->codecs->name)
 540                        dai->codecs->of_node = np_codec;
 541                dai->platforms->of_node = np_cpu;
 542                dai->cpus->of_node = np_cpu;
 543
 544                if (card->num_dapm_routes + rockchip_routes[index].num_routes >
 545                    num_routes) {
 546                        dev_err(dev, "Too many routes\n");
 547                        return -EINVAL;
 548                }
 549
 550                memcpy(routes + card->num_dapm_routes,
 551                       rockchip_routes[index].routes,
 552                       rockchip_routes[index].num_routes * sizeof(*routes));
 553                card->num_dapm_routes += rockchip_routes[index].num_routes;
 554        }
 555
 556        return 0;
 557}
 558
 559static int rockchip_sound_probe(struct platform_device *pdev)
 560{
 561        struct snd_soc_card *card = &rockchip_sound_card;
 562        int ret;
 563
 564        ret = rockchip_sound_of_parse_dais(&pdev->dev, card);
 565        if (ret < 0) {
 566                dev_err(&pdev->dev, "Failed to parse dais: %d\n", ret);
 567                return ret;
 568        }
 569
 570        /* Set DMIC wakeup delay */
 571        ret = device_property_read_u32(&pdev->dev, "dmic-wakeup-delay-ms",
 572                                        &dmic_wakeup_delay);
 573        if (ret) {
 574                dmic_wakeup_delay = 0;
 575                dev_dbg(&pdev->dev,
 576                        "no optional property 'dmic-wakeup-delay-ms' found, default: no delay\n");
 577        }
 578
 579        card->dev = &pdev->dev;
 580        return devm_snd_soc_register_card(&pdev->dev, card);
 581}
 582
 583static const struct of_device_id rockchip_sound_of_match[] = {
 584        { .compatible = "rockchip,rk3399-gru-sound", },
 585        {},
 586};
 587
 588static struct platform_driver rockchip_sound_driver = {
 589        .probe = rockchip_sound_probe,
 590        .driver = {
 591                .name = DRV_NAME,
 592                .of_match_table = rockchip_sound_of_match,
 593#ifdef CONFIG_PM
 594                .pm = &snd_soc_pm_ops,
 595#endif
 596        },
 597};
 598
 599module_platform_driver(rockchip_sound_driver);
 600
 601MODULE_AUTHOR("Xing Zheng <zhengxing@rock-chips.com>");
 602MODULE_DESCRIPTION("Rockchip ASoC Machine Driver");
 603MODULE_LICENSE("GPL v2");
 604MODULE_ALIAS("platform:" DRV_NAME);
 605MODULE_DEVICE_TABLE(of, rockchip_sound_of_match);
 606