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