summaryrefslogtreecommitdiff
authorZhe Wang <Zhe.Wang@amlogic.com>2019-07-09 09:07:20 (GMT)
committer zihuan.ling <zihuan.ling@amlogic.com>2019-10-17 06:07:18 (GMT)
commitd00eb245c0986bd1846648748d0699ef304683b5 (patch)
tree145328dd60d5a0b168ec024eaa3c33d0b5f5b19c
parentc066c0dd7fc193d60a6d49839d2d82818222cb5a (diff)
downloadcommon-d00eb245c0986bd1846648748d0699ef304683b5.zip
common-d00eb245c0986bd1846648748d0699ef304683b5.tar.gz
common-d00eb245c0986bd1846648748d0699ef304683b5.tar.bz2
audio: set audio path from frhdmirx through spdifin mode [1/2]
PD#SWPL-11054 Problem: hdmiin source, audio input is randomly LR invert Solution: set audio path from frhdmirx through spdifin mode Verify: Verified on X301 Change-Id: Ib40d30b8b6d8bc28da69bf9b4f37ae2ef9228761 Signed-off-by: Zhe Wang <Zhe.Wang@amlogic.com>
Diffstat
-rw-r--r--drivers/amlogic/media/vin/tvin/hdmirx/hdmi_rx_hw.c4
-rw-r--r--sound/soc/amlogic/auge/ddr_mngr.c41
-rw-r--r--sound/soc/amlogic/auge/extn.c69
-rw-r--r--sound/soc/amlogic/auge/frhdmirx_hw.c98
-rw-r--r--sound/soc/amlogic/auge/frhdmirx_hw.h15
-rw-r--r--sound/soc/amlogic/auge/resample.c10
-rw-r--r--sound/soc/amlogic/auge/resample_hw.c9
7 files changed, 123 insertions, 123 deletions
diff --git a/drivers/amlogic/media/vin/tvin/hdmirx/hdmi_rx_hw.c b/drivers/amlogic/media/vin/tvin/hdmirx/hdmi_rx_hw.c
index f48b2fb..cb31828 100644
--- a/drivers/amlogic/media/vin/tvin/hdmirx/hdmi_rx_hw.c
+++ b/drivers/amlogic/media/vin/tvin/hdmirx/hdmi_rx_hw.c
@@ -86,7 +86,7 @@ MODULE_PARM_DESC(hdcp22_on, "\n hdcp22_on\n");
module_param(hdcp22_on, int, 0664);
/* test for HBR CTS, audio module can set it to force 8ch */
-int hbr_force_8ch = 1;
+int hbr_force_8ch;
/*
* hdcp14_key_mode:hdcp1.4 key handle method select
* NORMAL_MODE:systemcontrol path
@@ -2140,7 +2140,7 @@ int hdmirx_audio_init(void)
hdmirx_wr_dwc(DWC_PDEC_ACRM_CTRL, data32);
/* unsupport HBR serial mode. invalid bit */
- /* hdmirx_wr_bits_dwc(DWC_AUD_CTRL, DWC_AUD_HBR_ENABLE, 1); */
+ hdmirx_wr_bits_dwc(DWC_AUD_CTRL, DWC_AUD_HBR_ENABLE, 1);
/* SAO cfg, disable I2S output, no use */
data32 = 0;
diff --git a/sound/soc/amlogic/auge/ddr_mngr.c b/sound/soc/amlogic/auge/ddr_mngr.c
index 1fa7282..fce113b 100644
--- a/sound/soc/amlogic/auge/ddr_mngr.c
+++ b/sound/soc/amlogic/auge/ddr_mngr.c
@@ -441,8 +441,8 @@ void aml_toddr_set_format(struct toddr *to, struct toddr_fmt *fmt)
reg = calc_toddr_address(EE_AUDIO_TODDR_A_CTRL0, reg_base);
aml_audiobus_update_bits(actrl, reg,
- 0x7 << 24 | 0x1fff << 3,
- fmt->endian << 24 | fmt->type << 13 |
+ 0x1 << 27 | 0x7 << 24 | 0x1fff << 3,
+ 0x1 << 27 | fmt->endian << 24 | fmt->type << 13 |
fmt->msb << 8 | fmt->lsb << 3);
}
@@ -695,15 +695,15 @@ static void aml_resample_enable(
resample_src_select(to->fifo_id);
}
- /* resample enable or not */
- resample_enable(p_attach_resample->id, enable);
-
/* select reample data */
if (to->chipinfo
&& to->chipinfo->asrc_src_sel_ctrl)
aml_toddr_set_resample_ab(to, p_attach_resample->id, enable);
else
aml_toddr_set_resample(to, enable);
+
+ /* resample enable or disable */
+ resample_enable(p_attach_resample->id, enable);
}
void aml_set_resample(enum resample_idx id,
@@ -711,7 +711,6 @@ void aml_set_resample(enum resample_idx id,
{
struct toddr_attach *p_attach_resample;
struct toddr *to;
- bool update_running = false;
if (id == RESAMPLE_A)
p_attach_resample = &attach_resample_a;
@@ -730,26 +729,7 @@ void aml_set_resample(enum resample_idx id,
goto exit;
}
- if (enable) {
- if ((p_attach_resample->status == DISABLED)
- || (p_attach_resample->status == READY)) {
-
- if (!to) {
- p_attach_resample->status = READY;
- } else {
- p_attach_resample->status = RUNNING;
- update_running = true;
- pr_info("Capture with resample\n");
- }
- }
- } else {
- if (p_attach_resample->status == RUNNING)
- update_running = true;
-
- p_attach_resample->status = DISABLED;
- }
-
- if (update_running && to)
+ if (p_attach_resample->status == RUNNING)
aml_resample_enable(to, p_attach_resample, enable);
exit:
@@ -770,18 +750,19 @@ static void aml_check_resample(struct toddr *to, bool enable)
start_check:
is_module_resample = false;
- if (p_attach_resample->enable
- && (to->src == p_attach_resample->attach_module))
+ if (to->src == p_attach_resample->attach_module)
is_module_resample = true;
- /* resample in enable */
if (is_module_resample) {
+ /* save toddr status */
if (enable)
p_attach_resample->status = RUNNING;
else
p_attach_resample->status = DISABLED;
- aml_resample_enable(to, p_attach_resample, enable);
+ /*if disable toddr, disable attached resampler*/
+ if (p_attach_resample->enable)
+ aml_resample_enable(to, p_attach_resample, enable);
}
if ((!resample_b_check)
diff --git a/sound/soc/amlogic/auge/extn.c b/sound/soc/amlogic/auge/extn.c
index f95afa5..97f7cc8 100644
--- a/sound/soc/amlogic/auge/extn.c
+++ b/sound/soc/amlogic/auge/extn.c
@@ -50,6 +50,11 @@
#define DYNC_KCNTL_CNT 2
+enum {
+ HDMIRX_MODE_SPDIFIN = 0,
+ HDMIRX_MODE_PAO = 1,
+};
+
struct extn_chipinfo {
/* try to check papb before fetch pcpd
* no nonpcm2pcm irq for tl1
@@ -147,27 +152,24 @@ static irqreturn_t extn_ddr_isr(int irq, void *devid)
struct snd_soc_pcm_runtime *rtd = substream->private_data;
struct device *dev = rtd->platform->dev;
struct extn *p_extn = (struct extn *)dev_get_drvdata(dev);
- int timeout_thres = 5;
-
-#ifdef CONFIG_AMLOGIC_MEDIA_TVIN_HDMI
- int sample_rate_index = get_hdmi_sample_rate_index();
-
- /*192K audio*/
- if (sample_rate_index == 7)
- timeout_thres = 10;
- else
- timeout_thres = 5;
-#endif
if (!snd_pcm_running(substream))
return IRQ_HANDLED;
snd_pcm_period_elapsed(substream);
- /* check pcm or nonpcm */
- if (p_extn &&
- p_extn->chipinfo &&
- p_extn->chipinfo->no_nonpcm2pcm_clr) {
+ /* check pcm or nonpcm for PAO*/
+ if (p_extn->hdmirx_mode == HDMIRX_MODE_PAO) {
+ int timeout_thres = 5;
+#ifdef CONFIG_AMLOGIC_MEDIA_TVIN_HDMI
+ int sample_rate_index = get_hdmi_sample_rate_index();
+
+ /*192K audio*/
+ if (sample_rate_index == 7)
+ timeout_thres = 10;
+ else
+ timeout_thres = 5;
+#endif
if (p_extn->frhdmirx_last_cnt == p_extn->frhdmirx_cnt) {
p_extn->frhdmirx_same_cnt++;
@@ -183,6 +185,8 @@ static irqreturn_t extn_ddr_isr(int irq, void *devid)
p_extn->nonpcm_flag = true;
frhdmirx_clr_PAO_irq_bits();
}
+ } else {
+ frhdmirx_clr_SPDIF_irq_bits();
}
return IRQ_HANDLED;
@@ -260,8 +264,7 @@ static int extn_close(struct snd_pcm_substream *substream)
if (toddr_src_get() == FRHDMIRX) {
frhdmirx_nonpcm2pcm_clr_reset(p_extn);
- if (p_extn->hdmirx_mode == 1)
- frhdmirx_clr_PAO_irq_bits();
+ frhdmirx_clr_all_irq_bits();
free_irq(p_extn->irq_frhdmirx, p_extn);
}
}
@@ -496,20 +499,26 @@ static int extn_dai_prepare(
*/
/* fratv_src_select(1); */
} else if (src == FRHDMIRX) {
- if (p_extn->hdmirx_mode) { /* PAO */
- if (bit_depth == 32)
- toddr_type = 3;
- else if (bit_depth == 24)
- toddr_type = 4;
- else
- toddr_type = 0;
+ if (bit_depth == 32)
+ toddr_type = 3;
+ else if (bit_depth == 24)
+ toddr_type = 4;
+ else
+ toddr_type = 0;
+ if (p_extn->hdmirx_mode == HDMIRX_MODE_PAO) { /* PAO */
msb = 28 - 1 - 4;
if (bit_depth == 16)
lsb = 24 - bit_depth;
else
lsb = 4;
+ } else { /* SPDIFIN */
+ msb = 28 - 1;
+ if (bit_depth <= 24)
+ lsb = 28 - bit_depth;
+ else
+ lsb = 4;
}
frhdmirx_ctrl(runtime->channels, p_extn->hdmirx_mode);
@@ -812,7 +821,7 @@ static int hdmiin_check_audio_type(struct extn *p_extn)
int audio_type = 0;
int i;
- if (!p_extn->nonpcm_flag)
+ if (!p_extn->nonpcm_flag && p_extn->hdmirx_mode)
return audio_type;
for (i = 0; i < total_num; i++) {
@@ -935,9 +944,9 @@ static const struct snd_kcontrol_new extn_controls[] = {
aml_set_atmos_audio_edid),
SOC_ENUM_EXT("HDMIIN Audio Type",
- hdmirx_audio_type_enum,
- hdmirx_audio_type_get_enum,
- NULL),
+ hdmirx_audio_type_enum,
+ hdmirx_audio_type_get_enum,
+ NULL),
#endif
};
@@ -1014,8 +1023,8 @@ static int extn_platform_probe(struct platform_device *pdev)
/* Default ARC SRC */
p_extn->arc_src = 1;
- /* Default: PAO mode */
- p_extn->hdmirx_mode = 1;
+ /* Default: SPDIFIN mode */
+ p_extn->hdmirx_mode = HDMIRX_MODE_SPDIFIN;
ret = devm_snd_soc_register_component(&pdev->dev,
&extn_component,
diff --git a/sound/soc/amlogic/auge/frhdmirx_hw.c b/sound/soc/amlogic/auge/frhdmirx_hw.c
index 1dd0593..6f2846b 100644
--- a/sound/soc/amlogic/auge/frhdmirx_hw.c
+++ b/sound/soc/amlogic/auge/frhdmirx_hw.c
@@ -51,12 +51,7 @@ void frhdmirx_src_select(int src)
static void frhdmirx_enable_irq_bits(int channels, int src)
{
- int lane, int_bits = 0, i;
-
- if (channels % 2)
- lane = channels / 2 + 1;
- else
- lane = channels / 2;
+ unsigned int int_bits = 0;
/* interrupt bits */
if (src) { /* PAO mode */
@@ -66,78 +61,59 @@ static void frhdmirx_enable_irq_bits(int channels, int src)
);
} else { /* SPDIF Lane */
int lane_irq_bits = (0x1 << 7 | /* lane: find papb */
- 0x1 << 6 | /* lane: find papb */
+ 0x1 << 6 | /* lane: find valid changed */
0x1 << 5 | /* lane: find nonpcm to pcm */
0x1 << 4 | /* lane: find pcpd changed */
0x1 << 3 | /* lane: find ch status changed */
0x1 << 1 /* lane: find parity error */
);
+ int lane, i;
+
+ lane = (channels % 2) ? (channels / 2 + 1) : (channels / 2);
for (i = 0; i < lane; i++)
- int_bits |= (lane_irq_bits << i);
+ int_bits |= (lane_irq_bits << 8 * i);
}
+
+ int_bits |= audiobus_read(EE_AUDIO_FRHDMIRX_CTRL2);
audiobus_write(EE_AUDIO_FRHDMIRX_CTRL2, int_bits);
}
-void frhdmirx_clr_irq_bits(int channels, int src)
+void frhdmirx_clr_all_irq_bits(void)
{
- int lane, int_clr_mask = 0, i;
-
- if (channels % 2)
- lane = channels / 2 + 1;
- else
- lane = channels / 2;
-
- /* interrupt bits */
- if (src) { /* PAO mode */
- int_clr_mask = (
- 0x1 << INT_PAO_PAPB_MASK | /* find papb */
- 0x1 << INT_PAO_PCPD_MASK /* find pcpd changed */
- );
- } else { /* SPDIF Lane */
- int lane_irq_bits = (0x1 << 7 | /* lane: find papb */
- 0x1 << 6 | /* lane: find valid changed; */
- 0x1 << 5 | /* lane: find nonpcm to pcm */
- 0x1 << 4 | /* lane: find pcpd changed */
- 0x1 << 3 | /* lane: find ch status changed */
- 0x1 << 1 /* lane: find parity error */
- );
-
- for (i = 0; i < lane; i++)
- int_clr_mask |= (lane_irq_bits << i);
- }
- audiobus_write(EE_AUDIO_FRHDMIRX_CTRL3, ~int_clr_mask);
- audiobus_write(EE_AUDIO_FRHDMIRX_CTRL3, int_clr_mask);
- audiobus_write(EE_AUDIO_FRHDMIRX_CTRL4, ~int_clr_mask);
- audiobus_write(EE_AUDIO_FRHDMIRX_CTRL4, int_clr_mask);
+ audiobus_write(EE_AUDIO_FRHDMIRX_CTRL3, 0xffffffff);
+ audiobus_write(EE_AUDIO_FRHDMIRX_CTRL3, 0x0);
+ audiobus_write(EE_AUDIO_FRHDMIRX_CTRL4, 0xffffffff);
+ audiobus_write(EE_AUDIO_FRHDMIRX_CTRL4, 0x0);
}
void frhdmirx_ctrl(int channels, int src)
{
- int lane, lane_mask = 0, i;
-
/* PAO mode */
if (src) {
audiobus_write(EE_AUDIO_FRHDMIRX_CTRL0,
0x1 << 22 | /* capture input by fall edge*/
0x1 << 8 | /* start detect PAPB */
+ 0x1 << 7 | /* add channel num */
0x4 << 4 /* chan status sel: pao pc/pd value */
);
} else {
- if (channels % 2)
- lane = channels / 2 + 1;
- else
- lane = channels / 2;
+ int lane, lane_mask = 0, i;
+ lane = (channels % 2) ? (channels / 2 + 1) : (channels / 2);
for (i = 0; i < lane; i++)
lane_mask |= (1 << i);
audiobus_update_bits(EE_AUDIO_FRHDMIRX_CTRL0,
- 0x1 << 30 | 0xf << 24 | 0x1 << 22 | 0x3 << 11,
+ 0x1 << 30 | 0xf << 24 | 0x1 << 22 |
+ 0x3 << 11 | 0x1 << 8 | 0x1 << 7 | 0x7 << 0,
0x1 << 30 | /* chnum_sel */
lane_mask << 24 | /* chnum_sel */
0x1 << 22 | /* clk_inv */
- 0x0 << 11 /* req_sel, Sync 4 spdifin by which */
+ 0x0 << 11 | /* req_sel, Sync 4 spdifin by which */
+ 0x1 << 8 | /* start detect PAPB */
+ 0x1 << 7 | /* add channel num*/
+ 0x6 << 0 /* channel status*/
);
}
/* nonpcm2pcm_th */
@@ -158,6 +134,35 @@ void frhdmirx_clr_PAO_irq_bits(void)
0x0 << INT_PAO_PAPB_MASK | 0x0 << INT_PAO_PCPD_MASK);
}
+void frhdmirx_clr_SPDIF_irq_bits(void)
+{
+ unsigned int value = audiobus_read(EE_AUDIO_FRHDMIRX_STAT0);
+ unsigned int clr_mask = audiobus_read(EE_AUDIO_FRHDMIRX_CTRL4);
+ unsigned int reg = 0;
+ int i;
+
+ reg = clr_mask | value;
+ audiobus_write(EE_AUDIO_FRHDMIRX_CTRL4, reg);
+
+ reg = clr_mask & (~value);
+ audiobus_write(EE_AUDIO_FRHDMIRX_CTRL4, reg);
+
+ /*compressed audio only transfer through lane0*/
+ for (i = 0; i < 1; i++) {
+ /*nonpcm2pcm irq, clear papb/pcpd/nonpcm*/
+ if (value & (0x20 << 8 * i)) {
+ audiobus_update_bits(
+ EE_AUDIO_FRHDMIRX_CTRL3,
+ 0xf << 8 * i, 0xf << 8 * i);
+ audiobus_update_bits(
+ EE_AUDIO_FRHDMIRX_CTRL3,
+ 0xf << 8 * i, 0x0 << 8 * i);
+ pr_info("raw to pcm change: irq status:%x, lane: %d\n",
+ value, i);
+ }
+ }
+}
+
unsigned int frhdmirx_get_ch_status0to31(void)
{
return (unsigned int)audiobus_read(EE_AUDIO_FRHDMIRX_STAT0);
@@ -170,3 +175,4 @@ unsigned int frhdmirx_get_chan_status_pc(void)
val = audiobus_read(EE_AUDIO_FRHDMIRX_STAT1);
return (val >> 16) & 0xff;
}
+
diff --git a/sound/soc/amlogic/auge/frhdmirx_hw.h b/sound/soc/amlogic/auge/frhdmirx_hw.h
index 7c83dd0..6b336cd 100644
--- a/sound/soc/amlogic/auge/frhdmirx_hw.h
+++ b/sound/soc/amlogic/auge/frhdmirx_hw.h
@@ -20,10 +20,13 @@
#define INT_PAO_PAPB_MASK 24
#define INT_PAO_PCPD_MASK 16
-extern void frhdmirx_enable(bool enable);
-extern void frhdmirx_src_select(int src);
-extern void frhdmirx_ctrl(int channels, int src);
-extern void frhdmirx_clr_PAO_irq_bits(void);
-extern unsigned int frhdmirx_get_ch_status0to31(void);
-extern unsigned int frhdmirx_get_chan_status_pc(void);
+void frhdmirx_enable(bool enable);
+void frhdmirx_src_select(int src);
+void frhdmirx_ctrl(int channels, int src);
+void frhdmirx_clr_PAO_irq_bits(void);
+void frhdmirx_clr_SPDIF_irq_bits(void);
+unsigned int frhdmirx_get_ch_status0to31(void);
+unsigned int frhdmirx_get_chan_status_pc(void);
+void frhdmirx_clr_all_irq_bits(void);
+
#endif
diff --git a/sound/soc/amlogic/auge/resample.c b/sound/soc/amlogic/auge/resample.c
index c4cd6c1..41905cf 100644
--- a/sound/soc/amlogic/auge/resample.c
+++ b/sound/soc/amlogic/auge/resample.c
@@ -143,12 +143,6 @@ static int resample_clk_set(struct audioresample *p_resample)
return ret;
}
-static void audio_resample_init(struct audioresample *p_resample)
-{
- aml_set_resample(p_resample->id, p_resample->enable,
- p_resample->resample_module);
-}
-
static int audio_resample_set(
struct audioresample *p_resample,
bool enable, int rate)
@@ -158,7 +152,9 @@ static int audio_resample_set(
p_resample->enable = enable;
p_resample->out_rate = rate;
- audio_resample_init(p_resample);
+ aml_set_resample(
+ p_resample->id, p_resample->enable,
+ p_resample->resample_module);
return 0;
}
diff --git a/sound/soc/amlogic/auge/resample_hw.c b/sound/soc/amlogic/auge/resample_hw.c
index f5d4d43..0ebbece 100644
--- a/sound/soc/amlogic/auge/resample_hw.c
+++ b/sound/soc/amlogic/auge/resample_hw.c
@@ -45,6 +45,11 @@ void resample_enable(enum resample_idx id, bool enable)
int offset = EE_AUDIO_RESAMPLEB_CTRL0 - EE_AUDIO_RESAMPLEA_CTRL0;
int reg = EE_AUDIO_RESAMPLEA_CTRL0 + offset * id;
+ /*don't change this flow*/
+ audiobus_update_bits(
+ reg, 0x1 << 31 | 0x1 << 28,
+ 0 << 31 | 0x0 << 28);
+
audiobus_update_bits(reg,
0x1 << 31,
1 << 31);
@@ -90,7 +95,7 @@ int resample_disable(enum resample_idx id)
int offset = EE_AUDIO_RESAMPLEB_CTRL0 - EE_AUDIO_RESAMPLEA_CTRL0;
int reg = EE_AUDIO_RESAMPLEA_CTRL0 + offset * id;
- audiobus_write(reg, 0);
+ audiobus_update_bits(reg, 0x1 << 28, 0 << 28);
return 0;
}
@@ -116,7 +121,7 @@ int resample_set_hw_param(enum resample_idx id,
offset = EE_AUDIO_RESAMPLEB_CTRL2 - EE_AUDIO_RESAMPLEA_CTRL2;
reg = EE_AUDIO_RESAMPLEA_CTRL2 + offset * id;
- audiobus_update_bits(reg, 1 << 25, 1 << 25);
+ audiobus_update_bits(reg, 3 << 26 | 1 << 25, 3 << 26 | 1 << 25);
resample_set_hw_pause_thd(id, 128);
return 0;