summaryrefslogtreecommitdiff
path: root/include
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2025-12-04 10:08:40 -0800
committerLinus Torvalds <torvalds@linux-foundation.org>2025-12-04 10:08:40 -0800
commit2aa680df68062e4e0c356ec2aa7100c13654907b (patch)
treeee3dc5125e11aac04f2e33922cfad4260e47de34 /include
parent6dfafbd0299a60bfb5d5e277fdf100037c7ded07 (diff)
parenteaf526cfa4e537af86543d77f402b9ae803f606e (diff)
Merge tag 'sound-6.19-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound
Pull sound updates from Takashi Iwai: "The majority of changes at this time were about ASoC with a lot of code refactoring works. From the functionality POV, there isn't much to see, but we have a wide range of device-specific fixes and updates. Here are some highlights: - Continued ASoC API cleanup work, spanned over many files - Added a SoundWire SCDA generic class driver with regmap support - Enhancements and fixes for Cirrus, Intel, Maxim and Qualcomm. - Support for ASoC Allwinner A523, Mediatek MT8189, Qualcomm QCM2290, QRB2210 and SM6115, SpacemiT K1, and TI TAS2568, TAS5802, TAS5806, TAS5815, TAS5828 and TAS5830 - Usual HD-audio and USB-audio quirks and fixups - Support for Onkyo SE-300PCIE, TASCAM IF-FW/DM MkII Some gpiolib changes for shared GPIOs are included along with this PR for covering ASoC drivers changes" * tag 'sound-6.19-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound: (739 commits) ALSA: hda/realtek: Add PCI SSIDs to HP ProBook quirks ALSA: usb-audio: Simplify with usb_endpoint_max_periodic_payload() ALSA: hda/realtek: fix mute/micmute LEDs don't work for more HP laptops ALSA: rawmidi: Fix inconsistent indenting warning reported by smatch ALSA: dice: fix buffer overflow in detect_stream_formats() ASoC: codecs: Modify awinic amplifier dsp read and write functions ASoC: SDCA: Fixup some more Kconfig issues ASoC: cs35l56: Log a message if firmware is missing ASoC: nau8325: Delete a stray tab firmware: cs_dsp: Add test cases for client_ops == NULL firmware: cs_dsp: Don't require client to provide a struct cs_dsp_client_ops ASoC: fsl_micfil: Set channel range control ASoC: fsl_micfil: Add default quality for different platforms ASoC: intel: sof_sdw: Add codec_info for cs42l45 ASoC: sdw_utils: Add cs42l45 support functions ASoC: intel: sof_sdw: Add ability to have auxiliary devices ASoC: sdw_utils: Move codec_name to dai info ASoC: sdw_utils: Add codec_conf for every DAI ASoC: SDCA: Add terminal type into input/output widget name ASoC: SDCA: Align mute controls to ALSA expectations ...
Diffstat (limited to 'include')
-rw-r--r--include/linux/firmware/cirrus/cs_dsp.h6
-rw-r--r--include/linux/firmware/cirrus/cs_dsp_test_utils.h18
-rw-r--r--include/linux/gpio/consumer.h9
-rw-r--r--include/linux/pci_ids.h1
-rw-r--r--include/linux/regmap.h21
-rw-r--r--include/linux/soundwire/sdw_registers.h2
-rw-r--r--include/linux/string.h18
-rw-r--r--include/sound/cs-amp-lib.h25
-rw-r--r--include/sound/cs35l56.h50
-rw-r--r--include/sound/sdca.h19
-rw-r--r--include/sound/sdca_fdl.h105
-rw-r--r--include/sound/sdca_function.h126
-rw-r--r--include/sound/sdca_hid.h21
-rw-r--r--include/sound/sdca_interrupts.h19
-rw-r--r--include/sound/sdca_regmap.h2
-rw-r--r--include/sound/sdca_ump.h50
-rw-r--r--include/sound/soc-acpi-intel-match.h2
-rw-r--r--include/sound/soc-acpi.h8
-rw-r--r--include/sound/soc.h39
-rw-r--r--include/sound/soc_sdw_utils.h19
-rw-r--r--include/sound/tas2781.h8
-rw-r--r--include/trace/events/asoc.h4
-rw-r--r--include/uapi/sound/intel/avs/tokens.h6
23 files changed, 514 insertions, 64 deletions
diff --git a/include/linux/firmware/cirrus/cs_dsp.h b/include/linux/firmware/cirrus/cs_dsp.h
index a66eb7624730..0ec1cdc5585d 100644
--- a/include/linux/firmware/cirrus/cs_dsp.h
+++ b/include/linux/firmware/cirrus/cs_dsp.h
@@ -102,7 +102,7 @@ struct cs_dsp_coeff_ctl {
const char *subname;
unsigned int subname_len;
unsigned int offset;
- size_t len;
+ unsigned int len;
unsigned int type;
unsigned int flags;
unsigned int set:1;
@@ -188,8 +188,8 @@ struct cs_dsp {
#ifdef CONFIG_DEBUG_FS
struct dentry *debugfs_root;
- char *wmfw_file_name;
- char *bin_file_name;
+ const char *wmfw_file_name;
+ const char *bin_file_name;
#endif
};
diff --git a/include/linux/firmware/cirrus/cs_dsp_test_utils.h b/include/linux/firmware/cirrus/cs_dsp_test_utils.h
index ecd821ed8064..1f97764fdfd7 100644
--- a/include/linux/firmware/cirrus/cs_dsp_test_utils.h
+++ b/include/linux/firmware/cirrus/cs_dsp_test_utils.h
@@ -26,21 +26,21 @@ struct cs_dsp_test {
struct cs_dsp_test_local *local;
- /* Following members are private */
+ /* private: Following members are private */
bool saw_bus_write;
};
/**
* struct cs_dsp_mock_alg_def - Info for creating a mock algorithm entry.
*
- * @id Algorithm ID.
- * @ver; Algorithm version.
- * @xm_base_words XM base address in DSP words.
- * @xm_size_words XM size in DSP words.
- * @ym_base_words YM base address in DSP words.
- * @ym_size_words YM size in DSP words.
- * @zm_base_words ZM base address in DSP words.
- * @zm_size_words ZM size in DSP words.
+ * @id: Algorithm ID.
+ * @ver: Algorithm version.
+ * @xm_base_words: XM base address in DSP words.
+ * @xm_size_words: XM size in DSP words.
+ * @ym_base_words: YM base address in DSP words.
+ * @ym_size_words: YM size in DSP words.
+ * @zm_base_words: ZM base address in DSP words.
+ * @zm_size_words: ZM size in DSP words.
*/
struct cs_dsp_mock_alg_def {
unsigned int id;
diff --git a/include/linux/gpio/consumer.h b/include/linux/gpio/consumer.h
index 00df68c51405..a8acb7c0b5af 100644
--- a/include/linux/gpio/consumer.h
+++ b/include/linux/gpio/consumer.h
@@ -167,6 +167,8 @@ int gpiod_cansleep(const struct gpio_desc *desc);
int gpiod_to_irq(const struct gpio_desc *desc);
int gpiod_set_consumer_name(struct gpio_desc *desc, const char *name);
+bool gpiod_is_shared(const struct gpio_desc *desc);
+
/* Convert between the old gpio_ and new gpiod_ interfaces */
struct gpio_desc *gpio_to_desc(unsigned gpio);
int desc_to_gpio(const struct gpio_desc *desc);
@@ -520,6 +522,13 @@ static inline int gpiod_set_consumer_name(struct gpio_desc *desc,
return -EINVAL;
}
+static inline bool gpiod_is_shared(const struct gpio_desc *desc)
+{
+ /* GPIO can never have been requested */
+ WARN_ON(desc);
+ return false;
+}
+
static inline struct gpio_desc *gpio_to_desc(unsigned gpio)
{
return NULL;
diff --git a/include/linux/pci_ids.h b/include/linux/pci_ids.h
index 92ffc4373f6d..a9a089566b7c 100644
--- a/include/linux/pci_ids.h
+++ b/include/linux/pci_ids.h
@@ -3075,6 +3075,7 @@
#define PCI_DEVICE_ID_INTEL_5100_22 0x65f6
#define PCI_DEVICE_ID_INTEL_IOAT_SCNB 0x65ff
#define PCI_DEVICE_ID_INTEL_HDA_FCL 0x67a8
+#define PCI_DEVICE_ID_INTEL_HDA_NVL_S 0x6e50
#define PCI_DEVICE_ID_INTEL_82371SB_0 0x7000
#define PCI_DEVICE_ID_INTEL_82371SB_1 0x7010
#define PCI_DEVICE_ID_INTEL_82371SB_2 0x7020
diff --git a/include/linux/regmap.h b/include/linux/regmap.h
index 55343795644b..64cd83b1f7bc 100644
--- a/include/linux/regmap.h
+++ b/include/linux/regmap.h
@@ -676,7 +676,7 @@ struct regmap *__regmap_init_sdw(struct sdw_slave *sdw,
const struct regmap_config *config,
struct lock_class_key *lock_key,
const char *lock_name);
-struct regmap *__regmap_init_sdw_mbq(struct sdw_slave *sdw,
+struct regmap *__regmap_init_sdw_mbq(struct device *dev, struct sdw_slave *sdw,
const struct regmap_config *config,
const struct regmap_sdw_mbq_cfg *mbq_config,
struct lock_class_key *lock_key,
@@ -738,7 +738,7 @@ struct regmap *__devm_regmap_init_sdw(struct sdw_slave *sdw,
const struct regmap_config *config,
struct lock_class_key *lock_key,
const char *lock_name);
-struct regmap *__devm_regmap_init_sdw_mbq(struct sdw_slave *sdw,
+struct regmap *__devm_regmap_init_sdw_mbq(struct device *dev, struct sdw_slave *sdw,
const struct regmap_config *config,
const struct regmap_sdw_mbq_cfg *mbq_config,
struct lock_class_key *lock_key,
@@ -970,7 +970,7 @@ bool regmap_ac97_default_volatile(struct device *dev, unsigned int reg);
*/
#define regmap_init_sdw_mbq(sdw, config) \
__regmap_lockdep_wrapper(__regmap_init_sdw_mbq, #config, \
- sdw, config, NULL)
+ &sdw->dev, sdw, config, NULL)
/**
* regmap_init_sdw_mbq_cfg() - Initialise MBQ SDW register map with config
@@ -983,9 +983,9 @@ bool regmap_ac97_default_volatile(struct device *dev, unsigned int reg);
* to a struct regmap. The regmap will be automatically freed by the
* device management code.
*/
-#define regmap_init_sdw_mbq_cfg(sdw, config, mbq_config) \
+#define regmap_init_sdw_mbq_cfg(dev, sdw, config, mbq_config) \
__regmap_lockdep_wrapper(__regmap_init_sdw_mbq, #config, \
- sdw, config, mbq_config)
+ dev, sdw, config, mbq_config)
/**
* regmap_init_spi_avmm() - Initialize register map for Intel SPI Slave
@@ -1198,12 +1198,13 @@ bool regmap_ac97_default_volatile(struct device *dev, unsigned int reg);
*/
#define devm_regmap_init_sdw_mbq(sdw, config) \
__regmap_lockdep_wrapper(__devm_regmap_init_sdw_mbq, #config, \
- sdw, config, NULL)
+ &sdw->dev, sdw, config, NULL)
/**
* devm_regmap_init_sdw_mbq_cfg() - Initialise managed MBQ SDW register map with config
*
- * @sdw: Device that will be interacted with
+ * @dev: Device that will be interacted with
+ * @sdw: SoundWire Device that will be interacted with
* @config: Configuration for register map
* @mbq_config: Properties for the MBQ registers
*
@@ -1211,9 +1212,9 @@ bool regmap_ac97_default_volatile(struct device *dev, unsigned int reg);
* to a struct regmap. The regmap will be automatically freed by the
* device management code.
*/
-#define devm_regmap_init_sdw_mbq_cfg(sdw, config, mbq_config) \
- __regmap_lockdep_wrapper(__devm_regmap_init_sdw_mbq, \
- #config, sdw, config, mbq_config)
+#define devm_regmap_init_sdw_mbq_cfg(dev, sdw, config, mbq_config) \
+ __regmap_lockdep_wrapper(__devm_regmap_init_sdw_mbq, \
+ #config, dev, sdw, config, mbq_config)
/**
* devm_regmap_init_slimbus() - Initialise managed register map
diff --git a/include/linux/soundwire/sdw_registers.h b/include/linux/soundwire/sdw_registers.h
index 0a5939285583..cae8a0a5a9b0 100644
--- a/include/linux/soundwire/sdw_registers.h
+++ b/include/linux/soundwire/sdw_registers.h
@@ -355,4 +355,6 @@
/* Check the reserved and fixed bits in address */
#define SDW_SDCA_VALID_CTL(reg) (((reg) & (GENMASK(31, 25) | BIT(18) | BIT(13))) == BIT(30))
+#define SDW_SDCA_MAX_REGISTER 0x47FFFFFF
+
#endif /* __SDW_REGISTERS_H */
diff --git a/include/linux/string.h b/include/linux/string.h
index fdd3442c6bcb..929d05d1247c 100644
--- a/include/linux/string.h
+++ b/include/linux/string.h
@@ -562,4 +562,22 @@ static inline bool strstarts(const char *str, const char *prefix)
return strncmp(str, prefix, strlen(prefix)) == 0;
}
+/**
+ * strends - Check if a string ends with another string.
+ * @str - NULL-terminated string to check against @suffix
+ * @suffix - NULL-terminated string defining the suffix to look for in @str
+ *
+ * Returns:
+ * True if @str ends with @suffix. False in all other cases.
+ */
+static inline bool strends(const char *str, const char *suffix)
+{
+ unsigned int str_len = strlen(str), suffix_len = strlen(suffix);
+
+ if (str_len < suffix_len)
+ return false;
+
+ return !(strcmp(str + str_len - suffix_len, suffix));
+}
+
#endif /* _LINUX_STRING_H_ */
diff --git a/include/sound/cs-amp-lib.h b/include/sound/cs-amp-lib.h
index 43a87a39110c..61e00017c9aa 100644
--- a/include/sound/cs-amp-lib.h
+++ b/include/sound/cs-amp-lib.h
@@ -47,21 +47,44 @@ struct cirrus_amp_cal_controls {
int cs_amp_write_cal_coeffs(struct cs_dsp *dsp,
const struct cirrus_amp_cal_controls *controls,
const struct cirrus_amp_cal_data *data);
+int cs_amp_read_cal_coeffs(struct cs_dsp *dsp,
+ const struct cirrus_amp_cal_controls *controls,
+ struct cirrus_amp_cal_data *data);
+int cs_amp_write_ambient_temp(struct cs_dsp *dsp,
+ const struct cirrus_amp_cal_controls *controls,
+ u32 temp);
int cs_amp_get_efi_calibration_data(struct device *dev, u64 target_uid, int amp_index,
struct cirrus_amp_cal_data *out_data);
+int cs_amp_set_efi_calibration_data(struct device *dev, int amp_index, int num_amps,
+ const struct cirrus_amp_cal_data *in_data);
int cs_amp_get_vendor_spkid(struct device *dev);
+struct dentry *cs_amp_create_debugfs(struct device *dev);
+
+static inline u64 cs_amp_cal_target_u64(const struct cirrus_amp_cal_data *data)
+{
+ return ((u64)data->calTarget[1] << 32) | data->calTarget[0];
+}
struct cs_amp_test_hooks {
efi_status_t (*get_efi_variable)(efi_char16_t *name,
efi_guid_t *guid,
+ u32 *returned_attr,
unsigned long *size,
void *buf);
+ efi_status_t (*set_efi_variable)(efi_char16_t *name,
+ efi_guid_t *guid,
+ u32 attr,
+ unsigned long size,
+ void *buf);
int (*write_cal_coeff)(struct cs_dsp *dsp,
const struct cirrus_amp_cal_controls *controls,
const char *ctl_name, u32 val);
-};
+ int (*read_cal_coeff)(struct cs_dsp *dsp,
+ const struct cirrus_amp_cal_controls *controls,
+ const char *ctl_name, u32 *val);
+};
extern const struct cs_amp_test_hooks * const cs_amp_test_hooks;
#endif /* CS_AMP_LIB_H */
diff --git a/include/sound/cs35l56.h b/include/sound/cs35l56.h
index ab044ce2aa8b..5928af539c46 100644
--- a/include/sound/cs35l56.h
+++ b/include/sound/cs35l56.h
@@ -9,12 +9,15 @@
#ifndef __CS35L56_H
#define __CS35L56_H
+#include <linux/debugfs.h>
#include <linux/firmware/cirrus/cs_dsp.h>
#include <linux/regulator/consumer.h>
#include <linux/regmap.h>
#include <linux/spi/spi.h>
#include <sound/cs-amp-lib.h>
+struct snd_ctl_elem_value;
+
#define CS35L56_DEVID 0x0000000
#define CS35L56_REVID 0x0000004
#define CS35L56_RELID 0x000000C
@@ -62,6 +65,8 @@
#define CS35L56_IRQ1_MASK_8 0x000E0AC
#define CS35L56_IRQ1_MASK_18 0x000E0D4
#define CS35L56_IRQ1_MASK_20 0x000E0DC
+#define CS35L56_MIXER_NGATE_CH1_CFG 0x0010004
+#define CS35L56_MIXER_NGATE_CH2_CFG 0x0010008
#define CS35L56_DSP_MBOX_1_RAW 0x0011000
#define CS35L56_DSP_VIRTUAL1_MBOX_1 0x0011020
#define CS35L56_DSP_VIRTUAL1_MBOX_2 0x0011024
@@ -177,6 +182,9 @@
/* IRQ1_EINT_8 */
#define CS35L56_TEMP_ERR_EINT1_MASK 0x80000000
+/* MIXER_NGATE_CHn_CFG */
+#define CS35L56_AUX_NGATE_CHn_EN 0x00000001
+
/* Mixer input sources */
#define CS35L56_INPUT_SRC_NONE 0x00
#define CS35L56_INPUT_SRC_ASP1RX1 0x08
@@ -243,6 +251,7 @@
#define CS35L56_MBOX_CMD_AUDIO_PLAY 0x0B000001
#define CS35L56_MBOX_CMD_AUDIO_PAUSE 0x0B000002
#define CS35L56_MBOX_CMD_AUDIO_REINIT 0x0B000003
+#define CS35L56_MBOX_CMD_AUDIO_CALIBRATION 0x0B000006
#define CS35L56_MBOX_CMD_HIBERNATE_NOW 0x02000001
#define CS35L56_MBOX_CMD_WAKEUP 0x02000002
#define CS35L56_MBOX_CMD_PREVENT_AUTO_HIBERNATE 0x02000003
@@ -258,12 +267,22 @@
#define CS35L56_PS3_POLL_US 500
#define CS35L56_PS3_TIMEOUT_US 300000
+#define CS35L56_CAL_STATUS_SUCCESS 1
+#define CS35L56_CAL_STATUS_OUT_OF_RANGE 3
+
+#define CS35L56_CAL_SET_STATUS_UNKNOWN 0
+#define CS35L56_CAL_SET_STATUS_DEFAULT 1
+#define CS35L56_CAL_SET_STATUS_SET 2
+
#define CS35L56_CONTROL_PORT_READY_US 2200
#define CS35L56_HALO_STATE_POLL_US 1000
#define CS35L56_HALO_STATE_TIMEOUT_US 250000
#define CS35L56_RESET_PULSE_MIN_US 1100
#define CS35L56_WAKE_HOLD_TIME_US 1000
+#define CS35L56_CALIBRATION_POLL_US (100 * USEC_PER_MSEC)
+#define CS35L56_CALIBRATION_TIMEOUT_US (5 * USEC_PER_SEC)
+
#define CS35L56_SDW1_PLAYBACK_PORT 1
#define CS35L56_SDW1_CAPTURE_PORT 3
@@ -291,9 +310,16 @@ struct cs35l56_fw_reg {
unsigned int posture_number;
};
+struct cs35l56_cal_debugfs_fops {
+ const struct debugfs_short_fops calibrate;
+ const struct debugfs_short_fops cal_temperature;
+ const struct debugfs_short_fops cal_data;
+};
+
struct cs35l56_base {
struct device *dev;
struct regmap *regmap;
+ struct cs_dsp *dsp;
int irq;
struct mutex irq_lock;
u8 type;
@@ -304,11 +330,14 @@ struct cs35l56_base {
bool can_hibernate;
bool cal_data_valid;
s8 cal_index;
+ u8 num_amps;
struct cirrus_amp_cal_data cal_data;
struct gpio_desc *reset_gpio;
struct cs35l56_spi_payload *spi_payload_buf;
const struct cs35l56_fw_reg *fw_reg;
const struct cirrus_amp_cal_controls *calibration_controls;
+ struct dentry *debugfs;
+ u64 silicon_uid;
};
static inline bool cs35l56_is_otp_register(unsigned int reg)
@@ -340,6 +369,7 @@ extern const struct regmap_config cs35l63_regmap_i2c;
extern const struct regmap_config cs35l63_regmap_sdw;
extern const struct cirrus_amp_cal_controls cs35l56_calibration_controls;
+extern const char * const cs35l56_cal_set_status_text[3];
extern const char * const cs35l56_tx_input_texts[CS35L56_NUM_INPUT_SRC];
extern const unsigned int cs35l56_tx_input_values[CS35L56_NUM_INPUT_SRC];
@@ -358,8 +388,28 @@ int cs35l56_runtime_suspend_common(struct cs35l56_base *cs35l56_base);
int cs35l56_runtime_resume_common(struct cs35l56_base *cs35l56_base, bool is_soundwire);
void cs35l56_init_cs_dsp(struct cs35l56_base *cs35l56_base, struct cs_dsp *cs_dsp);
int cs35l56_get_calibration(struct cs35l56_base *cs35l56_base);
+int cs35l56_stash_calibration(struct cs35l56_base *cs35l56_base,
+ const struct cirrus_amp_cal_data *data);
+ssize_t cs35l56_calibrate_debugfs_write(struct cs35l56_base *cs35l56_base,
+ const char __user *from, size_t count,
+ loff_t *ppos);
+ssize_t cs35l56_cal_ambient_debugfs_write(struct cs35l56_base *cs35l56_base,
+ const char __user *from, size_t count,
+ loff_t *ppos);
+ssize_t cs35l56_cal_data_debugfs_read(struct cs35l56_base *cs35l56_base,
+ char __user *to, size_t count,
+ loff_t *ppos);
+ssize_t cs35l56_cal_data_debugfs_write(struct cs35l56_base *cs35l56_base,
+ const char __user *from, size_t count,
+ loff_t *ppos);
+void cs35l56_create_cal_debugfs(struct cs35l56_base *cs35l56_base,
+ const struct cs35l56_cal_debugfs_fops *fops);
+void cs35l56_remove_cal_debugfs(struct cs35l56_base *cs35l56_base);
+int cs35l56_cal_set_status_get(struct cs35l56_base *cs35l56_base,
+ struct snd_ctl_elem_value *uvalue);
int cs35l56_read_prot_status(struct cs35l56_base *cs35l56_base,
bool *fw_missing, unsigned int *fw_version);
+void cs35l56_warn_if_firmware_missing(struct cs35l56_base *cs35l56_base);
void cs35l56_log_tuning(struct cs35l56_base *cs35l56_base, struct cs_dsp *cs_dsp);
int cs35l56_hw_init(struct cs35l56_base *cs35l56_base);
int cs35l56_get_speaker_id(struct cs35l56_base *cs35l56_base);
diff --git a/include/sound/sdca.h b/include/sound/sdca.h
index 9c6a351c9d47..67ff3c88705d 100644
--- a/include/sound/sdca.h
+++ b/include/sound/sdca.h
@@ -12,19 +12,24 @@
#include <linux/types.h>
#include <linux/kconfig.h>
+struct acpi_table_swft;
+struct fwnode_handle;
struct sdw_slave;
+struct sdca_dev;
#define SDCA_MAX_FUNCTION_COUNT 8
/**
* struct sdca_function_desc - short descriptor for an SDCA Function
* @node: firmware node for the Function.
+ * @func_dev: pointer to SDCA function device.
* @name: Human-readable string.
* @type: Function topology type.
* @adr: ACPI address (used for SDCA register access).
*/
struct sdca_function_desc {
struct fwnode_handle *node;
+ struct sdca_dev *func_dev;
const char *name;
u32 type;
u8 adr;
@@ -37,11 +42,13 @@ struct sdca_function_desc {
* @num_functions: Total number of supported SDCA functions. Invalid/unsupported
* functions will be skipped.
* @function: Array of function descriptors.
+ * @swft: Pointer to the SWFT table, if available.
*/
struct sdca_device_data {
u32 interface_revision;
int num_functions;
struct sdca_function_desc function[SDCA_MAX_FUNCTION_COUNT];
+ struct acpi_table_swft *swft;
};
enum sdca_quirk {
@@ -52,17 +59,29 @@ enum sdca_quirk {
#if IS_ENABLED(CONFIG_ACPI) && IS_ENABLED(CONFIG_SND_SOC_SDCA)
void sdca_lookup_functions(struct sdw_slave *slave);
+void sdca_lookup_swft(struct sdw_slave *slave);
void sdca_lookup_interface_revision(struct sdw_slave *slave);
bool sdca_device_quirk_match(struct sdw_slave *slave, enum sdca_quirk quirk);
+int sdca_dev_register_functions(struct sdw_slave *slave);
+void sdca_dev_unregister_functions(struct sdw_slave *slave);
#else
static inline void sdca_lookup_functions(struct sdw_slave *slave) {}
+static inline void sdca_lookup_swft(struct sdw_slave *slave) {}
static inline void sdca_lookup_interface_revision(struct sdw_slave *slave) {}
static inline bool sdca_device_quirk_match(struct sdw_slave *slave, enum sdca_quirk quirk)
{
return false;
}
+
+static inline int sdca_dev_register_functions(struct sdw_slave *slave)
+{
+ return 0;
+}
+
+static inline void sdca_dev_unregister_functions(struct sdw_slave *slave) {}
+
#endif
#endif
diff --git a/include/sound/sdca_fdl.h b/include/sound/sdca_fdl.h
new file mode 100644
index 000000000000..fbaf4b384c8a
--- /dev/null
+++ b/include/sound/sdca_fdl.h
@@ -0,0 +1,105 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * The MIPI SDCA specification is available for public downloads at
+ * https://www.mipi.org/mipi-sdca-v1-0-download
+ *
+ * Copyright (C) 2025 Cirrus Logic, Inc. and
+ * Cirrus Logic International Semiconductor Ltd.
+ */
+
+#ifndef __SDCA_FDL_H__
+#define __SDCA_FDL_H__
+
+#include <linux/completion.h>
+#include <linux/workqueue.h>
+
+struct device;
+struct regmap;
+struct sdca_fdl_set;
+struct sdca_function_data;
+struct sdca_interrupt;
+struct sdca_interrupt_info;
+
+/**
+ * struct fdl_state - FDL state structure to keep data between interrupts
+ * @begin: Completion indicating the start of an FDL download cycle.
+ * @done: Completion indicating the end of an FDL download cycle.
+ * @timeout: Delayed work used for timing out UMP transactions.
+ * @lock: Mutex to protect between the timeout work and IRQ handlers.
+ * @interrupt: Pointer to the interrupt struct to which this FDL is attached.
+ * @set: Pointer to the FDL set currently being downloaded.
+ * @file_index: Index of the current file being processed.
+ */
+struct fdl_state {
+ struct completion begin;
+ struct completion done;
+ struct delayed_work timeout;
+ struct mutex lock;
+
+ struct sdca_interrupt *interrupt;
+ struct sdca_fdl_set *set;
+ int file_index;
+};
+
+#define SDCA_CTL_XU_FDLH_COMPLETE 0
+#define SDCA_CTL_XU_FDLH_MORE_FILES SDCA_CTL_XU_FDLH_SET_IN_PROGRESS
+#define SDCA_CTL_XU_FDLH_FILE_AVAILABLE (SDCA_CTL_XU_FDLH_TRANSFERRED_FILE | \
+ SDCA_CTL_XU_FDLH_SET_IN_PROGRESS)
+#define SDCA_CTL_XU_FDLH_MASK (SDCA_CTL_XU_FDLH_TRANSFERRED_CHUNK | \
+ SDCA_CTL_XU_FDLH_TRANSFERRED_FILE | \
+ SDCA_CTL_XU_FDLH_SET_IN_PROGRESS | \
+ SDCA_CTL_XU_FDLH_RESET_ACK | \
+ SDCA_CTL_XU_FDLH_REQ_ABORT)
+
+#define SDCA_CTL_XU_FDLD_COMPLETE 0
+#define SDCA_CTL_XU_FDLD_FILE_OK (SDCA_CTL_XU_FDLH_TRANSFERRED_FILE | \
+ SDCA_CTL_XU_FDLH_SET_IN_PROGRESS | \
+ SDCA_CTL_XU_FDLD_ACK_TRANSFER | \
+ SDCA_CTL_XU_FDLD_NEEDS_SET)
+#define SDCA_CTL_XU_FDLD_MORE_FILES_OK (SDCA_CTL_XU_FDLH_SET_IN_PROGRESS | \
+ SDCA_CTL_XU_FDLD_ACK_TRANSFER | \
+ SDCA_CTL_XU_FDLD_NEEDS_SET)
+#define SDCA_CTL_XU_FDLD_MASK (SDCA_CTL_XU_FDLD_REQ_RESET | \
+ SDCA_CTL_XU_FDLD_REQ_ABORT | \
+ SDCA_CTL_XU_FDLD_ACK_TRANSFER | \
+ SDCA_CTL_XU_FDLD_NEEDS_SET)
+
+#if IS_ENABLED(CONFIG_SND_SOC_SDCA_FDL)
+
+int sdca_fdl_alloc_state(struct sdca_interrupt *interrupt);
+int sdca_fdl_process(struct sdca_interrupt *interrupt);
+int sdca_fdl_sync(struct device *dev, struct sdca_function_data *function,
+ struct sdca_interrupt_info *info);
+
+int sdca_reset_function(struct device *dev, struct sdca_function_data *function,
+ struct regmap *regmap);
+
+#else
+
+static inline int sdca_fdl_alloc_state(struct sdca_interrupt *interrupt)
+{
+ return 0;
+}
+
+static inline int sdca_fdl_process(struct sdca_interrupt *interrupt)
+{
+ return 0;
+}
+
+static inline int sdca_fdl_sync(struct device *dev,
+ struct sdca_function_data *function,
+ struct sdca_interrupt_info *info)
+{
+ return 0;
+}
+
+static inline int sdca_reset_function(struct device *dev,
+ struct sdca_function_data *function,
+ struct regmap *regmap)
+{
+ return 0;
+}
+
+#endif // CONFIG_SND_SOC_SDCA_FDL
+
+#endif // __SDCA_FDL_H__
diff --git a/include/sound/sdca_function.h b/include/sound/sdca_function.h
index ea68856e4c8c..6e9391b3816c 100644
--- a/include/sound/sdca_function.h
+++ b/include/sound/sdca_function.h
@@ -13,6 +13,7 @@
#include <linux/types.h>
#include <linux/hid.h>
+struct acpi_table_swft;
struct device;
struct sdca_entity;
struct sdca_function_desc;
@@ -63,6 +64,7 @@ struct sdca_function_desc;
* @SDCA_FUNCTION_TYPE_RJ: Retaskable jack.
* @SDCA_FUNCTION_TYPE_SIMPLE_JACK: Subset of UAJ.
* @SDCA_FUNCTION_TYPE_HID: Human Interface Device, for e.g. buttons.
+ * @SDCA_FUNCTION_TYPE_COMPANION_AMP: Sources audio from another amp.
* @SDCA_FUNCTION_TYPE_IMP_DEF: Implementation-defined function.
*
* SDCA Function Types from SDCA specification v1.0a Section 5.1.2
@@ -82,6 +84,7 @@ enum sdca_function_type {
SDCA_FUNCTION_TYPE_RJ = 0x07,
SDCA_FUNCTION_TYPE_SIMPLE_JACK = 0x08,
SDCA_FUNCTION_TYPE_HID = 0x0A,
+ SDCA_FUNCTION_TYPE_COMPANION_AMP = 0x0B,
SDCA_FUNCTION_TYPE_IMP_DEF = 0x1F,
};
@@ -95,6 +98,7 @@ enum sdca_function_type {
#define SDCA_FUNCTION_TYPE_RJ_NAME "RJ"
#define SDCA_FUNCTION_TYPE_SIMPLE_NAME "SimpleJack"
#define SDCA_FUNCTION_TYPE_HID_NAME "HID"
+#define SDCA_FUNCTION_TYPE_COMPANION_AMP_NAME "CompanionAmp"
#define SDCA_FUNCTION_TYPE_IMP_DEF_NAME "ImplementationDefined"
/**
@@ -134,6 +138,32 @@ struct sdca_init_write {
SDCA_CTL_##ent##_##sel)
/**
+ * enum sdca_messageoffset_range - Column definitions UMP MessageOffset
+ */
+enum sdca_messageoffset_range {
+ SDCA_MESSAGEOFFSET_BUFFER_START_ADDRESS = 0,
+ SDCA_MESSAGEOFFSET_BUFFER_LENGTH = 1,
+ SDCA_MESSAGEOFFSET_UMP_MODE = 2,
+ SDCA_MESSAGEOFFSET_NCOLS = 3,
+};
+
+/**
+ * enum sdca_ump_mode - SDCA UMP Mode
+ */
+enum sdca_ump_mode {
+ SDCA_UMP_MODE_DIRECT = 0x00,
+ SDCA_UMP_MODE_INDIRECT = 0x01,
+};
+
+/**
+ * enum sdca_ump_owner - SDCA UMP Owner
+ */
+enum sdca_ump_owner {
+ SDCA_UMP_OWNER_HOST = 0x00,
+ SDCA_UMP_OWNER_DEVICE = 0x01,
+};
+
+/**
* enum sdca_it_controls - SDCA Controls for Input Terminal
*
* Control Selectors for Input Terminal from SDCA specification v1.0
@@ -258,6 +288,27 @@ enum sdca_xu_controls {
SDCA_CTL_XU_FDL_STATUS = 0x14,
SDCA_CTL_XU_FDL_SET_INDEX = 0x15,
SDCA_CTL_XU_FDL_HOST_REQUEST = 0x16,
+
+ /* FDL Status Host->Device bit definitions */
+ SDCA_CTL_XU_FDLH_TRANSFERRED_CHUNK = BIT(0),
+ SDCA_CTL_XU_FDLH_TRANSFERRED_FILE = BIT(1),
+ SDCA_CTL_XU_FDLH_SET_IN_PROGRESS = BIT(2),
+ SDCA_CTL_XU_FDLH_RESET_ACK = BIT(4),
+ SDCA_CTL_XU_FDLH_REQ_ABORT = BIT(5),
+ /* FDL Status Device->Host bit definitions */
+ SDCA_CTL_XU_FDLD_REQ_RESET = BIT(4),
+ SDCA_CTL_XU_FDLD_REQ_ABORT = BIT(5),
+ SDCA_CTL_XU_FDLD_ACK_TRANSFER = BIT(6),
+ SDCA_CTL_XU_FDLD_NEEDS_SET = BIT(7),
+};
+
+/**
+ * enum sdca_set_index_range - Column definitions UMP SetIndex
+ */
+enum sdca_fdl_set_index_range {
+ SDCA_FDL_SET_INDEX_SET_NUMBER = 0,
+ SDCA_FDL_SET_INDEX_FILE_SET_ID = 1,
+ SDCA_FDL_SET_INDEX_NCOLS = 2,
};
/**
@@ -542,6 +593,9 @@ enum sdca_entity0_controls {
SDCA_CTL_ENTITY_0_FUNCTION_NEEDS_INITIALIZATION = BIT(5),
SDCA_CTL_ENTITY_0_FUNCTION_HAS_BEEN_RESET = BIT(6),
SDCA_CTL_ENTITY_0_FUNCTION_BUSY = BIT(7),
+
+ /* Function Action Bits */
+ SDCA_CTL_ENTITY_0_RESET_FUNCTION_NOW = BIT(0),
};
#define SDCA_CTL_MIC_BIAS_NAME "Mic Bias"
@@ -557,7 +611,7 @@ enum sdca_entity0_controls {
#define SDCA_CTL_NDAI_PACKETTYPE_NAME "NDAI Packet Type"
#define SDCA_CTL_MIXER_NAME "Mixer"
#define SDCA_CTL_SELECTOR_NAME "Selector"
-#define SDCA_CTL_MUTE_NAME "Mute"
+#define SDCA_CTL_MUTE_NAME "Channel"
#define SDCA_CTL_CHANNEL_VOLUME_NAME "Channel Volume"
#define SDCA_CTL_AGC_NAME "AGC"
#define SDCA_CTL_BASS_BOOST_NAME "Bass Boost"
@@ -771,6 +825,7 @@ struct sdca_control {
u8 layers;
bool deferrable;
+ bool is_volatile;
bool has_default;
bool has_fixed;
};
@@ -1090,6 +1145,27 @@ struct sdca_entity_hide {
};
/**
+ * enum sdca_xu_reset_machanism - SDCA FDL Resets
+ */
+enum sdca_xu_reset_mechanism {
+ SDCA_XU_RESET_FUNCTION = 0x0,
+ SDCA_XU_RESET_DEVICE = 0x1,
+ SDCA_XU_RESET_BUS = 0x2,
+};
+
+/**
+ * struct sdca_entity_xu - information specific to XU Entities
+ * @max_delay: the maximum time in microseconds allowed for the Device
+ * to change the ownership from Device to Host
+ * @reset_mechanism: indicates the type of reset that can be requested
+ * the end of an FDL.
+ */
+struct sdca_entity_xu {
+ unsigned int max_delay;
+ enum sdca_xu_reset_mechanism reset_mechanism;
+};
+
+/**
* struct sdca_entity - information for one SDCA Entity
* @label: String such as "OT 12".
* @id: Identifier used for addressing.
@@ -1105,6 +1181,7 @@ struct sdca_entity_hide {
* @pde: Power Domain Entity specific Entity properties.
* @ge: Group Entity specific Entity properties.
* @hide: HIDE Entity specific Entity properties.
+ * @xu: XU Entity specific Entity properties.
*/
struct sdca_entity {
const char *label;
@@ -1122,6 +1199,7 @@ struct sdca_entity {
struct sdca_entity_pde pde;
struct sdca_entity_ge ge;
struct sdca_entity_hide hide;
+ struct sdca_entity_xu xu;
};
};
@@ -1289,6 +1367,42 @@ enum sdca_cluster_range {
};
/**
+ * struct sdca_fdl_file - information about a file from a fileset used in FDL
+ * @vendor_id: Vendor ID of the file.
+ * @file_id: File ID of the file.
+ * @fdl_offset: Offset information for FDL.
+ */
+struct sdca_fdl_file {
+ u16 vendor_id;
+ u32 file_id;
+ u32 fdl_offset;
+};
+
+/**
+ * struct sdca_fdl_set - information about a set of files used in FDL
+ * @files: Array of files in this FDL set.
+ * @num_files: Number of files in this FDL set.
+ * @id: ID of the FDL set.
+ */
+struct sdca_fdl_set {
+ struct sdca_fdl_file *files;
+ int num_files;
+ u32 id;
+};
+
+/**
+ * struct sdca_fdl_data - information about a function's FDL data
+ * @swft: Pointer to the SoundWire File Table.
+ * @sets: Array of FDL sets used by this function.
+ * @num_sets: Number of FDL sets used by this function.
+ */
+struct sdca_fdl_data {
+ struct acpi_table_swft *swft;
+ struct sdca_fdl_set *sets;
+ int num_sets;
+};
+
+/**
* struct sdca_function_data - top-level information for one SDCA function
* @desc: Pointer to short descriptor from initial parsing.
* @init_table: Pointer to a table of initialization writes.
@@ -1299,6 +1413,9 @@ enum sdca_cluster_range {
* @num_clusters: Number of Channel Clusters reported in this Function.
* @busy_max_delay: Maximum Function busy delay in microseconds, before an
* error should be reported.
+ * @reset_max_delay: Maximum Function reset delay in microseconds, before an
+ * error should be reported.
+ * @fdl_data: FDL data for this Function, if available.
*/
struct sdca_function_data {
struct sdca_function_desc *desc;
@@ -1311,6 +1428,9 @@ struct sdca_function_data {
int num_clusters;
unsigned int busy_max_delay;
+ unsigned int reset_max_delay;
+
+ struct sdca_fdl_data fdl_data;
};
static inline u32 sdca_range(struct sdca_control_range *range,
@@ -1332,10 +1452,12 @@ static inline u32 sdca_range_search(struct sdca_control_range *range,
return 0;
}
-int sdca_parse_function(struct device *dev,
+int sdca_parse_function(struct device *dev, struct sdw_slave *sdw,
struct sdca_function_desc *desc,
struct sdca_function_data *function);
+const char *sdca_find_terminal_name(enum sdca_terminal_type type);
+
struct sdca_control *sdca_selector_find_control(struct device *dev,
struct sdca_entity *entity,
const int sel);
diff --git a/include/sound/sdca_hid.h b/include/sound/sdca_hid.h
index 8ab3e498884e..18bebbe428c9 100644
--- a/include/sound/sdca_hid.h
+++ b/include/sound/sdca_hid.h
@@ -8,14 +8,27 @@
#ifndef __SDCA_HID_H__
#define __SDCA_HID_H__
-#include <linux/types.h>
-#include <linux/hid.h>
+struct device;
+struct sdw_slave;
+
+struct sdca_entity;
+struct sdca_interrupt;
#if IS_ENABLED(CONFIG_SND_SOC_SDCA_HID)
-int sdca_add_hid_device(struct device *dev, struct sdca_entity *entity);
+
+int sdca_add_hid_device(struct device *dev, struct sdw_slave *sdw,
+ struct sdca_entity *entity);
+int sdca_hid_process_report(struct sdca_interrupt *interrupt);
#else
-static inline int sdca_add_hid_device(struct device *dev, struct sdca_entity *entity)
+
+static inline int sdca_add_hid_device(struct device *dev, struct sdw_slave *sdw,
+ struct sdca_entity *entity)
+{
+ return 0;
+}
+
+static inline int sdca_hid_process_report(struct sdca_interrupt *interrupt)
{
return 0;
}
diff --git a/include/sound/sdca_interrupts.h b/include/sound/sdca_interrupts.h
index bbbc3ab27eba..8f13417d129a 100644
--- a/include/sound/sdca_interrupts.h
+++ b/include/sound/sdca_interrupts.h
@@ -23,18 +23,23 @@ struct sdca_function_data;
/**
* struct sdca_interrupt - contains information about a single SDCA interrupt
* @name: The name of the interrupt.
+ * @dev: Pointer to the Function device.
+ * @device_regmap: Pointer to the IRQ regmap.
+ * @function_regmap: Pointer to the SDCA Function regmap.
* @component: Pointer to the ASoC component owns the interrupt.
* @function: Pointer to the Function that the interrupt is associated with.
* @entity: Pointer to the Entity that the interrupt is associated with.
* @control: Pointer to the Control that the interrupt is associated with.
* @priv: Pointer to private data for use by the handler.
- * @externally_requested: Internal flag used to check if a client driver has
- * already requested the interrupt, for custom handling, allowing the core to
- * skip handling this interrupt.
+ * @irq: IRQ number allocated to this interrupt, also used internally to track
+ * the IRQ being assigned.
*/
struct sdca_interrupt {
const char *name;
+ struct device *dev;
+ struct regmap *device_regmap;
+ struct regmap *function_regmap;
struct snd_soc_component *component;
struct sdca_function_data *function;
struct sdca_entity *entity;
@@ -42,7 +47,7 @@ struct sdca_interrupt {
void *priv;
- bool externally_requested;
+ int irq;
};
/**
@@ -64,11 +69,15 @@ struct sdca_interrupt_info {
int sdca_irq_request(struct device *dev, struct sdca_interrupt_info *interrupt_info,
int sdca_irq, const char *name, irq_handler_t handler,
void *data);
-int sdca_irq_data_populate(struct snd_soc_component *component,
+int sdca_irq_data_populate(struct device *dev, struct regmap *function_regmap,
+ struct snd_soc_component *component,
struct sdca_function_data *function,
struct sdca_entity *entity,
struct sdca_control *control,
struct sdca_interrupt *interrupt);
+int sdca_irq_populate_early(struct device *dev, struct regmap *function_regmap,
+ struct sdca_function_data *function,
+ struct sdca_interrupt_info *info);
int sdca_irq_populate(struct sdca_function_data *function,
struct snd_soc_component *component,
struct sdca_interrupt_info *info);
diff --git a/include/sound/sdca_regmap.h b/include/sound/sdca_regmap.h
index b2e3c2ad2bb8..792540a530fc 100644
--- a/include/sound/sdca_regmap.h
+++ b/include/sound/sdca_regmap.h
@@ -27,5 +27,7 @@ int sdca_regmap_populate_constants(struct device *dev, struct sdca_function_data
int sdca_regmap_write_defaults(struct device *dev, struct regmap *regmap,
struct sdca_function_data *function);
+int sdca_regmap_write_init(struct device *dev, struct regmap *regmap,
+ struct sdca_function_data *function);
#endif // __SDCA_REGMAP_H__
diff --git a/include/sound/sdca_ump.h b/include/sound/sdca_ump.h
new file mode 100644
index 000000000000..f54f9d48c64c
--- /dev/null
+++ b/include/sound/sdca_ump.h
@@ -0,0 +1,50 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * The MIPI SDCA specification is available for public downloads at
+ * https://www.mipi.org/mipi-sdca-v1-0-download
+ *
+ * Copyright (C) 2025 Cirrus Logic, Inc. and
+ * Cirrus Logic International Semiconductor Ltd.
+ */
+
+#ifndef __SDCA_UMP_H__
+#define __SDCA_UMP_H__
+
+struct regmap;
+struct sdca_control;
+struct sdca_entity;
+struct sdca_function_data;
+struct snd_soc_component;
+struct delayed_work;
+
+int sdca_ump_get_owner_host(struct device *dev,
+ struct regmap *function_regmap,
+ struct sdca_function_data *function,
+ struct sdca_entity *entity,
+ struct sdca_control *control);
+int sdca_ump_set_owner_device(struct device *dev,
+ struct regmap *function_regmap,
+ struct sdca_function_data *function,
+ struct sdca_entity *entity,
+ struct sdca_control *control);
+int sdca_ump_read_message(struct device *dev,
+ struct regmap *device_regmap,
+ struct regmap *function_regmap,
+ struct sdca_function_data *function,
+ struct sdca_entity *entity,
+ unsigned int offset_sel, unsigned int length_sel,
+ void **msg);
+int sdca_ump_write_message(struct device *dev,
+ struct regmap *device_regmap,
+ struct regmap *function_regmap,
+ struct sdca_function_data *function,
+ struct sdca_entity *entity,
+ unsigned int offset_sel, unsigned int msg_offset,
+ unsigned int length_sel,
+ void *msg, int msg_len);
+
+void sdca_ump_cancel_timeout(struct delayed_work *work);
+void sdca_ump_schedule_timeout(struct delayed_work *work,
+ unsigned int timeout_us);
+
+#endif // __SDCA_UMP_H__
diff --git a/include/sound/soc-acpi-intel-match.h b/include/sound/soc-acpi-intel-match.h
index daed7123df9d..382029724e85 100644
--- a/include/sound/soc-acpi-intel-match.h
+++ b/include/sound/soc-acpi-intel-match.h
@@ -34,6 +34,7 @@ extern struct snd_soc_acpi_mach snd_soc_acpi_intel_mtl_machines[];
extern struct snd_soc_acpi_mach snd_soc_acpi_intel_lnl_machines[];
extern struct snd_soc_acpi_mach snd_soc_acpi_intel_arl_machines[];
extern struct snd_soc_acpi_mach snd_soc_acpi_intel_ptl_machines[];
+extern struct snd_soc_acpi_mach snd_soc_acpi_intel_nvl_machines[];
extern struct snd_soc_acpi_mach snd_soc_acpi_intel_cnl_sdw_machines[];
extern struct snd_soc_acpi_mach snd_soc_acpi_intel_cfl_sdw_machines[];
@@ -46,6 +47,7 @@ extern struct snd_soc_acpi_mach snd_soc_acpi_intel_mtl_sdw_machines[];
extern struct snd_soc_acpi_mach snd_soc_acpi_intel_lnl_sdw_machines[];
extern struct snd_soc_acpi_mach snd_soc_acpi_intel_arl_sdw_machines[];
extern struct snd_soc_acpi_mach snd_soc_acpi_intel_ptl_sdw_machines[];
+extern struct snd_soc_acpi_mach snd_soc_acpi_intel_nvl_sdw_machines[];
/*
* generic table used for HDA codec-based platforms, possibly with
diff --git a/include/sound/soc-acpi.h b/include/sound/soc-acpi.h
index b8af309c2683..90d73b9bddab 100644
--- a/include/sound/soc-acpi.h
+++ b/include/sound/soc-acpi.h
@@ -114,8 +114,8 @@ struct snd_soc_acpi_endpoint {
* @name_prefix: string used for codec controls
*/
struct snd_soc_acpi_adr_device {
- const u64 adr;
- const u8 num_endpoints;
+ u64 adr;
+ u8 num_endpoints;
const struct snd_soc_acpi_endpoint *endpoints;
const char *name_prefix;
};
@@ -131,8 +131,8 @@ struct snd_soc_acpi_adr_device {
*/
struct snd_soc_acpi_link_adr {
- const u32 mask;
- const u32 num_adr;
+ u32 mask;
+ u32 num_adr;
const struct snd_soc_acpi_adr_device *adr_d;
};
diff --git a/include/sound/soc.h b/include/sound/soc.h
index ddc508ff7b9b..aa0fe6b80293 100644
--- a/include/sound/soc.h
+++ b/include/sound/soc.h
@@ -319,6 +319,13 @@ struct platform_device;
#define SOC_VALUE_ENUM_EXT(xname, xenum, xhandler_get, xhandler_put) \
SOC_ENUM_EXT(xname, xenum, xhandler_get, xhandler_put)
+#define SOC_ENUM_EXT_ACC(xname, xenum, xhandler_get, xhandler_put, xaccess) \
+{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \
+ .access = xaccess, \
+ .info = snd_soc_info_enum_double, \
+ .get = xhandler_get, .put = xhandler_put, \
+ .private_value = (unsigned long)&xenum }
+
#define SND_SOC_BYTES(xname, xbase, xregs) \
{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \
.info = snd_soc_bytes_info, .get = snd_soc_bytes_get, \
@@ -331,6 +338,13 @@ struct platform_device;
.put = xhandler_put, .private_value = \
((unsigned long)&(struct soc_bytes) \
{.base = xbase, .num_regs = xregs }) }
+#define SND_SOC_BYTES_E_ACC(xname, xbase, xregs, xhandler_get, xhandler_put, xaccess) \
+{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \
+ .access = xaccess, \
+ .info = snd_soc_bytes_info, .get = xhandler_get, \
+ .put = xhandler_put, .private_value = \
+ ((unsigned long)&(struct soc_bytes) \
+ {.base = xbase, .num_regs = xregs }) }
#define SND_SOC_BYTES_MASK(xname, xbase, xregs, xmask) \
{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \
@@ -1225,6 +1239,7 @@ struct soc_mixer_control {
unsigned int sign_bit;
unsigned int invert:1;
unsigned int autodisable:1;
+ unsigned int sdca_q78:1;
#ifdef CONFIG_SND_SOC_TOPOLOGY
struct snd_soc_dobj dobj;
#endif
@@ -1305,22 +1320,6 @@ static inline unsigned int snd_soc_enum_item_to_val(const struct soc_enum *e,
return e->values[item];
}
-/**
- * snd_soc_kcontrol_component() - Returns the component that registered the
- * control
- * @kcontrol: The control for which to get the component
- *
- * Note: This function will work correctly if the control has been registered
- * for a component. With snd_soc_add_codec_controls() or via table based
- * setup for either a CODEC or component driver. Otherwise the behavior is
- * undefined.
- */
-static inline struct snd_soc_component *snd_soc_kcontrol_component(
- struct snd_kcontrol *kcontrol)
-{
- return snd_kcontrol_chip(kcontrol);
-}
-
int snd_soc_util_init(void);
void snd_soc_util_exit(void);
@@ -1482,22 +1481,22 @@ static inline void _snd_soc_dapm_mutex_assert_held_c(struct snd_soc_card *card)
static inline void _snd_soc_dapm_mutex_lock_root_d(struct snd_soc_dapm_context *dapm)
{
- _snd_soc_dapm_mutex_lock_root_c(dapm->card);
+ _snd_soc_dapm_mutex_lock_root_c(snd_soc_dapm_to_card(dapm));
}
static inline void _snd_soc_dapm_mutex_lock_d(struct snd_soc_dapm_context *dapm)
{
- _snd_soc_dapm_mutex_lock_c(dapm->card);
+ _snd_soc_dapm_mutex_lock_c(snd_soc_dapm_to_card(dapm));
}
static inline void _snd_soc_dapm_mutex_unlock_d(struct snd_soc_dapm_context *dapm)
{
- _snd_soc_dapm_mutex_unlock_c(dapm->card);
+ _snd_soc_dapm_mutex_unlock_c(snd_soc_dapm_to_card(dapm));
}
static inline void _snd_soc_dapm_mutex_assert_held_d(struct snd_soc_dapm_context *dapm)
{
- _snd_soc_dapm_mutex_assert_held_c(dapm->card);
+ _snd_soc_dapm_mutex_assert_held_c(snd_soc_dapm_to_card(dapm));
}
#define snd_soc_dapm_mutex_lock_root(x) _Generic((x), \
diff --git a/include/sound/soc_sdw_utils.h b/include/sound/soc_sdw_utils.h
index 3c5e9b2af7f1..227347c8f0b3 100644
--- a/include/sound/soc_sdw_utils.h
+++ b/include/sound/soc_sdw_utils.h
@@ -13,6 +13,7 @@
#include <sound/soc-acpi.h>
#define SOC_SDW_MAX_DAI_NUM 8
+#define SOC_SDW_MAX_AUX_NUM 2
#define SOC_SDW_MAX_NO_PROPS 2
#define SOC_SDW_JACK_JDSRC(quirk) ((quirk) & GENMASK(3, 0))
@@ -45,6 +46,7 @@ struct asoc_sdw_codec_info;
struct asoc_sdw_dai_info {
const bool direction[2]; /* playback & capture support */
+ const char *codec_name;
const char *dai_name;
const char *component_name;
const int dai_type;
@@ -64,16 +66,22 @@ struct asoc_sdw_dai_info {
bool quirk_exclude;
};
+struct asoc_sdw_aux_info {
+ const char *codec_name;
+};
+
struct asoc_sdw_codec_info {
const int part_id;
const int version_id;
- const char *codec_name;
+ const char *name_prefix;
int amp_num;
const u8 acpi_id[ACPI_ID_LEN];
const bool ignore_internal_dmic;
const struct snd_soc_ops *ops;
struct asoc_sdw_dai_info dais[SOC_SDW_MAX_DAI_NUM];
const int dai_num;
+ struct asoc_sdw_aux_info auxs[SOC_SDW_MAX_AUX_NUM];
+ const int aux_num;
int (*codec_card_late_probe)(struct snd_soc_card *card);
@@ -130,7 +138,7 @@ int asoc_sdw_hw_free(struct snd_pcm_substream *substream);
void asoc_sdw_shutdown(struct snd_pcm_substream *substream);
const char *asoc_sdw_get_codec_name(struct device *dev,
- const struct asoc_sdw_codec_info *codec_info,
+ const struct asoc_sdw_dai_info *dai_info,
const struct snd_soc_acpi_link_adr *adr_link,
int adr_index);
@@ -164,12 +172,15 @@ int asoc_sdw_init_simple_dai_link(struct device *dev, struct snd_soc_dai_link *d
int no_pcm, int (*init)(struct snd_soc_pcm_runtime *rtd),
const struct snd_soc_ops *ops);
-int asoc_sdw_count_sdw_endpoints(struct snd_soc_card *card, int *num_devs, int *num_ends);
+int asoc_sdw_count_sdw_endpoints(struct snd_soc_card *card,
+ int *num_devs, int *num_ends, int *num_aux);
struct asoc_sdw_dailink *asoc_sdw_find_dailink(struct asoc_sdw_dailink *dailinks,
const struct snd_soc_acpi_endpoint *new);
+int asoc_sdw_get_dai_type(u32 type);
int asoc_sdw_parse_sdw_endpoints(struct snd_soc_card *card,
+ struct snd_soc_aux_dev *soc_aux,
struct asoc_sdw_dailink *soc_dais,
struct asoc_sdw_endpoint *soc_ends,
int *num_devs);
@@ -246,6 +257,8 @@ int asoc_sdw_cs42l42_rtd_init(struct snd_soc_pcm_runtime *rtd, struct snd_soc_da
int asoc_sdw_cs42l43_hs_rtd_init(struct snd_soc_pcm_runtime *rtd, struct snd_soc_dai *dai);
int asoc_sdw_cs42l43_spk_rtd_init(struct snd_soc_pcm_runtime *rtd, struct snd_soc_dai *dai);
int asoc_sdw_cs42l43_dmic_rtd_init(struct snd_soc_pcm_runtime *rtd, struct snd_soc_dai *dai);
+int asoc_sdw_cs42l45_hs_rtd_init(struct snd_soc_pcm_runtime *rtd, struct snd_soc_dai *dai);
+int asoc_sdw_cs42l45_dmic_rtd_init(struct snd_soc_pcm_runtime *rtd, struct snd_soc_dai *dai);
int asoc_sdw_cs_spk_rtd_init(struct snd_soc_pcm_runtime *rtd, struct snd_soc_dai *dai);
int asoc_sdw_maxim_spk_rtd_init(struct snd_soc_pcm_runtime *rtd, struct snd_soc_dai *dai);
/* TI */
diff --git a/include/sound/tas2781.h b/include/sound/tas2781.h
index 0fbcdb15c74b..9d3c54cb8223 100644
--- a/include/sound/tas2781.h
+++ b/include/sound/tas2781.h
@@ -117,14 +117,20 @@ enum audio_device {
TAS2120,
TAS2320,
TAS2563,
+ TAS2568,
TAS2570,
TAS2572,
+ TAS2574,
TAS2781,
TAS5802,
+ TAS5806M,
+ TAS5806MD,
TAS5815,
+ TAS5822,
TAS5825,
TAS5827,
TAS5828,
+ TAS5830,
TAS_OTHERS,
};
@@ -197,7 +203,6 @@ struct tasdevice_priv {
struct acoustic_data acou_data;
#endif
struct tasdevice_fw *fmw;
- struct gpio_desc *speaker_id;
struct gpio_desc *reset;
struct mutex codec_lock;
struct regmap *regmap;
@@ -215,6 +220,7 @@ struct tasdevice_priv {
unsigned int magic_num;
unsigned int chip_id;
unsigned int sysclk;
+ int speaker_id;
int irq;
int cur_prog;
diff --git a/include/trace/events/asoc.h b/include/trace/events/asoc.h
index 6696dbcc2b96..4a645549164e 100644
--- a/include/trace/events/asoc.h
+++ b/include/trace/events/asoc.h
@@ -27,8 +27,8 @@ DECLARE_EVENT_CLASS(snd_soc_dapm,
TP_ARGS(dapm, val),
TP_STRUCT__entry(
- __string( card_name, dapm->card->name)
- __string( comp_name, dapm->component ? dapm->component->name : "(none)")
+ __string( card_name, snd_soc_dapm_to_card(dapm)->name)
+ __string( comp_name, snd_soc_dapm_to_component(dapm) ? snd_soc_dapm_to_component(dapm)->name : "(none)")
__field( int, val)
),
diff --git a/include/uapi/sound/intel/avs/tokens.h b/include/uapi/sound/intel/avs/tokens.h
index f3ff6aae09a9..3ff6d9150822 100644
--- a/include/uapi/sound/intel/avs/tokens.h
+++ b/include/uapi/sound/intel/avs/tokens.h
@@ -21,6 +21,7 @@ enum avs_tplg_token {
AVS_TKN_MANIFEST_NUM_BINDINGS_U32 = 8,
AVS_TKN_MANIFEST_NUM_CONDPATH_TMPLS_U32 = 9,
AVS_TKN_MANIFEST_NUM_INIT_CONFIGS_U32 = 10,
+ AVS_TKN_MANIFEST_NUM_NHLT_CONFIGS_U32 = 11,
/* struct avs_tplg_library */
AVS_TKN_LIBRARY_ID_U32 = 101,
@@ -124,6 +125,7 @@ enum avs_tplg_token {
AVS_TKN_MOD_KCONTROL_ID_U32 = 1707,
AVS_TKN_MOD_INIT_CONFIG_NUM_IDS_U32 = 1708,
AVS_TKN_MOD_INIT_CONFIG_ID_U32 = 1709,
+ AVS_TKN_MOD_NHLT_CONFIG_ID_U32 = 1710,
/* struct avs_tplg_path_template */
AVS_TKN_PATH_TMPL_ID_U32 = 1801,
@@ -160,6 +162,10 @@ enum avs_tplg_token {
AVS_TKN_INIT_CONFIG_ID_U32 = 2401,
AVS_TKN_INIT_CONFIG_PARAM_U8 = 2402,
AVS_TKN_INIT_CONFIG_LENGTH_U32 = 2403,
+
+ /* struct avs_tplg_nhlt_config */
+ AVS_TKN_NHLT_CONFIG_ID_U32 = 2501,
+ AVS_TKN_NHLT_CONFIG_SIZE_U32 = 2502,
};
#endif