audio: auge: support av out and amp spk for sm1 [1/2]
authorXing Wang <xing.wang@amlogic.com>
Thu, 21 Mar 2019 14:52:17 +0000 (22:52 +0800)
committerJianxiong Pan <jianxiong.pan@amlogic.com>
Fri, 29 Mar 2019 12:23:06 +0000 (20:23 +0800)
PD#SWPL-6192

Problem:
no sound from av and amp spk

Solution:
1) fix tocodec for sm1
2) add no mclk control for ad82584

Verify:
ac200

Change-Id: I63f0ec94d2f5b980249ac5c9c810c8e4d8410ea3
Signed-off-by: Xing Wang <xing.wang@amlogic.com>
arch/arm/boot/dts/amlogic/sm1_s905d3_ac200.dts
arch/arm/boot/dts/amlogic/sm1_s905d3_skt.dts
arch/arm64/boot/dts/amlogic/sm1_s905d3_ac200.dts
arch/arm64/boot/dts/amlogic/sm1_s905d3_skt.dts
include/linux/amlogic/media/sound/auge_utils.h
sound/soc/amlogic/auge/audio_utils.c
sound/soc/codecs/amlogic/ad82584f.c
sound/soc/codecs/amlogic/ad82584f.h
sound/soc/codecs/amlogic/aml_codec_t9015.c

index 5ffa5aa..89f1e7e 100644 (file)
                compatible = "amlogic, aml_codec_T9015";
                reg = <0xFF632000 0x2000>;
                is_auge_used = <1>; /* meson or auge chipset used */
+               tocodec_inout = <1>;
                tdmout_index = <1>;
+               ch0_sel = <0>;
+               ch1_sel = <1>;
+
                status = "okay";
        };
 
                reg = <0x31>;
                status = "okay";
                reset_pin = <&gpio GPIOA_5 0>;
+               no_mclk;
        };
 
        bl_extern_i2c {
 
 
 }; /* end of pinctrl_periphs */
+
 &pinctrl_aobus {
        spdifout: spdifout {
                mux { /* GPIOAO_10 */
index ecfe87d..4cfed87 100644 (file)
                compatible = "amlogic, aml_codec_T9015";
                reg = <0xFF632000 0x2000>;
                is_auge_used = <1>; /* meson or auge chipset used */
+               tocodec_inout = <1>;
                tdmout_index = <1>;
+               ch0_sel = <0>;
+               ch1_sel = <1>;
+
                status = "okay";
        };
 
                reg = <0x31>;
                status = "okay";
                reset_pin = <&gpio GPIOA_5 0>;
+               no_mclk;
        };
 
        bl_extern_i2c {
 
                status = "okay";
        };
+
        earc:earc {
                compatible = "amlogic, sm1-snd-earc";
                #sound-dai-cells = <0>;
 
 
 }; /* end of pinctrl_periphs */
+
 &pinctrl_aobus {
        spdifout: spdifout {
                mux { /* GPIOAO_10 */
index 0be5aa8..825e324 100644 (file)
                compatible = "amlogic, aml_codec_T9015";
                reg = <0x0 0xFF632000 0x0 0x2000>;
                is_auge_used = <1>; /* meson or auge chipset used */
+               tocodec_inout = <1>;
                tdmout_index = <1>;
+               ch0_sel = <0>;
+               ch1_sel = <1>;
+
                status = "okay";
        };
 
                reg = <0x31>;
                status = "okay";
                reset_pin = <&gpio GPIOA_5 0>;
+               no_mclk;
        };
 
        bl_extern_i2c {
 
                status = "okay";
        };
+
        earc:earc {
                compatible = "amlogic, sm1-snd-earc";
                #sound-dai-cells = <0>;
index e522382..feb14de 100644 (file)
                compatible = "amlogic, aml_codec_T9015";
                reg = <0x0 0xFF632000 0x0 0x2000>;
                is_auge_used = <1>; /* meson or auge chipset used */
+               tocodec_inout = <1>;
                tdmout_index = <1>;
+               ch0_sel = <0>;
+               ch1_sel = <1>;
+
                status = "okay";
        };
 
                reg = <0x31>;
                status = "okay";
                reset_pin = <&gpio GPIOA_5 0>;
+               no_mclk;
        };
 
        bl_extern_i2c {
 
 
 }; /* end of pinctrl_periphs */
+
 &pinctrl_aobus {
        spdifout: spdifout {
                mux { /* GPIOAO_10 */
index 6b21c42..1e4f6fd 100644 (file)
@@ -20,4 +20,5 @@
 
 void auge_acodec_reset(void);
 void auge_toacodec_ctrl(int tdmout_id);
+void auge_toacodec_ctrl_ext(int tdmout_id, int ch0_sel, int ch1_sel);
 #endif
index aa2c827..505f994 100644 (file)
@@ -1589,6 +1589,20 @@ void auge_toacodec_ctrl(int tdmout_id)
                );
 }
 
+void auge_toacodec_ctrl_ext(int tdmout_id, int ch0_sel, int ch1_sel)
+{
+       // TODO: check skew for tl1/sm1
+       audiobus_write(EE_AUDIO_TOACODEC_CTRL0,
+               1 << 31
+               | ((tdmout_id << 2) + ch1_sel) << 20 /* data 1 */
+               | ((tdmout_id << 2) + ch0_sel) << 16 /* data 0 */
+               | tdmout_id << 12          /* lrclk */
+               | 1 << 9                   /* Bclk_cap_inv*/
+               | tdmout_id << 4           /* bclk */
+               | tdmout_id << 0           /* mclk */
+               );
+}
+
 void fratv_enable(bool enable)
 {
        /* Need reset firstlry ? */
index 88fea34..8e68ad5 100644 (file)
@@ -808,12 +808,22 @@ static int ad82584f_reg_init(struct snd_soc_codec *codec)
 }
 static int ad82584f_init(struct snd_soc_codec *codec)
 {
+       struct ad82584f_priv *ad82584f = snd_soc_codec_get_drvdata(codec);
+
        reset_ad82584f_GPIO(codec);
 
        dev_info(codec->dev, "ad82584f_init!\n");
 
        ad82584f_reg_init(codec);
 
+       /* Bclk system */
+       if (ad82584f->pdata->no_mclk)
+               snd_soc_write(codec,
+                       0x01,
+                       0x1 << 7 | /* Bclk system enable */
+                       0x1 << 0   /* 64x bclk/fs */
+                       );
+
        /*eq and drc*/
        ad82584f_set_eq_drc(codec);
 
@@ -945,6 +955,12 @@ static int ad82584f_parse_dt(
        }
        ad82584f->pdata->reset_pin = reset_pin;
 
+       ad82584f->pdata->no_mclk = of_property_read_bool(
+                       np,
+                       "no_mclk");
+       if (ad82584f->pdata->no_mclk)
+               pr_info("%s mclk is not connected.\n", __func__);
+
        return ret;
 }
 
index fd149b8..21207cc 100644 (file)
@@ -16,6 +16,7 @@
 
 struct ad82584f_platform_data {
        int reset_pin;
+       bool no_mclk;
 };
 
 #endif
index 9125aed..9085aa6 100644 (file)
@@ -46,7 +46,13 @@ struct aml_T9015_audio_priv {
 
        /* codec is used by meson or auge arch */
        bool is_auge_arch;
+       /* tocodec ctrl supports in and out data */
+       bool tocodec_inout;
+       /* attach which tdm when play */
        int tdmout_index;
+       /* channel map */
+       int ch0_sel;
+       int ch1_sel;
 };
 
 static const struct reg_default t9015_init_list[] = {
@@ -72,26 +78,20 @@ static int aml_DAC_Gain_get_enum(
        struct snd_kcontrol *kcontrol,
        struct snd_ctl_elem_value *ucontrol)
 {
-#if 0
        struct snd_soc_component *component = snd_kcontrol_chip(kcontrol);
        struct snd_soc_codec *codec = snd_soc_component_to_codec(component);
-       u32 add, val, val1, val2;
-#endif
-       /*TODO: return 0 for tmp, this wolud modified later */
-       return 0;
-#if 0
-       if (codec == NULL)
-               return -1;
+       u32 reg_addr = ADC_VOL_CTR_PGA_IN_CONFIG;
+       u32 val = snd_soc_read(codec, reg_addr);
+       u32 val1 = (val & (0x1 << DAC_GAIN_SEL_L))
+                                       >> DAC_GAIN_SEL_L;
+       u32 val2 = (val & (0x1 << DAC_GAIN_SEL_H))
+                                       >> (DAC_GAIN_SEL_H);
 
-       add = ADC_VOL_CTR_PGA_IN_CONFIG;
-       val = snd_soc_read(codec, add);
-       val1 = (val & (0x1 <<  DAC_GAIN_SEL_L)) >> DAC_GAIN_SEL_L;
-       val2 = (val & (0x1 <<  DAC_GAIN_SEL_H)) >> (DAC_GAIN_SEL_H - 1);
+       val = val1 | (val2 << 1);
 
-       val = val1 | val2;
        ucontrol->value.enumerated.item[0] = val;
+
        return 0;
- #endif
 }
 
 static int aml_DAC_Gain_set_enum(
@@ -100,8 +100,8 @@ static int aml_DAC_Gain_set_enum(
 {
        struct snd_soc_component *component = snd_kcontrol_chip(kcontrol);
        struct snd_soc_codec *codec = snd_soc_component_to_codec(component);
-       u32 add = ADC_VOL_CTR_PGA_IN_CONFIG;
-       u32 val = snd_soc_read(codec, add);
+       u32 addr = ADC_VOL_CTR_PGA_IN_CONFIG;
+       u32 val = snd_soc_read(codec, addr);
 
        if (ucontrol->value.enumerated.item[0] == 0) {
                val &= ~(0x1 << DAC_GAIN_SEL_H);
@@ -120,7 +120,7 @@ static int aml_DAC_Gain_set_enum(
                pr_info("It has risk of distortion!\n");
        }
 
-       snd_soc_write(codec, val, add);
+       snd_soc_write(codec, addr, val);
        return 0;
 }
 
@@ -392,9 +392,15 @@ static int aml_T9015_audio_probe(struct snd_soc_codec *codec)
        aml_T9015_audio_start_up(codec);
        aml_T9015_audio_reg_init(codec);
 
-       if (T9015_audio && T9015_audio->is_auge_arch)
-               auge_toacodec_ctrl(T9015_audio->tdmout_index);
-       else
+       if (T9015_audio && T9015_audio->is_auge_arch) {
+               if (T9015_audio->tocodec_inout)
+                       auge_toacodec_ctrl_ext(
+                               T9015_audio->tdmout_index,
+                               T9015_audio->ch0_sel,
+                               T9015_audio->ch1_sel);
+               else
+                       auge_toacodec_ctrl(T9015_audio->tdmout_index);
+       } else
                aml_write_cbus(AIU_ACODEC_CTRL,
                                (1 << 4)
                                |(1 << 6)
@@ -531,12 +537,27 @@ static int aml_T9015_audio_codec_probe(struct platform_device *pdev)
        T9015_audio->is_auge_arch = of_property_read_bool(
                        pdev->dev.of_node,
                        "is_auge_used");
+
+       T9015_audio->tocodec_inout = of_property_read_bool(
+                       pdev->dev.of_node,
+                       "tocodec_inout");
+
        of_property_read_u32(
                        pdev->dev.of_node,
                        "tdmout_index",
                        &T9015_audio->tdmout_index);
 
-       pr_info("aml_codec_T9015 is used by %s chipset, tdmout:%d\n",
+       of_property_read_u32(
+                       pdev->dev.of_node,
+                       "ch0_sel",
+                       &T9015_audio->ch0_sel);
+
+       of_property_read_u32(
+                       pdev->dev.of_node,
+                       "ch1_sel",
+                       &T9015_audio->ch1_sel);
+
+       pr_info("T9015 acodec used by %s, tdmout:%d\n",
                T9015_audio->is_auge_arch ? "auge" : "meson",
                T9015_audio->tdmout_index);