linux/sound/soc/qcom/sdm845.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0
   2/*
   3 * Copyright (c) 2018, The Linux Foundation. All rights reserved.
   4 */
   5
   6#include <dt-bindings/sound/qcom,q6afe.h>
   7#include <linux/module.h>
   8#include <linux/platform_device.h>
   9#include <sound/core.h>
  10#include <sound/pcm.h>
  11#include <sound/pcm_params.h>
  12#include <sound/jack.h>
  13#include <sound/soc.h>
  14#include <linux/soundwire/sdw.h>
  15#include <uapi/linux/input-event-codes.h>
  16#include "common.h"
  17#include "qdsp6/q6afe.h"
  18#include "sdw.h"
  19#include "../codecs/rt5663.h"
  20
  21#define DRIVER_NAME     "sdm845"
  22#define DEFAULT_SAMPLE_RATE_48K         48000
  23#define DEFAULT_MCLK_RATE               24576000
  24#define TDM_BCLK_RATE           6144000
  25#define MI2S_BCLK_RATE          1536000
  26#define LEFT_SPK_TDM_TX_MASK    0x30
  27#define RIGHT_SPK_TDM_TX_MASK   0xC0
  28#define SPK_TDM_RX_MASK         0x03
  29#define NUM_TDM_SLOTS           8
  30#define SLIM_MAX_TX_PORTS 16
  31#define SLIM_MAX_RX_PORTS 13
  32#define WCD934X_DEFAULT_MCLK_RATE       9600000
  33
  34struct sdm845_snd_data {
  35        struct snd_soc_jack jack;
  36        bool jack_setup;
  37        bool slim_port_setup;
  38        bool stream_prepared[AFE_PORT_MAX];
  39        struct snd_soc_card *card;
  40        uint32_t pri_mi2s_clk_count;
  41        uint32_t sec_mi2s_clk_count;
  42        uint32_t quat_tdm_clk_count;
  43        struct sdw_stream_runtime *sruntime[AFE_PORT_MAX];
  44};
  45
  46static struct snd_soc_jack_pin sdm845_jack_pins[] = {
  47        {
  48                .pin = "Headphone Jack",
  49                .mask = SND_JACK_HEADPHONE,
  50        },
  51        {
  52                .pin = "Headset Mic",
  53                .mask = SND_JACK_MICROPHONE,
  54        },
  55};
  56
  57static unsigned int tdm_slot_offset[8] = {0, 4, 8, 12, 16, 20, 24, 28};
  58
  59static int sdm845_slim_snd_hw_params(struct snd_pcm_substream *substream,
  60                                     struct snd_pcm_hw_params *params)
  61{
  62        struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream);
  63        struct snd_soc_dai *cpu_dai = snd_soc_rtd_to_cpu(rtd, 0);
  64        struct snd_soc_dai *codec_dai;
  65        struct sdm845_snd_data *pdata = snd_soc_card_get_drvdata(rtd->card);
  66        u32 rx_ch[SLIM_MAX_RX_PORTS], tx_ch[SLIM_MAX_TX_PORTS];
  67        struct sdw_stream_runtime *sruntime;
  68        u32 rx_ch_cnt = 0, tx_ch_cnt = 0;
  69        int ret = 0, i;
  70
  71        for_each_rtd_codec_dais(rtd, i, codec_dai) {
  72                sruntime = snd_soc_dai_get_stream(codec_dai,
  73                                                  substream->stream);
  74                if (sruntime != ERR_PTR(-ENOTSUPP))
  75                        pdata->sruntime[cpu_dai->id] = sruntime;
  76
  77                ret = snd_soc_dai_get_channel_map(codec_dai,
  78                                &tx_ch_cnt, tx_ch, &rx_ch_cnt, rx_ch);
  79
  80                if (ret != 0 && ret != -ENOTSUPP) {
  81                        pr_err("failed to get codec chan map, err:%d\n", ret);
  82                        return ret;
  83                } else if (ret == -ENOTSUPP) {
  84                        /* Ignore unsupported */
  85                        continue;
  86                }
  87
  88                if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
  89                        ret = snd_soc_dai_set_channel_map(cpu_dai, 0, NULL,
  90                                                          rx_ch_cnt, rx_ch);
  91                else
  92                        ret = snd_soc_dai_set_channel_map(cpu_dai, tx_ch_cnt,
  93                                                          tx_ch, 0, NULL);
  94                if (ret != 0 && ret != -ENOTSUPP) {
  95                        dev_err(rtd->dev, "failed to set cpu chan map, err:%d\n", ret);
  96                        return ret;
  97                }
  98        }
  99
 100        return 0;
 101}
 102
 103static int sdm845_tdm_snd_hw_params(struct snd_pcm_substream *substream,
 104                                        struct snd_pcm_hw_params *params)
 105{
 106        struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream);
 107        struct snd_soc_dai *cpu_dai = snd_soc_rtd_to_cpu(rtd, 0);
 108        struct snd_soc_dai *codec_dai;
 109        int ret = 0, j;
 110        int channels, slot_width;
 111
 112        switch (params_format(params)) {
 113        case SNDRV_PCM_FORMAT_S16_LE:
 114                slot_width = 16;
 115                break;
 116        default:
 117                dev_err(rtd->dev, "%s: invalid param format 0x%x\n",
 118                                __func__, params_format(params));
 119                return -EINVAL;
 120        }
 121
 122        channels = params_channels(params);
 123        if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
 124                ret = snd_soc_dai_set_tdm_slot(cpu_dai, 0, 0x3,
 125                                8, slot_width);
 126                if (ret < 0) {
 127                        dev_err(rtd->dev, "%s: failed to set tdm slot, err:%d\n",
 128                                        __func__, ret);
 129                        goto end;
 130                }
 131
 132                ret = snd_soc_dai_set_channel_map(cpu_dai, 0, NULL,
 133                                channels, tdm_slot_offset);
 134                if (ret < 0) {
 135                        dev_err(rtd->dev, "%s: failed to set channel map, err:%d\n",
 136                                        __func__, ret);
 137                        goto end;
 138                }
 139        } else {
 140                ret = snd_soc_dai_set_tdm_slot(cpu_dai, 0xf, 0,
 141                                8, slot_width);
 142                if (ret < 0) {
 143                        dev_err(rtd->dev, "%s: failed to set tdm slot, err:%d\n",
 144                                        __func__, ret);
 145                        goto end;
 146                }
 147
 148                ret = snd_soc_dai_set_channel_map(cpu_dai, channels,
 149                                tdm_slot_offset, 0, NULL);
 150                if (ret < 0) {
 151                        dev_err(rtd->dev, "%s: failed to set channel map, err:%d\n",
 152                                        __func__, ret);
 153                        goto end;
 154                }
 155        }
 156
 157        for_each_rtd_codec_dais(rtd, j, codec_dai) {
 158
 159                if (!strcmp(codec_dai->component->name_prefix, "Left")) {
 160                        ret = snd_soc_dai_set_tdm_slot(
 161                                        codec_dai, LEFT_SPK_TDM_TX_MASK,
 162                                        SPK_TDM_RX_MASK, NUM_TDM_SLOTS,
 163                                        slot_width);
 164                        if (ret < 0) {
 165                                dev_err(rtd->dev,
 166                                        "DEV0 TDM slot err:%d\n", ret);
 167                                return ret;
 168                        }
 169                }
 170
 171                if (!strcmp(codec_dai->component->name_prefix, "Right")) {
 172                        ret = snd_soc_dai_set_tdm_slot(
 173                                        codec_dai, RIGHT_SPK_TDM_TX_MASK,
 174                                        SPK_TDM_RX_MASK, NUM_TDM_SLOTS,
 175                                        slot_width);
 176                        if (ret < 0) {
 177                                dev_err(rtd->dev,
 178                                        "DEV1 TDM slot err:%d\n", ret);
 179                                return ret;
 180                        }
 181                }
 182        }
 183
 184end:
 185        return ret;
 186}
 187
 188static int sdm845_snd_hw_params(struct snd_pcm_substream *substream,
 189                                        struct snd_pcm_hw_params *params)
 190{
 191        struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream);
 192        struct snd_soc_dai *cpu_dai = snd_soc_rtd_to_cpu(rtd, 0);
 193        struct snd_soc_dai *codec_dai = snd_soc_rtd_to_codec(rtd, 0);
 194        int ret = 0;
 195
 196        switch (cpu_dai->id) {
 197        case PRIMARY_MI2S_RX:
 198        case PRIMARY_MI2S_TX:
 199                /*
 200                 * Use ASRC for internal clocks, as PLL rate isn't multiple
 201                 * of BCLK.
 202                 */
 203                rt5663_sel_asrc_clk_src(
 204                        codec_dai->component,
 205                        RT5663_DA_STEREO_FILTER | RT5663_AD_STEREO_FILTER,
 206                        RT5663_CLK_SEL_I2S1_ASRC);
 207                ret = snd_soc_dai_set_sysclk(
 208                        codec_dai, RT5663_SCLK_S_MCLK, DEFAULT_MCLK_RATE,
 209                        SND_SOC_CLOCK_IN);
 210                if (ret < 0)
 211                        dev_err(rtd->dev,
 212                                "snd_soc_dai_set_sysclk err = %d\n", ret);
 213                break;
 214        case QUATERNARY_TDM_RX_0:
 215        case QUATERNARY_TDM_TX_0:
 216                ret = sdm845_tdm_snd_hw_params(substream, params);
 217                break;
 218        case SLIMBUS_0_RX...SLIMBUS_6_TX:
 219                ret = sdm845_slim_snd_hw_params(substream, params);
 220                break;
 221        case QUATERNARY_MI2S_RX:
 222        case SECONDARY_MI2S_RX:
 223                break;
 224        default:
 225                pr_err("%s: invalid dai id 0x%x\n", __func__, cpu_dai->id);
 226                break;
 227        }
 228        return ret;
 229}
 230
 231static void sdm845_jack_free(struct snd_jack *jack)
 232{
 233        struct snd_soc_component *component = jack->private_data;
 234
 235        snd_soc_component_set_jack(component, NULL, NULL);
 236}
 237
 238static int sdm845_dai_init(struct snd_soc_pcm_runtime *rtd)
 239{
 240        struct snd_soc_component *component;
 241        struct snd_soc_card *card = rtd->card;
 242        struct snd_soc_dai *codec_dai = snd_soc_rtd_to_codec(rtd, 0);
 243        struct snd_soc_dai *cpu_dai = snd_soc_rtd_to_cpu(rtd, 0);
 244        struct sdm845_snd_data *pdata = snd_soc_card_get_drvdata(card);
 245        struct snd_soc_dai_link *link = rtd->dai_link;
 246        struct snd_jack *jack;
 247        /*
 248         * Codec SLIMBUS configuration
 249         * RX1, RX2, RX3, RX4, RX5, RX6, RX7, RX8, RX9, RX10, RX11, RX12, RX13
 250         * TX1, TX2, TX3, TX4, TX5, TX6, TX7, TX8, TX9, TX10, TX11, TX12, TX13
 251         * TX14, TX15, TX16
 252         */
 253        unsigned int rx_ch[SLIM_MAX_RX_PORTS] = {144, 145, 146, 147, 148, 149,
 254                                        150, 151, 152, 153, 154, 155, 156};
 255        unsigned int tx_ch[SLIM_MAX_TX_PORTS] = {128, 129, 130, 131, 132, 133,
 256                                            134, 135, 136, 137, 138, 139,
 257                                            140, 141, 142, 143};
 258        int rval, i;
 259
 260
 261        if (!pdata->jack_setup) {
 262                rval = snd_soc_card_jack_new_pins(card, "Headset Jack",
 263                                                  SND_JACK_HEADSET |
 264                                                  SND_JACK_HEADPHONE |
 265                                                  SND_JACK_BTN_0 | SND_JACK_BTN_1 |
 266                                                  SND_JACK_BTN_2 | SND_JACK_BTN_3,
 267                                                  &pdata->jack,
 268                                                  sdm845_jack_pins,
 269                                                  ARRAY_SIZE(sdm845_jack_pins));
 270
 271                if (rval < 0) {
 272                        dev_err(card->dev, "Unable to add Headphone Jack\n");
 273                        return rval;
 274                }
 275
 276                jack = pdata->jack.jack;
 277
 278                snd_jack_set_key(jack, SND_JACK_BTN_0, KEY_PLAYPAUSE);
 279                snd_jack_set_key(jack, SND_JACK_BTN_1, KEY_VOICECOMMAND);
 280                snd_jack_set_key(jack, SND_JACK_BTN_2, KEY_VOLUMEUP);
 281                snd_jack_set_key(jack, SND_JACK_BTN_3, KEY_VOLUMEDOWN);
 282                pdata->jack_setup = true;
 283        }
 284
 285        switch (cpu_dai->id) {
 286        case PRIMARY_MI2S_RX:
 287                jack  = pdata->jack.jack;
 288                component = codec_dai->component;
 289
 290                jack->private_data = component;
 291                jack->private_free = sdm845_jack_free;
 292                rval = snd_soc_component_set_jack(component,
 293                                                  &pdata->jack, NULL);
 294                if (rval != 0 && rval != -ENOTSUPP) {
 295                        dev_warn(card->dev, "Failed to set jack: %d\n", rval);
 296                        return rval;
 297                }
 298                break;
 299        case SLIMBUS_0_RX...SLIMBUS_6_TX:
 300                /* setting up wcd multiple times for slim port is redundant */
 301                if (pdata->slim_port_setup || !link->no_pcm)
 302                        return 0;
 303
 304                for_each_rtd_codec_dais(rtd, i, codec_dai) {
 305                        rval = snd_soc_dai_set_channel_map(codec_dai,
 306                                                          ARRAY_SIZE(tx_ch),
 307                                                          tx_ch,
 308                                                          ARRAY_SIZE(rx_ch),
 309                                                          rx_ch);
 310                        if (rval != 0 && rval != -ENOTSUPP)
 311                                return rval;
 312
 313                        snd_soc_dai_set_sysclk(codec_dai, 0,
 314                                               WCD934X_DEFAULT_MCLK_RATE,
 315                                               SNDRV_PCM_STREAM_PLAYBACK);
 316
 317                        rval = snd_soc_component_set_jack(codec_dai->component,
 318                                                          &pdata->jack, NULL);
 319                        if (rval != 0 && rval != -ENOTSUPP) {
 320                                dev_warn(card->dev, "Failed to set jack: %d\n", rval);
 321                                return rval;
 322                        }
 323                }
 324
 325                pdata->slim_port_setup = true;
 326
 327                break;
 328        default:
 329                break;
 330        }
 331
 332        return 0;
 333}
 334
 335
 336static int sdm845_snd_startup(struct snd_pcm_substream *substream)
 337{
 338        unsigned int fmt = SND_SOC_DAIFMT_BP_FP;
 339        unsigned int codec_dai_fmt = SND_SOC_DAIFMT_BC_FC;
 340        struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream);
 341        struct snd_soc_card *card = rtd->card;
 342        struct sdm845_snd_data *data = snd_soc_card_get_drvdata(card);
 343        struct snd_soc_dai *cpu_dai = snd_soc_rtd_to_cpu(rtd, 0);
 344        struct snd_soc_dai *codec_dai = snd_soc_rtd_to_codec(rtd, 0);
 345        int j;
 346        int ret;
 347
 348        switch (cpu_dai->id) {
 349        case PRIMARY_MI2S_RX:
 350        case PRIMARY_MI2S_TX:
 351                codec_dai_fmt |= SND_SOC_DAIFMT_NB_NF;
 352                if (++(data->pri_mi2s_clk_count) == 1) {
 353                        snd_soc_dai_set_sysclk(cpu_dai,
 354                                Q6AFE_LPASS_CLK_ID_MCLK_1,
 355                                DEFAULT_MCLK_RATE, SNDRV_PCM_STREAM_PLAYBACK);
 356                        snd_soc_dai_set_sysclk(cpu_dai,
 357                                Q6AFE_LPASS_CLK_ID_PRI_MI2S_IBIT,
 358                                MI2S_BCLK_RATE, SNDRV_PCM_STREAM_PLAYBACK);
 359                }
 360                snd_soc_dai_set_fmt(cpu_dai, fmt);
 361                snd_soc_dai_set_fmt(codec_dai, codec_dai_fmt);
 362                break;
 363
 364        case SECONDARY_MI2S_RX:
 365        case SECONDARY_MI2S_TX:
 366                codec_dai_fmt |= SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_I2S;
 367                if (++(data->sec_mi2s_clk_count) == 1) {
 368                        snd_soc_dai_set_sysclk(cpu_dai,
 369                                Q6AFE_LPASS_CLK_ID_SEC_MI2S_IBIT,
 370                                MI2S_BCLK_RATE, SNDRV_PCM_STREAM_CAPTURE);
 371                }
 372                snd_soc_dai_set_fmt(cpu_dai, fmt);
 373                snd_soc_dai_set_fmt(codec_dai, codec_dai_fmt);
 374                break;
 375        case QUATERNARY_MI2S_RX:
 376                snd_soc_dai_set_sysclk(cpu_dai,
 377                        Q6AFE_LPASS_CLK_ID_QUAD_MI2S_IBIT,
 378                        MI2S_BCLK_RATE, SNDRV_PCM_STREAM_PLAYBACK);
 379                snd_soc_dai_set_fmt(cpu_dai, fmt);
 380                break;
 381
 382        case QUATERNARY_TDM_RX_0:
 383        case QUATERNARY_TDM_TX_0:
 384                if (++(data->quat_tdm_clk_count) == 1) {
 385                        snd_soc_dai_set_sysclk(cpu_dai,
 386                                Q6AFE_LPASS_CLK_ID_QUAD_TDM_IBIT,
 387                                TDM_BCLK_RATE, SNDRV_PCM_STREAM_PLAYBACK);
 388                }
 389
 390                codec_dai_fmt |= SND_SOC_DAIFMT_IB_NF | SND_SOC_DAIFMT_DSP_B;
 391
 392                for_each_rtd_codec_dais(rtd, j, codec_dai) {
 393
 394                        if (!strcmp(codec_dai->component->name_prefix,
 395                                    "Left")) {
 396                                ret = snd_soc_dai_set_fmt(
 397                                                codec_dai, codec_dai_fmt);
 398                                if (ret < 0) {
 399                                        dev_err(rtd->dev,
 400                                                "Left TDM fmt err:%d\n", ret);
 401                                        return ret;
 402                                }
 403                        }
 404
 405                        if (!strcmp(codec_dai->component->name_prefix,
 406                                    "Right")) {
 407                                ret = snd_soc_dai_set_fmt(
 408                                                codec_dai, codec_dai_fmt);
 409                                if (ret < 0) {
 410                                        dev_err(rtd->dev,
 411                                                "Right TDM slot err:%d\n", ret);
 412                                        return ret;
 413                                }
 414                        }
 415                }
 416                break;
 417        case SLIMBUS_0_RX...SLIMBUS_6_TX:
 418                break;
 419
 420        default:
 421                pr_err("%s: invalid dai id 0x%x\n", __func__, cpu_dai->id);
 422                break;
 423        }
 424        return qcom_snd_sdw_startup(substream);
 425}
 426
 427static void  sdm845_snd_shutdown(struct snd_pcm_substream *substream)
 428{
 429        struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream);
 430        struct snd_soc_card *card = rtd->card;
 431        struct sdm845_snd_data *data = snd_soc_card_get_drvdata(card);
 432        struct snd_soc_dai *cpu_dai = snd_soc_rtd_to_cpu(rtd, 0);
 433        struct sdw_stream_runtime *sruntime = data->sruntime[cpu_dai->id];
 434
 435        switch (cpu_dai->id) {
 436        case PRIMARY_MI2S_RX:
 437        case PRIMARY_MI2S_TX:
 438                if (--(data->pri_mi2s_clk_count) == 0) {
 439                        snd_soc_dai_set_sysclk(cpu_dai,
 440                                Q6AFE_LPASS_CLK_ID_MCLK_1,
 441                                0, SNDRV_PCM_STREAM_PLAYBACK);
 442                        snd_soc_dai_set_sysclk(cpu_dai,
 443                                Q6AFE_LPASS_CLK_ID_PRI_MI2S_IBIT,
 444                                0, SNDRV_PCM_STREAM_PLAYBACK);
 445                }
 446                break;
 447
 448        case SECONDARY_MI2S_RX:
 449        case SECONDARY_MI2S_TX:
 450                if (--(data->sec_mi2s_clk_count) == 0) {
 451                        snd_soc_dai_set_sysclk(cpu_dai,
 452                                Q6AFE_LPASS_CLK_ID_SEC_MI2S_IBIT,
 453                                0, SNDRV_PCM_STREAM_CAPTURE);
 454                }
 455                break;
 456
 457        case QUATERNARY_TDM_RX_0:
 458        case QUATERNARY_TDM_TX_0:
 459                if (--(data->quat_tdm_clk_count) == 0) {
 460                        snd_soc_dai_set_sysclk(cpu_dai,
 461                                Q6AFE_LPASS_CLK_ID_QUAD_TDM_IBIT,
 462                                0, SNDRV_PCM_STREAM_PLAYBACK);
 463                }
 464                break;
 465        case SLIMBUS_0_RX...SLIMBUS_6_TX:
 466        case QUATERNARY_MI2S_RX:
 467                break;
 468
 469        default:
 470                pr_err("%s: invalid dai id 0x%x\n", __func__, cpu_dai->id);
 471                break;
 472        }
 473
 474        data->sruntime[cpu_dai->id] = NULL;
 475        sdw_release_stream(sruntime);
 476}
 477
 478static int sdm845_snd_prepare(struct snd_pcm_substream *substream)
 479{
 480        struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream);
 481        struct sdm845_snd_data *data = snd_soc_card_get_drvdata(rtd->card);
 482        struct snd_soc_dai *cpu_dai = snd_soc_rtd_to_cpu(rtd, 0);
 483        struct sdw_stream_runtime *sruntime = data->sruntime[cpu_dai->id];
 484        int ret;
 485
 486        if (!sruntime)
 487                return 0;
 488
 489        if (data->stream_prepared[cpu_dai->id]) {
 490                sdw_disable_stream(sruntime);
 491                sdw_deprepare_stream(sruntime);
 492                data->stream_prepared[cpu_dai->id] = false;
 493        }
 494
 495        ret = sdw_prepare_stream(sruntime);
 496        if (ret)
 497                return ret;
 498
 499        /**
 500         * NOTE: there is a strict hw requirement about the ordering of port
 501         * enables and actual WSA881x PA enable. PA enable should only happen
 502         * after soundwire ports are enabled if not DC on the line is
 503         * accumulated resulting in Click/Pop Noise
 504         * PA enable/mute are handled as part of codec DAPM and digital mute.
 505         */
 506
 507        ret = sdw_enable_stream(sruntime);
 508        if (ret) {
 509                sdw_deprepare_stream(sruntime);
 510                return ret;
 511        }
 512        data->stream_prepared[cpu_dai->id] = true;
 513
 514        return ret;
 515}
 516
 517static int sdm845_snd_hw_free(struct snd_pcm_substream *substream)
 518{
 519        struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream);
 520        struct sdm845_snd_data *data = snd_soc_card_get_drvdata(rtd->card);
 521        struct snd_soc_dai *cpu_dai = snd_soc_rtd_to_cpu(rtd, 0);
 522        struct sdw_stream_runtime *sruntime = data->sruntime[cpu_dai->id];
 523
 524        if (sruntime && data->stream_prepared[cpu_dai->id]) {
 525                sdw_disable_stream(sruntime);
 526                sdw_deprepare_stream(sruntime);
 527                data->stream_prepared[cpu_dai->id] = false;
 528        }
 529
 530        return 0;
 531}
 532
 533static const struct snd_soc_ops sdm845_be_ops = {
 534        .hw_params = sdm845_snd_hw_params,
 535        .hw_free = sdm845_snd_hw_free,
 536        .prepare = sdm845_snd_prepare,
 537        .startup = sdm845_snd_startup,
 538        .shutdown = sdm845_snd_shutdown,
 539};
 540
 541static int sdm845_be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd,
 542                                struct snd_pcm_hw_params *params)
 543{
 544        struct snd_interval *rate = hw_param_interval(params,
 545                                        SNDRV_PCM_HW_PARAM_RATE);
 546        struct snd_interval *channels = hw_param_interval(params,
 547                                        SNDRV_PCM_HW_PARAM_CHANNELS);
 548        struct snd_mask *fmt = hw_param_mask(params, SNDRV_PCM_HW_PARAM_FORMAT);
 549
 550        rate->min = rate->max = DEFAULT_SAMPLE_RATE_48K;
 551        channels->min = channels->max = 2;
 552        snd_mask_set_format(fmt, SNDRV_PCM_FORMAT_S16_LE);
 553
 554        return 0;
 555}
 556
 557static const struct snd_soc_dapm_widget sdm845_snd_widgets[] = {
 558        SND_SOC_DAPM_HP("Headphone Jack", NULL),
 559        SND_SOC_DAPM_MIC("Headset Mic", NULL),
 560        SND_SOC_DAPM_SPK("Left Spk", NULL),
 561        SND_SOC_DAPM_SPK("Right Spk", NULL),
 562        SND_SOC_DAPM_MIC("Int Mic", NULL),
 563};
 564
 565static const struct snd_kcontrol_new sdm845_snd_controls[] = {
 566        SOC_DAPM_PIN_SWITCH("Headphone Jack"),
 567        SOC_DAPM_PIN_SWITCH("Headset Mic"),
 568};
 569
 570static void sdm845_add_ops(struct snd_soc_card *card)
 571{
 572        struct snd_soc_dai_link *link;
 573        int i;
 574
 575        for_each_card_prelinks(card, i, link) {
 576                if (link->no_pcm == 1) {
 577                        link->ops = &sdm845_be_ops;
 578                        link->be_hw_params_fixup = sdm845_be_hw_params_fixup;
 579                }
 580                link->init = sdm845_dai_init;
 581        }
 582}
 583
 584static int sdm845_snd_platform_probe(struct platform_device *pdev)
 585{
 586        struct snd_soc_card *card;
 587        struct sdm845_snd_data *data;
 588        struct device *dev = &pdev->dev;
 589        int ret;
 590
 591        card = devm_kzalloc(dev, sizeof(*card), GFP_KERNEL);
 592        if (!card)
 593                return -ENOMEM;
 594
 595        /* Allocate the private data */
 596        data = devm_kzalloc(dev, sizeof(*data), GFP_KERNEL);
 597        if (!data)
 598                return -ENOMEM;
 599
 600        card->driver_name = DRIVER_NAME;
 601        card->dapm_widgets = sdm845_snd_widgets;
 602        card->num_dapm_widgets = ARRAY_SIZE(sdm845_snd_widgets);
 603        card->controls = sdm845_snd_controls;
 604        card->num_controls = ARRAY_SIZE(sdm845_snd_controls);
 605        card->dev = dev;
 606        card->owner = THIS_MODULE;
 607        dev_set_drvdata(dev, card);
 608        ret = qcom_snd_parse_of(card);
 609        if (ret)
 610                return ret;
 611
 612        data->card = card;
 613        snd_soc_card_set_drvdata(card, data);
 614
 615        sdm845_add_ops(card);
 616        return devm_snd_soc_register_card(dev, card);
 617}
 618
 619static const struct of_device_id sdm845_snd_device_id[]  = {
 620        { .compatible = "qcom,sdm845-sndcard" },
 621        /* Do not grow the list for compatible devices */
 622        { .compatible = "qcom,db845c-sndcard" },
 623        { .compatible = "lenovo,yoga-c630-sndcard" },
 624        {},
 625};
 626MODULE_DEVICE_TABLE(of, sdm845_snd_device_id);
 627
 628static struct platform_driver sdm845_snd_driver = {
 629        .probe = sdm845_snd_platform_probe,
 630        .driver = {
 631                .name = "msm-snd-sdm845",
 632                .of_match_table = sdm845_snd_device_id,
 633        },
 634};
 635module_platform_driver(sdm845_snd_driver);
 636
 637MODULE_DESCRIPTION("sdm845 ASoC Machine Driver");
 638MODULE_LICENSE("GPL");
 639