Merge "dsp: add audio ion virtualization support"
diff --git a/asoc/codecs/audio-ext-clk-up.c b/asoc/codecs/audio-ext-clk-up.c
index e6e68ad..6bdf00f 100644
--- a/asoc/codecs/audio-ext-clk-up.c
+++ b/asoc/codecs/audio-ext-clk-up.c
@@ -70,7 +70,7 @@
clk_priv->clk_cfg.enable = 1;
ret = afe_set_lpass_clk_cfg(IDX_RSVD_3, &clk_priv->clk_cfg);
if (ret < 0) {
- pr_err("%s afe_set_digital_codec_core_clock failed\n",
+ pr_err_ratelimited("%s afe_set_digital_codec_core_clock failed\n",
__func__);
return ret;
}
@@ -112,7 +112,7 @@
clk_priv->clk_cfg.enable = 0;
ret = afe_set_lpass_clk_cfg(IDX_RSVD_3, &clk_priv->clk_cfg);
if (ret < 0)
- pr_err("%s: afe_set_lpass_clk_cfg failed, ret = %d\n",
+ pr_err_ratelimited("%s: afe_set_lpass_clk_cfg failed, ret = %d\n",
__func__, ret);
}
diff --git a/asoc/codecs/bolero/tx-macro.c b/asoc/codecs/bolero/tx-macro.c
index 49b7da5..51930ee 100644
--- a/asoc/codecs/bolero/tx-macro.c
+++ b/asoc/codecs/bolero/tx-macro.c
@@ -212,7 +212,7 @@
TX_CORE_CLK,
true);
if (ret < 0) {
- dev_err(tx_priv->dev,
+ dev_err_ratelimited(tx_priv->dev,
"%s: request clock enable failed\n",
__func__);
goto exit;
diff --git a/asoc/codecs/bolero/wsa-macro.c b/asoc/codecs/bolero/wsa-macro.c
index d1ba346..68f1cb9 100644
--- a/asoc/codecs/bolero/wsa-macro.c
+++ b/asoc/codecs/bolero/wsa-macro.c
@@ -815,7 +815,7 @@
wsa_priv->default_clk_id,
true);
if (ret < 0) {
- dev_err(wsa_priv->dev,
+ dev_err_ratelimited(wsa_priv->dev,
"%s: wsa request clock enable failed\n",
__func__);
goto exit;
@@ -2637,7 +2637,7 @@
if (ret < 0) {
msm_cdc_pinctrl_select_sleep_state(
wsa_priv->wsa_swr_gpio_p);
- dev_err(wsa_priv->dev,
+ dev_err_ratelimited(wsa_priv->dev,
"%s: wsa request clock enable failed\n",
__func__);
goto exit;
diff --git a/asoc/msm-audio-effects-q6-v2.c b/asoc/msm-audio-effects-q6-v2.c
index 7ab6db4..bdb0059 100644
--- a/asoc/msm-audio-effects-q6-v2.c
+++ b/asoc/msm-audio-effects-q6-v2.c
@@ -1,8 +1,9 @@
// SPDX-License-Identifier: GPL-2.0-only
-/* Copyright (c) 2013-2018, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2013-2019, The Linux Foundation. All rights reserved.
*/
#include <linux/slab.h>
+#include <linux/ratelimit.h>
#include <sound/compress_params.h>
#include <sound/devdep_params.h>
#include <dsp/apr_audio-v2.h>
@@ -15,7 +16,8 @@
#define GET_NEXT(ptr, upper_limit, rc) \
({ \
if (((ptr) + 1) > (upper_limit)) { \
- pr_err("%s: param list out of boundary\n", __func__); \
+ pr_err_ratelimited("%s: param list out of boundary\n", \
+ __func__); \
(rc) = -EINVAL; \
} \
((rc) == 0) ? *(ptr)++ : -EINVAL; \
@@ -24,7 +26,8 @@
#define CHECK_PARAM_LEN(len, max_len, tag, rc) \
do { \
if ((len) > (max_len)) { \
- pr_err("%s: params length overflows\n", (tag)); \
+ pr_err_ratelimited("%s: params length overflows\n", \
+ (tag)); \
(rc) = -EINVAL; \
} \
} while (0)
@@ -244,7 +247,8 @@
param_data = (u8 *) &virtualizer->gain_adjust;
break;
default:
- pr_err("%s: Invalid command to set config\n", __func__);
+ pr_err_ratelimited("%s: Invalid command to set config\n",
+ __func__);
continue;
}
if (rc)
@@ -678,7 +682,8 @@
param_data = (u8 *) &reverb->density;
break;
default:
- pr_err("%s: Invalid command to set config\n", __func__);
+ pr_err_ratelimited("%s: Invalid command to set config\n",
+ __func__);
continue;
}
if (rc)
@@ -831,7 +836,8 @@
param_data = (u8 *) &bass_boost->strength;
break;
default:
- pr_err("%s: Invalid command to set config\n", __func__);
+ pr_err_ratelimited("%s: Invalid command to set config\n",
+ __func__);
continue;
}
if (rc)
@@ -956,7 +962,8 @@
param_data = (u8 *) values;
break;
default:
- pr_err("%s: Invalid command to set config\n", __func__);
+ pr_err_ratelimited("%s: Invalid command to set config\n",
+ __func__);
continue;
}
if (rc)
@@ -1214,7 +1221,8 @@
param_data = (u8 *) &eq->freq_millihertz;
break;
default:
- pr_err("%s: Invalid command to set config\n", __func__);
+ pr_err_ratelimited("%s: Invalid command to set config\n",
+ __func__);
continue;
}
if (rc)
@@ -1335,7 +1343,7 @@
"VOLUME/VOLUME2_GAIN_MASTER", rc);
break;
default:
- pr_err("%s: Invalid command id: %d to set config\n",
+ pr_err_ratelimited("%s: Invalid command id: %d to set config\n",
__func__, command_id);
continue;
}
diff --git a/asoc/msm-lsm-client.c b/asoc/msm-lsm-client.c
index 3a5707e..ff77e90 100644
--- a/asoc/msm-lsm-client.c
+++ b/asoc/msm-lsm-client.c
@@ -2425,6 +2425,7 @@
{
struct snd_pcm_runtime *runtime = substream->runtime;
struct lsm_priv *prtd;
+ struct snd_soc_pcm_runtime *rtd = substream->private_data;
int ret = 0;
pr_debug("%s\n", __func__);
@@ -2488,6 +2489,8 @@
prtd->lsm_client->perf_mode = 0;
prtd->lsm_client->event_mode = LSM_EVENT_NON_TIME_STAMP_MODE;
prtd->lsm_client->event_type = LSM_DET_EVENT_TYPE_LEGACY;
+ prtd->lsm_client->fe_id = rtd->dai_link->id;
+ prtd->lsm_client->unprocessed_data = 0;
return 0;
}
@@ -2958,13 +2961,81 @@
return 0;
}
+static int msm_lsm_afe_data_ctl_put(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ u64 fe_id = kcontrol->private_value;
+ uint16_t afe_data_format = 0;
+ int ret = 0;
+
+ afe_data_format = ucontrol->value.integer.value[0];
+ pr_debug("%s: afe data is %s\n", __func__,
+ afe_data_format ? "unprocessed" : "processed");
+
+ ret = q6lsm_set_afe_data_format(fe_id, afe_data_format);
+ if (ret)
+ pr_err("%s: q6lsm_set_afe_data_format failed, ret = %d\n",
+ __func__, ret);
+
+ return ret;
+}
+
+static int msm_lsm_afe_data_ctl_get(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ u64 fe_id = kcontrol->private_value;
+ uint16_t afe_data_format = 0;
+ int ret = 0;
+
+ q6lsm_get_afe_data_format(fe_id, &afe_data_format);
+ ucontrol->value.integer.value[0] = afe_data_format;
+ pr_debug("%s: afe data is %s\n", __func__,
+ afe_data_format ? "unprocessed" : "processed");
+
+ return ret;
+}
+
+static int msm_lsm_add_afe_data_controls(struct snd_soc_pcm_runtime *rtd)
+{
+ struct snd_pcm *pcm = rtd->pcm;
+ struct snd_pcm_usr *afe_data_info;
+ struct snd_kcontrol *kctl;
+ const char *mixer_ctl_name = "Listen Stream";
+ const char *deviceNo = "NN";
+ const char *suffix = "Unprocessed Data";
+ int ctl_len, ret = 0;
+
+ ctl_len = strlen(mixer_ctl_name) + 1 + strlen(deviceNo) + 1 +
+ strlen(suffix) + 1;
+ pr_debug("%s: Adding Listen afe data cntrls\n", __func__);
+ ret = snd_pcm_add_usr_ctls(pcm, SNDRV_PCM_STREAM_CAPTURE,
+ NULL, 1, ctl_len, rtd->dai_link->id,
+ &afe_data_info);
+ if (ret < 0) {
+ pr_err("%s: Adding Listen afe data cntrls failed: %d\n",
+ __func__, ret);
+ return ret;
+ }
+ kctl = afe_data_info->kctl;
+ snprintf(kctl->id.name, ctl_len, "%s %d %s",
+ mixer_ctl_name, rtd->pcm->device, suffix);
+ kctl->put = msm_lsm_afe_data_ctl_put;
+ kctl->get = msm_lsm_afe_data_ctl_get;
+
+ return 0;
+}
+
static int msm_lsm_add_controls(struct snd_soc_pcm_runtime *rtd)
{
int ret = 0;
ret = msm_lsm_add_app_type_controls(rtd);
if (ret)
- pr_err("%s, add app type controls failed:%d\n", __func__, ret);
+ pr_err("%s, add app type controls failed:%d\n", __func__, ret);
+
+ ret = msm_lsm_add_afe_data_controls(rtd);
+ if (ret)
+ pr_err("%s, add afe data controls failed:%d\n", __func__, ret);
return ret;
}
diff --git a/asoc/qcs405.c b/asoc/qcs405.c
index 0455748..554779d 100644
--- a/asoc/qcs405.c
+++ b/asoc/qcs405.c
@@ -440,6 +440,12 @@
[SEN_AUX_PCM] = {SAMPLING_RATE_8KHZ, SNDRV_PCM_FORMAT_S16_LE, 1},
};
+static struct dev_config afe_lb_tx_cfg = {
+ .sample_rate = SAMPLING_RATE_48KHZ,
+ .bit_format = SNDRV_PCM_FORMAT_S16_LE,
+ .channels = 2,
+};
+
static int msm_vi_feed_tx_ch = 2;
static const char *const slim_rx_ch_text[] = {"One", "Two"};
static const char *const slim_tx_ch_text[] = {"One", "Two", "Three", "Four",
@@ -602,6 +608,10 @@
static SOC_ENUM_SINGLE_EXT_DECL(spdif_tx_chs, spdif_ch_text);
static SOC_ENUM_SINGLE_EXT_DECL(spdif_rx_format, spdif_bit_format_text);
static SOC_ENUM_SINGLE_EXT_DECL(spdif_tx_format, spdif_bit_format_text);
+static SOC_ENUM_SINGLE_EXT_DECL(afe_lb_tx_chs, cdc_dma_tx_ch_text);
+static SOC_ENUM_SINGLE_EXT_DECL(afe_lb_tx_format, bit_format_text);
+static SOC_ENUM_SINGLE_EXT_DECL(afe_lb_tx_sample_rate,
+ cdc_dma_sample_rate_text);
static struct platform_device *spdev;
@@ -3444,6 +3454,184 @@
return 0;
}
+static int afe_lb_tx_ch_get(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ pr_debug("%s: afe_lb_tx_ch = %d\n", __func__,
+ afe_lb_tx_cfg.channels);
+ ucontrol->value.integer.value[0] = afe_lb_tx_cfg.channels - 1;
+ return 0;
+}
+
+static int afe_lb_tx_ch_put(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ afe_lb_tx_cfg.channels = ucontrol->value.integer.value[0] + 1;
+
+ pr_debug("%s: afe_lb_tx_ch = %d\n", __func__, afe_lb_tx_cfg.channels);
+ return 0;
+}
+
+static int afe_lb_tx_sample_rate_get(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ int sample_rate_val;
+
+ switch (afe_lb_tx_cfg.sample_rate) {
+ case SAMPLING_RATE_384KHZ:
+ sample_rate_val = 12;
+ break;
+ case SAMPLING_RATE_352P8KHZ:
+ sample_rate_val = 11;
+ break;
+ case SAMPLING_RATE_192KHZ:
+ sample_rate_val = 10;
+ break;
+ case SAMPLING_RATE_176P4KHZ:
+ sample_rate_val = 9;
+ break;
+ case SAMPLING_RATE_96KHZ:
+ sample_rate_val = 8;
+ break;
+ case SAMPLING_RATE_88P2KHZ:
+ sample_rate_val = 7;
+ break;
+ case SAMPLING_RATE_48KHZ:
+ sample_rate_val = 6;
+ break;
+ case SAMPLING_RATE_44P1KHZ:
+ sample_rate_val = 5;
+ break;
+ case SAMPLING_RATE_32KHZ:
+ sample_rate_val = 4;
+ break;
+ case SAMPLING_RATE_22P05KHZ:
+ sample_rate_val = 3;
+ break;
+ case SAMPLING_RATE_16KHZ:
+ sample_rate_val = 2;
+ break;
+ case SAMPLING_RATE_11P025KHZ:
+ sample_rate_val = 1;
+ break;
+ case SAMPLING_RATE_8KHZ:
+ sample_rate_val = 0;
+ break;
+ default:
+ sample_rate_val = 6;
+ break;
+ }
+
+ ucontrol->value.integer.value[0] = sample_rate_val;
+ pr_debug("%s: afe_lb_tx_sample_rate = %d\n", __func__,
+ afe_lb_tx_cfg.sample_rate);
+ return 0;
+}
+
+static int afe_lb_tx_sample_rate_put(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ switch (ucontrol->value.integer.value[0]) {
+ case 12:
+ afe_lb_tx_cfg.sample_rate = SAMPLING_RATE_384KHZ;
+ break;
+ case 11:
+ afe_lb_tx_cfg.sample_rate = SAMPLING_RATE_352P8KHZ;
+ break;
+ case 10:
+ afe_lb_tx_cfg.sample_rate = SAMPLING_RATE_192KHZ;
+ break;
+ case 9:
+ afe_lb_tx_cfg.sample_rate = SAMPLING_RATE_176P4KHZ;
+ break;
+ case 8:
+ afe_lb_tx_cfg.sample_rate = SAMPLING_RATE_96KHZ;
+ break;
+ case 7:
+ afe_lb_tx_cfg.sample_rate = SAMPLING_RATE_88P2KHZ;
+ break;
+ case 6:
+ afe_lb_tx_cfg.sample_rate = SAMPLING_RATE_48KHZ;
+ break;
+ case 5:
+ afe_lb_tx_cfg.sample_rate = SAMPLING_RATE_44P1KHZ;
+ break;
+ case 4:
+ afe_lb_tx_cfg.sample_rate = SAMPLING_RATE_32KHZ;
+ break;
+ case 3:
+ afe_lb_tx_cfg.sample_rate = SAMPLING_RATE_22P05KHZ;
+ break;
+ case 2:
+ afe_lb_tx_cfg.sample_rate = SAMPLING_RATE_16KHZ;
+ break;
+ case 1:
+ afe_lb_tx_cfg.sample_rate = SAMPLING_RATE_11P025KHZ;
+ break;
+ case 0:
+ afe_lb_tx_cfg.sample_rate = SAMPLING_RATE_8KHZ;
+ break;
+ default:
+ afe_lb_tx_cfg.sample_rate = SAMPLING_RATE_48KHZ;
+ break;
+ }
+
+ pr_debug("%s: control value = %ld, afe_lb_tx_sample_rate = %d\n",
+ __func__, ucontrol->value.integer.value[0],
+ afe_lb_tx_cfg.sample_rate);
+ return 0;
+}
+
+static int afe_lb_tx_format_get(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ switch (afe_lb_tx_cfg.bit_format) {
+ case SNDRV_PCM_FORMAT_S32_LE:
+ ucontrol->value.integer.value[0] = 3;
+ break;
+ case SNDRV_PCM_FORMAT_S24_3LE:
+ ucontrol->value.integer.value[0] = 2;
+ break;
+ case SNDRV_PCM_FORMAT_S24_LE:
+ ucontrol->value.integer.value[0] = 1;
+ break;
+ case SNDRV_PCM_FORMAT_S16_LE:
+ default:
+ ucontrol->value.integer.value[0] = 0;
+ break;
+ }
+
+ pr_debug("%s: afe_lb_tx_format = %d, ucontrol value = %ld\n",
+ __func__, afe_lb_tx_cfg.bit_format,
+ ucontrol->value.integer.value[0]);
+ return 0;
+}
+
+static int afe_lb_tx_format_put(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ switch (ucontrol->value.integer.value[0]) {
+ case 3:
+ afe_lb_tx_cfg.bit_format = SNDRV_PCM_FORMAT_S32_LE;
+ break;
+ case 2:
+ afe_lb_tx_cfg.bit_format = SNDRV_PCM_FORMAT_S24_3LE;
+ break;
+ case 1:
+ afe_lb_tx_cfg.bit_format = SNDRV_PCM_FORMAT_S24_LE;
+ break;
+ case 0:
+ default:
+ afe_lb_tx_cfg.bit_format = SNDRV_PCM_FORMAT_S16_LE;
+ break;
+ }
+
+ pr_debug("%s: afe_lb_tx_format = %d, ucontrol value = %ld\n",
+ __func__, afe_lb_tx_cfg.bit_format,
+ ucontrol->value.integer.value[0]);
+ return 0;
+}
+
static const struct snd_kcontrol_new msm_snd_sb_controls[] = {
SOC_ENUM_EXT("SLIM_0_RX Channels", slim_0_rx_chs,
slim_rx_ch_get, slim_rx_ch_put),
@@ -3826,6 +4014,13 @@
msm_spdif_rx_format_get, msm_spdif_rx_format_put),
SOC_ENUM_EXT("SEC_SPDIF_TX Format", spdif_tx_format,
msm_spdif_tx_format_get, msm_spdif_tx_format_put),
+ SOC_ENUM_EXT("AFE_LOOPBACK_TX Channels", afe_lb_tx_chs,
+ afe_lb_tx_ch_get, afe_lb_tx_ch_put),
+ SOC_ENUM_EXT("AFE_LOOPBACK_TX Format", afe_lb_tx_format,
+ afe_lb_tx_format_get, afe_lb_tx_format_put),
+ SOC_ENUM_EXT("AFE_LOOPBACK_TX SampleRate", afe_lb_tx_sample_rate,
+ afe_lb_tx_sample_rate_get,
+ afe_lb_tx_sample_rate_put),
};
static int msm_snd_enable_codec_ext_clk(struct snd_soc_component *component,
@@ -4610,6 +4805,13 @@
spdif_tx_cfg[SEC_SPDIF_TX].channels;
break;
+ case MSM_BACKEND_DAI_AFE_LOOPBACK_TX:
+ param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT,
+ afe_lb_tx_cfg.bit_format);
+ rate->min = rate->max = afe_lb_tx_cfg.sample_rate;
+ channels->min = channels->max = afe_lb_tx_cfg.channels;
+ break;
+
default:
rate->min = rate->max = SAMPLING_RATE_48KHZ;
break;
@@ -7630,6 +7832,7 @@
.no_pcm = 1,
.dpcm_capture = 1,
.id = MSM_BACKEND_DAI_AFE_LOOPBACK_TX,
+ .be_hw_params_fixup = msm_be_hw_params_fixup,
.ignore_pmdown_time = 1,
.ignore_suspend = 1,
},
diff --git a/dsp/codecs/audio_alac.c b/dsp/codecs/audio_alac.c
index f7e0932..a3e473f 100644
--- a/dsp/codecs/audio_alac.c
+++ b/dsp/codecs/audio_alac.c
@@ -1,15 +1,5 @@
// SPDX-License-Identifier: GPL-2.0-only
/* Copyright (c) 2015-2019, The Linux Foundation. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 and
- * only version 2 as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
*/
#include <linux/types.h>
diff --git a/dsp/codecs/audio_ape.c b/dsp/codecs/audio_ape.c
index 1e12981..319828b 100644
--- a/dsp/codecs/audio_ape.c
+++ b/dsp/codecs/audio_ape.c
@@ -1,15 +1,5 @@
// SPDX-License-Identifier: GPL-2.0-only
/* Copyright (c) 2015-2019, The Linux Foundation. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 and
- * only version 2 as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
*/
#include <linux/types.h>
diff --git a/dsp/codecs/audio_g711alaw.c b/dsp/codecs/audio_g711alaw.c
index b4a1d7e..27d7fe0 100644
--- a/dsp/codecs/audio_g711alaw.c
+++ b/dsp/codecs/audio_g711alaw.c
@@ -1,15 +1,5 @@
// SPDX-License-Identifier: GPL-2.0-only
/* Copyright (c) 2016-2017, 2019 The Linux Foundation. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 and
- * only version 2 as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
*/
#include <linux/types.h>
diff --git a/dsp/codecs/audio_g711mlaw.c b/dsp/codecs/audio_g711mlaw.c
index 1cf8a97..57c7f1a 100644
--- a/dsp/codecs/audio_g711mlaw.c
+++ b/dsp/codecs/audio_g711mlaw.c
@@ -1,15 +1,5 @@
// SPDX-License-Identifier: GPL-2.0-only
/* Copyright (c) 2016-2017, 2019 The Linux Foundation. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 and
- * only version 2 as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
*/
#include <linux/types.h>
diff --git a/dsp/q6afe.c b/dsp/q6afe.c
index 7a510be..23d30bc 100644
--- a/dsp/q6afe.c
+++ b/dsp/q6afe.c
@@ -7578,7 +7578,7 @@
ret = afe_q6_interface_prepare();
if (ret != 0) {
- pr_err("%s: Q6 interface prepare failed %d\n", __func__, ret);
+ pr_err_ratelimited("%s: Q6 interface prepare failed %d\n", __func__, ret);
return ret;
}
@@ -7599,7 +7599,7 @@
ret = q6afe_svc_pack_and_set_param_in_band(index, param_hdr,
(u8 *) cfg);
if (ret < 0)
- pr_err("%s: AFE clk cfg failed with ret %d\n",
+ pr_err_ratelimited("%s: AFE clk cfg failed with ret %d\n",
__func__, ret);
mutex_unlock(&this_afe.afe_cmd_lock);
diff --git a/dsp/q6lsm.c b/dsp/q6lsm.c
index 96671ec..d55dfc3 100644
--- a/dsp/q6lsm.c
+++ b/dsp/q6lsm.c
@@ -89,6 +89,13 @@
static int q6lsm_memory_unmap_regions(struct lsm_client *client,
uint32_t handle);
+struct lsm_client_afe_data {
+ uint64_t fe_id;
+ uint16_t unprocessed_data;
+};
+
+static struct lsm_client_afe_data lsm_client_afe_data[LSM_MAX_SESSION_ID + 1];
+
static int q6lsm_get_session_id_from_lsm_client(struct lsm_client *client)
{
int n;
@@ -255,6 +262,8 @@
pr_debug("%s: Freeing session ID %d\n", __func__, client->session);
spin_lock_irqsave(&lsm_session_lock, flags);
lsm_session[client->session] = NULL;
+ lsm_client_afe_data[client->session].fe_id = 0;
+ lsm_client_afe_data[client->session].unprocessed_data = 0;
spin_unlock_irqrestore(&lsm_session_lock, flags);
client->session = LSM_INVALID_SESSION_ID;
}
@@ -1063,6 +1072,72 @@
}
/**
+ * q6lsm_set_afe_data_format -
+ * command to set afe data format
+ *
+ * @fe_id: FrontEnd DAI link ID
+ * @afe_data_format: afe data format
+ *
+ * Returns 0 on success or -EINVAL on failure
+ */
+int q6lsm_set_afe_data_format(uint64_t fe_id, uint16_t afe_data_format)
+{
+ int n = 0;
+
+ if (0 != afe_data_format && 1 != afe_data_format)
+ goto done;
+
+ pr_debug("%s: afe data is %s\n", __func__,
+ afe_data_format ? "unprocessed" : "processed");
+
+ for (n = LSM_MIN_SESSION_ID; n <= LSM_MAX_SESSION_ID; n++) {
+ if (0 == lsm_client_afe_data[n].fe_id) {
+ lsm_client_afe_data[n].fe_id = fe_id;
+ lsm_client_afe_data[n].unprocessed_data =
+ afe_data_format;
+ pr_debug("%s: session ID is %d, fe_id is %d\n",
+ __func__, n, fe_id);
+ return 0;
+ }
+ }
+
+ pr_err("%s: all lsm sessions are taken\n", __func__);
+done:
+ return -EINVAL;
+}
+EXPORT_SYMBOL(q6lsm_set_afe_data_format);
+
+/**
+ * q6lsm_get_afe_data_format -
+ * command to get afe data format
+ *
+ * @fe_id: FrontEnd DAI link ID
+ * @afe_data_format: afe data format
+ *
+ */
+void q6lsm_get_afe_data_format(uint64_t fe_id, uint16_t *afe_data_format)
+{
+ int n = 0;
+
+ if (NULL == afe_data_format) {
+ pr_err("%s: Pointer afe_data_format is NULL\n", __func__);
+ return;
+ }
+
+ for (n = LSM_MIN_SESSION_ID; n <= LSM_MAX_SESSION_ID; n++) {
+ if (fe_id == lsm_client_afe_data[n].fe_id) {
+ *afe_data_format =
+ lsm_client_afe_data[n].unprocessed_data;
+ pr_debug("%s: session: %d, fe_id: %d, afe data: %s\n",
+ __func__, n, fe_id,
+ *afe_data_format ? "unprocessed" : "processed");
+ return;
+ }
+ }
+}
+EXPORT_SYMBOL(q6lsm_get_afe_data_format);
+
+/**
* q6lsm_set_port_connected -
* command to set LSM port connected
*
@@ -1092,14 +1167,19 @@
connectport_hdr.param_size = sizeof(connect_port);
client->connect_to_port = get_lsm_port();
+ if (ADM_LSM_PORT_ID != client->connect_to_port)
+ q6lsm_get_afe_data_format(client->fe_id,
+ &client->unprocessed_data);
connect_port.minor_version = QLSM_PARAM_ID_MINOR_VERSION;
connect_port.port_id = client->connect_to_port;
+ connect_port.unprocessed_data = client->unprocessed_data;
rc = q6lsm_pack_and_set_params(client, &connectport_hdr,
(uint8_t *) &connect_port,
set_param_opcode);
if (rc)
pr_err("%s: Failed set_params, rc %d\n", __func__, rc);
+
return rc;
}
EXPORT_SYMBOL(q6lsm_set_port_connected);
diff --git a/include/dsp/q6lsm.h b/include/dsp/q6lsm.h
index e4a007f..af43cdd 100644
--- a/include/dsp/q6lsm.h
+++ b/include/dsp/q6lsm.h
@@ -1,6 +1,6 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
- * Copyright (c) 2013-2018, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2013-2019, The Linux Foundation. All rights reserved.
*/
#ifndef __Q6LSM_H__
#define __Q6LSM_H__
@@ -102,6 +102,8 @@
uint32_t event_type;
uint32_t num_stages;
struct lsm_stage_config stage_cfg[LSM_MAX_STAGES_PER_SESSION];
+ uint64_t fe_id;
+ uint16_t unprocessed_data;
};
struct lsm_stream_cmd_open_tx {
@@ -159,7 +161,7 @@
uint32_t minor_version;
/* AFE port id that receives voice wake up data */
uint16_t port_id;
- uint16_t reserved;
+ uint16_t unprocessed_data;
} __packed;
struct lsm_param_poll_enable {
@@ -295,4 +297,6 @@
int q6lsm_lab_out_ch_cfg(struct lsm_client *client, u8 *ch_map,
struct lsm_params_info_v2 *p_info);
bool q6lsm_adsp_supports_multi_stage_detection(void);
+int q6lsm_set_afe_data_format(uint64_t fe_id, uint16_t afe_data_format);
+void q6lsm_get_afe_data_format(uint64_t fe_id, uint16_t *afe_data_format);
#endif /* __Q6LSM_H__ */
diff --git a/include/soc/wcd-spi-ac.h b/include/soc/wcd-spi-ac.h
index 5131c49..e07d235 100644
--- a/include/soc/wcd-spi-ac.h
+++ b/include/soc/wcd-spi-ac.h
@@ -1,13 +1,5 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
/* Copyright (c) 2018-2019, The Linux Foundation. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 and
- * only version 2 as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
*/
#ifndef __WCD_SPI_AC_H__
diff --git a/soc/swr-mstr-ctrl.c b/soc/swr-mstr-ctrl.c
index c9cccf6..461e82f 100644
--- a/soc/swr-mstr-ctrl.c
+++ b/soc/swr-mstr-ctrl.c
@@ -249,7 +249,7 @@
if (swrm->clk_ref_count == 1) {
ret = swrm->clk(swrm->handle, true);
if (ret) {
- dev_err(swrm->dev,
+ dev_err_ratelimited(swrm->dev,
"%s: clock enable req failed",
__func__);
--swrm->clk_ref_count;
@@ -1277,6 +1277,8 @@
mutex_lock(&swrm->reslock);
if (swrm_clk_request(swrm, true)) {
+ dev_err_ratelimited(swrm->dev, "%s:clk request failed\n",
+ __func__);
mutex_unlock(&swrm->reslock);
goto exit;
}
@@ -1447,8 +1449,15 @@
}
mutex_lock(&swrm->reslock);
- if (swrm->lpass_core_hw_vote)
- clk_prepare_enable(swrm->lpass_core_hw_vote);
+ if (swrm->lpass_core_hw_vote) {
+ ret = clk_prepare_enable(swrm->lpass_core_hw_vote);
+ if (ret < 0) {
+ dev_err(dev, "%s:lpass core hw enable failed\n",
+ __func__);
+ ret = IRQ_NONE;
+ goto exit;
+ }
+ }
swrm_clk_request(swrm, true);
mutex_unlock(&swrm->reslock);
@@ -1618,6 +1627,7 @@
swrm_clk_request(swrm, false);
if (swrm->lpass_core_hw_vote)
clk_disable_unprepare(swrm->lpass_core_hw_vote);
+exit:
mutex_unlock(&swrm->reslock);
swrm_unlock_sleep(swrm);
return ret;
diff --git a/soc/wcd-spi-ac.c b/soc/wcd-spi-ac.c
index ee7a7a9..87bdbb2 100644
--- a/soc/wcd-spi-ac.c
+++ b/soc/wcd-spi-ac.c
@@ -1,13 +1,5 @@
+// SPDX-License-Identifier: GPL-2.0-only
/* Copyright (c) 2018-2019, The Linux Foundation. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 and
- * only version 2 as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
*/
#include <linux/init.h>
diff --git a/soc/wcd_spi_ctl_v01.c b/soc/wcd_spi_ctl_v01.c
index 0e59ca3..a803fd0 100644
--- a/soc/wcd_spi_ctl_v01.c
+++ b/soc/wcd_spi_ctl_v01.c
@@ -1,14 +1,5 @@
+// SPDX-License-Identifier: GPL-2.0-only
/* Copyright (c) 2018-2019, The Linux Foundation. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 and
- * only version 2 as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
*/
#include <linux/qmi_encdec.h>
#include <soc/qcom/msm_qmi_interface.h>
diff --git a/soc/wcd_spi_ctl_v01.h b/soc/wcd_spi_ctl_v01.h
index dd9b1c3..683caa4 100644
--- a/soc/wcd_spi_ctl_v01.h
+++ b/soc/wcd_spi_ctl_v01.h
@@ -1,14 +1,5 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
/* Copyright (c) 2018-2019, The Linux Foundation. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 and
- * only version 2 as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
*/
#ifndef WCD_SPI_CTL_V01_H
#define WCD_SPI_CTL_V01_H