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