Hello,
I'm trying to set the SSI with multiple channel setting, but when I try to setup the mask, the register remain to 0x00000000.
I suppose that the problem is some un-compatible register setting.
In this log is possible to see the value of registers: SCR, SRCR, STCR, STCCR, SRCCR, STMSK and SRMSK (the last two remain set to 0x00, but in the variable tx_mask and rx_mask are sets to 0xfffffffd)
imx-ssi : imx_ssi_set_dai_fmt>sound/soc/imx/imx-ssi.c:253:
imx-ssi : SRCR=0000038c, SCR=00000118, STCR=0000038c
imx-ssi : imx_ssi_set_dai_fmt>sound/soc/imx/imx-ssi.c:254:
imx-ssi : STCCR=0004e100, SRCCR=00040100, STMSK=00000000, SRMSK=00000000
imx-ssi : imx_ssi_set_dai_tdm_slot>sound/soc/imx/imx-ssi.c:130:
imx-ssi : Error mask not set..
imx-ssi : imx_ssi_set_dai_tdm_slot>sound/soc/imx/imx-ssi.c:139:
imx-ssi : slots=2, SRCR=0000038c, SCR=00000118, STCR=0000038c
imx-ssi : imx_ssi_set_dai_tdm_slot>sound/soc/imx/imx-ssi.c:140:
imx-ssi : tx_mask=fffffffd, rx_mask=fffffffd, STCCR=0004e100, SRCCR=00040100, STMSK=00000000, SRMSK=00000000
The SCR[0] is 0 (disable SSI as specified).
The code is the follow in imx-ssi.c:
static int imx_ssi_set_dai_tdm_slot(struct snd_soc_dai *cpu_dai, unsigned int tx_mask, unsigned int rx_mask, int slots, int slot_width)
{
dbg_call();
struct imx_ssi *ssi = snd_soc_dai_get_drvdata(cpu_dai);
u32 sccr, scr;
int i;
sccr = readl(ssi->base + SSI_STCCR);
sccr &= ~SSI_STCCR_DC_MASK;
sccr |= SSI_STCCR_DC(slots - 1);
writel(sccr, ssi->base + SSI_STCCR);
sccr = readl(ssi->base + SSI_SRCCR);
sccr &= ~SSI_SRCCR_DC_MASK;
sccr |= SSI_SRCCR_DC(slots - 1);
writel(sccr, ssi->base + SSI_SRCCR);
writel(tx_mask, ssi->base + SSI_STMSK);
writel(rx_mask, ssi->base + SSI_SRMSK);
if(readl(ssi->base + SSI_STMSK) != rx_mask || readl(ssi->base + SSI_SRMSK) != rx_mask)
{
prn_info("Error mask not set..");
}
prn_info("slots=%d, SRCR=%08x, SCR=%08x, STCR=%08x", slots, readl(ssi->base + SSI_SRCR), readl(ssi->base + SSI_SCR), readl(ssi->base + SSI_STCR));
prn_info("tx_mask=%08x, rx_mask=%08x, STCCR=%08x, SRCCR=%08x, STMSK=%08x, SRMSK=%08x", tx_mask , rx_mask , readl(ssi->base + SSI_STCCR), readl(ssi->base + SSI_SRCCR), readl(ssi->base + SSI_STMSK), readl(ssi->base + SSI_SRMSK));
return 0;
}
Regards
解決済! 解決策の投稿を見る。
Check this comment from sound/soc/fsl/fsl_ssi.c:
/* The register SxMSKs needs SSI to provide essential clock due to |
* hardware design. So we here temporarily enable SSI to set them.
*/
regmap_read(regs, CCSR_SSI_SCR, &val);
val &= CCSR_SSI_SCR_SSIEN;
regmap_update_bits(regs, CCSR_SSI_SCR, CCSR_SSI_SCR_SSIEN,
CCSR_SSI_SCR_SSIEN); |
regmap_write(regs, CCSR_SSI_STMSK, ~tx_mask);
regmap_write(regs, CCSR_SSI_SRMSK, ~rx_mask);
Check this comment from sound/soc/fsl/fsl_ssi.c:
/* The register SxMSKs needs SSI to provide essential clock due to |
* hardware design. So we here temporarily enable SSI to set them.
*/
regmap_read(regs, CCSR_SSI_SCR, &val);
val &= CCSR_SSI_SCR_SSIEN;
regmap_update_bits(regs, CCSR_SSI_SCR, CCSR_SSI_SCR_SSIEN,
CCSR_SSI_SCR_SSIEN); |
regmap_write(regs, CCSR_SSI_STMSK, ~tx_mask);
regmap_write(regs, CCSR_SSI_SRMSK, ~rx_mask);
Yes it works, the SSI_SxMASK must be set with SSI_EN=1! (also if in the datasheet say that SSI_EN must be 0).
Really Thank's Fabio!!
Hello Alejandro, thank you for response!
the module si in network mode ( SCR=00000118 =in binary> 100011000 => NET, SYNC, TCH_EN).
Hello Fabio , thank you for response!
I don't understand the line
val &= CCSR_SSI_SCR_SSIEN;
I will try it and update you soon
Thank you!
Hi,
I am not an expert on this but after delving a little I noticed that in normal mode only one time slot is used per frame. And it might be the case that those register are not needed.
Have you checked in which mode the module is working? network or normal mode.
Best Regards,
Alejandro