.. spelling:word-list:: Clk fs mclk .. include:: /keyword.rst ============ DMIC Porting ============ .. contents:: Sections :local: :depth: 2 Driver Command Usage -------------------- There are 4 DMIC interfaces available on the Genio 510/700/1200, where each interface supports 2 channels, you can indeed receive data from up to 8 channels simultaneously. - ALSA command for DMIC 2 channels .. prompt:: bash # auto # amixer -c 0 cset name='O002 I004 Switch' 1 # amixer -c 0 cset name='O003 I005 Switch' 1 .. prompt:: bash # auto # arecord -Dhw:0,14 -c 2 -r 48000 -f S16_LE -d 10 rec.wav .. figure:: /_asset/sw_rity_porting-guide_audio_2dmic.png :align: center :scale: 100% DMIC 2 channels - ALSA command for DMIC 4 channels .. prompt:: bash # auto # amixer -c 0 cset name='O002 I004 Switch' 1 # amixer -c 0 cset name='O003 I005 Switch' 1 # amixer -c 0 cset name='O004 I006 Switch' 1 # amixer -c 0 cset name='O005 I007 Switch' 1 .. prompt:: bash # auto # arecord -Dhw:0,14 -c 4 -r 48000 -f S16_LE -d 10 rec.wav .. figure:: /_asset/sw_rity_porting-guide_audio_4dmic.png :align: center :scale: 100% DMIC 4 channels - ALSA command for DMIC 6 channels .. prompt:: bash # auto # amixer -c 0 cset name='O002 I004 Switch' 1 # amixer -c 0 cset name='O003 I005 Switch' 1 # amixer -c 0 cset name='O004 I006 Switch' 1 # amixer -c 0 cset name='O005 I007 Switch' 1 # amixer -c 0 cset name='O006 I008 Switch' 1 # amixer -c 0 cset name='O007 I009 Switch' 1 .. prompt:: bash # auto # arecord -Dhw:0,14 -c 6 -r 48000 -f S16_LE -d 10 rec.wav .. figure:: /_asset/sw_rity_porting-guide_audio_6dmic.png :align: center :scale: 100% DMIC 6 channels - ALSA command for DMIC 8 channels .. prompt:: bash # auto # amixer -c 0 cset name='O002 I004 Switch' 1 # amixer -c 0 cset name='O003 I005 Switch' 1 # amixer -c 0 cset name='O004 I006 Switch' 1 # amixer -c 0 cset name='O005 I007 Switch' 1 # amixer -c 0 cset name='O006 I008 Switch' 1 # amixer -c 0 cset name='O007 I009 Switch' 1 # amixer -c 0 cset name='O008 I010 Switch' 1 # amixer -c 0 cset name='O009 I011 Switch' 1 .. prompt:: bash # auto # arecord -Dhw:0,14 -c 8 -r 48000 -f S16_LE -d 10 rec.wav .. figure:: /_asset/sw_rity_porting-guide_audio_8dmic.png :align: center :scale: 100% DMIC 8 channels DTS Setting ----------- - `mediatek,dmic-iir-on` To remove DC offset generated by external DMIC components, enable infinite impulse response mode. IIR mode is enabled in DMIC by default. If not needed, remove it from the device tree. .. figure:: /_asset/sw_rity_porting-guide_audio_dmic-iir-on.svg :align: center :scale: 20% Enable DMIC infinite impulse response mode - `mediatek,dmic-clk-index` By default, the PDM interface activates DMIC clock signals in a particular sequence based on the number of channels being used. - For 2 channels, only DMIC1_CLK is enabled. - For 4 channels, both DMIC1_CLK and DMIC2_CLK are enabled. - For 6 channels, DMIC1_CLK, DMIC2_CLK, and DMIC3_CLK are enabled. - For 8 channels, all four clock signals from DMIC1_CLK to DMIC4_CLK are enabled. However, if the hardware wiring of the DMICs doesn't follow this default order, users have the flexibility to specify a custom clock enable sequence through the device tree. A property can be added within the device tree to outline the preferred order. The clock indices that are allowed range from 0 to 3, corresponding to DMIC1 through DMIC4. E.g. The sample DTS setting below shows the reordering enable sequence as DMIC1 -> DMIC4 -> DMIC3 -> DMIC2 .. figure:: /_asset/sw_rity_porting-guide_audio_dmic-clk-index.svg :align: center :scale: 20% DMIC clock indices setting - `mediatek,dmic-clk-mono` In `clk-mono` mode, each DMIC component is associated with an individual clock signal. This indicates that each of the two DMIC components is connected to the different interface. .. figure:: /_asset/sw_rity_porting-guide_audio_dmic-clk-mono-mode.png :align: center :scale: 70% DMIC clock mono mode To support `clk-mono` mode, additional configurations must be made within the Device Tree Source file to accurately represent the hardware design and ensure the correct pathways for clock signals are established. .. figure:: /_asset/sw_rity_porting-guide_audio_dmic-clk-mono.svg :align: center :scale: 20% DMIC clock mono mode DTS setting - `mediatek,dmic-two-wire-mode` MT8390/MT8395 typically uses a PDM interface in one-wire mode by default, which means that a single data pin is shared between two digital microphones. In this configuration, one PDM data line is used for both the left and right microphone channels. However, if you are implementing a two-wire mode, where each DMIC has its own dedicated data pin (thus providing separate PDM data lines for each microphone), an additional property needs to be specified in the Device Tree Source file to configure the hardware for this mode. .. figure:: /_asset/sw_rity_porting-guide_audio_dmic-one-wire-mode-pic.png :align: center :scale: 70% DMIC one-wire mode .. figure:: /_asset/sw_rity_porting-guide_audio_dmic-two-wire-mode-pic.png :align: center :scale: 70% DMIC two-wire mode .. figure:: /_asset/sw_rity_porting-guide_audio_dmic-two-wire-mode.svg :align: center :scale: 30% DMIC two-wire mode DTS setting - `mediatek,dmic-clk-phases` The DMIC clock phase setting configures the phase for hardware to latch data. Different phase settings are used to prevent latching data at transition area. In general, using the default phase setting is enough, there is no need to set this property. For the MT8390/MT8395 DMIC interface, there are 8 selectable phases per data pin. You can configure these phase settings using this property in the DMIC node in the DTS file. - For one-wire mode, the default phase settings is <0 4>. This indicates that one microphone will latch data at phase 0, and the other at phase 4. Because two DMICs share one data pin, so each DMIC has only 4 phases to set. .. prompt:: bash # auto mediatek,dmic-clk-phases = <0~3 4~7>; - For two-wire mode, the default phase settings is <0 0>. This means that each microphone will latch data at phase 0. In two-wire mode, each DMIC has 8 phases to set. .. prompt:: bash # auto mediatek,dmic-clk-phases = <0~7 0~7>; Here is an example of how to specify it for a two-wire mode configuration. In this case, DMIC0 will latch data at phase 0, and DMIC1 will latch data at phase 7. .. figure:: /_asset/sw_rity_porting-guide_audio_dmic-clk-phases.svg :align: center :scale: 30% DMIC clock phases DTS setting - `pinmux` To specify the DMIC pinmux settings, you'd likely need to manipulate the pin control subsystem within the DTS file. .. figure:: /_asset/sw_rity_porting-guide_audio_dmic-setting-pinmux.svg :align: center :scale: 30% DMIC pinmux DTS setting Gain Control ------------ - DMIC HW gain introduction .. csv-table:: DMIC HW Gain Introduction :header: "Attribute", "Meaning", "Bit-width", "Default Value", "Max Value", "Notation" :encoding: utf-8 :width: 100% :widths: 20 25 5 20 20 10 "Current gain", "Current gain", "28", ``0x80000`` (0 dB), ``0xFFFFFFF``, "Unsigned" "Target gain", "Target gain", "28", ``0x80000`` (0 dB), ``0xFFFFFFF``, "Unsigned" "Gain down per step", "The multiplier of each step", "20", ``0x7C5E5`` (-0.25 dB), ``0xFFFFF``, "Unsigned" "Gain up per step", "The multiplier of each step", "20", ``0x83BCD`` (+0.25 dB), ``0xFFFFF``, "Unsigned" "Sample per step", "How many samples per step", "8", ``0xC8`` (200), ``0xFF`` (255), "Unsigned" .. figure:: /_asset/sw_rity_porting-guide_audio_dmic-gain-introduction.svg :align: center :scale: 30% DMIC HW gain introduction The following table explains the variables used in DMIC gain control. All gain settings are adjusted based on a reference value, which is 0x80000 representing 0 dB. ======== ==================== Variable Description ======== ==================== Gain_val Gain to set in value Gain_dB Gain to set in dB ======== ==================== **Gain_dB = 20 * log(Gain_val / 0x80000)** **Gain_val = 10 ^ (Gain_dB / 20) * 0x80000 = 10 ^ (Gain_dB / 20) * 524288** - Enable/Disable DMIC hw gain **Enable example** 2 mic on DMIC1: .. prompt:: bash # auto # amixer -c 0 cset name='DMIC1_HW_GAIN_EN' 1 Clk-mono example (one mic is on DMIC1, another is on DMIC2): .. prompt:: bash # auto # amixer -c 0 cset name='DMIC1_HW_GAIN_EN' 1 # amixer -c 0 cset name='DMIC2_HW_GAIN_EN' 1 Reordering example (one mic is on DMIC1, another is on DMIC4): .. prompt:: bash # auto # amixer -c 0 cset name='DMIC1_HW_GAIN_EN' 1 # amixer -c 0 cset name='DMIC4_HW_GAIN_EN' 1 **Disable example** 2 mic on DMIC1: .. prompt:: bash # auto # amixer -c 0 cset name='DMIC1_HW_GAIN_EN' 0 Clk-mono example (one mic is on DMIC1, another is on DMIC2): .. prompt:: bash # auto # amixer -c 0 cset name='DMIC1_HW_GAIN_EN' 0 # amixer -c 0 cset name='DMIC2_HW_GAIN_EN' 0 - Target gain setting E.g. - set: Gain_dB = **10 dB** Gain_val = 10 ^ (10 / 20) * 524288 = 1657944 - set: Gain_dB = **30 dB** Gain_val = 10 ^ (30 / 20) * 524288 = 16579442 - set: Gain_dB = **50 dB** Gain_val = 10 ^ (50 / 20) * 524288 = 165794422 2 mic on DMIC1: .. prompt:: bash # auto # amixer -c 0 cset name='DMIC1_HW_GAIN_TARGET' 16579442 Clk-mono example (one mic is on DMIC1, another is on DMIC2): .. prompt:: bash # auto # amixer -c 0 cset name='DMIC1_HW_GAIN_TARGET' 16579442 # amixer -c 0 cset name='DMIC2_HW_GAIN_TARGET' 16579442 Reordering example (one mic is on DMIC1, another is on DMIC4): .. prompt:: bash # auto # amixer -c 0 cset name='DMIC1_HW_GAIN_TARGET' 16579442 # amixer -c 0 cset name='DMIC4_HW_GAIN_TARGET' 16579442 - Current gain setting The default setting for current gain is 0 dB. 2 mic on DMIC1: .. prompt:: bash # auto # amixer -c 0 cset name='DMIC1_HW_GAIN_CURRENT' 524288 Clk-mono example (one mic is on DMIC1, another is on DMIC2): .. prompt:: bash # auto # amixer -c 0 cset name='DMIC1_HW_GAIN_CURRENT' 524288 # amixer -c 0 cset name='DMIC2_HW_GAIN_CURRENT' 524288 Reordering example (one mic is on DMIC1, another is on DMIC4): .. prompt:: bash # auto # amixer -c 0 cset name='DMIC1_HW_GAIN_CURRENT' 524288 # amixer -c 0 cset name='DMIC4_HW_GAIN_CURRENT' 524288 - Gain up per step setting This setting is used to determine the increase amount of each step in dB. E.g. - set: Gain_dB = **0.25 dB** Gain_val = 10 ^ (0.25 / 20) * 524288 = 539597 2 mic on DMIC1: .. prompt:: bash # auto # amixer -c 0 cset name='DMIC1_HW_GAIN_UP_STEP' 539597 Clk-mono example (one mic is on DMIC1, another is on DMIC2): .. prompt:: bash # auto # amixer -c 0 cset name='DMIC1_HW_GAIN_UP_STEP' 539597 # amixer -c 0 cset name='DMIC2_HW_GAIN_UP_STEP' 539597 Reordering example (one mic is on DMIC1, another is on DMIC4): .. prompt:: bash # auto # amixer -c 0 cset name='DMIC1_HW_GAIN_UP_STEP' 539597 # amixer -c 0 cset name='DMIC4_HW_GAIN_UP_STEP' 539597 - Sample per step setting E.g. fs = 16k, sample_per_step = 200, target_gain = 30 dB, current_gain = 0 dB, gain_up_per_step = 0.25 dB The time to reach target gain from current gain is: (Gain_dB / gain_up_per_step) * sample_per_step / fs => (30/0.25) * 200 / 16000 = 1.5 s 2 mic on DMIC1: .. prompt:: bash # auto # amixer -c 0 cset name='DMIC1_HW_GAIN_SAMPLE_PER_STEP' 200 Clk-mono example (one mic is on DMIC1, another is on DMIC2): .. prompt:: bash # auto # amixer -c 0 cset name='DMIC1_HW_GAIN_SAMPLE_PER_STEP' 200 # amixer -c 0 cset name='DMIC2_HW_GAIN_SAMPLE_PER_STEP' 200 Reordering example (one mic is on DMIC1, another is on DMIC4): .. prompt:: bash # auto # amixer -c 0 cset name='DMIC1_HW_GAIN_SAMPLE_PER_STEP' 200 # amixer -c 0 cset name='DMIC4_HW_GAIN_SAMPLE_PER_STEP' 200 - Constant gain setting Set gain_current gain_target as the same value. E.g. 10 dB gain: .. prompt:: bash # auto # amixer -c 0 cset name='DMIC1_HW_GAIN_TARGET' 1657944 # amixer -c 0 cset name='DMIC1_HW_GAIN_CURRENT' 1657944 -10 dB gain: .. prompt:: bash # auto # amixer -c 0 cset name='DMIC1_HW_GAIN_TARGET' 165794 # amixer -c 0 cset name='DMIC1_HW_GAIN_CURRENT' 165794 .. figure:: /_asset/sw_rity_porting-guide_audio_dmic-gain-constant.svg :align: center :scale: 30% DMIC HW Gain Constant Gain Setting - Fade-in, fade-out setting Set the current gain as 0dB, and change the target gain E.g. 10 dB gain: .. prompt:: bash # auto # amixer -c 0 cset name='DMIC1_HW_GAIN_TARGET' 1657944 # amixer -c 0 cset name='DMIC1_HW_GAIN_CURRENT' 524288 -10 dB gain: .. prompt:: bash # auto # amixer -c 0 cset name='DMIC1_HW_GAIN_TARGET' 165794 # amixer -c 0 cset name='DMIC1_HW_GAIN_CURRENT' 524288 .. figure:: /_asset/sw_rity_porting-guide_audio_dmic-gain-fade.svg :align: center :scale: 30% DMIC HW Gain fade-in - Runtime setting Current gain and change target gain can be set in runtime. E.g. .. prompt:: bash # auto # amixer -c 0 cset name='DMIC1_HW_GAIN_TARGET' 1657944 # amixer -c 0 cset name='DMIC1_HW_GAIN_CURRENT' 1657944 .. prompt:: bash # auto # arecord -Dhw:0,14 -c 2 -r 48000 -f S16_LE -d 10 rec.wav & .. prompt:: bash # auto # amixer -c 0 cset name='DMIC1_HW_GAIN_TARGET' 16579442 # amixer -c 0 cset name='DMIC1_HW_GAIN_CURRENT' 16579442 DMIC gain can't be disabled in runtime, but we can achieve this by setting the current gain and target gain to 524288 (0dB). E.g. .. prompt:: bash # auto # amixer -c 0 cset name='DMIC1_HW_GAIN_TARGET' 1657944 # amixer -c 0 cset name='DMIC1_HW_GAIN_CURRENT' 1657944 .. prompt:: bash # auto # arecord -Dhw:0,14 -c 2 -r 48000 -f S16_LE -d 10 rec.wav & .. prompt:: bash # auto # amixer -c 0 cset name='DMIC1_HW_GAIN_TARGET' 524288 # amixer -c 0 cset name='DMIC1_HW_GAIN_CURRENT' 524288 If you want to integrate an external audio codec into the platform, please refer to :ref:`here `.