diff options
Diffstat (limited to 'sound')
-rw-r--r-- | sound/hda/codecs/cirrus/Kconfig | 9 | ||||
-rw-r--r-- | sound/hda/codecs/hdmi/Kconfig | 24 | ||||
-rw-r--r-- | sound/hda/codecs/hdmi/Makefile | 2 | ||||
-rw-r--r-- | sound/hda/codecs/realtek/Kconfig | 12 | ||||
-rw-r--r-- | sound/hda/codecs/realtek/alc269.c | 3 | ||||
-rw-r--r-- | sound/hda/codecs/side-codecs/tas2781_hda_i2c.c | 2 | ||||
-rw-r--r-- | sound/hda/controllers/intel.c | 4 | ||||
-rw-r--r-- | sound/hda/core/i915.c | 2 | ||||
-rw-r--r-- | sound/soc/codecs/aw88399.c | 9 | ||||
-rw-r--r-- | sound/soc/codecs/cs42l43-jack.c | 46 | ||||
-rw-r--r-- | sound/soc/codecs/cs42l43.c | 24 | ||||
-rw-r--r-- | sound/soc/codecs/cs42l43.h | 5 | ||||
-rw-r--r-- | sound/soc/fsl/fsl_xcvr.c | 25 | ||||
-rw-r--r-- | sound/soc/fsl/imx-card.c | 40 | ||||
-rw-r--r-- | sound/soc/sdca/sdca_functions.c | 99 | ||||
-rw-r--r-- | sound/soc/sdca/sdca_regmap.c | 29 | ||||
-rw-r--r-- | sound/usb/mixer_scarlett2.c | 14 | ||||
-rw-r--r-- | sound/usb/quirks.c | 2 |
18 files changed, 242 insertions, 109 deletions
diff --git a/sound/hda/codecs/cirrus/Kconfig b/sound/hda/codecs/cirrus/Kconfig index b3a5968e9a02..33cfe52713bc 100644 --- a/sound/hda/codecs/cirrus/Kconfig +++ b/sound/hda/codecs/cirrus/Kconfig @@ -1,8 +1,14 @@ # SPDX-License-Identifier: GPL-2.0-only +menuconfig SND_HDA_CODEC_CIRRUS + tristate "Cirrus Logic HD-audio codec support" + +if SND_HDA_CODEC_CIRRUS + config SND_HDA_CODEC_CS420X tristate "Build Cirrus Logic CS420x codec support" select SND_HDA_GENERIC + default y help Say Y or M here to include Cirrus Logic CS420x codec support in snd-hda-intel driver @@ -13,6 +19,7 @@ comment "Set to Y if you want auto-loading the codec driver" config SND_HDA_CODEC_CS421X tristate "Build Cirrus Logic CS421x codec support" select SND_HDA_GENERIC + default y help Say Y or M here to include Cirrus Logic CS421x codec support in snd-hda-intel driver @@ -29,3 +36,5 @@ config SND_HDA_CODEC_CS8409 comment "Set to Y if you want auto-loading the codec driver" depends on SND_HDA=y && SND_HDA_CODEC_CS8409=m + +endif diff --git a/sound/hda/codecs/hdmi/Kconfig b/sound/hda/codecs/hdmi/Kconfig index 498000d2c6ae..973ca4ca077b 100644 --- a/sound/hda/codecs/hdmi/Kconfig +++ b/sound/hda/codecs/hdmi/Kconfig @@ -1,9 +1,15 @@ # SPDX-License-Identifier: GPL-2.0-only -config SND_HDA_CODEC_HDMI +menuconfig SND_HDA_CODEC_HDMI + tristate "HD-audio HDMI codec support" + +if SND_HDA_CODEC_HDMI + +config SND_HDA_CODEC_HDMI_GENERIC tristate "Generic HDMI/DisplayPort HD-audio codec support" select SND_DYNAMIC_MINORS select SND_PCM_ELD + default y help Say Y or M here to include Generic HDMI and DisplayPort HD-audio codec support. @@ -13,13 +19,15 @@ config SND_HDA_CODEC_HDMI config SND_HDA_CODEC_HDMI_SIMPLE tristate "Simple HDMI/DisplayPort HD-audio codec support" + default y help Say Y or M here to include Simple HDMI and DisplayPort HD-audio codec support for VIA and other codecs. config SND_HDA_CODEC_HDMI_INTEL tristate "Intel HDMI/DisplayPort HD-audio codec support" - select SND_HDA_CODEC_HDMI + select SND_HDA_CODEC_HDMI_GENERIC + default y help Say Y or M here to include Intel graphics HDMI and DisplayPort HD-audio codec support. @@ -41,14 +49,16 @@ config SND_HDA_INTEL_HDMI_SILENT_STREAM config SND_HDA_CODEC_HDMI_ATI tristate "AMD/ATI HDMI/DisplayPort HD-audio codec support" - select SND_HDA_CODEC_HDMI + select SND_HDA_CODEC_HDMI_GENERIC + default y help Say Y or M here to include AMD/ATI graphics HDMI and DisplayPort HD-audio codec support. config SND_HDA_CODEC_HDMI_NVIDIA tristate "Nvidia HDMI/DisplayPort HD-audio codec support" - select SND_HDA_CODEC_HDMI + select SND_HDA_CODEC_HDMI_GENERIC + default y help Say Y or M here to include HDMI and DisplayPort HD-audio codec support for the recent Nvidia graphics cards. @@ -56,13 +66,17 @@ config SND_HDA_CODEC_HDMI_NVIDIA config SND_HDA_CODEC_HDMI_NVIDIA_MCP tristate "Legacy Nvidia HDMI/DisplayPort HD-audio codec support" select SND_HDA_CODEC_HDMI_SIMPLE + default y help Say Y or M here to include HDMI and DisplayPort HD-audio codec support for the legacy Nvidia graphics like MCP73, MCP67, MCP77/78. config SND_HDA_CODEC_HDMI_TEGRA tristate "Nvidia Tegra HDMI/DisplayPort HD-audio codec support" - select SND_HDA_CODEC_HDMI + select SND_HDA_CODEC_HDMI_GENERIC + default y help Say Y or M here to include HDMI and DisplayPort HD-audio codec support for Nvidia Tegra. + +endif diff --git a/sound/hda/codecs/hdmi/Makefile b/sound/hda/codecs/hdmi/Makefile index c07a0a71b64f..0e49a9421e3b 100644 --- a/sound/hda/codecs/hdmi/Makefile +++ b/sound/hda/codecs/hdmi/Makefile @@ -9,7 +9,7 @@ snd-hda-codec-nvhdmi-y := nvhdmi.o snd-hda-codec-nvhdmi-mcp-y := nvhdmi-mcp.o snd-hda-codec-tegrahdmi-y := tegrahdmi.o -obj-$(CONFIG_SND_HDA_CODEC_HDMI) += snd-hda-codec-hdmi.o +obj-$(CONFIG_SND_HDA_CODEC_HDMI_GENERIC) += snd-hda-codec-hdmi.o obj-$(CONFIG_SND_HDA_CODEC_HDMI_SIMPLE) += snd-hda-codec-simplehdmi.o obj-$(CONFIG_SND_HDA_CODEC_HDMI_INTEL) += snd-hda-codec-intelhdmi.o obj-$(CONFIG_SND_HDA_CODEC_HDMI_ATI) += snd-hda-codec-atihdmi.o diff --git a/sound/hda/codecs/realtek/Kconfig b/sound/hda/codecs/realtek/Kconfig index 4b3ab28203b4..20899f3fc051 100644 --- a/sound/hda/codecs/realtek/Kconfig +++ b/sound/hda/codecs/realtek/Kconfig @@ -1,7 +1,7 @@ # SPDX-License-Identifier: GPL-2.0-only menuconfig SND_HDA_CODEC_REALTEK - bool "Realtek HD-audio codec support" + tristate "Realtek HD-audio codec support" if SND_HDA_CODEC_REALTEK @@ -15,6 +15,7 @@ config SND_HDA_CODEC_ALC260 tristate "Build Realtek ALC260 HD-audio codec support" depends on INPUT select SND_HDA_CODEC_REALTEK_LIB + default y help Say Y or M here to include Realtek ALC260 HD-audio codec support @@ -22,6 +23,7 @@ config SND_HDA_CODEC_ALC262 tristate "Build Realtek ALC262 HD-audio codec support" depends on INPUT select SND_HDA_CODEC_REALTEK_LIB + default y help Say Y or M here to include Realtek ALC262 HD-audio codec support @@ -29,6 +31,7 @@ config SND_HDA_CODEC_ALC268 tristate "Build Realtek ALC268 HD-audio codec support" depends on INPUT select SND_HDA_CODEC_REALTEK_LIB + default y help Say Y or M here to include Realtek ALC268 and compatible HD-audio codec support @@ -37,6 +40,7 @@ config SND_HDA_CODEC_ALC269 tristate "Build Realtek ALC269 HD-audio codecs support" depends on INPUT select SND_HDA_CODEC_REALTEK_LIB + default y help Say Y or M here to include Realtek ALC269 and compatible HD-audio codec support @@ -45,6 +49,7 @@ config SND_HDA_CODEC_ALC662 tristate "Build Realtek ALC662 HD-audio codecs support" depends on INPUT select SND_HDA_CODEC_REALTEK_LIB + default y help Say Y or M here to include Realtek ALC662 and compatible HD-audio codec support @@ -53,6 +58,7 @@ config SND_HDA_CODEC_ALC680 tristate "Build Realtek ALC680 HD-audio codecs support" depends on INPUT select SND_HDA_CODEC_REALTEK_LIB + default y help Say Y or M here to include Realtek ALC680 HD-audio codec support @@ -60,6 +66,7 @@ config SND_HDA_CODEC_ALC861 tristate "Build Realtek ALC861 HD-audio codecs support" depends on INPUT select SND_HDA_CODEC_REALTEK_LIB + default y help Say Y or M here to include Realtek ALC861 HD-audio codec support @@ -67,6 +74,7 @@ config SND_HDA_CODEC_ALC861VD tristate "Build Realtek ALC861-VD HD-audio codecs support" depends on INPUT select SND_HDA_CODEC_REALTEK_LIB + default y help Say Y or M here to include Realtek ALC861-VD HD-audio codec support @@ -74,6 +82,7 @@ config SND_HDA_CODEC_ALC880 tristate "Build Realtek ALC880 HD-audio codecs support" depends on INPUT select SND_HDA_CODEC_REALTEK_LIB + default y help Say Y or M here to include Realtek ALC880 HD-audio codec support @@ -81,6 +90,7 @@ config SND_HDA_CODEC_ALC882 tristate "Build Realtek ALC882 HD-audio codecs support" depends on INPUT select SND_HDA_CODEC_REALTEK_LIB + default y help Say Y or M here to include Realtek ALC882 and compatible HD-audio codec support diff --git a/sound/hda/codecs/realtek/alc269.c b/sound/hda/codecs/realtek/alc269.c index 05019fa73297..2554b42eeb0f 100644 --- a/sound/hda/codecs/realtek/alc269.c +++ b/sound/hda/codecs/realtek/alc269.c @@ -6470,6 +6470,7 @@ static const struct hda_quirk alc269_fixup_tbl[] = { SND_PCI_QUIRK(0x103c, 0x8a0f, "HP Pavilion 14-ec1xxx", ALC287_FIXUP_HP_GPIO_LED), SND_PCI_QUIRK(0x103c, 0x8a20, "HP Laptop 15s-fq5xxx", ALC236_FIXUP_HP_MUTE_LED_COEFBIT2), SND_PCI_QUIRK(0x103c, 0x8a25, "HP Victus 16-d1xxx (MB 8A25)", ALC245_FIXUP_HP_MUTE_LED_COEFBIT), + SND_PCI_QUIRK(0x103c, 0x8a26, "HP Victus 16-d1xxx (MB 8A26)", ALC245_FIXUP_HP_MUTE_LED_COEFBIT), SND_PCI_QUIRK(0x103c, 0x8a28, "HP Envy 13", ALC287_FIXUP_CS35L41_I2C_2), SND_PCI_QUIRK(0x103c, 0x8a29, "HP Envy 15", ALC287_FIXUP_CS35L41_I2C_2), SND_PCI_QUIRK(0x103c, 0x8a2a, "HP Envy 15", ALC287_FIXUP_CS35L41_I2C_2), @@ -6528,6 +6529,7 @@ static const struct hda_quirk alc269_fixup_tbl[] = { SND_PCI_QUIRK(0x103c, 0x8bbe, "HP Victus 16-r0xxx (MB 8BBE)", ALC245_FIXUP_HP_MUTE_LED_COEFBIT), SND_PCI_QUIRK(0x103c, 0x8bc8, "HP Victus 15-fa1xxx", ALC245_FIXUP_HP_MUTE_LED_COEFBIT), SND_PCI_QUIRK(0x103c, 0x8bcd, "HP Omen 16-xd0xxx", ALC245_FIXUP_HP_MUTE_LED_V1_COEFBIT), + SND_PCI_QUIRK(0x103c, 0x8bd4, "HP Victus 16-s0xxx (MB 8BD4)", ALC245_FIXUP_HP_MUTE_LED_COEFBIT), SND_PCI_QUIRK(0x103c, 0x8bdd, "HP Envy 17", ALC287_FIXUP_CS35L41_I2C_2), SND_PCI_QUIRK(0x103c, 0x8bde, "HP Envy 17", ALC287_FIXUP_CS35L41_I2C_2), SND_PCI_QUIRK(0x103c, 0x8bdf, "HP Envy 15", ALC287_FIXUP_CS35L41_I2C_2), @@ -6580,6 +6582,7 @@ static const struct hda_quirk alc269_fixup_tbl[] = { SND_PCI_QUIRK(0x103c, 0x8c91, "HP EliteBook 660", ALC236_FIXUP_HP_GPIO_LED), SND_PCI_QUIRK(0x103c, 0x8c96, "HP", ALC236_FIXUP_HP_MUTE_LED_MICMUTE_VREF), SND_PCI_QUIRK(0x103c, 0x8c97, "HP ZBook", ALC236_FIXUP_HP_MUTE_LED_MICMUTE_VREF), + SND_PCI_QUIRK(0x103c, 0x8c99, "HP Victus 16-r1xxx (MB 8C99)", ALC245_FIXUP_HP_MUTE_LED_COEFBIT), SND_PCI_QUIRK(0x103c, 0x8c9c, "HP Victus 16-s1xxx (MB 8C9C)", ALC245_FIXUP_HP_MUTE_LED_COEFBIT), SND_PCI_QUIRK(0x103c, 0x8ca1, "HP ZBook Power", ALC236_FIXUP_HP_GPIO_LED), SND_PCI_QUIRK(0x103c, 0x8ca2, "HP ZBook Power", ALC236_FIXUP_HP_GPIO_LED), diff --git a/sound/hda/codecs/side-codecs/tas2781_hda_i2c.c b/sound/hda/codecs/side-codecs/tas2781_hda_i2c.c index a0b132681804..45ac5e41bd4f 100644 --- a/sound/hda/codecs/side-codecs/tas2781_hda_i2c.c +++ b/sound/hda/codecs/side-codecs/tas2781_hda_i2c.c @@ -260,7 +260,7 @@ static const struct snd_kcontrol_new tas2770_snd_controls[] = { 0, 0, 20, 0, tas2781_amp_getvol, tas2781_amp_putvol, tas2770_amp_tlv), ACARD_SINGLE_RANGE_EXT_TLV("Speaker Digital Volume", TAS2770_DVC_LEVEL, - 0, 0, 31, 0, tas2781_amp_getvol, + 0, 0, 200, 1, tas2781_amp_getvol, tas2781_amp_putvol, tas2770_dvc_tlv), }; diff --git a/sound/hda/controllers/intel.c b/sound/hda/controllers/intel.c index 32bfd92d817f..fcf67e97a546 100644 --- a/sound/hda/controllers/intel.c +++ b/sound/hda/controllers/intel.c @@ -1464,7 +1464,7 @@ static struct pci_dev *get_bound_vga(struct pci_dev *pci) * the dGPU is the one who is involved in * vgaswitcheroo. */ - if (((p->class >> 16) == PCI_BASE_CLASS_DISPLAY) && + if (pci_is_display(p) && (atpx_present() || apple_gmux_detect(NULL, NULL))) return p; pci_dev_put(p); @@ -1476,7 +1476,7 @@ static struct pci_dev *get_bound_vga(struct pci_dev *pci) p = pci_get_domain_bus_and_slot(pci_domain_nr(pci->bus), pci->bus->number, 0); if (p) { - if ((p->class >> 16) == PCI_BASE_CLASS_DISPLAY) + if (pci_is_display(p)) return p; pci_dev_put(p); } diff --git a/sound/hda/core/i915.c b/sound/hda/core/i915.c index e9425213320e..44438c799f95 100644 --- a/sound/hda/core/i915.c +++ b/sound/hda/core/i915.c @@ -155,7 +155,7 @@ static int i915_gfx_present(struct pci_dev *hdac_pci) for_each_pci_dev(display_dev) { if (display_dev->vendor != PCI_VENDOR_ID_INTEL || - (display_dev->class >> 16) != PCI_BASE_CLASS_DISPLAY) + !pci_is_display(display_dev)) continue; if (pci_match_id(denylist, display_dev)) diff --git a/sound/soc/codecs/aw88399.c b/sound/soc/codecs/aw88399.c index bad3ad6b8c0e..c23e70d64d0c 100644 --- a/sound/soc/codecs/aw88399.c +++ b/sound/soc/codecs/aw88399.c @@ -2330,9 +2330,18 @@ static const struct i2c_device_id aw88399_i2c_id[] = { }; MODULE_DEVICE_TABLE(i2c, aw88399_i2c_id); +#ifdef CONFIG_ACPI +static const struct acpi_device_id aw88399_acpi_match[] = { + { "AWDZ8399", 0 }, + { }, +}; +MODULE_DEVICE_TABLE(acpi, aw88399_acpi_match); +#endif + static struct i2c_driver aw88399_i2c_driver = { .driver = { .name = AW88399_I2C_NAME, + .acpi_match_table = ACPI_PTR(aw88399_acpi_match), }, .probe = aw88399_i2c_probe, .id_table = aw88399_i2c_id, diff --git a/sound/soc/codecs/cs42l43-jack.c b/sound/soc/codecs/cs42l43-jack.c index f5c5150c25e5..2a0a4986a9ce 100644 --- a/sound/soc/codecs/cs42l43-jack.c +++ b/sound/soc/codecs/cs42l43-jack.c @@ -361,14 +361,15 @@ static void cs42l43_stop_button_detect(struct cs42l43_codec *priv) priv->button_detect_running = false; } +#define CS42L43_BUTTON_COMB_US 11000 #define CS42L43_BUTTON_COMB_MAX 512 #define CS42L43_BUTTON_ROUT 2210 -void cs42l43_button_press_work(struct work_struct *work) +irqreturn_t cs42l43_button_press(int irq, void *data) { - struct cs42l43_codec *priv = container_of(work, struct cs42l43_codec, - button_press_work.work); + struct cs42l43_codec *priv = data; struct cs42l43 *cs42l43 = priv->core; + irqreturn_t iret = IRQ_NONE; unsigned int buttons = 0; unsigned int val = 0; int i, ret; @@ -376,7 +377,7 @@ void cs42l43_button_press_work(struct work_struct *work) ret = pm_runtime_resume_and_get(priv->dev); if (ret) { dev_err(priv->dev, "Failed to resume for button press: %d\n", ret); - return; + return iret; } mutex_lock(&priv->jack_lock); @@ -386,6 +387,9 @@ void cs42l43_button_press_work(struct work_struct *work) goto error; } + // Wait for 2 full cycles of comb filter to ensure good reading + usleep_range(2 * CS42L43_BUTTON_COMB_US, 2 * CS42L43_BUTTON_COMB_US + 50); + regmap_read(cs42l43->regmap, CS42L43_DETECT_STATUS_1, &val); /* Bail if jack removed, the button is irrelevant and likely invalid */ @@ -419,33 +423,26 @@ void cs42l43_button_press_work(struct work_struct *work) snd_soc_jack_report(priv->jack_hp, buttons, CS42L43_JACK_BUTTONS); + iret = IRQ_HANDLED; + error: mutex_unlock(&priv->jack_lock); pm_runtime_put_autosuspend(priv->dev); -} - -irqreturn_t cs42l43_button_press(int irq, void *data) -{ - struct cs42l43_codec *priv = data; - - // Wait for 2 full cycles of comb filter to ensure good reading - queue_delayed_work(system_wq, &priv->button_press_work, - msecs_to_jiffies(20)); - return IRQ_HANDLED; + return iret; } -void cs42l43_button_release_work(struct work_struct *work) +irqreturn_t cs42l43_button_release(int irq, void *data) { - struct cs42l43_codec *priv = container_of(work, struct cs42l43_codec, - button_release_work); + struct cs42l43_codec *priv = data; + irqreturn_t iret = IRQ_NONE; int ret; ret = pm_runtime_resume_and_get(priv->dev); if (ret) { dev_err(priv->dev, "Failed to resume for button release: %d\n", ret); - return; + return iret; } mutex_lock(&priv->jack_lock); @@ -454,6 +451,8 @@ void cs42l43_button_release_work(struct work_struct *work) dev_dbg(priv->dev, "Button release IRQ\n"); snd_soc_jack_report(priv->jack_hp, 0, CS42L43_JACK_BUTTONS); + + iret = IRQ_HANDLED; } else { dev_dbg(priv->dev, "Spurious button release IRQ\n"); } @@ -461,15 +460,8 @@ void cs42l43_button_release_work(struct work_struct *work) mutex_unlock(&priv->jack_lock); pm_runtime_put_autosuspend(priv->dev); -} -irqreturn_t cs42l43_button_release(int irq, void *data) -{ - struct cs42l43_codec *priv = data; - - queue_work(system_wq, &priv->button_release_work); - - return IRQ_HANDLED; + return iret; } void cs42l43_bias_sense_timeout(struct work_struct *work) @@ -782,8 +774,6 @@ irqreturn_t cs42l43_tip_sense(int irq, void *data) cancel_delayed_work(&priv->bias_sense_timeout); cancel_delayed_work(&priv->tip_sense_work); - cancel_delayed_work(&priv->button_press_work); - cancel_work(&priv->button_release_work); // Ensure delay after suspend is long enough to avoid false detection if (priv->suspend_jack_debounce) diff --git a/sound/soc/codecs/cs42l43.c b/sound/soc/codecs/cs42l43.c index d84ad8d43438..b0c27d696c58 100644 --- a/sound/soc/codecs/cs42l43.c +++ b/sound/soc/codecs/cs42l43.c @@ -167,13 +167,14 @@ static void cs42l43_hp_ilimit_clear_work(struct work_struct *work) snd_soc_dapm_mutex_unlock(dapm); } -static void cs42l43_hp_ilimit_work(struct work_struct *work) +static irqreturn_t cs42l43_hp_ilimit(int irq, void *data) { - struct cs42l43_codec *priv = container_of(work, struct cs42l43_codec, - hp_ilimit_work); + struct cs42l43_codec *priv = data; struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(priv->component); struct cs42l43 *cs42l43 = priv->core; + dev_dbg(priv->dev, "headphone ilimit IRQ\n"); + snd_soc_dapm_mutex_lock(dapm); if (priv->hp_ilimit_count < CS42L43_HP_ILIMIT_MAX_COUNT) { @@ -183,7 +184,7 @@ static void cs42l43_hp_ilimit_work(struct work_struct *work) priv->hp_ilimit_count++; snd_soc_dapm_mutex_unlock(dapm); - return; + return IRQ_HANDLED; } dev_err(priv->dev, "Disabling headphone for %dmS, due to frequent current limit\n", @@ -218,15 +219,6 @@ static void cs42l43_hp_ilimit_work(struct work_struct *work) priv->hp_ilimited = false; snd_soc_dapm_mutex_unlock(dapm); -} - -static irqreturn_t cs42l43_hp_ilimit(int irq, void *data) -{ - struct cs42l43_codec *priv = data; - - dev_dbg(priv->dev, "headphone ilimit IRQ\n"); - - queue_work(system_long_wq, &priv->hp_ilimit_work); return IRQ_HANDLED; } @@ -2158,10 +2150,7 @@ static void cs42l43_component_remove(struct snd_soc_component *component) cancel_delayed_work_sync(&priv->bias_sense_timeout); cancel_delayed_work_sync(&priv->tip_sense_work); - cancel_delayed_work_sync(&priv->button_press_work); - cancel_work_sync(&priv->button_release_work); - cancel_work_sync(&priv->hp_ilimit_work); cancel_delayed_work_sync(&priv->hp_ilimit_clear_work); priv->component = NULL; @@ -2313,10 +2302,7 @@ static int cs42l43_codec_probe(struct platform_device *pdev) INIT_DELAYED_WORK(&priv->tip_sense_work, cs42l43_tip_sense_work); INIT_DELAYED_WORK(&priv->bias_sense_timeout, cs42l43_bias_sense_timeout); - INIT_DELAYED_WORK(&priv->button_press_work, cs42l43_button_press_work); INIT_DELAYED_WORK(&priv->hp_ilimit_clear_work, cs42l43_hp_ilimit_clear_work); - INIT_WORK(&priv->button_release_work, cs42l43_button_release_work); - INIT_WORK(&priv->hp_ilimit_work, cs42l43_hp_ilimit_work); pm_runtime_set_autosuspend_delay(priv->dev, 100); pm_runtime_use_autosuspend(priv->dev); diff --git a/sound/soc/codecs/cs42l43.h b/sound/soc/codecs/cs42l43.h index 1cd9d8a71c43..3ea36362b11a 100644 --- a/sound/soc/codecs/cs42l43.h +++ b/sound/soc/codecs/cs42l43.h @@ -88,8 +88,6 @@ struct cs42l43_codec { struct delayed_work tip_sense_work; struct delayed_work bias_sense_timeout; - struct delayed_work button_press_work; - struct work_struct button_release_work; struct completion type_detect; struct completion load_detect; @@ -99,7 +97,6 @@ struct cs42l43_codec { int jack_override; bool suspend_jack_debounce; - struct work_struct hp_ilimit_work; struct delayed_work hp_ilimit_clear_work; bool hp_ilimited; int hp_ilimit_count; @@ -134,8 +131,6 @@ int cs42l43_set_jack(struct snd_soc_component *component, struct snd_soc_jack *jack, void *d); void cs42l43_bias_sense_timeout(struct work_struct *work); void cs42l43_tip_sense_work(struct work_struct *work); -void cs42l43_button_press_work(struct work_struct *work); -void cs42l43_button_release_work(struct work_struct *work); irqreturn_t cs42l43_bias_detect_clamp(int irq, void *data); irqreturn_t cs42l43_button_press(int irq, void *data); irqreturn_t cs42l43_button_release(int irq, void *data); diff --git a/sound/soc/fsl/fsl_xcvr.c b/sound/soc/fsl/fsl_xcvr.c index e3111dd80be4..5d804860f7d8 100644 --- a/sound/soc/fsl/fsl_xcvr.c +++ b/sound/soc/fsl/fsl_xcvr.c @@ -1395,7 +1395,7 @@ static irqreturn_t irq0_isr(int irq, void *devid) if (isr & FSL_XCVR_IRQ_NEW_CS) { dev_dbg(dev, "Received new CS block\n"); isr_clr |= FSL_XCVR_IRQ_NEW_CS; - if (!xcvr->soc_data->spdif_only) { + if (xcvr->soc_data->fw_name) { /* Data RAM is 4KiB, last two pages: 8 and 9. Select page 8. */ regmap_update_bits(xcvr->regmap, FSL_XCVR_EXT_CTRL, FSL_XCVR_EXT_CTRL_PAGE_MASK, @@ -1423,6 +1423,26 @@ static irqreturn_t irq0_isr(int irq, void *devid) /* clear CS control register */ memset_io(reg_ctrl, 0, sizeof(val)); } + } else { + regmap_read(xcvr->regmap, FSL_XCVR_RX_CS_DATA_0, + (u32 *)&xcvr->rx_iec958.status[0]); + regmap_read(xcvr->regmap, FSL_XCVR_RX_CS_DATA_1, + (u32 *)&xcvr->rx_iec958.status[4]); + regmap_read(xcvr->regmap, FSL_XCVR_RX_CS_DATA_2, + (u32 *)&xcvr->rx_iec958.status[8]); + regmap_read(xcvr->regmap, FSL_XCVR_RX_CS_DATA_3, + (u32 *)&xcvr->rx_iec958.status[12]); + regmap_read(xcvr->regmap, FSL_XCVR_RX_CS_DATA_4, + (u32 *)&xcvr->rx_iec958.status[16]); + regmap_read(xcvr->regmap, FSL_XCVR_RX_CS_DATA_5, + (u32 *)&xcvr->rx_iec958.status[20]); + for (i = 0; i < 6; i++) { + val = *(u32 *)(xcvr->rx_iec958.status + i * 4); + *(u32 *)(xcvr->rx_iec958.status + i * 4) = + bitrev32(val); + } + regmap_set_bits(xcvr->regmap, FSL_XCVR_RX_DPTH_CTRL, + FSL_XCVR_RX_DPTH_CTRL_CSA); } } if (isr & FSL_XCVR_IRQ_NEW_UD) { @@ -1497,6 +1517,7 @@ static const struct fsl_xcvr_soc_data fsl_xcvr_imx93_data = { }; static const struct fsl_xcvr_soc_data fsl_xcvr_imx95_data = { + .fw_name = "imx/xcvr/xcvr-imx95.bin", .spdif_only = true, .use_phy = true, .use_edma = true, @@ -1786,7 +1807,7 @@ static int fsl_xcvr_runtime_resume(struct device *dev) } } - if (xcvr->mode == FSL_XCVR_MODE_EARC) { + if (xcvr->soc_data->fw_name) { ret = fsl_xcvr_load_firmware(xcvr); if (ret) { dev_err(dev, "failed to load firmware.\n"); diff --git a/sound/soc/fsl/imx-card.c b/sound/soc/fsl/imx-card.c index ea5dbb54b584..28699d7b75ca 100644 --- a/sound/soc/fsl/imx-card.c +++ b/sound/soc/fsl/imx-card.c @@ -26,6 +26,7 @@ enum codec_type { CODEC_AK4497, CODEC_AK5552, CODEC_CS42888, + CODEC_WM8524, }; /* @@ -196,6 +197,13 @@ static struct imx_akcodec_tdm_fs_mul cs42888_tdm_fs_mul[] = { { .min = 256, .max = 256, .mul = 256 }, }; +static struct imx_akcodec_fs_mul wm8524_fs_mul[] = { + { .rmin = 8000, .rmax = 32000, .wmin = 256, .wmax = 1152, }, + { .rmin = 44100, .rmax = 48000, .wmin = 256, .wmax = 768, }, + { .rmin = 88200, .rmax = 96000, .wmin = 128, .wmax = 384, }, + { .rmin = 176400, .rmax = 192000, .wmin = 128, .wmax = 192, }, +}; + static const u32 akcodec_rates[] = { 8000, 11025, 16000, 22050, 32000, 44100, 48000, 88200, 96000, 176400, 192000, 352800, 384000, 705600, 768000, @@ -229,6 +237,10 @@ static const u32 cs42888_tdm_channels[] = { 1, 2, 3, 4, 5, 6, 7, 8, }; +static const u32 wm8524_channels[] = { + 2, +}; + static bool format_is_dsd(struct snd_pcm_hw_params *params) { snd_pcm_format_t format = params_format(params); @@ -261,6 +273,7 @@ static bool codec_is_akcodec(unsigned int type) case CODEC_AK5558: case CODEC_AK5552: case CODEC_CS42888: + case CODEC_WM8524: return true; default: break; @@ -477,9 +490,24 @@ static int imx_aif_startup(struct snd_pcm_substream *substream) return ret; } +static void imx_aif_shutdown(struct snd_pcm_substream *substream) +{ + struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream); + struct snd_soc_dai *cpu_dai; + struct snd_soc_dai *codec_dai; + int i; + + for_each_rtd_cpu_dais(rtd, i, cpu_dai) + snd_soc_dai_set_sysclk(cpu_dai, 0, 0, SND_SOC_CLOCK_OUT); + + for_each_rtd_codec_dais(rtd, i, codec_dai) + snd_soc_dai_set_sysclk(codec_dai, 0, 0, SND_SOC_CLOCK_IN); +} + static const struct snd_soc_ops imx_aif_ops = { .hw_params = imx_aif_hw_params, .startup = imx_aif_startup, + .shutdown = imx_aif_shutdown, }; static const struct snd_soc_ops imx_aif_ops_be = { @@ -632,6 +660,8 @@ static int imx_card_parse_of(struct imx_card_data *data) plat_data->type = CODEC_AK5552; else if (!strcmp(link->codecs->dai_name, "cs42888")) plat_data->type = CODEC_CS42888; + else if (!strcmp(link->codecs->dai_name, "wm8524-hifi")) + plat_data->type = CODEC_WM8524; } else { link->codecs = &snd_soc_dummy_dlc; @@ -805,6 +835,10 @@ static int imx_card_probe(struct platform_device *pdev) data->dapm_routes[1].sink = "CPU-Capture"; data->dapm_routes[1].source = "Capture"; break; + case CODEC_WM8524: + data->dapm_routes[0].sink = "Playback"; + data->dapm_routes[0].source = "CPU-Playback"; + break; default: break; } @@ -854,6 +888,12 @@ static int imx_card_probe(struct platform_device *pdev) plat_data->support_tdm_channels = cs42888_tdm_channels; plat_data->num_tdm_channels = ARRAY_SIZE(cs42888_tdm_channels); break; + case CODEC_WM8524: + plat_data->fs_mul = wm8524_fs_mul; + plat_data->num_fs_mul = ARRAY_SIZE(wm8524_fs_mul); + plat_data->support_channels = wm8524_channels; + plat_data->num_channels = ARRAY_SIZE(wm8524_channels); + break; default: break; } diff --git a/sound/soc/sdca/sdca_functions.c b/sound/soc/sdca/sdca_functions.c index 93767e73bc5f..f26f597dca9e 100644 --- a/sound/soc/sdca/sdca_functions.c +++ b/sound/soc/sdca/sdca_functions.c @@ -814,6 +814,43 @@ static int find_sdca_control_range(struct device *dev, return 0; } +static int find_sdca_control_value(struct device *dev, struct sdca_entity *entity, + struct fwnode_handle *control_node, + struct sdca_control *control, + const char * const label) +{ + char property[SDCA_PROPERTY_LENGTH]; + bool global = true; + int ret, cn, i; + u32 tmp; + + snprintf(property, sizeof(property), "mipi-sdca-control-%s", label); + + ret = fwnode_property_read_u32(control_node, property, &tmp); + if (ret == -EINVAL) + global = false; + else if (ret) + return ret; + + i = 0; + for_each_set_bit(cn, (unsigned long *)&control->cn_list, + BITS_PER_TYPE(control->cn_list)) { + if (!global) { + snprintf(property, sizeof(property), + "mipi-sdca-control-cn-%d-%s", cn, label); + + ret = fwnode_property_read_u32(control_node, property, &tmp); + if (ret) + return ret; + } + + control->values[i] = tmp; + i++; + } + + return 0; +} + /* * TODO: Add support for -cn- properties, allowing different channels to have * different defaults etc. @@ -843,44 +880,44 @@ static int find_sdca_entity_control(struct device *dev, struct sdca_entity *enti control->layers = tmp; + ret = fwnode_property_read_u64(control_node, "mipi-sdca-control-cn-list", + &control->cn_list); + if (ret == -EINVAL) { + /* Spec allows not specifying cn-list if only the first number is used */ + control->cn_list = 0x1; + } else if (ret || !control->cn_list) { + dev_err(dev, "%s: control %#x: cn list missing: %d\n", + entity->label, control->sel, ret); + return ret; + } + + control->values = devm_kzalloc(dev, hweight64(control->cn_list), GFP_KERNEL); + if (!control->values) + return -ENOMEM; + switch (control->mode) { case SDCA_ACCESS_MODE_DC: - ret = fwnode_property_read_u32(control_node, - "mipi-sdca-control-dc-value", - &tmp); + ret = find_sdca_control_value(dev, entity, control_node, control, + "dc-value"); if (ret) { dev_err(dev, "%s: control %#x: dc value missing: %d\n", entity->label, control->sel, ret); return ret; } - control->value = tmp; control->has_fixed = true; break; case SDCA_ACCESS_MODE_RW: case SDCA_ACCESS_MODE_DUAL: - ret = fwnode_property_read_u32(control_node, - "mipi-sdca-control-default-value", - &tmp); - if (!ret) { - control->value = tmp; + ret = find_sdca_control_value(dev, entity, control_node, control, + "default-value"); + if (!ret) control->has_default = true; - } - - ret = fwnode_property_read_u32(control_node, - "mipi-sdca-control-fixed-value", - &tmp); - if (!ret) { - if (control->has_default && control->value != tmp) { - dev_err(dev, - "%s: control %#x: default and fixed value don't match\n", - entity->label, control->sel); - return -EINVAL; - } - control->value = tmp; + ret = find_sdca_control_value(dev, entity, control_node, control, + "fixed-value"); + if (!ret) control->has_fixed = true; - } fallthrough; case SDCA_ACCESS_MODE_RO: control->deferrable = fwnode_property_read_bool(control_node, @@ -897,17 +934,6 @@ static int find_sdca_entity_control(struct device *dev, struct sdca_entity *enti return ret; } - ret = fwnode_property_read_u64(control_node, "mipi-sdca-control-cn-list", - &control->cn_list); - if (ret == -EINVAL) { - /* Spec allows not specifying cn-list if only the first number is used */ - control->cn_list = 0x1; - } else if (ret || !control->cn_list) { - dev_err(dev, "%s: control %#x: cn list missing: %d\n", - entity->label, control->sel, ret); - return ret; - } - ret = fwnode_property_read_u32(control_node, "mipi-sdca-control-interrupt-position", &tmp); @@ -923,11 +949,10 @@ static int find_sdca_entity_control(struct device *dev, struct sdca_entity *enti control->type = find_sdca_control_datatype(entity, control); control->nbits = find_sdca_control_bits(entity, control); - dev_info(dev, "%s: %s: control %#x mode %#x layers %#x cn %#llx int %d value %#x %s\n", + dev_info(dev, "%s: %s: control %#x mode %#x layers %#x cn %#llx int %d %s\n", entity->label, control->label, control->sel, control->mode, control->layers, control->cn_list, - control->interrupt_position, control->value, - control->deferrable ? "deferrable" : ""); + control->interrupt_position, control->deferrable ? "deferrable" : ""); return 0; } diff --git a/sound/soc/sdca/sdca_regmap.c b/sound/soc/sdca/sdca_regmap.c index 66e7eee7d7f4..5cb3048ea8cf 100644 --- a/sound/soc/sdca/sdca_regmap.c +++ b/sound/soc/sdca/sdca_regmap.c @@ -72,12 +72,18 @@ bool sdca_regmap_readable(struct sdca_function_data *function, unsigned int reg) if (!control) return false; + if (!(BIT(SDW_SDCA_CTL_CNUM(reg)) & control->cn_list)) + return false; + switch (control->mode) { case SDCA_ACCESS_MODE_RW: case SDCA_ACCESS_MODE_RO: - case SDCA_ACCESS_MODE_DUAL: case SDCA_ACCESS_MODE_RW1S: case SDCA_ACCESS_MODE_RW1C: + if (SDW_SDCA_NEXT_CTL(0) & reg) + return false; + fallthrough; + case SDCA_ACCESS_MODE_DUAL: /* No access to registers marked solely for device use */ return control->layers & ~SDCA_ACCESS_LAYER_DEVICE; default: @@ -104,11 +110,17 @@ bool sdca_regmap_writeable(struct sdca_function_data *function, unsigned int reg if (!control) return false; + if (!(BIT(SDW_SDCA_CTL_CNUM(reg)) & control->cn_list)) + return false; + switch (control->mode) { case SDCA_ACCESS_MODE_RW: - case SDCA_ACCESS_MODE_DUAL: case SDCA_ACCESS_MODE_RW1S: case SDCA_ACCESS_MODE_RW1C: + if (SDW_SDCA_NEXT_CTL(0) & reg) + return false; + fallthrough; + case SDCA_ACCESS_MODE_DUAL: /* No access to registers marked solely for device use */ return control->layers & ~SDCA_ACCESS_LAYER_DEVICE; default: @@ -241,7 +253,7 @@ int sdca_regmap_populate_constants(struct device *dev, struct sdca_function_data *function, struct reg_default *consts) { - int i, j, k; + int i, j, k, l; for (i = 0, k = 0; i < function->num_entities; i++) { struct sdca_entity *entity = &function->entities[i]; @@ -253,13 +265,15 @@ int sdca_regmap_populate_constants(struct device *dev, if (control->mode != SDCA_ACCESS_MODE_DC) continue; + l = 0; for_each_set_bit(cn, (unsigned long *)&control->cn_list, BITS_PER_TYPE(control->cn_list)) { consts[k].reg = SDW_SDCA_CTL(function->desc->adr, entity->id, control->sel, cn); - consts[k].def = control->value; + consts[k].def = control->values[l]; k++; + l++; } } } @@ -283,7 +297,7 @@ EXPORT_SYMBOL_NS(sdca_regmap_populate_constants, "SND_SOC_SDCA"); int sdca_regmap_write_defaults(struct device *dev, struct regmap *regmap, struct sdca_function_data *function) { - int i, j; + int i, j, k; int ret; for (i = 0; i < function->num_entities; i++) { @@ -299,6 +313,7 @@ int sdca_regmap_write_defaults(struct device *dev, struct regmap *regmap, if (!control->has_default && !control->has_fixed) continue; + k = 0; for_each_set_bit(cn, (unsigned long *)&control->cn_list, BITS_PER_TYPE(control->cn_list)) { unsigned int reg; @@ -306,9 +321,11 @@ int sdca_regmap_write_defaults(struct device *dev, struct regmap *regmap, reg = SDW_SDCA_CTL(function->desc->adr, entity->id, control->sel, cn); - ret = regmap_write(regmap, reg, control->value); + ret = regmap_write(regmap, reg, control->values[k]); if (ret) return ret; + + k++; } } } diff --git a/sound/usb/mixer_scarlett2.c b/sound/usb/mixer_scarlett2.c index 49eeb1444dce..1ec203cbbd94 100644 --- a/sound/usb/mixer_scarlett2.c +++ b/sound/usb/mixer_scarlett2.c @@ -2351,6 +2351,8 @@ static int scarlett2_usb( struct scarlett2_usb_packet *req, *resp = NULL; size_t req_buf_size = struct_size(req, data, req_size); size_t resp_buf_size = struct_size(resp, data, resp_size); + int retries = 0; + const int max_retries = 5; int err; req = kmalloc(req_buf_size, GFP_KERNEL); @@ -2374,10 +2376,15 @@ static int scarlett2_usb( if (req_size) memcpy(req->data, req_data, req_size); +retry: err = scarlett2_usb_tx(dev, private->bInterfaceNumber, req, req_buf_size); if (err != req_buf_size) { + if (err == -EPROTO && ++retries <= max_retries) { + msleep(5 * (1 << (retries - 1))); + goto retry; + } usb_audio_err( mixer->chip, "%s USB request result cmd %x was %d\n", @@ -3971,8 +3978,13 @@ static int scarlett2_input_select_ctl_info( goto unlock; /* Loop through each input */ - for (i = 0; i < inputs; i++) + for (i = 0; i < inputs; i++) { values[i] = kasprintf(GFP_KERNEL, "Input %d", i + 1); + if (!values[i]) { + err = -ENOMEM; + goto unlock; + } + } err = snd_ctl_enum_info(uinfo, 1, i, (const char * const *)values); diff --git a/sound/usb/quirks.c b/sound/usb/quirks.c index bd24f3a78ea9..e75b0b1df6eb 100644 --- a/sound/usb/quirks.c +++ b/sound/usb/quirks.c @@ -2408,6 +2408,8 @@ static const struct usb_audio_quirk_flags_table quirk_flags_table[] = { QUIRK_FLAG_DSD_RAW), VENDOR_FLG(0x2d87, /* Cayin device */ QUIRK_FLAG_DSD_RAW), + VENDOR_FLG(0x2fc6, /* Comture-inc devices */ + QUIRK_FLAG_DSD_RAW), VENDOR_FLG(0x3336, /* HEM devices */ QUIRK_FLAG_DSD_RAW), VENDOR_FLG(0x3353, /* Khadas devices */ |