aboutsummaryrefslogtreecommitdiffstats
path: root/sound/pci/hda
diff options
context:
space:
mode:
Diffstat (limited to 'sound/pci/hda')
-rw-r--r--sound/pci/hda/Kconfig62
-rw-r--r--sound/pci/hda/dell_wmi_helper.c48
-rw-r--r--sound/pci/hda/hda_codec.c16
-rw-r--r--sound/pci/hda/hda_controller.c11
-rw-r--r--sound/pci/hda/hda_controller.h8
-rw-r--r--sound/pci/hda/hda_generic.c31
-rw-r--r--sound/pci/hda/hda_generic.h2
-rw-r--r--sound/pci/hda/hda_intel.c274
-rw-r--r--sound/pci/hda/hda_jack.c56
-rw-r--r--sound/pci/hda/hda_jack.h12
-rw-r--r--sound/pci/hda/hda_tegra.c22
-rw-r--r--sound/pci/hda/patch_ca0132.c207
-rw-r--r--sound/pci/hda/patch_conexant.c1
-rw-r--r--sound/pci/hda/patch_hdmi.c14
-rw-r--r--sound/pci/hda/patch_realtek.c106
-rw-r--r--sound/pci/hda/thinkpad_helper.c43
16 files changed, 547 insertions, 366 deletions
diff --git a/sound/pci/hda/Kconfig b/sound/pci/hda/Kconfig
index 4235907b7858..0d38c006e182 100644
--- a/sound/pci/hda/Kconfig
+++ b/sound/pci/hda/Kconfig
@@ -226,6 +226,68 @@ config SND_HDA_POWER_SAVE_DEFAULT
The default time-out value in seconds for HD-audio automatic
power-save mode. 0 means to disable the power-save mode.
+if SND_HDA_INTEL
+
+# The options below should not be enabled by distributions or
+# users. They are selected by Intel/Skylake or SOF drivers when they
+# register for a PCI ID which is also handled by the HDAudio legacy
+# driver. When this option is selected and the DSP is detected based on
+# the PCI class/subclass/prog-if, the probe of the HDAudio legacy
+# aborts. This mechanism removes the need for distributions to use
+# blacklists. It can be bypassed with module parameters should the
+# Intel/Skylake or SOF drivers fail to handle a specific platform.
+
+config SND_HDA_INTEL_DSP_DETECTION_SKL
+ bool
+ help
+ This option is selected by SOF or SST drivers, not users or distros.
+ It enables DSP detection based on PCI class information for
+ Skylake machines.
+
+config SND_HDA_INTEL_DSP_DETECTION_APL
+ bool
+ help
+ This option is selected by SOF or SST drivers, not users or distros.
+ It enables DSP detection based on PCI class information for
+ Broxton/ApolloLake machines
+
+config SND_HDA_INTEL_DSP_DETECTION_KBL
+ bool
+ help
+ This option is selected by SOF or SST drivers, not users or distros.
+ It enables DSP detection based on PCI class information for
+ KabyLake machines
+
+config SND_HDA_INTEL_DSP_DETECTION_GLK
+ bool
+ help
+ This option is selected by SOF or SST drivers, not users or distros.
+ It enables DSP detection based on PCI class information for
+ GeminiLake machines
+
+config SND_HDA_INTEL_DSP_DETECTION_CNL
+ bool
+ help
+ This option is selected by SOF or SST drivers, not users or distros.
+ It enables DSP detection based on PCI class information for
+ CannonLake machines
+
+config SND_HDA_INTEL_DSP_DETECTION_CFL
+ bool
+ help
+ This option is selected by SOF or SST drivers, not users or distros.
+ It enables DSP detection based on PCI class information for
+ CoffeeLake machines
+
+config SND_HDA_INTEL_DSP_DETECTION_ICL
+ bool
+ help
+ This option is selected by SOF or SST drivers, not users or distros.
+ It enables DSP detection based on PCI class information for
+ IceLake machines
+
+endif ## SND_HDA_INTEL
+
endif
endmenu
diff --git a/sound/pci/hda/dell_wmi_helper.c b/sound/pci/hda/dell_wmi_helper.c
deleted file mode 100644
index bbd6c87a4ed6..000000000000
--- a/sound/pci/hda/dell_wmi_helper.c
+++ /dev/null
@@ -1,48 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-/* Helper functions for Dell Mic Mute LED control;
- * to be included from codec driver
- */
-
-#if IS_ENABLED(CONFIG_DELL_LAPTOP)
-#include <linux/dell-led.h>
-
-static int (*dell_micmute_led_set_func)(int);
-
-static void dell_micmute_update(struct hda_codec *codec)
-{
- struct hda_gen_spec *spec = codec->spec;
-
- dell_micmute_led_set_func(spec->micmute_led.led_value);
-}
-
-static void alc_fixup_dell_wmi(struct hda_codec *codec,
- const struct hda_fixup *fix, int action)
-{
- bool removefunc = false;
-
- if (action == HDA_FIXUP_ACT_PROBE) {
- if (!dell_micmute_led_set_func)
- dell_micmute_led_set_func = symbol_request(dell_micmute_led_set);
- if (!dell_micmute_led_set_func) {
- codec_warn(codec, "Failed to find dell wmi symbol dell_micmute_led_set\n");
- return;
- }
-
- removefunc = (dell_micmute_led_set_func(false) < 0) ||
- (snd_hda_gen_add_micmute_led(codec,
- dell_micmute_update) < 0);
- }
-
- if (dell_micmute_led_set_func && (action == HDA_FIXUP_ACT_FREE || removefunc)) {
- symbol_put(dell_micmute_led_set);
- dell_micmute_led_set_func = NULL;
- }
-}
-
-#else /* CONFIG_DELL_LAPTOP */
-static void alc_fixup_dell_wmi(struct hda_codec *codec,
- const struct hda_fixup *fix, int action)
-{
-}
-
-#endif /* CONFIG_DELL_LAPTOP */
diff --git a/sound/pci/hda/hda_codec.c b/sound/pci/hda/hda_codec.c
index 0957813939e5..9f8d59e7e89f 100644
--- a/sound/pci/hda/hda_codec.c
+++ b/sound/pci/hda/hda_codec.c
@@ -36,6 +36,7 @@
#include "hda_beep.h"
#include "hda_jack.h"
#include <sound/hda_hwdep.h>
+#include <sound/hda_component.h>
#define codec_in_pm(codec) snd_hdac_is_in_pm(&codec->core)
#define hda_codec_is_power_on(codec) snd_hdac_is_power_on(&codec->core)
@@ -799,6 +800,13 @@ void snd_hda_codec_cleanup_for_unbind(struct hda_codec *codec)
static unsigned int hda_set_power_state(struct hda_codec *codec,
unsigned int power_state);
+/* enable/disable display power per codec */
+static void codec_display_power(struct hda_codec *codec, bool enable)
+{
+ if (codec->display_power_control)
+ snd_hdac_display_power(&codec->bus->core, codec->addr, enable);
+}
+
/* also called from hda_bind.c */
void snd_hda_codec_register(struct hda_codec *codec)
{
@@ -806,7 +814,7 @@ void snd_hda_codec_register(struct hda_codec *codec)
return;
if (device_is_registered(hda_codec_dev(codec))) {
snd_hda_register_beep_device(codec);
- snd_hdac_link_power(&codec->core, true);
+ codec_display_power(codec, true);
pm_runtime_enable(hda_codec_dev(codec));
/* it was powered up in snd_hda_codec_new(), now all done */
snd_hda_power_down(codec);
@@ -834,7 +842,7 @@ static int snd_hda_codec_dev_free(struct snd_device *device)
codec->in_freeing = 1;
snd_hdac_device_unregister(&codec->core);
- snd_hdac_link_power(&codec->core, false);
+ codec_display_power(codec, false);
put_device(hda_codec_dev(codec));
return 0;
}
@@ -2926,7 +2934,7 @@ static int hda_codec_runtime_suspend(struct device *dev)
(codec_has_clkstop(codec) && codec_has_epss(codec) &&
(state & AC_PWRST_CLK_STOP_OK)))
snd_hdac_codec_link_down(&codec->core);
- snd_hdac_link_power(&codec->core, false);
+ codec_display_power(codec, false);
return 0;
}
@@ -2934,7 +2942,7 @@ static int hda_codec_runtime_resume(struct device *dev)
{
struct hda_codec *codec = dev_to_hda_codec(dev);
- snd_hdac_link_power(&codec->core, true);
+ codec_display_power(codec, true);
snd_hdac_codec_link_up(&codec->core);
hda_call_codec_resume(codec);
pm_runtime_mark_last_busy(dev);
diff --git a/sound/pci/hda/hda_controller.c b/sound/pci/hda/hda_controller.c
index fe2506672a72..532e081f8b8a 100644
--- a/sound/pci/hda/hda_controller.c
+++ b/sound/pci/hda/hda_controller.c
@@ -989,20 +989,9 @@ static int azx_get_response(struct hdac_bus *bus, unsigned int addr,
return azx_rirb_get_response(bus, addr, res);
}
-static int azx_link_power(struct hdac_bus *bus, bool enable)
-{
- struct azx *chip = bus_to_azx(bus);
-
- if (chip->ops->link_power)
- return chip->ops->link_power(chip, enable);
- else
- return -EINVAL;
-}
-
static const struct hdac_bus_ops bus_core_ops = {
.command = azx_send_cmd,
.get_response = azx_get_response,
- .link_power = azx_link_power,
};
#ifdef CONFIG_SND_HDA_DSP_LOADER
diff --git a/sound/pci/hda/hda_controller.h b/sound/pci/hda/hda_controller.h
index c95097bb5a0c..e0c3fcbaa028 100644
--- a/sound/pci/hda/hda_controller.h
+++ b/sound/pci/hda/hda_controller.h
@@ -37,7 +37,7 @@
#else
#define AZX_DCAPS_I915_COMPONENT 0 /* NOP */
#endif
-/* 14 unused */
+#define AZX_DCAPS_INTEL_SHARED (1 << 14) /* shared with ASoC */
#define AZX_DCAPS_CTX_WORKAROUND (1 << 15) /* X-Fi workaround */
#define AZX_DCAPS_POSFIX_LPIB (1 << 16) /* Use LPIB as default */
/* 17 unused */
@@ -50,11 +50,7 @@
/* 24 unused */
#define AZX_DCAPS_COUNT_LPIB_DELAY (1 << 25) /* Take LPIB as delay */
#define AZX_DCAPS_PM_RUNTIME (1 << 26) /* runtime PM support */
-#ifdef CONFIG_SND_HDA_I915
-#define AZX_DCAPS_I915_POWERWELL (1 << 27) /* HSW i915 powerwell support */
-#else
-#define AZX_DCAPS_I915_POWERWELL 0 /* NOP */
-#endif
+/* 27 unused */
#define AZX_DCAPS_CORBRP_SELF_CLEAR (1 << 28) /* CORBRP clears itself after reset */
#define AZX_DCAPS_NO_MSI64 (1 << 29) /* Stick to 32-bit MSIs */
#define AZX_DCAPS_SEPARATE_STREAM_TAG (1 << 30) /* capture and playback use separate stream tag */
diff --git a/sound/pci/hda/hda_generic.c b/sound/pci/hda/hda_generic.c
index 276150f29cda..4095cd7c56c6 100644
--- a/sound/pci/hda/hda_generic.c
+++ b/sound/pci/hda/hda_generic.c
@@ -29,6 +29,7 @@
#include <linux/string.h>
#include <linux/bitops.h>
#include <linux/module.h>
+#include <linux/leds.h>
#include <sound/core.h>
#include <sound/jack.h>
#include <sound/tlv.h>
@@ -4035,6 +4036,36 @@ int snd_hda_gen_add_micmute_led(struct hda_codec *codec,
}
EXPORT_SYMBOL_GPL(snd_hda_gen_add_micmute_led);
+#if IS_REACHABLE(CONFIG_LEDS_TRIGGER_AUDIO)
+static void call_ledtrig_micmute(struct hda_codec *codec)
+{
+ struct hda_gen_spec *spec = codec->spec;
+
+ ledtrig_audio_set(LED_AUDIO_MICMUTE,
+ spec->micmute_led.led_value ? LED_ON : LED_OFF);
+}
+#endif
+
+/**
+ * snd_hda_gen_fixup_micmute_led - A fixup for mic-mute LED trigger
+ *
+ * Pass this function to the quirk entry if another driver supports the
+ * audio mic-mute LED trigger. Then this will bind the mixer capture switch
+ * change with the LED.
+ *
+ * Note that this fixup has to be called after other fixup that sets
+ * cap_sync_hook. Otherwise the chaining wouldn't work.
+ */
+void snd_hda_gen_fixup_micmute_led(struct hda_codec *codec,
+ const struct hda_fixup *fix, int action)
+{
+#if IS_REACHABLE(CONFIG_LEDS_TRIGGER_AUDIO)
+ if (action == HDA_FIXUP_ACT_PROBE)
+ snd_hda_gen_add_micmute_led(codec, call_ledtrig_micmute);
+#endif
+}
+EXPORT_SYMBOL_GPL(snd_hda_gen_fixup_micmute_led);
+
/*
* parse digital I/Os and set up NIDs in BIOS auto-parse mode
*/
diff --git a/sound/pci/hda/hda_generic.h b/sound/pci/hda/hda_generic.h
index 10123664fa61..78d77042b05a 100644
--- a/sound/pci/hda/hda_generic.h
+++ b/sound/pci/hda/hda_generic.h
@@ -357,5 +357,7 @@ int snd_hda_gen_fix_pin_power(struct hda_codec *codec, hda_nid_t pin);
int snd_hda_gen_add_micmute_led(struct hda_codec *codec,
void (*hook)(struct hda_codec *));
+void snd_hda_gen_fixup_micmute_led(struct hda_codec *codec,
+ const struct hda_fixup *fix, int action);
#endif /* __SOUND_HDA_GENERIC_H */
diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c
index 76f03abd15ab..e42cc2230977 100644
--- a/sound/pci/hda/hda_intel.c
+++ b/sound/pci/hda/hda_intel.c
@@ -172,6 +172,9 @@ module_param_array(beep_mode, bool, NULL, 0444);
MODULE_PARM_DESC(beep_mode, "Select HDA Beep registration mode "
"(0=off, 1=on) (default=1).");
#endif
+static int skl_pci_binding;
+module_param_named(pci_binding, skl_pci_binding, int, 0444);
+MODULE_PARM_DESC(pci_binding, "PCI binding (0=auto, 1=only legacy, 2=only asoc");
#ifdef CONFIG_PM
static int param_set_xint(const char *val, const struct kernel_param *kp);
@@ -310,31 +313,28 @@ enum {
#define AZX_DCAPS_INTEL_HASWELL \
(/*AZX_DCAPS_ALIGN_BUFSIZE |*/ AZX_DCAPS_COUNT_LPIB_DELAY |\
AZX_DCAPS_PM_RUNTIME | AZX_DCAPS_I915_COMPONENT |\
- AZX_DCAPS_I915_POWERWELL | AZX_DCAPS_SNOOP_TYPE(SCH))
+ AZX_DCAPS_SNOOP_TYPE(SCH))
/* Broadwell HDMI can't use position buffer reliably, force to use LPIB */
#define AZX_DCAPS_INTEL_BROADWELL \
(/*AZX_DCAPS_ALIGN_BUFSIZE |*/ AZX_DCAPS_POSFIX_LPIB |\
AZX_DCAPS_PM_RUNTIME | AZX_DCAPS_I915_COMPONENT |\
- AZX_DCAPS_I915_POWERWELL | AZX_DCAPS_SNOOP_TYPE(SCH))
+ AZX_DCAPS_SNOOP_TYPE(SCH))
#define AZX_DCAPS_INTEL_BAYTRAIL \
- (AZX_DCAPS_INTEL_PCH_BASE | AZX_DCAPS_I915_COMPONENT |\
- AZX_DCAPS_I915_POWERWELL)
+ (AZX_DCAPS_INTEL_PCH_BASE | AZX_DCAPS_I915_COMPONENT)
#define AZX_DCAPS_INTEL_BRASWELL \
(AZX_DCAPS_INTEL_PCH_BASE | AZX_DCAPS_PM_RUNTIME |\
- AZX_DCAPS_I915_COMPONENT | AZX_DCAPS_I915_POWERWELL)
+ AZX_DCAPS_I915_COMPONENT)
#define AZX_DCAPS_INTEL_SKYLAKE \
(AZX_DCAPS_INTEL_PCH_BASE | AZX_DCAPS_PM_RUNTIME |\
- AZX_DCAPS_SEPARATE_STREAM_TAG | AZX_DCAPS_I915_COMPONENT |\
- AZX_DCAPS_I915_POWERWELL)
+ AZX_DCAPS_SEPARATE_STREAM_TAG | AZX_DCAPS_I915_COMPONENT)
#define AZX_DCAPS_INTEL_BROXTON \
(AZX_DCAPS_INTEL_PCH_BASE | AZX_DCAPS_PM_RUNTIME |\
- AZX_DCAPS_SEPARATE_STREAM_TAG | AZX_DCAPS_I915_COMPONENT |\
- AZX_DCAPS_I915_POWERWELL)
+ AZX_DCAPS_SEPARATE_STREAM_TAG | AZX_DCAPS_I915_COMPONENT)
/* quirks for ATI SB / AMD Hudson */
#define AZX_DCAPS_PRESET_ATI_SB \
@@ -360,6 +360,7 @@ enum {
AZX_DCAPS_NO_64BIT |\
AZX_DCAPS_4K_BDLE_BOUNDARY | AZX_DCAPS_SNOOP_OFF)
+#define AZX_DCAPS_INTEL_DSP_DETECTION(conf) (IS_ENABLED(CONFIG_SND_HDA_INTEL_DSP_DETECTION_##conf) ? AZX_DCAPS_INTEL_SHARED : 0)
/*
* vga_switcheroo support
*/
@@ -591,8 +592,7 @@ static void hda_intel_init_chip(struct azx *chip, bool full_reset)
struct pci_dev *pci = chip->pci;
u32 val;
- if (chip->driver_caps & AZX_DCAPS_I915_POWERWELL)
- snd_hdac_set_codec_wakeup(bus, true);
+ snd_hdac_set_codec_wakeup(bus, true);
if (chip->driver_type == AZX_DRIVER_SKL) {
pci_read_config_dword(pci, INTEL_HDA_CGCTL, &val);
val = val & ~INTEL_HDA_CGCTL_MISCBDCGE;
@@ -604,8 +604,8 @@ static void hda_intel_init_chip(struct azx *chip, bool full_reset)
val = val | INTEL_HDA_CGCTL_MISCBDCGE;
pci_write_config_dword(pci, INTEL_HDA_CGCTL, val);
}
- if (chip->driver_caps & AZX_DCAPS_I915_POWERWELL)
- snd_hdac_set_codec_wakeup(bus, false);
+
+ snd_hdac_set_codec_wakeup(bus, false);
/* reduce dma latency to avoid noise */
if (IS_BXT(pci))
@@ -667,13 +667,8 @@ static int azx_position_check(struct azx *chip, struct azx_dev *azx_dev)
return 0;
}
-/* Enable/disable i915 display power for the link */
-static int azx_intel_link_power(struct azx *chip, bool enable)
-{
- struct hdac_bus *bus = azx_bus(chip);
-
- return snd_hdac_display_power(bus, enable);
-}
+#define display_power(chip, enable) \
+ snd_hdac_display_power(azx_bus(chip), HDA_CODEC_IDX_CONTROLLER, enable)
/*
* Check whether the current DMA position is acceptable for updating
@@ -930,35 +925,75 @@ static int param_set_xint(const char *val, const struct kernel_param *kp)
mutex_unlock(&card_list_lock);
return 0;
}
-#else
-#define azx_add_card_list(chip) /* NOP */
-#define azx_del_card_list(chip) /* NOP */
-#endif /* CONFIG_PM */
-#ifdef CONFIG_PM_SLEEP
/*
* power management
*/
-static int azx_suspend(struct device *dev)
+static bool azx_is_pm_ready(struct snd_card *card)
{
- struct snd_card *card = dev_get_drvdata(dev);
struct azx *chip;
struct hda_intel *hda;
- struct hdac_bus *bus;
if (!card)
- return 0;
-
+ return false;
chip = card->private_data;
hda = container_of(chip, struct hda_intel, chip);
if (chip->disabled || hda->init_failed || !chip->running)
+ return false;
+ return true;
+}
+
+static void __azx_runtime_suspend(struct azx *chip)
+{
+ azx_stop_chip(chip);
+ azx_enter_link_reset(chip);
+ azx_clear_irq_pending(chip);
+ display_power(chip, false);
+}
+
+static void __azx_runtime_resume(struct azx *chip)
+{
+ struct hda_intel *hda = container_of(chip, struct hda_intel, chip);
+ struct hdac_bus *bus = azx_bus(chip);
+ struct hda_codec *codec;
+ int status;
+
+ display_power(chip, true);
+ if (hda->need_i915_power)
+ snd_hdac_i915_set_bclk(bus);
+
+ /* Read STATESTS before controller reset */
+ status = azx_readw(chip, STATESTS);
+
+ azx_init_pci(chip);
+ hda_intel_init_chip(chip, true);
+
+ if (status) {
+ list_for_each_codec(codec, &chip->bus)
+ if (status & (1 << codec->addr))
+ schedule_delayed_work(&codec->jackpoll_work,
+ codec->jackpoll_interval);
+ }
+
+ /* power down again for link-controlled chips */
+ if (!hda->need_i915_power)
+ display_power(chip, false);
+}
+
+#ifdef CONFIG_PM_SLEEP
+static int azx_suspend(struct device *dev)
+{
+ struct snd_card *card = dev_get_drvdata(dev);
+ struct azx *chip;
+ struct hdac_bus *bus;
+
+ if (!azx_is_pm_ready(card))
return 0;
+ chip = card->private_data;
bus = azx_bus(chip);
snd_power_change_state(card, SNDRV_CTL_POWER_D3hot);
- azx_clear_irq_pending(chip);
- azx_stop_chip(chip);
- azx_enter_link_reset(chip);
+ __azx_runtime_suspend(chip);
if (bus->irq >= 0) {
free_irq(bus->irq, chip);
bus->irq = -1;
@@ -966,9 +1001,6 @@ static int azx_suspend(struct device *dev)
if (chip->msi)
pci_disable_msi(chip->pci);
- if ((chip->driver_caps & AZX_DCAPS_I915_POWERWELL)
- && hda->need_i915_power)
- snd_hdac_display_power(bus, false);
trace_azx_suspend(chip);
return 0;
@@ -976,41 +1008,19 @@ static int azx_suspend(struct device *dev)
static int azx_resume(struct device *dev)
{
- struct pci_dev *pci = to_pci_dev(dev);
struct snd_card *card = dev_get_drvdata(dev);
struct azx *chip;
- struct hda_intel *hda;
- struct hdac_bus *bus;
- if (!card)
+ if (!azx_is_pm_ready(card))
return 0;
chip = card->private_data;
- hda = container_of(chip, struct hda_intel, chip);
- bus = azx_bus(chip);
- if (chip->disabled || hda->init_failed || !chip->running)
- return 0;
-
- if (chip->driver_caps & AZX_DCAPS_I915_POWERWELL) {
- snd_hdac_display_power(bus, true);
- if (hda->need_i915_power)
- snd_hdac_i915_set_bclk(bus);
- }
-
if (chip->msi)
- if (pci_enable_msi(pci) < 0)
+ if (pci_enable_msi(chip->pci) < 0)
chip->msi = 0;
if (azx_acquire_irq(chip, 1) < 0)
return -EIO;
- azx_init_pci(chip);
-
- hda_intel_init_chip(chip, true);
-
- /* power down again for link-controlled chips */
- if ((chip->driver_caps & AZX_DCAPS_I915_POWERWELL) &&
- !hda->need_i915_power)
- snd_hdac_display_power(bus, false);
-
+ __azx_runtime_resume(chip);
snd_power_change_state(card, SNDRV_CTL_POWER_D0);
trace_azx_resume(chip);
@@ -1045,21 +1055,14 @@ static int azx_thaw_noirq(struct device *dev)
}
#endif /* CONFIG_PM_SLEEP */
-#ifdef CONFIG_PM
static int azx_runtime_suspend(struct device *dev)
{
struct snd_card *card = dev_get_drvdata(dev);
struct azx *chip;
- struct hda_intel *hda;
- if (!card)
+ if (!azx_is_pm_ready(card))
return 0;
-
chip = card->private_data;
- hda = container_of(chip, struct hda_intel, chip);
- if (chip->disabled || hda->init_failed)
- return 0;
-
if (!azx_has_pm_runtime(chip))
return 0;
@@ -1067,13 +1070,7 @@ static int azx_runtime_suspend(struct device *dev)
azx_writew(chip, WAKEEN, azx_readw(chip, WAKEEN) |
STATESTS_INT_MASK);
- azx_stop_chip(chip);
- azx_enter_link_reset(chip);
- azx_clear_irq_pending(chip);
- if ((chip->driver_caps & AZX_DCAPS_I915_POWERWELL)
- && hda->need_i915_power)
- snd_hdac_display_power(azx_bus(chip), false);
-
+ __azx_runtime_suspend(chip);
trace_azx_runtime_suspend(chip);
return 0;
}
@@ -1082,51 +1079,18 @@ static int azx_runtime_resume(struct device *dev)
{
struct snd_card *card = dev_get_drvdata(dev);
struct azx *chip;
- struct hda_intel *hda;
- struct hdac_bus *bus;
- struct hda_codec *codec;
- int status;
- if (!card)
+ if (!azx_is_pm_ready(card))
return 0;
-
chip = card->private_data;
- hda = container_of(chip, struct hda_intel, chip);
- bus = azx_bus(chip);
- if (chip->disabled || hda->init_failed)
- return 0;
-
if (!azx_has_pm_runtime(chip))
return 0;
-
- if (chip->driver_caps & AZX_DCAPS_I915_POWERWELL) {
- snd_hdac_display_power(bus, true);
- if (hda->need_i915_power)
- snd_hdac_i915_set_bclk(bus);
- }
-
- /* Read STATESTS before controller reset */
- status = azx_readw(chip, STATESTS);
-
- azx_init_pci(chip);
- hda_intel_init_chip(chip, true);
-
- if (status) {
- list_for_each_codec(codec, &chip->bus)
- if (status & (1 << codec->addr))
- schedule_delayed_work(&codec->jackpoll_work,
- codec->jackpoll_interval);
- }
+ __azx_runtime_resume(chip);
/* disable controller Wake Up event*/
azx_writew(chip, WAKEEN, azx_readw(chip, WAKEEN) &
~STATESTS_INT_MASK);
- /* power down again for link-controlled chips */
- if ((chip->driver_caps & AZX_DCAPS_I915_POWERWELL) &&
- !hda->need_i915_power)
- snd_hdac_display_power(bus, false);
-
trace_azx_runtime_resume(chip);
return 0;
}
@@ -1167,6 +1131,8 @@ static const struct dev_pm_ops azx_pm = {
#define AZX_PM_OPS &azx_pm
#else
+#define azx_add_card_list(chip) /* NOP */
+#define azx_del_card_list(chip) /* NOP */
#define AZX_PM_OPS NULL
#endif /* CONFIG_PM */
@@ -1374,11 +1340,8 @@ static int azx_free(struct azx *chip)
#ifdef CONFIG_SND_HDA_PATCH_LOADER
release_firmware(chip->fw);
#endif
+ display_power(chip, false);
- if (chip->driver_caps & AZX_DCAPS_I915_POWERWELL) {
- if (hda->need_i915_power)
- snd_hdac_display_power(bus, false);
- }
if (chip->driver_caps & AZX_DCAPS_I915_COMPONENT)
snd_hdac_i915_exit(bus);
kfree(hda);
@@ -1935,8 +1898,7 @@ static int azx_first_init(struct azx *chip)
/* initialize chip */
azx_init_pci(chip);
- if (chip->driver_caps & AZX_DCAPS_I915_POWERWELL)
- snd_hdac_i915_set_bclk(bus);
+ snd_hdac_i915_set_bclk(bus);
hda_intel_init_chip(chip, (probe_only[dev] & 2) == 0);
@@ -2078,7 +2040,6 @@ static const struct hda_controller_ops pci_hda_ops = {
.disable_msi_reset_irq = disable_msi_reset_irq,
.pcm_mmap_prepare = pcm_mmap_prepare,
.position_check = azx_position_check,
- .link_power = azx_intel_link_power,
};
static int azx_probe(struct pci_dev *pci,
@@ -2091,6 +2052,28 @@ static int azx_probe(struct pci_dev *pci,
bool schedule_probe;
int err;
+ /* check if this driver can be used on SKL+ Intel platforms */
+ if (pci_id->driver_data & AZX_DCAPS_INTEL_SHARED) {
+ switch (skl_pci_binding) {
+ case SND_SKL_PCI_BIND_AUTO:
+ if (pci->class != 0x040300) {
+ dev_info(&pci->dev, "The DSP is enabled on this platform, aborting probe\n");
+ return -ENODEV;
+ }
+ dev_info(&pci->dev, "No DSP detected, continuing HDaudio legacy probe\n");
+ break;
+ case SND_SKL_PCI_BIND_LEGACY:
+ dev_info(&pci->dev, "Module parameter forced binding with HDaudio legacy, bypassed detection logic\n");
+ break;
+ case SND_SKL_PCI_BIND_ASOC:
+ dev_info(&pci->dev, "Module parameter forced binding with SKL+ ASoC driver, aborting probe\n");
+ return -ENODEV;
+ default:
+ dev_err(&pci->dev, "invalid value for skl_pci_binding module parameter, ignored\n");
+ break;
+ }
+ }
+
if (dev >= SNDRV_CARDS)
return -ENODEV;
if (!enable[dev]) {
@@ -2245,10 +2228,13 @@ static int azx_probe_continue(struct azx *chip)
goto out_free;
} else {
/* don't bother any longer */
- chip->driver_caps &=
- ~(AZX_DCAPS_I915_COMPONENT | AZX_DCAPS_I915_POWERWELL);
+ chip->driver_caps &= ~AZX_DCAPS_I915_COMPONENT;
}
}
+
+ /* HSW/BDW controllers need this power */
+ if (CONTROLLER_IN_GPU(pci))
+ hda->need_i915_power = 1;
}
/* Request display power well for the HDA controller or codec. For
@@ -2256,18 +2242,7 @@ static int azx_probe_continue(struct azx *chip)
* this power. For other platforms, like Baytrail/Braswell, only the
* display codec needs the power and it can be released after probe.
*/
- if (chip->driver_caps & AZX_DCAPS_I915_POWERWELL) {
- /* HSW/BDW controllers need this power */
- if (CONTROLLER_IN_GPU(pci))
- hda->need_i915_power = 1;
-
- err = snd_hdac_display_power(bus, true);
- if (err < 0) {
- dev_err(chip->card->dev,
- "Cannot turn on display power on i915\n");
- goto i915_power_fail;
- }
- }
+ display_power(chip, true);
err = azx_first_init(chip);
if (err < 0)
@@ -2315,11 +2290,8 @@ static int azx_probe_continue(struct azx *chip)
pm_runtime_put_autosuspend(&pci->dev);
out_free:
- if ((chip->driver_caps & AZX_DCAPS_I915_POWERWELL)
- && !hda->need_i915_power)
- snd_hdac_display_power(bus, false);
-
-i915_power_fail:
+ if (err < 0 || !hda->need_i915_power)
+ display_power(chip, false);
if (err < 0)
hda->init_failed = 1;
complete_all(&hda->probe_wait);
@@ -2408,34 +2380,48 @@ static const struct pci_device_id azx_ids[] = {
.driver_data = AZX_DRIVER_SKL | AZX_DCAPS_INTEL_SKYLAKE },
/* Sunrise Point-LP */
{ PCI_DEVICE(0x8086, 0x9d70),
- .driver_data = AZX_DRIVER_SKL | AZX_DCAPS_INTEL_SKYLAKE },
+ .driver_data = AZX_DRIVER_SKL | AZX_DCAPS_INTEL_SKYLAKE |
+ AZX_DCAPS_INTEL_DSP_DETECTION(SKL)
+ },
/* Kabylake */
{ PCI_DEVICE(0x8086, 0xa171),
.driver_data = AZX_DRIVER_SKL | AZX_DCAPS_INTEL_SKYLAKE },
/* Kabylake-LP */
{ PCI_DEVICE(0x8086, 0x9d71),
- .driver_data = AZX_DRIVER_SKL | AZX_DCAPS_INTEL_SKYLAKE },
+ .driver_data = AZX_DRIVER_SKL | AZX_DCAPS_INTEL_SKYLAKE |
+ AZX_DCAPS_INTEL_DSP_DETECTION(KBL)
+ },
/* Kabylake-H */
{ PCI_DEVICE(0x8086, 0xa2f0),
.driver_data = AZX_DRIVER_SKL | AZX_DCAPS_INTEL_SKYLAKE },
/* Coffelake */
{ PCI_DEVICE(0x8086, 0xa348),
- .driver_data = AZX_DRIVER_SKL | AZX_DCAPS_INTEL_SKYLAKE},
+ .driver_data = AZX_DRIVER_SKL | AZX_DCAPS_INTEL_SKYLAKE |
+ AZX_DCAPS_INTEL_DSP_DETECTION(CFL)
+ },
/* Cannonlake */
{ PCI_DEVICE(0x8086, 0x9dc8),
- .driver_data = AZX_DRIVER_SKL | AZX_DCAPS_INTEL_SKYLAKE},
+ .driver_data = AZX_DRIVER_SKL | AZX_DCAPS_INTEL_SKYLAKE |
+ AZX_DCAPS_INTEL_DSP_DETECTION(CNL)
+ },
/* Icelake */
{ PCI_DEVICE(0x8086, 0x34c8),
- .driver_data = AZX_DRIVER_SKL | AZX_DCAPS_INTEL_SKYLAKE},
+ .driver_data = AZX_DRIVER_SKL | AZX_DCAPS_INTEL_SKYLAKE |
+ AZX_DCAPS_INTEL_DSP_DETECTION(ICL)
+ },
/* Broxton-P(Apollolake) */
{ PCI_DEVICE(0x8086, 0x5a98),
- .driver_data = AZX_DRIVER_SKL | AZX_DCAPS_INTEL_BROXTON },
+ .driver_data = AZX_DRIVER_SKL | AZX_DCAPS_INTEL_BROXTON |
+ AZX_DCAPS_INTEL_DSP_DETECTION(APL)
+ },
/* Broxton-T */
{ PCI_DEVICE(0x8086, 0x1a98),
.driver_data = AZX_DRIVER_SKL | AZX_DCAPS_INTEL_BROXTON },
/* Gemini-Lake */
{ PCI_DEVICE(0x8086, 0x3198),
- .driver_data = AZX_DRIVER_SKL | AZX_DCAPS_INTEL_BROXTON },
+ .driver_data = AZX_DRIVER_SKL | AZX_DCAPS_INTEL_BROXTON |
+ AZX_DCAPS_INTEL_DSP_DETECTION(GLK)
+ },
/* Haswell */
{ PCI_DEVICE(0x8086, 0x0a0c),
.driver_data = AZX_DRIVER_HDMI | AZX_DCAPS_INTEL_HASWELL },
diff --git a/sound/pci/hda/hda_jack.c b/sound/pci/hda/hda_jack.c
index c499727920e6..74b46952fc98 100644
--- a/sound/pci/hda/hda_jack.c
+++ b/sound/pci/hda/hda_jack.c
@@ -339,9 +339,15 @@ void snd_hda_jack_report_sync(struct hda_codec *codec)
if (jack->nid) {
if (!jack->jack || jack->block_report)
continue;
- state = get_jack_plug_state(jack->pin_sense);
- snd_jack_report(jack->jack,
- state ? jack->type : 0);
+ state = jack->button_state;
+ if (get_jack_plug_state(jack->pin_sense))
+ state |= jack->type;
+ snd_jack_report(jack->jack, state);
+ if (jack->button_state) {
+ snd_jack_report(jack->jack,
+ state & ~jack->button_state);
+ jack->button_state = 0; /* button released */
+ }
}
}
EXPORT_SYMBOL_GPL(snd_hda_jack_report_sync);
@@ -379,15 +385,19 @@ static void hda_free_jack_priv(struct snd_jack *jack)
* @nid: pin NID to assign
* @name: string name for the jack
* @phantom_jack: flag to deal as a phantom jack
+ * @type: jack type bits to be reported, 0 for guessing from pincfg
+ * @keymap: optional jack / key mapping
*
* This assigns a jack-detection kctl to the given pin. The kcontrol
* will have the given name and index.
*/
int snd_hda_jack_add_kctl(struct hda_codec *codec, hda_nid_t nid,
- const char *name, bool phantom_jack)
+ const char *name, bool phantom_jack,
+ int type, const struct hda_jack_keymap *keymap)
{
struct hda_jack_tbl *jack;
- int err, state, type;
+ const struct hda_jack_keymap *map;
+ int err, state, buttons;
jack = snd_hda_jack_tbl_new(codec, nid);
if (!jack)
@@ -395,16 +405,30 @@ int snd_hda_jack_add_kctl(struct hda_codec *codec, hda_nid_t nid,
if (jack->jack)
return 0; /* already created */
- type = get_input_jack_type(codec, nid);
- err = snd_jack_new(codec->card, name, type,
+ if (!type)
+ type = get_input_jack_type(codec, nid);
+
+ buttons = 0;
+ if (keymap) {
+ for (map = keymap; map->type; map++)
+ buttons |= map->type;
+ }
+
+ err = snd_jack_new(codec->card, name, type | buttons,
&jack->jack, true, phantom_jack);
if (err < 0)
return err;
jack->phantom_jack = !!phantom_jack;
jack->type = type;
+ jack->button_state = 0;
jack->jack->private_data = jack;
jack->jack->private_free = hda_free_jack_priv;
+ if (keymap) {
+ for (map = keymap; map->type; map++)
+ snd_jack_set_key(jack->jack, map->type, map->key);
+ }
+
state = snd_hda_jack_detect(codec, nid);
snd_jack_report(jack->jack, state ? jack->type : 0);
@@ -437,7 +461,7 @@ static int add_jack_kctl(struct hda_codec *codec, hda_nid_t nid,
if (phantom_jack)
/* Example final name: "Internal Mic Phantom Jack" */
strncat(name, " Phantom", sizeof(name) - strlen(name) - 1);
- err = snd_hda_jack_add_kctl(codec, nid, name, phantom_jack);
+ err = snd_hda_jack_add_kctl(codec, nid, name, phantom_jack, 0, NULL);
if (err < 0)
return err;
@@ -508,19 +532,25 @@ int snd_hda_jack_add_kctls(struct hda_codec *codec,
}
EXPORT_SYMBOL_GPL(snd_hda_jack_add_kctls);
-static void call_jack_callback(struct hda_codec *codec,
+static void call_jack_callback(struct hda_codec *codec, unsigned int res,
struct hda_jack_tbl *jack)
{
struct hda_jack_callback *cb;
- for (cb = jack->callback; cb; cb = cb->next)
+ for (cb = jack->callback; cb; cb = cb->next) {
+ cb->jack = jack;
+ cb->unsol_res = res;
cb->func(codec, cb);
+ }
if (jack->gated_jack) {
struct hda_jack_tbl *gated =
snd_hda_jack_tbl_get(codec, jack->gated_jack);
if (gated) {
- for (cb = gated->callback; cb; cb = cb->next)
+ for (cb = gated->callback; cb; cb = cb->next) {
+ cb->jack = gated;
+ cb->unsol_res = res;
cb->func(codec, cb);
+ }
}
}
}
@@ -540,7 +570,7 @@ void snd_hda_jack_unsol_event(struct hda_codec *codec, unsigned int res)
return;
event->jack_dirty = 1;
- call_jack_callback(codec, event);
+ call_jack_callback(codec, res, event);
snd_hda_jack_report_sync(codec);
}
EXPORT_SYMBOL_GPL(snd_hda_jack_unsol_event);
@@ -566,7 +596,7 @@ void snd_hda_jack_poll_all(struct hda_codec *codec)
if (old_sense == get_jack_plug_state(jack->pin_sense))
continue;
changes = 1;
- call_jack_callback(codec, jack);
+ call_jack_callback(codec, 0, jack);
}
if (changes)
snd_hda_jack_report_sync(codec);
diff --git a/sound/pci/hda/hda_jack.h b/sound/pci/hda/hda_jack.h
index e9814c0168ea..1d713201c160 100644
--- a/sound/pci/hda/hda_jack.h
+++ b/sound/pci/hda/hda_jack.h
@@ -13,6 +13,7 @@
#define __SOUND_HDA_JACK_H
#include <linux/err.h>
+#include <sound/jack.h>
struct auto_pin_cfg;
struct hda_jack_tbl;
@@ -24,6 +25,8 @@ struct hda_jack_callback {
hda_nid_t nid;
hda_jack_callback_fn func;
unsigned int private_data; /* arbitrary data */
+ unsigned int unsol_res; /* unsolicited event bits */
+ struct hda_jack_tbl *jack; /* associated jack entry */
struct hda_jack_callback *next;
};
@@ -40,9 +43,15 @@ struct hda_jack_tbl {
hda_nid_t gating_jack; /* valid when gating jack plugged */
hda_nid_t gated_jack; /* gated is dependent on this jack */
int type;
+ int button_state;
struct snd_jack *jack;
};
+struct hda_jack_keymap {
+ enum snd_jack_types type;
+ int key;
+};
+
struct hda_jack_tbl *
snd_hda_jack_tbl_get(struct hda_codec *codec, hda_nid_t nid);
struct hda_jack_tbl *
@@ -82,7 +91,8 @@ static inline bool snd_hda_jack_detect(struct hda_codec *codec, hda_nid_t nid)
bool is_jack_detectable(struct hda_codec *codec, hda_nid_t nid);
int snd_hda_jack_add_kctl(struct hda_codec *codec, hda_nid_t nid,
- const char *name, bool phantom_jack);
+ const char *name, bool phantom_jack,
+ int type, const struct hda_jack_keymap *keymap);
int snd_hda_jack_add_kctls(struct hda_codec *codec,
const struct auto_pin_cfg *cfg);
diff --git a/sound/pci/hda/hda_tegra.c b/sound/pci/hda/hda_tegra.c
index dd7d4242d6d2..83befd8d43e8 100644
--- a/sound/pci/hda/hda_tegra.c
+++ b/sound/pci/hda/hda_tegra.c
@@ -31,6 +31,7 @@
#include <linux/of_device.h>
#include <linux/slab.h>
#include <linux/time.h>
+#include <linux/string.h>
#include <sound/core.h>
#include <sound/initval.h>
@@ -344,6 +345,8 @@ static int hda_tegra_first_init(struct azx *chip, struct platform_device *pdev)
int err;
unsigned short gcap;
int irq_id = platform_get_irq(pdev, 0);
+ const char *sname;
+ struct device_node *root;
err = hda_tegra_init_chip(chip, pdev);
if (err)
@@ -401,8 +404,23 @@ static int hda_tegra_first_init(struct azx *chip, struct platform_device *pdev)
return -ENODEV;
}
+ /* driver name */
strcpy(card->driver, "tegra-hda");
- strcpy(card->shortname, "tegra-hda");
+
+ root = of_find_node_by_path("/");
+ sname = of_get_property(root, "compatible", NULL);
+ of_node_put(root);
+ if (!sname) {
+ dev_err(card->dev,
+ "failed to get compatible property from root node\n");
+ return -ENODEV;
+ }
+ /* shortname for card */
+ if (strlen(sname) > sizeof(card->shortname))
+ dev_info(card->dev, "truncating shortname for card\n");
+ strncpy(card->shortname, sname, sizeof(card->shortname));
+
+ /* longname for card */
snprintf(card->longname, sizeof(card->longname),
"%s at 0x%lx irq %i",
card->shortname, bus->addr, bus->irq);
@@ -513,7 +531,7 @@ static void hda_tegra_probe_work(struct work_struct *work)
goto out_free;
/* create codec instances */
- err = azx_probe_codecs(chip, 0);
+ err = azx_probe_codecs(chip, 8);
if (err < 0)
goto out_free;
diff --git a/sound/pci/hda/patch_ca0132.c b/sound/pci/hda/patch_ca0132.c
index 0a567634e5fa..e5bdbc245682 100644
--- a/sound/pci/hda/patch_ca0132.c
+++ b/sound/pci/hda/patch_ca0132.c
@@ -1081,6 +1081,18 @@ enum {
QUIRK_AE5,
};
+#ifdef CONFIG_PCI
+#define ca0132_quirk(spec) ((spec)->quirk)
+#define ca0132_use_pci_mmio(spec) ((spec)->use_pci_mmio)
+#define ca0132_use_alt_functions(spec) ((spec)->use_alt_functions)
+#define ca0132_use_alt_controls(spec) ((spec)->use_alt_controls)
+#else
+#define ca0132_quirk(spec) ({ (void)(spec); QUIRK_NONE; })
+#define ca0132_use_alt_functions(spec) ({ (void)(spec); false; })
+#define ca0132_use_pci_mmio(spec) ({ (void)(spec); false; })
+#define ca0132_use_alt_controls(spec) ({ (void)(spec); false; })
+#endif
+
static const struct hda_pintbl alienware_pincfgs[] = {
{ 0x0b, 0x90170110 }, /* Builtin Speaker */
{ 0x0c, 0x411111f0 }, /* N/A */
@@ -3101,7 +3113,7 @@ static void dspload_post_setup(struct hda_codec *codec)
{
struct ca0132_spec *spec = codec->spec;
codec_dbg(codec, "---- dspload_post_setup ------\n");
- if (!spec->use_alt_functions) {
+ if (!ca0132_use_alt_functions(spec)) {
/*set DSP speaker to 2.0 configuration*/
chipio_write(codec, XRAM_XRAM_INST_OFFSET(0x18), 0x08080080);
chipio_write(codec, XRAM_XRAM_INST_OFFSET(0x19), 0x3f800000);
@@ -3333,7 +3345,7 @@ static void ca0132_gpio_init(struct hda_codec *codec)
{
struct ca0132_spec *spec = codec->spec;
- switch (spec->quirk) {
+ switch (ca0132_quirk(spec)) {
case QUIRK_SBZ:
case QUIRK_AE5:
snd_hda_codec_write(codec, 0x01, 0, 0x793, 0x00);
@@ -3344,6 +3356,8 @@ static void ca0132_gpio_init(struct hda_codec *codec)
snd_hda_codec_write(codec, 0x01, 0, 0x793, 0x00);
snd_hda_codec_write(codec, 0x01, 0, 0x794, 0x5B);
break;
+ default:
+ break;
}
}
@@ -3353,7 +3367,7 @@ static void ca0132_gpio_setup(struct hda_codec *codec)
{
struct ca0132_spec *spec = codec->spec;
- switch (spec->quirk) {
+ switch (ca0132_quirk(spec)) {
case QUIRK_SBZ:
snd_hda_codec_write(codec, 0x01, 0,
AC_VERB_SET_GPIO_DIRECTION, 0x07);
@@ -3372,6 +3386,8 @@ static void ca0132_gpio_setup(struct hda_codec *codec)
snd_hda_codec_write(codec, 0x01, 0,
AC_VERB_SET_GPIO_DATA, 0x0C);
break;
+ default:
+ break;
}
}
@@ -4172,7 +4188,7 @@ static void ca0132_alt_select_out_quirk_handler(struct hda_codec *codec)
switch (spec->cur_out_type) {
case SPEAKER_OUT:
- switch (spec->quirk) {
+ switch (ca0132_quirk(spec)) {
case QUIRK_SBZ:
ca0113_mmio_gpio_set(codec, 7, false);
ca0113_mmio_gpio_set(codec, 4, true);
@@ -4203,10 +4219,12 @@ static void ca0132_alt_select_out_quirk_handler(struct hda_codec *codec)
chipio_set_control_param(codec, 0x0d, 0xa4);
chipio_write(codec, 0x18b03c, 0x00000012);
break;
+ default:
+ break;
}
break;
case HEADPHONE_OUT:
- switch (spec->quirk) {
+ switch (ca0132_quirk(spec)) {
case QUIRK_SBZ:
ca0113_mmio_gpio_set(codec, 7, true);
ca0113_mmio_gpio_set(codec, 4, true);
@@ -4238,10 +4256,12 @@ static void ca0132_alt_select_out_quirk_handler(struct hda_codec *codec)
chipio_set_control_param(codec, 0x0d, 0xa1);
chipio_write(codec, 0x18b03c, 0x00000012);
break;
+ default:
+ break;
}
break;
case SURROUND_OUT:
- switch (spec->quirk) {
+ switch (ca0132_quirk(spec)) {
case QUIRK_SBZ:
ca0113_mmio_gpio_set(codec, 7, false);
ca0113_mmio_gpio_set(codec, 4, true);
@@ -4272,6 +4292,8 @@ static void ca0132_alt_select_out_quirk_handler(struct hda_codec *codec)
chipio_set_control_param(codec, 0x0d, 0xa4);
chipio_write(codec, 0x18b03c, 0x00000012);
break;
+ default:
+ break;
}
break;
}
@@ -4446,7 +4468,7 @@ static void ca0132_unsol_hp_delayed(struct work_struct *work)
to_delayed_work(work), struct ca0132_spec, unsol_hp_work);
struct hda_jack_tbl *jack;
- if (spec->use_alt_functions)
+ if (ca0132_use_alt_functions(spec))
ca0132_alt_select_out(spec->codec);
else
ca0132_select_out(spec->codec);
@@ -4530,14 +4552,14 @@ static int ca0132_alt_set_vipsource(struct hda_codec *codec, int val)
chipio_set_conn_rate(codec, MEM_CONNID_MICIN1, SR_96_000);
chipio_set_conn_rate(codec, MEM_CONNID_MICOUT1, SR_96_000);
- if (spec->quirk == QUIRK_R3DI)
+ if (ca0132_quirk(spec) == QUIRK_R3DI)
chipio_set_conn_rate(codec, 0x0F, SR_96_000);
if (spec->in_enum_val == REAR_LINE_IN)
tmp = FLOAT_ZERO;
else {
- if (spec->quirk == QUIRK_SBZ)
+ if (ca0132_quirk(spec) == QUIRK_SBZ)
tmp = FLOAT_THREE;
else
tmp = FLOAT_ONE;
@@ -4549,7 +4571,7 @@ static int ca0132_alt_set_vipsource(struct hda_codec *codec, int val)
codec_dbg(codec, "%s: on.", __func__);
chipio_set_conn_rate(codec, MEM_CONNID_MICIN1, SR_16_000);
chipio_set_conn_rate(codec, MEM_CONNID_MICOUT1, SR_16_000);
- if (spec->quirk == QUIRK_R3DI)
+ if (ca0132_quirk(spec) == QUIRK_R3DI)
chipio_set_conn_rate(codec, 0x0F, SR_16_000);
if (spec->effects_switch[VOICE_FOCUS - EFFECT_START_NID])
@@ -4645,7 +4667,7 @@ static int ca0132_alt_select_in(struct hda_codec *codec)
switch (spec->cur_mic_type) {
case REAR_MIC:
- switch (spec->quirk) {
+ switch (ca0132_quirk(spec)) {
case QUIRK_SBZ:
case QUIRK_R3D:
ca0113_mmio_gpio_set(codec, 0, false);
@@ -4669,14 +4691,14 @@ static int ca0132_alt_select_in(struct hda_codec *codec)
chipio_set_conn_rate(codec, MEM_CONNID_MICIN1, SR_96_000);
chipio_set_conn_rate(codec, MEM_CONNID_MICOUT1, SR_96_000);
- if (spec->quirk == QUIRK_R3DI)
+ if (ca0132_quirk(spec) == QUIRK_R3DI)
chipio_set_conn_rate(codec, 0x0F, SR_96_000);
dspio_set_uint_param(codec, 0x80, 0x00, tmp);
chipio_set_stream_control(codec, 0x03, 1);
chipio_set_stream_control(codec, 0x04, 1);
- switch (spec->quirk) {
+ switch (ca0132_quirk(spec)) {
case QUIRK_SBZ:
chipio_write(codec, 0x18B098, 0x0000000C);
chipio_write(codec, 0x18B09C, 0x0000000C);
@@ -4689,12 +4711,14 @@ static int ca0132_alt_select_in(struct hda_codec *codec)
chipio_write(codec, 0x18B098, 0x0000000C);
chipio_write(codec, 0x18B09C, 0x0000004C);
break;
+ default:
+ break;
}
ca0132_alt_mic_boost_set(codec, spec->mic_boost_enum_val);
break;
case REAR_LINE_IN:
ca0132_mic_boost_set(codec, 0);
- switch (spec->quirk) {
+ switch (ca0132_quirk(spec)) {
case QUIRK_SBZ:
case QUIRK_R3D:
ca0113_mmio_gpio_set(codec, 0, false);
@@ -4705,28 +4729,32 @@ static int ca0132_alt_select_in(struct hda_codec *codec)
case QUIRK_AE5:
ca0113_mmio_command_set(codec, 0x48, 0x28, 0x00);
break;
+ default:
+ break;
}
chipio_set_conn_rate(codec, MEM_CONNID_MICIN1, SR_96_000);
chipio_set_conn_rate(codec, MEM_CONNID_MICOUT1, SR_96_000);
- if (spec->quirk == QUIRK_R3DI)
+ if (ca0132_quirk(spec) == QUIRK_R3DI)
chipio_set_conn_rate(codec, 0x0F, SR_96_000);
tmp = FLOAT_ZERO;
dspio_set_uint_param(codec, 0x80, 0x00, tmp);
- switch (spec->quirk) {
+ switch (ca0132_quirk(spec)) {
case QUIRK_SBZ:
case QUIRK_AE5:
chipio_write(codec, 0x18B098, 0x00000000);
chipio_write(codec, 0x18B09C, 0x00000000);
break;
+ default:
+ break;
}
chipio_set_stream_control(codec, 0x03, 1);
chipio_set_stream_control(codec, 0x04, 1);
break;
case FRONT_MIC:
- switch (spec->quirk) {
+ switch (ca0132_quirk(spec)) {
case QUIRK_SBZ:
case QUIRK_R3D:
ca0113_mmio_gpio_set(codec, 0, true);
@@ -4748,7 +4776,7 @@ static int ca0132_alt_select_in(struct hda_codec *codec)
chipio_set_conn_rate(codec, MEM_CONNID_MICIN1, SR_96_000);
chipio_set_conn_rate(codec, MEM_CONNID_MICOUT1, SR_96_000);
- if (spec->quirk == QUIRK_R3DI)
+ if (ca0132_quirk(spec) == QUIRK_R3DI)
chipio_set_conn_rate(codec, 0x0F, SR_96_000);
dspio_set_uint_param(codec, 0x80, 0x00, tmp);
@@ -4756,7 +4784,7 @@ static int ca0132_alt_select_in(struct hda_codec *codec)
chipio_set_stream_control(codec, 0x03, 1);
chipio_set_stream_control(codec, 0x04, 1);
- switch (spec->quirk) {
+ switch (ca0132_quirk(spec)) {
case QUIRK_SBZ:
chipio_write(codec, 0x18B098, 0x0000000C);
chipio_write(codec, 0x18B09C, 0x000000CC);
@@ -4765,6 +4793,8 @@ static int ca0132_alt_select_in(struct hda_codec *codec)
chipio_write(codec, 0x18B098, 0x0000000C);
chipio_write(codec, 0x18B09C, 0x0000004C);
break;
+ default:
+ break;
}
ca0132_alt_mic_boost_set(codec, spec->mic_boost_enum_val);
break;
@@ -4859,7 +4889,7 @@ static int ca0132_effects_set(struct hda_codec *codec, hda_nid_t nid, long val)
val = 0;
/* If Voice Focus on SBZ, set to two channel. */
- if ((nid == VOICE_FOCUS) && (spec->use_pci_mmio)
+ if ((nid == VOICE_FOCUS) && ca0132_use_pci_mmio(spec)
&& (spec->cur_mic_type != REAR_LINE_IN)) {
if (spec->effects_switch[CRYSTAL_VOICE -
EFFECT_START_NID]) {
@@ -4878,7 +4908,7 @@ static int ca0132_effects_set(struct hda_codec *codec, hda_nid_t nid, long val)
* For SBZ noise reduction, there's an extra command
* to module ID 0x47. No clue why.
*/
- if ((nid == NOISE_REDUCTION) && (spec->use_pci_mmio)
+ if ((nid == NOISE_REDUCTION) && ca0132_use_pci_mmio(spec)
&& (spec->cur_mic_type != REAR_LINE_IN)) {
if (spec->effects_switch[CRYSTAL_VOICE -
EFFECT_START_NID]) {
@@ -4894,7 +4924,7 @@ static int ca0132_effects_set(struct hda_codec *codec, hda_nid_t nid, long val)
}
/* If rear line in disable effects. */
- if (spec->use_alt_functions &&
+ if (ca0132_use_alt_functions(spec) &&
spec->in_enum_val == REAR_LINE_IN)
val = 0;
}
@@ -4924,7 +4954,7 @@ static int ca0132_pe_switch_set(struct hda_codec *codec)
codec_dbg(codec, "ca0132_pe_switch_set: val=%ld\n",
spec->effects_switch[PLAY_ENHANCEMENT - EFFECT_START_NID]);
- if (spec->use_alt_functions)
+ if (ca0132_use_alt_functions(spec))
ca0132_alt_select_out(codec);
i = OUT_EFFECT_START_NID - EFFECT_START_NID;
@@ -4984,7 +5014,7 @@ static int ca0132_cvoice_switch_set(struct hda_codec *codec)
/* set correct vipsource */
oldval = stop_mic1(codec);
- if (spec->use_alt_functions)
+ if (ca0132_use_alt_functions(spec))
ret |= ca0132_alt_set_vipsource(codec, 1);
else
ret |= ca0132_set_vipsource(codec, 1);
@@ -5053,7 +5083,7 @@ static int ca0132_vnode_switch_set(struct snd_kcontrol *kcontrol,
auto_jack =
spec->vnode_lswitch[VNID_HP_ASEL - VNODE_START_NID];
if (!auto_jack) {
- if (spec->use_alt_functions)
+ if (ca0132_use_alt_functions(spec))
ca0132_alt_select_out(codec);
else
ca0132_select_out(codec);
@@ -5070,7 +5100,7 @@ static int ca0132_vnode_switch_set(struct snd_kcontrol *kcontrol,
}
if (nid == VNID_HP_ASEL) {
- if (spec->use_alt_functions)
+ if (ca0132_use_alt_functions(spec))
ca0132_alt_select_out(codec);
else
ca0132_select_out(codec);
@@ -5784,7 +5814,7 @@ static int ca0132_switch_put(struct snd_kcontrol *kcontrol,
/* mic boost */
if (nid == spec->input_pins[0]) {
spec->cur_mic_boost = *valp;
- if (spec->use_alt_functions) {
+ if (ca0132_use_alt_functions(spec)) {
if (spec->in_enum_val != REAR_LINE_IN)
changed = ca0132_mic_boost_set(codec, *valp);
} else {
@@ -6080,7 +6110,7 @@ static int add_fx_switch(struct hda_codec *codec, hda_nid_t nid,
/* If using alt_controls, add FX: prefix. But, don't add FX:
* prefix to OutFX or InFX enable controls.
*/
- if ((spec->use_alt_controls) && (nid <= IN_EFFECT_END_NID))
+ if (ca0132_use_alt_controls(spec) && (nid <= IN_EFFECT_END_NID))
sprintf(namestr, "FX: %s %s Switch", pfx, dirstr[dir]);
else
sprintf(namestr, "%s %s Switch", pfx, dirstr[dir]);
@@ -6357,7 +6387,7 @@ static int ca0132_build_controls(struct hda_codec *codec)
return err;
}
/* Setup vmaster with surround slaves for desktop ca0132 devices */
- if (spec->use_alt_functions) {
+ if (ca0132_use_alt_functions(spec)) {
snd_hda_set_vmaster_tlv(codec, spec->dacs[0], HDA_OUTPUT,
spec->tlv);
snd_hda_add_vmaster(codec, "Master Playback Volume",
@@ -6377,7 +6407,7 @@ static int ca0132_build_controls(struct hda_codec *codec)
num_fx = OUT_EFFECTS_COUNT + IN_EFFECTS_COUNT;
for (i = 0; i < num_fx; i++) {
/* Desktop cards break if Echo Cancellation is used. */
- if (spec->use_pci_mmio) {
+ if (ca0132_use_pci_mmio(spec)) {
if (i == (ECHO_CANCELLATION - IN_EFFECT_START_NID +
OUT_EFFECTS_COUNT))
continue;
@@ -6394,7 +6424,7 @@ static int ca0132_build_controls(struct hda_codec *codec)
* EQ presets, and Smart Volume presets. Also, change names to add FX
* prefix, and change PlayEnhancement and CrystalVoice to match.
*/
- if (spec->use_alt_controls) {
+ if (ca0132_use_alt_controls(spec)) {
err = ca0132_alt_add_svm_enum(codec);
if (err < 0)
return err;
@@ -6448,7 +6478,7 @@ static int ca0132_build_controls(struct hda_codec *codec)
* to select the new outputs and inputs, plus add the new mic boost
* setting control.
*/
- if (spec->use_alt_functions) {
+ if (ca0132_use_alt_functions(spec)) {
err = ca0132_alt_add_output_enum(codec);
if (err < 0)
return err;
@@ -6459,14 +6489,14 @@ static int ca0132_build_controls(struct hda_codec *codec)
* ZxR only has microphone input, there is no front panel
* header on the card, and aux-in is handled by the DBPro board.
*/
- if (spec->quirk != QUIRK_ZXR) {
+ if (ca0132_quirk(spec) != QUIRK_ZXR) {
err = ca0132_alt_add_input_enum(codec);
if (err < 0)
return err;
}
}
- if (spec->quirk == QUIRK_AE5) {
+ if (ca0132_quirk(spec) == QUIRK_AE5) {
err = ae5_add_headphone_gain_enum(codec);
if (err < 0)
return err;
@@ -6475,7 +6505,7 @@ static int ca0132_build_controls(struct hda_codec *codec)
return err;
}
- if (spec->quirk == QUIRK_ZXR) {
+ if (ca0132_quirk(spec) == QUIRK_ZXR) {
err = zxr_add_headphone_gain_switch(codec);
if (err < 0)
return err;
@@ -6505,7 +6535,7 @@ static int ca0132_build_controls(struct hda_codec *codec)
return err;
}
- if (spec->use_alt_functions)
+ if (ca0132_use_alt_functions(spec))
ca0132_alt_add_chmap_ctls(codec);
return 0;
@@ -6583,7 +6613,7 @@ static int ca0132_build_pcms(struct hda_codec *codec)
info = snd_hda_codec_pcm_new(codec, "CA0132 Analog");
if (!info)
return -ENOMEM;
- if (spec->use_alt_functions) {
+ if (ca0132_use_alt_functions(spec)) {
info->own_chmap = true;
info->stream[SNDRV_PCM_STREAM_PLAYBACK].chmap
= ca0132_alt_chmaps;
@@ -6597,7 +6627,7 @@ static int ca0132_build_pcms(struct hda_codec *codec)
info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->adcs[0];
/* With the DSP enabled, desktops don't use this ADC. */
- if (!spec->use_alt_functions) {
+ if (!ca0132_use_alt_functions(spec)) {
info = snd_hda_codec_pcm_new(codec, "CA0132 Analog Mic-In2");
if (!info)
return -ENOMEM;
@@ -6795,7 +6825,7 @@ static void ca0132_init_dmic(struct hda_codec *codec)
* Bit 6: set to select Data2, clear for Data1
* Bit 7: set to enable DMic, clear for AMic
*/
- if (spec->quirk == QUIRK_ALIENWARE_M17XR4)
+ if (ca0132_quirk(spec) == QUIRK_ALIENWARE_M17XR4)
val = 0x33;
else
val = 0x23;
@@ -6877,7 +6907,7 @@ static void ca0132_alt_init_analog_mics(struct hda_codec *codec)
/* Mic 1 Setup */
chipio_set_conn_rate(codec, MEM_CONNID_MICIN1, SR_96_000);
chipio_set_conn_rate(codec, MEM_CONNID_MICOUT1, SR_96_000);
- if (spec->quirk == QUIRK_R3DI) {
+ if (ca0132_quirk(spec) == QUIRK_R3DI) {
chipio_set_conn_rate(codec, 0x0F, SR_96_000);
tmp = FLOAT_ONE;
} else
@@ -6887,7 +6917,7 @@ static void ca0132_alt_init_analog_mics(struct hda_codec *codec)
/* Mic 2 setup (not present on desktop cards) */
chipio_set_conn_rate(codec, MEM_CONNID_MICIN2, SR_96_000);
chipio_set_conn_rate(codec, MEM_CONNID_MICOUT2, SR_96_000);
- if (spec->quirk == QUIRK_R3DI)
+ if (ca0132_quirk(spec) == QUIRK_R3DI)
chipio_set_conn_rate(codec, 0x0F, SR_96_000);
tmp = FLOAT_ZERO;
dspio_set_uint_param(codec, 0x80, 0x01, tmp);
@@ -6949,7 +6979,7 @@ static void sbz_chipio_startup_data(struct hda_codec *codec)
chipio_set_stream_channels(codec, 0x0C, 6);
chipio_set_stream_control(codec, 0x0C, 1);
/* No clue what these control */
- if (spec->quirk == QUIRK_SBZ) {
+ if (ca0132_quirk(spec) == QUIRK_SBZ) {
chipio_write_no_mutex(codec, 0x190030, 0x0001e0c0);
chipio_write_no_mutex(codec, 0x190034, 0x0001e1c1);
chipio_write_no_mutex(codec, 0x190038, 0x0001e4c2);
@@ -6962,7 +6992,7 @@ static void sbz_chipio_startup_data(struct hda_codec *codec)
chipio_write_no_mutex(codec, 0x190054, 0x0001edc9);
chipio_write_no_mutex(codec, 0x190058, 0x0001eaca);
chipio_write_no_mutex(codec, 0x19005c, 0x0001ebcb);
- } else if (spec->quirk == QUIRK_ZXR) {
+ } else if (ca0132_quirk(spec) == QUIRK_ZXR) {
chipio_write_no_mutex(codec, 0x190038, 0x000140c2);
chipio_write_no_mutex(codec, 0x19003c, 0x000141c3);
chipio_write_no_mutex(codec, 0x190040, 0x000150c4);
@@ -6992,7 +7022,7 @@ static void ca0132_alt_dsp_scp_startup(struct hda_codec *codec)
* why this is, but multiple tests have confirmed it.
*/
for (i = 0; i < 2; i++) {
- switch (spec->quirk) {
+ switch (ca0132_quirk(spec)) {
case QUIRK_SBZ:
case QUIRK_AE5:
tmp = 0x00000003;
@@ -7021,6 +7051,8 @@ static void ca0132_alt_dsp_scp_startup(struct hda_codec *codec)
tmp = 0x00000000;
dspio_set_uint_param_no_source(codec, 0x80, 0x0C, tmp);
break;
+ default:
+ break;
}
msleep(100);
}
@@ -7043,7 +7075,7 @@ static void ca0132_alt_dsp_initial_mic_setup(struct hda_codec *codec)
chipio_set_stream_control(codec, 0x03, 1);
chipio_set_stream_control(codec, 0x04, 1);
- switch (spec->quirk) {
+ switch (ca0132_quirk(spec)) {
case QUIRK_SBZ:
chipio_write(codec, 0x18b098, 0x0000000c);
chipio_write(codec, 0x18b09C, 0x0000000c);
@@ -7052,6 +7084,8 @@ static void ca0132_alt_dsp_initial_mic_setup(struct hda_codec *codec)
chipio_write(codec, 0x18b098, 0x0000000c);
chipio_write(codec, 0x18b09c, 0x0000004c);
break;
+ default:
+ break;
}
}
@@ -7273,7 +7307,7 @@ static void r3d_setup_defaults(struct hda_codec *codec)
/* Set speaker source? */
dspio_set_uint_param(codec, 0x32, 0x00, tmp);
- if (spec->quirk == QUIRK_R3DI)
+ if (ca0132_quirk(spec) == QUIRK_R3DI)
r3di_gpio_dsp_status_set(codec, R3DI_DSP_DOWNLOADED);
/* Setup effect defaults */
@@ -7420,7 +7454,7 @@ static void ca0132_init_flags(struct hda_codec *codec)
{
struct ca0132_spec *spec = codec->spec;
- if (spec->use_alt_functions) {
+ if (ca0132_use_alt_functions(spec)) {
chipio_set_control_flag(codec, CONTROL_FLAG_DSP_96KHZ, 1);
chipio_set_control_flag(codec, CONTROL_FLAG_DAC_96KHZ, 1);
chipio_set_control_flag(codec, CONTROL_FLAG_ADC_B_96KHZ, 1);
@@ -7453,7 +7487,7 @@ static void ca0132_init_params(struct hda_codec *codec)
{
struct ca0132_spec *spec = codec->spec;
- if (spec->use_alt_functions) {
+ if (ca0132_use_alt_functions(spec)) {
chipio_set_conn_rate(codec, MEM_CONNID_WUH, SR_48_000);
chipio_set_conn_rate(codec, 0x0B, SR_48_000);
chipio_set_control_param(codec, CONTROL_PARAM_SPDIF1_SOURCE, 0);
@@ -7490,7 +7524,7 @@ static bool ca0132_download_dsp_images(struct hda_codec *codec)
* can use the default firmware, but I'll leave the option in case
* it needs it again.
*/
- switch (spec->quirk) {
+ switch (ca0132_quirk(spec)) {
case QUIRK_SBZ:
case QUIRK_R3D:
case QUIRK_AE5:
@@ -7564,7 +7598,7 @@ static void ca0132_download_dsp(struct hda_codec *codec)
}
/* For codecs using alt functions, this is already done earlier */
- if (spec->dsp_state == DSP_DOWNLOADED && (!spec->use_alt_functions))
+ if (spec->dsp_state == DSP_DOWNLOADED && !ca0132_use_alt_functions(spec))
ca0132_set_dsp_msr(codec, true);
}
@@ -7601,7 +7635,7 @@ static void amic_callback(struct hda_codec *codec, struct hda_jack_callback *cb)
{
struct ca0132_spec *spec = codec->spec;
- if (spec->use_alt_functions)
+ if (ca0132_use_alt_functions(spec))
ca0132_alt_select_in(codec);
else
ca0132_select_mic(codec);
@@ -7616,7 +7650,7 @@ static void ca0132_init_unsol(struct hda_codec *codec)
snd_hda_jack_detect_enable_callback(codec, UNSOL_TAG_DSP,
ca0132_process_dsp_response);
/* Front headphone jack detection */
- if (spec->use_alt_functions)
+ if (ca0132_use_alt_functions(spec))
snd_hda_jack_detect_enable_callback(codec,
spec->unsol_tag_front_hp, hp_callback);
}
@@ -7706,7 +7740,7 @@ static void ca0132_init_chip(struct hda_codec *codec)
mutex_init(&spec->chipio_mutex);
spec->cur_out_type = SPEAKER_OUT;
- if (!spec->use_alt_functions)
+ if (!ca0132_use_alt_functions(spec))
spec->cur_mic_type = DIGITAL_MIC;
else
spec->cur_mic_type = REAR_MIC;
@@ -7732,7 +7766,7 @@ static void ca0132_init_chip(struct hda_codec *codec)
* Sets defaults for the effect slider controls, only for alternative
* ca0132 codecs. Also sets x-bass crossover frequency to 80hz.
*/
- if (spec->use_alt_controls) {
+ if (ca0132_use_alt_controls(spec)) {
spec->xbass_xover_freq = 8;
for (i = 0; i < EFFECT_LEVEL_SLIDERS; i++)
spec->fx_ctl_val[i] = effect_slider_defaults[i];
@@ -7747,7 +7781,7 @@ static void ca0132_init_chip(struct hda_codec *codec)
* the daughter board. So, there is no input enum control, and we need
* to make sure that spec->in_enum_val is set properly.
*/
- if (spec->quirk == QUIRK_ZXR)
+ if (ca0132_quirk(spec) == QUIRK_ZXR)
spec->in_enum_val = REAR_MIC;
#ifdef ENABLE_TUNING_CONTROLS
@@ -8088,27 +8122,27 @@ static void ca0132_mmio_init(struct hda_codec *codec)
{
struct ca0132_spec *spec = codec->spec;
- if (spec->quirk == QUIRK_AE5)
+ if (ca0132_quirk(spec) == QUIRK_AE5)
writel(0x00000001, spec->mem_base + 0x400);
else
writel(0x00000000, spec->mem_base + 0x400);
- if (spec->quirk == QUIRK_AE5)
+ if (ca0132_quirk(spec) == QUIRK_AE5)
writel(0x00000001, spec->mem_base + 0x408);
else
writel(0x00000000, spec->mem_base + 0x408);
- if (spec->quirk == QUIRK_AE5)
+ if (ca0132_quirk(spec) == QUIRK_AE5)
writel(0x00000001, spec->mem_base + 0x40c);
else
writel(0x00000000, spec->mem_base + 0x40C);
- if (spec->quirk == QUIRK_ZXR)
+ if (ca0132_quirk(spec) == QUIRK_ZXR)
writel(0x00880640, spec->mem_base + 0x01C);
else
writel(0x00880680, spec->mem_base + 0x01C);
- if (spec->quirk == QUIRK_AE5)
+ if (ca0132_quirk(spec) == QUIRK_AE5)
writel(0x00000080, spec->mem_base + 0xC0C);
else
writel(0x00000083, spec->mem_base + 0xC0C);
@@ -8116,7 +8150,7 @@ static void ca0132_mmio_init(struct hda_codec *codec)
writel(0x00000030, spec->mem_base + 0xC00);
writel(0x00000000, spec->mem_base + 0xC04);
- if (spec->quirk == QUIRK_AE5)
+ if (ca0132_quirk(spec) == QUIRK_AE5)
writel(0x00000000, spec->mem_base + 0xC0C);
else
writel(0x00000003, spec->mem_base + 0xC0C);
@@ -8125,7 +8159,7 @@ static void ca0132_mmio_init(struct hda_codec *codec)
writel(0x00000003, spec->mem_base + 0xC0C);
writel(0x00000003, spec->mem_base + 0xC0C);
- if (spec->quirk == QUIRK_AE5)
+ if (ca0132_quirk(spec) == QUIRK_AE5)
writel(0x00000001, spec->mem_base + 0xC08);
else
writel(0x000000C1, spec->mem_base + 0xC08);
@@ -8136,7 +8170,7 @@ static void ca0132_mmio_init(struct hda_codec *codec)
writel(0x000000C1, spec->mem_base + 0xC08);
writel(0x00000080, spec->mem_base + 0xC04);
- if (spec->quirk == QUIRK_AE5) {
+ if (ca0132_quirk(spec) == QUIRK_AE5) {
writel(0x00000000, spec->mem_base + 0x42c);
writel(0x00000000, spec->mem_base + 0x46c);
writel(0x00000000, spec->mem_base + 0x4ac);
@@ -8211,7 +8245,7 @@ static void ca0132_alt_init(struct hda_codec *codec)
ca0132_alt_vol_setup(codec);
- switch (spec->quirk) {
+ switch (ca0132_quirk(spec)) {
case QUIRK_SBZ:
codec_dbg(codec, "SBZ alt_init");
ca0132_gpio_init(codec);
@@ -8248,6 +8282,8 @@ static void ca0132_alt_init(struct hda_codec *codec)
snd_hda_sequence_write(codec, spec->chip_init_verbs);
snd_hda_sequence_write(codec, spec->desktop_init_verbs);
break;
+ default:
+ break;
}
}
@@ -8274,7 +8310,7 @@ static int ca0132_init(struct hda_codec *codec)
spec->dsp_reload = true;
spec->dsp_state = DSP_DOWNLOAD_INIT;
} else {
- if (spec->quirk == QUIRK_SBZ)
+ if (ca0132_quirk(spec) == QUIRK_SBZ)
sbz_dsp_startup_check(codec);
return 0;
}
@@ -8284,12 +8320,12 @@ static int ca0132_init(struct hda_codec *codec)
spec->dsp_state = DSP_DOWNLOAD_INIT;
spec->curr_chip_addx = INVALID_CHIP_ADDRESS;
- if (spec->use_pci_mmio)
+ if (ca0132_use_pci_mmio(spec))
ca0132_mmio_init(codec);
snd_hda_power_up_pm(codec);
- if (spec->quirk == QUIRK_AE5)
+ if (ca0132_quirk(spec) == QUIRK_AE5)
ae5_register_set(codec);
ca0132_init_unsol(codec);
@@ -8298,14 +8334,14 @@ static int ca0132_init(struct hda_codec *codec)
snd_hda_sequence_write(codec, spec->base_init_verbs);
- if (spec->use_alt_functions)
+ if (ca0132_use_alt_functions(spec))
ca0132_alt_init(codec);
ca0132_download_dsp(codec);
ca0132_refresh_widget_caps(codec);
- switch (spec->quirk) {
+ switch (ca0132_quirk(spec)) {
case QUIRK_R3DI:
case QUIRK_R3D:
r3d_setup_defaults(codec);
@@ -8334,7 +8370,7 @@ static int ca0132_init(struct hda_codec *codec)
init_input(codec, cfg->dig_in_pin, spec->dig_in);
- if (!spec->use_alt_functions) {
+ if (!ca0132_use_alt_functions(spec)) {
snd_hda_sequence_write(codec, spec->chip_init_verbs);
snd_hda_codec_write(codec, WIDGET_CHIP_CTRL, 0,
VENDOR_CHIPIO_PARAM_EX_ID_SET, 0x0D);
@@ -8342,11 +8378,11 @@ static int ca0132_init(struct hda_codec *codec)
VENDOR_CHIPIO_PARAM_EX_VALUE_SET, 0x20);
}
- if (spec->quirk == QUIRK_SBZ)
+ if (ca0132_quirk(spec) == QUIRK_SBZ)
ca0132_gpio_setup(codec);
snd_hda_sequence_write(codec, spec->spec_init_verbs);
- if (spec->use_alt_functions) {
+ if (ca0132_use_alt_functions(spec)) {
ca0132_alt_select_out(codec);
ca0132_alt_select_in(codec);
} else {
@@ -8391,7 +8427,7 @@ static void ca0132_free(struct hda_codec *codec)
cancel_delayed_work_sync(&spec->unsol_hp_work);
snd_hda_power_up(codec);
- switch (spec->quirk) {
+ switch (ca0132_quirk(spec)) {
case QUIRK_SBZ:
sbz_exit_chip(codec);
break;
@@ -8407,13 +8443,15 @@ static void ca0132_free(struct hda_codec *codec)
case QUIRK_R3DI:
r3di_gpio_shutdown(codec);
break;
+ default:
+ break;
}
snd_hda_sequence_write(codec, spec->base_exit_verbs);
ca0132_exit_chip(codec);
snd_hda_power_down(codec);
- if (spec->mem_base)
+ if (IS_ENABLED(CONFIG_PCI) && spec->mem_base)
pci_iounmap(codec->bus->pci, spec->mem_base);
kfree(spec->spec_init_verbs);
kfree(codec->spec);
@@ -8461,12 +8499,12 @@ static void ca0132_config(struct hda_codec *codec)
spec->multiout.dac_nids = spec->dacs;
spec->multiout.num_dacs = 3;
- if (!spec->use_alt_functions)
+ if (!ca0132_use_alt_functions(spec))
spec->multiout.max_channels = 2;
else
spec->multiout.max_channels = 6;
- switch (spec->quirk) {
+ switch (ca0132_quirk(spec)) {
case QUIRK_ALIENWARE:
codec_dbg(codec, "%s: QUIRK_ALIENWARE applied.\n", __func__);
snd_hda_apply_pincfgs(codec, alienware_pincfgs);
@@ -8491,9 +8529,11 @@ static void ca0132_config(struct hda_codec *codec)
codec_dbg(codec, "%s: QUIRK_AE5 applied.\n", __func__);
snd_hda_apply_pincfgs(codec, ae5_pincfgs);
break;
+ default:
+ break;
}
- switch (spec->quirk) {
+ switch (ca0132_quirk(spec)) {
case QUIRK_ALIENWARE:
spec->num_outputs = 2;
spec->out_pins[0] = 0x0b; /* speaker out */
@@ -8654,7 +8694,7 @@ static int ca0132_prepare_verbs(struct hda_codec *codec)
* Since desktop cards use pci_mmio, this can be used to determine
* whether or not to use these verbs instead of a separate bool.
*/
- if (spec->use_pci_mmio)
+ if (ca0132_use_pci_mmio(spec))
spec->desktop_init_verbs = ca0132_init_verbs1;
spec->spec_init_verbs = kcalloc(NUM_SPEC_VERBS,
sizeof(struct hda_verb),
@@ -8729,11 +8769,10 @@ static int patch_ca0132(struct hda_codec *codec)
spec->quirk = quirk->value;
else
spec->quirk = QUIRK_NONE;
-
- if (spec->quirk == QUIRK_SBZ)
+ if (ca0132_quirk(spec) == QUIRK_SBZ)
sbz_detect_quirk(codec);
- if (spec->quirk == QUIRK_ZXR_DBPRO)
+ if (ca0132_quirk(spec) == QUIRK_ZXR_DBPRO)
codec->patch_ops = dbpro_patch_ops;
else
codec->patch_ops = ca0132_patch_ops;
@@ -8746,7 +8785,7 @@ static int patch_ca0132(struct hda_codec *codec)
spec->num_mixers = 1;
/* Set which mixers each quirk uses. */
- switch (spec->quirk) {
+ switch (ca0132_quirk(spec)) {
case QUIRK_SBZ:
spec->mixers[0] = desktop_mixer;
snd_hda_codec_set_name(codec, "Sound Blaster Z");
@@ -8775,7 +8814,7 @@ static int patch_ca0132(struct hda_codec *codec)
}
/* Setup whether or not to use alt functions/controls/pci_mmio */
- switch (spec->quirk) {
+ switch (ca0132_quirk(spec)) {
case QUIRK_SBZ:
case QUIRK_R3D:
case QUIRK_AE5:
@@ -8796,6 +8835,7 @@ static int patch_ca0132(struct hda_codec *codec)
break;
}
+#ifdef CONFIG_PCI
if (spec->use_pci_mmio) {
spec->mem_base = pci_iomap(codec->bus->pci, 2, 0xC20);
if (spec->mem_base == NULL) {
@@ -8803,6 +8843,7 @@ static int patch_ca0132(struct hda_codec *codec)
spec->quirk = QUIRK_NONE;
}
}
+#endif
spec->base_init_verbs = ca0132_base_init_verbs;
spec->base_exit_verbs = ca0132_base_exit_verbs;
diff --git a/sound/pci/hda/patch_conexant.c b/sound/pci/hda/patch_conexant.c
index 950e02e71766..51cc6589443f 100644
--- a/sound/pci/hda/patch_conexant.c
+++ b/sound/pci/hda/patch_conexant.c
@@ -923,6 +923,7 @@ static const struct snd_pci_quirk cxt5066_fixups[] = {
SND_PCI_QUIRK(0x103c, 0x8079, "HP EliteBook 840 G3", CXT_FIXUP_HP_DOCK),
SND_PCI_QUIRK(0x103c, 0x807C, "HP EliteBook 820 G3", CXT_FIXUP_HP_DOCK),
SND_PCI_QUIRK(0x103c, 0x80FD, "HP ProBook 640 G2", CXT_FIXUP_HP_DOCK),
+ SND_PCI_QUIRK(0x103c, 0x828c, "HP EliteBook 840 G4", CXT_FIXUP_HP_DOCK),
SND_PCI_QUIRK(0x103c, 0x83b3, "HP EliteBook 830 G5", CXT_FIXUP_HP_DOCK),
SND_PCI_QUIRK(0x103c, 0x83d3, "HP ProBook 640 G4", CXT_FIXUP_HP_DOCK),
SND_PCI_QUIRK(0x103c, 0x8174, "HP Spectre x360", CXT_FIXUP_HP_SPECTRE),
diff --git a/sound/pci/hda/patch_hdmi.c b/sound/pci/hda/patch_hdmi.c
index 67099cbb6be2..46f88dc7b7e8 100644
--- a/sound/pci/hda/patch_hdmi.c
+++ b/sound/pci/hda/patch_hdmi.c
@@ -2142,7 +2142,7 @@ static int generic_hdmi_build_jack(struct hda_codec *codec, int pcm_idx)
strncat(hdmi_str, " Phantom",
sizeof(hdmi_str) - strlen(hdmi_str) - 1);
ret = snd_hda_jack_add_kctl(codec, per_pin->pin_nid, hdmi_str,
- phantom_jack);
+ phantom_jack, 0, NULL);
if (ret < 0)
return ret;
jack = snd_hda_jack_tbl_get(codec, per_pin->pin_nid);
@@ -2616,11 +2616,7 @@ static int intel_hsw_common_init(struct hda_codec *codec, hda_nid_t vendor_nid)
intel_haswell_enable_all_pins(codec, true);
intel_haswell_fixup_enable_dp12(codec);
- /* For Haswell/Broadwell, the controller is also in the power well and
- * can cover the codec power request, and so need not set this flag.
- */
- if (!is_haswell(codec) && !is_broadwell(codec))
- codec->core.link_power_control = 1;
+ codec->display_power_control = 1;
codec->patch_ops.set_power_state = haswell_set_power_state;
codec->depop_delay = 0;
@@ -2656,7 +2652,7 @@ static int patch_i915_byt_hdmi(struct hda_codec *codec)
/* For Valleyview/Cherryview, only the display codec is in the display
* power well and can use link_power ops to request/release the power.
*/
- codec->core.link_power_control = 1;
+ codec->display_power_control = 1;
codec->depop_delay = 0;
codec->auto_runtime_pm = 1;
@@ -3834,6 +3830,10 @@ HDA_CODEC_ENTRY(0x10de0020, "Tegra30 HDMI", patch_tegra_hdmi),
HDA_CODEC_ENTRY(0x10de0022, "Tegra114 HDMI", patch_tegra_hdmi),
HDA_CODEC_ENTRY(0x10de0028, "Tegra124 HDMI", patch_tegra_hdmi),
HDA_CODEC_ENTRY(0x10de0029, "Tegra210 HDMI/DP", patch_tegra_hdmi),
+HDA_CODEC_ENTRY(0x10de002d, "Tegra186 HDMI/DP0", patch_tegra_hdmi),
+HDA_CODEC_ENTRY(0x10de002e, "Tegra186 HDMI/DP1", patch_tegra_hdmi),
+HDA_CODEC_ENTRY(0x10de002f, "Tegra194 HDMI/DP2", patch_tegra_hdmi),
+HDA_CODEC_ENTRY(0x10de0030, "Tegra194 HDMI/DP3", patch_tegra_hdmi),
HDA_CODEC_ENTRY(0x10de0040, "GPU 40 HDMI/DP", patch_nvhdmi),
HDA_CODEC_ENTRY(0x10de0041, "GPU 41 HDMI/DP", patch_nvhdmi),
HDA_CODEC_ENTRY(0x10de0042, "GPU 42 HDMI/DP", patch_nvhdmi),
diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c
index 15021c839372..a4f4a9dd488d 100644
--- a/sound/pci/hda/patch_realtek.c
+++ b/sound/pci/hda/patch_realtek.c
@@ -5380,6 +5380,66 @@ static void alc285_fixup_invalidate_dacs(struct hda_codec *codec,
snd_hda_override_wcaps(codec, 0x03, 0);
}
+static const struct hda_jack_keymap alc_headset_btn_keymap[] = {
+ { SND_JACK_BTN_0, KEY_PLAYPAUSE },
+ { SND_JACK_BTN_1, KEY_VOICECOMMAND },
+ { SND_JACK_BTN_2, KEY_VOLUMEUP },
+ { SND_JACK_BTN_3, KEY_VOLUMEDOWN },
+ {}
+};
+
+static void alc_headset_btn_callback(struct hda_codec *codec,
+ struct hda_jack_callback *jack)
+{
+ int report = 0;
+
+ if (jack->unsol_res & (7 << 13))
+ report |= SND_JACK_BTN_0;
+
+ if (jack->unsol_res & (1 << 16 | 3 << 8))
+ report |= SND_JACK_BTN_1;
+
+ /* Volume up key */
+ if (jack->unsol_res & (7 << 23))
+ report |= SND_JACK_BTN_2;
+
+ /* Volume down key */
+ if (jack->unsol_res & (7 << 10))
+ report |= SND_JACK_BTN_3;
+
+ jack->jack->button_state = report;
+}
+
+static void alc_fixup_headset_jack(struct hda_codec *codec,
+ const struct hda_fixup *fix, int action)
+{
+
+ switch (action) {
+ case HDA_FIXUP_ACT_PRE_PROBE:
+ snd_hda_jack_detect_enable_callback(codec, 0x55,
+ alc_headset_btn_callback);
+ snd_hda_jack_add_kctl(codec, 0x55, "Headset Jack", false,
+ SND_JACK_HEADSET, alc_headset_btn_keymap);
+ break;
+ case HDA_FIXUP_ACT_INIT:
+ switch (codec->core.vendor_id) {
+ case 0x10ec0225:
+ case 0x10ec0295:
+ case 0x10ec0299:
+ alc_write_coef_idx(codec, 0x48, 0xd011);
+ alc_update_coef_idx(codec, 0x49, 0x007f, 0x0045);
+ alc_update_coef_idx(codec, 0x44, 0x007f << 8, 0x0045 << 8);
+ break;
+ case 0x10ec0236:
+ case 0x10ec0256:
+ alc_write_coef_idx(codec, 0x48, 0xd011);
+ alc_update_coef_idx(codec, 0x49, 0x007f, 0x0045);
+ break;
+ }
+ break;
+ }
+}
+
/* for hda_fixup_thinkpad_acpi() */
#include "thinkpad_helper.c"
@@ -5390,9 +5450,6 @@ static void alc_fixup_thinkpad_acpi(struct hda_codec *codec,
hda_fixup_thinkpad_acpi(codec, fix, action);
}
-/* for dell wmi mic mute led */
-#include "dell_wmi_helper.c"
-
/* for alc295_fixup_hp_top_speakers */
#include "hp_x360_helper.c"
@@ -5470,7 +5527,7 @@ enum {
ALC292_FIXUP_TPT440_DOCK,
ALC292_FIXUP_TPT440,
ALC283_FIXUP_HEADSET_MIC,
- ALC255_FIXUP_DELL_WMI_MIC_MUTE_LED,
+ ALC255_FIXUP_MIC_MUTE_LED,
ALC282_FIXUP_ASPIRE_V5_PINS,
ALC280_FIXUP_HP_GPIO4,
ALC286_FIXUP_HP_GPIO_LED,
@@ -5515,6 +5572,7 @@ enum {
ALC298_FIXUP_TPT470_DOCK,
ALC255_FIXUP_DUMMY_LINEOUT_VERB,
ALC255_FIXUP_DELL_HEADSET_MIC,
+ ALC256_FIXUP_HUAWEI_MBXP_PINS,
ALC295_FIXUP_HP_X360,
ALC221_FIXUP_HP_HEADSET_MIC,
ALC285_FIXUP_LENOVO_HEADPHONE_NOISE,
@@ -5523,6 +5581,7 @@ enum {
ALC294_FIXUP_ASUS_MIC,
ALC294_FIXUP_ASUS_HEADSET_MIC,
ALC294_FIXUP_ASUS_SPK,
+ ALC225_FIXUP_HEADSET_JACK,
};
static const struct hda_fixup alc269_fixups[] = {
@@ -5770,7 +5829,7 @@ static const struct hda_fixup alc269_fixups[] = {
.type = HDA_FIXUP_FUNC,
.v.func = alc_fixup_headset_mode,
.chained = true,
- .chain_id = ALC255_FIXUP_DELL_WMI_MIC_MUTE_LED
+ .chain_id = ALC255_FIXUP_MIC_MUTE_LED
},
[ALC269_FIXUP_HEADSET_MODE_NO_HP_MIC] = {
.type = HDA_FIXUP_FUNC,
@@ -5794,6 +5853,24 @@ static const struct hda_fixup alc269_fixups[] = {
.chained = true,
.chain_id = ALC269_FIXUP_HEADSET_MIC
},
+ [ALC256_FIXUP_HUAWEI_MBXP_PINS] = {
+ .type = HDA_FIXUP_PINS,
+ .v.pins = (const struct hda_pintbl[]) {
+ {0x12, 0x90a60130},
+ {0x13, 0x40000000},
+ {0x14, 0x90170110},
+ {0x18, 0x411111f0},
+ {0x19, 0x04a11040},
+ {0x1a, 0x411111f0},
+ {0x1b, 0x90170112},
+ {0x1d, 0x40759a05},
+ {0x1e, 0x411111f0},
+ {0x21, 0x04211020},
+ { }
+ },
+ .chained = true,
+ .chain_id = ALC255_FIXUP_MIC_MUTE_LED
+ },
[ALC269_FIXUP_ASUS_X101_FUNC] = {
.type = HDA_FIXUP_FUNC,
.v.func = alc269_fixup_x101_headset_mic,
@@ -5996,7 +6073,7 @@ static const struct hda_fixup alc269_fixups[] = {
.type = HDA_FIXUP_FUNC,
.v.func = alc_fixup_headset_mode_alc255,
.chained = true,
- .chain_id = ALC255_FIXUP_DELL_WMI_MIC_MUTE_LED
+ .chain_id = ALC255_FIXUP_MIC_MUTE_LED
},
[ALC255_FIXUP_HEADSET_MODE_NO_HP_MIC] = {
.type = HDA_FIXUP_FUNC,
@@ -6031,9 +6108,9 @@ static const struct hda_fixup alc269_fixups[] = {
{ },
},
},
- [ALC255_FIXUP_DELL_WMI_MIC_MUTE_LED] = {
+ [ALC255_FIXUP_MIC_MUTE_LED] = {
.type = HDA_FIXUP_FUNC,
- .v.func = alc_fixup_dell_wmi,
+ .v.func = snd_hda_gen_fixup_micmute_led,
},
[ALC282_FIXUP_ASPIRE_V5_PINS] = {
.type = HDA_FIXUP_PINS,
@@ -6092,7 +6169,7 @@ static const struct hda_fixup alc269_fixups[] = {
.type = HDA_FIXUP_FUNC,
.v.func = alc_fixup_headset_mode_dell_alc288,
.chained = true,
- .chain_id = ALC255_FIXUP_DELL_WMI_MIC_MUTE_LED
+ .chain_id = ALC255_FIXUP_MIC_MUTE_LED
},
[ALC288_FIXUP_DELL1_MIC_NO_PRESENCE] = {
.type = HDA_FIXUP_PINS,
@@ -6441,6 +6518,10 @@ static const struct hda_fixup alc269_fixups[] = {
.chained = true,
.chain_id = ALC294_FIXUP_ASUS_HEADSET_MIC
},
+ [ALC225_FIXUP_HEADSET_JACK] = {
+ .type = HDA_FIXUP_FUNC,
+ .v.func = alc_fixup_headset_jack,
+ },
};
static const struct snd_pci_quirk alc269_fixup_tbl[] = {
@@ -6573,6 +6654,7 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = {
SND_PCI_QUIRK(0x1043, 0x103e, "ASUS X540SA", ALC256_FIXUP_ASUS_MIC),
SND_PCI_QUIRK(0x1043, 0x103f, "ASUS TX300", ALC282_FIXUP_ASUS_TX300),
SND_PCI_QUIRK(0x1043, 0x106d, "Asus K53BE", ALC269_FIXUP_LIMIT_INT_MIC_BOOST),
+ SND_PCI_QUIRK(0x1043, 0x10a1, "ASUS UX391UA", ALC294_FIXUP_ASUS_SPK),
SND_PCI_QUIRK(0x1043, 0x10c0, "ASUS X540SA", ALC256_FIXUP_ASUS_MIC),
SND_PCI_QUIRK(0x1043, 0x10d0, "ASUS X540LA/X540LJ", ALC255_FIXUP_ASUS_MIC_NO_PRESENCE),
SND_PCI_QUIRK(0x1043, 0x115d, "Asus 1015E", ALC269_FIXUP_LIMIT_INT_MIC_BOOST),
@@ -6680,6 +6762,9 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = {
SND_PCI_QUIRK(0x17aa, 0x511f, "Thinkpad", ALC298_FIXUP_TPT470_DOCK),
SND_PCI_QUIRK(0x17aa, 0x3bf8, "Quanta FL1", ALC269_FIXUP_PCM_44K),
SND_PCI_QUIRK(0x17aa, 0x9e54, "LENOVO NB", ALC269_FIXUP_LENOVO_EAPD),
+ SND_PCI_QUIRK(0x19e5, 0x3200, "Huawei MBX", ALC255_FIXUP_MIC_MUTE_LED),
+ SND_PCI_QUIRK(0x19e5, 0x3201, "Huawei MBX", ALC255_FIXUP_MIC_MUTE_LED),
+ SND_PCI_QUIRK(0x19e5, 0x3204, "Huawei MBXP", ALC256_FIXUP_HUAWEI_MBXP_PINS),
SND_PCI_QUIRK(0x1b7d, 0xa831, "Ordissimo EVE2 ", ALC269VB_FIXUP_ORDISSIMO_EVE2), /* Also known as Malata PC-B1303 */
#if 0
@@ -6805,7 +6890,7 @@ static const struct hda_model_fixup alc269_fixup_models[] = {
{.id = ALC255_FIXUP_DELL2_MIC_NO_PRESENCE, .name = "alc255-dell2"},
{.id = ALC293_FIXUP_DELL1_MIC_NO_PRESENCE, .name = "alc293-dell1"},
{.id = ALC283_FIXUP_HEADSET_MIC, .name = "alc283-headset"},
- {.id = ALC255_FIXUP_DELL_WMI_MIC_MUTE_LED, .name = "alc255-dell-mute"},
+ {.id = ALC255_FIXUP_MIC_MUTE_LED, .name = "alc255-dell-mute"},
{.id = ALC282_FIXUP_ASPIRE_V5_PINS, .name = "aspire-v5"},
{.id = ALC280_FIXUP_HP_GPIO4, .name = "hp-gpio4"},
{.id = ALC286_FIXUP_HP_GPIO_LED, .name = "hp-gpio-led"},
@@ -6844,6 +6929,7 @@ static const struct hda_model_fixup alc269_fixup_models[] = {
{.id = ALC255_FIXUP_DUMMY_LINEOUT_VERB, .name = "alc255-dummy-lineout"},
{.id = ALC255_FIXUP_DELL_HEADSET_MIC, .name = "alc255-dell-headset"},
{.id = ALC295_FIXUP_HP_X360, .name = "alc295-hp-x360"},
+ {.id = ALC225_FIXUP_HEADSET_JACK, .name = "alc-sense-combo"},
{}
};
#define ALC225_STANDARD_PINS \
diff --git a/sound/pci/hda/thinkpad_helper.c b/sound/pci/hda/thinkpad_helper.c
index 568575b72f2f..4089feb8c68e 100644
--- a/sound/pci/hda/thinkpad_helper.c
+++ b/sound/pci/hda/thinkpad_helper.c
@@ -3,12 +3,11 @@
* to be included from codec driver
*/
-#if IS_ENABLED(CONFIG_THINKPAD_ACPI)
+#if IS_ENABLED(CONFIG_THINKPAD_ACPI) && IS_REACHABLE(CONFIG_LEDS_TRIGGER_AUDIO)
#include <linux/acpi.h>
-#include <linux/thinkpad_acpi.h>
+#include <linux/leds.h>
-static int (*led_set_func)(int, bool);
static void (*old_vmaster_hook)(void *, int);
static bool is_thinkpad(struct hda_codec *codec)
@@ -23,50 +22,20 @@ static void update_tpacpi_mute_led(void *private_data, int enabled)
if (old_vmaster_hook)
old_vmaster_hook(private_data, enabled);
- if (led_set_func)
- led_set_func(TPACPI_LED_MUTE, !enabled);
-}
-
-static void update_tpacpi_micmute(struct hda_codec *codec)
-{
- struct hda_gen_spec *spec = codec->spec;
-
- led_set_func(TPACPI_LED_MICMUTE, spec->micmute_led.led_value);
+ ledtrig_audio_set(LED_AUDIO_MUTE, enabled ? LED_OFF : LED_ON);
}
static void hda_fixup_thinkpad_acpi(struct hda_codec *codec,
const struct hda_fixup *fix, int action)
{
struct hda_gen_spec *spec = codec->spec;
- bool removefunc = false;
if (action == HDA_FIXUP_ACT_PROBE) {
if (!is_thinkpad(codec))
return;
- if (!led_set_func)
- led_set_func = symbol_request(tpacpi_led_set);
- if (!led_set_func) {
- codec_warn(codec,
- "Failed to find thinkpad-acpi symbol tpacpi_led_set\n");
- return;
- }
-
- removefunc = true;
- if (led_set_func(TPACPI_LED_MUTE, false) >= 0) {
- old_vmaster_hook = spec->vmaster_mute.hook;
- spec->vmaster_mute.hook = update_tpacpi_mute_led;
- removefunc = false;
- }
- if (led_set_func(TPACPI_LED_MICMUTE, false) >= 0 &&
- !snd_hda_gen_add_micmute_led(codec,
- update_tpacpi_micmute))
- removefunc = false;
- }
-
- if (led_set_func && (action == HDA_FIXUP_ACT_FREE || removefunc)) {
- symbol_put(tpacpi_led_set);
- led_set_func = NULL;
- old_vmaster_hook = NULL;
+ old_vmaster_hook = spec->vmaster_mute.hook;
+ spec->vmaster_mute.hook = update_tpacpi_mute_led;
+ snd_hda_gen_fixup_micmute_led(codec, fix, action);
}
}