Skip to content

Commit

Permalink
topology: nhlt: intel: support more device types and directions
Browse files Browse the repository at this point in the history
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: #226
Signed-off-by: Brent Lu <brent.lu@intel.com>
Signed-off-by: Jaroslav Kysela <perex@perex.cz>
  • Loading branch information
brentlu authored and perexg committed Aug 1, 2023
1 parent 9d058ff commit 3a47ef2
Show file tree
Hide file tree
Showing 4 changed files with 50 additions and 9 deletions.
9 changes: 6 additions & 3 deletions topology/nhlt/intel/ssp-nhlt.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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;
Expand All @@ -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 */
Expand Down
2 changes: 2 additions & 0 deletions topology/nhlt/intel/ssp/ssp-internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
46 changes: 41 additions & 5 deletions topology/nhlt/intel/ssp/ssp-process.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand All @@ -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;
}
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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;
Expand Down
2 changes: 1 addition & 1 deletion topology/nhlt/intel/ssp/ssp-process.h
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down

0 comments on commit 3a47ef2

Please sign in to comment.