1 /* SPDX-License-Identifier: GPL-2.0-only */ 2 3 #ifndef _NHLT_H_ 4 #define _NHLT_H_ 5 6 #include <stdint.h> 7 #include <stddef.h> 8 9 struct nhlt; 10 struct nhlt_endpoint; 11 struct nhlt_format; 12 struct nhlt_format_config; 13 14 /* 15 * Non HD Audio ACPI support. This table is typically used for Intel Smart 16 * Sound Technology DSP. It provides a way to encode opaque settings in 17 * the ACPI tables. 18 * 19 * While the structure fields of the NHLT structs are exposed below 20 * the SoC/chipset code should be the only other user manipulating the 21 * fields directly aside from the library itself. 22 * 23 * The NHLT table consists of endpoints which in turn contain different 24 * supporting stream formats. Each endpoint may contain a device specific 25 * configuration payload as well as each stream format. 26 * 27 * Most code should use the SoC variants of the functions because 28 * there is required logic needed to be performed by the SoC. The SoC 29 * code should be abstracting the inner details of these functions that 30 * specifically apply to NHLT objects for that SoC. 31 * 32 * An example sequence: 33 * 34 * nhlt = nhlt_init() 35 * ep = nhlt_add_endpoint() 36 * nhlt_endpoint_append_config(ep) 37 * nhlt_endpoint_add_formats(ep) 38 * nhlt_soc_serialize() 39 */ 40 41 /* Obtain an nhlt object for adding endpoints. Returns NULL on error. */ 42 struct nhlt *nhlt_init(void); 43 44 /* Return the size of the NHLT table including ACPI header. */ 45 size_t nhlt_current_size(struct nhlt *nhlt); 46 47 /* 48 * Helper functions for adding NHLT devices utilizing an nhlt_endp_descriptor 49 * to drive the logic. 50 */ 51 52 struct nhlt_endp_descriptor { 53 /* NHLT endpoint types. */ 54 int link; 55 int device; 56 int direction; 57 uint16_t vid; 58 uint16_t did; 59 /* Optional endpoint specific configuration data. */ 60 const void *cfg; 61 size_t cfg_size; 62 /* Formats supported for endpoint. */ 63 const struct nhlt_format_config *formats; 64 size_t num_formats; 65 }; 66 67 /* 68 * Add the number of endpoints described by each descriptor. The virtual bus 69 * id for each descriptor is the default value of 0. 70 * Returns < 0 on error, 0 on success. 71 */ 72 int nhlt_add_endpoints(struct nhlt *nhlt, 73 const struct nhlt_endp_descriptor *epds, 74 size_t num_epds); 75 76 /* 77 * Add the number of endpoints associated with a single NHLT SSP instance id. 78 * Each endpoint described in the endpoint descriptor array uses the provided 79 * virtual bus id. Returns < 0 on error, 0 on success. 80 */ 81 int nhlt_add_ssp_endpoints(struct nhlt *nhlt, int virtual_bus_id, 82 const struct nhlt_endp_descriptor *epds, size_t num_epds); 83 84 /* 85 * Add endpoint to NHLT object. Returns NULL on error. 86 * 87 * generic nhlt_add_endpoint() is called by the SoC code to provide 88 * the specific assumptions/uses for NHLT for that platform. All fields 89 * are the NHLT enumerations found within this header file. 90 */ 91 struct nhlt_endpoint *nhlt_add_endpoint(struct nhlt *nhlt, int link_type, 92 int device_type, int dir, 93 uint16_t vid, uint16_t did); 94 95 /* 96 * Append blob of configuration to the endpoint proper. Returns 0 on 97 * success, < 0 on error. A copy of the configuration is made so any 98 * resources pointed to by config can be freed after the call. 99 */ 100 int nhlt_endpoint_append_config(struct nhlt_endpoint *endpoint, 101 const void *config, size_t config_sz); 102 103 /* Add a format type to the provided endpoint. Returns NULL on error. */ 104 struct nhlt_format *nhlt_add_format(struct nhlt_endpoint *endpoint, 105 int num_channels, 106 int sample_freq_khz, 107 int container_bits_per_sample, 108 int valid_bits_per_sample, 109 uint32_t speaker_mask); 110 111 /* 112 * Append blob of configuration to the format proper. Returns 0 on 113 * success, < 0 on error. A copy of the configuration is made so any 114 * resources pointed to by config can be freed after the call. 115 */ 116 int nhlt_format_append_config(struct nhlt_format *format, const void *config, 117 size_t config_sz); 118 119 /* 120 * Add num_formats described by formats to the endpoint. This function 121 * effectively wraps nhlt_add_format() and nhlt_format_config() using the 122 * data found in each nhlt_format_config object. Returns 0 on success, < 0 123 * on error. 124 */ 125 int nhlt_endpoint_add_formats(struct nhlt_endpoint *endpoint, 126 const struct nhlt_format_config *formats, 127 size_t num_formats); 128 129 /* 130 * Increment the instance id for a given link type. This function is 131 * used for marking a device being completely added to the NHLT object. 132 * Subsequent endpoints added to the nhlt object with the same link type 133 * will use incremented instance id. 134 */ 135 void nhlt_next_instance(struct nhlt *nhlt, int link_type); 136 137 /* 138 * Serialize NHLT object to ACPI table. Take in the beginning address of where 139 * the table will reside and return the address of the next ACPI table. On 140 * error 0 will be returned. The NHLT object is no longer valid after this 141 * function is called. 142 */ 143 uintptr_t nhlt_serialize(struct nhlt *nhlt, uintptr_t acpi_addr); 144 145 /* 146 * Serialize NHLT object to ACPI table. Take in the beginning address of where 147 * the table will reside oem_id and oem_table_id and return the address of the 148 * next ACPI table. On error 0 will be returned. The NHLT object is no longer 149 * valid after this function is called. 150 */ 151 uintptr_t nhlt_serialize_oem_overrides(struct nhlt *nhlt, uintptr_t acpi_addr, 152 const char *oem_id, const char *oem_table_id, 153 uint32_t oem_revision); 154 155 /* 156 * While very similar to nhlt_serialize() the SoC specific function allows 157 * the chipset to perform any needed accounting work such as updating ACPI 158 * field references for the serialized structure. 159 */ 160 uintptr_t nhlt_soc_serialize(struct nhlt *nhlt, uintptr_t acpi_addr); 161 162 /* 163 * While very similar to nhlt_serialize_oem_overrides() the SoC specific 164 * function allows the chipset to perform any needed accounting work such 165 * as updating ACPI field references for the serialized structure. 166 */ 167 uintptr_t nhlt_soc_serialize_oem_overrides(struct nhlt *nhlt, 168 uintptr_t acpi_addr, const char *oem_id, const char *oem_table_id, 169 uint32_t oem_revision); 170 171 /* Link and device types. */ 172 enum { 173 NHLT_LINK_HDA, 174 NHLT_LINK_DSP, 175 NHLT_LINK_PDM, 176 NHLT_LINK_SSP, 177 NHLT_MAX_LINK_TYPES, 178 }; 179 180 enum { 181 NHLT_SSP_DEV_BT, /* Bluetooth */ 182 NHLT_SSP_DEV_MODEM, 183 NHLT_SSP_DEV_FM, 184 NHLT_SSP_DEV_RESERVED, 185 NHLT_SSP_DEV_I2S = 4, 186 }; 187 188 enum { 189 NHLT_PDM_DEV, 190 NHLT_PDM_DEV_CAVS15, // NHLT_PDM_DEV on cAVS1.5 (KBL) based platforms 191 }; 192 193 /* Endpoint direction. */ 194 enum { 195 NHLT_DIR_RENDER, 196 NHLT_DIR_CAPTURE, 197 NHLT_DIR_BIDIRECTIONAL, 198 }; 199 200 /* Channel Mask for an endpoint. While they are prefixed with 'SPEAKER' the 201 * channel masks are also used for capture devices. */ 202 enum { 203 SPEAKER_FRONT_LEFT = 1 << 0, 204 SPEAKER_FRONT_RIGHT = 1 << 1, 205 SPEAKER_FRONT_CENTER = 1 << 2, 206 SPEAKER_LOW_FREQUENCY = 1 << 3, 207 SPEAKER_BACK_LEFT = 1 << 4, 208 SPEAKER_BACK_RIGHT = 1 << 5, 209 SPEAKER_FRONT_LEFT_OF_CENTER = 1 << 6, 210 SPEAKER_FRONT_RIGHT_OF_CENTER = 1 << 7, 211 SPEAKER_BACK_CENTER = 1 << 8, 212 SPEAKER_SIDE_LEFT = 1 << 9, 213 SPEAKER_SIDE_RIGHT = 1 << 10, 214 SPEAKER_TOP_CENTER = 1 << 11, 215 SPEAKER_TOP_FRONT_LEFT = 1 << 12, 216 SPEAKER_TOP_FRONT_CENTER = 1 << 13, 217 SPEAKER_TOP_FRONT_RIGHT = 1 << 14, 218 SPEAKER_TOP_BACK_LEFT = 1 << 15, 219 SPEAKER_TOP_BACK_CENTER = 1 << 16, 220 SPEAKER_TOP_BACK_RIGHT = 1 << 17, 221 }; 222 223 /* Supporting structures. Only SoC/chipset and the library code directly should 224 * be manipulating these structures. */ 225 struct sub_format { 226 uint32_t data1; 227 uint16_t data2; 228 uint16_t data3; 229 uint8_t data4[8]; 230 }; 231 232 struct nhlt_specific_config { 233 uint32_t size; 234 void *capabilities; 235 }; 236 237 struct nhlt_waveform { 238 uint16_t tag; 239 uint16_t num_channels; 240 uint32_t samples_per_second; 241 uint32_t bytes_per_second; 242 uint16_t block_align; 243 uint16_t bits_per_sample; 244 uint16_t extra_size; 245 uint16_t valid_bits_per_sample; 246 uint32_t channel_mask; 247 struct sub_format sub_format; 248 }; 249 250 struct nhlt_format { 251 struct nhlt_waveform waveform; 252 struct nhlt_specific_config config; 253 }; 254 255 /* 256 * This struct is used by nhlt_endpoint_add_formats() for easily adding 257 * waveform formats with associated settings file. 258 */ 259 struct nhlt_format_config { 260 int num_channels; 261 int sample_freq_khz; 262 int container_bits_per_sample; 263 int valid_bits_per_sample; 264 uint32_t speaker_mask; 265 const char *settings_file; 266 }; 267 268 /* Arbitrary max number of formats per endpoint. */ 269 #define MAX_FORMATS 2 270 struct nhlt_endpoint { 271 uint32_t length; 272 uint8_t link_type; 273 uint8_t instance_id; 274 uint16_t vendor_id; 275 uint16_t device_id; 276 uint16_t revision_id; 277 uint32_t subsystem_id; 278 uint8_t device_type; 279 uint8_t direction; 280 uint8_t virtual_bus_id; 281 struct nhlt_specific_config config; 282 uint8_t num_formats; 283 struct nhlt_format formats[MAX_FORMATS]; 284 }; 285 286 #define MAX_ENDPOINTS 8 287 struct nhlt { 288 uint32_t subsystem_id; 289 uint8_t num_endpoints; 290 struct nhlt_endpoint endpoints[MAX_ENDPOINTS]; 291 uint8_t current_instance_id[NHLT_MAX_LINK_TYPES]; 292 }; 293 294 struct nhlt_tdm_config { 295 uint8_t virtual_slot; 296 uint8_t config_type; 297 }; 298 299 enum { 300 NHLT_TDM_BASIC, 301 NHLT_TDM_MIC_ARRAY, 302 NHLT_TDM_RENDER_WITH_LOOPBACK, 303 NHLT_TDM_RENDER_FEEDBACK, 304 NHLT_TDM_MULTI_MODE, 305 NHLT_TDM_MULTI_MODE_MIC_ARRAY = NHLT_TDM_MULTI_MODE | NHLT_TDM_MIC_ARRAY 306 }; 307 308 struct nhlt_feedback_config { 309 struct nhlt_tdm_config tdm_config; 310 uint8_t feedback_virtual_slot; 311 uint16_t feedback_channels; 312 uint16_t feedback_valid_bits_per_sample; 313 }; 314 315 struct nhlt_dmic_array_config { 316 struct nhlt_tdm_config tdm_config; 317 uint8_t array_type; 318 }; 319 320 /* 321 * Microphone array definitions may be found here: 322 * https://msdn.microsoft.com/en-us/library/windows/hardware/dn613960%28v=vs.85%29.aspx 323 */ 324 enum { 325 NHLT_MIC_ARRAY_2CH_SMALL = 0xa, 326 NHLT_MIC_ARRAY_2CH_BIG = 0xb, 327 NHLT_MIC_ARRAY_4CH_1ST_GEOM = 0xc, 328 NHLT_MIC_ARRAY_4CH_L_SHAPED = 0xd, 329 NHLT_MIC_ARRAY_4CH_2ND_GEOM = 0xe, 330 NHLT_MIC_ARRAY_VENDOR_DEFINED = 0xf, 331 }; 332 333 #endif 334