Routings or register settings for modem i2s in the hikey

Hi Everyone,

I am trying to write the i2s driver for the hikey modem i2s. I am currently making hacks in the current i2s driver of it.

I enabled the pins in the low-speed expansion header with the help of this post.

I have the Huawei honor kernel code which uses the same soc as hikey.

I am trying to understand the relationship between the i2s driver in the hikey and hissc.c codec driver in the mobile.

Till now everything is clear.

I got a doubt that, can we route the tinyplay data to the modem i2s?

As per the routings in that file, I am seeing nothing.

/* audio play route soc */
{"STEREO_DLINK_TEST_SEL MUX",               "APB",                  "AUDIO_DLINK INPUT"},
{"STEREO_DLINK_L_EN PGA",                       NULL,                   "STEREO_DLINK_TEST_SEL MUX"},
{"STEREO_DLINK_R_EN PGA",                      NULL,                   "STEREO_DLINK_TEST_SEL MUX"},
{"DACL_MIXER_EN MIXER",            "DACL_MIXER_IN2_MUTE",  "STEREO_DLINK_L_EN PGA"},
{"DACR_MIXER_EN MIXER",           "DACR_MIXER_IN2_MUTE",  "STEREO_DLINK_R_EN PGA"},
{"DACL_AGC_EN PGA",                                NULL,                   "DACL_MIXER_EN MIXER"},
{"DACR_AGC_EN PGA",                               NULL,                   "DACR_MIXER_EN MIXER"},

 .....

/* voice downlink route SoC(bt) */
{"S2_OL_MIXER_EN MIXER",      "S2_OL_MIXER_IN1_MUTE",    "DACL_MIXER_EN MIXER"},
{"S2_OL_MIXER_EN MIXER",      "S2_OL_MIXER_IN2_MUTE",    "DACR_MIXER_EN MIXER"},
{"S2_DOUT_LEFT_SEL MUX",      "SRC3",                                "S2_OL_MIXER_EN MIXER"},
{"S2_DOUT_LEFT_SEL MUX",      "VOICE_DLINK_PGA",            "VOICE_DLINK_EN PGA"},
{"S2_DOUT_TEST_SEL MUX",     "VOICE_DLINK_PGA_S2",       "S2_DOUT_LEFT_SEL MUX"},
{"S2_DOUT_TEST_SEL MUX",     "DACL_MIXER",                      "DACL_MIXER_EN MIXER"},
{"I2S1_2_3 OUTPUT",                NULL,                                    "S2_DOUT_TEST_SEL MUX"},
{"S1_IF_TX_ENA MIXER",                      "ADC_LR",              "I2S1_2_3 INPUT"},
{"S1_IF_TX_ENA MIXER",                      "DAC_LR",              "I2S1_2_3 INPUT"},
{"S1_IF_RX_ENA MIXER",                      "FM_L",                "I2S1_2_3 INPUT"},
{"S1_IF_RX_ENA MIXER",                      "FM_R",                "I2S1_2_3 INPUT"},
{"S1_IF_CLK_EN PGA",             NULL,                  "S1_IF_TX_ENA MIXER"},
{"S1_IF_CLK_EN PGA",             NULL,                  "S1_IF_RX_ENA MIXER"},
{"I2S1_2_3 OUTPUT",               NULL,                  "S1_IF_CLK_EN PGA"},
{"S2_IF_TX_ENA MIXER",                      "DACL",                "I2S1_2_3 INPUT"},
{"S2_IF_TX_ENA MIXER",                      "VOICE_DLINK",         "I2S1_2_3 INPUT"},
{"S2_IF_RX_ENA MIXER",                      "VOICE_UL",            "I2S1_2_3 INPUT"},
{"S2_IF_RX_ENA MIXER",                      "VOICE_UR",            "I2S1_2_3 INPUT"},
{"S2_IF_CLK_EN PGA",             NULL,                  "S2_IF_TX_ENA MIXER"},
{"S2_IF_CLK_EN PGA",             NULL,                  "S2_IF_RX_ENA MIXER"},
{"I2S1_2_3 OUTPUT",               NULL,                  "S2_IF_CLK_EN PGA"},
{"S3_IF_TX_ENA MIXER",                      "VOICE_DL",            "I2S1_2_3 INPUT"},
{"S3_IF_TX_ENA MIXER",                      "VOICE_DR",            "I2S1_2_3 INPUT"},
{"S3_IF_RX_ENA MIXER",                      "VOICE_UP",            "I2S1_2_3 INPUT"},
{"S3_IF_CLK_EN PGA",             NULL,                  "S3_IF_TX_ENA MIXER"},
{"S3_IF_CLK_EN PGA",             NULL,                  "S3_IF_RX_ENA MIXER"},
{"I2S1_2_3 OUTPUT",               NULL,                  "S3_IF_CLK_EN PGA"},

/* 3rd modem downlink */
{"THIRDMD_DLINK_DIN_SEL MUX",   "APB_THIRDMD",             "THIRDMD_DOWN INPUT"},
{"THIRDMD_DLINK_EN SWITCH",      "THIRDMD_DLINK_EN",    "THIRDMD_DLINK_DIN_SEL MUX"},
{"S3_DOUT_RIGHT_SEL MUX",          "THIRDMD_DLINK_PGA",  "THIRDMD_DLINK_EN SWITCH"},
{"S3_DOUT_RIGHT_SEL MUX",          "ADCR_PGA",                  "ADCR_PGA_EN PGA"},
{"S3_DOUT_RIGHT_SEL MUX",          "OTHER",                        "I2S1_2_3 INPUT"},
{"I2S1_2_3 OUTPUT",                        NULL,                            "S3_DOUT_RIGHT_SEL MUX"},
{"S3_DOUT_LEFT_SEL MUX",             "THIRDMD_DLINK_PGA", "THIRDMD_DLINK_EN SWITCH"},
{"S3_DOUT_LEFT_SEL MUX",             "ADCL_PGA",                  "ADCL_PGA_EN PGA"},
{"I2S1_2_3 OUTPUT",                        NULL,                            "S3_DOUT_LEFT_SEL MUX"},

Is there anything that I am missing or no possiblilty to route the tinyplay data to the modem i2s?
I am getting the clocks(lrclk and bclk as I configured those registers).
Only thing left here was that routing the stuff to modem i2s data.

We can see in the comment “audio play route soc” and the source for the first route is “AUDIO_DLINK INPUT”. Is that means the tinyplay data comes to that widget?

And as per the routing we can route the “AUDIO_DLINK INPUT” to S2(bt) but not S3(modem)

Hmmm, I tried using the modem routings.

When I did like that I am getting Errror Playing Sample From the tinyplay.

Did a little debugging and found there is an issue with the DMA or IRQ based on the log playback write error (DMA or IRQ trouble?)

Can anybody know about this issue?

How can I solve that?

Am I missing setting any other registers?

@leo-yan Can you help me in this? :confused:

Hi,

Sorry I have not replied quickly.

I have not worked for audio driver for long time and I’m also not Hisilicon engineer, so please forgive me if I misunderstand or miss something. Below are some thoughts and questions to can make things more clear (sorry you may have brought them in other tickets):

  • Usually we need three parts to enable the audio playback chain: I2S port driver, PCM driver, codec driver. I looked a bit for the driver hissc.c, it’s codec driver and it has configured the internal mux, gates, jack port with damp framework. So if you use this driver, that means you are connecting low speed port with one codec. So I am not sure if this is your case, because on Hikey board we have no any codec on it; except you connect the same codec with low speed port.

  • Please aware one thing, I think it’s not a good idea to refer Hisilicon production code line. The reason is, Hi6220 has one DSP to process audio stream, but AFAIK we have not enabled that on Hikey board.

  • So for quick enabling audio playback, you could refer the audio driver which implemented on Hikey for HDMI: hi6210-hdmi-card.c « hisilicon « soc « sound - john.stultz/android-dev.git - Android Development/Trivial Tree. WARNING: Branches may be rebased., basically I think this driver is used to create a dummy linkage between I2S port and codec, but the codec is a dummy device if I understand correctly. If so, you can see the I2S signal is output from LS port.

I noticed actually you are asking related question in the post: https://github.com/96boards-hikey/linux/commit/4b0b1cd4aca9d033a2ed0823287bb3dfc06c0bc8.

Please let me know if I can provide furthermore info.

Thanks,
Leo Yan

Hi Leo Yan,

Thank you for the reply.

I am not using hissc.c (codec).
I am just tweaking the i2s driver to get the signals on the low-speed expansion header.

I am using the same dummy codec that comes with the hikey(hi6210-hdmi-card.c).

I enabled the pin muxing that you suggested me in the other post.

And changed the registers to get the s3 clocks.
Everything is perfect till here.

But I am not getting DMA error.
I am looking into it.

I feel I missed something related to the configuration of the DMA for s3.

If I change everything back to s2 (i2s driver to original state) I am getting audio on the HDMI.

When I changed everything to s3 (removing the s2 settings and adding s3 settings in the i2s driver and changing the FIFO to thirdmd), I am getting the proper lrclk and bclk but I am getting an error related to DMA or IRQ.

Now I am trying to understand what I need to enable to solve that DMA error.
If you have anything related to this, that helps me a lot :slight_smile:

AFAIK we are using the k3dma driver for the dma transactions.
Is that only limited to stereo fifo(HII2S_ST_DL_CHANNEL) or it can work with the thirdmd fifo(HII2S_THIRDMD_DLINK_CHANNEL) but we need to enable or configure something?

Hi,

Just want to firstly check one thing: which DMA port you are using?

I read a bit for spec, looks like modem I2S using different DMA channels, so need to change DMA channel to below:

 879                         dmas = <&dma0 19 &dma0 18>;
 880                         dma-names = "rx", "tx";

Oh thank you, I will try that. I am using the 14 and 15

Love you man, It is working :slight_smile:

No error in the tinyplay and dmesg.

I just need to verify it by connecting any codec.

And finally from where I can get those document related to those.

I saw this document called Hi6220V100_Multi-Mode_Application_Processor_Function_Description.pdf, but there is nothing specified.

Is that information confidential?
If not can you share those pin mux and dma stuff to me.

Once again thank you leo-yan :grinning:

You are welcome!

I read Hi6220 function description spec (Chinese version) so it keeps some content for codec description. I reviewed English version which you are seeing, it removed related content.

Let me check internally for the doc sharing, I am concern the docs are under NDA.

Modem i2s is only for mono?

If I Play mono data of 60 seconds, it is playing for 60 seconds only.
If I play stereo data of 60 seconds, it is playing for 120 seconds

Hi @vvn2023,

I checked doc, it said support stereo data for 16/18/20/24 bits, have no any special for model i2s for this.

For playing stereo data, do BCLK and LRCLK have double frequency compared against mono data playback? I just want to get clear if this issue is caused by clock rate or by configurations for DMA and port?

Thanks,
Leo Yan

LRCLK is same for both as it is the sample rate played.
I am getting double BCLK when I played stereo data as BCLK = sample rate * bits * channel.
But the stereo taking double time to play.
Don’t know what’s going wrong with it.

Hi @leo-yan ,

Any update?

Or am I missing any configurations?

I did the same way that bt i2s did.

Hi Praveen,

At last week I have shared your question with Hisilicon so ask Hisilicon to confirm internally. But so far I have not get response yet, let me check again with Hisilicon colleague. BTW, if possible could you share me the related setting for I2S port and DMA controller? This will be helpful for detailed checking.

Thanks,
Leo Yan

For dma I changed only the port in the dts file to 19 and 18.

I configured the following registers the same way as the current hdmi or bt i2s doing:

#define HII2S_THIRD_MODEM_FIFO_TH		0x70
#define HII2S_IF_CLK_EN_CFG			4  //enabled the clock related to the s3

setting master slave, setting the func mode for the s3 at register 6c.

In the start up
hi6210_bits(i2s, HII2S_SW_RST_N,
(HII2S_SW_RST_N__THIRDMD_DLINK_WORDLEN_MASK <<
HII2S_SW_RST_N__THIRDMD_DLINK_WORDLEN_SHIFT),
(HII2S_BITS_16 << HII2S_SW_RST_N__THIRDMD_DLINK_WORDLEN_SHIFT));

	hi6210_bits(i2s, HII2S_MISC_CFG,
		    HII2S_MISC_CFG__THIRDMD_DLINK_DIN_SEL |
		    HII2S_MISC_CFG__S3_DOUT_RIGHT_SEL |
		    HII2S_MISC_CFG__S3_DOUT_LEFT_SEL, 0);

Enabled the tx and rx of the s3 and configured the fs and codec data format and io width

Hi @leo-yan ,
I have a new observation related to the bt i2s.
I changed the min channel to 1 and tried playing a 48k 1 channel tone of length 10 seconds.
It played only for 5 seconds.
But when I played 2 channel tone of 10 seconds it played for 10 seconds only.

So s2 interface is exact opposite of the s3 interface because when I play 2 channel 10 seconds tone using the s3 it is playing for 20 seconds and when I play 1 channel 10 seconds tone it is playing for 10 seconds.

Here comes s2 uses stereo fifo (2), so I think it playing the 1 channel as 2 channel or some kind of that stuff.

s3 using thirdmd fifo and I think it is mono(not sure yet), so it is playing 2 channel double duration.

Hi Praveen,

I found the block diagram is indicating modem is supporting only one channel. Please see enclosed picture. Let me double check for this.