From 197e4f880ddac6e1fbc747b4d6e3c5ed604dc211 Mon Sep 17 00:00:00 2001 From: Shuai Li Date: Sun, 4 Jun 2017 17:37:30 -0700 Subject: [PATCH] audio: add tdm lanemask config PD#142470: audio: add lanesmask Change-Id: I56d01ff4f77c90c4fb5575fc654b3459fec1ed14 Signed-off-by: Shuai Li --- arch/arm64/boot/dts/amlogic/axg_s400.dts | 19 ++++---- sound/soc/amlogic/auge/tdm.c | 58 ++++++++++++++++-------- sound/soc/amlogic/auge/tdm_hw.c | 10 ++-- 3 files changed, 52 insertions(+), 35 deletions(-) diff --git a/arch/arm64/boot/dts/amlogic/axg_s400.dts b/arch/arm64/boot/dts/amlogic/axg_s400.dts index f9e8fd9ac096..ec04c8df060a 100644 --- a/arch/arm64/boot/dts/amlogic/axg_s400.dts +++ b/arch/arm64/boot/dts/amlogic/axg_s400.dts @@ -391,7 +391,8 @@ system-clock-frequency = <12288000>; }; codec { - sound-dai = <&tas5707_36 &tas5707_3a>; + sound-dai = <&tas5707_36 &tas5707_3a + &dummy_codec>; }; }; @@ -730,7 +731,7 @@ GIC_SPI 90 IRQ_TYPE_EDGE_RISING>; interrupt-names = "tdmin", "tdmout"; pinctrl-names = "tdm_pins"; - pinctrl-0 = <&tdmc_mclk &tdmout_c>;// &tdmin_c>; + pinctrl-0 = <&tdmc_mclk &tdmout_c &tdmin_c>; }; aml_spdif: spdif { @@ -825,18 +826,18 @@ tdmout_c:tdmout_c { mux { pins = "GPIOA_2", "GPIOA_3", "GPIOA_4", - "GPIOA_5", "GPIOA_6", "GPIOA_7"; + "GPIOA_6", "GPIOA_7"; function = "tdmc_out"; }; }; - //tdmin_c:tdmin_c { - // mux { - // pins = "GPIOA_4", "GPIOA_5", "GPIOA_6", "GPIOA_7"; - // function = "tdmc_in"; - // }; - //}; + tdmin_c:tdmin_c { + mux { + pins = "GPIOA_5"; + function = "tdmc_in"; + }; + }; spdifout: spidfout { mux { diff --git a/sound/soc/amlogic/auge/tdm.c b/sound/soc/amlogic/auge/tdm.c index a4df89830cc1..659500e0aeb8 100644 --- a/sound/soc/amlogic/auge/tdm.c +++ b/sound/soc/amlogic/auge/tdm.c @@ -119,7 +119,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) { @@ -132,7 +132,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) @@ -484,34 +484,52 @@ static int aml_tdm_set_lanes(struct aml_tdm *p_tdm, { struct pcm_setting *setting = &p_tdm->setting; unsigned int lanes, swap_val; + unsigned int lane_mask; + unsigned int set_num = 0; unsigned int i; pr_info("asoc debug: %d-%d\n", channels, setting->slots); swap_val = 0; - // assume mask channels one lane + // calc lanes by channels and slots lanes = (channels - 1) / setting->slots + 1; - - pr_info("asoc debug: lanes_ddr = %d\n", lanes); - - // set channels swap - for (i = 0; i < channels; i++) - swap_val |= i << (i * 4); - aml_tdm_set_lane_channel_swap(p_tdm->actrl, - stream, p_tdm->id, swap_val); + if (lanes > 4) { + pr_err("lanes setting error\n"); + return -EINVAL; + } if (stream == SNDRV_PCM_STREAM_PLAYBACK) { - aml_tdm_set_channel_mask(p_tdm->actrl, - stream, p_tdm->id, lanes, setting->tx_mask); + // set lanes mask acordingly + lane_mask = setting->lane_mask_out; + for (i = 0; i < 4; i++) { + unsigned int ch = i * 2; - if (pop_count(setting->tx_mask) > 2) - swap_val = 1 << 4; + if (i < lanes) + aml_tdm_set_channel_mask(p_tdm->actrl, + stream, p_tdm->id, i, setting->tx_mask); + if ((1 << i) & lane_mask) { + // each lane only L/R swap + swap_val |= set_num++ << (ch++ * 4); + swap_val |= set_num++ << (ch * 4); + } + } aml_tdm_set_lane_channel_swap(p_tdm->actrl, stream, p_tdm->id, swap_val); } else { - aml_tdm_set_channel_mask(p_tdm->actrl, - stream, p_tdm->id, lanes, setting->rx_mask); + lane_mask = setting->lane_mask_in; + + for (i = 0; i < 4; i++) { + if (i < lanes) + aml_tdm_set_channel_mask(p_tdm->actrl, + stream, p_tdm->id, i, setting->rx_mask); + if ((1 << i) & lane_mask) { + // each lane only L/R masked + pr_info("tdmin set lane %d\n", i); + swap_val |= (i * 2) << (set_num++ * 4); + swap_val |= (i * 2 + 1) << (set_num++ * 4); + } + } aml_tdm_set_lane_channel_swap(p_tdm->actrl, stream, p_tdm->id, swap_val); @@ -560,9 +578,11 @@ static int aml_dai_tdm_hw_free(struct snd_pcm_substream *substream, struct snd_soc_dai *cpu_dai) { struct aml_tdm *p_tdm = snd_soc_dai_get_drvdata(cpu_dai); + int i; - aml_tdm_set_channel_mask(p_tdm->actrl, - substream->stream, p_tdm->id, 4, 0); + for (i = 0; i < 4; i++) + aml_tdm_set_channel_mask(p_tdm->actrl, + substream->stream, p_tdm->id, i, 0); return 0; } diff --git a/sound/soc/amlogic/auge/tdm_hw.c b/sound/soc/amlogic/auge/tdm_hw.c index 1372dffbc08c..25f24e4d3bb3 100644 --- a/sound/soc/amlogic/auge/tdm_hw.c +++ b/sound/soc/amlogic/auge/tdm_hw.c @@ -164,7 +164,7 @@ void aml_tdm_set_format( case SND_SOC_DAIFMT_I2S: if (master_mode) { bclkout_skew = 1; - bclkin_skew = 5; + bclkin_skew = 3; } else { bclkout_skew = 2; bclkin_skew = 3; @@ -273,10 +273,9 @@ void aml_tdm_set_slot( void aml_tdm_set_channel_mask( struct aml_audio_controller *actrl, - int stream, int index, int lanes, int mask) + int stream, int index, int lane, int mask) { unsigned int offset, reg; - int i; if (stream == SNDRV_PCM_STREAM_PLAYBACK) { offset = EE_AUDIO_TDMOUT_B_MASK0 - EE_AUDIO_TDMOUT_A_MASK0; @@ -286,10 +285,7 @@ void aml_tdm_set_channel_mask( reg = EE_AUDIO_TDMIN_A_MASK0 + offset * index; } - /* mask 0~3 */ - for (i = 0; i < lanes; i++) - aml_audiobus_write(actrl, reg + i, mask); - + aml_audiobus_write(actrl, reg + lane, mask); } void aml_tdm_set_lane_channel_swap(