mirror of
https://github.com/hardkernel/linux.git
synced 2026-06-08 11:50:43 +09:00
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>
This commit is contained in:
@@ -90,7 +90,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
|
||||
@@ -1913,7 +1913,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;
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -651,9 +651,6 @@ static void aml_resample_enable(
|
||||
}
|
||||
}
|
||||
|
||||
/* resample enable or not */
|
||||
resample_enable(p_attach_resample->id, enable);
|
||||
|
||||
/* select reample data */
|
||||
if (to->chipinfo
|
||||
&& to->chipinfo->asrc_src_sel_ctrl)
|
||||
@@ -673,7 +670,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;
|
||||
@@ -688,26 +684,7 @@ void aml_set_resample(enum resample_idx id,
|
||||
to = fetch_toddr_by_src(
|
||||
p_attach_resample->attach_module);
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
|
||||
@@ -48,6 +48,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
|
||||
@@ -145,27 +150,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++;
|
||||
@@ -181,6 +183,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;
|
||||
@@ -258,8 +262,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);
|
||||
}
|
||||
}
|
||||
@@ -497,20 +500,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);
|
||||
@@ -808,7 +817,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++) {
|
||||
@@ -931,9 +940,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
|
||||
|
||||
};
|
||||
@@ -1010,8 +1019,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,
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -156,12 +156,6 @@ static int resample_clk_set(struct audioresample *p_resample, int output_sr)
|
||||
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)
|
||||
@@ -171,7 +165,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;
|
||||
}
|
||||
|
||||
@@ -317,7 +317,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;
|
||||
|
||||
Reference in New Issue
Block a user