Skip to content

Commit

Permalink
topology: pre-processor: add NHLT blob generation
Browse files Browse the repository at this point in the history
Add a mechanism to generate Intel specific nhlt blob from topology2 dai
definitions. This is done by by using pre-preprocessor's auto attribute
mechanism.

With every dai parsed an internal vendor blob is created. Internal blobs
are kept in pre-processor's private data field. Currently only DMIC and
SSP dais are implemented. When topology parsing has finished a NHLT acpi
table with endpoints is created and added to the manifest.

NHTL and vendor specific DMIC and SSP processing files are added under
intel subdir in topology.

Signed-off-by: Jaska Uimonen <[email protected]>
  • Loading branch information
Jaska Uimonen committed Sep 29, 2021
1 parent 90763f9 commit 6305878
Show file tree
Hide file tree
Showing 24 changed files with 6,478 additions and 5 deletions.
20 changes: 17 additions & 3 deletions topology/Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,23 @@ endif
rst2man $< > $@

alsatplg_SOURCES = topology.c pre-processor.c pre-process-class.c pre-process-object.c \
pre-process-dapm.c pre-process-dai.c

noinst_HEADERS = topology.h pre-processor.h
pre-process-dapm.c pre-process-dai.c intel/nhlt.c intel/dmic/dmic-nhlt.c \
intel/ssp/ssp-nhlt.c

noinst_HEADERS = topology.h pre-processor.h \
intel/nhlt.h intel/nhlt-internal.h \
intel/dmic/dmic-nhlt.h intel/dmic/dmic-macros.h \
intel/dmic/filters/pdm_decim_fir.h \
intel/dmic/filters/pdm_decim_int32_02_4375_5100_010_095.h \
intel/dmic/filters/pdm_decim_int32_08_4156_5301_010_090.h \
intel/dmic/filters/pdm_decim_int32_03_4375_5100_010_095.h \
intel/dmic/filters/pdm_decim_int32_10_4156_5345_010_090.h \
intel/dmic/filters/pdm_decim_int32_04_4318_5100_010_095.h \
intel/dmic/filters/pdm_decim_int32_12_4156_5345_010_090.h \
intel/dmic/filters/pdm_decim_int32_05_4325_5100_010_095.h \
intel/dmic/filters/pdm_decim_int32_02_4323_5100_010_095.h \
intel/dmic/filters/pdm_decim_int32_06_4172_5100_010_095.h \
intel/ssp/ssp-nhlt.h intel/ssp/ssp-macros.h

AM_CPPFLAGS = \
-Wall -I$(top_srcdir)/include
Expand Down
241 changes: 241 additions & 0 deletions topology/intel/dmic/dmic-macros.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,241 @@
/*
Copyright(c) 2021 Intel Corporation
All rights reserved.
This program is free software; you can redistribute it and/or modify
it under the terms of version 2 of the GNU General Public License as
published by the Free Software Foundation.
This program is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
The full GNU General Public License is included in this distribution
in the file called LICENSE.GPL.
*/

#ifndef __DMIC_MACROS_H
#define __DMIC_MACROS_H

/* Get max and min signed integer values for N bits word length */
#define INT_MAX(N) ((int64_t)((1ULL << ((N) - 1)) - 1))

/* Fractional multiplication with shift and round
* Note that the parameters px and py must be cast to (int64_t) if other type.
*/
#define Q_MULTSR_32X32(px, py, qx, qy, qp) \
((((px) * (py) >> ((qx) + (qy) - (qp) - 1)) + 1) >> 1)

/* Convert a float number to fractional Qnx.ny format. Note that there is no
* check for nx+ny number of bits to fit the word length of int. The parameter
* qy must be 31 or less.
*/
#define Q_CONVERT_FLOAT(f, qy) \
((int32_t)(((const double)f) * ((int64_t)1 << (const int)qy) + 0.5))

/* Saturation */
#define SATP_INT32(x) (((x) > INT32_MAX) ? INT32_MAX : (x))

#define EXP_FIXED_INPUT_QY 27
#define EXP_FIXED_OUTPUT_QY 20
#define DB2LIN_FIXED_INPUT_QY 24
#define DB2LIN_FIXED_OUTPUT_QY 20

#define DMIC_MAX_MODES 50
#define DMIC_FIR_PIPELINE_OVERHEAD 5
#define DMIC_UNMUTE_RAMP_US 1000

/* Parameters used in modes computation */
#define DMIC_HW_BITS_CIC 26
#define DMIC_HW_BITS_FIR_COEF 20
#define DMIC_HW_BITS_FIR_GAIN 20
#define DMIC_HW_BITS_FIR_INPUT 22
#define DMIC_HW_BITS_FIR_OUTPUT 24
#define DMIC_HW_BITS_FIR_INTERNAL 26
#define DMIC_HW_BITS_GAIN_OUTPUT 22
#define DMIC_HW_CIC_SHIFT_MIN -8
#define DMIC_HW_CIC_SHIFT_MAX 4
#define DMIC_HW_FIR_SHIFT_MIN 0
#define DMIC_HW_FIR_SHIFT_MAX 8
#define DMIC_HW_CIC_DECIM_MIN 5
#define DMIC_HW_CIC_DECIM_MAX 31 /* Note: Limited by BITS_CIC */
#define DMIC_HW_FIR_DECIM_MIN 2
#define DMIC_HW_FIR_DECIM_MAX 20 /* Note: Practical upper limit */
#define DMIC_HW_SENS_Q28 Q_CONVERT_FLOAT(1.0, 28) /* Q1.28 */
#define DMIC_HW_PDM_CLK_MIN 100000 /* Note: Practical min value */
#define DMIC_HW_DUTY_MIN 20 /* Note: Practical min value */
#define DMIC_HW_DUTY_MAX 80 /* Note: Practical max value */

/* OUTCONTROL0 bits */
#define OUTCONTROL0_TIE_BIT BIT(27)
#define OUTCONTROL0_SIP_BIT BIT(26)
#define OUTCONTROL0_FINIT_BIT BIT(25)
#define OUTCONTROL0_FCI_BIT BIT(24)
#define OUTCONTROL0_TIE(x) SET_BIT(27, x)
#define OUTCONTROL0_SIP(x) SET_BIT(26, x)
#define OUTCONTROL0_FINIT(x) SET_BIT(25, x)
#define OUTCONTROL0_FCI(x) SET_BIT(24, x)
#define OUTCONTROL0_BFTH(x) SET_BITS(23, 20, x)
#define OUTCONTROL0_OF(x) SET_BITS(19, 18, x)
#define OUTCONTROL0_TH(x) SET_BITS(5, 0, x)

/* OUTCONTROL1 bits */
#define OUTCONTROL1_TIE_BIT BIT(27)
#define OUTCONTROL1_SIP_BIT BIT(26)
#define OUTCONTROL1_FINIT_BIT BIT(25)
#define OUTCONTROL1_FCI_BIT BIT(24)
#define OUTCONTROL1_TIE(x) SET_BIT(27, x)
#define OUTCONTROL1_SIP(x) SET_BIT(26, x)
#define OUTCONTROL1_FINIT(x) SET_BIT(25, x)
#define OUTCONTROL1_FCI(x) SET_BIT(24, x)
#define OUTCONTROL1_BFTH(x) SET_BITS(23, 20, x)
#define OUTCONTROL1_OF(x) SET_BITS(19, 18, x)
#define OUTCONTROL1_TH(x) SET_BITS(5, 0, x)

/* OUTCONTROL0 bits ver1*/
#define OUTCONTROL0_IPM_VER1(x) SET_BITS(17, 16, x)
/* OUTCONTROL1 bits ver1 */
#define OUTCONTROL1_IPM_VER1(x) SET_BITS(17, 16, x)

/* OUTCONTROL0 bits */
#define OUTCONTROL0_IPM_VER2(x) SET_BITS(17, 15, x)
#define OUTCONTROL0_IPM_SOURCE_1(x) SET_BITS(14, 13, x)
#define OUTCONTROL0_IPM_SOURCE_2(x) SET_BITS(12, 11, x)
#define OUTCONTROL0_IPM_SOURCE_3(x) SET_BITS(10, 9, x)
#define OUTCONTROL0_IPM_SOURCE_4(x) SET_BITS(8, 7, x)

/* OUTCONTROL1 bits */
#define OUTCONTROL1_IPM_VER2(x) SET_BITS(17, 15, x)
#define OUTCONTROL1_IPM_SOURCE_1(x) SET_BITS(14, 13, x)
#define OUTCONTROL1_IPM_SOURCE_2(x) SET_BITS(12, 11, x)
#define OUTCONTROL1_IPM_SOURCE_3(x) SET_BITS(10, 9, x)
#define OUTCONTROL1_IPM_SOURCE_4(x) SET_BITS(8, 7, x)

#define OUTCONTROLX_IPM_NUMSOURCES 4

/* CIC_CONTROL bits */
#define CIC_CONTROL_SOFT_RESET_BIT BIT(16)
#define CIC_CONTROL_CIC_START_B_BIT BIT(15)
#define CIC_CONTROL_CIC_START_A_BIT BIT(14)
#define CIC_CONTROL_MIC_B_POLARITY_BIT BIT(3)
#define CIC_CONTROL_MIC_A_POLARITY_BIT BIT(2)
#define CIC_CONTROL_MIC_MUTE_BIT BIT(1)
#define CIC_CONTROL_STEREO_MODE_BIT BIT(0)

#define CIC_CONTROL_SOFT_RESET(x) SET_BIT(16, x)
#define CIC_CONTROL_CIC_START_B(x) SET_BIT(15, x)
#define CIC_CONTROL_CIC_START_A(x) SET_BIT(14, x)
#define CIC_CONTROL_MIC_B_POLARITY(x) SET_BIT(3, x)
#define CIC_CONTROL_MIC_A_POLARITY(x) SET_BIT(2, x)
#define CIC_CONTROL_MIC_MUTE(x) SET_BIT(1, x)
#define CIC_CONTROL_STEREO_MODE(x) SET_BIT(0, x)

/* CIC_CONFIG bits */
#define CIC_CONFIG_CIC_SHIFT(x) SET_BITS(27, 24, x)
#define CIC_CONFIG_COMB_COUNT(x) SET_BITS(15, 8, x)

/* CIC_CONFIG masks */
#define CIC_CONFIG_CIC_SHIFT_MASK MASK(27, 24)
#define CIC_CONFIG_COMB_COUNT_MASK MASK(15, 8)

/* MIC_CONTROL bits */
#define MIC_CONTROL_PDM_EN_B_BIT BIT(1)
#define MIC_CONTROL_PDM_EN_A_BIT BIT(0)
#define MIC_CONTROL_PDM_CLKDIV(x) SET_BITS(15, 8, x)
#define MIC_CONTROL_PDM_SKEW(x) SET_BITS(7, 4, x)
#define MIC_CONTROL_CLK_EDGE(x) SET_BIT(3, x)
#define MIC_CONTROL_PDM_EN_B(x) SET_BIT(1, x)
#define MIC_CONTROL_PDM_EN_A(x) SET_BIT(0, x)

/* MIC_CONTROL masks */
#define MIC_CONTROL_PDM_CLKDIV_MASK MASK(15, 8)

/* FIR_CONTROL_A bits */
#define FIR_CONTROL_A_START_BIT BIT(7)
#define FIR_CONTROL_A_ARRAY_START_EN_BIT BIT(6)
#define FIR_CONTROL_A_MUTE_BIT BIT(1)
#define FIR_CONTROL_A_START(x) SET_BIT(7, x)
#define FIR_CONTROL_A_ARRAY_START_EN(x) SET_BIT(6, x)
#define FIR_CONTROL_A_DCCOMP(x) SET_BIT(4, x)
#define FIR_CONTROL_A_MUTE(x) SET_BIT(1, x)
#define FIR_CONTROL_A_STEREO(x) SET_BIT(0, x)

/* FIR_CONFIG_A bits */
#define FIR_CONFIG_A_FIR_DECIMATION(x) SET_BITS(20, 16, x)
#define FIR_CONFIG_A_FIR_SHIFT(x) SET_BITS(11, 8, x)
#define FIR_CONFIG_A_FIR_LENGTH(x) SET_BITS(7, 0, x)

/* DC offset compensation time constants */
#define DCCOMP_TC0 0
#define DCCOMP_TC1 1
#define DCCOMP_TC2 2
#define DCCOMP_TC3 3
#define DCCOMP_TC4 4
#define DCCOMP_TC5 5
#define DCCOMP_TC6 6
#define DCCOMP_TC7 7

/* DC_OFFSET_LEFT_A bits */
#define DC_OFFSET_LEFT_A_DC_OFFS(x) SET_BITS(21, 0, x)

/* DC_OFFSET_RIGHT_A bits */
#define DC_OFFSET_RIGHT_A_DC_OFFS(x) SET_BITS(21, 0, x)

/* OUT_GAIN_LEFT_A bits */
#define OUT_GAIN_LEFT_A_GAIN(x) SET_BITS(19, 0, x)

/* OUT_GAIN_RIGHT_A bits */
#define OUT_GAIN_RIGHT_A_GAIN(x) SET_BITS(19, 0, x)

/* FIR_CONTROL_B bits */
#define FIR_CONTROL_B_START_BIT BIT(7)
#define FIR_CONTROL_B_ARRAY_START_EN_BIT BIT(6)
#define FIR_CONTROL_B_MUTE_BIT BIT(1)
#define FIR_CONTROL_B_START(x) SET_BIT(7, x)
#define FIR_CONTROL_B_ARRAY_START_EN(x) SET_BIT(6, x)
#define FIR_CONTROL_B_DCCOMP(x) SET_BIT(4, x)
#define FIR_CONTROL_B_MUTE(x) SET_BIT(1, x)
#define FIR_CONTROL_B_STEREO(x) SET_BIT(0, x)

/* FIR_CONFIG_B bits */
#define FIR_CONFIG_B_FIR_DECIMATION(x) SET_BITS(20, 16, x)
#define FIR_CONFIG_B_FIR_SHIFT(x) SET_BITS(11, 8, x)
#define FIR_CONFIG_B_FIR_LENGTH(x) SET_BITS(7, 0, x)

/* DC_OFFSET_LEFT_B bits */
#define DC_OFFSET_LEFT_B_DC_OFFS(x) SET_BITS(21, 0, x)

/* DC_OFFSET_RIGHT_B bits */
#define DC_OFFSET_RIGHT_B_DC_OFFS(x) SET_BITS(21, 0, x)

/* OUT_GAIN_LEFT_B bits */
#define OUT_GAIN_LEFT_B_GAIN(x) SET_BITS(19, 0, x)

/* OUT_GAIN_RIGHT_B bits */
#define OUT_GAIN_RIGHT_B_GAIN(x) SET_BITS(19, 0, x)

/* FIR coefficients */
#define FIR_COEF_A(x) SET_BITS(19, 0, x)
#define FIR_COEF_B(x) SET_BITS(19, 0, x)

/* Minimum OSR is always applied for 48 kHz and less sample rates */
#define DMIC_MIN_OSR 50

/* These are used as guideline for configuring > 48 kHz sample rates. The
* minimum OSR can be relaxed down to 40 (use 3.84 MHz clock for 96 kHz).
*/
#define DMIC_HIGH_RATE_MIN_FS 64000
#define DMIC_HIGH_RATE_OSR_MIN 40

/* Used for scaling FIR coefficients for HW */
#define DMIC_HW_FIR_COEF_MAX ((1 << (DMIC_HW_BITS_FIR_COEF - 1)) - 1)
#define DMIC_HW_FIR_COEF_Q (DMIC_HW_BITS_FIR_COEF - 1)

/* Internal precision in gains computation, e.g. Q4.28 in int32_t */
#define DMIC_FIR_SCALE_Q 28

#endif /* __DMIC_MACROS_H */
Loading

0 comments on commit 6305878

Please sign in to comment.