diff --git a/arch/arm64/boot/dts/amlogic/g12a_s905d2_skt.dts b/arch/arm64/boot/dts/amlogic/g12a_s905d2_skt.dts index bace141d46c9..d18b67a9d2b9 100644 --- a/arch/arm64/boot/dts/amlogic/g12a_s905d2_skt.dts +++ b/arch/arm64/boot/dts/amlogic/g12a_s905d2_skt.dts @@ -571,12 +571,13 @@ sound-dai = <&dummy_codec>; }; }; + /* spdif_b to hdmi, only playback */ aml-audio-card,dai-link@5 { mclk-fs = <128>; /* suffix-name, sync with android audio hal * what's the dai link used for */ - suffix-name = "alsaPORT-hdmi"; + suffix-name = "alsaPORT-spdifb2hdmi"; cpu { sound-dai = <&aml_spdif_b>; system-clock-frequency = <6144000>; @@ -585,6 +586,33 @@ sound-dai = <&dummy_codec>; }; }; + /* + * dai link for i2s to hdmix, + * Notice to select a tdm lane not used by hw + */ + aml-audio-card,dai-link@6 { + format = "i2s"; + mclk-fs = <256>; + //continuous-clock; + //bitclock-inversion; + //frame-inversion; + bitclock-master = <&aml_i2s2hdmi>; + frame-master = <&aml_i2s2hdmi>; + /* suffix-name, sync with android audio hal + * what's the dai link used for + */ + suffix-name = "alsaPORT-i2s2hdmi"; + cpu { + sound-dai = <&aml_i2s2hdmi>; + dai-tdm-slot-tx-mask = <1 1>; + dai-tdm-slot-num = <2>; + dai-tdm-slot-width = <32>; + system-clock-frequency = <12288000>; + }; + codec { + sound-dai = <&dummy_codec>; + }; + }; }; audiolocker: locker { compatible = "amlogic, audiolocker"; @@ -775,6 +803,21 @@ pinctrl-0 = <&tdmc_mclk &tdmout_c &tdmin_c>; }; + /* copy a useless tdm to output for hdmi, no pinmux */ + aml_i2s2hdmi: i2s2hdmi { + compatible = "amlogic, g12a-snd-tdmc"; + #sound-dai-cells = <0>; + dai-tdm-lane-slot-mask-out = <1 1 1 1>; + dai-tdm-clk-sel = <2>; + clocks = <&clkaudio CLKID_AUDIO_MCLK_C + &clkc CLKID_MPLL2>; + clock-names = "mclk", "clk_srcpll"; + + i2s2hdmi = <1>; + + status = "okay"; + }; + aml_spdif: spdif { compatible = "amlogic, g12a-snd-spdif-a"; #sound-dai-cells = <0>; diff --git a/arch/arm64/boot/dts/amlogic/g12a_s905d2_u200.dts b/arch/arm64/boot/dts/amlogic/g12a_s905d2_u200.dts index ae6fc6235dc1..4e97b28a305d 100644 --- a/arch/arm64/boot/dts/amlogic/g12a_s905d2_u200.dts +++ b/arch/arm64/boot/dts/amlogic/g12a_s905d2_u200.dts @@ -539,7 +539,7 @@ system-clock-frequency = <12288000>; }; codec { - sound-dai = <&dummy_codec &dummy_codec>; + sound-dai = <&tlv320adc3101_32 &dummy_codec>; }; }; @@ -571,12 +571,13 @@ sound-dai = <&dummy_codec>; }; }; + /* spdif_b to hdmi, only playback */ aml-audio-card,dai-link@5 { mclk-fs = <128>; /* suffix-name, sync with android audio hal * what's the dai link used for */ - suffix-name = "alsaPORT-hdmi"; + suffix-name = "alsaPORT-spdifb2hdmi"; cpu { sound-dai = <&aml_spdif_b>; system-clock-frequency = <6144000>; @@ -585,6 +586,33 @@ sound-dai = <&dummy_codec>; }; }; + /* + * dai link for i2s to hdmix, + * Notice to select a tdm lane not used by hw + */ + aml-audio-card,dai-link@6 { + format = "i2s"; + mclk-fs = <256>; + //continuous-clock; + //bitclock-inversion; + //frame-inversion; + bitclock-master = <&aml_i2s2hdmi>; + frame-master = <&aml_i2s2hdmi>; + /* suffix-name, sync with android audio hal + * what's the dai link used for + */ + suffix-name = "alsaPORT-i2s2hdmi"; + cpu { + sound-dai = <&aml_i2s2hdmi>; + dai-tdm-slot-tx-mask = <1 1>; + dai-tdm-slot-num = <2>; + dai-tdm-slot-width = <32>; + system-clock-frequency = <12288000>; + }; + codec { + sound-dai = <&dummy_codec>; + }; + }; }; audiolocker: locker { compatible = "amlogic, audiolocker"; @@ -708,6 +736,14 @@ reset_pin = <&gpio GPIOA_5 0>; }; + tlv320adc3101_32: tlv320adc3101_32@32 { + compatible = "ti,tlv320adc3101"; + #sound-dai-cells = <0>; + reg = <0x19>; + differential_pair = <1>; + status = "okay"; + }; + tas5707_36: tas5707_36@36 { compatible = "ti,tas5707"; #sound-dai-cells = <0>; @@ -763,10 +799,10 @@ aml_tdmc: tdmc { compatible = "amlogic, g12a-snd-tdmc"; #sound-dai-cells = <0>; - dai-tdm-lane-slot-mask-in = <0 1 0 0>; + dai-tdm-lane-slot-mask-in = <1 0 0 0>; #dai-tdm-lane-slot-mask-out = <1 0 1 1>; #dai-tdm-lane-oe-slot-mask-in = <0 0 0 0>; - dai-tdm-lane-oe-slot-mask-out = <1 0 0 0>; + #dai-tdm-lane-oe-slot-mask-out = <1 0 0 0>; dai-tdm-clk-sel = <2>; clocks = <&clkaudio CLKID_AUDIO_MCLK_C &clkc CLKID_MPLL2>; @@ -775,6 +811,21 @@ pinctrl-0 = <&tdmc_mclk &tdmout_c &tdmin_c>; }; + /* copy a useless tdm to output for hdmi, no pinmux */ + aml_i2s2hdmi: i2s2hdmi { + compatible = "amlogic, g12a-snd-tdmc"; + #sound-dai-cells = <0>; + dai-tdm-lane-slot-mask-out = <1 1 1 1>; + dai-tdm-clk-sel = <2>; + clocks = <&clkaudio CLKID_AUDIO_MCLK_C + &clkc CLKID_MPLL2>; + clock-names = "mclk", "clk_srcpll"; + + i2s2hdmi = <1>; + + status = "okay"; + }; + aml_spdif: spdif { compatible = "amlogic, g12a-snd-spdif-a"; #sound-dai-cells = <0>; @@ -951,7 +1002,7 @@ }; tdmout_c:tdmout_c { - mux { /* GPIOA_12, GPIOA_13, GPIOA_10, GPIOA_8, GPIOA_7*/ + mux { /* GPIOA_12, GPIOA_13, GPIOA_8, GPIOA_7*/ groups = "tdmc_sclk_a", "tdmc_fs_a", "tdmc_dout0_a" @@ -963,8 +1014,8 @@ }; tdmin_c:tdmin_c { - mux { /* GPIOA_9 */ - groups = "tdmc_din1_a"; + mux { /* GPIOA_10 */ + groups = "tdmc_din0_a"; function = "tdmc_in"; }; }; diff --git a/arch/arm64/boot/dts/amlogic/g12a_s905x2_u211.dts b/arch/arm64/boot/dts/amlogic/g12a_s905x2_u211.dts index 08b006e9af12..4ed56e21ac49 100644 --- a/arch/arm64/boot/dts/amlogic/g12a_s905x2_u211.dts +++ b/arch/arm64/boot/dts/amlogic/g12a_s905x2_u211.dts @@ -571,12 +571,13 @@ sound-dai = <&dummy_codec>; }; }; + /* spdif_b to hdmi, only playback */ aml-audio-card,dai-link@5 { mclk-fs = <128>; /* suffix-name, sync with android audio hal * what's the dai link used for */ - suffix-name = "alsaPORT-hdmi"; + suffix-name = "alsaPORT-spdifb2hdmi"; cpu { sound-dai = <&aml_spdif_b>; system-clock-frequency = <6144000>; @@ -585,6 +586,33 @@ sound-dai = <&dummy_codec>; }; }; + /* + * dai link for i2s to hdmix, + * Notice to select a tdm lane not used by hw + */ + aml-audio-card,dai-link@6 { + format = "i2s"; + mclk-fs = <256>; + //continuous-clock; + //bitclock-inversion; + //frame-inversion; + bitclock-master = <&aml_i2s2hdmi>; + frame-master = <&aml_i2s2hdmi>; + /* suffix-name, sync with android audio hal + * what's the dai link used for + */ + suffix-name = "alsaPORT-i2s2hdmi"; + cpu { + sound-dai = <&aml_i2s2hdmi>; + dai-tdm-slot-tx-mask = <1 1>; + dai-tdm-slot-num = <2>; + dai-tdm-slot-width = <32>; + system-clock-frequency = <12288000>; + }; + codec { + sound-dai = <&dummy_codec>; + }; + }; }; audiolocker: locker { compatible = "amlogic, audiolocker"; @@ -775,6 +803,21 @@ pinctrl-0 = <&tdmc_mclk &tdmout_c &tdmin_c>; }; + /* copy a useless tdm to output for hdmi, no pinmux */ + aml_i2s2hdmi: i2s2hdmi { + compatible = "amlogic, g12a-snd-tdmc"; + #sound-dai-cells = <0>; + dai-tdm-lane-slot-mask-out = <1 1 1 1>; + dai-tdm-clk-sel = <2>; + clocks = <&clkaudio CLKID_AUDIO_MCLK_C + &clkc CLKID_MPLL2>; + clock-names = "mclk", "clk_srcpll"; + + i2s2hdmi = <1>; + + status = "okay"; + }; + aml_spdif: spdif { compatible = "amlogic, g12a-snd-spdif-a"; #sound-dai-cells = <0>; diff --git a/arch/arm64/boot/dts/amlogic/g12a_s905y2_u221.dts b/arch/arm64/boot/dts/amlogic/g12a_s905y2_u221.dts index 4e87719eff7a..797ca3060588 100644 --- a/arch/arm64/boot/dts/amlogic/g12a_s905y2_u221.dts +++ b/arch/arm64/boot/dts/amlogic/g12a_s905y2_u221.dts @@ -571,12 +571,13 @@ sound-dai = <&dummy_codec>; }; }; + /* spdif_b to hdmi, only playback */ aml-audio-card,dai-link@5 { mclk-fs = <128>; /* suffix-name, sync with android audio hal * what's the dai link used for */ - suffix-name = "alsaPORT-hdmi"; + suffix-name = "alsaPORT-spdifb2hdmi"; cpu { sound-dai = <&aml_spdif_b>; system-clock-frequency = <6144000>; @@ -585,6 +586,33 @@ sound-dai = <&dummy_codec>; }; }; + /* + * dai link for i2s to hdmix, + * Notice to select a tdm lane not used by hw + */ + aml-audio-card,dai-link@6 { + format = "i2s"; + mclk-fs = <256>; + //continuous-clock; + //bitclock-inversion; + //frame-inversion; + bitclock-master = <&aml_i2s2hdmi>; + frame-master = <&aml_i2s2hdmi>; + /* suffix-name, sync with android audio hal + * what's the dai link used for + */ + suffix-name = "alsaPORT-i2s2hdmi"; + cpu { + sound-dai = <&aml_i2s2hdmi>; + dai-tdm-slot-tx-mask = <1 1>; + dai-tdm-slot-num = <2>; + dai-tdm-slot-width = <32>; + system-clock-frequency = <12288000>; + }; + codec { + sound-dai = <&dummy_codec>; + }; + }; }; audiolocker: locker { compatible = "amlogic, audiolocker"; @@ -775,6 +803,21 @@ pinctrl-0 = <&tdmc_mclk &tdmout_c &tdmin_c>; }; + /* copy a useless tdm to output for hdmi, no pinmux */ + aml_i2s2hdmi: i2s2hdmi { + compatible = "amlogic, g12a-snd-tdmc"; + #sound-dai-cells = <0>; + dai-tdm-lane-slot-mask-out = <1 1 1 1>; + dai-tdm-clk-sel = <2>; + clocks = <&clkaudio CLKID_AUDIO_MCLK_C + &clkc CLKID_MPLL2>; + clock-names = "mclk", "clk_srcpll"; + + i2s2hdmi = <1>; + + status = "okay"; + }; + aml_spdif: spdif { compatible = "amlogic, g12a-snd-spdif-a"; #sound-dai-cells = <0>; diff --git a/sound/soc/amlogic/auge/audio_utils.c b/sound/soc/amlogic/auge/audio_utils.c index d261072fc8fa..bc723cc93478 100644 --- a/sound/soc/amlogic/auge/audio_utils.c +++ b/sound/soc/amlogic/auge/audio_utils.c @@ -163,10 +163,11 @@ static int snd_int_get(struct snd_kcontrol *kcontrol, val = audiobus_read(reg); ucontrol->value.integer.value[0] = val; - pr_info("%s:reg:0x%x, val:0x%x\n", - __func__, - reg, - val); + /* pr_info("%s:reg:0x%x, val:0x%x\n", + * __func__, + * reg, + * val); + */ return 0; } @@ -177,10 +178,11 @@ static int snd_int_set(struct snd_kcontrol *kcontrol, int val = (int)ucontrol->value.integer.value[0]; unsigned int reg = kcontrol->private_value; - pr_info("%s:reg:0x%x, val:0x%x\n", - __func__, - reg, - val); + /* pr_info("%s:reg:0x%x, val:0x%x\n", + * __func__, + * reg, + * val); + */ audiobus_write(reg, val); @@ -220,11 +222,12 @@ static int snd_byte_get(struct snd_kcontrol *kcontrol, ucontrol->value.integer.value[0] = val; - pr_info("%s:reg:0x%x, mask:0x%x, mask val:0x%x\n", - __func__, - einfo->reg, - einfo->mask, - val); + /* pr_info("%s:reg:0x%x, mask:0x%x, mask val:0x%x\n", + * __func__, + * einfo->reg, + * einfo->mask, + * val); + */ return 0; } @@ -240,11 +243,12 @@ static int snd_byte_set(struct snd_kcontrol *kcontrol, if (val > 255) val = 255; - pr_info("%s:reg:0x%x, mask:0x%x, mask val:0x%x\n", - __func__, - einfo->reg, - einfo->mask, - val); + /* pr_info("%s:reg:0x%x, mask:0x%x, mask val:0x%x\n", + * __func__, + * einfo->reg, + * einfo->mask, + * val); + */ audiobus_update_bits( einfo->reg, @@ -284,17 +288,18 @@ static int snd_enum_get(struct snd_kcontrol *kcontrol, int val; struct snd_elem_info *einfo = (void *)kcontrol->private_value; - pr_info("%s:reg:0x%x, mask:0x%x", - __func__, - einfo->reg, - einfo->mask); + /* pr_info("%s:reg:0x%x, mask:0x%x", + * __func__, + * einfo->reg, + * einfo->mask); + */ val = audiobus_read(einfo->reg); val >>= einfo->shift; val &= einfo->mask; ucontrol->value.integer.value[0] = val; - pr_info("\t val:0x%x\n", val); + /* pr_info("\t val:0x%x\n", val); */ return 0; } @@ -305,12 +310,12 @@ static int snd_enum_set(struct snd_kcontrol *kcontrol, struct snd_elem_info *einfo = (void *)kcontrol->private_value; int val = (int)ucontrol->value.integer.value[0]; - pr_info("%s:reg:0x%x, swap mask:0x%x, val:0x%x\n", - __func__, - einfo->reg, - einfo->mask, - val); - + /* pr_info("%s:reg:0x%x, swap mask:0x%x, val:0x%x\n", + * __func__, + * einfo->reg, + * einfo->mask, + * val); + */ audiobus_update_bits( einfo->reg, einfo->mask << einfo->shift, @@ -481,20 +486,21 @@ static int spdif_channel_status_info(struct snd_kcontrol *kcontrol, static int spdifin_channel_status_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct soc_enum *e = (struct soc_enum *)kcontrol->private_value; + /* struct soc_enum *e = (struct soc_enum *)kcontrol->private_value; */ int reg, status; - pr_info("set which channel status you wanted to get firstly\n"); + /* pr_info("set which channel status you wanted to get firstly\n"); */ reg = SPDIFIN_CHSTS_REG; status = spdif_get_channel_status(reg); ucontrol->value.enumerated.item[0] = status; /*channel status value in printk information*/ - pr_info("%s: 0x%x\n", - e->texts[spdifin_channel_status], - status - ); + /* pr_info("%s: 0x%x\n", + * e->texts[spdifin_channel_status], + * status + * ); + */ return 0; } @@ -518,8 +524,9 @@ static int spdifin_channel_status_set( valid_bits = (chst >= 6) ? (chst - 6) : chst; spdifin_channel_status = chst; - pr_info("%s\n", - e->texts[spdifin_channel_status]); + /* pr_info("%s\n", + * e->texts[spdifin_channel_status]); + */ spdifin_set_channel_status(ch, valid_bits); @@ -529,21 +536,22 @@ static int spdifin_channel_status_set( static int spdifout_channel_status_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct soc_enum *e = (struct soc_enum *)kcontrol->private_value; + /* struct soc_enum *e = (struct soc_enum *)kcontrol->private_value; */ int reg, status; - pr_info("set which channel status you wanted to get firstly\n"); + /* pr_info("set which channel status you wanted to get firstly\n"); */ reg = SPDIFOUT_CHSTS_REG(spdifout_channel_status); status = spdif_get_channel_status(reg); ucontrol->value.enumerated.item[0] = status; /*channel status value in printk information*/ - pr_info("%s: reg:0x%x, status:0x%x\n", - e->texts[spdifout_channel_status], - reg, - status - ); + /* pr_info("%s: reg:0x%x, status:0x%x\n", + * e->texts[spdifout_channel_status], + * reg, + * status + * ); + */ return 0; } @@ -564,9 +572,9 @@ static int spdifout_channel_status_set( } spdifout_channel_status = chst; - pr_info("%s\n", - e->texts[chst]); - + /* pr_info("%s\n", + * e->texts[chst]); + */ return 0; } diff --git a/sound/soc/amlogic/auge/ddr_mngr.c b/sound/soc/amlogic/auge/ddr_mngr.c index 2ac41394b85c..5412f6593fa6 100644 --- a/sound/soc/amlogic/auge/ddr_mngr.c +++ b/sound/soc/amlogic/auge/ddr_mngr.c @@ -746,33 +746,34 @@ void aml_frddr_select_dst(struct frddr *fr, enum frddr_dest dst) * sel 1 is for reg_frddr_src_sel2 * sel 2 is for reg_frddr_src_sel3 */ -void aml_frddr_select_dst_ss(struct frddr *fr, enum frddr_dest dst, int sel) +void aml_frddr_select_dst_ss(struct frddr *fr, + enum frddr_dest dst, int sel, bool enable) { struct aml_audio_controller *actrl = fr->actrl; unsigned int reg_base = fr->reg_base; unsigned int reg; - if (dst == fr->dest) { - pr_warn_once("same source sel is same with frddr->dest\r"); - return; - } - reg = calc_frddr_address(EE_AUDIO_FRDDR_A_CTRL0, reg_base); /* same source en */ if (fr->chipinfo && fr->chipinfo->same_src_fn) { + int s_v = 0, s_m = 0; - if (sel == 1) - aml_audiobus_update_bits(actrl, reg, - 0xf << 4, - dst << 4 | 1 << 7); - else if (sel == 2) - aml_audiobus_update_bits(actrl, reg, - 0xf << 8, - dst << 8 | 1 << 11); - else - pr_warn_once("sel :%d is not supported for same source\n", - sel); + switch (sel) { + case 1: + s_m = 0xf << 4; + s_v = enable ? (dst << 4 | 1 << 7) : 0 << 4; + break; + case 2: + s_m = 0xf << 8; + s_v = enable ? (dst << 8 | 1 << 11) : 0 << 8; + break; + default: + pr_warn_once("sel :%d is not supported for same source\n", + sel); + break; + } + aml_audiobus_update_bits(actrl, reg, s_m, s_v); } } diff --git a/sound/soc/amlogic/auge/ddr_mngr.h b/sound/soc/amlogic/auge/ddr_mngr.h index 8fcb91dc3e8c..e5762a7a4d08 100644 --- a/sound/soc/amlogic/auge/ddr_mngr.h +++ b/sound/soc/amlogic/auge/ddr_mngr.h @@ -93,7 +93,7 @@ unsigned int aml_frddr_get_position(struct frddr *fr); void aml_frddr_enable(struct frddr *fr, bool enable); void aml_frddr_select_dst(struct frddr *fr, enum frddr_dest); extern void aml_frddr_select_dst_ss(struct frddr *fr, - enum frddr_dest dst, int sel); + enum frddr_dest dst, int sel, bool enable); void aml_frddr_set_fifos(struct frddr *fr, unsigned int depth, unsigned int thresh); unsigned int aml_frddr_get_fifo_id(struct frddr *fr); diff --git a/sound/soc/amlogic/auge/sharebuffer.c b/sound/soc/amlogic/auge/sharebuffer.c index 6d1392b85638..99cca7a37d40 100644 --- a/sound/soc/amlogic/auge/sharebuffer.c +++ b/sound/soc/amlogic/auge/sharebuffer.c @@ -23,7 +23,7 @@ #include "spdif_hw.h" -int sharebuffer_spdifout_prepare(struct snd_pcm_substream *substream, +static int sharebuffer_spdifout_prepare(struct snd_pcm_substream *substream, struct frddr *fr, int spdif_id) { struct snd_pcm_runtime *runtime = substream->runtime; @@ -37,13 +37,28 @@ int sharebuffer_spdifout_prepare(struct snd_pcm_substream *substream, /* spdif b, notify hdmitx audio */ if (spdif_id == 1) { - spdifoutb_to_hdmitx_ctrl(); + spdifoutb_to_hdmitx_ctrl(spdif_id); aout_notifier_call_chain(0x1, substream); } return 0; } +static int sharebuffer_spdifout_free(struct snd_pcm_substream *substream, + struct frddr *fr, int spdif_id) +{ + struct snd_pcm_runtime *runtime = substream->runtime; + int bit_depth; + + bit_depth = snd_pcm_format_width(runtime->format); + + spdifout_samesource_set(spdif_id, + aml_frddr_get_fifo_id(fr), + bit_depth, false); + + return 0; +} + void sharebuffer_enable(int sel, bool enable) { if (sel < 0) { @@ -74,11 +89,34 @@ int sharebuffer_prepare(struct snd_pcm_substream *substream, } /* frddr, share buffer, src_sel1 */ - aml_frddr_select_dst_ss(fr, samesource_sel, 1); + aml_frddr_select_dst_ss(fr, samesource_sel, 1, true); return 0; } +int sharebuffer_free(struct snd_pcm_substream *substream, + void *pfrddr, int samesource_sel) +{ + struct frddr *fr = (struct frddr *)pfrddr; + + /* each module prepare, clocks and controls */ + if (samesource_sel < 0) { + pr_err("Not support same source\n"); + return -EINVAL; + } else if (samesource_sel < 3) { + // TODO: same with tdm + } else if (samesource_sel < 5) { + /* same source with spdif a/b */ + sharebuffer_spdifout_free(substream, fr, samesource_sel - 3); + } + + /* frddr, share buffer, src_sel1 */ + aml_frddr_select_dst_ss(fr, samesource_sel, 1, false); + + return 0; +} + + int sharebuffer_trigger(int cmd, int samesource_sel) { switch (cmd) { diff --git a/sound/soc/amlogic/auge/sharebuffer.h b/sound/soc/amlogic/auge/sharebuffer.h index fa2823ba0b5f..25dca7d09ef4 100644 --- a/sound/soc/amlogic/auge/sharebuffer.h +++ b/sound/soc/amlogic/auge/sharebuffer.h @@ -19,6 +19,8 @@ extern int sharebuffer_prepare(struct snd_pcm_substream *substream, void *pfrddr, int samesource_sel); +extern int sharebuffer_free(struct snd_pcm_substream *substream, + void *pfrddr, int samesource_sel); extern int sharebuffer_trigger(int cmd, int samesource_sel); extern void sharebuffer_get_mclk_fs_ratio(int samesource_sel, diff --git a/sound/soc/amlogic/auge/spdif.c b/sound/soc/amlogic/auge/spdif.c index 111bf90098a4..3e8df7003f4c 100644 --- a/sound/soc/amlogic/auge/spdif.c +++ b/sound/soc/amlogic/auge/spdif.c @@ -418,7 +418,7 @@ static int aml_dai_spdif_prepare( /* TOHDMITX_CTRL0 */ if (p_spdif->id == 1) { - spdifoutb_to_hdmitx_ctrl(); + spdifoutb_to_hdmitx_ctrl(p_spdif->id); aout_notifier_call_chain(AOUT_EVENT_IEC_60958_PCM, substream); } diff --git a/sound/soc/amlogic/auge/spdif_hw.c b/sound/soc/amlogic/auge/spdif_hw.c index 9accf28500db..017f6d7a83e1 100644 --- a/sound/soc/amlogic/auge/spdif_hw.c +++ b/sound/soc/amlogic/auge/spdif_hw.c @@ -270,14 +270,15 @@ void aml_spdifout_get_aed_info(int spdifout_id, *frddrtype = (val >> 4) & 0x7; } -void spdifoutb_to_hdmitx_ctrl(void) +/*value for spdif_index is only 0, 1 */ +void spdifoutb_to_hdmitx_ctrl(int spdif_index) { audiobus_write(EE_AUDIO_TOHDMITX_CTRL0, 1 << 31 | 1 << 3 /* spdif_clk_cap_inv */ | 0 << 2 /* spdif_clk_inv */ - | 1 << 1 /* spdif_out_b */ - | 1 << 0 /* spdif_clk_b */ + | spdif_index << 1 /* spdif_out_b */ + | spdif_index << 0 /* spdif_clk_b */ ); } @@ -364,6 +365,9 @@ void spdifout_samesource_set(int spdif_index, int fifo_id, else spdif_id = 0; - spdifout_clk_ctrl(spdif_id, true); - spdifout_fifo_ctrl(spdif_id, fifo_id, bitwidth); + if (is_enable) { + spdifout_clk_ctrl(spdif_id, true); + spdifout_fifo_ctrl(spdif_id, fifo_id, bitwidth); + } else + spdifout_clk_ctrl(spdif_id, false); } diff --git a/sound/soc/amlogic/auge/spdif_hw.h b/sound/soc/amlogic/auge/spdif_hw.h index d3a9e48b2653..c332bfb813bf 100644 --- a/sound/soc/amlogic/auge/spdif_hw.h +++ b/sound/soc/amlogic/auge/spdif_hw.h @@ -53,7 +53,7 @@ extern void aml_spdifout_select_aed(bool enable, int spdifout_id); extern void aml_spdifout_get_aed_info(int spdifout_id, int *bitwidth, int *frddrtype); -extern void spdifoutb_to_hdmitx_ctrl(void); +extern void spdifoutb_to_hdmitx_ctrl(int spdif_index); extern void spdifout_samesource_set(int spdif_index, int fifo_id, int bitwidth, bool is_enable); diff --git a/sound/soc/amlogic/auge/tdm.c b/sound/soc/amlogic/auge/tdm.c index 99771878f037..9b72816469ac 100644 --- a/sound/soc/amlogic/auge/tdm.c +++ b/sound/soc/amlogic/auge/tdm.c @@ -34,6 +34,8 @@ #include #include +#include + #include "ddr_mngr.h" #include "tdm_hw.h" @@ -107,6 +109,8 @@ struct aml_tdm { struct tdm_chipinfo *chipinfo; /* share buffer with module */ int samesource_sel; + /* virtual link for i2s to hdmitx */ + int i2s2hdmitx; }; static const struct snd_pcm_hardware aml_tdm_hardware = { @@ -401,6 +405,13 @@ static int aml_dai_tdm_prepare(struct snd_pcm_substream *substream, fr, p_tdm->samesource_sel); } + /* i2s source to hdmix */ + if (p_tdm->i2s2hdmitx) { + i2s_to_hdmitx_ctrl(p_tdm->id); + aout_notifier_call_chain(AOUT_EVENT_IEC_60958_PCM, + substream); + } + fifo_id = aml_frddr_get_fifo_id(fr); aml_tdm_fifo_ctrl(p_tdm->actrl, bit_depth, @@ -681,12 +692,21 @@ 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); + struct frddr *fr = p_tdm->fddr; int i; for (i = 0; i < 4; i++) aml_tdm_set_channel_mask(p_tdm->actrl, substream->stream, p_tdm->id, i, 0); + /* share buffer free */ + if (p_tdm->chipinfo && + p_tdm->chipinfo->same_src_fn && fr) { + if (p_tdm->samesource_sel >= 0) + sharebuffer_free(substream, + fr, p_tdm->samesource_sel); + } + return 0; } @@ -1134,6 +1154,14 @@ static int aml_tdm_platform_probe(struct platform_device *pdev) p_tdm->samesource_sel); } + ret = of_property_read_u32(node, "i2s2hdmi", + &p_tdm->i2s2hdmitx); + if (ret < 0) + p_tdm->i2s2hdmitx = 0; + pr_info("TDM id %d i2s2hdmi:%d\n", + p_tdm->id, + p_tdm->i2s2hdmitx); + /* get tdm lanes info. if not, set to default 1 */ ret = of_parse_tdm_lane_slot_in(node, &p_tdm->setting.lane_mask_in); diff --git a/sound/soc/amlogic/auge/tdm_hw.c b/sound/soc/amlogic/auge/tdm_hw.c index 358a0a23d965..3ace5a7f787e 100644 --- a/sound/soc/amlogic/auge/tdm_hw.c +++ b/sound/soc/amlogic/auge/tdm_hw.c @@ -587,3 +587,15 @@ void aml_tdm_clk_pad_select( mask_offset, val_offset); } + +void i2s_to_hdmitx_ctrl(int tdm_index) +{ + audiobus_write(EE_AUDIO_TOHDMITX_CTRL0, + 1 << 31 + | tdm_index << 12 /* dat_sel */ + | tdm_index << 8 /* lrclk_sel */ + | 1 << 7 /* Bclk_cap_inv */ + | 0 << 6 /* Bclk_o_inv */ + | tdm_index << 4 /* Bclk_sel */ + ); +} diff --git a/sound/soc/amlogic/auge/tdm_hw.h b/sound/soc/amlogic/auge/tdm_hw.h index 506c0167e133..896bdf2b5e1f 100644 --- a/sound/soc/amlogic/auge/tdm_hw.h +++ b/sound/soc/amlogic/auge/tdm_hw.h @@ -109,4 +109,6 @@ extern void aml_tdm_clk_pad_select( struct aml_audio_controller *actrl, int mpad, int mclk_sel, int tdm_index, int clk_sel); + +extern void i2s_to_hdmitx_ctrl(int tdm_index); #endif