diff --git a/tools/topology/topology2/README.md b/tools/topology/topology2/README.md index bea7ffcfdcde..15b57abd8143 100644 --- a/tools/topology/topology2/README.md +++ b/tools/topology/topology2/README.md @@ -252,6 +252,31 @@ default ID ranges for the same endpoint types. > `BT_PCM_ID` override variable to set the correct value when BT coexists with a speaker > amplifier (which also uses PCM ID 2 by default). +### Wake-on-voice parameters + +For a CAVS topology with PCH DMIC enabled and `PASSTHROUGH=false`, set +`INCLUDE_WOV=true` to add the DMIC1, KPB, detector, and drain PCM +pipelines. IPC4 targets must also override `KPB_UUID` with the `kpb4` +UUID registered by their firmware. The class default is the IPC3 KPB +UUID so existing IPC3 users are unchanged. + +The detector's module manifest determines its frame and memory settings. +Override these variables together when selecting a detector: + +| Variable | Default | Purpose | +|---|---:|---| +| `WOV_FORMAT` | `s32le` | Pipeline sample format | +| `WOV_PCM_FMT` | `S32_LE` | Drain PCM sample format | +| `WOV_BIT_DEPTH` | 32 | Audio container width | +| `WOV_VALID_BIT_DEPTH` | 32 | Valid sample width | +| `WOV_IBS` | 64 | Detector input frame bytes | +| `WOV_OBS` | 64 | Detector output frame bytes | +| `WOV_IS_PAGES` | 0 | Module instance memory pages | +| `WOV_CONTROL_MAX` | 4096 | Maximum bytes-control payload | + +The `wov_init` bytes control supports runtime TLV reads and writes. Increase +`WOV_CONTROL_MAX` only when a detector accepts a larger configuration. + **Intel HDA PCM IDs:** | Endpoint | Default PCM ID | Override Variable | diff --git a/tools/topology/topology2/cavs-sdw.conf b/tools/topology/topology2/cavs-sdw.conf index 311e0376b333..23fa33880c17 100644 --- a/tools/topology/topology2/cavs-sdw.conf +++ b/tools/topology/topology2/cavs-sdw.conf @@ -35,6 +35,10 @@ + + + + diff --git a/tools/topology/topology2/include/components/kpb.conf b/tools/topology/topology2/include/components/kpb.conf index 03f7989be8ac..ffa73d01f567 100644 --- a/tools/topology/topology2/include/components/kpb.conf +++ b/tools/topology/topology2/include/components/kpb.conf @@ -12,6 +12,12 @@ # # Where N is the unique instance number for the kpb object within the same alsaconf node. +# Keep the IPC3 UUID as the default. IPC4 topologies must select kpb4 by +# overriding KPB_UUID in the top-level topology. +Define { + KPB_UUID "43:84:21:d8:f3:5f:4c:4a:b3:88:6c:fe:07:b9:56:2e" +} + Class.Widget."kpb" { # # Pipeline ID for the kpb object @@ -67,8 +73,7 @@ Class.Widget."kpb" { num_input_audio_formats 1 num_output_audio_formats 1 - #UUID: D8218443-5FF3-4A4C-B388-6CFE07B9562E - uuid "43:84:21:d8:f3:5f:4c:4a:b3:88:6c:fe:07:b9:56:2e" + uuid $KPB_UUID no_pm "true" cpc 720000 num_input_pins 1 diff --git a/tools/topology/topology2/include/components/wov.conf b/tools/topology/topology2/include/components/wov.conf index fccf2066be6e..15148833b235 100644 --- a/tools/topology/topology2/include/components/wov.conf +++ b/tools/topology/topology2/include/components/wov.conf @@ -14,6 +14,10 @@ # # Where N is the unique instance number for the wov object within the same alsaconf node. +Define { + WOV_CONTROL_MAX 4096 +} + Class.Widget."wov" { # # Pipeline ID for the wov object @@ -72,13 +76,14 @@ Class.Widget."wov" { name wov_init access [ tlv_read + tlv_write tlv_callback ] Object.Base.extops."extctl" { get 258 - put 0 + put 258 } - max 4096 + max $WOV_CONTROL_MAX Object.Base.data."1" { IncludeByKey.WOV_UUID { '1f:d5:a8:eb:27:78:b5:47:82:ee:de:6e:77:43:af:67' {bytes "0x53, 0x4f, 0x46, 0x34, 0x02, 0x00, 0x00, 0x00, diff --git a/tools/topology/topology2/include/pipelines/cavs/dai-kpb-be.conf b/tools/topology/topology2/include/pipelines/cavs/dai-kpb-be.conf index 91ca50a62bed..700082d9090b 100644 --- a/tools/topology/topology2/include/pipelines/cavs/dai-kpb-be.conf +++ b/tools/topology/topology2/include/pipelines/cavs/dai-kpb-be.conf @@ -89,14 +89,14 @@ Class.Pipeline."dai-kpb-be" { Object.Base.input_audio_format [ { in_rate 16000 - in_bit_depth 32 - in_valid_bit_depth 32 + in_bit_depth $WOV_BIT_DEPTH + in_valid_bit_depth $WOV_VALID_BIT_DEPTH } { in_rate 16000 in_channels 4 - in_bit_depth 32 - in_valid_bit_depth 32 + in_bit_depth $WOV_BIT_DEPTH + in_valid_bit_depth $WOV_VALID_BIT_DEPTH in_ch_cfg $CHANNEL_CONFIG_3_POINT_1 in_ch_map $CHANNEL_MAP_3_POINT_1 } @@ -105,14 +105,14 @@ Class.Pipeline."dai-kpb-be" { Object.Base.output_audio_format [ { out_rate 16000 - out_bit_depth 32 - out_valid_bit_depth 32 + out_bit_depth $WOV_BIT_DEPTH + out_valid_bit_depth $WOV_VALID_BIT_DEPTH } { out_rate 16000 out_channels 4 - out_bit_depth 32 - out_valid_bit_depth 32 + out_bit_depth $WOV_BIT_DEPTH + out_valid_bit_depth $WOV_VALID_BIT_DEPTH out_ch_cfg $CHANNEL_CONFIG_3_POINT_1 out_ch_map $CHANNEL_MAP_3_POINT_1 } @@ -125,12 +125,8 @@ Class.Pipeline."dai-kpb-be" { } } - Object.Base { - route."1" { - source "dai-copier.DMIC.$index.1" - sink "kpb.$index.1" - } - } + # DAI copier names contain the stream name instead of the pipeline + # index. The instantiating topology must provide the route to KPB. time_domain "timer" dynamic_pipeline 1 diff --git a/tools/topology/topology2/include/pipelines/cavs/wov-detect.conf b/tools/topology/topology2/include/pipelines/cavs/wov-detect.conf index 0f4490525c83..da99f97a6569 100644 --- a/tools/topology/topology2/include/pipelines/cavs/wov-detect.conf +++ b/tools/topology/topology2/include/pipelines/cavs/wov-detect.conf @@ -64,8 +64,8 @@ Class.Pipeline."wov-detect" { in_channels 2 in_ch_map $CHANNEL_MAP_STEREO in_ch_cfg 1 - in_bit_depth 32 - in_valid_bit_depth 32 + in_bit_depth $WOV_BIT_DEPTH + in_valid_bit_depth $WOV_VALID_BIT_DEPTH } ] Object.Base.output_audio_format [ @@ -74,8 +74,8 @@ Class.Pipeline."wov-detect" { out_channels 1 out_ch_map $CHANNEL_MAP_MONO out_ch_cfg 0 - out_bit_depth 32 - out_valid_bit_depth 32 + out_bit_depth $WOV_BIT_DEPTH + out_valid_bit_depth $WOV_VALID_BIT_DEPTH } ] } @@ -89,16 +89,18 @@ Class.Pipeline."wov-detect" { in_channels 1 in_ch_cfg 0 in_ch_map $CHANNEL_MAP_MONO - in_bit_depth 32 - in_valid_bit_depth 32 + in_bit_depth $WOV_BIT_DEPTH + in_valid_bit_depth $WOV_VALID_BIT_DEPTH + ibs $WOV_IBS } ] Object.Base.output_audio_format [ { out_rate 16000 out_channels 1 - out_bit_depth 32 - out_valid_bit_depth 32 + out_bit_depth $WOV_BIT_DEPTH + out_valid_bit_depth $WOV_VALID_BIT_DEPTH + obs $WOV_OBS } ] } diff --git a/tools/topology/topology2/platform/intel/dmic-default.conf b/tools/topology/topology2/platform/intel/dmic-default.conf index 1bb96a45465b..9b2dc3456bf1 100644 --- a/tools/topology/topology2/platform/intel/dmic-default.conf +++ b/tools/topology/topology2/platform/intel/dmic-default.conf @@ -25,15 +25,17 @@ Define { DMIC1_HOST_PIPELINE_ID 18 DMIC1_DAI_PIPELINE_ID 19 WOV_PIPELINE_ID 20 - DMIC1_HOST_PIPELINE_SINK 'copier.host.18.1' - DMIC_WOV_DAI_PIPELINE_SRC 'dai-copier.DMIC.dmic16k.capture' - DMIC_WOV_DAI_PIPELINE_KPB 'kpb.19.1' - WOV_PIPELINE_SINK 'micsel.20.1' - WOV_PIPELINE_VIRTUAL 'virtual.detect_sink' INCLUDE_WOV 'false' # The UUID corresponds to the test detect component WOV_UUID '1f:d5:a8:eb:27:78:b5:47:82:ee:de:6e:77:43:af:67' WOV_CPC '360000' + WOV_FORMAT s32le + WOV_PCM_FMT 'S32_LE' + WOV_BIT_DEPTH 32 + WOV_VALID_BIT_DEPTH 32 + WOV_IBS 64 + WOV_OBS 64 + WOV_IS_PAGES 0 DMIC1_PCM_CAPS 'Passthrough Capture 18' DMIC_CORE_ID 0 PASSTHROUGH "false" diff --git a/tools/topology/topology2/platform/intel/dmic-wov.conf b/tools/topology/topology2/platform/intel/dmic-wov.conf index 0094941e0c74..1a00ad6381a3 100644 --- a/tools/topology/topology2/platform/intel/dmic-wov.conf +++ b/tools/topology/topology2/platform/intel/dmic-wov.conf @@ -1,7 +1,7 @@ Object.Pipeline { host-gateway-capture [ { - format $FORMAT + format $WOV_FORMAT rate 16000 rate_min 16000 rate_max 16000 @@ -9,19 +9,51 @@ Object.Pipeline { Object.Widget.host-copier.1 { stream_name $DMIC1_PCM_CAPS - pcm_id 11 - num_output_audio_formats 2 + pcm_id $DMIC1_PCM_ID + num_input_audio_formats 3 + num_output_audio_formats 3 + Object.Base.input_audio_format [ + { + in_rate 16000 + in_channels 1 + in_ch_cfg $CHANNEL_CONFIG_MONO + in_ch_map $CHANNEL_MAP_MONO + in_bit_depth $WOV_BIT_DEPTH + in_valid_bit_depth $WOV_VALID_BIT_DEPTH + } + { + in_rate 16000 + in_bit_depth $WOV_BIT_DEPTH + in_valid_bit_depth $WOV_VALID_BIT_DEPTH + } + { + in_rate 16000 + in_channels 4 + in_bit_depth $WOV_BIT_DEPTH + in_valid_bit_depth $WOV_VALID_BIT_DEPTH + in_ch_cfg $CHANNEL_CONFIG_3_POINT_1 + in_ch_map $CHANNEL_MAP_3_POINT_1 + } + ] Object.Base.output_audio_format [ { out_rate 16000 - out_bit_depth 32 - out_valid_bit_depth 32 + out_channels 1 + out_ch_cfg $CHANNEL_CONFIG_MONO + out_ch_map $CHANNEL_MAP_MONO + out_bit_depth $WOV_BIT_DEPTH + out_valid_bit_depth $WOV_VALID_BIT_DEPTH + } + { + out_rate 16000 + out_bit_depth $WOV_BIT_DEPTH + out_valid_bit_depth $WOV_VALID_BIT_DEPTH } { out_rate 16000 out_channels 4 - out_bit_depth 32 - out_valid_bit_depth 32 + out_bit_depth $WOV_BIT_DEPTH + out_valid_bit_depth $WOV_VALID_BIT_DEPTH out_ch_cfg $CHANNEL_CONFIG_3_POINT_1 out_ch_map $CHANNEL_MAP_3_POINT_1 } @@ -33,7 +65,7 @@ Object.Pipeline { dai-kpb-be [ { direction "capture" - format $FORMAT + format $WOV_FORMAT rate 16000 rate_min 16000 rate_max 16000 @@ -52,14 +84,14 @@ Object.Pipeline { Object.Base.input_audio_format [ { in_rate 16000 - in_bit_depth 32 - in_valid_bit_depth 32 + in_bit_depth $WOV_BIT_DEPTH + in_valid_bit_depth $WOV_VALID_BIT_DEPTH } { in_rate 16000 in_channels 4 - in_bit_depth 32 - in_valid_bit_depth 32 + in_bit_depth $WOV_BIT_DEPTH + in_valid_bit_depth $WOV_VALID_BIT_DEPTH in_ch_cfg $CHANNEL_CONFIG_3_POINT_1 in_ch_map $CHANNEL_MAP_3_POINT_1 } @@ -68,14 +100,14 @@ Object.Pipeline { Object.Base.output_audio_format [ { out_rate 16000 - out_bit_depth 32 - out_valid_bit_depth 32 + out_bit_depth $WOV_BIT_DEPTH + out_valid_bit_depth $WOV_VALID_BIT_DEPTH } { out_rate 16000 out_channels 4 - out_bit_depth 32 - out_valid_bit_depth 32 + out_bit_depth $WOV_BIT_DEPTH + out_valid_bit_depth $WOV_VALID_BIT_DEPTH out_ch_cfg $CHANNEL_CONFIG_3_POINT_1 out_ch_map $CHANNEL_MAP_3_POINT_1 } @@ -84,10 +116,10 @@ Object.Pipeline { Object.Widget.kpb.1 { Object.Base.output_pin_binding.1 { - output_pin_binding_name $WOV_PIPELINE_SINK + output_pin_binding_name "micsel.$WOV_PIPELINE_ID.1" } Object.Base.output_pin_binding.2 { - output_pin_binding_name $DMIC1_HOST_PIPELINE_SINK + output_pin_binding_name "host-copier.$DMIC1_PCM_ID.capture" } Object.Base.output_pin_binding.3 { output_pin_binding_name "NotConnected" @@ -99,11 +131,12 @@ Object.Pipeline { wov-detect [ { index $WOV_PIPELINE_ID - format s32le + format $WOV_FORMAT channels 2 Object.Widget.wov.1 { uuid $WOV_UUID cpc $WOV_CPC + is_pages $WOV_IS_PAGES } } ] @@ -111,23 +144,27 @@ Object.Pipeline { Object.Base.route [ { - source $DMIC_WOV_DAI_PIPELINE_KPB - sink "host-copier.11.capture" + source "dai-copier.DMIC.$DMIC1_NAME.capture" + sink "kpb.$DMIC1_DAI_PIPELINE_ID.1" + } + { + source "kpb.$DMIC1_DAI_PIPELINE_ID.1" + sink "host-copier.$DMIC1_PCM_ID.capture" } { - source $DMIC_WOV_DAI_PIPELINE_KPB - sink $WOV_PIPELINE_SINK + source "kpb.$DMIC1_DAI_PIPELINE_ID.1" + sink "micsel.$WOV_PIPELINE_ID.1" } { - source $WOV_PIPELINE_VIRTUAL - sink "host-copier.11.capture" + source "virtual.detect_sink" + sink "host-copier.$DMIC1_PCM_ID.capture" } ] Object.PCM.pcm [ { name "DMIC16k" - id 11 + id $DMIC1_PCM_ID direction "capture" capture_compatible_d0i3 true Object.Base.fe_dai.1 { @@ -136,10 +173,10 @@ Object.PCM.pcm [ Object.PCM.pcm_caps.1 { name $DMIC1_PCM_CAPS - # only 32-bit capture supported now - formats 'S32_LE' - channels_min $NUM_DMICS + formats $WOV_PCM_FMT + channels_min 1 channels_max $NUM_DMICS + rates '16000' rate_min 16000 rate_max 16000 }