summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorqctecmdr <qctecmdr@localhost>2020-07-25 08:50:41 -0700
committerGerrit - the friendly Code Review server <code-review@localhost>2020-07-25 08:50:41 -0700
commit5d891ffce38a477e9c451a06231e69c2442111df (patch)
treec55b5f8ae491a901e6e8cbe478c8319c9da48e20
parente13679cd64ac944db6a3e02e8641ab75f879177e (diff)
parent0d196604a5e78eb1cceac10d58a73395843716a0 (diff)
downloadmsm-extra-5d891ffce38a477e9c451a06231e69c2442111df.tar.gz
Merge "ASoC: Add tdm dynamic configuration support"
-rw-r--r--asoc/kona.c52
1 files changed, 48 insertions, 4 deletions
diff --git a/asoc/kona.c b/asoc/kona.c
index f2bdb382..5192e3ec 100644
--- a/asoc/kona.c
+++ b/asoc/kona.c
@@ -106,6 +106,7 @@ enum {
#define TDM_MAX_SLOTS 8
#define TDM_SLOT_WIDTH_BITS 32
+#define TDM_SLOT_WIDTH_BYTES TDM_SLOT_WIDTH_BITS/8
enum {
TDM_PRI = 0,
@@ -192,6 +193,7 @@ struct msm_asoc_mach_data {
struct device_node *fsa_handle;
struct clk *lpass_audio_hw_vote;
int core_audio_vote_count;
+ u32 tdm_max_slots; /* Max TDM slots used */
};
struct tdm_port {
@@ -1989,8 +1991,11 @@ static int tdm_slot_map_put(struct snd_kcontrol *kcontrol,
int interface = ucontrol->value.integer.value[0];
int channel = ucontrol->value.integer.value[1];
unsigned int offset_val = 0;
+ unsigned int max_slot_offset = 0;
unsigned int *slot_offset = NULL;
struct tdm_dev_config *config = NULL;
+ struct msm_asoc_mach_data *pdata = NULL;
+ struct snd_soc_component *component = NULL;
if (interface < 0 || interface >= (TDM_INTERFACE_MAX * MAX_PATH)) {
pr_err("%s: incorrect interface = %d\n", __func__, interface);
@@ -2004,15 +2009,28 @@ static int tdm_slot_map_put(struct snd_kcontrol *kcontrol,
pr_debug("%s: interface = %d, channel = %d\n", __func__,
interface, channel);
+ component = snd_soc_kcontrol_component(kcontrol);
+ pdata = snd_soc_card_get_drvdata(component->card);
config = ((struct tdm_dev_config *) tdm_cfg[interface / MAX_PATH]) +
((interface % MAX_PATH) * TDM_PORT_MAX) + channel;
+ if (!config) {
+ pr_err("%s: tdm config is NULL\n", __func__);
+ return -EINVAL;
+ }
+
slot_offset = config->tdm_slot_offset;
+ if (!slot_offset) {
+ pr_err("%s: slot offset is NULL\n", __func__);
+ return -EINVAL;
+ }
+
+ max_slot_offset = TDM_SLOT_WIDTH_BYTES * (pdata->tdm_max_slots - 1);
- for (slot_index = 0; slot_index < TDM_MAX_SLOTS; slot_index++) {
+ for (slot_index = 0; slot_index < pdata->tdm_max_slots; slot_index++) {
offset_val = ucontrol->value.integer.value[MAX_PATH +
slot_index];
- /* Offset value can only be 0, 4, 8, ..28 */
- if (offset_val % 4 == 0 && offset_val <= 28)
+ /* Offset value can only be 0, 4, 8, .. */
+ if (offset_val % 4 == 0 && offset_val <= max_slot_offset)
slot_offset[slot_index] = offset_val;
pr_debug("%s: slot offset[%d] = %d\n", __func__,
slot_index, slot_offset[slot_index]);
@@ -4585,14 +4603,17 @@ static int kona_tdm_snd_hw_params(struct snd_pcm_substream *substream,
struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
int ret = 0;
int slot_width = TDM_SLOT_WIDTH_BITS;
- int channels, slots = TDM_MAX_SLOTS;
+ int channels, slots;
unsigned int slot_mask, rate, clk_freq;
unsigned int *slot_offset;
struct tdm_dev_config *config;
+ struct msm_asoc_mach_data *pdata = NULL;
unsigned int path_dir = 0, interface = 0, channel_interface = 0;
pr_debug("%s: dai id = 0x%x\n", __func__, cpu_dai->id);
+ pdata = snd_soc_card_get_drvdata(rtd->card);
+ slots = pdata->tdm_max_slots;
if (cpu_dai->id < AFE_PORT_ID_TDM_PORT_RANGE_START) {
pr_err("%s: dai id 0x%x not supported\n",
__func__, cpu_dai->id);
@@ -4616,7 +4637,16 @@ static int kona_tdm_snd_hw_params(struct snd_pcm_substream *substream,
config = ((struct tdm_dev_config *) tdm_cfg[interface]) +
(path_dir * TDM_PORT_MAX) + channel_interface;
+ if (!config) {
+ pr_err("%s: tdm config is NULL\n", __func__);
+ return -EINVAL;
+ }
+
slot_offset = config->tdm_slot_offset;
+ if (!slot_offset) {
+ pr_err("%s: slot offset is NULL\n", __func__);
+ return -EINVAL;
+ }
if (path_dir)
channels = tdm_tx_cfg[interface][channel_interface].channels;
@@ -8270,6 +8300,20 @@ static int msm_asoc_machine_probe(struct platform_device *pdev)
dev_info(&pdev->dev, "%s: Sound card %s registered\n",
__func__, card->name);
+ ret = of_property_read_u32(pdev->dev.of_node, "qcom,tdm-max-slots",
+ &pdata->tdm_max_slots);
+ if (ret) {
+ dev_err(&pdev->dev, "%s: No DT match for tdm max slots\n",
+ __func__);
+ }
+
+ if ((pdata->tdm_max_slots <= 0) || (pdata->tdm_max_slots >
+ TDM_MAX_SLOTS)) {
+ pdata->tdm_max_slots = TDM_MAX_SLOTS;
+ dev_err(&pdev->dev, "%s: Using default tdm max slot: %d\n",
+ __func__, pdata->tdm_max_slots);
+ }
+
pdata->hph_en1_gpio_p = of_parse_phandle(pdev->dev.of_node,
"qcom,hph-en1-gpio", 0);
if (!pdata->hph_en1_gpio_p) {