2020-02-07 21:00:12

by Adam Serbinski

[permalink] [raw]
Subject: [PATCH 8/8] ASoC: qcom: apq8096: add kcontrols to set PCM rate

This makes it possible for the backend sample rate to be
set to 8000 or 16000 Hz, depending on the needs of the HFP
call being set up.

Signed-off-by: Adam Serbinski <[email protected]>
CC: Andy Gross <[email protected]>
CC: Mark Rutland <[email protected]>
CC: Liam Girdwood <[email protected]>
CC: Patrick Lai <[email protected]>
CC: Banajit Goswami <[email protected]>
CC: Jaroslav Kysela <[email protected]>
CC: Takashi Iwai <[email protected]>
CC: [email protected]
CC: [email protected]
CC: [email protected]
CC: [email protected]
---
sound/soc/qcom/apq8096.c | 92 +++++++++++++++++++++++++++++++++++++++-
1 file changed, 90 insertions(+), 2 deletions(-)

diff --git a/sound/soc/qcom/apq8096.c b/sound/soc/qcom/apq8096.c
index 1edcaa15234f..882f2c456321 100644
--- a/sound/soc/qcom/apq8096.c
+++ b/sound/soc/qcom/apq8096.c
@@ -16,6 +16,9 @@
#define MI2S_BCLK_RATE 1536000
#define PCM_BCLK_RATE 1024000

+static int pri_pcm_sample_rate = 16000;
+static int quat_pcm_sample_rate = 16000;
+
static int msm_snd_hw_params(struct snd_pcm_substream *substream,
struct snd_pcm_hw_params *params)
{
@@ -33,10 +36,15 @@ static int msm_snd_hw_params(struct snd_pcm_substream *substream,
switch (cpu_dai->id) {
case PRIMARY_PCM_RX:
case PRIMARY_PCM_TX:
+ rate->min = pri_pcm_sample_rate;
+ rate->max = pri_pcm_sample_rate;
+ channels->min = 1;
+ channels->max = 1;
+ break;
case QUATERNARY_PCM_RX:
case QUATERNARY_PCM_TX:
- rate->min = 16000;
- rate->max = 16000;
+ rate->min = quat_pcm_sample_rate;
+ rate->max = quat_pcm_sample_rate;
channels->min = 1;
channels->max = 1;
break;
@@ -121,6 +129,83 @@ static struct snd_soc_ops apq8096_ops = {
.startup = msm_snd_startup,
};

+static char const *pcm_sample_rate_text[] = {"8 kHz", "16 kHz"};
+static const struct soc_enum pcm_snd_enum =
+ SOC_ENUM_SINGLE_EXT(2, pcm_sample_rate_text);
+
+static int get_sample_rate_idx(int sample_rate)
+{
+ int sample_rate_idx = 0;
+
+ switch (sample_rate) {
+ case 8000:
+ sample_rate_idx = 0;
+ break;
+ case 16000:
+ default:
+ sample_rate_idx = 1;
+ break;
+ }
+
+ return sample_rate_idx;
+}
+
+static int pri_pcm_sample_rate_get(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ ucontrol->value.integer.value[0] =
+ get_sample_rate_idx(pri_pcm_sample_rate);
+ return 0;
+}
+
+static int quat_pcm_sample_rate_get(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ ucontrol->value.integer.value[0] =
+ get_sample_rate_idx(quat_pcm_sample_rate);
+ return 0;
+}
+
+static int get_sample_rate(int idx)
+{
+ int sample_rate_val = 0;
+
+ switch (idx) {
+ case 0:
+ sample_rate_val = 8000;
+ break;
+ case 1:
+ default:
+ sample_rate_val = 16000;
+ break;
+ }
+
+ return sample_rate_val;
+}
+
+static int pri_pcm_sample_rate_put(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ pri_pcm_sample_rate =
+ get_sample_rate(ucontrol->value.integer.value[0]);
+ return 0;
+}
+
+static int quat_pcm_sample_rate_put(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ quat_pcm_sample_rate =
+ get_sample_rate(ucontrol->value.integer.value[0]);
+ return 0;
+}
+
+static const struct snd_kcontrol_new card_controls[] = {
+ SOC_ENUM_EXT("PRI_PCM SampleRate", pcm_snd_enum,
+ pri_pcm_sample_rate_get, pri_pcm_sample_rate_put),
+ SOC_ENUM_EXT("QUAT_PCM SampleRate", pcm_snd_enum,
+ quat_pcm_sample_rate_get, quat_pcm_sample_rate_put),
+};
+
static int apq8096_init(struct snd_soc_pcm_runtime *rtd)
{
struct snd_soc_dai *codec_dai = rtd->codec_dai;
@@ -182,6 +267,9 @@ static int apq8096_platform_probe(struct platform_device *pdev)
if (ret)
goto err_card_register;

+ snd_soc_add_card_controls(card, card_controls,
+ ARRAY_SIZE(card_controls));
+
return 0;

err_card_register:
--
2.21.1