hc
2024-12-19 9370bb92b2d16684ee45cf24e879c93c509162da
kernel/sound/soc/qcom/sdm845.c
....@@ -6,34 +6,95 @@
66 #include <linux/module.h>
77 #include <linux/platform_device.h>
88 #include <linux/of_device.h>
9
+#include <sound/core.h>
910 #include <sound/pcm.h>
1011 #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>
1116 #include "common.h"
1217 #include "qdsp6/q6afe.h"
18
+#include "../codecs/rt5663.h"
1319
20
+#define DRIVER_NAME "sdm845"
1421 #define DEFAULT_SAMPLE_RATE_48K 48000
1522 #define DEFAULT_MCLK_RATE 24576000
16
-#define DEFAULT_BCLK_RATE 12288000
23
+#define TDM_BCLK_RATE 6144000
24
+#define MI2S_BCLK_RATE 1536000
25
+#define LEFT_SPK_TDM_TX_MASK 0x30
26
+#define RIGHT_SPK_TDM_TX_MASK 0xC0
27
+#define SPK_TDM_RX_MASK 0x03
28
+#define NUM_TDM_SLOTS 8
29
+#define SLIM_MAX_TX_PORTS 16
30
+#define SLIM_MAX_RX_PORTS 13
31
+#define WCD934X_DEFAULT_MCLK_RATE 9600000
1732
1833 struct sdm845_snd_data {
34
+ struct snd_soc_jack jack;
35
+ bool jack_setup;
36
+ bool stream_prepared[AFE_PORT_MAX];
1937 struct snd_soc_card *card;
2038 uint32_t pri_mi2s_clk_count;
39
+ uint32_t sec_mi2s_clk_count;
2140 uint32_t quat_tdm_clk_count;
41
+ struct sdw_stream_runtime *sruntime[AFE_PORT_MAX];
2242 };
2343
2444 static unsigned int tdm_slot_offset[8] = {0, 4, 8, 12, 16, 20, 24, 28};
2545
46
+static int sdm845_slim_snd_hw_params(struct snd_pcm_substream *substream,
47
+ struct snd_pcm_hw_params *params)
48
+{
49
+ struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
50
+ struct snd_soc_dai *cpu_dai = asoc_rtd_to_cpu(rtd, 0);
51
+ struct snd_soc_dai *codec_dai;
52
+ struct sdm845_snd_data *pdata = snd_soc_card_get_drvdata(rtd->card);
53
+ u32 rx_ch[SLIM_MAX_RX_PORTS], tx_ch[SLIM_MAX_TX_PORTS];
54
+ struct sdw_stream_runtime *sruntime;
55
+ u32 rx_ch_cnt = 0, tx_ch_cnt = 0;
56
+ int ret = 0, i;
57
+
58
+ for_each_rtd_codec_dais(rtd, i, codec_dai) {
59
+ sruntime = snd_soc_dai_get_sdw_stream(codec_dai,
60
+ substream->stream);
61
+ if (sruntime != ERR_PTR(-ENOTSUPP))
62
+ pdata->sruntime[cpu_dai->id] = sruntime;
63
+
64
+ ret = snd_soc_dai_get_channel_map(codec_dai,
65
+ &tx_ch_cnt, tx_ch, &rx_ch_cnt, rx_ch);
66
+
67
+ if (ret != 0 && ret != -ENOTSUPP) {
68
+ pr_err("failed to get codec chan map, err:%d\n", ret);
69
+ return ret;
70
+ } else if (ret == -ENOTSUPP) {
71
+ /* Ignore unsupported */
72
+ continue;
73
+ }
74
+
75
+ if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
76
+ ret = snd_soc_dai_set_channel_map(cpu_dai, 0, NULL,
77
+ rx_ch_cnt, rx_ch);
78
+ else
79
+ ret = snd_soc_dai_set_channel_map(cpu_dai, tx_ch_cnt,
80
+ tx_ch, 0, NULL);
81
+ }
82
+
83
+ return 0;
84
+}
85
+
2686 static int sdm845_tdm_snd_hw_params(struct snd_pcm_substream *substream,
2787 struct snd_pcm_hw_params *params)
2888 {
29
- struct snd_soc_pcm_runtime *rtd = substream->private_data;
30
- struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
31
- int ret = 0;
89
+ struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
90
+ struct snd_soc_dai *cpu_dai = asoc_rtd_to_cpu(rtd, 0);
91
+ struct snd_soc_dai *codec_dai;
92
+ int ret = 0, j;
3293 int channels, slot_width;
3394
3495 switch (params_format(params)) {
3596 case SNDRV_PCM_FORMAT_S16_LE:
36
- slot_width = 32;
97
+ slot_width = 16;
3798 break;
3899 default:
39100 dev_err(rtd->dev, "%s: invalid param format 0x%x\n",
....@@ -75,6 +136,34 @@
75136 goto end;
76137 }
77138 }
139
+
140
+ for_each_rtd_codec_dais(rtd, j, codec_dai) {
141
+
142
+ if (!strcmp(codec_dai->component->name_prefix, "Left")) {
143
+ ret = snd_soc_dai_set_tdm_slot(
144
+ codec_dai, LEFT_SPK_TDM_TX_MASK,
145
+ SPK_TDM_RX_MASK, NUM_TDM_SLOTS,
146
+ slot_width);
147
+ if (ret < 0) {
148
+ dev_err(rtd->dev,
149
+ "DEV0 TDM slot err:%d\n", ret);
150
+ return ret;
151
+ }
152
+ }
153
+
154
+ if (!strcmp(codec_dai->component->name_prefix, "Right")) {
155
+ ret = snd_soc_dai_set_tdm_slot(
156
+ codec_dai, RIGHT_SPK_TDM_TX_MASK,
157
+ SPK_TDM_RX_MASK, NUM_TDM_SLOTS,
158
+ slot_width);
159
+ if (ret < 0) {
160
+ dev_err(rtd->dev,
161
+ "DEV1 TDM slot err:%d\n", ret);
162
+ return ret;
163
+ }
164
+ }
165
+ }
166
+
78167 end:
79168 return ret;
80169 }
....@@ -82,14 +171,37 @@
82171 static int sdm845_snd_hw_params(struct snd_pcm_substream *substream,
83172 struct snd_pcm_hw_params *params)
84173 {
85
- struct snd_soc_pcm_runtime *rtd = substream->private_data;
86
- struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
174
+ struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
175
+ struct snd_soc_dai *cpu_dai = asoc_rtd_to_cpu(rtd, 0);
176
+ struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 0);
87177 int ret = 0;
88178
89179 switch (cpu_dai->id) {
180
+ case PRIMARY_MI2S_RX:
181
+ case PRIMARY_MI2S_TX:
182
+ /*
183
+ * Use ASRC for internal clocks, as PLL rate isn't multiple
184
+ * of BCLK.
185
+ */
186
+ rt5663_sel_asrc_clk_src(
187
+ codec_dai->component,
188
+ RT5663_DA_STEREO_FILTER | RT5663_AD_STEREO_FILTER,
189
+ RT5663_CLK_SEL_I2S1_ASRC);
190
+ ret = snd_soc_dai_set_sysclk(
191
+ codec_dai, RT5663_SCLK_S_MCLK, DEFAULT_MCLK_RATE,
192
+ SND_SOC_CLOCK_IN);
193
+ if (ret < 0)
194
+ dev_err(rtd->dev,
195
+ "snd_soc_dai_set_sysclk err = %d\n", ret);
196
+ break;
90197 case QUATERNARY_TDM_RX_0:
91198 case QUATERNARY_TDM_TX_0:
92199 ret = sdm845_tdm_snd_hw_params(substream, params);
200
+ break;
201
+ case SLIMBUS_0_RX...SLIMBUS_6_TX:
202
+ ret = sdm845_slim_snd_hw_params(substream, params);
203
+ break;
204
+ case QUATERNARY_MI2S_RX:
93205 break;
94206 default:
95207 pr_err("%s: invalid dai id 0x%x\n", __func__, cpu_dai->id);
....@@ -98,26 +210,139 @@
98210 return ret;
99211 }
100212
213
+static void sdm845_jack_free(struct snd_jack *jack)
214
+{
215
+ struct snd_soc_component *component = jack->private_data;
216
+
217
+ snd_soc_component_set_jack(component, NULL, NULL);
218
+}
219
+
220
+static int sdm845_dai_init(struct snd_soc_pcm_runtime *rtd)
221
+{
222
+ struct snd_soc_component *component;
223
+ struct snd_soc_card *card = rtd->card;
224
+ struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 0);
225
+ struct snd_soc_dai *cpu_dai = asoc_rtd_to_cpu(rtd, 0);
226
+ struct sdm845_snd_data *pdata = snd_soc_card_get_drvdata(card);
227
+ struct snd_jack *jack;
228
+ /*
229
+ * Codec SLIMBUS configuration
230
+ * RX1, RX2, RX3, RX4, RX5, RX6, RX7, RX8, RX9, RX10, RX11, RX12, RX13
231
+ * TX1, TX2, TX3, TX4, TX5, TX6, TX7, TX8, TX9, TX10, TX11, TX12, TX13
232
+ * TX14, TX15, TX16
233
+ */
234
+ unsigned int rx_ch[SLIM_MAX_RX_PORTS] = {144, 145, 146, 147, 148, 149,
235
+ 150, 151, 152, 153, 154, 155, 156};
236
+ unsigned int tx_ch[SLIM_MAX_TX_PORTS] = {128, 129, 130, 131, 132, 133,
237
+ 134, 135, 136, 137, 138, 139,
238
+ 140, 141, 142, 143};
239
+ int rval, i;
240
+
241
+
242
+ if (!pdata->jack_setup) {
243
+ rval = snd_soc_card_jack_new(card, "Headset Jack",
244
+ SND_JACK_HEADSET |
245
+ SND_JACK_HEADPHONE |
246
+ SND_JACK_BTN_0 | SND_JACK_BTN_1 |
247
+ SND_JACK_BTN_2 | SND_JACK_BTN_3,
248
+ &pdata->jack, NULL, 0);
249
+
250
+ if (rval < 0) {
251
+ dev_err(card->dev, "Unable to add Headphone Jack\n");
252
+ return rval;
253
+ }
254
+
255
+ jack = pdata->jack.jack;
256
+
257
+ snd_jack_set_key(jack, SND_JACK_BTN_0, KEY_PLAYPAUSE);
258
+ snd_jack_set_key(jack, SND_JACK_BTN_1, KEY_VOICECOMMAND);
259
+ snd_jack_set_key(jack, SND_JACK_BTN_2, KEY_VOLUMEUP);
260
+ snd_jack_set_key(jack, SND_JACK_BTN_3, KEY_VOLUMEDOWN);
261
+ pdata->jack_setup = true;
262
+ }
263
+
264
+ switch (cpu_dai->id) {
265
+ case PRIMARY_MI2S_RX:
266
+ jack = pdata->jack.jack;
267
+ component = codec_dai->component;
268
+
269
+ jack->private_data = component;
270
+ jack->private_free = sdm845_jack_free;
271
+ rval = snd_soc_component_set_jack(component,
272
+ &pdata->jack, NULL);
273
+ if (rval != 0 && rval != -ENOTSUPP) {
274
+ dev_warn(card->dev, "Failed to set jack: %d\n", rval);
275
+ return rval;
276
+ }
277
+ break;
278
+ case SLIMBUS_0_RX...SLIMBUS_6_TX:
279
+ for_each_rtd_codec_dais(rtd, i, codec_dai) {
280
+ rval = snd_soc_dai_set_channel_map(codec_dai,
281
+ ARRAY_SIZE(tx_ch),
282
+ tx_ch,
283
+ ARRAY_SIZE(rx_ch),
284
+ rx_ch);
285
+ if (rval != 0 && rval != -ENOTSUPP)
286
+ return rval;
287
+
288
+ snd_soc_dai_set_sysclk(codec_dai, 0,
289
+ WCD934X_DEFAULT_MCLK_RATE,
290
+ SNDRV_PCM_STREAM_PLAYBACK);
291
+ }
292
+ break;
293
+ default:
294
+ break;
295
+ }
296
+
297
+ return 0;
298
+}
299
+
300
+
101301 static int sdm845_snd_startup(struct snd_pcm_substream *substream)
102302 {
103303 unsigned int fmt = SND_SOC_DAIFMT_CBS_CFS;
104
- struct snd_soc_pcm_runtime *rtd = substream->private_data;
304
+ unsigned int codec_dai_fmt = SND_SOC_DAIFMT_CBS_CFS;
305
+ struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
105306 struct snd_soc_card *card = rtd->card;
106307 struct sdm845_snd_data *data = snd_soc_card_get_drvdata(card);
107
- struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
308
+ struct snd_soc_dai *cpu_dai = asoc_rtd_to_cpu(rtd, 0);
309
+ struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 0);
310
+ int j;
311
+ int ret;
108312
109313 switch (cpu_dai->id) {
110314 case PRIMARY_MI2S_RX:
111315 case PRIMARY_MI2S_TX:
316
+ codec_dai_fmt |= SND_SOC_DAIFMT_NB_NF;
112317 if (++(data->pri_mi2s_clk_count) == 1) {
113318 snd_soc_dai_set_sysclk(cpu_dai,
114319 Q6AFE_LPASS_CLK_ID_MCLK_1,
115320 DEFAULT_MCLK_RATE, SNDRV_PCM_STREAM_PLAYBACK);
116321 snd_soc_dai_set_sysclk(cpu_dai,
117322 Q6AFE_LPASS_CLK_ID_PRI_MI2S_IBIT,
118
- DEFAULT_BCLK_RATE, SNDRV_PCM_STREAM_PLAYBACK);
323
+ MI2S_BCLK_RATE, SNDRV_PCM_STREAM_PLAYBACK);
119324 }
120325 snd_soc_dai_set_fmt(cpu_dai, fmt);
326
+ snd_soc_dai_set_fmt(codec_dai, codec_dai_fmt);
327
+ break;
328
+
329
+ case SECONDARY_MI2S_TX:
330
+ codec_dai_fmt |= SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_I2S;
331
+ if (++(data->sec_mi2s_clk_count) == 1) {
332
+ snd_soc_dai_set_sysclk(cpu_dai,
333
+ Q6AFE_LPASS_CLK_ID_SEC_MI2S_IBIT,
334
+ MI2S_BCLK_RATE, SNDRV_PCM_STREAM_CAPTURE);
335
+ }
336
+ snd_soc_dai_set_fmt(cpu_dai, fmt);
337
+ snd_soc_dai_set_fmt(codec_dai, codec_dai_fmt);
338
+ break;
339
+ case QUATERNARY_MI2S_RX:
340
+ snd_soc_dai_set_sysclk(cpu_dai,
341
+ Q6AFE_LPASS_CLK_ID_QUAD_MI2S_IBIT,
342
+ MI2S_BCLK_RATE, SNDRV_PCM_STREAM_PLAYBACK);
343
+ snd_soc_dai_set_fmt(cpu_dai, SND_SOC_DAIFMT_CBS_CFS);
344
+
345
+
121346 break;
122347
123348 case QUATERNARY_TDM_RX_0:
....@@ -125,8 +350,37 @@
125350 if (++(data->quat_tdm_clk_count) == 1) {
126351 snd_soc_dai_set_sysclk(cpu_dai,
127352 Q6AFE_LPASS_CLK_ID_QUAD_TDM_IBIT,
128
- DEFAULT_BCLK_RATE, SNDRV_PCM_STREAM_PLAYBACK);
353
+ TDM_BCLK_RATE, SNDRV_PCM_STREAM_PLAYBACK);
129354 }
355
+
356
+ codec_dai_fmt |= SND_SOC_DAIFMT_IB_NF | SND_SOC_DAIFMT_DSP_B;
357
+
358
+ for_each_rtd_codec_dais(rtd, j, codec_dai) {
359
+
360
+ if (!strcmp(codec_dai->component->name_prefix,
361
+ "Left")) {
362
+ ret = snd_soc_dai_set_fmt(
363
+ codec_dai, codec_dai_fmt);
364
+ if (ret < 0) {
365
+ dev_err(rtd->dev,
366
+ "Left TDM fmt err:%d\n", ret);
367
+ return ret;
368
+ }
369
+ }
370
+
371
+ if (!strcmp(codec_dai->component->name_prefix,
372
+ "Right")) {
373
+ ret = snd_soc_dai_set_fmt(
374
+ codec_dai, codec_dai_fmt);
375
+ if (ret < 0) {
376
+ dev_err(rtd->dev,
377
+ "Right TDM slot err:%d\n", ret);
378
+ return ret;
379
+ }
380
+ }
381
+ }
382
+ break;
383
+ case SLIMBUS_0_RX...SLIMBUS_6_TX:
130384 break;
131385
132386 default:
....@@ -138,10 +392,10 @@
138392
139393 static void sdm845_snd_shutdown(struct snd_pcm_substream *substream)
140394 {
141
- struct snd_soc_pcm_runtime *rtd = substream->private_data;
395
+ struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
142396 struct snd_soc_card *card = rtd->card;
143397 struct sdm845_snd_data *data = snd_soc_card_get_drvdata(card);
144
- struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
398
+ struct snd_soc_dai *cpu_dai = asoc_rtd_to_cpu(rtd, 0);
145399
146400 switch (cpu_dai->id) {
147401 case PRIMARY_MI2S_RX:
....@@ -153,7 +407,15 @@
153407 snd_soc_dai_set_sysclk(cpu_dai,
154408 Q6AFE_LPASS_CLK_ID_PRI_MI2S_IBIT,
155409 0, SNDRV_PCM_STREAM_PLAYBACK);
156
- };
410
+ }
411
+ break;
412
+
413
+ case SECONDARY_MI2S_TX:
414
+ if (--(data->sec_mi2s_clk_count) == 0) {
415
+ snd_soc_dai_set_sysclk(cpu_dai,
416
+ Q6AFE_LPASS_CLK_ID_SEC_MI2S_IBIT,
417
+ 0, SNDRV_PCM_STREAM_CAPTURE);
418
+ }
157419 break;
158420
159421 case QUATERNARY_TDM_RX_0:
....@@ -164,6 +426,9 @@
164426 0, SNDRV_PCM_STREAM_PLAYBACK);
165427 }
166428 break;
429
+ case SLIMBUS_0_RX...SLIMBUS_6_TX:
430
+ case QUATERNARY_MI2S_RX:
431
+ break;
167432
168433 default:
169434 pr_err("%s: invalid dai id 0x%x\n", __func__, cpu_dai->id);
....@@ -171,8 +436,65 @@
171436 }
172437 }
173438
174
-static struct snd_soc_ops sdm845_be_ops = {
439
+static int sdm845_snd_prepare(struct snd_pcm_substream *substream)
440
+{
441
+ struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
442
+ struct sdm845_snd_data *data = snd_soc_card_get_drvdata(rtd->card);
443
+ struct snd_soc_dai *cpu_dai = asoc_rtd_to_cpu(rtd, 0);
444
+ struct sdw_stream_runtime *sruntime = data->sruntime[cpu_dai->id];
445
+ int ret;
446
+
447
+ if (!sruntime)
448
+ return 0;
449
+
450
+ if (data->stream_prepared[cpu_dai->id]) {
451
+ sdw_disable_stream(sruntime);
452
+ sdw_deprepare_stream(sruntime);
453
+ data->stream_prepared[cpu_dai->id] = false;
454
+ }
455
+
456
+ ret = sdw_prepare_stream(sruntime);
457
+ if (ret)
458
+ return ret;
459
+
460
+ /**
461
+ * NOTE: there is a strict hw requirement about the ordering of port
462
+ * enables and actual WSA881x PA enable. PA enable should only happen
463
+ * after soundwire ports are enabled if not DC on the line is
464
+ * accumulated resulting in Click/Pop Noise
465
+ * PA enable/mute are handled as part of codec DAPM and digital mute.
466
+ */
467
+
468
+ ret = sdw_enable_stream(sruntime);
469
+ if (ret) {
470
+ sdw_deprepare_stream(sruntime);
471
+ return ret;
472
+ }
473
+ data->stream_prepared[cpu_dai->id] = true;
474
+
475
+ return ret;
476
+}
477
+
478
+static int sdm845_snd_hw_free(struct snd_pcm_substream *substream)
479
+{
480
+ struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
481
+ struct sdm845_snd_data *data = snd_soc_card_get_drvdata(rtd->card);
482
+ struct snd_soc_dai *cpu_dai = asoc_rtd_to_cpu(rtd, 0);
483
+ struct sdw_stream_runtime *sruntime = data->sruntime[cpu_dai->id];
484
+
485
+ if (sruntime && data->stream_prepared[cpu_dai->id]) {
486
+ sdw_disable_stream(sruntime);
487
+ sdw_deprepare_stream(sruntime);
488
+ data->stream_prepared[cpu_dai->id] = false;
489
+ }
490
+
491
+ return 0;
492
+}
493
+
494
+static const struct snd_soc_ops sdm845_be_ops = {
175495 .hw_params = sdm845_snd_hw_params,
496
+ .hw_free = sdm845_snd_hw_free,
497
+ .prepare = sdm845_snd_prepare,
176498 .startup = sdm845_snd_startup,
177499 .shutdown = sdm845_snd_shutdown,
178500 };
....@@ -193,17 +515,25 @@
193515 return 0;
194516 }
195517
196
-static void sdm845_add_be_ops(struct snd_soc_card *card)
197
-{
198
- struct snd_soc_dai_link *link = card->dai_link;
199
- int i, num_links = card->num_links;
518
+static const struct snd_soc_dapm_widget sdm845_snd_widgets[] = {
519
+ SND_SOC_DAPM_HP("Headphone Jack", NULL),
520
+ SND_SOC_DAPM_MIC("Headset Mic", NULL),
521
+ SND_SOC_DAPM_SPK("Left Spk", NULL),
522
+ SND_SOC_DAPM_SPK("Right Spk", NULL),
523
+ SND_SOC_DAPM_MIC("Int Mic", NULL),
524
+};
200525
201
- for (i = 0; i < num_links; i++) {
526
+static void sdm845_add_ops(struct snd_soc_card *card)
527
+{
528
+ struct snd_soc_dai_link *link;
529
+ int i;
530
+
531
+ for_each_card_prelinks(card, i, link) {
202532 if (link->no_pcm == 1) {
203533 link->ops = &sdm845_be_ops;
204534 link->be_hw_params_fixup = sdm845_be_hw_params_fixup;
205535 }
206
- link++;
536
+ link->init = sdm845_dai_init;
207537 }
208538 }
209539
....@@ -214,67 +544,42 @@
214544 struct device *dev = &pdev->dev;
215545 int ret;
216546
217
- card = kzalloc(sizeof(*card), GFP_KERNEL);
547
+ card = devm_kzalloc(dev, sizeof(*card), GFP_KERNEL);
218548 if (!card)
219549 return -ENOMEM;
220550
221551 /* Allocate the private data */
222
- data = kzalloc(sizeof(*data), GFP_KERNEL);
223
- if (!data) {
224
- ret = -ENOMEM;
225
- goto data_alloc_fail;
226
- }
552
+ data = devm_kzalloc(dev, sizeof(*data), GFP_KERNEL);
553
+ if (!data)
554
+ return -ENOMEM;
227555
556
+ card->driver_name = DRIVER_NAME;
557
+ card->dapm_widgets = sdm845_snd_widgets;
558
+ card->num_dapm_widgets = ARRAY_SIZE(sdm845_snd_widgets);
228559 card->dev = dev;
229560 card->owner = THIS_MODULE;
230561 dev_set_drvdata(dev, card);
231562 ret = qcom_snd_parse_of(card);
232
- if (ret) {
233
- dev_err(dev, "Error parsing OF data\n");
234
- goto parse_dt_fail;
235
- }
563
+ if (ret)
564
+ return ret;
236565
237566 data->card = card;
238567 snd_soc_card_set_drvdata(card, data);
239568
240
- sdm845_add_be_ops(card);
241
- ret = snd_soc_register_card(card);
242
- if (ret) {
243
- dev_err(dev, "Sound card registration failed\n");
244
- goto register_card_fail;
245
- }
246
- return ret;
247
-
248
-register_card_fail:
249
- kfree(card->dai_link);
250
-parse_dt_fail:
251
- kfree(data);
252
-data_alloc_fail:
253
- kfree(card);
254
- return ret;
255
-}
256
-
257
-static int sdm845_snd_platform_remove(struct platform_device *pdev)
258
-{
259
- struct snd_soc_card *card = dev_get_drvdata(&pdev->dev);
260
- struct sdm845_snd_data *data = snd_soc_card_get_drvdata(card);
261
-
262
- snd_soc_unregister_card(card);
263
- kfree(card->dai_link);
264
- kfree(data);
265
- kfree(card);
266
- return 0;
569
+ sdm845_add_ops(card);
570
+ return devm_snd_soc_register_card(dev, card);
267571 }
268572
269573 static const struct of_device_id sdm845_snd_device_id[] = {
270574 { .compatible = "qcom,sdm845-sndcard" },
575
+ { .compatible = "qcom,db845c-sndcard" },
576
+ { .compatible = "lenovo,yoga-c630-sndcard" },
271577 {},
272578 };
273579 MODULE_DEVICE_TABLE(of, sdm845_snd_device_id);
274580
275581 static struct platform_driver sdm845_snd_driver = {
276582 .probe = sdm845_snd_platform_probe,
277
- .remove = sdm845_snd_platform_remove,
278583 .driver = {
279584 .name = "msm-snd-sdm845",
280585 .of_match_table = sdm845_snd_device_id,