diff options
Diffstat (limited to 'sound/soc/qcom/sc8280xp.c')
| -rw-r--r-- | sound/soc/qcom/sc8280xp.c | 94 |
1 files changed, 65 insertions, 29 deletions
diff --git a/sound/soc/qcom/sc8280xp.c b/sound/soc/qcom/sc8280xp.c index 14d9fea33d16..7925aa3f63ba 100644 --- a/sound/soc/qcom/sc8280xp.c +++ b/sound/soc/qcom/sc8280xp.c @@ -1,12 +1,13 @@ // SPDX-License-Identifier: GPL-2.0 // Copyright (c) 2022, Linaro Limited +#include <dt-bindings/sound/qcom,q6afe.h> #include <linux/module.h> #include <linux/platform_device.h> -#include <linux/of_device.h> #include <sound/soc.h> #include <sound/soc-dapm.h> #include <sound/pcm.h> +#include <sound/pcm_params.h> #include <linux/soundwire/sdw.h> #include <sound/jack.h> #include <linux/input-event-codes.h> @@ -14,19 +15,54 @@ #include "common.h" #include "sdw.h" -#define DRIVER_NAME "sc8280xp" - struct sc8280xp_snd_data { bool stream_prepared[AFE_PORT_MAX]; struct snd_soc_card *card; - struct sdw_stream_runtime *sruntime[AFE_PORT_MAX]; struct snd_soc_jack jack; + struct snd_soc_jack dp_jack[8]; bool jack_setup; }; static int sc8280xp_snd_init(struct snd_soc_pcm_runtime *rtd) { struct sc8280xp_snd_data *data = snd_soc_card_get_drvdata(rtd->card); + struct snd_soc_dai *cpu_dai = snd_soc_rtd_to_cpu(rtd, 0); + struct snd_soc_card *card = rtd->card; + struct snd_soc_jack *dp_jack = NULL; + int dp_pcm_id = 0; + + switch (cpu_dai->id) { + case PRIMARY_MI2S_RX...QUATERNARY_MI2S_TX: + case QUINARY_MI2S_RX...QUINARY_MI2S_TX: + snd_soc_dai_set_fmt(cpu_dai, SND_SOC_DAIFMT_BP_FP); + break; + case WSA_CODEC_DMA_RX_0: + case WSA_CODEC_DMA_RX_1: + /* + * Set limit of -3 dB on Digital Volume and 0 dB on PA Volume + * to reduce the risk of speaker damage until we have active + * speaker protection in place. + */ + snd_soc_limit_volume(card, "WSA_RX0 Digital Volume", 81); + snd_soc_limit_volume(card, "WSA_RX1 Digital Volume", 81); + snd_soc_limit_volume(card, "SpkrLeft PA Volume", 17); + snd_soc_limit_volume(card, "SpkrRight PA Volume", 17); + break; + case DISPLAY_PORT_RX_0: + /* DISPLAY_PORT dai ids are not contiguous */ + dp_pcm_id = 0; + dp_jack = &data->dp_jack[dp_pcm_id]; + break; + case DISPLAY_PORT_RX_1 ... DISPLAY_PORT_RX_7: + dp_pcm_id = cpu_dai->id - DISPLAY_PORT_RX_1 + 1; + dp_jack = &data->dp_jack[dp_pcm_id]; + break; + default: + break; + } + + if (dp_jack) + return qcom_snd_dp_jack_setup(rtd, dp_jack, dp_pcm_id); return qcom_snd_wcd_jack_setup(rtd, &data->jack, &data->jack_setup); } @@ -34,13 +70,15 @@ static int sc8280xp_snd_init(struct snd_soc_pcm_runtime *rtd) static int sc8280xp_be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd, struct snd_pcm_hw_params *params) { - struct snd_soc_dai *cpu_dai = asoc_rtd_to_cpu(rtd, 0); + struct snd_soc_dai *cpu_dai = snd_soc_rtd_to_cpu(rtd, 0); struct snd_interval *rate = hw_param_interval(params, SNDRV_PCM_HW_PARAM_RATE); struct snd_interval *channels = hw_param_interval(params, SNDRV_PCM_HW_PARAM_CHANNELS); + struct snd_mask *fmt = hw_param_mask(params, SNDRV_PCM_HW_PARAM_FORMAT); rate->min = rate->max = 48000; + snd_mask_set_format(fmt, SNDRV_PCM_FORMAT_S16_LE); channels->min = 2; channels->max = 2; switch (cpu_dai->id) { @@ -58,40 +96,27 @@ static int sc8280xp_be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd, return 0; } -static int sc8280xp_snd_hw_params(struct snd_pcm_substream *substream, - struct snd_pcm_hw_params *params) -{ - struct snd_soc_pcm_runtime *rtd = substream->private_data; - struct snd_soc_dai *cpu_dai = asoc_rtd_to_cpu(rtd, 0); - struct sc8280xp_snd_data *pdata = snd_soc_card_get_drvdata(rtd->card); - - return qcom_snd_sdw_hw_params(substream, params, &pdata->sruntime[cpu_dai->id]); -} - static int sc8280xp_snd_prepare(struct snd_pcm_substream *substream) { - struct snd_soc_pcm_runtime *rtd = substream->private_data; - struct snd_soc_dai *cpu_dai = asoc_rtd_to_cpu(rtd, 0); + struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream); + struct snd_soc_dai *cpu_dai = snd_soc_rtd_to_cpu(rtd, 0); struct sc8280xp_snd_data *data = snd_soc_card_get_drvdata(rtd->card); - struct sdw_stream_runtime *sruntime = data->sruntime[cpu_dai->id]; - return qcom_snd_sdw_prepare(substream, sruntime, - &data->stream_prepared[cpu_dai->id]); + return qcom_snd_sdw_prepare(substream, &data->stream_prepared[cpu_dai->id]); } static int sc8280xp_snd_hw_free(struct snd_pcm_substream *substream) { - struct snd_soc_pcm_runtime *rtd = substream->private_data; + struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream); struct sc8280xp_snd_data *data = snd_soc_card_get_drvdata(rtd->card); - struct snd_soc_dai *cpu_dai = asoc_rtd_to_cpu(rtd, 0); - struct sdw_stream_runtime *sruntime = data->sruntime[cpu_dai->id]; + struct snd_soc_dai *cpu_dai = snd_soc_rtd_to_cpu(rtd, 0); - return qcom_snd_sdw_hw_free(substream, sruntime, - &data->stream_prepared[cpu_dai->id]); + return qcom_snd_sdw_hw_free(substream, &data->stream_prepared[cpu_dai->id]); } static const struct snd_soc_ops sc8280xp_be_ops = { - .hw_params = sc8280xp_snd_hw_params, + .startup = qcom_snd_sdw_startup, + .shutdown = qcom_snd_sdw_shutdown, .hw_free = sc8280xp_snd_hw_free, .prepare = sc8280xp_snd_prepare, }; @@ -133,13 +158,24 @@ static int sc8280xp_platform_probe(struct platform_device *pdev) if (ret) return ret; - card->driver_name = DRIVER_NAME; + card->driver_name = of_device_get_match_data(dev); sc8280xp_add_be_ops(card); return devm_snd_soc_register_card(dev, card); } static const struct of_device_id snd_sc8280xp_dt_match[] = { - {.compatible = "qcom,sc8280xp-sndcard",}, + {.compatible = "qcom,kaanapali-sndcard", "kaanapali"}, + {.compatible = "qcom,qcm6490-idp-sndcard", "qcm6490"}, + {.compatible = "qcom,qcs615-sndcard", "qcs615"}, + {.compatible = "qcom,qcs6490-rb3gen2-sndcard", "qcs6490"}, + {.compatible = "qcom,qcs8275-sndcard", "qcs8300"}, + {.compatible = "qcom,qcs9075-sndcard", "sa8775p"}, + {.compatible = "qcom,qcs9100-sndcard", "sa8775p"}, + {.compatible = "qcom,sc8280xp-sndcard", "sc8280xp"}, + {.compatible = "qcom,sm8450-sndcard", "sm8450"}, + {.compatible = "qcom,sm8550-sndcard", "sm8550"}, + {.compatible = "qcom,sm8650-sndcard", "sm8650"}, + {.compatible = "qcom,sm8750-sndcard", "sm8750"}, {} }; @@ -155,4 +191,4 @@ static struct platform_driver snd_sc8280xp_driver = { module_platform_driver(snd_sc8280xp_driver); MODULE_AUTHOR("Srinivas Kandagatla <srinivas.kandagatla@linaro.org"); MODULE_DESCRIPTION("SC8280XP ASoC Machine Driver"); -MODULE_LICENSE("GPL v2"); +MODULE_LICENSE("GPL"); |
