Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0
0002 /*
0003  * Copyright (c) 2018, The Linux Foundation. All rights reserved.
0004  */
0005 
0006 #include <linux/module.h>
0007 #include <linux/platform_device.h>
0008 #include <linux/of_device.h>
0009 #include <sound/core.h>
0010 #include <sound/pcm.h>
0011 #include <sound/pcm_params.h>
0012 #include <sound/jack.h>
0013 #include <sound/soc.h>
0014 #include <linux/soundwire/sdw.h>
0015 #include <uapi/linux/input-event-codes.h>
0016 #include "common.h"
0017 #include "qdsp6/q6afe.h"
0018 #include "../codecs/rt5663.h"
0019 
0020 #define DRIVER_NAME "sdm845"
0021 #define DEFAULT_SAMPLE_RATE_48K     48000
0022 #define DEFAULT_MCLK_RATE       24576000
0023 #define TDM_BCLK_RATE       6144000
0024 #define MI2S_BCLK_RATE      1536000
0025 #define LEFT_SPK_TDM_TX_MASK    0x30
0026 #define RIGHT_SPK_TDM_TX_MASK   0xC0
0027 #define SPK_TDM_RX_MASK         0x03
0028 #define NUM_TDM_SLOTS           8
0029 #define SLIM_MAX_TX_PORTS 16
0030 #define SLIM_MAX_RX_PORTS 13
0031 #define WCD934X_DEFAULT_MCLK_RATE   9600000
0032 
0033 struct sdm845_snd_data {
0034     struct snd_soc_jack jack;
0035     bool jack_setup;
0036     bool slim_port_setup;
0037     bool stream_prepared[AFE_PORT_MAX];
0038     struct snd_soc_card *card;
0039     uint32_t pri_mi2s_clk_count;
0040     uint32_t sec_mi2s_clk_count;
0041     uint32_t quat_tdm_clk_count;
0042     struct sdw_stream_runtime *sruntime[AFE_PORT_MAX];
0043 };
0044 
0045 static unsigned int tdm_slot_offset[8] = {0, 4, 8, 12, 16, 20, 24, 28};
0046 
0047 static int sdm845_slim_snd_hw_params(struct snd_pcm_substream *substream,
0048                      struct snd_pcm_hw_params *params)
0049 {
0050     struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
0051     struct snd_soc_dai *cpu_dai = asoc_rtd_to_cpu(rtd, 0);
0052     struct snd_soc_dai *codec_dai;
0053     struct sdm845_snd_data *pdata = snd_soc_card_get_drvdata(rtd->card);
0054     u32 rx_ch[SLIM_MAX_RX_PORTS], tx_ch[SLIM_MAX_TX_PORTS];
0055     struct sdw_stream_runtime *sruntime;
0056     u32 rx_ch_cnt = 0, tx_ch_cnt = 0;
0057     int ret = 0, i;
0058 
0059     for_each_rtd_codec_dais(rtd, i, codec_dai) {
0060         sruntime = snd_soc_dai_get_stream(codec_dai,
0061                           substream->stream);
0062         if (sruntime != ERR_PTR(-ENOTSUPP))
0063             pdata->sruntime[cpu_dai->id] = sruntime;
0064 
0065         ret = snd_soc_dai_get_channel_map(codec_dai,
0066                 &tx_ch_cnt, tx_ch, &rx_ch_cnt, rx_ch);
0067 
0068         if (ret != 0 && ret != -ENOTSUPP) {
0069             pr_err("failed to get codec chan map, err:%d\n", ret);
0070             return ret;
0071         } else if (ret == -ENOTSUPP) {
0072             /* Ignore unsupported */
0073             continue;
0074         }
0075 
0076         if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
0077             ret = snd_soc_dai_set_channel_map(cpu_dai, 0, NULL,
0078                               rx_ch_cnt, rx_ch);
0079         else
0080             ret = snd_soc_dai_set_channel_map(cpu_dai, tx_ch_cnt,
0081                               tx_ch, 0, NULL);
0082     }
0083 
0084     return 0;
0085 }
0086 
0087 static int sdm845_tdm_snd_hw_params(struct snd_pcm_substream *substream,
0088                     struct snd_pcm_hw_params *params)
0089 {
0090     struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
0091     struct snd_soc_dai *cpu_dai = asoc_rtd_to_cpu(rtd, 0);
0092     struct snd_soc_dai *codec_dai;
0093     int ret = 0, j;
0094     int channels, slot_width;
0095 
0096     switch (params_format(params)) {
0097     case SNDRV_PCM_FORMAT_S16_LE:
0098         slot_width = 16;
0099         break;
0100     default:
0101         dev_err(rtd->dev, "%s: invalid param format 0x%x\n",
0102                 __func__, params_format(params));
0103         return -EINVAL;
0104     }
0105 
0106     channels = params_channels(params);
0107     if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
0108         ret = snd_soc_dai_set_tdm_slot(cpu_dai, 0, 0x3,
0109                 8, slot_width);
0110         if (ret < 0) {
0111             dev_err(rtd->dev, "%s: failed to set tdm slot, err:%d\n",
0112                     __func__, ret);
0113             goto end;
0114         }
0115 
0116         ret = snd_soc_dai_set_channel_map(cpu_dai, 0, NULL,
0117                 channels, tdm_slot_offset);
0118         if (ret < 0) {
0119             dev_err(rtd->dev, "%s: failed to set channel map, err:%d\n",
0120                     __func__, ret);
0121             goto end;
0122         }
0123     } else {
0124         ret = snd_soc_dai_set_tdm_slot(cpu_dai, 0xf, 0,
0125                 8, slot_width);
0126         if (ret < 0) {
0127             dev_err(rtd->dev, "%s: failed to set tdm slot, err:%d\n",
0128                     __func__, ret);
0129             goto end;
0130         }
0131 
0132         ret = snd_soc_dai_set_channel_map(cpu_dai, channels,
0133                 tdm_slot_offset, 0, NULL);
0134         if (ret < 0) {
0135             dev_err(rtd->dev, "%s: failed to set channel map, err:%d\n",
0136                     __func__, ret);
0137             goto end;
0138         }
0139     }
0140 
0141     for_each_rtd_codec_dais(rtd, j, codec_dai) {
0142 
0143         if (!strcmp(codec_dai->component->name_prefix, "Left")) {
0144             ret = snd_soc_dai_set_tdm_slot(
0145                     codec_dai, LEFT_SPK_TDM_TX_MASK,
0146                     SPK_TDM_RX_MASK, NUM_TDM_SLOTS,
0147                     slot_width);
0148             if (ret < 0) {
0149                 dev_err(rtd->dev,
0150                     "DEV0 TDM slot err:%d\n", ret);
0151                 return ret;
0152             }
0153         }
0154 
0155         if (!strcmp(codec_dai->component->name_prefix, "Right")) {
0156             ret = snd_soc_dai_set_tdm_slot(
0157                     codec_dai, RIGHT_SPK_TDM_TX_MASK,
0158                     SPK_TDM_RX_MASK, NUM_TDM_SLOTS,
0159                     slot_width);
0160             if (ret < 0) {
0161                 dev_err(rtd->dev,
0162                     "DEV1 TDM slot err:%d\n", ret);
0163                 return ret;
0164             }
0165         }
0166     }
0167 
0168 end:
0169     return ret;
0170 }
0171 
0172 static int sdm845_snd_hw_params(struct snd_pcm_substream *substream,
0173                     struct snd_pcm_hw_params *params)
0174 {
0175     struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
0176     struct snd_soc_dai *cpu_dai = asoc_rtd_to_cpu(rtd, 0);
0177     struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 0);
0178     int ret = 0;
0179 
0180     switch (cpu_dai->id) {
0181     case PRIMARY_MI2S_RX:
0182     case PRIMARY_MI2S_TX:
0183         /*
0184          * Use ASRC for internal clocks, as PLL rate isn't multiple
0185          * of BCLK.
0186          */
0187         rt5663_sel_asrc_clk_src(
0188             codec_dai->component,
0189             RT5663_DA_STEREO_FILTER | RT5663_AD_STEREO_FILTER,
0190             RT5663_CLK_SEL_I2S1_ASRC);
0191         ret = snd_soc_dai_set_sysclk(
0192             codec_dai, RT5663_SCLK_S_MCLK, DEFAULT_MCLK_RATE,
0193             SND_SOC_CLOCK_IN);
0194         if (ret < 0)
0195             dev_err(rtd->dev,
0196                 "snd_soc_dai_set_sysclk err = %d\n", ret);
0197         break;
0198     case QUATERNARY_TDM_RX_0:
0199     case QUATERNARY_TDM_TX_0:
0200         ret = sdm845_tdm_snd_hw_params(substream, params);
0201         break;
0202     case SLIMBUS_0_RX...SLIMBUS_6_TX:
0203         ret = sdm845_slim_snd_hw_params(substream, params);
0204         break;
0205     case QUATERNARY_MI2S_RX:
0206         break;
0207     default:
0208         pr_err("%s: invalid dai id 0x%x\n", __func__, cpu_dai->id);
0209         break;
0210     }
0211     return ret;
0212 }
0213 
0214 static void sdm845_jack_free(struct snd_jack *jack)
0215 {
0216     struct snd_soc_component *component = jack->private_data;
0217 
0218     snd_soc_component_set_jack(component, NULL, NULL);
0219 }
0220 
0221 static int sdm845_dai_init(struct snd_soc_pcm_runtime *rtd)
0222 {
0223     struct snd_soc_component *component;
0224     struct snd_soc_card *card = rtd->card;
0225     struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 0);
0226     struct snd_soc_dai *cpu_dai = asoc_rtd_to_cpu(rtd, 0);
0227     struct sdm845_snd_data *pdata = snd_soc_card_get_drvdata(card);
0228     struct snd_soc_dai_link *link = rtd->dai_link;
0229     struct snd_jack *jack;
0230     /*
0231      * Codec SLIMBUS configuration
0232      * RX1, RX2, RX3, RX4, RX5, RX6, RX7, RX8, RX9, RX10, RX11, RX12, RX13
0233      * TX1, TX2, TX3, TX4, TX5, TX6, TX7, TX8, TX9, TX10, TX11, TX12, TX13
0234      * TX14, TX15, TX16
0235      */
0236     unsigned int rx_ch[SLIM_MAX_RX_PORTS] = {144, 145, 146, 147, 148, 149,
0237                     150, 151, 152, 153, 154, 155, 156};
0238     unsigned int tx_ch[SLIM_MAX_TX_PORTS] = {128, 129, 130, 131, 132, 133,
0239                         134, 135, 136, 137, 138, 139,
0240                         140, 141, 142, 143};
0241     int rval, i;
0242 
0243 
0244     if (!pdata->jack_setup) {
0245         rval = snd_soc_card_jack_new(card, "Headset Jack",
0246                 SND_JACK_HEADSET |
0247                 SND_JACK_HEADPHONE |
0248                 SND_JACK_BTN_0 | SND_JACK_BTN_1 |
0249                 SND_JACK_BTN_2 | SND_JACK_BTN_3,
0250                 &pdata->jack);
0251 
0252         if (rval < 0) {
0253             dev_err(card->dev, "Unable to add Headphone Jack\n");
0254             return rval;
0255         }
0256 
0257         jack = pdata->jack.jack;
0258 
0259         snd_jack_set_key(jack, SND_JACK_BTN_0, KEY_PLAYPAUSE);
0260         snd_jack_set_key(jack, SND_JACK_BTN_1, KEY_VOICECOMMAND);
0261         snd_jack_set_key(jack, SND_JACK_BTN_2, KEY_VOLUMEUP);
0262         snd_jack_set_key(jack, SND_JACK_BTN_3, KEY_VOLUMEDOWN);
0263         pdata->jack_setup = true;
0264     }
0265 
0266     switch (cpu_dai->id) {
0267     case PRIMARY_MI2S_RX:
0268         jack  = pdata->jack.jack;
0269         component = codec_dai->component;
0270 
0271         jack->private_data = component;
0272         jack->private_free = sdm845_jack_free;
0273         rval = snd_soc_component_set_jack(component,
0274                           &pdata->jack, NULL);
0275         if (rval != 0 && rval != -ENOTSUPP) {
0276             dev_warn(card->dev, "Failed to set jack: %d\n", rval);
0277             return rval;
0278         }
0279         break;
0280     case SLIMBUS_0_RX...SLIMBUS_6_TX:
0281         /* setting up wcd multiple times for slim port is redundant */
0282         if (pdata->slim_port_setup || !link->no_pcm)
0283             return 0;
0284 
0285         for_each_rtd_codec_dais(rtd, i, codec_dai) {
0286             rval = snd_soc_dai_set_channel_map(codec_dai,
0287                               ARRAY_SIZE(tx_ch),
0288                               tx_ch,
0289                               ARRAY_SIZE(rx_ch),
0290                               rx_ch);
0291             if (rval != 0 && rval != -ENOTSUPP)
0292                 return rval;
0293 
0294             snd_soc_dai_set_sysclk(codec_dai, 0,
0295                            WCD934X_DEFAULT_MCLK_RATE,
0296                            SNDRV_PCM_STREAM_PLAYBACK);
0297 
0298             rval = snd_soc_component_set_jack(codec_dai->component,
0299                               &pdata->jack, NULL);
0300             if (rval != 0 && rval != -ENOTSUPP) {
0301                 dev_warn(card->dev, "Failed to set jack: %d\n", rval);
0302                 return rval;
0303             }
0304         }
0305 
0306         pdata->slim_port_setup = true;
0307 
0308         break;
0309     default:
0310         break;
0311     }
0312 
0313     return 0;
0314 }
0315 
0316 
0317 static int sdm845_snd_startup(struct snd_pcm_substream *substream)
0318 {
0319     unsigned int fmt = SND_SOC_DAIFMT_BP_FP;
0320     unsigned int codec_dai_fmt = SND_SOC_DAIFMT_BC_FC;
0321     struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
0322     struct snd_soc_card *card = rtd->card;
0323     struct sdm845_snd_data *data = snd_soc_card_get_drvdata(card);
0324     struct snd_soc_dai *cpu_dai = asoc_rtd_to_cpu(rtd, 0);
0325     struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 0);
0326     int j;
0327     int ret;
0328 
0329     switch (cpu_dai->id) {
0330     case PRIMARY_MI2S_RX:
0331     case PRIMARY_MI2S_TX:
0332         codec_dai_fmt |= SND_SOC_DAIFMT_NB_NF;
0333         if (++(data->pri_mi2s_clk_count) == 1) {
0334             snd_soc_dai_set_sysclk(cpu_dai,
0335                 Q6AFE_LPASS_CLK_ID_MCLK_1,
0336                 DEFAULT_MCLK_RATE, SNDRV_PCM_STREAM_PLAYBACK);
0337             snd_soc_dai_set_sysclk(cpu_dai,
0338                 Q6AFE_LPASS_CLK_ID_PRI_MI2S_IBIT,
0339                 MI2S_BCLK_RATE, SNDRV_PCM_STREAM_PLAYBACK);
0340         }
0341         snd_soc_dai_set_fmt(cpu_dai, fmt);
0342         snd_soc_dai_set_fmt(codec_dai, codec_dai_fmt);
0343         break;
0344 
0345     case SECONDARY_MI2S_TX:
0346         codec_dai_fmt |= SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_I2S;
0347         if (++(data->sec_mi2s_clk_count) == 1) {
0348             snd_soc_dai_set_sysclk(cpu_dai,
0349                 Q6AFE_LPASS_CLK_ID_SEC_MI2S_IBIT,
0350                 MI2S_BCLK_RATE, SNDRV_PCM_STREAM_CAPTURE);
0351         }
0352         snd_soc_dai_set_fmt(cpu_dai, fmt);
0353         snd_soc_dai_set_fmt(codec_dai, codec_dai_fmt);
0354         break;
0355     case QUATERNARY_MI2S_RX:
0356         snd_soc_dai_set_sysclk(cpu_dai,
0357             Q6AFE_LPASS_CLK_ID_QUAD_MI2S_IBIT,
0358             MI2S_BCLK_RATE, SNDRV_PCM_STREAM_PLAYBACK);
0359         snd_soc_dai_set_fmt(cpu_dai, fmt);
0360 
0361 
0362         break;
0363 
0364     case QUATERNARY_TDM_RX_0:
0365     case QUATERNARY_TDM_TX_0:
0366         if (++(data->quat_tdm_clk_count) == 1) {
0367             snd_soc_dai_set_sysclk(cpu_dai,
0368                 Q6AFE_LPASS_CLK_ID_QUAD_TDM_IBIT,
0369                 TDM_BCLK_RATE, SNDRV_PCM_STREAM_PLAYBACK);
0370         }
0371 
0372         codec_dai_fmt |= SND_SOC_DAIFMT_IB_NF | SND_SOC_DAIFMT_DSP_B;
0373 
0374         for_each_rtd_codec_dais(rtd, j, codec_dai) {
0375 
0376             if (!strcmp(codec_dai->component->name_prefix,
0377                     "Left")) {
0378                 ret = snd_soc_dai_set_fmt(
0379                         codec_dai, codec_dai_fmt);
0380                 if (ret < 0) {
0381                     dev_err(rtd->dev,
0382                         "Left TDM fmt err:%d\n", ret);
0383                     return ret;
0384                 }
0385             }
0386 
0387             if (!strcmp(codec_dai->component->name_prefix,
0388                     "Right")) {
0389                 ret = snd_soc_dai_set_fmt(
0390                         codec_dai, codec_dai_fmt);
0391                 if (ret < 0) {
0392                     dev_err(rtd->dev,
0393                         "Right TDM slot err:%d\n", ret);
0394                     return ret;
0395                 }
0396             }
0397         }
0398         break;
0399     case SLIMBUS_0_RX...SLIMBUS_6_TX:
0400         break;
0401 
0402     default:
0403         pr_err("%s: invalid dai id 0x%x\n", __func__, cpu_dai->id);
0404         break;
0405     }
0406     return 0;
0407 }
0408 
0409 static void  sdm845_snd_shutdown(struct snd_pcm_substream *substream)
0410 {
0411     struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
0412     struct snd_soc_card *card = rtd->card;
0413     struct sdm845_snd_data *data = snd_soc_card_get_drvdata(card);
0414     struct snd_soc_dai *cpu_dai = asoc_rtd_to_cpu(rtd, 0);
0415 
0416     switch (cpu_dai->id) {
0417     case PRIMARY_MI2S_RX:
0418     case PRIMARY_MI2S_TX:
0419         if (--(data->pri_mi2s_clk_count) == 0) {
0420             snd_soc_dai_set_sysclk(cpu_dai,
0421                 Q6AFE_LPASS_CLK_ID_MCLK_1,
0422                 0, SNDRV_PCM_STREAM_PLAYBACK);
0423             snd_soc_dai_set_sysclk(cpu_dai,
0424                 Q6AFE_LPASS_CLK_ID_PRI_MI2S_IBIT,
0425                 0, SNDRV_PCM_STREAM_PLAYBACK);
0426         }
0427         break;
0428 
0429     case SECONDARY_MI2S_TX:
0430         if (--(data->sec_mi2s_clk_count) == 0) {
0431             snd_soc_dai_set_sysclk(cpu_dai,
0432                 Q6AFE_LPASS_CLK_ID_SEC_MI2S_IBIT,
0433                 0, SNDRV_PCM_STREAM_CAPTURE);
0434         }
0435         break;
0436 
0437     case QUATERNARY_TDM_RX_0:
0438     case QUATERNARY_TDM_TX_0:
0439         if (--(data->quat_tdm_clk_count) == 0) {
0440             snd_soc_dai_set_sysclk(cpu_dai,
0441                 Q6AFE_LPASS_CLK_ID_QUAD_TDM_IBIT,
0442                 0, SNDRV_PCM_STREAM_PLAYBACK);
0443         }
0444         break;
0445     case SLIMBUS_0_RX...SLIMBUS_6_TX:
0446     case QUATERNARY_MI2S_RX:
0447         break;
0448 
0449     default:
0450         pr_err("%s: invalid dai id 0x%x\n", __func__, cpu_dai->id);
0451         break;
0452     }
0453 }
0454 
0455 static int sdm845_snd_prepare(struct snd_pcm_substream *substream)
0456 {
0457     struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
0458     struct sdm845_snd_data *data = snd_soc_card_get_drvdata(rtd->card);
0459     struct snd_soc_dai *cpu_dai = asoc_rtd_to_cpu(rtd, 0);
0460     struct sdw_stream_runtime *sruntime = data->sruntime[cpu_dai->id];
0461     int ret;
0462 
0463     if (!sruntime)
0464         return 0;
0465 
0466     if (data->stream_prepared[cpu_dai->id]) {
0467         sdw_disable_stream(sruntime);
0468         sdw_deprepare_stream(sruntime);
0469         data->stream_prepared[cpu_dai->id] = false;
0470     }
0471 
0472     ret = sdw_prepare_stream(sruntime);
0473     if (ret)
0474         return ret;
0475 
0476     /**
0477      * NOTE: there is a strict hw requirement about the ordering of port
0478      * enables and actual WSA881x PA enable. PA enable should only happen
0479      * after soundwire ports are enabled if not DC on the line is
0480      * accumulated resulting in Click/Pop Noise
0481      * PA enable/mute are handled as part of codec DAPM and digital mute.
0482      */
0483 
0484     ret = sdw_enable_stream(sruntime);
0485     if (ret) {
0486         sdw_deprepare_stream(sruntime);
0487         return ret;
0488     }
0489     data->stream_prepared[cpu_dai->id] = true;
0490 
0491     return ret;
0492 }
0493 
0494 static int sdm845_snd_hw_free(struct snd_pcm_substream *substream)
0495 {
0496     struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
0497     struct sdm845_snd_data *data = snd_soc_card_get_drvdata(rtd->card);
0498     struct snd_soc_dai *cpu_dai = asoc_rtd_to_cpu(rtd, 0);
0499     struct sdw_stream_runtime *sruntime = data->sruntime[cpu_dai->id];
0500 
0501     if (sruntime && data->stream_prepared[cpu_dai->id]) {
0502         sdw_disable_stream(sruntime);
0503         sdw_deprepare_stream(sruntime);
0504         data->stream_prepared[cpu_dai->id] = false;
0505     }
0506 
0507     return 0;
0508 }
0509 
0510 static const struct snd_soc_ops sdm845_be_ops = {
0511     .hw_params = sdm845_snd_hw_params,
0512     .hw_free = sdm845_snd_hw_free,
0513     .prepare = sdm845_snd_prepare,
0514     .startup = sdm845_snd_startup,
0515     .shutdown = sdm845_snd_shutdown,
0516 };
0517 
0518 static int sdm845_be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd,
0519                 struct snd_pcm_hw_params *params)
0520 {
0521     struct snd_interval *rate = hw_param_interval(params,
0522                     SNDRV_PCM_HW_PARAM_RATE);
0523     struct snd_interval *channels = hw_param_interval(params,
0524                     SNDRV_PCM_HW_PARAM_CHANNELS);
0525     struct snd_mask *fmt = hw_param_mask(params, SNDRV_PCM_HW_PARAM_FORMAT);
0526 
0527     rate->min = rate->max = DEFAULT_SAMPLE_RATE_48K;
0528     channels->min = channels->max = 2;
0529     snd_mask_set_format(fmt, SNDRV_PCM_FORMAT_S16_LE);
0530 
0531     return 0;
0532 }
0533 
0534 static const struct snd_soc_dapm_widget sdm845_snd_widgets[] = {
0535     SND_SOC_DAPM_HP("Headphone Jack", NULL),
0536     SND_SOC_DAPM_MIC("Headset Mic", NULL),
0537     SND_SOC_DAPM_SPK("Left Spk", NULL),
0538     SND_SOC_DAPM_SPK("Right Spk", NULL),
0539     SND_SOC_DAPM_MIC("Int Mic", NULL),
0540 };
0541 
0542 static void sdm845_add_ops(struct snd_soc_card *card)
0543 {
0544     struct snd_soc_dai_link *link;
0545     int i;
0546 
0547     for_each_card_prelinks(card, i, link) {
0548         if (link->no_pcm == 1) {
0549             link->ops = &sdm845_be_ops;
0550             link->be_hw_params_fixup = sdm845_be_hw_params_fixup;
0551         }
0552         link->init = sdm845_dai_init;
0553     }
0554 }
0555 
0556 static int sdm845_snd_platform_probe(struct platform_device *pdev)
0557 {
0558     struct snd_soc_card *card;
0559     struct sdm845_snd_data *data;
0560     struct device *dev = &pdev->dev;
0561     int ret;
0562 
0563     card = devm_kzalloc(dev, sizeof(*card), GFP_KERNEL);
0564     if (!card)
0565         return -ENOMEM;
0566 
0567     /* Allocate the private data */
0568     data = devm_kzalloc(dev, sizeof(*data), GFP_KERNEL);
0569     if (!data)
0570         return -ENOMEM;
0571 
0572     card->driver_name = DRIVER_NAME;
0573     card->dapm_widgets = sdm845_snd_widgets;
0574     card->num_dapm_widgets = ARRAY_SIZE(sdm845_snd_widgets);
0575     card->dev = dev;
0576     card->owner = THIS_MODULE;
0577     dev_set_drvdata(dev, card);
0578     ret = qcom_snd_parse_of(card);
0579     if (ret)
0580         return ret;
0581 
0582     data->card = card;
0583     snd_soc_card_set_drvdata(card, data);
0584 
0585     sdm845_add_ops(card);
0586     return devm_snd_soc_register_card(dev, card);
0587 }
0588 
0589 static const struct of_device_id sdm845_snd_device_id[]  = {
0590     { .compatible = "qcom,sdm845-sndcard" },
0591     { .compatible = "qcom,db845c-sndcard" },
0592     { .compatible = "lenovo,yoga-c630-sndcard" },
0593     {},
0594 };
0595 MODULE_DEVICE_TABLE(of, sdm845_snd_device_id);
0596 
0597 static struct platform_driver sdm845_snd_driver = {
0598     .probe = sdm845_snd_platform_probe,
0599     .driver = {
0600         .name = "msm-snd-sdm845",
0601         .of_match_table = sdm845_snd_device_id,
0602     },
0603 };
0604 module_platform_driver(sdm845_snd_driver);
0605 
0606 MODULE_DESCRIPTION("sdm845 ASoC Machine Driver");
0607 MODULE_LICENSE("GPL v2");