0001
0002
0003
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
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
0185
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
0232
0233
0234
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
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
0478
0479
0480
0481
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
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");