sm8250.c 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213
  1. // SPDX-License-Identifier: GPL-2.0
  2. // Copyright (c) 2020, Linaro Limited
  3. #include <dt-bindings/sound/qcom,q6afe.h>
  4. #include <linux/module.h>
  5. #include <linux/platform_device.h>
  6. #include <sound/soc.h>
  7. #include <sound/soc-dapm.h>
  8. #include <sound/pcm.h>
  9. #include <sound/pcm_params.h>
  10. #include <linux/soundwire/sdw.h>
  11. #include <sound/jack.h>
  12. #include <linux/input-event-codes.h>
  13. #include "qdsp6/q6afe.h"
  14. #include "common.h"
  15. #include "usb_offload_utils.h"
  16. #include "sdw.h"
  17. #define MI2S_BCLK_RATE 1536000
  18. struct sm8250_snd_data {
  19. bool stream_prepared[AFE_PORT_MAX];
  20. struct snd_soc_card *card;
  21. struct snd_soc_jack jack;
  22. struct snd_soc_jack usb_offload_jack;
  23. bool usb_offload_jack_setup;
  24. struct snd_soc_jack dp_jack;
  25. bool jack_setup;
  26. };
  27. static int sm8250_snd_init(struct snd_soc_pcm_runtime *rtd)
  28. {
  29. struct sm8250_snd_data *data = snd_soc_card_get_drvdata(rtd->card);
  30. struct snd_soc_dai *cpu_dai = snd_soc_rtd_to_cpu(rtd, 0);
  31. switch (cpu_dai->id) {
  32. case DISPLAY_PORT_RX:
  33. return qcom_snd_dp_jack_setup(rtd, &data->dp_jack, 0);
  34. case USB_RX:
  35. return qcom_snd_usb_offload_jack_setup(rtd, &data->usb_offload_jack,
  36. &data->usb_offload_jack_setup);
  37. default:
  38. return qcom_snd_wcd_jack_setup(rtd, &data->jack, &data->jack_setup);
  39. }
  40. }
  41. static void sm8250_snd_exit(struct snd_soc_pcm_runtime *rtd)
  42. {
  43. struct sm8250_snd_data *data = snd_soc_card_get_drvdata(rtd->card);
  44. struct snd_soc_dai *cpu_dai = snd_soc_rtd_to_cpu(rtd, 0);
  45. if (cpu_dai->id == USB_RX)
  46. qcom_snd_usb_offload_jack_remove(rtd,
  47. &data->usb_offload_jack_setup);
  48. }
  49. static int sm8250_be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd,
  50. struct snd_pcm_hw_params *params)
  51. {
  52. struct snd_interval *rate = hw_param_interval(params,
  53. SNDRV_PCM_HW_PARAM_RATE);
  54. struct snd_interval *channels = hw_param_interval(params,
  55. SNDRV_PCM_HW_PARAM_CHANNELS);
  56. struct snd_mask *fmt = hw_param_mask(params, SNDRV_PCM_HW_PARAM_FORMAT);
  57. rate->min = rate->max = 48000;
  58. channels->min = channels->max = 2;
  59. snd_mask_set_format(fmt, SNDRV_PCM_FORMAT_S16_LE);
  60. return 0;
  61. }
  62. static int sm8250_snd_startup(struct snd_pcm_substream *substream)
  63. {
  64. unsigned int fmt = SND_SOC_DAIFMT_BP_FP;
  65. unsigned int codec_dai_fmt = SND_SOC_DAIFMT_BC_FC;
  66. struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream);
  67. struct snd_soc_dai *cpu_dai = snd_soc_rtd_to_cpu(rtd, 0);
  68. struct snd_soc_dai *codec_dai = snd_soc_rtd_to_codec(rtd, 0);
  69. switch (cpu_dai->id) {
  70. case PRIMARY_MI2S_RX:
  71. codec_dai_fmt |= SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_I2S;
  72. snd_soc_dai_set_sysclk(cpu_dai,
  73. Q6AFE_LPASS_CLK_ID_PRI_MI2S_IBIT,
  74. MI2S_BCLK_RATE, SNDRV_PCM_STREAM_PLAYBACK);
  75. snd_soc_dai_set_fmt(cpu_dai, fmt);
  76. snd_soc_dai_set_fmt(codec_dai, codec_dai_fmt);
  77. break;
  78. case SECONDARY_MI2S_RX:
  79. codec_dai_fmt |= SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_I2S;
  80. snd_soc_dai_set_sysclk(cpu_dai,
  81. Q6AFE_LPASS_CLK_ID_SEC_MI2S_IBIT,
  82. MI2S_BCLK_RATE, SNDRV_PCM_STREAM_PLAYBACK);
  83. snd_soc_dai_set_fmt(cpu_dai, fmt);
  84. snd_soc_dai_set_fmt(codec_dai, codec_dai_fmt);
  85. break;
  86. case TERTIARY_MI2S_RX:
  87. codec_dai_fmt |= SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_I2S;
  88. snd_soc_dai_set_sysclk(cpu_dai,
  89. Q6AFE_LPASS_CLK_ID_TER_MI2S_IBIT,
  90. MI2S_BCLK_RATE, SNDRV_PCM_STREAM_PLAYBACK);
  91. snd_soc_dai_set_fmt(cpu_dai, fmt);
  92. snd_soc_dai_set_fmt(codec_dai, codec_dai_fmt);
  93. break;
  94. case QUINARY_MI2S_RX:
  95. codec_dai_fmt |= SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_I2S;
  96. snd_soc_dai_set_sysclk(cpu_dai,
  97. Q6AFE_LPASS_CLK_ID_QUI_MI2S_IBIT,
  98. MI2S_BCLK_RATE, SNDRV_PCM_STREAM_PLAYBACK);
  99. snd_soc_dai_set_fmt(cpu_dai, fmt);
  100. snd_soc_dai_set_fmt(codec_dai, codec_dai_fmt);
  101. break;
  102. default:
  103. break;
  104. }
  105. return qcom_snd_sdw_startup(substream);
  106. }
  107. static int sm8250_snd_prepare(struct snd_pcm_substream *substream)
  108. {
  109. struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream);
  110. struct snd_soc_dai *cpu_dai = snd_soc_rtd_to_cpu(rtd, 0);
  111. struct sm8250_snd_data *data = snd_soc_card_get_drvdata(rtd->card);
  112. return qcom_snd_sdw_prepare(substream, &data->stream_prepared[cpu_dai->id]);
  113. }
  114. static int sm8250_snd_hw_free(struct snd_pcm_substream *substream)
  115. {
  116. struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream);
  117. struct sm8250_snd_data *data = snd_soc_card_get_drvdata(rtd->card);
  118. struct snd_soc_dai *cpu_dai = snd_soc_rtd_to_cpu(rtd, 0);
  119. return qcom_snd_sdw_hw_free(substream, &data->stream_prepared[cpu_dai->id]);
  120. }
  121. static const struct snd_soc_ops sm8250_be_ops = {
  122. .startup = sm8250_snd_startup,
  123. .shutdown = qcom_snd_sdw_shutdown,
  124. .hw_free = sm8250_snd_hw_free,
  125. .prepare = sm8250_snd_prepare,
  126. };
  127. static void sm8250_add_be_ops(struct snd_soc_card *card)
  128. {
  129. struct snd_soc_dai_link *link;
  130. int i;
  131. for_each_card_prelinks(card, i, link) {
  132. if (link->no_pcm == 1) {
  133. link->init = sm8250_snd_init;
  134. link->exit = sm8250_snd_exit;
  135. link->be_hw_params_fixup = sm8250_be_hw_params_fixup;
  136. link->ops = &sm8250_be_ops;
  137. }
  138. }
  139. }
  140. static int sm8250_platform_probe(struct platform_device *pdev)
  141. {
  142. struct snd_soc_card *card;
  143. struct sm8250_snd_data *data;
  144. struct device *dev = &pdev->dev;
  145. int ret;
  146. card = devm_kzalloc(dev, sizeof(*card), GFP_KERNEL);
  147. if (!card)
  148. return -ENOMEM;
  149. card->owner = THIS_MODULE;
  150. /* Allocate the private data */
  151. data = devm_kzalloc(dev, sizeof(*data), GFP_KERNEL);
  152. if (!data)
  153. return -ENOMEM;
  154. card->dev = dev;
  155. dev_set_drvdata(dev, card);
  156. snd_soc_card_set_drvdata(card, data);
  157. ret = qcom_snd_parse_of(card);
  158. if (ret)
  159. return ret;
  160. card->driver_name = of_device_get_match_data(dev);
  161. sm8250_add_be_ops(card);
  162. return devm_snd_soc_register_card(dev, card);
  163. }
  164. static const struct of_device_id snd_sm8250_dt_match[] = {
  165. { .compatible = "fairphone,fp4-sndcard", .data = "sm7225" },
  166. { .compatible = "fairphone,fp5-sndcard", .data = "qcm6490" },
  167. { .compatible = "qcom,qrb2210-sndcard", .data = "qcm2290" },
  168. { .compatible = "qcom,qrb4210-rb2-sndcard", .data = "sm4250" },
  169. { .compatible = "qcom,qrb5165-rb5-sndcard", .data = "sm8250" },
  170. { .compatible = "qcom,sm8250-sndcard", .data = "sm8250" },
  171. {}
  172. };
  173. MODULE_DEVICE_TABLE(of, snd_sm8250_dt_match);
  174. static struct platform_driver snd_sm8250_driver = {
  175. .probe = sm8250_platform_probe,
  176. .driver = {
  177. .name = "snd-sm8250",
  178. .of_match_table = snd_sm8250_dt_match,
  179. },
  180. };
  181. module_platform_driver(snd_sm8250_driver);
  182. MODULE_AUTHOR("Srinivas Kandagatla <srinivas.kandagatla@linaro.org");
  183. MODULE_DESCRIPTION("SM8250 ASoC Machine Driver");
  184. MODULE_LICENSE("GPL");