diff options
Diffstat (limited to 'src/include')
-rw-r--r-- | src/include/nhlt.h | 284 |
1 files changed, 284 insertions, 0 deletions
diff --git a/src/include/nhlt.h b/src/include/nhlt.h new file mode 100644 index 0000000000..ca1669381c --- /dev/null +++ b/src/include/nhlt.h @@ -0,0 +1,284 @@ +/* + * This file is part of the coreboot project. + * + * Copyright 2015 Google, Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#ifndef _NHLT_H_ +#define _NHLT_H_ + +#include <stdint.h> +#include <stddef.h> + +struct nhlt; +struct nhlt_endpoint; +struct nhlt_format; +struct nhlt_format_config; + +/* + * Non HD Audio ACPI support. This table is typically used for Intel Smart + * Sound Technology DSP. It provides a way to encode opaque settings in + * the ACPI tables. + * + * While the structure fields of the NHLT structs are exposed below + * the SoC/chipset code should be the only other user manipulating the + * fields directly aside from the library itself. + * + * The NHLT table consists of endpoints which in turn contain different + * supporting stream formats. Each endpoint may contain a device specific + * configuration payload as well as each stream format. + * + * Most code should use the SoC variants of the functions because + * there is required logic needed to be performed by the SoC. The SoC + * code should be abstracting the inner details of these functions that + * specically apply to NHLT objects for that SoC. + * + * An example sequence: + * + * nhlt = nhlt_init() + * ep = nhlt_soc_add_endpoint() + * nhlt_endpoint_append_config(ep) + * nhlt_endpoint_add_formats(ep) + * nhlt_soc_serialize() + */ + +/* Obtain an nhlt object for adding endpoints. Returns NULL on error. */ +struct nhlt *nhlt_init(void); + +/* Return the size of the NHLT table including APCI header. */ +size_t nhlt_current_size(struct nhlt *nhlt); + +/* + * Add endpoint to NHLT object. Returns NULL on error. + * + * Note that the SoC variant uses SoC-specifc types for the hardware interface + * and device types. This is to allow the SoC code to validate its particular + * device support for specific hardware interfaces. + * + * The more generic nhlt_add_endpoint() is called by the SoC code to provide + * the specific assumptions/uses for NHLT for that platform. All fields + * are the NHLT enumerations found within this header file. + */ +struct nhlt_endpoint *nhlt_add_endpoint(struct nhlt *nhlt, int link_type, + int device_type, int dir, + uint16_t vid, uint16_t did); +struct nhlt_endpoint *nhlt_soc_add_endpoint(struct nhlt *nhlt, int soc_hwintf, + int soc_devtype, int dir); + +/* + * Append blob of configuration to the endpoint proper. Returns 0 on + * success, < 0 on error. A copy of the configuration is made so any + * resources pointed to by config can be freed after the call. + */ +int nhlt_endpoint_append_config(struct nhlt_endpoint *endpoint, + const void *config, size_t config_sz); + +/* Add a format type to the provided endpoint. Returns NULL on error. */ +struct nhlt_format *nhlt_add_format(struct nhlt_endpoint *endpoint, + int num_channels, + int sample_freq_khz, + int container_bits_per_sample, + int valid_bits_per_sample, + uint32_t speaker_mask); + +/* + * Append blob of configuration to the format proper. Returns 0 on + * success, < 0 on error. A copy of the configuration is made so any + * resources pointed to by config can be freed after the call. + */ +int nhlt_format_append_config(struct nhlt_format *format, const void *config, + size_t config_sz); + +/* + * Add num_formats described by formats to the endpoint. This function + * effectively wraps nhlt_add_format() and nhlt_format_config() using the + * data found in each nhlt_format_config object. Returns 0 on success, < 0 + * on error. + */ +int nhlt_endpoint_add_formats(struct nhlt_endpoint *endpoint, + const struct nhlt_format_config *formats, + size_t num_formats); + +/* + * Increment the instance id for a given link type. This function is + * used for marking a device being completely added to the NHLT object. + * Subsequent endpoints added to the nhlt object with the same link type + * will use incremented instance id. + */ +void nhlt_next_instance(struct nhlt *nhlt, int link_type); + +/* + * Serialize NHLT object to ACPI table. Take in the beginning address of where + * the table will reside and return the address of the next ACPI table. On + * error 0 will be returned. The NHLT object is no longer valid after this + * function is called. + */ +uintptr_t nhlt_serialize(struct nhlt *nhlt, uintptr_t acpi_addr); + +/* + * While very similar to nhlt_serialize() the SoC specific function allows + * the chipset to perform any needed accounting work such as updating ACPI + * field references for the serialized structure. + */ +uintptr_t nhlt_soc_serialize(struct nhlt *nhlt, uintptr_t acpi_addr); + +/* Link and device types. */ +enum { + NHLT_LINK_HDA, + NHLT_LINK_DSP, + NHLT_LINK_PDM, + NHLT_LINK_SSP, + NHLT_MAX_LINK_TYPES, +}; + +enum { + NHLT_SSP_DEV_BT, /* Bluetooth */ + NHLT_SSP_DEV_MODEM, + NHLT_SSP_DEV_FM, + NHLT_SSP_DEV_RESERVED, + NHLT_SSP_DEV_I2S = 4, +}; + +enum { + NHLT_PDM_DEV, +}; + +/* Endpoint direction. */ +enum { + NHLT_DIR_RENDER, + NHLT_DIR_CAPTURE, + NHLT_DIR_BIDIRECTIONAL, +}; + +/* Channel Mask for an endpoint. While they are prefixed with 'SPEAKER' the + * channel masks are also used for capture devices. */ +enum { + SPEAKER_FRONT_LEFT = 1 << 0, + SPEAKER_FRONT_RIGHT = 1 << 1, + SPEAKER_FRONT_CENTER = 1 << 2, + SPEAKER_LOW_FREQUENCY = 1 << 3, + SPEAKER_BACK_LEFT = 1 << 4, + SPEAKER_BACK_RIGHT = 1 << 5, + SPEAKER_FRONT_LEFT_OF_CENTER = 1 << 6, + SPEAKER_FRONT_RIGHT_OF_CENTER = 1 << 7, + SPEAKER_BACK_CENTER = 1 << 8, + SPEAKER_SIDE_LEFT = 1 << 9, + SPEAKER_SIDE_RIGHT = 1 << 10, + SPEAKER_TOP_CENTER = 1 << 11, + SPEAKER_TOP_FRONT_LEFT = 1 << 12, + SPEAKER_TOP_FRONT_CENTER = 1 << 13, + SPEAKER_TOP_FRONT_RIGHT = 1 << 14, + SPEAKER_TOP_BACK_LEFT = 1 << 15, + SPEAKER_TOP_BACK_CENTER = 1 << 16, + SPEAKER_TOP_BACK_RIGHT = 1 << 17, +}; + + +/* Supporting structures. Only SoC/chipset and the library code directly should + * be manipulating these structures. */ +struct sub_format { + uint32_t data1; + uint16_t data2; + uint16_t data3; + uint8_t data4[8]; +}; + +struct nhlt_specific_config { + uint32_t size; + void *capabilities; +}; + +struct nhlt_waveform { + uint16_t tag; + uint16_t num_channels; + uint32_t samples_per_second; + uint32_t bytes_per_second; + uint16_t block_align; + uint16_t bits_per_sample; + uint16_t extra_size; + uint16_t valid_bits_per_sample; + uint32_t channel_mask; + struct sub_format sub_format; +}; + +struct nhlt_format { + struct nhlt_waveform waveform; + struct nhlt_specific_config config; +}; + +/* + * This struct is used by nhlt_endpoint_add_formats() for easily adding + * waveform formats with associated settings file. + */ +struct nhlt_format_config { + int num_channels; + int sample_freq_khz; + int container_bits_per_sample; + int valid_bits_per_sample; + uint32_t speaker_mask; + const char *settings_file; +}; + +/* Arbitrary max number of formats per endpoint. */ +#define MAX_FORMATS 2 +struct nhlt_endpoint { + uint32_t length; + uint8_t link_type; + uint8_t instance_id; + uint16_t vendor_id; + uint16_t device_id; + uint16_t revision_id; + uint32_t subsystem_id; + uint8_t device_type; + uint8_t direction; + uint8_t virtual_bus_id; + struct nhlt_specific_config config; + uint8_t num_formats; + struct nhlt_format formats[MAX_FORMATS]; +}; + +#define MAX_ENDPOINTS 8 +struct nhlt { + uint8_t num_endpoints; + struct nhlt_endpoint endpoints[MAX_ENDPOINTS]; + uint8_t current_instance_id[NHLT_MAX_LINK_TYPES]; +}; + +struct nhlt_tdm_config { + uint8_t virtual_slot; + uint8_t config_type; +}; + +enum { + NHLT_TDM_BASIC, + NHLT_TDM_MIC_ARRAY, +}; + +struct nhlt_dmic_array_config { + struct nhlt_tdm_config tdm_config; + uint8_t array_type; +}; + +/* + * Microphone array definitions may be found here: + * https://msdn.microsoft.com/en-us/library/windows/hardware/dn613960%28v=vs.85%29.aspx + */ +enum { + NHLT_MIC_ARRAY_2CH_SMALL = 0xa, + NHLT_MIC_ARRAY_2CH_BIG = 0xb, + NHLT_MIC_ARRAY_4CH_1ST_GEOM = 0xc, + NHLT_MIC_ARRAY_4CH_L_SHAPED = 0xd, + NHLT_MIC_ARRAY_4CH_2ND_GEOM = 0xe, + NHLT_MIC_ARRAY_VENDOR_DEFINED = 0xf, +}; + +#endif |