1 // SPDX-License-Identifier: GPL-2.0 2 // Copyright (c) 2020, 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 "common.h" 16 #include "usb_offload_utils.h" 17 #include "sdw.h" 18 19 #define MI2S_BCLK_RATE 1536000 20 21 struct sm8250_snd_data { 22 bool stream_prepared[AFE_PORT_MAX]; 23 struct snd_soc_card *card; 24 struct sdw_stream_runtime *sruntime[AFE_PORT_MAX]; 25 struct snd_soc_jack jack; 26 struct snd_soc_jack usb_offload_jack; 27 bool usb_offload_jack_setup; 28 struct snd_soc_jack dp_jack; 29 bool jack_setup; 30 }; 31 32 static int sm8250_snd_init(struct snd_soc_pcm_runtime *rtd) 33 { 34 struct sm8250_snd_data *data = snd_soc_card_get_drvdata(rtd->card); 35 struct snd_soc_dai *cpu_dai = snd_soc_rtd_to_cpu(rtd, 0); 36 37 switch (cpu_dai->id) { 38 case DISPLAY_PORT_RX: 39 return qcom_snd_dp_jack_setup(rtd, &data->dp_jack, 0); 40 case USB_RX: 41 return qcom_snd_usb_offload_jack_setup(rtd, &data->usb_offload_jack, 42 &data->usb_offload_jack_setup); 43 default: 44 return qcom_snd_wcd_jack_setup(rtd, &data->jack, &data->jack_setup); 45 } 46 } 47 48 static void sm8250_snd_exit(struct snd_soc_pcm_runtime *rtd) 49 { 50 struct sm8250_snd_data *data = snd_soc_card_get_drvdata(rtd->card); 51 struct snd_soc_dai *cpu_dai = snd_soc_rtd_to_cpu(rtd, 0); 52 53 if (cpu_dai->id == USB_RX) 54 qcom_snd_usb_offload_jack_remove(rtd, 55 &data->usb_offload_jack_setup); 56 57 } 58 59 static int sm8250_be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd, 60 struct snd_pcm_hw_params *params) 61 { 62 struct snd_interval *rate = hw_param_interval(params, 63 SNDRV_PCM_HW_PARAM_RATE); 64 struct snd_interval *channels = hw_param_interval(params, 65 SNDRV_PCM_HW_PARAM_CHANNELS); 66 struct snd_mask *fmt = hw_param_mask(params, SNDRV_PCM_HW_PARAM_FORMAT); 67 68 rate->min = rate->max = 48000; 69 channels->min = channels->max = 2; 70 snd_mask_set_format(fmt, SNDRV_PCM_FORMAT_S16_LE); 71 72 return 0; 73 } 74 75 static int sm8250_snd_startup(struct snd_pcm_substream *substream) 76 { 77 unsigned int fmt = SND_SOC_DAIFMT_BP_FP; 78 unsigned int codec_dai_fmt = SND_SOC_DAIFMT_BC_FC; 79 struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream); 80 struct snd_soc_dai *cpu_dai = snd_soc_rtd_to_cpu(rtd, 0); 81 struct snd_soc_dai *codec_dai = snd_soc_rtd_to_codec(rtd, 0); 82 83 switch (cpu_dai->id) { 84 case PRIMARY_MI2S_RX: 85 codec_dai_fmt |= SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_I2S; 86 snd_soc_dai_set_sysclk(cpu_dai, 87 Q6AFE_LPASS_CLK_ID_PRI_MI2S_IBIT, 88 MI2S_BCLK_RATE, SNDRV_PCM_STREAM_PLAYBACK); 89 snd_soc_dai_set_fmt(cpu_dai, fmt); 90 snd_soc_dai_set_fmt(codec_dai, codec_dai_fmt); 91 break; 92 case SECONDARY_MI2S_RX: 93 codec_dai_fmt |= SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_I2S; 94 snd_soc_dai_set_sysclk(cpu_dai, 95 Q6AFE_LPASS_CLK_ID_SEC_MI2S_IBIT, 96 MI2S_BCLK_RATE, SNDRV_PCM_STREAM_PLAYBACK); 97 snd_soc_dai_set_fmt(cpu_dai, fmt); 98 snd_soc_dai_set_fmt(codec_dai, codec_dai_fmt); 99 break; 100 case TERTIARY_MI2S_RX: 101 codec_dai_fmt |= SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_I2S; 102 snd_soc_dai_set_sysclk(cpu_dai, 103 Q6AFE_LPASS_CLK_ID_TER_MI2S_IBIT, 104 MI2S_BCLK_RATE, SNDRV_PCM_STREAM_PLAYBACK); 105 snd_soc_dai_set_fmt(cpu_dai, fmt); 106 snd_soc_dai_set_fmt(codec_dai, codec_dai_fmt); 107 break; 108 default: 109 break; 110 } 111 112 return qcom_snd_sdw_startup(substream); 113 } 114 115 static void sm8250_snd_shutdown(struct snd_pcm_substream *substream) 116 { 117 struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream); 118 struct snd_soc_dai *cpu_dai = snd_soc_rtd_to_cpu(rtd, 0); 119 struct sm8250_snd_data *data = snd_soc_card_get_drvdata(rtd->card); 120 struct sdw_stream_runtime *sruntime = data->sruntime[cpu_dai->id]; 121 122 data->sruntime[cpu_dai->id] = NULL; 123 sdw_release_stream(sruntime); 124 } 125 126 static int sm8250_snd_hw_params(struct snd_pcm_substream *substream, 127 struct snd_pcm_hw_params *params) 128 { 129 struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream); 130 struct snd_soc_dai *cpu_dai = snd_soc_rtd_to_cpu(rtd, 0); 131 struct sm8250_snd_data *pdata = snd_soc_card_get_drvdata(rtd->card); 132 133 return qcom_snd_sdw_hw_params(substream, params, &pdata->sruntime[cpu_dai->id]); 134 } 135 136 static int sm8250_snd_prepare(struct snd_pcm_substream *substream) 137 { 138 struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream); 139 struct snd_soc_dai *cpu_dai = snd_soc_rtd_to_cpu(rtd, 0); 140 struct sm8250_snd_data *data = snd_soc_card_get_drvdata(rtd->card); 141 struct sdw_stream_runtime *sruntime = data->sruntime[cpu_dai->id]; 142 143 return qcom_snd_sdw_prepare(substream, sruntime, 144 &data->stream_prepared[cpu_dai->id]); 145 } 146 147 static int sm8250_snd_hw_free(struct snd_pcm_substream *substream) 148 { 149 struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream); 150 struct sm8250_snd_data *data = snd_soc_card_get_drvdata(rtd->card); 151 struct snd_soc_dai *cpu_dai = snd_soc_rtd_to_cpu(rtd, 0); 152 struct sdw_stream_runtime *sruntime = data->sruntime[cpu_dai->id]; 153 154 return qcom_snd_sdw_hw_free(substream, sruntime, 155 &data->stream_prepared[cpu_dai->id]); 156 } 157 158 static const struct snd_soc_ops sm8250_be_ops = { 159 .startup = sm8250_snd_startup, 160 .shutdown = sm8250_snd_shutdown, 161 .hw_params = sm8250_snd_hw_params, 162 .hw_free = sm8250_snd_hw_free, 163 .prepare = sm8250_snd_prepare, 164 }; 165 166 static void sm8250_add_be_ops(struct snd_soc_card *card) 167 { 168 struct snd_soc_dai_link *link; 169 int i; 170 171 for_each_card_prelinks(card, i, link) { 172 if (link->no_pcm == 1) { 173 link->init = sm8250_snd_init; 174 link->exit = sm8250_snd_exit; 175 link->be_hw_params_fixup = sm8250_be_hw_params_fixup; 176 link->ops = &sm8250_be_ops; 177 } 178 } 179 } 180 181 static int sm8250_platform_probe(struct platform_device *pdev) 182 { 183 struct snd_soc_card *card; 184 struct sm8250_snd_data *data; 185 struct device *dev = &pdev->dev; 186 int ret; 187 188 card = devm_kzalloc(dev, sizeof(*card), GFP_KERNEL); 189 if (!card) 190 return -ENOMEM; 191 192 card->owner = THIS_MODULE; 193 /* Allocate the private data */ 194 data = devm_kzalloc(dev, sizeof(*data), GFP_KERNEL); 195 if (!data) 196 return -ENOMEM; 197 198 card->dev = dev; 199 dev_set_drvdata(dev, card); 200 snd_soc_card_set_drvdata(card, data); 201 ret = qcom_snd_parse_of(card); 202 if (ret) 203 return ret; 204 205 card->driver_name = of_device_get_match_data(dev); 206 sm8250_add_be_ops(card); 207 return devm_snd_soc_register_card(dev, card); 208 } 209 210 static const struct of_device_id snd_sm8250_dt_match[] = { 211 { .compatible = "fairphone,fp4-sndcard", .data = "sm7225" }, 212 { .compatible = "fairphone,fp5-sndcard", .data = "qcm6490" }, 213 { .compatible = "qcom,qrb4210-rb2-sndcard", .data = "sm4250" }, 214 { .compatible = "qcom,qrb5165-rb5-sndcard", .data = "sm8250" }, 215 { .compatible = "qcom,sm8250-sndcard", .data = "sm8250" }, 216 {} 217 }; 218 219 MODULE_DEVICE_TABLE(of, snd_sm8250_dt_match); 220 221 static struct platform_driver snd_sm8250_driver = { 222 .probe = sm8250_platform_probe, 223 .driver = { 224 .name = "snd-sm8250", 225 .of_match_table = snd_sm8250_dt_match, 226 }, 227 }; 228 module_platform_driver(snd_sm8250_driver); 229 MODULE_AUTHOR("Srinivas Kandagatla <srinivas.kandagatla@linaro.org"); 230 MODULE_DESCRIPTION("SM8250 ASoC Machine Driver"); 231 MODULE_LICENSE("GPL"); 232