From 3ad6cafbff8cac0c6f1b89588bc67e3a116af7e7 Mon Sep 17 00:00:00 2001 From: Shuai Li Date: Mon, 28 Aug 2017 11:16:16 +0800 Subject: [PATCH] audio: add channel constrains for TDM PD#149888: constrains max channels number by DTS lanes and tx_mask configs. If not, FIFO will fetch the wrong data and cause abnormal behavior for I2S data. Change-Id: Ic10bb773f6360ad0dfee74c227adb279dcc47cec Signed-off-by: Shuai Li --- sound/soc/amlogic/auge/tdm.c | 21 ++++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/sound/soc/amlogic/auge/tdm.c b/sound/soc/amlogic/auge/tdm.c index 20a1f0b..c806a97 100644 --- a/sound/soc/amlogic/auge/tdm.c +++ b/sound/soc/amlogic/auge/tdm.c @@ -122,7 +122,7 @@ static irqreturn_t aml_tdmin_isr(int irq, void *devid) return IRQ_HANDLED; } -#if 0 + /* get counts of '1's in val */ static unsigned int pop_count(unsigned int val) { @@ -135,7 +135,7 @@ static unsigned int pop_count(unsigned int val) return count; } -#endif + static int snd_soc_of_get_slot_mask(struct device_node *np, const char *prop_name, unsigned int *mask) @@ -529,9 +529,10 @@ static int aml_tdm_set_lanes(struct aml_tdm *p_tdm, // set lanes mask acordingly lane_mask = setting->lane_mask_out; for (i = 0; i < 4; i++) { - if (((1 << i) & lane_mask) && lanes--) { + if (((1 << i) & lane_mask) && lanes) { aml_tdm_set_channel_mask(p_tdm->actrl, stream, p_tdm->id, i, setting->tx_mask); + lanes--; } } swap_val = 0x76543210; @@ -727,15 +728,21 @@ static int aml_dai_set_tdm_slot(struct snd_soc_dai *cpu_dai, int slots, int slot_width) { struct aml_tdm *p_tdm = snd_soc_dai_get_drvdata(cpu_dai); - - pr_info("aml_dai_set_tdm_slot, %x, %x, %d, %d\n", - tx_mask, rx_mask, slots, slot_width); + struct snd_soc_dai_driver *drv = cpu_dai->driver; + unsigned int lanes_cnt = 0; + + lanes_cnt = pop_count(p_tdm->setting.lane_mask_out); + pr_info("%s(), txmask(%#x), rxmask(%#x)\n", + __func__, tx_mask, rx_mask); + pr_info("\tslots(%d), slot_width(%d), lanes(%d)\n", + slots, slot_width, lanes_cnt); p_tdm->setting.tx_mask = tx_mask; p_tdm->setting.rx_mask = rx_mask; p_tdm->setting.slots = slots; p_tdm->setting.slot_width = slot_width; - aml_tdm_set_slot(p_tdm->actrl, slots, slot_width, p_tdm->id); + /* constrains hw channels_max by DTS configs */ + drv->playback.channels_max = slots * lanes_cnt; return 0; } -- 2.7.4