Saurabh Satija (saurabh.satija@intel.com) just uploaded a new patch set to gerrit, which you can find at https://review.coreboot.org/15023
-gerrit
commit 21b049a404969f9b0d00cf19d75655b043b83b25 Author: Saurabh Satija saurabh.satija@intel.com Date: Thu Jun 23 14:46:27 2016 -0700
lib/nhlt: Add common NHLT audio for Intel platforms
The use of a NHLT table is required to make audio work on the Intel SoCs employing the internal DSP. The table describes the audio endpoints (render vs capture) along with their supported formats. These formats are not only dependent on the audio peripheral but also hardware interfaces. As such each format has an associated blob of DSP settings to make the peripheral work. Lastly, each of these settings are provided by Intel and need to be generated for each device's hardware connection plus mode/format it supports. This patch does not include the DSP setting blobs.
Change-Id: I3c75d3537288c47d29e8949ca253ea8c5c1a387d Signed-off-by: Saurabh Satija saurabh.satija@intel.com --- src/include/nhlt.h | 45 +++++++++++++++++++++++++++ src/lib/nhlt.c | 91 ++++++++++++++++++++++++++++++++++++++++++++++++++++-- 2 files changed, 134 insertions(+), 2 deletions(-)
diff --git a/src/include/nhlt.h b/src/include/nhlt.h index f0b3b6f..20d20ed 100644 --- a/src/include/nhlt.h +++ b/src/include/nhlt.h @@ -23,6 +23,51 @@ struct nhlt; struct nhlt_endpoint; struct nhlt_format; struct nhlt_format_config; +struct nhlt_tdm_config; + +/* + * NHLT device types. These values are used with nhlt_soc_add_endpoint(). + */ +enum { + AUDIO_DEV_I2S, + AUDIO_DEV_DMIC, + AUDIO_DEV_BT, +}; + +/* + * Returns corresponding nhlt link type based on hardware link number. + * Hardware link number is the SSP port number on which the particular + * is present, which is mainboard specfic. + * nhlt_soc_get_link_type() is SoC specific. + */ +int nhlt_soc_get_link_type(int hwlink, int soc_devtype); + +/* + * Add a dmic array composed of the provided number of channels. + * Returns 0 on success, < 0 on error. + */ +int nhlt_add_dmic_array(struct nhlt *nhlt, int num_channels, + const struct nhlt_format_config *dmic_ch_config, int num_fmt); + +/* + * Add audio codec on provided SSP link. Return 0 on succes, < 0 on error. + * + * The same DSP firmware settings can be used for both the capture and render + * endpoints in some cases. Most of the smart amps use different DSP firmware + * settings for capture and render endpoints. + * + * render_cfg, capture_cfg: These are the audio codec configuration defined + * in mainboard souce code. + * cfg_size: This is the number of configurations defined in codec config. + * Each configuration is added as an endpoint. + * tdm_config: This is also board specific and defined in mainboard.c + * hwlink: This is the SSP hardware port number. + * direction: This can be Render only, Capture only or Bi-directional. + */ +int nhlt_add_codec_on_ssp(struct nhlt *nhlt, int hwlink, + const struct nhlt_format_config *render_cfg, int r_num_fmt, + const struct nhlt_format_config *capture_cfg, int c_num_fmt, + const struct nhlt_tdm_config *tdm_config, size_t tdm_size);
/* * Non HD Audio ACPI support. This table is typically used for Intel Smart diff --git a/src/lib/nhlt.c b/src/lib/nhlt.c index d9107ee..3883b32 100644 --- a/src/lib/nhlt.c +++ b/src/lib/nhlt.c @@ -15,9 +15,12 @@
#include <arch/acpi.h> #include <cbfs.h> +#include <cbmem.h> #include <commonlib/endian.h> #include <console/console.h> #include <nhlt.h> +#include <soc/nvs.h> +#include <soc/nhlt.h> #include <stdlib.h> #include <string.h>
@@ -47,8 +50,7 @@ struct nhlt *nhlt_init(void) }
struct nhlt_endpoint *nhlt_add_endpoint(struct nhlt *nhlt, int link_type, - int device_type, int dir, - uint16_t vid, uint16_t did) + int device_type, int dir, uint16_t vid, uint16_t did) { struct nhlt_endpoint *endp;
@@ -503,3 +505,88 @@ uintptr_t nhlt_soc_serialize_oem_overrides(struct nhlt *nhlt, return nhlt_serialize_oem_overrides(nhlt, acpi_addr, oem_id, oem_table_id); } + +int nhlt_add_dmic_array(struct nhlt *nhlt, int num_channels, + const struct nhlt_format_config *dmic_ch_cfg, int num_fmt) +{ + struct nhlt_endpoint *endp; + struct nhlt_dmic_array_config mic_config; + + 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) { + case 2: + mic_config.array_type = NHLT_MIC_ARRAY_2CH_SMALL; + break; + case 4: + mic_config.array_type = NHLT_MIC_ARRAY_4CH_L_SHAPED; + break; + } + + if (nhlt_endpoint_append_config(endp, &mic_config, sizeof(mic_config))) + return -1; + + return nhlt_endpoint_add_formats(endp, dmic_ch_cfg, num_fmt); +} + +int nhlt_add_codec_on_ssp(struct nhlt *nhlt, int hwlink, + const struct nhlt_format_config *render_cfg, int r_num_fmt, + const struct nhlt_format_config *capture_cfg, int c_num_fmt, + const struct nhlt_tdm_config *tdm_config, size_t tdm_size) +{ + struct nhlt_endpoint *endp; + + /* For Bi-directional amplifiers, both capture and render + * configuratoins are needed. + */ + if (render_cfg == NULL && capture_cfg == NULL) + return -1; + + /* Render Endpoint */ + if (render_cfg != NULL) { + endp = nhlt_soc_add_endpoint(nhlt, hwlink, AUDIO_DEV_I2S, + NHLT_DIR_RENDER); + if (endp == NULL) + return -1; + + if (tdm_config != NULL) { + if (nhlt_endpoint_append_config(endp, tdm_config, + tdm_size)) + return -1; + } + + if (nhlt_endpoint_add_formats(endp, render_cfg, r_num_fmt)) + return -1; + } + + /* Capture Endpoint */ + if (capture_cfg != NULL) { + endp = nhlt_soc_add_endpoint(nhlt, hwlink, AUDIO_DEV_I2S, + NHLT_DIR_CAPTURE); + if (endp == NULL) + return -1; + + if (tdm_config != NULL) { + if (nhlt_endpoint_append_config(endp, tdm_config, + tdm_size)) + return -1; + } + + if (nhlt_endpoint_add_formats(endp, capture_cfg, c_num_fmt)) + return -1; + } + + nhlt_next_instance(nhlt, NHLT_LINK_SSP); + + return 0; +}