Enable DMic (Linux)


#1

Has anyone had any luck enabling DMIC functionality on the Dragonboard + Linux?

According to this document, disabling UART0 is required followed by enabling the DMIC in the source of the OS.

I have been able to edit the APQ8016-sbc.dtsi to disable UART1 (indexing starts at 1 in this file, there doesn’t appear to be a UART0) BUT am unable to find where to enable the DMIC.

I am using the rpb-console-image and Bitbake to create the image.


#2

Was able to migrate to Linux 4.9 and many of the audio issues I was having on 4.4 are now gone. However, still unable to get DMIC to work.

Anyone had any luck?


#3

as far as I know, DMIC has not been tested yet on DB410c (on Linaro Linux release and/or QCOM Android releases).


#4

Is there any timeline for when this might happen?

And/or

Any suggestions about where to progress on my own?


#5

Hi Sabjorn

Sorry for the delay getting back to you about this. I haven’t tested it, however I can describe the Hardware, hopefully that may help you get started. The DMIC hardware (M2) is on the Arrow Audio Mezzanine board:

As you can see you will need to turn on CDC_MIC_BIAS1 to power up the DMIC. The DMIC uses GPIO0 and GPIO1 for clock and data. In the default software builds GPIO0 and GPIO1 are used as UART0 TxD and RxD, so you will need to disable UART0 so that you can use the pins for DMIC. You may also need to install a Zero ohm resistor (or a solder short) to connect the DMIC Data to the GPIO, I am unclear if the board ships with the resistor installed or removed…

As to the details of ‘how’ you disable UART0, and enable DMIC, and how you get the data through to the Audio Drivers, that is way beyond my knowledge of Linux kernels. Hopefully someone else can help you with these details.


#6

Hello,
I have it working on Android.
From the HW side the DMIC should be connected to UART pins.
From SW side the pin configuration should be changed to DMIC
In file: kernel\arch\arm\boot\dts\qcom\msm8916-pinctrl.dtsi Line 112:
cdc-dmic-lines {
qcom,pins = <&gp 0>, <&gp 1>;
qcom,num-grp-pins = <2>;
qcom,pin-func = <4>;
label = “cdc-dmic-lines”;
cdc_dmic_lines_act: dmic_lines_on {
drive-strength = <8>;
};
cdc_dmic_lines_sus: dmic_lines_off {
drive-strength = <2>;
bias-disable;
};
};

While testing by Sound Recorder application type the following command in the shell:
" # tinymix 631 DMIC1"

You can use this application to permanently switch to DMIC:
https://play.google.com/store/apps/details?id=com.woodslink.android.wiredheadphoneroutingfix&hl=en


#7

What kernel version is this, leonid? With qcomlt-4.9, the file is msm8961-pins.dtsi and it has different names for the gpio pins…


#8

Hello,
I was talking about Android 5.1.1, kernel version 3.10.49
Thank you, Leonid.


#9

With qcomlt-4.9, the syntax used in the dtsi is completely different.

I’ve sorted through all that, and told the driver to claim the pins by actually including them in the pinctrl list:

/* apq8016-sbc.dtsi */
...
sound: sound {
    ...
    -pinctrl-0 = <&cdc_pdm_lines_act &ext_sec_tlmm_lines_act &ext_mclk_tlmm_lines_act>;
    +pinctrl-0 = <&cdc_dmic_lines_act &cdc_pdm_lines_act &ext_sec_tlmm_lines_act &ext_mclk_tlmm_lines_act>;
    -pinctrl-1 = <&cdc_pdm_lines_sus &ext_sec_tlmm_lines_sus &ext_mclk_tlmm_lines_sus>;
    +pinctrl-1 = <&cdc_dmic_lines_sus &cdc_pdm_lines_sus &ext_sec_tlmm_lines_sus &ext_mclk_tlmm_lines_sus>;
    ...
}

That gets me this:

root@dragonboard-2528:/sys/kernel/debug/pinctrl# grep -r dmic * 
1000000.pinctrl/pinmux-pins:pin 0 (GPIO_0): 7702000.sound 1000000.pinctrl:0 function dmic0_clk group gpio0
1000000.pinctrl/pinmux-pins:pin 1 (GPIO_1): 7702000.sound (GPIO UNCLAIMED) function dmic0_data group gpio1
1000000.pinctrl/pinmux-functions:function: dmic0_clk, groups = [ gpio0 ]
1000000.pinctrl/pinmux-functions:function: dmic0_data, groups = [ gpio1 ]
pinctrl-handles:    type: MUX_GROUP controller 1000000.pinctrl group: gpio0 (0) function: dmic0_clk (56)
pinctrl-handles:    type: MUX_GROUP controller 1000000.pinctrl group: gpio1 (1) function: dmic0_data (57)
pinctrl-maps:function dmic0_clk
pinctrl-maps:function dmic0_data

I’ve also sorted out the typos in the lm80-p0436-43 doc, and put the Audio Mezzanine’s analog mic on TX1 (a.k.a. “left”), and the digital mic on TX2 (“right”):

# map analog mic to left channel
$ amixer –c 0 cset iface=MIXER,name=’ADC2 MUX’ ‘INP3’
$ amixer –c 0 cset iface=MIXER,name=’ADC2 Volume’ 8
$ amixer –c 0 cset iface=MIXER,name=’DEC1 MUX’ 'ADC2′
$ amixer -c 0 cset iface=MIXER,name='TX1 Digital Volume' 255

# map dmic to right channel
$ amixer -c 0 cset iface=MIXER,name='DEC2 MUX' 'DMIC1'
$ amixer -c 0 cset iface=MIXER,name='TX2 Digital Volume' 255

$ arecord –c 2 -D plughw:0,2 -r 48000 -f S16_LE /tmp/f-48000.wav

I’ve also swapped TX1 and TX2, and confirmed that the audio switches sides like you’d expect.

Still no clock on the DMIC lines, tho.

What’s left, I think, is possibly a silent failure related to this dmesg output:

[ 1380.949926] msm8916-wcd-digital-codec 771c000.codec: Invalid mclk rate 19200000

It’s too late in the day here to hunt this one down, so I’m passing the baton for the night.


#10

Weird.

In msm8916-wcd-digital.c, the startup code demands one of two mclk rates:

    switch (mclk_rate) {
    case 12288000:
            snd_soc_update_bits(codec, LPASS_CDC_TOP_CTL,
                                TOP_CTL_DIG_MCLK_FREQ_MASK,
                                TOP_CTL_DIG_MCLK_FREQ_F_12_288MHZ);
            break;
    case 9600000:
            snd_soc_update_bits(codec, LPASS_CDC_TOP_CTL,
                                TOP_CTL_DIG_MCLK_FREQ_MASK,
                                TOP_CTL_DIG_MCLK_FREQ_F_9_6MHZ);
            break;
    default:
            dev_err(codec->dev, "Invalid mclk rate %ld\n", mclk_rate);
            break;
    }

But, in gcc-msm8916, the frequency table contains just two entries:

static const struct freq_tbl ftbl_codec_clk[] = {
        F(19200000, P_XO, 1, 0, 0),
        F(11289600, P_EXT_MCLK, 1, 0, 0),
        { }
};

Without documentation, I can’t really tell how to reconcile these two values…


#11

Nobody has any further thoughts on this? I’ve kinda hit a brick wall here…


#12

Anyone? Srini? Leonid?


#13

Hi @bgat:

I haven’t tested any of this, I have just been reading through this thread. Curiously one of the clock rates in gcc-msm8916 is exactly 2x the rates requested in msm8916-wcd-digital.c, the other clock rate is probably close enough to work, but not an exact match.

There is another document recently released that may shed more insight into the clocking of the system here: https://developer.qualcomm.com/download/db410c/clock-plan-apq8016e.pdf

Can you let me know about the typos in the Audio App note and I will get the app note fixed up. I will also try to add some of the information I have seen in a couple other forum posts.

Full disclosure: I am an employee of Qualcomm Canada. Any opinions I may have expressed in this or any other post may not reflect the opinions of my employer.


#14

I’ll review that document, then look at that clock rate.

The “typos” in the Audio App note are really just mismatches between the organizational conventions that apparently changed with later kernels. I’ll organize my notes and report back on that, too.


#15

Hi All,
Here is a branch[1] with few patches that are required to get dmic support working on linux.
I have tested this with audio mezz board: https://www.arrow.com/en/products/audiomezz/seeed-technology-limited

on cmd line use below cmds to test dmic or alsa ucm will do the job from UI:

$amixer cset iface=MIXER,name=‘DEC1 MUX’ ‘DMIC1’
$arecord -D plughw:0,2 -r 48000 -f S16_LE /tmp/f-48000.wav

Thanks,
srini

[1] https://git.linaro.org/people/srinivas.kandagatla/linux.git/log/?h=v4.11-dmic-db410c


#16

Srini:

Your patches are against the v4.11 kernel, but they applied cleanly to 4.9.

And, guess what? They seem to work!! :slight_smile:

Thanks very, very much!

b.g.


#17

thanks for your report! we will add these patches in the next release (17.06, later this month) and we will upstream them as well!

cheers


#18

@ndec did this DMIC patch make it into 17.06?
Tried looking through the linaro git commit logs but I haven’t been able to find a reference.


#19

ouch. no… sorry about that. let me see what we can do to get them asap.


#20

Looks like the latest release has DMIC support. However, I am not certain how to enable it. I’ve tried switching DEC1 MUX to DMIC1 (and also DMIC2) but the DMIC does not seem to activate.

Any suggestions?
Is there documentation anywhere?