From 3a47ef2487eda6e6e053b13ab714b96917f63d2d Mon Sep 17 00:00:00 2001 From: Brent Lu Date: Tue, 25 Jul 2023 22:58:17 +0800 Subject: [PATCH] topology: nhlt: intel: support more device types and directions In current NHLT table the device type of all SSP endpoints are set to BT Sideband(0) instead of SSP Analog Codec(4) and the direction only supports Render(0) and Capture(1). Here we introduce two new quirks from topology to set the device type correctly and support two more directions: Render with loopback(2) and Feedback for render(3) for speakers with echo reference or IV sense feedback. Fixes: https://github.com/alsa-project/alsa-utils/pull/226 Signed-off-by: Brent Lu Signed-off-by: Jaroslav Kysela --- topology/nhlt/intel/ssp-nhlt.c | 9 +++-- topology/nhlt/intel/ssp/ssp-internal.h | 2 ++ topology/nhlt/intel/ssp/ssp-process.c | 46 +++++++++++++++++++++++--- topology/nhlt/intel/ssp/ssp-process.h | 2 +- 4 files changed, 50 insertions(+), 9 deletions(-) diff --git a/topology/nhlt/intel/ssp-nhlt.c b/topology/nhlt/intel/ssp-nhlt.c index f1e4fc3..7a1a013 100644 --- a/topology/nhlt/intel/ssp-nhlt.c +++ b/topology/nhlt/intel/ssp-nhlt.c @@ -456,6 +456,8 @@ int nhlt_ssp_get_ep(struct intel_nhlt_params *nhlt, struct endpoint_descriptor * uint32_t bits_per_sample; uint32_t virtualbus_id; uint32_t formats_count; + uint32_t device_type; + uint32_t direction = dir; uint8_t *ep_target; size_t blob_size; int ret; @@ -471,7 +473,8 @@ int nhlt_ssp_get_ep(struct intel_nhlt_params *nhlt, struct endpoint_descriptor * * vendor_blob sizeof(vendor_blob) */ - ret = ssp_get_params(nhlt, dai_index, &virtualbus_id, &formats_count); + ret = ssp_get_params(nhlt, dai_index, &virtualbus_id, &formats_count, + &device_type, &direction); if (ret < 0) { fprintf(stderr, "nhlt_ssp_get_ep: ssp_get_params failed\n"); return ret; @@ -483,9 +486,9 @@ int nhlt_ssp_get_ep(struct intel_nhlt_params *nhlt, struct endpoint_descriptor * ep.device_id = NHLT_DEVICE_ID_INTEL_I2S_TDM; ep.revision_id = 0; ep.subsystem_id = 0; - ep.device_type = 0; + ep.device_type = device_type; - ep.direction = dir; + ep.direction = direction; /* ssp device index */ ep.virtualbus_id = virtualbus_id; /* ssp config */ diff --git a/topology/nhlt/intel/ssp/ssp-internal.h b/topology/nhlt/intel/ssp/ssp-internal.h index ab6a875..23a8489 100644 --- a/topology/nhlt/intel/ssp/ssp-internal.h +++ b/topology/nhlt/intel/ssp/ssp-internal.h @@ -353,6 +353,8 @@ struct intel_ssp_params { #define SSP_INTEL_QUIRK_PSPSTWFDFD (1 << 4) #define SSP_INTEL_QUIRK_PSPSRWFDFD (1 << 5) #define SSP_INTEL_QUIRK_LBM (1 << 6) +#define SSP_INTEL_QUIRK_BT_SIDEBAND (1 << 7) +#define SSP_INTEL_QUIRK_RENDER_FEEDBACK (1 << 8) #define SSP_INTEL_FRAME_PULSE_WIDTH_MAX 38 #define SSP_INTEL_SLOT_PADDING_MAX 31 diff --git a/topology/nhlt/intel/ssp/ssp-process.c b/topology/nhlt/intel/ssp/ssp-process.c index e5ff26c..237eaec 100644 --- a/topology/nhlt/intel/ssp/ssp-process.c +++ b/topology/nhlt/intel/ssp/ssp-process.c @@ -768,7 +768,7 @@ int ssp_get_dir(struct intel_nhlt_params *nhlt, int dai_index, uint8_t *dir) } int ssp_get_params(struct intel_nhlt_params *nhlt, int dai_index, uint32_t *virtualbus_id, - uint32_t *formats_count) + uint32_t *formats_count, uint32_t *device_type, uint32_t *direction) { struct intel_ssp_params *ssp = (struct intel_ssp_params *)nhlt->ssp_params; @@ -777,6 +777,16 @@ int ssp_get_params(struct intel_nhlt_params *nhlt, int dai_index, uint32_t *virt *virtualbus_id = ssp->ssp_dai_index[dai_index]; *formats_count = ssp->ssp_hw_config_count[dai_index]; + if (ssp->ssp_prm[dai_index].quirks & SSP_INTEL_QUIRK_BT_SIDEBAND) + *device_type = NHLT_DEVICE_TYPE_SSP_BT_SIDEBAND; + else + *device_type = NHLT_DEVICE_TYPE_SSP_ANALOG; + if (ssp->ssp_prm[dai_index].quirks & SSP_INTEL_QUIRK_RENDER_FEEDBACK) { + if (*direction == NHLT_ENDPOINT_DIRECTION_RENDER) + *direction = NHLT_ENDPOINT_DIRECTION_RENDER_WITH_LOOPBACK; + else if (*direction == NHLT_ENDPOINT_DIRECTION_CAPTURE) + *direction = NHLT_ENDPOINT_DIRECTION_FEEDBACK_FOR_RENDER; + } return 0; } @@ -874,6 +884,8 @@ int ssp_set_params(struct intel_nhlt_params *nhlt, const char *dir, int dai_inde int version) { struct intel_ssp_params *ssp = (struct intel_ssp_params *)nhlt->ssp_params; + char delim[] = ","; + char *buf, *token = NULL; if (!ssp) return -EINVAL; @@ -903,10 +915,34 @@ int ssp_set_params(struct intel_nhlt_params *nhlt, const char *dir, int dai_inde ssp->ssp_prm[ssp->ssp_count].tdm_per_slot_padding_flag = 1; else ssp->ssp_prm[ssp->ssp_count].tdm_per_slot_padding_flag = 0; - if (quirks && !strcmp(quirks, "lbm_mode")) - ssp->ssp_prm[ssp->ssp_count].quirks = 64; /* 1 << 6 */ - else - ssp->ssp_prm[ssp->ssp_count].quirks = 0; + + ssp->ssp_prm[ssp->ssp_count].quirks = 0; + + if (quirks) { + buf = strdup(quirks); + if (!buf) + return -ENOMEM; + + token = strtok(buf, delim); + + while (token) { + if (!strcmp(token, "lbm_mode")) + ssp->ssp_prm[ssp->ssp_count].quirks |= SSP_INTEL_QUIRK_LBM; + else if (!strcmp(token, "bt_sideband")) + ssp->ssp_prm[ssp->ssp_count].quirks |= SSP_INTEL_QUIRK_BT_SIDEBAND; + else if (!strcmp(token, "render_feedback")) { + if (!strcmp(dir, "duplex")) + ssp->ssp_prm[ssp->ssp_count].quirks |= SSP_INTEL_QUIRK_RENDER_FEEDBACK; + } else { + fprintf(stderr, "ssp_set_params(): unknown quirk %s\n", token); + return -EINVAL; + } + + token = strtok(NULL, delim); + } + + free(buf); + } /* reset hw config count for this ssp instance */ ssp->ssp_hw_config_count[ssp->ssp_count] = 0; diff --git a/topology/nhlt/intel/ssp/ssp-process.h b/topology/nhlt/intel/ssp/ssp-process.h index 6830fa1..ea80482 100644 --- a/topology/nhlt/intel/ssp/ssp-process.h +++ b/topology/nhlt/intel/ssp/ssp-process.h @@ -55,7 +55,7 @@ int ssp_link_set_params(struct intel_nhlt_params *nhlt, int clock_source); int ssp_calculate(struct intel_nhlt_params *nhlt); /* get spec parameters when building the nhlt endpoint */ int ssp_get_params(struct intel_nhlt_params *nhlt, int dai_index, uint32_t *virtualbus_id, - uint32_t *formats_count); + uint32_t *formats_count, uint32_t *device_type, uint32_t *direction); int ssp_get_hw_params(struct intel_nhlt_params *nhlt, int dai_index, int hw_index, uint32_t *sample_rate, uint16_t *channel_count, uint32_t *bits_per_sample); int ssp_get_dir(struct intel_nhlt_params *nhlt, int dai_index, uint8_t *dir); -- 2.47.1