1 // SPDX-License-Identifier: GPL-2.0 2 // Copyright (c) 2020, Linaro Limited 3 4 #include <linux/module.h> 5 #include <linux/platform_device.h> 6 #include <linux/of_device.h> 7 #include <sound/soc.h> 8 #include <sound/soc-dapm.h> 9 #include <sound/pcm.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 16 #define DRIVER_NAME "sm8250" 17 #define MI2S_BCLK_RATE 1536000 18 19 struct sm8250_snd_data { 20 bool stream_prepared[AFE_PORT_MAX]; 21 struct snd_soc_card *card; 22 struct sdw_stream_runtime *sruntime[AFE_PORT_MAX]; 23 struct snd_soc_jack jack; 24 bool jack_setup; 25 }; 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 31 return qcom_snd_wcd_jack_setup(rtd, &data->jack, &data->jack_setup); 32 } 33 34 static int sm8250_be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd, 35 struct snd_pcm_hw_params *params) 36 { 37 struct snd_interval *rate = hw_param_interval(params, 38 SNDRV_PCM_HW_PARAM_RATE); 39 struct snd_interval *channels = hw_param_interval(params, 40 SNDRV_PCM_HW_PARAM_CHANNELS); 41 42 rate->min = rate->max = 48000; 43 channels->min = channels->max = 2; 44 45 return 0; 46 } 47 48 static int sm8250_snd_startup(struct snd_pcm_substream *substream) 49 { 50 unsigned int fmt = SND_SOC_DAIFMT_BP_FP; 51 unsigned int codec_dai_fmt = SND_SOC_DAIFMT_BC_FC; 52 struct snd_soc_pcm_runtime *rtd = substream->private_data; 53 struct snd_soc_dai *cpu_dai = asoc_rtd_to_cpu(rtd, 0); 54 struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 0); 55 56 switch (cpu_dai->id) { 57 case TERTIARY_MI2S_RX: 58 codec_dai_fmt |= SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_I2S; 59 snd_soc_dai_set_sysclk(cpu_dai, 60 Q6AFE_LPASS_CLK_ID_TER_MI2S_IBIT, 61 MI2S_BCLK_RATE, SNDRV_PCM_STREAM_PLAYBACK); 62 snd_soc_dai_set_fmt(cpu_dai, fmt); 63 snd_soc_dai_set_fmt(codec_dai, codec_dai_fmt); 64 break; 65 default: 66 break; 67 } 68 return 0; 69 } 70 71 static int sm8250_snd_hw_params(struct snd_pcm_substream *substream, 72 struct snd_pcm_hw_params *params) 73 { 74 struct snd_soc_pcm_runtime *rtd = substream->private_data; 75 struct snd_soc_dai *cpu_dai = asoc_rtd_to_cpu(rtd, 0); 76 struct sm8250_snd_data *pdata = snd_soc_card_get_drvdata(rtd->card); 77 78 return qcom_snd_sdw_hw_params(substream, params, &pdata->sruntime[cpu_dai->id]); 79 } 80 81 static int sm8250_snd_prepare(struct snd_pcm_substream *substream) 82 { 83 struct snd_soc_pcm_runtime *rtd = substream->private_data; 84 struct snd_soc_dai *cpu_dai = asoc_rtd_to_cpu(rtd, 0); 85 struct sm8250_snd_data *data = snd_soc_card_get_drvdata(rtd->card); 86 struct sdw_stream_runtime *sruntime = data->sruntime[cpu_dai->id]; 87 88 return qcom_snd_sdw_prepare(substream, sruntime, 89 &data->stream_prepared[cpu_dai->id]); 90 } 91 92 static int sm8250_snd_hw_free(struct snd_pcm_substream *substream) 93 { 94 struct snd_soc_pcm_runtime *rtd = substream->private_data; 95 struct sm8250_snd_data *data = snd_soc_card_get_drvdata(rtd->card); 96 struct snd_soc_dai *cpu_dai = asoc_rtd_to_cpu(rtd, 0); 97 struct sdw_stream_runtime *sruntime = data->sruntime[cpu_dai->id]; 98 99 return qcom_snd_sdw_hw_free(substream, sruntime, 100 &data->stream_prepared[cpu_dai->id]); 101 } 102 103 static const struct snd_soc_ops sm8250_be_ops = { 104 .startup = sm8250_snd_startup, 105 .hw_params = sm8250_snd_hw_params, 106 .hw_free = sm8250_snd_hw_free, 107 .prepare = sm8250_snd_prepare, 108 }; 109 110 static void sm8250_add_be_ops(struct snd_soc_card *card) 111 { 112 struct snd_soc_dai_link *link; 113 int i; 114 115 for_each_card_prelinks(card, i, link) { 116 if (link->no_pcm == 1) { 117 link->init = sm8250_snd_init; 118 link->be_hw_params_fixup = sm8250_be_hw_params_fixup; 119 link->ops = &sm8250_be_ops; 120 } 121 } 122 } 123 124 static int sm8250_platform_probe(struct platform_device *pdev) 125 { 126 struct snd_soc_card *card; 127 struct sm8250_snd_data *data; 128 struct device *dev = &pdev->dev; 129 int ret; 130 131 card = devm_kzalloc(dev, sizeof(*card), GFP_KERNEL); 132 if (!card) 133 return -ENOMEM; 134 135 card->owner = THIS_MODULE; 136 /* Allocate the private data */ 137 data = devm_kzalloc(dev, sizeof(*data), GFP_KERNEL); 138 if (!data) 139 return -ENOMEM; 140 141 card->dev = dev; 142 dev_set_drvdata(dev, card); 143 snd_soc_card_set_drvdata(card, data); 144 ret = qcom_snd_parse_of(card); 145 if (ret) 146 return ret; 147 148 card->driver_name = DRIVER_NAME; 149 sm8250_add_be_ops(card); 150 return devm_snd_soc_register_card(dev, card); 151 } 152 153 static const struct of_device_id snd_sm8250_dt_match[] = { 154 {.compatible = "qcom,sm8250-sndcard"}, 155 {.compatible = "qcom,qrb5165-rb5-sndcard"}, 156 {} 157 }; 158 159 MODULE_DEVICE_TABLE(of, snd_sm8250_dt_match); 160 161 static struct platform_driver snd_sm8250_driver = { 162 .probe = sm8250_platform_probe, 163 .driver = { 164 .name = "snd-sm8250", 165 .of_match_table = snd_sm8250_dt_match, 166 }, 167 }; 168 module_platform_driver(snd_sm8250_driver); 169 MODULE_AUTHOR("Srinivas Kandagatla <srinivas.kandagatla@linaro.org"); 170 MODULE_DESCRIPTION("SM8250 ASoC Machine Driver"); 171 MODULE_LICENSE("GPL v2"); 172