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 <brent.lu@intel.com>
Signed-off-by: Jaroslav Kysela <perex@perex.cz>
This commit is contained in:
Brent Lu 2023-07-25 22:58:17 +08:00 committed by Jaroslav Kysela
parent 9d058fff27
commit 3a47ef2487
4 changed files with 50 additions and 9 deletions

View file

@ -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 */

View file

@ -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

View file

@ -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;

View file

@ -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);