audio: add tdm lanemask config
authorShuai Li <shuai.li@amlogic.com>
Mon, 5 Jun 2017 00:37:30 +0000 (17:37 -0700)
committerShuai Li <shuai.li@amlogic.com>
Mon, 5 Jun 2017 03:34:04 +0000 (20:34 -0700)
PD#142470: audio: add lanesmask

Change-Id: I56d01ff4f77c90c4fb5575fc654b3459fec1ed14
Signed-off-by: Shuai Li <shuai.li@amlogic.com>
arch/arm64/boot/dts/amlogic/axg_s400.dts
sound/soc/amlogic/auge/tdm.c
sound/soc/amlogic/auge/tdm_hw.c

index f9e8fd9..ec04c8d 100644 (file)
                                system-clock-frequency = <12288000>;
                        };
                        codec {
-                               sound-dai = <&tas5707_36 &tas5707_3a>;
+                               sound-dai = <&tas5707_36 &tas5707_3a
+                                               &dummy_codec>;
                        };
                };
 
                                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 {
        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 {
index a4df898..659500e 100644 (file)
@@ -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);
-
-               if (pop_count(setting->tx_mask) > 2)
-                       swap_val = 1 << 4;
-
+               // set lanes mask acordingly
+               lane_mask = setting->lane_mask_out;
+               for (i = 0; i < 4; i++) {
+                       unsigned int ch = i * 2;
+
+                       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;
 }
index 1372dff..25f24e4 100644 (file)
@@ -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(