Merge "ASoC: Update routing driver for FFV and AFE Loopback"
diff --git a/asoc/codecs/sdm660_cdc/msm-digital-cdc.c b/asoc/codecs/sdm660_cdc/msm-digital-cdc.c
index f1f1ed4..8519e67 100644
--- a/asoc/codecs/sdm660_cdc/msm-digital-cdc.c
+++ b/asoc/codecs/sdm660_cdc/msm-digital-cdc.c
@@ -1391,7 +1391,21 @@
atomic_set(&msm_dig_cdc->on_demand_list[ON_DEMAND_DIGITAL].ref, 0);
registered_digcodec = codec;
+ if (msm_dig_cdc->no_analog_codec) {
+ msm_dig_cdc->fw_data = devm_kzalloc(codec->dev,
+ sizeof(*(msm_dig_cdc->fw_data)),
+ GFP_KERNEL);
+ if (!msm_dig_cdc->fw_data)
+ return -ENOMEM;
+ ret = wcd_cal_create_hwdep(msm_dig_cdc->fw_data,
+ WCD9XXX_CODEC_HWDEP_NODE, codec);
+ if (ret < 0) {
+ dev_err(codec->dev, "%s hwdep failed %d\n", __func__,
+ ret);
+ return ret;
+ }
+ }
snd_soc_dapm_ignore_suspend(dapm, "AIF1 Playback");
snd_soc_dapm_ignore_suspend(dapm, "AIF1 Capture");
snd_soc_dapm_ignore_suspend(dapm, "ADC1_IN");
@@ -2469,7 +2483,6 @@
u32 dig_cdc_addr;
struct msm_dig_priv *msm_dig_cdc;
struct dig_ctrl_platform_data *pdata = NULL;
- bool no_analog_codec = false;
int adsp_state;
adsp_state = apr_get_subsys_state();
@@ -2491,10 +2504,11 @@
return -EINVAL;
if (pdev->dev.of_node)
- no_analog_codec = of_property_read_bool(pdev->dev.of_node,
+ msm_dig_cdc->no_analog_codec = of_property_read_bool(
+ pdev->dev.of_node,
"qcom,no-analog-codec");
- if (no_analog_codec) {
+ if (msm_dig_cdc->no_analog_codec) {
dev_dbg(&pdev->dev, "%s:Platform data from device tree\n",
__func__);
if (msm_digital_cdc_populate_dt_pdata(&pdev->dev,
@@ -2549,7 +2563,7 @@
__func__, dig_cdc_addr);
return ret;
err_supplies:
- if (no_analog_codec)
+ if (msm_dig_cdc->no_analog_codec)
msm_digital_cdc_disable_supplies(msm_dig_cdc);
rtn:
return ret;
diff --git a/asoc/codecs/sdm660_cdc/msm-digital-cdc.h b/asoc/codecs/sdm660_cdc/msm-digital-cdc.h
index a841a09..f230cac 100644
--- a/asoc/codecs/sdm660_cdc/msm-digital-cdc.h
+++ b/asoc/codecs/sdm660_cdc/msm-digital-cdc.h
@@ -73,6 +73,9 @@
s32 dmic_3_4_clk_cnt;
bool dec_active[NUM_DECIMATORS];
int version;
+ /* cal info for codec */
+ struct fw_info *fw_data;
+ bool no_analog_codec;
/* Entry for version info */
struct snd_info_entry *entry;
struct snd_info_entry *version_entry;
diff --git a/asoc/codecs/wcd934x/wcd934x.c b/asoc/codecs/wcd934x/wcd934x.c
index 7ff8179..8a70ea3 100644
--- a/asoc/codecs/wcd934x/wcd934x.c
+++ b/asoc/codecs/wcd934x/wcd934x.c
@@ -8911,6 +8911,8 @@
static void tavil_codec_power_gate_digital_core(struct tavil_priv *tavil)
{
+ if (!tavil)
+ return;
mutex_lock(&tavil->power_lock);
dev_dbg(tavil->dev, "%s: Entering power gating function, %d\n",
__func__, tavil->power_active_ref);
diff --git a/asoc/msm-compress-q6-v2.c b/asoc/msm-compress-q6-v2.c
index f03433c..c98c1cf 100644
--- a/asoc/msm-compress-q6-v2.c
+++ b/asoc/msm-compress-q6-v2.c
@@ -540,7 +540,7 @@
__func__, ret);
return ret;
}
- prtd->bytes_read += buffer_length;
+ prtd->bytes_read += buffer_length + prtd->ts_header_offset;
prtd->bytes_read_offset += buffer_length + prtd->ts_header_offset;
if (prtd->bytes_read_offset >= prtd->buffer_size)
prtd->bytes_read_offset -= prtd->buffer_size;
diff --git a/asoc/msm-pcm-routing-v2.c b/asoc/msm-pcm-routing-v2.c
index 1c16ac9..826981d 100644
--- a/asoc/msm-pcm-routing-v2.c
+++ b/asoc/msm-pcm-routing-v2.c
@@ -2469,13 +2469,13 @@
lsm_port = ADM_LSM_PORT_ID;
break;
case 10:
- lsm_port = AFE_PORT_ID_PRIMARY_TDM_TX_2;
+ lsm_port = AFE_PORT_ID_INT3_MI2S_TX;
break;
case 11:
- lsm_port = AFE_PORT_ID_PRIMARY_TDM_TX_3;
+ lsm_port = AFE_PORT_ID_PRIMARY_TDM_TX_2;
break;
case 12:
- lsm_port = AFE_PORT_ID_INT3_MI2S_TX;
+ lsm_port = AFE_PORT_ID_PRIMARY_TDM_TX_3;
break;
default:
pr_err("Default lsm port");
@@ -12315,6 +12315,9 @@
} else if (!strcmp(kcontrol->id.name + strlen(prefix),
"INT3_MI2S")) {
*port_id = AFE_PORT_ID_INT3_MI2S_TX;
+ } else if (!strcmp(kcontrol->id.name + strlen(prefix),
+ "PRIMARY_TDM")) {
+ *port_id = AFE_PORT_ID_PRIMARY_TDM_TX;
} else {
pr_err("%s: mixer ctl name=%s, could not derive valid port id\n",
__func__, kcontrol->id.name);
@@ -12549,6 +12552,21 @@
.info = msm_source_tracking_info,
.get = msm_audio_source_tracking_get,
},
+ {
+ .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
+ .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+ .name = "Sound Focus Audio Tx PRIMARY_TDM",
+ .info = msm_sound_focus_info,
+ .get = msm_audio_sound_focus_get,
+ .put = msm_audio_sound_focus_put,
+ },
+ {
+ .access = SNDRV_CTL_ELEM_ACCESS_READ,
+ .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+ .name = "Source Tracking Audio Tx PRIMARY_TDM",
+ .info = msm_source_tracking_info,
+ .get = msm_audio_source_tracking_get,
+ },
};
static int spkr_prot_put_vi_lch_port(struct snd_kcontrol *kcontrol,
diff --git a/asoc/sdm660-external.c b/asoc/sdm660-external.c
index 8ff98ed..91accff 100644
--- a/asoc/sdm660-external.c
+++ b/asoc/sdm660-external.c
@@ -124,7 +124,12 @@
static char const *bt_sample_rate_text[] = {"KHZ_8", "KHZ_16",
"KHZ_44P1", "KHZ_48",
"KHZ_88P2", "KHZ_96"};
-
+static char const *bt_sample_rate_rx_text[] = {"KHZ_8", "KHZ_16",
+ "KHZ_44P1", "KHZ_48",
+ "KHZ_88P2", "KHZ_96"};
+static char const *bt_sample_rate_tx_text[] = {"KHZ_8", "KHZ_16",
+ "KHZ_44P1", "KHZ_48",
+ "KHZ_88P2", "KHZ_96"};
static SOC_ENUM_SINGLE_EXT_DECL(spk_func_en, spk_function_text);
static SOC_ENUM_SINGLE_EXT_DECL(slim_0_rx_chs, slim_rx_ch_text);
static SOC_ENUM_SINGLE_EXT_DECL(slim_2_rx_chs, slim_rx_ch_text);
@@ -143,6 +148,8 @@
static SOC_ENUM_SINGLE_EXT_DECL(slim_5_rx_sample_rate, slim_sample_rate_text);
static SOC_ENUM_SINGLE_EXT_DECL(slim_6_rx_sample_rate, slim_sample_rate_text);
static SOC_ENUM_SINGLE_EXT_DECL(bt_sample_rate, bt_sample_rate_text);
+static SOC_ENUM_SINGLE_EXT_DECL(bt_sample_rate_rx, bt_sample_rate_rx_text);
+static SOC_ENUM_SINGLE_EXT_DECL(bt_sample_rate_tx, bt_sample_rate_tx_text);
static int slim_get_sample_rate_val(int sample_rate)
{
@@ -379,6 +386,130 @@
return 0;
}
+static int msm_bt_sample_rate_rx_get(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ switch (slim_rx_cfg[SLIM_RX_7].sample_rate) {
+ case SAMPLING_RATE_96KHZ:
+ ucontrol->value.integer.value[0] = 5;
+ break;
+ case SAMPLING_RATE_88P2KHZ:
+ ucontrol->value.integer.value[0] = 4;
+ break;
+ case SAMPLING_RATE_48KHZ:
+ ucontrol->value.integer.value[0] = 3;
+ break;
+ case SAMPLING_RATE_44P1KHZ:
+ ucontrol->value.integer.value[0] = 2;
+ break;
+ case SAMPLING_RATE_16KHZ:
+ ucontrol->value.integer.value[0] = 1;
+ break;
+ case SAMPLING_RATE_8KHZ:
+ default:
+ ucontrol->value.integer.value[0] = 0;
+ break;
+ }
+ pr_debug("%s: sample rate = %d", __func__,
+ slim_rx_cfg[SLIM_RX_7].sample_rate);
+
+ return 0;
+}
+
+static int msm_bt_sample_rate_rx_put(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ switch (ucontrol->value.integer.value[0]) {
+ case 1:
+ slim_rx_cfg[SLIM_RX_7].sample_rate = SAMPLING_RATE_16KHZ;
+ break;
+ case 2:
+ slim_rx_cfg[SLIM_RX_7].sample_rate = SAMPLING_RATE_44P1KHZ;
+ break;
+ case 3:
+ slim_rx_cfg[SLIM_RX_7].sample_rate = SAMPLING_RATE_48KHZ;
+ break;
+ case 4:
+ slim_rx_cfg[SLIM_RX_7].sample_rate = SAMPLING_RATE_88P2KHZ;
+ break;
+ case 5:
+ slim_rx_cfg[SLIM_RX_7].sample_rate = SAMPLING_RATE_96KHZ;
+ break;
+ case 0:
+ default:
+ slim_rx_cfg[SLIM_RX_7].sample_rate = SAMPLING_RATE_8KHZ;
+ break;
+ }
+ pr_debug("%s: sample rates: slim7_rx = %d, value = %d\n",
+ __func__,
+ slim_rx_cfg[SLIM_RX_7].sample_rate,
+ ucontrol->value.enumerated.item[0]);
+
+ return 0;
+}
+
+static int msm_bt_sample_rate_tx_get(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ switch (slim_tx_cfg[SLIM_TX_7].sample_rate) {
+ case SAMPLING_RATE_96KHZ:
+ ucontrol->value.integer.value[0] = 5;
+ break;
+ case SAMPLING_RATE_88P2KHZ:
+ ucontrol->value.integer.value[0] = 4;
+ break;
+ case SAMPLING_RATE_48KHZ:
+ ucontrol->value.integer.value[0] = 3;
+ break;
+ case SAMPLING_RATE_44P1KHZ:
+ ucontrol->value.integer.value[0] = 2;
+ break;
+ case SAMPLING_RATE_16KHZ:
+ ucontrol->value.integer.value[0] = 1;
+ break;
+ case SAMPLING_RATE_8KHZ:
+ default:
+ ucontrol->value.integer.value[0] = 0;
+ break;
+ }
+ pr_debug("%s: sample rate = %d", __func__,
+ slim_tx_cfg[SLIM_TX_7].sample_rate);
+
+ return 0;
+}
+
+static int msm_bt_sample_rate_tx_put(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ switch (ucontrol->value.integer.value[0]) {
+ case 1:
+ slim_tx_cfg[SLIM_TX_7].sample_rate = SAMPLING_RATE_16KHZ;
+ break;
+ case 2:
+ slim_tx_cfg[SLIM_TX_7].sample_rate = SAMPLING_RATE_44P1KHZ;
+ break;
+ case 3:
+ slim_tx_cfg[SLIM_TX_7].sample_rate = SAMPLING_RATE_48KHZ;
+ break;
+ case 4:
+ slim_tx_cfg[SLIM_TX_7].sample_rate = SAMPLING_RATE_88P2KHZ;
+ break;
+ case 5:
+ slim_tx_cfg[SLIM_TX_7].sample_rate = SAMPLING_RATE_96KHZ;
+ break;
+ case 0:
+ default:
+ slim_tx_cfg[SLIM_TX_7].sample_rate = SAMPLING_RATE_8KHZ;
+ break;
+ }
+ pr_debug("%s: sample rates: slim7_tx = %d, value = %d\n",
+ __func__,
+ slim_tx_cfg[SLIM_TX_7].sample_rate,
+ ucontrol->value.enumerated.item[0]);
+
+ return 0;
+}
+
static int slim_rx_sample_rate_get(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
{
@@ -750,6 +881,12 @@
SOC_ENUM_EXT("BT SampleRate", bt_sample_rate,
msm_bt_sample_rate_get,
msm_bt_sample_rate_put),
+ SOC_ENUM_EXT("BT SampleRate RX", bt_sample_rate_rx,
+ msm_bt_sample_rate_rx_get,
+ msm_bt_sample_rate_rx_put),
+ SOC_ENUM_EXT("BT SampleRate TX", bt_sample_rate_tx,
+ msm_bt_sample_rate_tx_get,
+ msm_bt_sample_rate_tx_put),
};
static int msm_slim_get_ch_from_beid(int32_t id)
diff --git a/dsp/q6lsm.c b/dsp/q6lsm.c
index d03f24c..a702661 100644
--- a/dsp/q6lsm.c
+++ b/dsp/q6lsm.c
@@ -78,6 +78,7 @@
uint32_t param_id;
};
+static DEFINE_MUTEX(session_lock);
static struct lsm_common lsm_common;
/*
* mmap_handle_p can point either client->sound_model.mem_map_handle or
@@ -130,6 +131,24 @@
}
}
+static int q6lsm_get_session_id_from_lsm_client(struct lsm_client *client)
+{
+ int n;
+
+ for (n = LSM_MIN_SESSION_ID; n <= LSM_MAX_SESSION_ID; n++) {
+ if (lsm_session[n] == client)
+ return n;
+ }
+ pr_err("%s: cannot find matching lsm client. client = %pa\n",
+ __func__, client);
+ return LSM_INVALID_SESSION_ID;
+}
+
+static bool q6lsm_is_valid_lsm_client(struct lsm_client *client)
+{
+ return q6lsm_get_session_id_from_lsm_client(client) ? 1 : 0;
+}
+
static int q6lsm_callback(struct apr_client_data *data, void *priv)
{
struct lsm_client *client = (struct lsm_client *)priv;
@@ -148,6 +167,13 @@
__func__, data->opcode, data->reset_event,
data->reset_proc);
+ mutex_lock(&session_lock);
+ if (!client || !q6lsm_is_valid_lsm_client(client)) {
+ pr_err("%s: client already freed/invalid, return\n",
+ __func__);
+ mutex_unlock(&session_lock);
+ return 0;
+ }
apr_reset(client->apr);
client->apr = NULL;
atomic_set(&client->cmd_state, CMD_STATE_CLEARED);
@@ -157,6 +183,7 @@
mutex_lock(&lsm_common.cal_data[LSM_CUSTOM_TOP_IDX]->lock);
lsm_common.set_custom_topology = 1;
mutex_unlock(&lsm_common.cal_data[LSM_CUSTOM_TOP_IDX]->lock);
+ mutex_unlock(&session_lock);
return 0;
}
@@ -369,6 +396,7 @@
pr_err("%s: Invalid Session %d\n", __func__, client->session);
return;
}
+ mutex_lock(&session_lock);
apr_deregister(client->apr);
client->mmap_apr = NULL;
q6lsm_session_free(client);
@@ -376,6 +404,7 @@
mutex_destroy(&client->cmd_lock);
kfree(client);
client = NULL;
+ mutex_unlock(&session_lock);
}
EXPORT_SYMBOL(q6lsm_client_free);