1 // SPDX-License-Identifier: GPL-2.0 2 // Copyright (c) 2022, Linaro Limited 3 4 #include <dt-bindings/sound/qcom,q6afe.h> 5 #include <linux/module.h> 6 #include <linux/platform_device.h> 7 #include <sound/soc.h> 8 #include <sound/soc-dapm.h> 9 #include <sound/pcm.h> 10 #include <sound/pcm_params.h> 11 #include <linux/soundwire/sdw.h> 12 #include <sound/jack.h> 13 #include <linux/input-event-codes.h> 14 #include "qdsp6/q6afe.h" 15 #include "qdsp6/q6apm.h" 16 #include "qdsp6/q6prm.h" 17 #include "qdsp6/q6dsp-common.h" 18 #include "common.h" 19 #include "sdw.h" 20 21 #define I2S_MCLKFS 256 22 23 #define I2S_MCLK_RATE(rate) \ 24 ((rate) * (I2S_MCLKFS)) 25 #define I2S_BIT_RATE(rate, channels, format) \ 26 ((rate) * (channels) * (format)) 27 28 static struct snd_soc_dapm_widget sc8280xp_dapm_widgets[] = { 29 SND_SOC_DAPM_HP("Headphone Jack", NULL), 30 SND_SOC_DAPM_MIC("Mic Jack", NULL), 31 SND_SOC_DAPM_SPK("DP0 Jack", NULL), 32 SND_SOC_DAPM_SPK("DP1 Jack", NULL), 33 SND_SOC_DAPM_SPK("DP2 Jack", NULL), 34 SND_SOC_DAPM_SPK("DP3 Jack", NULL), 35 SND_SOC_DAPM_SPK("DP4 Jack", NULL), 36 SND_SOC_DAPM_SPK("DP5 Jack", NULL), 37 SND_SOC_DAPM_SPK("DP6 Jack", NULL), 38 SND_SOC_DAPM_SPK("DP7 Jack", NULL), 39 }; 40 41 static const struct snd_kcontrol_new max98090_controls[] = { 42 SOC_DAPM_PIN_SWITCH("Headset Mic12"), 43 SOC_DAPM_PIN_SWITCH("Headphone"), 44 SOC_DAPM_PIN_SWITCH("Headset Mic56"), 45 SOC_DAPM_PIN_SWITCH("Speaker"), 46 SOC_DAPM_PIN_SWITCH("Receiver"), 47 SOC_DAPM_PIN_SWITCH("Int Mic"), 48 }; 49 50 static const struct snd_soc_dapm_widget max98090_dapm_widgets[] = { 51 SND_SOC_DAPM_HP("Headphone Jack", NULL), 52 SND_SOC_DAPM_MIC("Mic Jack", NULL), 53 SND_SOC_DAPM_HP("Headphone", NULL), 54 SND_SOC_DAPM_MIC("Headset Mic12", NULL), 55 SND_SOC_DAPM_MIC("Headset Mic56", NULL), 56 SND_SOC_DAPM_MIC("Int Mic", NULL), 57 SND_SOC_DAPM_SPK("Receiver", NULL), 58 SND_SOC_DAPM_SPK("Speaker", NULL), 59 }; 60 61 struct qcom_snd_soc_common { 62 const char *driver_name; 63 const struct snd_soc_dapm_widget *dapm_widgets; 64 int num_dapm_widgets; 65 const struct snd_soc_dapm_route *dapm_routes; 66 int num_dapm_routes; 67 const struct snd_kcontrol_new *controls; 68 int num_controls; 69 unsigned int codec_dai_fmt; 70 bool codec_sysclk_set; 71 bool mi2s_mclk_enable; 72 bool mi2s_bclk_enable; 73 bool wcd_jack; 74 int (*snd_prepare)(struct snd_pcm_substream *substream); 75 }; 76 77 struct sc8280xp_snd_data { 78 bool stream_prepared[AFE_PORT_MAX]; 79 struct snd_soc_card *card; 80 struct snd_soc_jack jack; 81 struct snd_soc_jack dp_jack[8]; 82 const struct qcom_snd_soc_common *priv; 83 bool jack_setup; 84 }; 85 86 static inline int sc8280xp_get_mclk_freq(struct snd_pcm_hw_params *params) 87 { 88 int rate = params_rate(params); 89 90 switch (rate) { 91 case 11025: 92 case 44100: 93 case 88200: 94 return I2S_MCLK_RATE(44100); 95 default: 96 break; 97 } 98 99 return I2S_MCLK_RATE(rate); 100 } 101 102 static inline int sc8280xp_get_bclk_freq(struct snd_pcm_hw_params *params) 103 { 104 return I2S_BIT_RATE(params_rate(params), 105 params_channels(params), 106 snd_pcm_format_width(params_format(params))); 107 } 108 109 static int sc8280xp_tdm_hw_params(struct snd_pcm_substream *substream, 110 struct snd_pcm_hw_params *params) 111 { 112 struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream); 113 struct sc8280xp_snd_data *data = snd_soc_card_get_drvdata(rtd->card); 114 struct snd_soc_dai *cpu_dai = snd_soc_rtd_to_cpu(rtd, 0); 115 struct snd_soc_dai *codec_dai; 116 struct qcom_snd_tdm_slot_cfg cpu_cfg; 117 struct qcom_snd_tdm_slot_cfg codec_cfg; 118 int bclk_freq; 119 int ret; 120 int i; 121 122 ret = qcom_snd_get_dai_tdm_slots(rtd, &cpu_cfg, &codec_cfg); 123 if (ret) 124 return ret == -ENOENT ? 0 : ret; 125 126 if (!cpu_cfg.slots) 127 return 0; 128 129 ret = snd_soc_dai_set_fmt(cpu_dai, SND_SOC_DAIFMT_BP_FP); 130 if (ret && ret != -ENOTSUPP) 131 return ret; 132 133 if (data->priv->codec_dai_fmt) { 134 for_each_rtd_codec_dais(rtd, i, codec_dai) { 135 ret = snd_soc_dai_set_fmt(codec_dai, 136 data->priv->codec_dai_fmt); 137 if (ret && ret != -ENOTSUPP) 138 return ret; 139 } 140 } 141 142 ret = qcom_snd_apply_dai_tdm_slots_cfg(rtd, &cpu_cfg, &codec_cfg); 143 if (ret) 144 return ret; 145 146 bclk_freq = snd_soc_tdm_params_to_bclk(params, cpu_cfg.slot_width, cpu_cfg.slots, 1); 147 if (bclk_freq <= 0) 148 return -EINVAL; 149 150 if (data->priv->mi2s_bclk_enable) { 151 ret = snd_soc_dai_set_sysclk(cpu_dai, LPAIF_MI2S_BCLK, bclk_freq, 152 SND_SOC_CLOCK_IN); 153 if (ret && ret != -ENOTSUPP) { 154 dev_err(rtd->dev, "%s: failed to set cpu sysclk: %d\n", 155 __func__, ret); 156 return ret; 157 } 158 } 159 160 if (data->priv->codec_sysclk_set) { 161 for_each_rtd_codec_dais(rtd, i, codec_dai) { 162 ret = snd_soc_dai_set_sysclk(codec_dai, 0, bclk_freq, 163 SND_SOC_CLOCK_IN); 164 if (ret && ret != -ENOTSUPP) { 165 dev_err(rtd->dev, "%s: failed to set codec sysclk on %s: %d\n", 166 __func__, codec_dai->name, ret); 167 return ret; 168 } 169 } 170 } 171 172 return 0; 173 } 174 175 static int sc8280xp_snd_init(struct snd_soc_pcm_runtime *rtd) 176 { 177 struct sc8280xp_snd_data *data = snd_soc_card_get_drvdata(rtd->card); 178 struct snd_soc_dai *cpu_dai = snd_soc_rtd_to_cpu(rtd, 0); 179 struct snd_soc_card *card = rtd->card; 180 struct snd_soc_jack *dp_jack = NULL; 181 int dp_pcm_id = 0; 182 183 switch (cpu_dai->id) { 184 case WSA_CODEC_DMA_RX_0: 185 case WSA_CODEC_DMA_RX_1: 186 /* 187 * Set limit of -3 dB on Digital Volume and 0 dB on PA Volume 188 * to reduce the risk of speaker damage until we have active 189 * speaker protection in place. 190 */ 191 snd_soc_limit_volume(card, "WSA_RX0 Digital Volume", 81); 192 snd_soc_limit_volume(card, "WSA_RX1 Digital Volume", 81); 193 snd_soc_limit_volume(card, "SpkrLeft PA Volume", 17); 194 snd_soc_limit_volume(card, "SpkrRight PA Volume", 17); 195 break; 196 case DISPLAY_PORT_RX_0: 197 /* DISPLAY_PORT dai ids are not contiguous */ 198 dp_pcm_id = 0; 199 dp_jack = &data->dp_jack[dp_pcm_id]; 200 break; 201 case DISPLAY_PORT_RX_1 ... DISPLAY_PORT_RX_7: 202 dp_pcm_id = cpu_dai->id - DISPLAY_PORT_RX_1 + 1; 203 dp_jack = &data->dp_jack[dp_pcm_id]; 204 break; 205 default: 206 break; 207 } 208 209 if (dp_jack) 210 return qcom_snd_dp_jack_setup(rtd, dp_jack, dp_pcm_id); 211 212 if (data->priv->wcd_jack) 213 return qcom_snd_wcd_jack_setup(rtd, &data->jack, &data->jack_setup); 214 215 return 0; 216 } 217 218 static int sc8280xp_be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd, 219 struct snd_pcm_hw_params *params) 220 { 221 struct snd_soc_dai *cpu_dai = snd_soc_rtd_to_cpu(rtd, 0); 222 struct snd_interval *rate = hw_param_interval(params, 223 SNDRV_PCM_HW_PARAM_RATE); 224 struct snd_interval *channels = hw_param_interval(params, 225 SNDRV_PCM_HW_PARAM_CHANNELS); 226 struct snd_mask *fmt = hw_param_mask(params, SNDRV_PCM_HW_PARAM_FORMAT); 227 228 rate->min = rate->max = 48000; 229 snd_mask_set_format(fmt, SNDRV_PCM_FORMAT_S16_LE); 230 channels->min = 2; 231 channels->max = 2; 232 switch (cpu_dai->id) { 233 case TX_CODEC_DMA_TX_0: 234 case TX_CODEC_DMA_TX_1: 235 case TX_CODEC_DMA_TX_2: 236 case TX_CODEC_DMA_TX_3: 237 channels->min = 1; 238 break; 239 default: 240 break; 241 } 242 243 244 return 0; 245 } 246 247 static int sc8280xp_snd_hw_params(struct snd_pcm_substream *substream, 248 struct snd_pcm_hw_params *params) 249 { 250 struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream); 251 struct snd_soc_dai *codec_dai = snd_soc_rtd_to_codec(rtd, 0); 252 struct snd_soc_dai *cpu_dai = snd_soc_rtd_to_cpu(rtd, 0); 253 struct sc8280xp_snd_data *data = snd_soc_card_get_drvdata(rtd->card); 254 int mclk_freq = sc8280xp_get_mclk_freq(params); 255 int bclk_freq = sc8280xp_get_bclk_freq(params); 256 int ret; 257 258 switch (cpu_dai->id) { 259 case PRIMARY_MI2S_RX ... QUATERNARY_MI2S_TX: 260 case QUINARY_MI2S_RX ... QUINARY_MI2S_TX: 261 case SENARY_MI2S_RX ... SENARY_MI2S_TX: 262 case LPI_MI2S_RX_0 ... LPI_MI2S_TX_4: 263 ret = snd_soc_dai_set_fmt(cpu_dai, SND_SOC_DAIFMT_BP_FP); 264 if (ret && ret != -ENOTSUPP) 265 return ret; 266 267 if (data->priv->codec_dai_fmt) { 268 ret = snd_soc_dai_set_fmt(codec_dai, 269 data->priv->codec_dai_fmt); 270 if (ret && ret != -ENOTSUPP) 271 return ret; 272 } 273 274 if (data->priv->mi2s_mclk_enable) { 275 ret = snd_soc_dai_set_sysclk(cpu_dai, 276 LPAIF_MI2S_MCLK, mclk_freq, 277 SND_SOC_CLOCK_OUT); 278 if (ret) 279 return ret; 280 } 281 282 if (data->priv->mi2s_bclk_enable) { 283 ret = snd_soc_dai_set_sysclk(cpu_dai, 284 LPAIF_MI2S_BCLK, bclk_freq, 285 SND_SOC_CLOCK_OUT); 286 if (ret) 287 return ret; 288 } 289 290 if (data->priv->codec_sysclk_set) { 291 ret = snd_soc_dai_set_sysclk(codec_dai, 292 0, mclk_freq, 293 SND_SOC_CLOCK_IN); 294 if (ret && ret != -ENOTSUPP) 295 return ret; 296 } 297 break; 298 case PRIMARY_TDM_RX_0 ... QUINARY_TDM_TX_7: 299 return sc8280xp_tdm_hw_params(substream, params); 300 default: 301 break; 302 } 303 304 return 0; 305 } 306 307 /* 308 * WSA and WSA2 are handled as a single interface with the 309 * following channels mask: 310 * __________________________________________________ 311 * | Bits | 3 | 2 | 1 | 0 | 312 * --------------------------------------------------- 313 * | Line | WSA2 Ch2 | WSA2 Ch1 | WSA Ch2 | WSA Ch1 | 314 * --------------------------------------------------- 315 * 316 * The Ayaneo Pocket S2 speakers are connected only to 317 * the WSA2 interface and the WSA interface is not enabled. 318 * 319 * Set the channel mapping on the WSA2 channels only. 320 */ 321 static const unsigned int ayaneo_ps2_channels_mapping[] = { 322 0, /* WSA Ch1 */ 323 0, /* WSA Ch2 */ 324 PCM_CHANNEL_FL, /* WSA2 Ch1 */ 325 PCM_CHANNEL_FR /* WSA2 Ch2 */ 326 }; 327 328 static int ayaneo_ps2_snd_prepare(struct snd_pcm_substream *substream) 329 { 330 struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream); 331 struct snd_soc_dai *cpu_dai = snd_soc_rtd_to_cpu(rtd, 0); 332 unsigned int channels = substream->runtime->channels; 333 334 if (cpu_dai->id != WSA_CODEC_DMA_RX_0) 335 return 0; 336 337 if (channels != 2) 338 return -EINVAL; 339 340 return snd_soc_dai_set_channel_map(cpu_dai, 0, NULL, 341 ARRAY_SIZE(ayaneo_ps2_channels_mapping), 342 ayaneo_ps2_channels_mapping); 343 } 344 345 static int sc8280xp_snd_prepare(struct snd_pcm_substream *substream) 346 { 347 struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream); 348 struct snd_soc_dai *cpu_dai = snd_soc_rtd_to_cpu(rtd, 0); 349 struct sc8280xp_snd_data *data = snd_soc_card_get_drvdata(rtd->card); 350 351 if (data->priv->snd_prepare) { 352 int ret; 353 354 ret = data->priv->snd_prepare(substream); 355 if (ret) 356 return ret; 357 } 358 359 return qcom_snd_sdw_prepare(substream, &data->stream_prepared[cpu_dai->id]); 360 } 361 362 static int sc8280xp_snd_hw_free(struct snd_pcm_substream *substream) 363 { 364 struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream); 365 struct sc8280xp_snd_data *data = snd_soc_card_get_drvdata(rtd->card); 366 struct snd_soc_dai *cpu_dai = snd_soc_rtd_to_cpu(rtd, 0); 367 368 return qcom_snd_sdw_hw_free(substream, &data->stream_prepared[cpu_dai->id]); 369 } 370 371 static const struct snd_soc_ops sc8280xp_be_ops = { 372 .startup = qcom_snd_sdw_startup, 373 .shutdown = qcom_snd_sdw_shutdown, 374 .hw_params = sc8280xp_snd_hw_params, 375 .hw_free = sc8280xp_snd_hw_free, 376 .prepare = sc8280xp_snd_prepare, 377 }; 378 379 static void sc8280xp_add_be_ops(struct snd_soc_card *card) 380 { 381 struct snd_soc_dai_link *link; 382 int i; 383 384 for_each_card_prelinks(card, i, link) { 385 if (link->no_pcm == 1) { 386 link->init = sc8280xp_snd_init; 387 link->be_hw_params_fixup = sc8280xp_be_hw_params_fixup; 388 link->ops = &sc8280xp_be_ops; 389 } 390 } 391 } 392 393 static int sc8280xp_platform_probe(struct platform_device *pdev) 394 { 395 struct snd_soc_card *card; 396 struct sc8280xp_snd_data *data; 397 struct device *dev = &pdev->dev; 398 int ret; 399 400 card = devm_kzalloc(dev, sizeof(*card), GFP_KERNEL); 401 if (!card) 402 return -ENOMEM; 403 404 /* Allocate the private data */ 405 data = devm_kzalloc(dev, sizeof(*data), GFP_KERNEL); 406 if (!data) 407 return -ENOMEM; 408 409 data->priv = of_device_get_match_data(dev); 410 if (!data->priv) 411 return -ENODEV; 412 413 card->owner = THIS_MODULE; 414 card->dev = dev; 415 dev_set_drvdata(dev, card); 416 snd_soc_card_set_drvdata(card, data); 417 card->dapm_widgets = data->priv->dapm_widgets; 418 card->num_dapm_widgets = data->priv->num_dapm_widgets; 419 card->dapm_routes = data->priv->dapm_routes; 420 card->num_dapm_routes = data->priv->num_dapm_routes; 421 card->controls = data->priv->controls; 422 card->num_controls = data->priv->num_controls; 423 424 ret = qcom_snd_parse_of(card); 425 if (ret) 426 return ret; 427 428 card->driver_name = data->priv->driver_name; 429 sc8280xp_add_be_ops(card); 430 return devm_snd_soc_register_card(dev, card); 431 } 432 433 static struct qcom_snd_soc_common ayaneo_ps2_priv_data = { 434 .driver_name = "ayaneo-ps2", 435 .dapm_widgets = sc8280xp_dapm_widgets, 436 .num_dapm_widgets = ARRAY_SIZE(sc8280xp_dapm_widgets), 437 .snd_prepare = ayaneo_ps2_snd_prepare, 438 .wcd_jack = true, 439 }; 440 441 static const struct qcom_snd_soc_common eliza_priv_data = { 442 .driver_name = "eliza", 443 .dapm_widgets = sc8280xp_dapm_widgets, 444 .num_dapm_widgets = ARRAY_SIZE(sc8280xp_dapm_widgets), 445 .wcd_jack = true, 446 }; 447 448 static const struct qcom_snd_soc_common hawi_priv_data = { 449 .driver_name = "hawi", 450 .dapm_widgets = sc8280xp_dapm_widgets, 451 .num_dapm_widgets = ARRAY_SIZE(sc8280xp_dapm_widgets), 452 .codec_sysclk_set = true, 453 .mi2s_bclk_enable = true, 454 .wcd_jack = true, 455 }; 456 457 static const struct qcom_snd_soc_common kaanapali_priv_data = { 458 .driver_name = "kaanapali", 459 .dapm_widgets = sc8280xp_dapm_widgets, 460 .num_dapm_widgets = ARRAY_SIZE(sc8280xp_dapm_widgets), 461 .wcd_jack = true, 462 }; 463 464 static const struct qcom_snd_soc_common qcs9100_priv_data = { 465 .driver_name = "sa8775p", 466 .dapm_widgets = sc8280xp_dapm_widgets, 467 .num_dapm_widgets = ARRAY_SIZE(sc8280xp_dapm_widgets), 468 }; 469 470 static const struct qcom_snd_soc_common qcs615_priv_data = { 471 .driver_name = "qcs615", 472 .dapm_widgets = sc8280xp_dapm_widgets, 473 .num_dapm_widgets = ARRAY_SIZE(sc8280xp_dapm_widgets), 474 .codec_sysclk_set = true, 475 }; 476 477 static const struct qcom_snd_soc_common qcm6490_priv_data = { 478 .driver_name = "qcm6490", 479 .dapm_widgets = sc8280xp_dapm_widgets, 480 .num_dapm_widgets = ARRAY_SIZE(sc8280xp_dapm_widgets), 481 .wcd_jack = true, 482 }; 483 484 static const struct qcom_snd_soc_common qcs6490_priv_data = { 485 .driver_name = "qcs6490", 486 .dapm_widgets = sc8280xp_dapm_widgets, 487 .num_dapm_widgets = ARRAY_SIZE(sc8280xp_dapm_widgets), 488 .wcd_jack = true, 489 }; 490 491 static const struct qcom_snd_soc_common qcs8275_priv_data = { 492 .driver_name = "qcs8300", 493 .dapm_widgets = max98090_dapm_widgets, 494 .num_dapm_widgets = ARRAY_SIZE(max98090_dapm_widgets), 495 .controls = max98090_controls, 496 .num_controls = ARRAY_SIZE(max98090_controls), 497 .codec_sysclk_set = true, 498 .codec_dai_fmt = SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_BC_FC, 499 }; 500 501 static const struct qcom_snd_soc_common sc8280xp_priv_data = { 502 .driver_name = "sc8280xp", 503 .dapm_widgets = sc8280xp_dapm_widgets, 504 .num_dapm_widgets = ARRAY_SIZE(sc8280xp_dapm_widgets), 505 .wcd_jack = true, 506 }; 507 508 static const struct qcom_snd_soc_common sm8450_priv_data = { 509 .driver_name = "sm8450", 510 .dapm_widgets = sc8280xp_dapm_widgets, 511 .num_dapm_widgets = ARRAY_SIZE(sc8280xp_dapm_widgets), 512 .wcd_jack = true, 513 /* I2S Connected to HDMI */ 514 .mi2s_mclk_enable = true, 515 .mi2s_bclk_enable = true, 516 .codec_dai_fmt = SND_SOC_DAIFMT_BC_FC | 517 SND_SOC_DAIFMT_NB_NF | 518 SND_SOC_DAIFMT_I2S, 519 }; 520 521 static const struct qcom_snd_soc_common sm8475_priv_data = { 522 .driver_name = "sm8475", 523 .dapm_widgets = sc8280xp_dapm_widgets, 524 .num_dapm_widgets = ARRAY_SIZE(sc8280xp_dapm_widgets), 525 .wcd_jack = true, 526 }; 527 528 static const struct qcom_snd_soc_common sm8550_priv_data = { 529 .driver_name = "sm8550", 530 .dapm_widgets = sc8280xp_dapm_widgets, 531 .num_dapm_widgets = ARRAY_SIZE(sc8280xp_dapm_widgets), 532 .wcd_jack = true, 533 /* I2S Connected to HDMI */ 534 .mi2s_mclk_enable = true, 535 .mi2s_bclk_enable = true, 536 .codec_dai_fmt = SND_SOC_DAIFMT_BC_FC | 537 SND_SOC_DAIFMT_NB_NF | 538 SND_SOC_DAIFMT_I2S, 539 }; 540 541 static const struct qcom_snd_soc_common sm8650_priv_data = { 542 .driver_name = "sm8650", 543 .dapm_widgets = sc8280xp_dapm_widgets, 544 .num_dapm_widgets = ARRAY_SIZE(sc8280xp_dapm_widgets), 545 .wcd_jack = true, 546 /* I2S Connected to HDMI */ 547 .mi2s_mclk_enable = true, 548 .mi2s_bclk_enable = true, 549 .codec_dai_fmt = SND_SOC_DAIFMT_BC_FC | 550 SND_SOC_DAIFMT_NB_NF | 551 SND_SOC_DAIFMT_I2S, 552 }; 553 554 static const struct qcom_snd_soc_common sm8750_priv_data = { 555 .driver_name = "sm8750", 556 .dapm_widgets = sc8280xp_dapm_widgets, 557 .num_dapm_widgets = ARRAY_SIZE(sc8280xp_dapm_widgets), 558 .wcd_jack = true, 559 }; 560 561 static const struct of_device_id snd_sc8280xp_dt_match[] = { 562 { .compatible = "ayaneo,pocket-s2-sndcard", .data = &ayaneo_ps2_priv_data }, 563 { .compatible = "qcom,eliza-sndcard", .data = &eliza_priv_data }, 564 { .compatible = "qcom,hawi-sndcard", .data = &hawi_priv_data }, 565 { .compatible = "qcom,kaanapali-sndcard", .data = &kaanapali_priv_data }, 566 { .compatible = "qcom,maili-sndcard", .data = &hawi_priv_data }, 567 { .compatible = "qcom,qcm6490-idp-sndcard", .data = &qcm6490_priv_data }, 568 { .compatible = "qcom,qcs615-sndcard", .data = &qcs615_priv_data }, 569 { .compatible = "qcom,qcs6490-rb3gen2-sndcard", .data = &qcs6490_priv_data }, 570 { .compatible = "qcom,qcs8275-sndcard", .data = &qcs8275_priv_data }, 571 { .compatible = "qcom,qcs9075-sndcard", .data = &qcs9100_priv_data }, 572 { .compatible = "qcom,qcs9100-sndcard", .data = &qcs9100_priv_data }, 573 { .compatible = "qcom,sc8280xp-sndcard", .data = &sc8280xp_priv_data }, 574 { .compatible = "qcom,sm8450-sndcard", .data = &sm8450_priv_data }, 575 { .compatible = "qcom,sm8475-sndcard", .data = &sm8475_priv_data }, 576 { .compatible = "qcom,sm8550-sndcard", .data = &sm8550_priv_data }, 577 { .compatible = "qcom,sm8650-sndcard", .data = &sm8650_priv_data }, 578 { .compatible = "qcom,sm8750-sndcard", .data = &sm8750_priv_data }, 579 {} 580 }; 581 582 MODULE_DEVICE_TABLE(of, snd_sc8280xp_dt_match); 583 584 static struct platform_driver snd_sc8280xp_driver = { 585 .probe = sc8280xp_platform_probe, 586 .driver = { 587 .name = "snd-sc8280xp", 588 .of_match_table = snd_sc8280xp_dt_match, 589 }, 590 }; 591 module_platform_driver(snd_sc8280xp_driver); 592 MODULE_AUTHOR("Srinivas Kandagatla <srinivas.kandagatla@linaro.org"); 593 MODULE_DESCRIPTION("SC8280XP ASoC Machine Driver"); 594 MODULE_LICENSE("GPL"); 595