Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Merge branch 'topic/hda-nhlt' into for-next

Pull HD-audio NHLT fix

Signed-off-by: Takashi Iwai <tiwai@suse.de>

+601 -189
+3
drivers/acpi/Kconfig
··· 469 469 470 470 If you are unsure what to do, do not enable this option. 471 471 472 + config ACPI_NHLT 473 + bool 474 + 472 475 source "drivers/acpi/nfit/Kconfig" 473 476 source "drivers/acpi/numa/Kconfig" 474 477 source "drivers/acpi/apei/Kconfig"
+1
drivers/acpi/Makefile
··· 93 93 obj-$(CONFIG_ACPI_THERMAL) += thermal.o 94 94 obj-$(CONFIG_ACPI_PLATFORM_PROFILE) += platform_profile.o 95 95 obj-$(CONFIG_ACPI_NFIT) += nfit/ 96 + obj-$(CONFIG_ACPI_NHLT) += nhlt.o 96 97 obj-$(CONFIG_ACPI_NUMA) += numa/ 97 98 obj-$(CONFIG_ACPI) += acpi_memhotplug.o 98 99 obj-$(CONFIG_ACPI_HOTPLUG_IOAPIC) += ioapic.o
+289
drivers/acpi/nhlt.c
··· 1 + // SPDX-License-Identifier: GPL-2.0-only 2 + /* 3 + * Copyright(c) 2023-2024 Intel Corporation 4 + * 5 + * Authors: Cezary Rojewski <cezary.rojewski@intel.com> 6 + * Amadeusz Slawinski <amadeuszx.slawinski@linux.intel.com> 7 + */ 8 + 9 + #define pr_fmt(fmt) "ACPI: NHLT: " fmt 10 + 11 + #include <linux/acpi.h> 12 + #include <linux/errno.h> 13 + #include <linux/export.h> 14 + #include <linux/minmax.h> 15 + #include <linux/printk.h> 16 + #include <linux/types.h> 17 + #include <acpi/nhlt.h> 18 + 19 + static struct acpi_table_nhlt *acpi_gbl_nhlt; 20 + 21 + static struct acpi_table_nhlt empty_nhlt = { 22 + .header = { 23 + .signature = ACPI_SIG_NHLT, 24 + }, 25 + }; 26 + 27 + /** 28 + * acpi_nhlt_get_gbl_table - Retrieve a pointer to the first NHLT table. 29 + * 30 + * If there is no NHLT in the system, acpi_gbl_nhlt will instead point to an 31 + * empty table. 32 + * 33 + * Return: ACPI status code of the operation. 34 + */ 35 + acpi_status acpi_nhlt_get_gbl_table(void) 36 + { 37 + acpi_status status; 38 + 39 + status = acpi_get_table(ACPI_SIG_NHLT, 0, (struct acpi_table_header **)(&acpi_gbl_nhlt)); 40 + if (!acpi_gbl_nhlt) 41 + acpi_gbl_nhlt = &empty_nhlt; 42 + return status; 43 + } 44 + EXPORT_SYMBOL_GPL(acpi_nhlt_get_gbl_table); 45 + 46 + /** 47 + * acpi_nhlt_put_gbl_table - Release the global NHLT table. 48 + */ 49 + void acpi_nhlt_put_gbl_table(void) 50 + { 51 + acpi_put_table((struct acpi_table_header *)acpi_gbl_nhlt); 52 + } 53 + EXPORT_SYMBOL_GPL(acpi_nhlt_put_gbl_table); 54 + 55 + /** 56 + * acpi_nhlt_endpoint_match - Verify if an endpoint matches criteria. 57 + * @ep: the endpoint to check. 58 + * @link_type: the hardware link type, e.g.: PDM or SSP. 59 + * @dev_type: the device type. 60 + * @dir: stream direction. 61 + * @bus_id: the ID of virtual bus hosting the endpoint. 62 + * 63 + * Either of @link_type, @dev_type, @dir or @bus_id may be set to a negative 64 + * value to ignore the parameter when matching. 65 + * 66 + * Return: %true if endpoint matches specified criteria or %false otherwise. 67 + */ 68 + bool acpi_nhlt_endpoint_match(const struct acpi_nhlt_endpoint *ep, 69 + int link_type, int dev_type, int dir, int bus_id) 70 + { 71 + return ep && 72 + (link_type < 0 || ep->link_type == link_type) && 73 + (dev_type < 0 || ep->device_type == dev_type) && 74 + (bus_id < 0 || ep->virtual_bus_id == bus_id) && 75 + (dir < 0 || ep->direction == dir); 76 + } 77 + EXPORT_SYMBOL_GPL(acpi_nhlt_endpoint_match); 78 + 79 + /** 80 + * acpi_nhlt_tb_find_endpoint - Search a NHLT table for an endpoint. 81 + * @tb: the table to search. 82 + * @link_type: the hardware link type, e.g.: PDM or SSP. 83 + * @dev_type: the device type. 84 + * @dir: stream direction. 85 + * @bus_id: the ID of virtual bus hosting the endpoint. 86 + * 87 + * Either of @link_type, @dev_type, @dir or @bus_id may be set to a negative 88 + * value to ignore the parameter during the search. 89 + * 90 + * Return: A pointer to endpoint matching the criteria, %NULL if not found or 91 + * an ERR_PTR() otherwise. 92 + */ 93 + struct acpi_nhlt_endpoint * 94 + acpi_nhlt_tb_find_endpoint(const struct acpi_table_nhlt *tb, 95 + int link_type, int dev_type, int dir, int bus_id) 96 + { 97 + struct acpi_nhlt_endpoint *ep; 98 + 99 + for_each_nhlt_endpoint(tb, ep) 100 + if (acpi_nhlt_endpoint_match(ep, link_type, dev_type, dir, bus_id)) 101 + return ep; 102 + return NULL; 103 + } 104 + EXPORT_SYMBOL_GPL(acpi_nhlt_tb_find_endpoint); 105 + 106 + /** 107 + * acpi_nhlt_find_endpoint - Search all NHLT tables for an endpoint. 108 + * @link_type: the hardware link type, e.g.: PDM or SSP. 109 + * @dev_type: the device type. 110 + * @dir: stream direction. 111 + * @bus_id: the ID of virtual bus hosting the endpoint. 112 + * 113 + * Either of @link_type, @dev_type, @dir or @bus_id may be set to a negative 114 + * value to ignore the parameter during the search. 115 + * 116 + * Return: A pointer to endpoint matching the criteria, %NULL if not found or 117 + * an ERR_PTR() otherwise. 118 + */ 119 + struct acpi_nhlt_endpoint * 120 + acpi_nhlt_find_endpoint(int link_type, int dev_type, int dir, int bus_id) 121 + { 122 + /* TODO: Currently limited to table of index 0. */ 123 + return acpi_nhlt_tb_find_endpoint(acpi_gbl_nhlt, link_type, dev_type, dir, bus_id); 124 + } 125 + EXPORT_SYMBOL_GPL(acpi_nhlt_find_endpoint); 126 + 127 + /** 128 + * acpi_nhlt_endpoint_find_fmtcfg - Search endpoint's formats configuration space 129 + * for a specific format. 130 + * @ep: the endpoint to search. 131 + * @ch: number of channels. 132 + * @rate: samples per second. 133 + * @vbps: valid bits per sample. 134 + * @bps: bits per sample. 135 + * 136 + * Return: A pointer to format matching the criteria, %NULL if not found or 137 + * an ERR_PTR() otherwise. 138 + */ 139 + struct acpi_nhlt_format_config * 140 + acpi_nhlt_endpoint_find_fmtcfg(const struct acpi_nhlt_endpoint *ep, 141 + u16 ch, u32 rate, u16 vbps, u16 bps) 142 + { 143 + struct acpi_nhlt_wave_formatext *wav; 144 + struct acpi_nhlt_format_config *fmt; 145 + 146 + for_each_nhlt_endpoint_fmtcfg(ep, fmt) { 147 + wav = &fmt->format; 148 + 149 + if (wav->valid_bits_per_sample == vbps && 150 + wav->samples_per_sec == rate && 151 + wav->bits_per_sample == bps && 152 + wav->channel_count == ch) 153 + return fmt; 154 + } 155 + 156 + return NULL; 157 + } 158 + EXPORT_SYMBOL_GPL(acpi_nhlt_endpoint_find_fmtcfg); 159 + 160 + /** 161 + * acpi_nhlt_tb_find_fmtcfg - Search a NHLT table for a specific format. 162 + * @tb: the table to search. 163 + * @link_type: the hardware link type, e.g.: PDM or SSP. 164 + * @dev_type: the device type. 165 + * @dir: stream direction. 166 + * @bus_id: the ID of virtual bus hosting the endpoint. 167 + * 168 + * @ch: number of channels. 169 + * @rate: samples per second. 170 + * @vbps: valid bits per sample. 171 + * @bps: bits per sample. 172 + * 173 + * Either of @link_type, @dev_type, @dir or @bus_id may be set to a negative 174 + * value to ignore the parameter during the search. 175 + * 176 + * Return: A pointer to format matching the criteria, %NULL if not found or 177 + * an ERR_PTR() otherwise. 178 + */ 179 + struct acpi_nhlt_format_config * 180 + acpi_nhlt_tb_find_fmtcfg(const struct acpi_table_nhlt *tb, 181 + int link_type, int dev_type, int dir, int bus_id, 182 + u16 ch, u32 rate, u16 vbps, u16 bps) 183 + { 184 + struct acpi_nhlt_format_config *fmt; 185 + struct acpi_nhlt_endpoint *ep; 186 + 187 + for_each_nhlt_endpoint(tb, ep) { 188 + if (!acpi_nhlt_endpoint_match(ep, link_type, dev_type, dir, bus_id)) 189 + continue; 190 + 191 + fmt = acpi_nhlt_endpoint_find_fmtcfg(ep, ch, rate, vbps, bps); 192 + if (fmt) 193 + return fmt; 194 + } 195 + 196 + return NULL; 197 + } 198 + EXPORT_SYMBOL_GPL(acpi_nhlt_tb_find_fmtcfg); 199 + 200 + /** 201 + * acpi_nhlt_find_fmtcfg - Search all NHLT tables for a specific format. 202 + * @link_type: the hardware link type, e.g.: PDM or SSP. 203 + * @dev_type: the device type. 204 + * @dir: stream direction. 205 + * @bus_id: the ID of virtual bus hosting the endpoint. 206 + * 207 + * @ch: number of channels. 208 + * @rate: samples per second. 209 + * @vbps: valid bits per sample. 210 + * @bps: bits per sample. 211 + * 212 + * Either of @link_type, @dev_type, @dir or @bus_id may be set to a negative 213 + * value to ignore the parameter during the search. 214 + * 215 + * Return: A pointer to format matching the criteria, %NULL if not found or 216 + * an ERR_PTR() otherwise. 217 + */ 218 + struct acpi_nhlt_format_config * 219 + acpi_nhlt_find_fmtcfg(int link_type, int dev_type, int dir, int bus_id, 220 + u16 ch, u32 rate, u16 vbps, u16 bps) 221 + { 222 + /* TODO: Currently limited to table of index 0. */ 223 + return acpi_nhlt_tb_find_fmtcfg(acpi_gbl_nhlt, link_type, dev_type, dir, bus_id, 224 + ch, rate, vbps, bps); 225 + } 226 + EXPORT_SYMBOL_GPL(acpi_nhlt_find_fmtcfg); 227 + 228 + static bool acpi_nhlt_config_is_micdevice(struct acpi_nhlt_config *cfg) 229 + { 230 + return cfg->capabilities_size >= sizeof(struct acpi_nhlt_micdevice_config); 231 + } 232 + 233 + static bool acpi_nhlt_config_is_vendor_micdevice(struct acpi_nhlt_config *cfg) 234 + { 235 + struct acpi_nhlt_vendor_micdevice_config *devcfg = __acpi_nhlt_config_caps(cfg); 236 + 237 + return cfg->capabilities_size >= sizeof(*devcfg) && 238 + cfg->capabilities_size == struct_size(devcfg, mics, devcfg->mics_count); 239 + } 240 + 241 + /** 242 + * acpi_nhlt_endpoint_mic_count - Retrieve number of digital microphones for a PDM endpoint. 243 + * @ep: the endpoint to return microphones count for. 244 + * 245 + * Return: A number of microphones or an error code if an invalid endpoint is provided. 246 + */ 247 + int acpi_nhlt_endpoint_mic_count(const struct acpi_nhlt_endpoint *ep) 248 + { 249 + union acpi_nhlt_device_config *devcfg; 250 + struct acpi_nhlt_format_config *fmt; 251 + struct acpi_nhlt_config *cfg; 252 + u16 max_ch = 0; 253 + 254 + if (!ep || ep->link_type != ACPI_NHLT_LINKTYPE_PDM) 255 + return -EINVAL; 256 + 257 + /* Find max number of channels based on formats configuration. */ 258 + for_each_nhlt_endpoint_fmtcfg(ep, fmt) 259 + max_ch = max(fmt->format.channel_count, max_ch); 260 + 261 + cfg = __acpi_nhlt_endpoint_config(ep); 262 + devcfg = __acpi_nhlt_config_caps(cfg); 263 + 264 + /* If @ep is not a mic array, fallback to channels count. */ 265 + if (!acpi_nhlt_config_is_micdevice(cfg) || 266 + devcfg->gen.config_type != ACPI_NHLT_CONFIGTYPE_MICARRAY) 267 + return max_ch; 268 + 269 + switch (devcfg->mic.array_type) { 270 + case ACPI_NHLT_ARRAYTYPE_LINEAR2_SMALL: 271 + case ACPI_NHLT_ARRAYTYPE_LINEAR2_BIG: 272 + return 2; 273 + 274 + case ACPI_NHLT_ARRAYTYPE_LINEAR4_GEO1: 275 + case ACPI_NHLT_ARRAYTYPE_PLANAR4_LSHAPED: 276 + case ACPI_NHLT_ARRAYTYPE_LINEAR4_GEO2: 277 + return 4; 278 + 279 + case ACPI_NHLT_ARRAYTYPE_VENDOR: 280 + if (!acpi_nhlt_config_is_vendor_micdevice(cfg)) 281 + return -EINVAL; 282 + return devcfg->vendor_mic.mics_count; 283 + 284 + default: 285 + pr_warn("undefined mic array type: %#x\n", devcfg->mic.array_type); 286 + return max_ch; 287 + } 288 + } 289 + EXPORT_SYMBOL_GPL(acpi_nhlt_endpoint_mic_count);
+117 -182
include/acpi/actbl2.h
··· 1889 1889 1890 1890 /******************************************************************************* 1891 1891 * 1892 - * NHLT - Non HD Audio Link Table 1893 - * 1894 - * Conforms to: Intel Smart Sound Technology NHLT Specification 1895 - * Version 0.8.1, January 2020. 1892 + * NHLT - Non HDAudio Link Table 1893 + * Version 1 1896 1894 * 1897 1895 ******************************************************************************/ 1898 1896 1899 - /* Main table */ 1900 - 1901 1897 struct acpi_table_nhlt { 1902 1898 struct acpi_table_header header; /* Common ACPI table header */ 1903 - u8 endpoint_count; 1899 + u8 endpoints_count; 1900 + /* 1901 + * struct acpi_nhlt_endpoint endpoints[]; 1902 + * struct acpi_nhlt_config oed_config; 1903 + */ 1904 1904 }; 1905 1905 1906 1906 struct acpi_nhlt_endpoint { 1907 - u32 descriptor_length; 1907 + u32 length; 1908 1908 u8 link_type; 1909 1909 u8 instance_id; 1910 1910 u16 vendor_id; ··· 1914 1914 u8 device_type; 1915 1915 u8 direction; 1916 1916 u8 virtual_bus_id; 1917 + /* 1918 + * struct acpi_nhlt_config device_config; 1919 + * struct acpi_nhlt_formats_config formats_config; 1920 + * struct acpi_nhlt_devices_info devices_info; 1921 + */ 1917 1922 }; 1918 1923 1919 - /* Types for link_type field above */ 1920 - 1921 - #define ACPI_NHLT_RESERVED_HD_AUDIO 0 1922 - #define ACPI_NHLT_RESERVED_DSP 1 1923 - #define ACPI_NHLT_PDM 2 1924 - #define ACPI_NHLT_SSP 3 1925 - #define ACPI_NHLT_RESERVED_SLIMBUS 4 1926 - #define ACPI_NHLT_RESERVED_SOUNDWIRE 5 1927 - #define ACPI_NHLT_TYPE_RESERVED 6 /* 6 and above are reserved */ 1928 - 1929 - /* All other values above are reserved */ 1924 + /* 1925 + * Values for link_type field above 1926 + * 1927 + * Only types PDM and SSP are used 1928 + */ 1929 + #define ACPI_NHLT_LINKTYPE_HDA 0 1930 + #define ACPI_NHLT_LINKTYPE_DSP 1 1931 + #define ACPI_NHLT_LINKTYPE_PDM 2 1932 + #define ACPI_NHLT_LINKTYPE_SSP 3 1933 + #define ACPI_NHLT_LINKTYPE_SLIMBUS 4 1934 + #define ACPI_NHLT_LINKTYPE_SDW 5 1935 + #define ACPI_NHLT_LINKTYPE_UAOL 6 1930 1936 1931 1937 /* Values for device_id field above */ 1932 1938 1933 - #define ACPI_NHLT_PDM_DMIC 0xAE20 1934 - #define ACPI_NHLT_BT_SIDEBAND 0xAE30 1935 - #define ACPI_NHLT_I2S_TDM_CODECS 0xAE23 1939 + #define ACPI_NHLT_DEVICEID_DMIC 0xAE20 1940 + #define ACPI_NHLT_DEVICEID_BT 0xAE30 1941 + #define ACPI_NHLT_DEVICEID_I2S 0xAE34 1936 1942 1937 1943 /* Values for device_type field above */ 1938 1944 1939 - /* SSP Link */ 1940 - 1941 - #define ACPI_NHLT_LINK_BT_SIDEBAND 0 1942 - #define ACPI_NHLT_LINK_FM 1 1943 - #define ACPI_NHLT_LINK_MODEM 2 1944 - /* 3 is reserved */ 1945 - #define ACPI_NHLT_LINK_SSP_ANALOG_CODEC 4 1946 - 1947 - /* PDM Link */ 1948 - 1949 - #define ACPI_NHLT_PDM_ON_CAVS_1P8 0 1950 - #define ACPI_NHLT_PDM_ON_CAVS_1P5 1 1945 + /* 1946 + * Device types unique to endpoint of link_type=PDM 1947 + * 1948 + * Type PDM used for all SKL+ platforms 1949 + */ 1950 + #define ACPI_NHLT_DEVICETYPE_PDM 0 1951 + #define ACPI_NHLT_DEVICETYPE_PDM_SKL 1 1952 + /* Device types unique to endpoint of link_type=SSP */ 1953 + #define ACPI_NHLT_DEVICETYPE_BT 0 1954 + #define ACPI_NHLT_DEVICETYPE_FM 1 1955 + #define ACPI_NHLT_DEVICETYPE_MODEM 2 1956 + #define ACPI_NHLT_DEVICETYPE_CODEC 4 1951 1957 1952 1958 /* Values for Direction field above */ 1953 1959 1954 - #define ACPI_NHLT_DIR_RENDER 0 1955 - #define ACPI_NHLT_DIR_CAPTURE 1 1956 - #define ACPI_NHLT_DIR_RENDER_LOOPBACK 2 1957 - #define ACPI_NHLT_DIR_RENDER_FEEDBACK 3 1958 - #define ACPI_NHLT_DIR_RESERVED 4 /* 4 and above are reserved */ 1960 + #define ACPI_NHLT_DIR_RENDER 0 1961 + #define ACPI_NHLT_DIR_CAPTURE 1 1959 1962 1960 - struct acpi_nhlt_device_specific_config { 1963 + struct acpi_nhlt_config { 1961 1964 u32 capabilities_size; 1965 + u8 capabilities[]; 1966 + }; 1967 + 1968 + struct acpi_nhlt_gendevice_config { 1962 1969 u8 virtual_slot; 1963 1970 u8 config_type; 1964 1971 }; 1965 1972 1966 - struct acpi_nhlt_device_specific_config_a { 1967 - u32 capabilities_size; 1973 + /* Values for config_type field above */ 1974 + 1975 + #define ACPI_NHLT_CONFIGTYPE_GENERIC 0 1976 + #define ACPI_NHLT_CONFIGTYPE_MICARRAY 1 1977 + 1978 + struct acpi_nhlt_micdevice_config { 1968 1979 u8 virtual_slot; 1969 1980 u8 config_type; 1970 1981 u8 array_type; 1971 1982 }; 1972 1983 1973 - /* Values for Config Type above */ 1984 + /* Values for array_type field above */ 1974 1985 1975 - #define ACPI_NHLT_CONFIG_TYPE_GENERIC 0x00 1976 - #define ACPI_NHLT_CONFIG_TYPE_MIC_ARRAY 0x01 1977 - #define ACPI_NHLT_CONFIG_TYPE_RENDER_FEEDBACK 0x03 1978 - #define ACPI_NHLT_CONFIG_TYPE_RESERVED 0x04 /* 4 and above are reserved */ 1986 + #define ACPI_NHLT_ARRAYTYPE_LINEAR2_SMALL 0xA 1987 + #define ACPI_NHLT_ARRAYTYPE_LINEAR2_BIG 0xB 1988 + #define ACPI_NHLT_ARRAYTYPE_LINEAR4_GEO1 0xC 1989 + #define ACPI_NHLT_ARRAYTYPE_PLANAR4_LSHAPED 0xD 1990 + #define ACPI_NHLT_ARRAYTYPE_LINEAR4_GEO2 0xE 1991 + #define ACPI_NHLT_ARRAYTYPE_VENDOR 0xF 1979 1992 1980 - struct acpi_nhlt_device_specific_config_b { 1981 - u32 capabilities_size; 1993 + struct acpi_nhlt_vendor_mic_config { 1994 + u8 type; 1995 + u8 panel; 1996 + u16 speaker_position_distance; /* mm */ 1997 + u16 horizontal_offset; /* mm */ 1998 + u16 vertical_offset; /* mm */ 1999 + u8 frequency_low_band; /* 5*Hz */ 2000 + u8 frequency_high_band; /* 500*Hz */ 2001 + u16 direction_angle; /* -180 - +180 */ 2002 + u16 elevation_angle; /* -180 - +180 */ 2003 + u16 work_vertical_angle_begin; /* -180 - +180 with 2 deg step */ 2004 + u16 work_vertical_angle_end; /* -180 - +180 with 2 deg step */ 2005 + u16 work_horizontal_angle_begin; /* -180 - +180 with 2 deg step */ 2006 + u16 work_horizontal_angle_end; /* -180 - +180 with 2 deg step */ 1982 2007 }; 1983 2008 1984 - struct acpi_nhlt_device_specific_config_c { 1985 - u32 capabilities_size; 2009 + /* Values for Type field above */ 2010 + 2011 + #define ACPI_NHLT_MICTYPE_OMNIDIRECTIONAL 0 2012 + #define ACPI_NHLT_MICTYPE_SUBCARDIOID 1 2013 + #define ACPI_NHLT_MICTYPE_CARDIOID 2 2014 + #define ACPI_NHLT_MICTYPE_SUPERCARDIOID 3 2015 + #define ACPI_NHLT_MICTYPE_HYPERCARDIOID 4 2016 + #define ACPI_NHLT_MICTYPE_8SHAPED 5 2017 + #define ACPI_NHLT_MICTYPE_RESERVED 6 2018 + #define ACPI_NHLT_MICTYPE_VENDORDEFINED 7 2019 + 2020 + /* Values for Panel field above */ 2021 + 2022 + #define ACPI_NHLT_MICLOCATION_TOP 0 2023 + #define ACPI_NHLT_MICLOCATION_BOTTOM 1 2024 + #define ACPI_NHLT_MICLOCATION_LEFT 2 2025 + #define ACPI_NHLT_MICLOCATION_RIGHT 3 2026 + #define ACPI_NHLT_MICLOCATION_FRONT 4 2027 + #define ACPI_NHLT_MICLOCATION_REAR 5 2028 + 2029 + struct acpi_nhlt_vendor_micdevice_config { 1986 2030 u8 virtual_slot; 2031 + u8 config_type; 2032 + u8 array_type; 2033 + u8 mics_count; 2034 + struct acpi_nhlt_vendor_mic_config mics[]; 1987 2035 }; 1988 2036 1989 - struct acpi_nhlt_render_device_specific_config { 1990 - u32 capabilities_size; 2037 + union acpi_nhlt_device_config { 1991 2038 u8 virtual_slot; 2039 + struct acpi_nhlt_gendevice_config gen; 2040 + struct acpi_nhlt_micdevice_config mic; 2041 + struct acpi_nhlt_vendor_micdevice_config vendor_mic; 1992 2042 }; 1993 2043 1994 - struct acpi_nhlt_wave_extensible { 2044 + /* Inherited from Microsoft's WAVEFORMATEXTENSIBLE. */ 2045 + struct acpi_nhlt_wave_formatext { 1995 2046 u16 format_tag; 1996 2047 u16 channel_count; 1997 2048 u32 samples_per_sec; ··· 2052 2001 u16 extra_format_size; 2053 2002 u16 valid_bits_per_sample; 2054 2003 u32 channel_mask; 2055 - u8 sub_format_guid[16]; 2004 + u8 subformat[16]; 2056 2005 }; 2057 2006 2058 - /* Values for channel_mask above */ 2059 - 2060 - #define ACPI_NHLT_SPKR_FRONT_LEFT 0x1 2061 - #define ACPI_NHLT_SPKR_FRONT_RIGHT 0x2 2062 - #define ACPI_NHLT_SPKR_FRONT_CENTER 0x4 2063 - #define ACPI_NHLT_SPKR_LOW_FREQ 0x8 2064 - #define ACPI_NHLT_SPKR_BACK_LEFT 0x10 2065 - #define ACPI_NHLT_SPKR_BACK_RIGHT 0x20 2066 - #define ACPI_NHLT_SPKR_FRONT_LEFT_OF_CENTER 0x40 2067 - #define ACPI_NHLT_SPKR_FRONT_RIGHT_OF_CENTER 0x80 2068 - #define ACPI_NHLT_SPKR_BACK_CENTER 0x100 2069 - #define ACPI_NHLT_SPKR_SIDE_LEFT 0x200 2070 - #define ACPI_NHLT_SPKR_SIDE_RIGHT 0x400 2071 - #define ACPI_NHLT_SPKR_TOP_CENTER 0x800 2072 - #define ACPI_NHLT_SPKR_TOP_FRONT_LEFT 0x1000 2073 - #define ACPI_NHLT_SPKR_TOP_FRONT_CENTER 0x2000 2074 - #define ACPI_NHLT_SPKR_TOP_FRONT_RIGHT 0x4000 2075 - #define ACPI_NHLT_SPKR_TOP_BACK_LEFT 0x8000 2076 - #define ACPI_NHLT_SPKR_TOP_BACK_CENTER 0x10000 2077 - #define ACPI_NHLT_SPKR_TOP_BACK_RIGHT 0x20000 2078 - 2079 2007 struct acpi_nhlt_format_config { 2080 - struct acpi_nhlt_wave_extensible format; 2081 - u32 capability_size; 2082 - u8 capabilities[]; 2008 + struct acpi_nhlt_wave_formatext format; 2009 + struct acpi_nhlt_config config; 2083 2010 }; 2084 2011 2085 2012 struct acpi_nhlt_formats_config { 2086 2013 u8 formats_count; 2087 - }; 2088 - 2089 - struct acpi_nhlt_device_specific_hdr { 2090 - u8 virtual_slot; 2091 - u8 config_type; 2092 - }; 2093 - 2094 - /* Types for config_type above */ 2095 - 2096 - #define ACPI_NHLT_GENERIC 0 2097 - #define ACPI_NHLT_MIC 1 2098 - #define ACPI_NHLT_RENDER 3 2099 - 2100 - struct acpi_nhlt_mic_device_specific_config { 2101 - struct acpi_nhlt_device_specific_hdr device_config; 2102 - u8 array_type_ext; 2103 - }; 2104 - 2105 - /* Values for array_type_ext above */ 2106 - 2107 - #define ACPI_NHLT_ARRAY_TYPE_RESERVED 0x09 /* 9 and below are reserved */ 2108 - #define ACPI_NHLT_SMALL_LINEAR_2ELEMENT 0x0A 2109 - #define ACPI_NHLT_BIG_LINEAR_2ELEMENT 0x0B 2110 - #define ACPI_NHLT_FIRST_GEOMETRY_LINEAR_4ELEMENT 0x0C 2111 - #define ACPI_NHLT_PLANAR_LSHAPED_4ELEMENT 0x0D 2112 - #define ACPI_NHLT_SECOND_GEOMETRY_LINEAR_4ELEMENT 0x0E 2113 - #define ACPI_NHLT_VENDOR_DEFINED 0x0F 2114 - #define ACPI_NHLT_ARRAY_TYPE_MASK 0x0F 2115 - #define ACPI_NHLT_ARRAY_TYPE_EXT_MASK 0x10 2116 - 2117 - #define ACPI_NHLT_NO_EXTENSION 0x0 2118 - #define ACPI_NHLT_MIC_SNR_SENSITIVITY_EXT (1<<4) 2119 - 2120 - struct acpi_nhlt_vendor_mic_count { 2121 - u8 microphone_count; 2122 - }; 2123 - 2124 - struct acpi_nhlt_vendor_mic_config { 2125 - u8 type; 2126 - u8 panel; 2127 - u16 speaker_position_distance; /* mm */ 2128 - u16 horizontal_offset; /* mm */ 2129 - u16 vertical_offset; /* mm */ 2130 - u8 frequency_low_band; /* 5*Hz */ 2131 - u8 frequency_high_band; /* 500*Hz */ 2132 - u16 direction_angle; /* -180 - + 180 */ 2133 - u16 elevation_angle; /* -180 - + 180 */ 2134 - u16 work_vertical_angle_begin; /* -180 - + 180 with 2 deg step */ 2135 - u16 work_vertical_angle_end; /* -180 - + 180 with 2 deg step */ 2136 - u16 work_horizontal_angle_begin; /* -180 - + 180 with 2 deg step */ 2137 - u16 work_horizontal_angle_end; /* -180 - + 180 with 2 deg step */ 2138 - }; 2139 - 2140 - /* Values for Type field above */ 2141 - 2142 - #define ACPI_NHLT_MIC_OMNIDIRECTIONAL 0 2143 - #define ACPI_NHLT_MIC_SUBCARDIOID 1 2144 - #define ACPI_NHLT_MIC_CARDIOID 2 2145 - #define ACPI_NHLT_MIC_SUPER_CARDIOID 3 2146 - #define ACPI_NHLT_MIC_HYPER_CARDIOID 4 2147 - #define ACPI_NHLT_MIC_8_SHAPED 5 2148 - #define ACPI_NHLT_MIC_RESERVED6 6 /* 6 is reserved */ 2149 - #define ACPI_NHLT_MIC_VENDOR_DEFINED 7 2150 - #define ACPI_NHLT_MIC_RESERVED 8 /* 8 and above are reserved */ 2151 - 2152 - /* Values for Panel field above */ 2153 - 2154 - #define ACPI_NHLT_MIC_POSITION_TOP 0 2155 - #define ACPI_NHLT_MIC_POSITION_BOTTOM 1 2156 - #define ACPI_NHLT_MIC_POSITION_LEFT 2 2157 - #define ACPI_NHLT_MIC_POSITION_RIGHT 3 2158 - #define ACPI_NHLT_MIC_POSITION_FRONT 4 2159 - #define ACPI_NHLT_MIC_POSITION_BACK 5 2160 - #define ACPI_NHLT_MIC_POSITION_RESERVED 6 /* 6 and above are reserved */ 2161 - 2162 - struct acpi_nhlt_vendor_mic_device_specific_config { 2163 - struct acpi_nhlt_mic_device_specific_config mic_array_device_config; 2164 - u8 number_of_microphones; 2165 - struct acpi_nhlt_vendor_mic_config mic_config[]; /* Indexed by number_of_microphones */ 2166 - }; 2167 - 2168 - /* Microphone SNR and Sensitivity extension */ 2169 - 2170 - struct acpi_nhlt_mic_snr_sensitivity_extension { 2171 - u32 SNR; 2172 - u32 sensitivity; 2173 - }; 2174 - 2175 - /* Render device with feedback */ 2176 - 2177 - struct acpi_nhlt_render_feedback_device_specific_config { 2178 - u8 feedback_virtual_slot; /* Render slot in case of capture */ 2179 - u16 feedback_channels; /* Informative only */ 2180 - u16 feedback_valid_bits_per_sample; 2181 - }; 2182 - 2183 - /* Non documented structures */ 2184 - 2185 - struct acpi_nhlt_device_info_count { 2186 - u8 structure_count; 2014 + struct acpi_nhlt_format_config formats[]; 2187 2015 }; 2188 2016 2189 2017 struct acpi_nhlt_device_info { 2190 - u8 device_id[16]; 2191 - u8 device_instance_id; 2192 - u8 device_port_id; 2018 + u8 id[16]; 2019 + u8 instance_id; 2020 + u8 port_id; 2021 + }; 2022 + 2023 + struct acpi_nhlt_devices_info { 2024 + u8 devices_count; 2025 + struct acpi_nhlt_device_info devices[]; 2193 2026 }; 2194 2027 2195 2028 /*******************************************************************************
+181
include/acpi/nhlt.h
··· 1 + /* SPDX-License-Identifier: GPL-2.0-only */ 2 + /* 3 + * Copyright(c) 2023-2024 Intel Corporation 4 + * 5 + * Authors: Cezary Rojewski <cezary.rojewski@intel.com> 6 + * Amadeusz Slawinski <amadeuszx.slawinski@linux.intel.com> 7 + */ 8 + 9 + #ifndef __ACPI_NHLT_H__ 10 + #define __ACPI_NHLT_H__ 11 + 12 + #include <linux/acpi.h> 13 + #include <linux/kconfig.h> 14 + #include <linux/overflow.h> 15 + #include <linux/types.h> 16 + 17 + #define __acpi_nhlt_endpoint_config(ep) ((void *)((ep) + 1)) 18 + #define __acpi_nhlt_config_caps(cfg) ((void *)((cfg) + 1)) 19 + 20 + /** 21 + * acpi_nhlt_endpoint_fmtscfg - Get the formats configuration space. 22 + * @ep: the endpoint to retrieve the space for. 23 + * 24 + * Return: A pointer to the formats configuration space. 25 + */ 26 + static inline struct acpi_nhlt_formats_config * 27 + acpi_nhlt_endpoint_fmtscfg(const struct acpi_nhlt_endpoint *ep) 28 + { 29 + struct acpi_nhlt_config *cfg = __acpi_nhlt_endpoint_config(ep); 30 + 31 + return (struct acpi_nhlt_formats_config *)((u8 *)(cfg + 1) + cfg->capabilities_size); 32 + } 33 + 34 + #define __acpi_nhlt_first_endpoint(tb) \ 35 + ((void *)(tb + 1)) 36 + 37 + #define __acpi_nhlt_next_endpoint(ep) \ 38 + ((void *)((u8 *)(ep) + (ep)->length)) 39 + 40 + #define __acpi_nhlt_get_endpoint(tb, ep, i) \ 41 + ((i) ? __acpi_nhlt_next_endpoint(ep) : __acpi_nhlt_first_endpoint(tb)) 42 + 43 + #define __acpi_nhlt_first_fmtcfg(fmts) \ 44 + ((void *)(fmts + 1)) 45 + 46 + #define __acpi_nhlt_next_fmtcfg(fmt) \ 47 + ((void *)((u8 *)((fmt) + 1) + (fmt)->config.capabilities_size)) 48 + 49 + #define __acpi_nhlt_get_fmtcfg(fmts, fmt, i) \ 50 + ((i) ? __acpi_nhlt_next_fmtcfg(fmt) : __acpi_nhlt_first_fmtcfg(fmts)) 51 + 52 + /* 53 + * The for_each_nhlt_*() macros rely on an iterator to deal with the 54 + * variable length of each endpoint structure and the possible presence 55 + * of an OED-Config used by Windows only. 56 + */ 57 + 58 + /** 59 + * for_each_nhlt_endpoint - Iterate over endpoints in a NHLT table. 60 + * @tb: the pointer to a NHLT table. 61 + * @ep: the pointer to endpoint to use as loop cursor. 62 + */ 63 + #define for_each_nhlt_endpoint(tb, ep) \ 64 + for (unsigned int __i = 0; \ 65 + __i < (tb)->endpoints_count && \ 66 + (ep = __acpi_nhlt_get_endpoint(tb, ep, __i)); \ 67 + __i++) 68 + 69 + /** 70 + * for_each_nhlt_fmtcfg - Iterate over format configurations. 71 + * @fmts: the pointer to formats configuration space. 72 + * @fmt: the pointer to format to use as loop cursor. 73 + */ 74 + #define for_each_nhlt_fmtcfg(fmts, fmt) \ 75 + for (unsigned int __i = 0; \ 76 + __i < (fmts)->formats_count && \ 77 + (fmt = __acpi_nhlt_get_fmtcfg(fmts, fmt, __i)); \ 78 + __i++) 79 + 80 + /** 81 + * for_each_nhlt_endpoint_fmtcfg - Iterate over format configurations in an endpoint. 82 + * @ep: the pointer to an endpoint. 83 + * @fmt: the pointer to format to use as loop cursor. 84 + */ 85 + #define for_each_nhlt_endpoint_fmtcfg(ep, fmt) \ 86 + for_each_nhlt_fmtcfg(acpi_nhlt_endpoint_fmtscfg(ep), fmt) 87 + 88 + #if IS_ENABLED(CONFIG_ACPI_NHLT) 89 + 90 + /* 91 + * System-wide pointer to the first NHLT table. 92 + * 93 + * A sound driver may utilize acpi_nhlt_get/put_gbl_table() on its 94 + * initialization and removal respectively to avoid excessive mapping 95 + * and unmapping of the memory occupied by the table between streaming 96 + * operations. 97 + */ 98 + 99 + acpi_status acpi_nhlt_get_gbl_table(void); 100 + void acpi_nhlt_put_gbl_table(void); 101 + 102 + bool acpi_nhlt_endpoint_match(const struct acpi_nhlt_endpoint *ep, 103 + int link_type, int dev_type, int dir, int bus_id); 104 + struct acpi_nhlt_endpoint * 105 + acpi_nhlt_tb_find_endpoint(const struct acpi_table_nhlt *tb, 106 + int link_type, int dev_type, int dir, int bus_id); 107 + struct acpi_nhlt_endpoint * 108 + acpi_nhlt_find_endpoint(int link_type, int dev_type, int dir, int bus_id); 109 + struct acpi_nhlt_format_config * 110 + acpi_nhlt_endpoint_find_fmtcfg(const struct acpi_nhlt_endpoint *ep, 111 + u16 ch, u32 rate, u16 vbps, u16 bps); 112 + struct acpi_nhlt_format_config * 113 + acpi_nhlt_tb_find_fmtcfg(const struct acpi_table_nhlt *tb, 114 + int link_type, int dev_type, int dir, int bus_id, 115 + u16 ch, u32 rate, u16 vpbs, u16 bps); 116 + struct acpi_nhlt_format_config * 117 + acpi_nhlt_find_fmtcfg(int link_type, int dev_type, int dir, int bus_id, 118 + u16 ch, u32 rate, u16 vpbs, u16 bps); 119 + int acpi_nhlt_endpoint_mic_count(const struct acpi_nhlt_endpoint *ep); 120 + 121 + #else /* !CONFIG_ACPI_NHLT */ 122 + 123 + static inline acpi_status acpi_nhlt_get_gbl_table(void) 124 + { 125 + return AE_NOT_FOUND; 126 + } 127 + 128 + static inline void acpi_nhlt_put_gbl_table(void) 129 + { 130 + } 131 + 132 + static inline bool 133 + acpi_nhlt_endpoint_match(const struct acpi_nhlt_endpoint *ep, 134 + int link_type, int dev_type, int dir, int bus_id) 135 + { 136 + return false; 137 + } 138 + 139 + static inline struct acpi_nhlt_endpoint * 140 + acpi_nhlt_tb_find_endpoint(const struct acpi_table_nhlt *tb, 141 + int link_type, int dev_type, int dir, int bus_id) 142 + { 143 + return NULL; 144 + } 145 + 146 + static inline struct acpi_nhlt_format_config * 147 + acpi_nhlt_endpoint_find_fmtcfg(const struct acpi_nhlt_endpoint *ep, 148 + u16 ch, u32 rate, u16 vbps, u16 bps) 149 + { 150 + return NULL; 151 + } 152 + 153 + static inline struct acpi_nhlt_format_config * 154 + acpi_nhlt_tb_find_fmtcfg(const struct acpi_table_nhlt *tb, 155 + int link_type, int dev_type, int dir, int bus_id, 156 + u16 ch, u32 rate, u16 vpbs, u16 bps) 157 + { 158 + return NULL; 159 + } 160 + 161 + static inline int acpi_nhlt_endpoint_mic_count(const struct acpi_nhlt_endpoint *ep) 162 + { 163 + return 0; 164 + } 165 + 166 + static inline struct acpi_nhlt_endpoint * 167 + acpi_nhlt_find_endpoint(int link_type, int dev_type, int dir, int bus_id) 168 + { 169 + return NULL; 170 + } 171 + 172 + static inline struct acpi_nhlt_format_config * 173 + acpi_nhlt_find_fmtcfg(int link_type, int dev_type, int dir, int bus_id, 174 + u16 ch, u32 rate, u16 vpbs, u16 bps) 175 + { 176 + return NULL; 177 + } 178 + 179 + #endif /* CONFIG_ACPI_NHLT */ 180 + 181 + #endif /* __ACPI_NHLT_H__ */
+1
sound/hda/Kconfig
··· 42 42 43 43 config SND_INTEL_DSP_CONFIG 44 44 tristate 45 + select ACPI_NHLT if ACPI 45 46 select SND_INTEL_NHLT if ACPI 46 47 select SND_INTEL_SOUNDWIRE_ACPI if ACPI 47 48 # this config should be selected only for Intel DSP platforms.
+9 -7
sound/hda/intel-dsp-config.c
··· 13 13 #include <sound/intel-nhlt.h> 14 14 #include <sound/soc-acpi.h> 15 15 16 + #include <acpi/nhlt.h> 17 + 16 18 static int dsp_driver; 17 19 18 20 module_param(dsp_driver, int, 0444); ··· 595 593 596 594 static int snd_intel_dsp_check_dmic(struct pci_dev *pci) 597 595 { 598 - struct nhlt_acpi_table *nhlt; 599 596 int ret = 0; 600 597 601 - nhlt = intel_nhlt_init(&pci->dev); 602 - if (nhlt) { 603 - if (intel_nhlt_has_endpoint_type(nhlt, NHLT_LINK_DMIC)) 604 - ret = 1; 605 - intel_nhlt_free(nhlt); 606 - } 598 + acpi_nhlt_get_gbl_table(); 599 + 600 + if (acpi_nhlt_find_endpoint(ACPI_NHLT_LINKTYPE_PDM, -1, -1, -1)) 601 + ret = 1; 602 + 603 + acpi_nhlt_put_gbl_table(); 604 + 607 605 return ret; 608 606 } 609 607