soc/intel/skylake: refactor nhlt support

Utilize the new NHLT helper functions by driving the NHLT
endpoints through data descriptors.

Change-Id: I80838214d3615b83d4939ec2d96a4fd7050d5920
Signed-off-by: Aaron Durbin <adurbin@chromium.org>
Reviewed-on: https://review.coreboot.org/15488
Tested-by: build bot (Jenkins)
Reviewed-by: Furquan Shaikh <furquan@google.com>
This commit is contained in:
Aaron Durbin 2016-06-28 15:00:30 -05:00
parent 5e0a9c7436
commit e9657bc8dc
6 changed files with 138 additions and 196 deletions

View File

@ -18,9 +18,14 @@
#include <nhlt.h> #include <nhlt.h>
#define NHLT_VID 0x8086
#define NHLT_DID_DMIC 0xae20
#define NHLT_DID_BT 0xae30
#define NHLT_DID_SSP 0xae34
/* /*
* Skylake NHLT device and hardware link types. These values are to be used * Skylake NHLT link types. These values are to be used for the hwlink
* with nhlt_soc_add_endpoint(). * fields in the functions below to specify which link a device is on.
*/ */
enum { enum {
@ -30,12 +35,6 @@ enum {
AUDIO_LINK_DMIC, AUDIO_LINK_DMIC,
}; };
enum {
AUDIO_DEV_I2S,
AUDIO_DEV_DMIC,
AUDIO_DEV_BT,
};
/* /*
* Add a dmic array composed of the provided number of channels. The skylake * Add a dmic array composed of the provided number of channels. The skylake
* SoC currently only supports dmic arrays on the dmic signals. Either 2 * SoC currently only supports dmic arrays on the dmic signals. Either 2

View File

@ -14,9 +14,8 @@
*/ */
#include <soc/nhlt.h> #include <soc/nhlt.h>
#include <string.h>
static const struct nhlt_format_config dmic_2ch_cfg[] = { static const struct nhlt_format_config dmic_2ch_formats[] = {
/* 48 KHz 16-bits per sample. */ /* 48 KHz 16-bits per sample. */
{ {
.num_channels = 2, .num_channels = 2,
@ -37,7 +36,28 @@ static const struct nhlt_format_config dmic_2ch_cfg[] = {
}, },
}; };
static const struct nhlt_format_config dmic_4ch_cfg[] = { static const struct nhlt_dmic_array_config dmic_2ch_mic_config = {
.tdm_config = {
.config_type = NHLT_TDM_MIC_ARRAY,
},
.array_type = NHLT_MIC_ARRAY_2CH_SMALL,
};
static const struct nhlt_endp_descriptor dmic_2ch_descriptors[] = {
{
.link = NHLT_LINK_PDM,
.device = NHLT_PDM_DEV,
.direction = NHLT_DIR_CAPTURE,
.vid = NHLT_VID,
.did = NHLT_DID_DMIC,
.cfg = &dmic_2ch_mic_config,
.cfg_size = sizeof(dmic_2ch_mic_config),
.formats = dmic_2ch_formats,
.num_formats = ARRAY_SIZE(dmic_2ch_formats),
},
};
static const struct nhlt_format_config dmic_4ch_formats[] = {
/* 48 KHz 16-bits per sample. */ /* 48 KHz 16-bits per sample. */
{ {
.num_channels = 4, .num_channels = 4,
@ -60,42 +80,37 @@ static const struct nhlt_format_config dmic_4ch_cfg[] = {
}, },
}; };
static const struct nhlt_dmic_array_config dmic_4ch_mic_config = {
.tdm_config = {
.config_type = NHLT_TDM_MIC_ARRAY,
},
.array_type = NHLT_MIC_ARRAY_4CH_L_SHAPED,
};
static const struct nhlt_endp_descriptor dmic_4ch_descriptors[] = {
{
.link = NHLT_LINK_PDM,
.device = NHLT_PDM_DEV,
.direction = NHLT_DIR_CAPTURE,
.vid = NHLT_VID,
.did = NHLT_DID_DMIC,
.cfg = &dmic_4ch_mic_config,
.cfg_size = sizeof(dmic_4ch_mic_config),
.formats = dmic_4ch_formats,
.num_formats = ARRAY_SIZE(dmic_4ch_formats),
},
};
int nhlt_soc_add_dmic_array(struct nhlt *nhlt, int num_channels) int nhlt_soc_add_dmic_array(struct nhlt *nhlt, int num_channels)
{ {
struct nhlt_endpoint *endp;
struct nhlt_dmic_array_config mic_config;
const struct nhlt_format_config *formats;
size_t num_formats;
if (num_channels != 2 && num_channels != 4)
return -1;
endp = nhlt_soc_add_endpoint(nhlt, AUDIO_LINK_DMIC, AUDIO_DEV_DMIC,
NHLT_DIR_CAPTURE);
if (endp == NULL)
return -1;
memset(&mic_config, 0, sizeof(mic_config));
mic_config.tdm_config.config_type = NHLT_TDM_MIC_ARRAY;
switch (num_channels) { switch (num_channels) {
case 2: case 2:
formats = dmic_2ch_cfg; return nhlt_add_endpoints(nhlt, dmic_2ch_descriptors,
num_formats = ARRAY_SIZE(dmic_2ch_cfg); ARRAY_SIZE(dmic_2ch_descriptors));
mic_config.array_type = NHLT_MIC_ARRAY_2CH_SMALL;
break;
case 4: case 4:
formats = dmic_4ch_cfg; return nhlt_add_endpoints(nhlt, dmic_4ch_descriptors,
num_formats = ARRAY_SIZE(dmic_4ch_cfg); ARRAY_SIZE(dmic_4ch_descriptors));
mic_config.array_type = NHLT_MIC_ARRAY_4CH_L_SHAPED;
break;
default: default:
return -1; return -1;
} }
if (nhlt_endpoint_append_config(endp, &mic_config, sizeof(mic_config)))
return -1;
return nhlt_endpoint_add_formats(endp, formats, num_formats);
} }

View File

@ -15,7 +15,7 @@
#include <soc/nhlt.h> #include <soc/nhlt.h>
static const struct nhlt_format_config max98357_render_cfg[] = { static const struct nhlt_format_config max98357_render_formats[] = {
/* 48 KHz 24-bits per sample. */ /* 48 KHz 24-bits per sample. */
{ {
.num_channels = 2, .num_channels = 2,
@ -27,22 +27,21 @@ static const struct nhlt_format_config max98357_render_cfg[] = {
}, },
}; };
static const struct nhlt_endp_descriptor max98357_descriptors[] = {
{
.link = NHLT_LINK_SSP,
.device = NHLT_SSP_DEV_I2S,
.direction = NHLT_DIR_RENDER,
.vid = NHLT_VID,
.did = NHLT_DID_SSP,
.formats = max98357_render_formats,
.num_formats = ARRAY_SIZE(max98357_render_formats),
},
};
int nhlt_soc_add_max98357(struct nhlt *nhlt, int hwlink) int nhlt_soc_add_max98357(struct nhlt *nhlt, int hwlink)
{ {
struct nhlt_endpoint *endp; /* Virtual bus id of SSP links are the hardware port ids proper. */
return nhlt_add_ssp_endpoints(nhlt, hwlink, max98357_descriptors,
/* Render Endpoint */ ARRAY_SIZE(max98357_descriptors));
endp = nhlt_soc_add_endpoint(nhlt, hwlink, AUDIO_DEV_I2S,
NHLT_DIR_RENDER);
if (endp == NULL)
return -1;
if (nhlt_endpoint_add_formats(endp, max98357_render_cfg,
ARRAY_SIZE(max98357_render_cfg)))
return -1;
nhlt_next_instance(nhlt, NHLT_LINK_SSP);
return 0;
} }

View File

@ -17,7 +17,7 @@
/* The same DSP firmware settings are used for both the capture and /* The same DSP firmware settings are used for both the capture and
* render endpoints. */ * render endpoints. */
static const struct nhlt_format_config nau88l25_cfg[] = { static const struct nhlt_format_config nau88l25_formats[] = {
/* 48 KHz 24-bits per sample. */ /* 48 KHz 24-bits per sample. */
{ {
.num_channels = 2, .num_channels = 2,
@ -29,45 +29,43 @@ static const struct nhlt_format_config nau88l25_cfg[] = {
}, },
}; };
/* The nau88l25 just has headphones and a mic. Both the capture and render
* endpoints occupy the same virtual slot. */
static const struct nhlt_tdm_config tdm_config = {
.virtual_slot = 0,
.config_type = NHLT_TDM_BASIC,
};
static const struct nhlt_endp_descriptor nau88l25_descriptors[] = {
/* Render Endpoint */
{
.link = NHLT_LINK_SSP,
.device = NHLT_SSP_DEV_I2S,
.direction = NHLT_DIR_RENDER,
.vid = NHLT_VID,
.did = NHLT_DID_SSP,
.cfg = &tdm_config,
.cfg_size = sizeof(tdm_config),
.formats = nau88l25_formats,
.num_formats = ARRAY_SIZE(nau88l25_formats),
},
/* Capture Endpoint */
{
.link = NHLT_LINK_SSP,
.device = NHLT_SSP_DEV_I2S,
.direction = NHLT_DIR_CAPTURE,
.vid = NHLT_VID,
.did = NHLT_DID_SSP,
.cfg = &tdm_config,
.cfg_size = sizeof(tdm_config),
.formats = nau88l25_formats,
.num_formats = ARRAY_SIZE(nau88l25_formats),
},
};
int nhlt_soc_add_nau88l25(struct nhlt *nhlt, int hwlink) int nhlt_soc_add_nau88l25(struct nhlt *nhlt, int hwlink)
{ {
struct nhlt_endpoint *endp; /* Virtual bus id of SSP links are the hardware port ids proper. */
/* The nau88l25 just has headphones and a mic. Both the capture and return nhlt_add_ssp_endpoints(nhlt, hwlink, nau88l25_descriptors,
* render endpoints occupy the same virtual slot. */ ARRAY_SIZE(nau88l25_descriptors));
struct nhlt_tdm_config tdm_config = {
.virtual_slot = 0,
.config_type = NHLT_TDM_BASIC,
};
const void *fmt_cfg = nau88l25_cfg;
size_t fmt_sz = ARRAY_SIZE(nau88l25_cfg);
/* Render Endpoint */
endp = nhlt_soc_add_endpoint(nhlt, hwlink, AUDIO_DEV_I2S,
NHLT_DIR_RENDER);
if (endp == NULL)
return -1;
if (nhlt_endpoint_append_config(endp, &tdm_config, sizeof(tdm_config)))
return -1;
if (nhlt_endpoint_add_formats(endp, fmt_cfg, fmt_sz))
return -1;
/* Capture Endpoint */
endp = nhlt_soc_add_endpoint(nhlt, hwlink, AUDIO_DEV_I2S,
NHLT_DIR_CAPTURE);
if (endp == NULL)
return -1;
if (nhlt_endpoint_append_config(endp, &tdm_config, sizeof(tdm_config)))
return -1;
if (nhlt_endpoint_add_formats(endp, fmt_cfg, fmt_sz))
return -1;
nhlt_next_instance(nhlt, NHLT_LINK_SSP);
return 0;
} }

View File

@ -14,76 +14,8 @@
*/ */
#include <cbmem.h> #include <cbmem.h>
#include <nhlt.h>
#include <soc/acpi.h> #include <soc/acpi.h>
#include <soc/nhlt.h>
#define NHLT_VID 0x8086
#define NHLT_DID_DMIC 0xae20
#define NHLT_DID_BT 0xae30
#define NHLT_DID_SSP 0xae34
struct nhlt_endpoint *nhlt_soc_add_endpoint(struct nhlt *nhlt, int soc_hwintf,
int soc_devtype, int dir)
{
int nhlt_link_type;
int nhlt_dev_type;
uint16_t did;
struct nhlt_endpoint *endp;
/* Check link type and device type. */
switch (soc_hwintf) {
case AUDIO_LINK_SSP0:
case AUDIO_LINK_SSP1:
/* Only I2S devices on SSP0 and SSP1. */
if (soc_devtype != AUDIO_DEV_I2S)
return NULL;
nhlt_link_type = NHLT_LINK_SSP;
break;
case AUDIO_LINK_SSP2:
/* Only Bluetooth devices on SSP2. */
if (soc_devtype != AUDIO_DEV_BT)
return NULL;
nhlt_link_type = NHLT_LINK_SSP;
break;
case AUDIO_LINK_DMIC:
/* Only DMIC devices on DMIC links. */
if (soc_devtype != AUDIO_DEV_DMIC)
return NULL;
nhlt_link_type = NHLT_LINK_PDM;
break;
default:
return NULL;
}
switch (soc_devtype) {
case AUDIO_DEV_I2S:
nhlt_dev_type = NHLT_SSP_DEV_I2S;
did = NHLT_DID_SSP;
break;
case AUDIO_DEV_DMIC:
nhlt_dev_type = NHLT_PDM_DEV;
did = NHLT_DID_DMIC;
break;
case AUDIO_DEV_BT:
nhlt_dev_type = NHLT_SSP_DEV_BT;
did = NHLT_DID_BT;
break;
default:
return NULL;
}
endp = nhlt_add_endpoint(nhlt, nhlt_link_type, nhlt_dev_type, dir,
NHLT_VID, did);
if (endp == NULL)
return NULL;
/* Virtual bus id of SSP links are the hardware port ids proper. */
if (nhlt_link_type == NHLT_LINK_SSP)
endp->virtual_bus_id = soc_hwintf;
return endp;
}
uintptr_t nhlt_soc_serialize(struct nhlt *nhlt, uintptr_t acpi_addr) uintptr_t nhlt_soc_serialize(struct nhlt *nhlt, uintptr_t acpi_addr)
{ {

View File

@ -15,7 +15,7 @@
#include <soc/nhlt.h> #include <soc/nhlt.h>
static const struct nhlt_format_config ssm4567_render_cfg[] = { static const struct nhlt_format_config ssm4567_render_formats[] = {
/* 48 KHz 24-bits per sample. */ /* 48 KHz 24-bits per sample. */
{ {
.num_channels = 2, .num_channels = 2,
@ -28,7 +28,7 @@ static const struct nhlt_format_config ssm4567_render_cfg[] = {
}; };
/* Capture Blob used for IV feedback for Speaker Protection Algorithm */ /* Capture Blob used for IV feedback for Speaker Protection Algorithm */
static const struct nhlt_format_config ssm4567_capture_cfg[] = { static const struct nhlt_format_config ssm4567_capture_formats[] = {
/* 48 KHz 32-bits per sample. */ /* 48 KHz 32-bits per sample. */
{ {
.num_channels = 4, .num_channels = 4,
@ -39,33 +39,32 @@ static const struct nhlt_format_config ssm4567_capture_cfg[] = {
}, },
}; };
static const struct nhlt_endp_descriptor ssm4567_descriptors[] = {
/* Render Endpoint */
{
.link = NHLT_LINK_SSP,
.device = NHLT_SSP_DEV_I2S,
.direction = NHLT_DIR_RENDER,
.vid = NHLT_VID,
.did = NHLT_DID_SSP,
.formats = ssm4567_render_formats,
.num_formats = ARRAY_SIZE(ssm4567_render_formats),
},
/* Capture Endpoint */
{
.link = NHLT_LINK_SSP,
.device = NHLT_SSP_DEV_I2S,
.direction = NHLT_DIR_CAPTURE,
.vid = NHLT_VID,
.did = NHLT_DID_SSP,
.formats = ssm4567_capture_formats,
.num_formats = ARRAY_SIZE(ssm4567_capture_formats),
},
};
int nhlt_soc_add_ssm4567(struct nhlt *nhlt, int hwlink) int nhlt_soc_add_ssm4567(struct nhlt *nhlt, int hwlink)
{ {
struct nhlt_endpoint *endp; /* Virtual bus id of SSP links are the hardware port ids proper. */
return nhlt_add_ssp_endpoints(nhlt, hwlink, ssm4567_descriptors,
/* Render Endpoint */ ARRAY_SIZE(ssm4567_descriptors));
endp = nhlt_soc_add_endpoint(nhlt, hwlink, AUDIO_DEV_I2S,
NHLT_DIR_RENDER);
if (endp == NULL)
return -1;
if (nhlt_endpoint_add_formats(endp, ssm4567_render_cfg,
ARRAY_SIZE(ssm4567_render_cfg)))
return -1;
/* Capture Endpoint for IV Feedback */
endp = nhlt_soc_add_endpoint(nhlt, hwlink, AUDIO_DEV_I2S,
NHLT_DIR_CAPTURE);
if (endp == NULL)
return -1;
if (nhlt_endpoint_add_formats(endp, ssm4567_capture_cfg,
ARRAY_SIZE(ssm4567_capture_cfg)))
return -1;
nhlt_next_instance(nhlt, NHLT_LINK_SSP);
return 0;
} }