return 0;
}
-void sharebuffer_enable(int sel, bool enable)
+void sharebuffer_enable(int sel, bool enable, bool reenable)
{
if (sel < 0) {
pr_err("Not support same source\n");
// TODO: same with tdm
} else if (sel < 5) {
/* same source with spdif a/b */
- spdifout_enable(sel - 3, enable);
+ spdifout_enable(sel - 3, enable, reenable);
}
}
}
-int sharebuffer_trigger(int cmd, int samesource_sel)
+int sharebuffer_trigger(int cmd, int samesource_sel, bool reenable)
{
switch (cmd) {
case SNDRV_PCM_TRIGGER_START:
case SNDRV_PCM_TRIGGER_RESUME:
case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
- sharebuffer_enable(samesource_sel, true);
+ sharebuffer_enable(samesource_sel, true, reenable);
break;
case SNDRV_PCM_TRIGGER_STOP:
case SNDRV_PCM_TRIGGER_SUSPEND:
case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
- sharebuffer_enable(samesource_sel, false);
+ sharebuffer_enable(samesource_sel, false, reenable);
break;
default:
return -EINVAL;
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 int sharebuffer_trigger(int cmd, int samesource_sel, bool reenable);
extern void sharebuffer_get_mclk_fs_ratio(int samesource_sel,
int *pll_mclk_ratio, int *mclk_fs_ratio);
bool eq_drc_en;
/* pc, pd interrupt is separated. */
bool pcpd_separated;
+ /* same source, spdif re-enable */
+ bool same_src_spdif_reen;
};
struct aml_spdif {
.chnum_en = true,
.hold_start = true,
.eq_drc_en = true,
+ .same_src_spdif_reen = true,
};
struct spdif_chipinfo tl1_spdif_b_chipinfo = {
.chnum_en = true,
.hold_start = true,
.eq_drc_en = true,
+ .same_src_spdif_reen = true,
};
static const struct of_device_id aml_spdif_device_id[] = {
struct aml_spdif *aml_spdif = NULL;
struct spdif_chipinfo *p_spdif_chipinfo;
int ret = 0;
+ bool spdif_reenable = false;
aml_spdif = devm_kzalloc(dev, sizeof(struct aml_spdif), GFP_KERNEL);
aml_spdif->clk_cont = 1;
aml_spdif->chipinfo = p_spdif_chipinfo;
+
+ spdif_reenable = p_spdif_chipinfo->same_src_spdif_reen;
} else
dev_warn_once(dev,
"check whether to update spdif chipinfo\n");
return -EINVAL;
if (aml_spdif->clk_cont)
- spdifout_play_with_zerodata(aml_spdif->id);
+ spdifout_play_with_zerodata(aml_spdif->id, spdif_reenable);
ret = devm_snd_soc_register_component(dev, &aml_spdif_component,
&aml_spdif_dai[aml_spdif->id], 1);
offset = EE_AUDIO_SPDIFOUT_B_SWAP - EE_AUDIO_SPDIFOUT_SWAP;
reg = EE_AUDIO_SPDIFOUT_SWAP + offset * spdif_id;
audiobus_write(reg, 1<<4);
-
- /* reset afifo */
- offset = EE_AUDIO_SPDIFOUT_B_CTRL0 - EE_AUDIO_SPDIFOUT_CTRL0;
- reg = EE_AUDIO_SPDIFOUT_CTRL0 + offset * spdif_id;
- audiobus_update_bits(reg, 3<<28, 0);
- audiobus_update_bits(reg, 1<<29, 1<<29);
- audiobus_update_bits(reg, 1<<28, 1<<28);
}
static bool spdifout_is_enable(int spdif_id)
return ((val >> 31) == 1);
}
-void spdifout_enable(int spdif_id, bool is_enable)
+void spdifout_enable(int spdif_id, bool is_enable, bool reenable)
{
unsigned int offset, reg;
return;
}
+ /* disable then for reset, to correct channel map */
+ if (reenable)
+ audiobus_update_bits(reg, 1<<31, 0x0<<31);
+
+ /* reset afifo */
+ audiobus_update_bits(reg, 3<<28, 0);
+ audiobus_update_bits(reg, 1<<29, 1<<29);
+ audiobus_update_bits(reg, 1<<28, 1<<28);
+
audiobus_update_bits(reg, 1<<31, is_enable<<31);
}
audiobus_write(reg, chsts->chstat1_r << 16 | chsts->chstat0_r);
}
-void spdifout_play_with_zerodata(unsigned int spdif_id)
+void spdifout_play_with_zerodata(unsigned int spdif_id, bool reenable)
{
pr_debug("%s, spdif id:%d enable:%d\n",
__func__,
frddr_init_without_mngr(frddr_index, src0_sel);
/* spdif enable */
- spdifout_enable(spdif_id, true);
+ spdifout_enable(spdif_id, true, reenable);
}
}
extern void spdifout_samesource_set(int spdif_index, int fifo_id,
int bitwidth, int channels, bool is_enable);
-extern void spdifout_enable(int spdif_id, bool is_enable);
+extern void spdifout_enable(int spdif_id, bool is_enable, bool reenable);
extern int spdifin_get_sample_rate(void);
extern void spdif_set_channel_status_info(
struct iec958_chsts *chsts, int spdif_id);
-extern void spdifout_play_with_zerodata(unsigned int spdif_id);
+extern void spdifout_play_with_zerodata(unsigned int spdif_id, bool reenable);
extern void spdifout_play_with_zerodata_free(unsigned int spdif_id);
extern void spdifin_set_src(int src);
#endif
/* same source */
bool same_src_fn;
+ /* same source, spdif re-enable */
+ bool same_src_spdif_reen;
+
/* ACODEC_ADC function */
bool adc_fn;
};
&& p_tdm->chipinfo->same_src_fn
&& (p_tdm->samesource_sel >= 0)
&& (aml_check_sharebuffer_valid(p_tdm->fddr,
- p_tdm->samesource_sel))) {
- sharebuffer_trigger(cmd, p_tdm->samesource_sel);
- }
+ p_tdm->samesource_sel))
+ )
+ sharebuffer_trigger(cmd,
+ p_tdm->samesource_sel,
+ p_tdm->chipinfo->same_src_spdif_reen);
switch (cmd) {
case SNDRV_PCM_TRIGGER_START:
.clk_pad_ctl = true,
.same_src_fn = true,
.adc_fn = true,
+ .same_src_spdif_reen = true,
};
struct tdm_chipinfo tl1_tdmb_chipinfo = {
.clk_pad_ctl = true,
.same_src_fn = true,
.adc_fn = true,
+ .same_src_spdif_reen = true,
};
struct tdm_chipinfo tl1_tdmc_chipinfo = {
.clk_pad_ctl = true,
.same_src_fn = true,
.adc_fn = true,
+ .same_src_spdif_reen = true,
};
static const struct of_device_id aml_tdm_device_id[] = {