mirror of
https://github.com/alsa-project/alsa-utils
synced 2024-12-23 04:26:30 +01:00
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:
parent
9d058fff27
commit
3a47ef2487
4 changed files with 50 additions and 9 deletions
|
@ -456,6 +456,8 @@ int nhlt_ssp_get_ep(struct intel_nhlt_params *nhlt, struct endpoint_descriptor *
|
||||||
uint32_t bits_per_sample;
|
uint32_t bits_per_sample;
|
||||||
uint32_t virtualbus_id;
|
uint32_t virtualbus_id;
|
||||||
uint32_t formats_count;
|
uint32_t formats_count;
|
||||||
|
uint32_t device_type;
|
||||||
|
uint32_t direction = dir;
|
||||||
uint8_t *ep_target;
|
uint8_t *ep_target;
|
||||||
size_t blob_size;
|
size_t blob_size;
|
||||||
int ret;
|
int ret;
|
||||||
|
@ -471,7 +473,8 @@ int nhlt_ssp_get_ep(struct intel_nhlt_params *nhlt, struct endpoint_descriptor *
|
||||||
* vendor_blob sizeof(vendor_blob)
|
* 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) {
|
if (ret < 0) {
|
||||||
fprintf(stderr, "nhlt_ssp_get_ep: ssp_get_params failed\n");
|
fprintf(stderr, "nhlt_ssp_get_ep: ssp_get_params failed\n");
|
||||||
return ret;
|
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.device_id = NHLT_DEVICE_ID_INTEL_I2S_TDM;
|
||||||
ep.revision_id = 0;
|
ep.revision_id = 0;
|
||||||
ep.subsystem_id = 0;
|
ep.subsystem_id = 0;
|
||||||
ep.device_type = 0;
|
ep.device_type = device_type;
|
||||||
|
|
||||||
ep.direction = dir;
|
ep.direction = direction;
|
||||||
/* ssp device index */
|
/* ssp device index */
|
||||||
ep.virtualbus_id = virtualbus_id;
|
ep.virtualbus_id = virtualbus_id;
|
||||||
/* ssp config */
|
/* ssp config */
|
||||||
|
|
|
@ -353,6 +353,8 @@ struct intel_ssp_params {
|
||||||
#define SSP_INTEL_QUIRK_PSPSTWFDFD (1 << 4)
|
#define SSP_INTEL_QUIRK_PSPSTWFDFD (1 << 4)
|
||||||
#define SSP_INTEL_QUIRK_PSPSRWFDFD (1 << 5)
|
#define SSP_INTEL_QUIRK_PSPSRWFDFD (1 << 5)
|
||||||
#define SSP_INTEL_QUIRK_LBM (1 << 6)
|
#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_FRAME_PULSE_WIDTH_MAX 38
|
||||||
#define SSP_INTEL_SLOT_PADDING_MAX 31
|
#define SSP_INTEL_SLOT_PADDING_MAX 31
|
||||||
|
|
|
@ -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,
|
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;
|
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];
|
*virtualbus_id = ssp->ssp_dai_index[dai_index];
|
||||||
*formats_count = ssp->ssp_hw_config_count[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;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -874,6 +884,8 @@ int ssp_set_params(struct intel_nhlt_params *nhlt, const char *dir, int dai_inde
|
||||||
int version)
|
int version)
|
||||||
{
|
{
|
||||||
struct intel_ssp_params *ssp = (struct intel_ssp_params *)nhlt->ssp_params;
|
struct intel_ssp_params *ssp = (struct intel_ssp_params *)nhlt->ssp_params;
|
||||||
|
char delim[] = ",";
|
||||||
|
char *buf, *token = NULL;
|
||||||
|
|
||||||
if (!ssp)
|
if (!ssp)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
@ -903,11 +915,35 @@ 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;
|
ssp->ssp_prm[ssp->ssp_count].tdm_per_slot_padding_flag = 1;
|
||||||
else
|
else
|
||||||
ssp->ssp_prm[ssp->ssp_count].tdm_per_slot_padding_flag = 0;
|
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 */
|
/* reset hw config count for this ssp instance */
|
||||||
ssp->ssp_hw_config_count[ssp->ssp_count] = 0;
|
ssp->ssp_hw_config_count[ssp->ssp_count] = 0;
|
||||||
|
|
||||||
|
|
|
@ -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);
|
int ssp_calculate(struct intel_nhlt_params *nhlt);
|
||||||
/* get spec parameters when building the nhlt endpoint */
|
/* get spec parameters when building the nhlt endpoint */
|
||||||
int ssp_get_params(struct intel_nhlt_params *nhlt, int dai_index, uint32_t *virtualbus_id,
|
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,
|
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);
|
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);
|
int ssp_get_dir(struct intel_nhlt_params *nhlt, int dai_index, uint8_t *dir);
|
||||||
|
|
Loading…
Reference in a new issue