audio: auge: add i2s to hdmix port

PD#161826: audio: auge: add i2s to hdmix port

Change-Id: I0aca7160342810385ea0e531ab8fe31c948a80b6
Signed-off-by: Xing Wang <xing.wang@amlogic.com>
This commit is contained in:
Xing Wang
2018-03-15 15:19:40 +08:00
committed by Jianxin Pan
parent 3af713f88a
commit 5faf25a4fd
15 changed files with 360 additions and 85 deletions

View File

@@ -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>;

View File

@@ -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";
};
};

View File

@@ -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>;

View File

@@ -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>;

View File

@@ -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;
}

View File

@@ -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);
}
}

View File

@@ -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);

View File

@@ -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) {

View File

@@ -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,

View File

@@ -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);
}

View File

@@ -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);
}

View File

@@ -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);

View File

@@ -34,6 +34,8 @@
#include <linux/amlogic/clk_measure.h>
#include <linux/amlogic/cpu_version.h>
#include <linux/amlogic/media/sound/aout_notify.h>
#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);

View File

@@ -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 */
);
}

View File

@@ -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