Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0
0002 // Copyright (c) 2020, Linaro Limited
0003 
0004 #include <linux/module.h>
0005 #include <linux/platform_device.h>
0006 #include <linux/of_device.h>
0007 #include <sound/soc.h>
0008 #include <sound/soc-dapm.h>
0009 #include <sound/pcm.h>
0010 #include <linux/soundwire/sdw.h>
0011 #include <sound/jack.h>
0012 #include <linux/input-event-codes.h>
0013 #include "qdsp6/q6afe.h"
0014 #include "common.h"
0015 
0016 #define DRIVER_NAME     "sm8250"
0017 #define MI2S_BCLK_RATE      1536000
0018 
0019 struct sm8250_snd_data {
0020     bool stream_prepared[AFE_PORT_MAX];
0021     struct snd_soc_card *card;
0022     struct sdw_stream_runtime *sruntime[AFE_PORT_MAX];
0023     struct snd_soc_jack jack;
0024     bool jack_setup;
0025 };
0026 
0027 static int sm8250_snd_init(struct snd_soc_pcm_runtime *rtd)
0028 {
0029     struct sm8250_snd_data *data = snd_soc_card_get_drvdata(rtd->card);
0030     struct snd_soc_dai *cpu_dai = asoc_rtd_to_cpu(rtd, 0);
0031     struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 0);
0032     struct snd_soc_card *card = rtd->card;
0033     int rval, i;
0034 
0035     if (!data->jack_setup) {
0036         struct snd_jack *jack;
0037 
0038         rval = snd_soc_card_jack_new(card, "Headset Jack",
0039                          SND_JACK_HEADSET | SND_JACK_LINEOUT |
0040                          SND_JACK_MECHANICAL |
0041                          SND_JACK_BTN_0 | SND_JACK_BTN_1 |
0042                          SND_JACK_BTN_2 | SND_JACK_BTN_3 |
0043                          SND_JACK_BTN_4 | SND_JACK_BTN_5,
0044                          &data->jack);
0045 
0046         if (rval < 0) {
0047             dev_err(card->dev, "Unable to add Headphone Jack\n");
0048             return rval;
0049         }
0050 
0051         jack = data->jack.jack;
0052 
0053         snd_jack_set_key(jack, SND_JACK_BTN_0, KEY_MEDIA);
0054         snd_jack_set_key(jack, SND_JACK_BTN_1, KEY_VOICECOMMAND);
0055         snd_jack_set_key(jack, SND_JACK_BTN_2, KEY_VOLUMEUP);
0056         snd_jack_set_key(jack, SND_JACK_BTN_3, KEY_VOLUMEDOWN);
0057         data->jack_setup = true;
0058     }
0059 
0060     switch (cpu_dai->id) {
0061     case TX_CODEC_DMA_TX_0:
0062     case TX_CODEC_DMA_TX_1:
0063     case TX_CODEC_DMA_TX_2:
0064     case TX_CODEC_DMA_TX_3:
0065         for_each_rtd_codec_dais(rtd, i, codec_dai) {
0066             rval = snd_soc_component_set_jack(codec_dai->component,
0067                               &data->jack, NULL);
0068             if (rval != 0 && rval != -ENOTSUPP) {
0069                 dev_warn(card->dev, "Failed to set jack: %d\n", rval);
0070                 return rval;
0071             }
0072         }
0073 
0074         break;
0075     default:
0076         break;
0077     }
0078 
0079 
0080     return 0;
0081 }
0082 
0083 static int sm8250_be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd,
0084                      struct snd_pcm_hw_params *params)
0085 {
0086     struct snd_interval *rate = hw_param_interval(params,
0087                     SNDRV_PCM_HW_PARAM_RATE);
0088     struct snd_interval *channels = hw_param_interval(params,
0089                     SNDRV_PCM_HW_PARAM_CHANNELS);
0090 
0091     rate->min = rate->max = 48000;
0092     channels->min = channels->max = 2;
0093 
0094     return 0;
0095 }
0096 
0097 static int sm8250_snd_startup(struct snd_pcm_substream *substream)
0098 {
0099     unsigned int fmt = SND_SOC_DAIFMT_BP_FP;
0100     unsigned int codec_dai_fmt = SND_SOC_DAIFMT_BC_FC;
0101     struct snd_soc_pcm_runtime *rtd = substream->private_data;
0102     struct snd_soc_dai *cpu_dai = asoc_rtd_to_cpu(rtd, 0);
0103     struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 0);
0104 
0105     switch (cpu_dai->id) {
0106     case TERTIARY_MI2S_RX:
0107         codec_dai_fmt |= SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_I2S;
0108         snd_soc_dai_set_sysclk(cpu_dai,
0109             Q6AFE_LPASS_CLK_ID_TER_MI2S_IBIT,
0110             MI2S_BCLK_RATE, SNDRV_PCM_STREAM_PLAYBACK);
0111         snd_soc_dai_set_fmt(cpu_dai, fmt);
0112         snd_soc_dai_set_fmt(codec_dai, codec_dai_fmt);
0113         break;
0114     default:
0115         break;
0116     }
0117     return 0;
0118 }
0119 
0120 static int sm8250_snd_hw_params(struct snd_pcm_substream *substream,
0121                 struct snd_pcm_hw_params *params)
0122 {
0123     struct snd_soc_pcm_runtime *rtd = substream->private_data;
0124     struct snd_soc_dai *codec_dai;
0125     struct snd_soc_dai *cpu_dai = asoc_rtd_to_cpu(rtd, 0);
0126     struct sm8250_snd_data *pdata = snd_soc_card_get_drvdata(rtd->card);
0127     struct sdw_stream_runtime *sruntime;
0128     int i;
0129 
0130     switch (cpu_dai->id) {
0131     case WSA_CODEC_DMA_RX_0:
0132     case RX_CODEC_DMA_RX_0:
0133     case RX_CODEC_DMA_RX_1:
0134     case TX_CODEC_DMA_TX_0:
0135     case TX_CODEC_DMA_TX_1:
0136     case TX_CODEC_DMA_TX_2:
0137     case TX_CODEC_DMA_TX_3:
0138         for_each_rtd_codec_dais(rtd, i, codec_dai) {
0139             sruntime = snd_soc_dai_get_stream(codec_dai,
0140                               substream->stream);
0141             if (sruntime != ERR_PTR(-ENOTSUPP))
0142                 pdata->sruntime[cpu_dai->id] = sruntime;
0143         }
0144         break;
0145     }
0146 
0147     return 0;
0148 
0149 }
0150 
0151 static int sm8250_snd_wsa_dma_prepare(struct snd_pcm_substream *substream)
0152 {
0153     struct snd_soc_pcm_runtime *rtd = substream->private_data;
0154     struct snd_soc_dai *cpu_dai = asoc_rtd_to_cpu(rtd, 0);
0155     struct sm8250_snd_data *data = snd_soc_card_get_drvdata(rtd->card);
0156     struct sdw_stream_runtime *sruntime = data->sruntime[cpu_dai->id];
0157     int ret;
0158 
0159     if (!sruntime)
0160         return 0;
0161 
0162     if (data->stream_prepared[cpu_dai->id]) {
0163         sdw_disable_stream(sruntime);
0164         sdw_deprepare_stream(sruntime);
0165         data->stream_prepared[cpu_dai->id] = false;
0166     }
0167 
0168     ret = sdw_prepare_stream(sruntime);
0169     if (ret)
0170         return ret;
0171 
0172     /**
0173      * NOTE: there is a strict hw requirement about the ordering of port
0174      * enables and actual WSA881x PA enable. PA enable should only happen
0175      * after soundwire ports are enabled if not DC on the line is
0176      * accumulated resulting in Click/Pop Noise
0177      * PA enable/mute are handled as part of codec DAPM and digital mute.
0178      */
0179 
0180     ret = sdw_enable_stream(sruntime);
0181     if (ret) {
0182         sdw_deprepare_stream(sruntime);
0183         return ret;
0184     }
0185     data->stream_prepared[cpu_dai->id]  = true;
0186 
0187     return ret;
0188 }
0189 
0190 static int sm8250_snd_prepare(struct snd_pcm_substream *substream)
0191 {
0192     struct snd_soc_pcm_runtime *rtd = substream->private_data;
0193     struct snd_soc_dai *cpu_dai = asoc_rtd_to_cpu(rtd, 0);
0194 
0195     switch (cpu_dai->id) {
0196     case WSA_CODEC_DMA_RX_0:
0197     case WSA_CODEC_DMA_RX_1:
0198     case RX_CODEC_DMA_RX_0:
0199     case RX_CODEC_DMA_RX_1:
0200     case TX_CODEC_DMA_TX_0:
0201     case TX_CODEC_DMA_TX_1:
0202     case TX_CODEC_DMA_TX_2:
0203     case TX_CODEC_DMA_TX_3:
0204         return sm8250_snd_wsa_dma_prepare(substream);
0205     default:
0206         break;
0207     }
0208 
0209     return 0;
0210 }
0211 
0212 static int sm8250_snd_hw_free(struct snd_pcm_substream *substream)
0213 {
0214     struct snd_soc_pcm_runtime *rtd = substream->private_data;
0215     struct sm8250_snd_data *data = snd_soc_card_get_drvdata(rtd->card);
0216     struct snd_soc_dai *cpu_dai = asoc_rtd_to_cpu(rtd, 0);
0217     struct sdw_stream_runtime *sruntime = data->sruntime[cpu_dai->id];
0218 
0219     switch (cpu_dai->id) {
0220     case WSA_CODEC_DMA_RX_0:
0221     case WSA_CODEC_DMA_RX_1:
0222     case RX_CODEC_DMA_RX_0:
0223     case RX_CODEC_DMA_RX_1:
0224     case TX_CODEC_DMA_TX_0:
0225     case TX_CODEC_DMA_TX_1:
0226     case TX_CODEC_DMA_TX_2:
0227     case TX_CODEC_DMA_TX_3:
0228         if (sruntime && data->stream_prepared[cpu_dai->id]) {
0229             sdw_disable_stream(sruntime);
0230             sdw_deprepare_stream(sruntime);
0231             data->stream_prepared[cpu_dai->id] = false;
0232         }
0233         break;
0234     default:
0235         break;
0236     }
0237 
0238     return 0;
0239 }
0240 
0241 static const struct snd_soc_ops sm8250_be_ops = {
0242     .startup = sm8250_snd_startup,
0243     .hw_params = sm8250_snd_hw_params,
0244     .hw_free = sm8250_snd_hw_free,
0245     .prepare = sm8250_snd_prepare,
0246 };
0247 
0248 static void sm8250_add_be_ops(struct snd_soc_card *card)
0249 {
0250     struct snd_soc_dai_link *link;
0251     int i;
0252 
0253     for_each_card_prelinks(card, i, link) {
0254         if (link->no_pcm == 1) {
0255             link->init = sm8250_snd_init;
0256             link->be_hw_params_fixup = sm8250_be_hw_params_fixup;
0257             link->ops = &sm8250_be_ops;
0258         }
0259     }
0260 }
0261 
0262 static int sm8250_platform_probe(struct platform_device *pdev)
0263 {
0264     struct snd_soc_card *card;
0265     struct sm8250_snd_data *data;
0266     struct device *dev = &pdev->dev;
0267     int ret;
0268 
0269     card = devm_kzalloc(dev, sizeof(*card), GFP_KERNEL);
0270     if (!card)
0271         return -ENOMEM;
0272 
0273     card->owner = THIS_MODULE;
0274     /* Allocate the private data */
0275     data = devm_kzalloc(dev, sizeof(*data), GFP_KERNEL);
0276     if (!data)
0277         return -ENOMEM;
0278 
0279     card->dev = dev;
0280     dev_set_drvdata(dev, card);
0281     snd_soc_card_set_drvdata(card, data);
0282     ret = qcom_snd_parse_of(card);
0283     if (ret)
0284         return ret;
0285 
0286     card->driver_name = DRIVER_NAME;
0287     sm8250_add_be_ops(card);
0288     return devm_snd_soc_register_card(dev, card);
0289 }
0290 
0291 static const struct of_device_id snd_sm8250_dt_match[] = {
0292     {.compatible = "qcom,sm8250-sndcard"},
0293     {.compatible = "qcom,qrb5165-rb5-sndcard"},
0294     {}
0295 };
0296 
0297 MODULE_DEVICE_TABLE(of, snd_sm8250_dt_match);
0298 
0299 static struct platform_driver snd_sm8250_driver = {
0300     .probe  = sm8250_platform_probe,
0301     .driver = {
0302         .name = "snd-sm8250",
0303         .of_match_table = snd_sm8250_dt_match,
0304     },
0305 };
0306 module_platform_driver(snd_sm8250_driver);
0307 MODULE_AUTHOR("Srinivas Kandagatla <srinivas.kandagatla@linaro.org");
0308 MODULE_DESCRIPTION("SM8250 ASoC Machine Driver");
0309 MODULE_LICENSE("GPL v2");